xml2b40.py
changeset 6 193999e56a90
parent 1 7fd6cac1a69d
equal deleted inserted replaced
5:377c84f956dc 6:193999e56a90
    10 eem gebonden noot tussen twee stemmen verloren gaat als voor de backup (naar de andere stem)
    10 eem gebonden noot tussen twee stemmen verloren gaat als voor de backup (naar de andere stem)
    11 de noot nog een keer voorkomt.
    11 de noot nog een keer voorkomt.
    12 '''
    12 '''
    13 import operator, sys, os
    13 import operator, sys, os
    14 import xml.etree.ElementTree as E
    14 import xml.etree.ElementTree as E
       
    15 from functools import reduce
    15 
    16 
    16 b40List = ['Cbb','Cb','C','C#','C##','-','Dbb','Db','D','D#','D##','-','Ebb','Eb','E','E#','E##','Fbb','Fb','F',
    17 b40List = ['Cbb','Cb','C','C#','C##','-','Dbb','Db','D','D#','D##','-','Ebb','Eb','E','E#','E##','Fbb','Fb','F',
    17            'F#','F##','-','Gbb','Gb','G','G#','G##','-','Abb','Ab','A','A#','A##','-','Bbb','Bb','B','B#','B##']
    18            'F#','F##','-','Gbb','Gb','G','G#','G##','-','Abb','Ab','A','A#','A##','-','Bbb','Bb','B','B#','B##']
    18 b40Dict = dict (zip (b40List, range (len (b40List))))
    19 b40Dict = dict (list (zip(b40List, range(len (b40List)))))
    19 
    20 
    20 gtikkenPerKwart = 384   # ticks per quarter note
    21 gtikkenPerKwart = 384   # ticks per quarter note
    21 gC5 = False             # central C == C5 if gC5 else C4
    22 gC5 = False             # central C == C5 if gC5 else C4
    22 
    23 
    23 def ntB40 (p, o, alt):
    24 def ntB40 (p, o, alt):
    67 
    68 
    68 def appendNote (v, dur, noot):
    69 def appendNote (v, dur, noot):
    69     global tijd
    70     global tijd
    70     t = vtimes [v]
    71     t = vtimes [v]
    71     if tijd > t: voices [v].append ([tijd - t, t, 'z'])
    72     if tijd > t: voices [v].append ([tijd - t, t, 'z'])
    72     if tijd < t: raise 'kenniet'
    73     if tijd < t: raise Exception ('kenniet')
    73     voices [v].append ([dur, tijd, noot])
    74     voices [v].append ([dur, tijd, noot])
    74     tijd += int (dur)
    75     tijd += int (dur)
    75     vtimes[v] = tijd
    76     vtimes[v] = tijd
    76 
    77 
    77 def addChord (v, noot):
    78 def addChord (v, noot):
    84     gMaten.append (voices)
    85     gMaten.append (voices)
    85     voices = [[] for i in range (nVoices)]
    86     voices = [[] for i in range (nVoices)]
    86 
    87 
    87 def outMaat (i, mbuf, ns):
    88 def outMaat (i, mbuf, ns):
    88     for nx in mbuf:
    89     for nx in mbuf:
    89         dur = nx[0]  * gTikkenPerKwart / durUnit
    90         dur = int (nx[0]  * gTikkenPerKwart / durUnit)
    90         tijd = nx[1] * gTikkenPerKwart / durUnit
    91         tijd = int (nx[1] * gTikkenPerKwart / durUnit)
    91         if not dur: continue # alleen echte noten
    92         if not dur: continue # alleen echte noten
    92         for noot in nx[2:]: # de noot of noten in chord
    93         for noot in nx[2:]: # de noot of noten in chord
    93             if 'z' in noot: continue # skip rusten
    94             if 'z' in noot: continue # skip rusten
    94             ns.append ((tijd, noot, dur))
    95             ns.append ((tijd, noot, dur))
    95 
    96 
   103         else:
   104         else:
   104             if noot in tieBufDur: # bij de volgdende niet gebonden noot vorige uitvoeren
   105             if noot in tieBufDur: # bij de volgdende niet gebonden noot vorige uitvoeren
   105                 noten.append ((tieBufTijd [noot], noot, tieBufDur[noot]))
   106                 noten.append ((tieBufTijd [noot], noot, tieBufDur[noot]))
   106             tieBufTijd [noot] = tijd # alle noten vast houden voor evt. volgende tie
   107             tieBufTijd [noot] = tijd # alle noten vast houden voor evt. volgende tie
   107             tieBufDur [noot] = dur
   108             tieBufDur [noot] = dur
   108     for noot, dur in tieBufDur.iteritems (): # alle vastgehouden noten nu uitvoeren
   109     for noot, dur in tieBufDur.items (): # alle vastgehouden noten nu uitvoeren
   109         noten.append ((tieBufTijd[noot], noot, dur))
   110         noten.append ((tieBufTijd[noot], noot, dur))
   110 
   111 
   111 def outVoices (vceCnt):         # output alle stemmen in een part, nummering begint bij vceCnt
   112 def outVoices (vceCnt):         # output alle stemmen in een part, nummering begint bij vceCnt
   112     global tijd, gMaten, voices, vtimes, tupcnt, maxVoice, noten
   113     global tijd, gMaten, voices, vtimes, tupcnt, maxVoice, noten
   113     ns = []
   114     ns = []
   142     parts = e.findall ('part')
   143     parts = e.findall ('part')
   143     noten = []      # de uitvoer van alle noten
   144     noten = []      # de uitvoer van alle noten
   144     for p in parts:
   145     for p in parts:
   145         maten = p.findall ('measure')
   146         maten = p.findall ('measure')
   146         for maat in maten:
   147         for maat in maten:
   147             es = maat.getchildren ()
   148             es = list (maat) # alle kinderen van maat
   148             for e in es:
   149             for e in es:
   149                 if e.tag == 'note': doNote (e)
   150                 if e.tag == 'note': doNote (e)
   150                 elif e.tag == 'attributes': doAttr (e)
   151                 elif e.tag == 'attributes': doAttr (e)
   151                 elif e.tag == 'backup':
   152                 elif e.tag == 'backup':
   152                     dt = int (e.findtext ('duration'))
   153                     dt = int (e.findtext ('duration'))
   167     return noten
   168     return noten
   168 
   169 
   169 
   170 
   170 if __name__ == '__main__':
   171 if __name__ == '__main__':
   171     from optparse import OptionParser
   172     from optparse import OptionParser
   172     parser = OptionParser (usage='%prog [-h] [-g TPQ] [--C5] <file1>')
   173     parser = OptionParser (usage='%prog [-h] [-t TPQ] [--C5] [-w] <file1>')
   173     parser.add_option ("-t", action="store", type="int", help="ticks per quarternote", default=120, metavar='TPQ')
   174     parser.add_option ("-t", action="store", type="int", help="ticks per quarternote", default=120, metavar='TPQ')
   174     parser.add_option ("--C5", action="store_true", help="central C is C5", default=False)
   175     parser.add_option ("--C5", action="store_true", help="central C is C5", default=False)
   175     parser.add_option ("-w", action="store_true", help="write .b40 file", default=False)
   176     parser.add_option ("-w", action="store_true", help="write .b40 file", default=False)
   176     options, args = parser.parse_args ()
   177     options, args = parser.parse_args ()
   177     if len (args) < 1: parser.error ('file argument needed')
   178     if len (args) < 1: parser.error ('file argument needed')
   182     xml2b40 (fnmext, options.t, options.C5)
   183     xml2b40 (fnmext, options.t, options.C5)
   183     if options.w:
   184     if options.w:
   184         g = file (fnm + '.b40', 'w')
   185         g = file (fnm + '.b40', 'w')
   185         for tijd, noot in noten: g.write ('%d %s\n' % (tijd, noot))
   186         for tijd, noot in noten: g.write ('%d %s\n' % (tijd, noot))
   186         g.close ()
   187         g.close ()
   187         print fnm + '.b40 written'
   188         print(fnm + '.b40 written')
   188     else:
   189     else:
   189         for tijd, noot in noten: print tijd, noot
   190         for tijd, noot in noten: print(tijd, noot)