Commits

Anonymous committed a3e2642

Built a basic/naive structure for convert()
(TODO: clean up duplicated "staff finished" routines)

  • Participants
  • Parent commits 72390ab

Comments (0)

Files changed (2)

 #
 # Noteworthy Composer Text Format Converter
 # (Korean version)
-import sys
+#
+# The binary nwc format may have incompatible changes
+# when the version of nwc is updated, but nwctxt can be
+# readable rather stably.
+import sys, codecs
 
 position_bases = {
     'Treble': 67,  # 가온 다 오른쪽 첫번째 B(시)음
 # - 
 
 def usage():
+    # TODO
     print 'blah blah'
 
 def parse_parts(parts):
             v = True
         elif v == 'N':
             v = False
-        if v.startswith('"') and v.endswith('"'):
+        elif v.startswith('"') and v.endswith('"'):
             v = v[1:-1].replace('\\r\\n', '\r\n').decode('cp949')
         data[k] = v
     return data
 
 def parse_opts(value):
     data = {}
-    for item in data.split(','):
+    for item in value.split(','):
         try:
             k, v = item.split('=')
         except ValueError:
         data[k] = v
     return data
 
-def absolute_pos(relative_pos, clef='Treble'):
+def get_absolute_octave(relative_pos, clef='Treble'):
     return position_bases[clef] + relative_pos
 
+def get_relative_octave(pos, last_pos):
+    octave = ''
+    diff = pos - last_pos 
+    if diff > 3:
+        for i in range((diff - 4 + 7) / 7):
+            octave += "'"
+        if octave == '':
+            octave += "'"
+    elif diff < -3:
+        for i in range((-diff - 4 + 7) / 7):
+            octave += ","
+        if octave == '':
+            octave += ","
+    return octave
+
 def normalize_name(name):
-    # TODO
     return name.replace(' ', '_')
 
 def convert_key(keysig):
 
 def convert(input_file, output_file):
     staff_began = False
-    layered = False
+    num_staves, num_processed_staves = 0, 0
+    num_notes, num_bars = 0, 0
+    output_file.write('\\version "2.12"\n')
     for line in input_file:
         if line.startswith('!'):  # comment lines
             continue
         parts = line.strip().split('|')
         object_type = parts[1]
         data = parse_parts(parts[2:])
-        print object_type, data
+        #print object_type, data
         if object_type == 'SongInfo':
-            pass
+            output_file.write('\\header {\n')
+            output_file.write(''.join([
+                '\ttitle = "%s"\n' % data['Title'],
+                '\tenteredby = "%s"\n' % data['Author'],
+                '\tcopyright = "%s"\n' % data['Copyright1'],
+                '\tfooter = "%s"\n' % data['Copyright2'],
+                '\t%%{ %s %%}\n' % data['Comments'],
+            ]))
+            output_file.write('\\}\n')
         if object_type == 'PgSetup':
-            pass
+            print 'skipping page setup...'
         if object_type == 'Font':
-            pass
+            print 'skipping font configuration...'
         if object_type == 'PgMargins':
-            pass
+            print 'skipping page margins...'
         if object_type == 'AddStaff':
-            data['Style']
-            data['Layer']
+            # followed by several StaffProperties lines and StaffInstrument line
             if staff_began:
-                pass
-            else:
-                pass
+                num_processed_staves += 1
+                output_file.write('}\n')
+                print 'Staff finished'
+                print '  Number of bars : %d' % num_bars
+                print '  Number of notes : %d' % num_notes
+            staff_began = False
+            num_staves += 1
+            staff_name = data['Name']
+            staff_label = data['Label']
+            print 'Adding a staff (%s)' % staff_label
+            staff_style = None
+            staff_layered = None
+            staff_endingbar = None
+            staff_muted = None
+            staff_midi_channel = None
+            staff_lines = None
+            num_bars, num_notes = 0, 0
         if object_type == 'StaffProperties':
-            pass
+            if staff_style is not None:
+                staff_style = data.get('Style', 'Standard')
+            if staff_layered is not None:
+                staff_layered = data.get('Layer', False)
+            if staff_endingbar is not None:
+                staff_endingbar = data.get('EndingBar', 'MasterClose')
+            if staff_muted is not None:
+                staff_muted = data.get('Muted', False)
+            if staff_midi_channel is not None:
+                staff_midi_channel = data.get('Channel', 1)  # TODO: support percussions?
         if object_type == 'StaffInstrument':
             pass
+            if staff_midi_channel == 10 or staff_midi_channel == 13:
+                print 'WARNING: unsupported staff (percussion channel)'
+            else:
+                staff_began = True
+                output_file.write('new Staff {\n')
+                last_clef = ''
+                last_note_pos = ''
+                last_dur = ''
         if object_type == 'Lyrics':
             pass
         if object_type.startswith('Lyric'):
             pass
-        if object_type == 'Clef':
-            pass
-        if object_type == 'TimeSig':
-            pass
-        if object_type == 'Key':
-            pass
-        if object_type == 'Tempo':
-            data.get('Text', '')
-            pass
-        if object_type == 'Rest':
-            pass
-        if object_type == 'Bar':
-            pass
-        if object_type == 'Text':
-            pass
-        if object_type == 'Note':
-            dur = data['Dur'].split(',')
-            dur_opts = parse_opts(dur[1:])
-            pass
-        if object_type == 'Chord':
-            pass
-        if object_type == 'Dynamic':
-            data['Style']
-            pass
-        if object_type == 'SustainPedal':
-            pass
-        if object_type == 'PerformanceStyle':
-            pass
-        if object_type == 'Flow':
-            pass
+        if staff_began:
+            if object_type == 'Clef':
+                pass
+            if object_type == 'TimeSig':
+                pass
+            if object_type == 'Key':
+                pass
+            if object_type == 'Tempo':
+                data.get('Text', '')
+                pass
+            if object_type == 'Rest':
+                pass
+            if object_type == 'Bar':
+                pass
+                num_bars += 1
+            if object_type == 'Text':
+                pass
+            if object_type == 'Note':
+                dur = data['Dur'].split(',')
+                dur_opts = parse_opts(''.join(dur[1:]))
+                pass
+                num_notes += 1
+            if object_type == 'Chord':
+                pass
+                num_notes += 1
+            if object_type == 'Dynamic':
+                data['Style']
+                pass
+            if object_type == 'SustainPedal':
+                pass
+            if object_type == 'PerformanceStyle':
+                pass
+            if object_type == 'Flow':
+                pass
+            if object_type == 'Text':
+                pass
+        else:
+            continue
+    if staff_began:
+        num_processed_staves += 1
+        output_file.write('}\n')
+        print 'Staff finished'
+        print '  Number of bars : %d' % num_bars
+        print '  Number of notes : %d' % num_notes
+    print 'Total number of staves found : %d' % num_staves
+    print 'Number of processed staves : %d' % num_processed_staves
 
 if __name__ == '__main__':
     if len(sys.argv) == 1:
     else:
         input_file = open(sys.argv[1], 'r')
         try:
-            output_file = open(sys.argv[2], 'w')
+            output_file = codecs.open(sys.argv[2], 'w', encoding='utf8')
         except IndexError:
             output_file = sys.stdout
 

File sample1.nwctxt

 |SustainPedal|Status:Released|Pos:-8|Wide:Y
 |Bar|Style:Double
 |Key|Signature:F#,C#
+|AddStaff|Name:"Percussion"|Label:"Percussion"|Group:"Standard"
+|StaffProperties|EndingBar:Section Close|Visible:Y|BoundaryTop:10|BoundaryBottom:10|Lines:1|Style:Standard|Layer:N|Color:Default
+|StaffProperties|Muted:N|Volume:127|StereoPan:64|Device:0|Channel:10
+|StaffInstrument|Trans:0|DynVel:10,30,45,60,75,92,108,127
+|Clef|Type:Bass
+|TimeSig|Signature:Common
+|Note|Dur:4th|Pos:1
+|Note|Dur:4th|Pos:1
+|Note|Dur:4th|Pos:1
+|Note|Dur:4th|Pos:1
+|Bar
+|Note|Dur:4th|Pos:1
+|Note|Dur:4th|Pos:1
+|Note|Dur:4th|Pos:1
+|Note|Dur:4th|Pos:1
+|Bar
 !NoteWorthyComposer-End