Mercurial > ~darius > hgwebdir.cgi > musiccutter
comparison musiccutter.py @ 21:c710c4c3f44f
Add pitch offset (number of midi notes to move up/down)
author | Daniel O'Connor <darius@dons.net.au> |
---|---|
date | Fri, 29 Apr 2016 15:57:32 +0930 |
parents | 9bb72ae63651 |
children | 65e8298f5800 |
comparison
equal
deleted
inserted
replaced
20:9bb72ae63651 | 21:c710c4c3f44f |
---|---|
16 def test(filename = None): | 16 def test(filename = None): |
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 m = Midi2PDF('notes', 120, 155, 5.5, 3.0, 6.0, 50, False, False, False, False, 10, 'Helvetica', 12) | 21 m = Midi2PDF('notes', 120, 155, 5.5, 3.0, 6.0, 50, False, False, False, False, 12, 10, 'Helvetica', 12) |
22 base, ext = os.path.splitext(filename) | 22 base, ext = os.path.splitext(filename) |
23 m.processMidi(filename, base + '-%02d.pdf') | 23 m.processMidi(filename, base + '-%02d.pdf') |
24 | 24 |
25 class Midi2PDF(object): | 25 class Midi2PDF(object): |
26 def __init__(self, notefile, pagewidth, pageheight, pitch, slotsize, offset, leadin, timemarks, drawrect, notenames, notelines, timescale, fontname, fontsize): | 26 def __init__(self, notefile, pagewidth, pageheight, pitch, slotsize, offset, leadin, timemarks, drawrect, notenames, notelines, noteoffset, timescale, fontname, fontsize): |
27 self.midi2note, self.note2midi = Midi2PDF.genmidi2note() | 27 self.midi2note, self.note2midi = Midi2PDF.genmidi2note(noteoffset) |
28 self.note2slot, self.slot2note = Midi2PDF.loadnote2slot(notefile, self.note2midi) | 28 self.note2slot, self.slot2note = Midi2PDF.loadnote2slot(notefile, self.note2midi) |
29 self.pagewidth = pagewidth # Dimensions are in millimetres | 29 self.pagewidth = pagewidth # Dimensions are in millimetres |
30 self.pageheight = pageheight | 30 self.pageheight = pageheight |
31 self.pitch = pitch # Distance between each slot | 31 self.pitch = pitch # Distance between each slot |
32 self.slotsize = slotsize # Size of each slot cut out | 32 self.slotsize = slotsize # Size of each slot cut out |
73 elif ev.type == 'note_off' or (ev.type == 'note_on' and ev.velocity == 0): | 73 elif ev.type == 'note_off' or (ev.type == 'note_on' and ev.velocity == 0): |
74 if ev.note not in channels[ev.channel]: | 74 if ev.note not in channels[ev.channel]: |
75 print 'note_off with no corresponding note_on for channel %d note %d' % (ev.channel, ev.note) | 75 print 'note_off with no corresponding note_on for channel %d note %d' % (ev.channel, ev.note) |
76 else: | 76 else: |
77 if note not in self.note2slot: | 77 if note not in self.note2slot: |
78 print 'Skipping unplayable note %s' % (note) | 78 print 'Skipping unplayable note %d (%s)' % (ev.note, note) |
79 unplayablecount += 1 | 79 unplayablecount += 1 |
80 else: | 80 else: |
81 start = channels[ev.channel][ev.note] | 81 start = channels[ev.channel][ev.note] |
82 notelen = ctime - start | 82 notelen = ctime - start |
83 slot = self.note2slot[note] | 83 slot = self.note2slot[note] |
133 Midi2PDF.textHelper(pdf, (self.pagewidth - 10) * mm, ofs + 1 * mm, ENGRAVE_COLOUR, False, self.fontname, self.fontsize, self.slot2note[slot]) | 133 Midi2PDF.textHelper(pdf, (self.pagewidth - 10) * mm, ofs + 1 * mm, ENGRAVE_COLOUR, False, self.fontname, self.fontsize, self.slot2note[slot]) |
134 pdf.save() | 134 pdf.save() |
135 | 135 |
136 # http://newt.phys.unsw.edu.au/jw/notes.html | 136 # http://newt.phys.unsw.edu.au/jw/notes.html |
137 @staticmethod | 137 @staticmethod |
138 def genmidi2note(): | 138 def genmidi2note(offset): |
139 '''Create forward & reverse tables for midi number to note name (assuming 69 = A4 = A440)''' | 139 '''Create forward & reverse tables for midi number to note name (assuming 69 = A4 = A440) |
140 offset is amount to shift notes (+12 = +1 octave)''' | |
140 names = ['C%d', 'C%d#', 'D%d', 'D%d#', 'E%d', 'F%d', 'F%d#', 'G%d', 'G%d#', 'A%d', 'A%d#', 'B%d'] | 141 names = ['C%d', 'C%d#', 'D%d', 'D%d#', 'E%d', 'F%d', 'F%d#', 'G%d', 'G%d#', 'A%d', 'A%d#', 'B%d'] |
141 midi2note = {} | 142 midi2note = {} |
142 note2midi = {} | 143 note2midi = {} |
143 for midi in range(21, 128): | 144 for midi in range(21, 128): |
144 octave = midi / len(names) - 1 | 145 octave = midi / len(names) - 1 |
145 index = midi % len(names) | 146 index = midi % len(names) |
146 name = names[index] % (octave) | 147 name = names[index] % (octave) |
147 midi2note[midi] = name | 148 midi2note[midi - offset] = name |
148 note2midi[name] = midi | 149 note2midi[name] = midi - offset |
149 | 150 |
150 return midi2note, note2midi | 151 return midi2note, note2midi |
151 | 152 |
152 @staticmethod | 153 @staticmethod |
153 def loadnote2slot(fname, note2midi): | 154 def loadnote2slot(fname, note2midi): |