comparison musiccutter.py @ 30:f46cc9401e79

Make transposition optional and add note scale parameter (to get rearticulation)
author Daniel O'Connor <darius@dons.net.au>
date Tue, 03 May 2016 09:10:33 +0930
parents 767ba8ec90e6
children ea98c9507f47 f053dd6e9e68
comparison
equal deleted inserted replaced
29:767ba8ec90e6 30:f46cc9401e79
17 if filename == None: 17 if filename == None:
18 filename = 'test.midi' 18 filename = 'test.midi'
19 # Card layout from http://www.orgues-de-barbarie.com/wp-content/uploads/2014/09/format-cartons.pdf 19 # Card layout from http://www.orgues-de-barbarie.com/wp-content/uploads/2014/09/format-cartons.pdf
20 # Notes are read from right to left 20 # Notes are read from right to left
21 # Highest note is at the bottom (closest to the crank) 21 # Highest note is at the bottom (closest to the crank)
22 m = Midi2PDF('notes', 120, 155, 5.5, 3.3, 6.0, 50, False, False, False, False, 0, 10, 'Helvetica', 12) 22 m = Midi2PDF('notes', 120, 155, 5.5, 3.3, 6.0, 50, False, False, False, False, False, 0, 30, 0.9, 'Helvetica', 12)
23 base, ext = os.path.splitext(filename) 23 base, ext = os.path.splitext(filename)
24 base = os.path.basename(base) 24 base = os.path.basename(base)
25 m.processMidi(filename, base + '-%02d.pdf') 25 m.processMidi(filename, base + '-%02d.pdf')
26 26
27 class Midi2PDF(object): 27 class Midi2PDF(object):
28 def __init__(self, notefile, pagewidth, pageheight, pitch, slotsize, heel, leadin, timemarks, drawrect, notenames, notelines, noteoffset, timescale, fontname, fontsize): 28 def __init__(self, notefile, pagewidth, pageheight, pitch, slotsize, heel, leadin, timemarks, trytranspose, drawrect, notenames, notelines, noteoffset, timescale, notescale, fontname, fontsize):
29 self.midi2note, self.note2midi = Midi2PDF.genmidi2note() 29 self.midi2note, self.note2midi = Midi2PDF.genmidi2note()
30 self.note2slot, self.slot2note = Midi2PDF.loadnote2slot(notefile, self.note2midi) 30 self.note2slot, self.slot2note = Midi2PDF.loadnote2slot(notefile, self.note2midi)
31 self.pagewidth = pagewidth # Dimensions are in millimetres 31 self.pagewidth = pagewidth # Dimensions are in millimetres
32 self.pageheight = pageheight 32 self.pageheight = pageheight
33 self.pitch = pitch # Distance between each slot 33 self.pitch = pitch # Distance between each slot
34 self.slotsize = slotsize # Size of each slot cut out 34 self.slotsize = slotsize # Size of each slot cut out
35 self.heel = heel # Bottom margin (from bottom of page to centre of slot) 35 self.heel = heel # Bottom margin (from bottom of page to centre of slot)
36 self.leadin = leadin # Extra at the start 36 self.leadin = leadin # Extra at the start
37 self.timemarks = timemarks # Draw vertical time lines 37 self.timemarks = timemarks # Draw vertical time lines
38 self.trytranspose = trytranspose # Attempt to tranpose unplayable notes
38 self.drawrect = drawrect # Draw rectangle around each page 39 self.drawrect = drawrect # Draw rectangle around each page
39 self.notenames = notenames # Draw note names on the right edge 40 self.notenames = notenames # Draw note names on the right edge
40 self.notelines = notelines # Draw line rulers 41 self.notelines = notelines # Draw line rulers
41 self.noteoffset = noteoffset # Amount to adjust note pitches by (+12 = 1 octave) 42 self.noteoffset = noteoffset # Amount to adjust note pitches by (+12 = 1 octave)
42 self.timescale = timescale # Width per second 43 self.timescale = timescale # Width per second
44 self.notescale = notescale # Multiply all note lengths by this (to get rearticulation)
43 self.fontname = fontname 45 self.fontname = fontname
44 self.fontsize = fontsize # Points 46 self.fontsize = fontsize # Points
45 47
46 def processMidi(self, midifile, outpat): 48 def processMidi(self, midifile, outpat):
47 playablecount = 0 49 playablecount = 0
92 notelen = ctime - start 94 notelen = ctime - start
93 playable = True 95 playable = True
94 96
95 if note in self.note2slot: 97 if note in self.note2slot:
96 slot = self.note2slot[note] 98 slot = self.note2slot[note]
97 elif ev.note - 12 in self.midi2note and self.note2slot[self.midi2note[ev.note - 12]]: 99 elif self.trytranspose and (ev.note - 12 in self.midi2note and self.note2slot[self.midi2note[ev.note - 12]]):
98 print 'Transposing note %d (%s) down' % (ev.note, note) 100 print 'Transposing note %d (%s) down' % (ev.note, note)
99 slot = self.note2slot[self.midi2note[ev.note - 12]] 101 slot = self.note2slot[self.midi2note[ev.note - 12]]
100 transposedowncount += 1 102 transposedowncount += 1
101 elif ev.note + 12 in self.midi2note and self.note2slot[self.midi2note[ev.note + 12]]: 103 elif self.trytranspose and (ev.note + 12 in self.midi2note and self.note2slot[self.midi2note[ev.note + 12]]):
102 print 'Transposing note %d (%s) up' % (ev.note, note) 104 print 'Transposing note %d (%s) up' % (ev.note, note)
103 slot = self.note2slot[self.midi2note[ev.note + 12]] 105 slot = self.note2slot[self.midi2note[ev.note + 12]]
104 transposeupcount += 1 106 transposeupcount += 1
105 else: 107 else:
106 unplayablecount += 1 108 unplayablecount += 1
107 playable = False 109 playable = False
108 110
109 if playable: 111 if playable:
110 #print 'Note %s (%d) at %.2f length %.2f' % (note, slot, start, notelen) 112 #print 'Note %s (%d) at %.2f length %.2f' % (note, slot, start, notelen)
111 self.emitnote(pdfs, slot, start, notelen) 113 self.emitnote(pdfs, slot, start, notelen * self.notescale)
112 playablecount += 1 114 playablecount += 1
113 115
114 del channels[ev.channel][ev.note] 116 del channels[ev.channel][ev.note]
115 elif ev.type == 'end_of_track': 117 elif ev.type == 'end_of_track':
116 print 'EOT, not flushing, check for missed notes' 118 print 'EOT, not flushing, check for missed notes'
118 for ev in chan: 120 for ev in chan:
119 print ev 121 print ev
120 122
121 print 'Playable count:', playablecount 123 print 'Playable count:', playablecount
122 print 'Unplayable count:', unplayablecount 124 print 'Unplayable count:', unplayablecount
123 print 'Transpose down:', transposedowncount 125 if self.trytranspose:
124 print 'Transpose up:', transposeupcount 126 print 'Transpose down:', transposedowncount
127 print 'Transpose up:', transposeupcount
125 128
126 for pindx in range(len(pdfs)): 129 for pindx in range(len(pdfs)):
127 pdf = pdfs[pindx] 130 pdf = pdfs[pindx]
128 # Add title and page number 131 # Add title and page number
129 Midi2PDF.textHelper(pdf, 0 * mm, 1 * mm, ENGRAVE_COLOUR, True, self.fontname, self.fontsize, '%s (%d / %d)' % (title, pindx + 1, npages)) 132 Midi2PDF.textHelper(pdf, 0 * mm, 1 * mm, ENGRAVE_COLOUR, True, self.fontname, self.fontsize, '%s (%d / %d)' % (title, pindx + 1, npages))