annotate musiccutter.py @ 38:9e8ed92b477c

Re-jig note translation to only happen when we are going to emit a note. This fixes "note_off with no note_on" cases (iWriteMusic likes to emit these for rests). This means some messages have untransposed notes but we draw the line because they only have to be transposed because of limitations in the organ so before that they are are untransposed (except for the bulk adjustment)
author Daniel O'Connor <darius@dons.net.au>
date Mon, 23 May 2016 22:35:44 +0930
parents c490fecec0ef
children 86622ba474e4
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
0773354c7428 Initial commit, WIP.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
1 #!/usr/bin/env python
0773354c7428 Initial commit, WIP.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
2
37
c490fecec0ef Have another crack at fixing transposition.
Daniel O'Connor <darius@dons.net.au>
parents: 36
diff changeset
3 from IPython.core.debugger import Tracer
0
0773354c7428 Initial commit, WIP.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
4 import exceptions
4
9f4fa5f231e6 Rework to use mido iterator and paginate.
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
5 import itertools
7
31db42ce72b8 Rework to be class-y
Daniel O'Connor <darius@dons.net.au>
parents: 5
diff changeset
6 import math
0
0773354c7428 Initial commit, WIP.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
7 import mido
22
65e8298f5800 Remove extension and path name from title.
Daniel O'Connor <darius@dons.net.au>
parents: 21
diff changeset
8 import os.path
11
9faad813e39e switch to PDF to avoid dealing with CorelDraw crashing
Daniel O'Connor <darius@dons.net.au>
parents: 9
diff changeset
9 import reportlab.lib.colors
12
6e46ceee57a7 Use correct MIDI note generation, previous version did not agree with
Daniel O'Connor <darius@dons.net.au>
parents: 11
diff changeset
10 import reportlab.pdfgen.canvas
11
9faad813e39e switch to PDF to avoid dealing with CorelDraw crashing
Daniel O'Connor <darius@dons.net.au>
parents: 9
diff changeset
11 from reportlab.lib.units import mm
0
0773354c7428 Initial commit, WIP.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
12 import sys
0773354c7428 Initial commit, WIP.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
13
11
9faad813e39e switch to PDF to avoid dealing with CorelDraw crashing
Daniel O'Connor <darius@dons.net.au>
parents: 9
diff changeset
14 CUT_COLOUR = reportlab.lib.colors.red
9faad813e39e switch to PDF to avoid dealing with CorelDraw crashing
Daniel O'Connor <darius@dons.net.au>
parents: 9
diff changeset
15 ENGRAVE_COLOUR = reportlab.lib.colors.black
9faad813e39e switch to PDF to avoid dealing with CorelDraw crashing
Daniel O'Connor <darius@dons.net.au>
parents: 9
diff changeset
16
37
c490fecec0ef Have another crack at fixing transposition.
Daniel O'Connor <darius@dons.net.au>
parents: 36
diff changeset
17 class Stats(object):
c490fecec0ef Have another crack at fixing transposition.
Daniel O'Connor <darius@dons.net.au>
parents: 36
diff changeset
18 pass
c490fecec0ef Have another crack at fixing transposition.
Daniel O'Connor <darius@dons.net.au>
parents: 36
diff changeset
19
c490fecec0ef Have another crack at fixing transposition.
Daniel O'Connor <darius@dons.net.au>
parents: 36
diff changeset
20 class EVWrap(object):
c490fecec0ef Have another crack at fixing transposition.
Daniel O'Connor <darius@dons.net.au>
parents: 36
diff changeset
21 def __init__(self, ev):
c490fecec0ef Have another crack at fixing transposition.
Daniel O'Connor <darius@dons.net.au>
parents: 36
diff changeset
22 self.ev = ev
c490fecec0ef Have another crack at fixing transposition.
Daniel O'Connor <darius@dons.net.au>
parents: 36
diff changeset
23
c490fecec0ef Have another crack at fixing transposition.
Daniel O'Connor <darius@dons.net.au>
parents: 36
diff changeset
24 def test(filename = None, shift = 0):
3
49a33c431b45 Accept filename for test function
Daniel O'Connor <darius@dons.net.au>
parents: 2
diff changeset
25 if filename == None:
49a33c431b45 Accept filename for test function
Daniel O'Connor <darius@dons.net.au>
parents: 2
diff changeset
26 filename = 'test.midi'
7
31db42ce72b8 Rework to be class-y
Daniel O'Connor <darius@dons.net.au>
parents: 5
diff changeset
27 # Card layout from http://www.orgues-de-barbarie.com/wp-content/uploads/2014/09/format-cartons.pdf
19
ffaf97818ce3 - Music needs to run right to left.
Daniel O'Connor <darius@dons.net.au>
parents: 18
diff changeset
28 # Notes are read from right to left
24
71b78f06ff03 Highest notes are at the bottom not the top.
Daniel O'Connor <darius@dons.net.au>
parents: 23
diff changeset
29 # Highest note is at the bottom (closest to the crank)
32
f053dd6e9e68 Add l33t ASCII diagram to show how folds should be
Daniel O'Connor <darius@dons.net.au>
parents: 30
diff changeset
30 # fold fold
f053dd6e9e68 Add l33t ASCII diagram to show how folds should be
Daniel O'Connor <darius@dons.net.au>
parents: 30
diff changeset
31 # in out
f053dd6e9e68 Add l33t ASCII diagram to show how folds should be
Daniel O'Connor <darius@dons.net.au>
parents: 30
diff changeset
32 # V ^
f053dd6e9e68 Add l33t ASCII diagram to show how folds should be
Daniel O'Connor <darius@dons.net.au>
parents: 30
diff changeset
33 # +---+---+---+ lowest note
f053dd6e9e68 Add l33t ASCII diagram to show how folds should be
Daniel O'Connor <darius@dons.net.au>
parents: 30
diff changeset
34 # | | | |
f053dd6e9e68 Add l33t ASCII diagram to show how folds should be
Daniel O'Connor <darius@dons.net.au>
parents: 30
diff changeset
35 # +---+---+---+ highest note
f053dd6e9e68 Add l33t ASCII diagram to show how folds should be
Daniel O'Connor <darius@dons.net.au>
parents: 30
diff changeset
36 #
37
c490fecec0ef Have another crack at fixing transposition.
Daniel O'Connor <darius@dons.net.au>
parents: 36
diff changeset
37 m = Midi2PDF('notes', 120, 155, 5.5, 3.3, 6.0, 50, False, True, False, False, False, shift, 1, 30, 0.9, 'Helvetica', 12)
11
9faad813e39e switch to PDF to avoid dealing with CorelDraw crashing
Daniel O'Connor <darius@dons.net.au>
parents: 9
diff changeset
38 base, ext = os.path.splitext(filename)
22
65e8298f5800 Remove extension and path name from title.
Daniel O'Connor <darius@dons.net.au>
parents: 21
diff changeset
39 base = os.path.basename(base)
11
9faad813e39e switch to PDF to avoid dealing with CorelDraw crashing
Daniel O'Connor <darius@dons.net.au>
parents: 9
diff changeset
40 m.processMidi(filename, base + '-%02d.pdf')
0
0773354c7428 Initial commit, WIP.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
41
11
9faad813e39e switch to PDF to avoid dealing with CorelDraw crashing
Daniel O'Connor <darius@dons.net.au>
parents: 9
diff changeset
42 class Midi2PDF(object):
31
ea98c9507f47 Preliminary multi-page support. Breaks time marks though.
Daniel O'Connor <darius@dons.net.au>
parents: 30
diff changeset
43 def __init__(self, notefile, pagewidth, pageheight, pitch, slotsize, heel, leadin, timemarks, trytranspose, drawrect, notenames, notelines, noteoffset, pagesperpdf, timescale, notescale, fontname, fontsize):
27
87cf66e04ef9 Handle offsetting note pitch in a better way.
Daniel O'Connor <darius@dons.net.au>
parents: 26
diff changeset
44 self.midi2note, self.note2midi = Midi2PDF.genmidi2note()
13
5f4c21bb5140 Add lines and notes engraved on the paper.
Daniel O'Connor <darius@dons.net.au>
parents: 12
diff changeset
45 self.note2slot, self.slot2note = Midi2PDF.loadnote2slot(notefile, self.note2midi)
11
9faad813e39e switch to PDF to avoid dealing with CorelDraw crashing
Daniel O'Connor <darius@dons.net.au>
parents: 9
diff changeset
46 self.pagewidth = pagewidth # Dimensions are in millimetres
7
31db42ce72b8 Rework to be class-y
Daniel O'Connor <darius@dons.net.au>
parents: 5
diff changeset
47 self.pageheight = pageheight
13
5f4c21bb5140 Add lines and notes engraved on the paper.
Daniel O'Connor <darius@dons.net.au>
parents: 12
diff changeset
48 self.pitch = pitch # Distance between each slot
16
20337b22977d Add left margin and slot size support.
Daniel O'Connor <darius@dons.net.au>
parents: 14
diff changeset
49 self.slotsize = slotsize # Size of each slot cut out
24
71b78f06ff03 Highest notes are at the bottom not the top.
Daniel O'Connor <darius@dons.net.au>
parents: 23
diff changeset
50 self.heel = heel # Bottom margin (from bottom of page to centre of slot)
19
ffaf97818ce3 - Music needs to run right to left.
Daniel O'Connor <darius@dons.net.au>
parents: 18
diff changeset
51 self.leadin = leadin # Extra at the start
ffaf97818ce3 - Music needs to run right to left.
Daniel O'Connor <darius@dons.net.au>
parents: 18
diff changeset
52 self.timemarks = timemarks # Draw vertical time lines
30
f46cc9401e79 Make transposition optional and add note scale parameter (to get rearticulation)
Daniel O'Connor <darius@dons.net.au>
parents: 29
diff changeset
53 self.trytranspose = trytranspose # Attempt to tranpose unplayable notes
19
ffaf97818ce3 - Music needs to run right to left.
Daniel O'Connor <darius@dons.net.au>
parents: 18
diff changeset
54 self.drawrect = drawrect # Draw rectangle around each page
20
9bb72ae63651 - Make various things optional.
Daniel O'Connor <darius@dons.net.au>
parents: 19
diff changeset
55 self.notenames = notenames # Draw note names on the right edge
9bb72ae63651 - Make various things optional.
Daniel O'Connor <darius@dons.net.au>
parents: 19
diff changeset
56 self.notelines = notelines # Draw line rulers
27
87cf66e04ef9 Handle offsetting note pitch in a better way.
Daniel O'Connor <darius@dons.net.au>
parents: 26
diff changeset
57 self.noteoffset = noteoffset # Amount to adjust note pitches by (+12 = 1 octave)
31
ea98c9507f47 Preliminary multi-page support. Breaks time marks though.
Daniel O'Connor <darius@dons.net.au>
parents: 30
diff changeset
58 self.pagesperpdf = pagesperpdf # Number of pages to emit per PDF
16
20337b22977d Add left margin and slot size support.
Daniel O'Connor <darius@dons.net.au>
parents: 14
diff changeset
59 self.timescale = timescale # Width per second
30
f46cc9401e79 Make transposition optional and add note scale parameter (to get rearticulation)
Daniel O'Connor <darius@dons.net.au>
parents: 29
diff changeset
60 self.notescale = notescale # Multiply all note lengths by this (to get rearticulation)
11
9faad813e39e switch to PDF to avoid dealing with CorelDraw crashing
Daniel O'Connor <darius@dons.net.au>
parents: 9
diff changeset
61 self.fontname = fontname
16
20337b22977d Add left margin and slot size support.
Daniel O'Connor <darius@dons.net.au>
parents: 14
diff changeset
62 self.fontsize = fontsize # Points
0
0773354c7428 Initial commit, WIP.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
63
31
ea98c9507f47 Preliminary multi-page support. Breaks time marks though.
Daniel O'Connor <darius@dons.net.au>
parents: 30
diff changeset
64 self.pdfwidth = self.pagewidth * self.pagesperpdf
ea98c9507f47 Preliminary multi-page support. Breaks time marks though.
Daniel O'Connor <darius@dons.net.au>
parents: 30
diff changeset
65
7
31db42ce72b8 Rework to be class-y
Daniel O'Connor <darius@dons.net.au>
parents: 5
diff changeset
66 def processMidi(self, midifile, outpat):
37
c490fecec0ef Have another crack at fixing transposition.
Daniel O'Connor <darius@dons.net.au>
parents: 36
diff changeset
67 stats = Stats()
c490fecec0ef Have another crack at fixing transposition.
Daniel O'Connor <darius@dons.net.au>
parents: 36
diff changeset
68 stats.playablecount = 0
c490fecec0ef Have another crack at fixing transposition.
Daniel O'Connor <darius@dons.net.au>
parents: 36
diff changeset
69 stats.unplayablecount = 0
c490fecec0ef Have another crack at fixing transposition.
Daniel O'Connor <darius@dons.net.au>
parents: 36
diff changeset
70 stats.transposeupcount = 0
c490fecec0ef Have another crack at fixing transposition.
Daniel O'Connor <darius@dons.net.au>
parents: 36
diff changeset
71 stats.transposedowncount = 0
7
31db42ce72b8 Rework to be class-y
Daniel O'Connor <darius@dons.net.au>
parents: 5
diff changeset
72 midi = mido.MidiFile(midifile)
31db42ce72b8 Rework to be class-y
Daniel O'Connor <darius@dons.net.au>
parents: 5
diff changeset
73 ctime = 0
31db42ce72b8 Rework to be class-y
Daniel O'Connor <darius@dons.net.au>
parents: 5
diff changeset
74 channels = []
31db42ce72b8 Rework to be class-y
Daniel O'Connor <darius@dons.net.au>
parents: 5
diff changeset
75 for i in range(16):
31db42ce72b8 Rework to be class-y
Daniel O'Connor <darius@dons.net.au>
parents: 5
diff changeset
76 channels.append({})
0
0773354c7428 Initial commit, WIP.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
77
19
ffaf97818ce3 - Music needs to run right to left.
Daniel O'Connor <darius@dons.net.au>
parents: 18
diff changeset
78 npages = int(math.ceil(((midi.length * self.timescale) + self.leadin) / self.pagewidth))
31
ea98c9507f47 Preliminary multi-page support. Breaks time marks though.
Daniel O'Connor <darius@dons.net.au>
parents: 30
diff changeset
79 npdfs = int(math.ceil(float(npages) / self.pagesperpdf))
ea98c9507f47 Preliminary multi-page support. Breaks time marks though.
Daniel O'Connor <darius@dons.net.au>
parents: 30
diff changeset
80 print 'npages %d, npdfs %d' % (npages, npdfs)
ea98c9507f47 Preliminary multi-page support. Breaks time marks though.
Daniel O'Connor <darius@dons.net.au>
parents: 30
diff changeset
81
11
9faad813e39e switch to PDF to avoid dealing with CorelDraw crashing
Daniel O'Connor <darius@dons.net.au>
parents: 9
diff changeset
82 pdfs = []
31
ea98c9507f47 Preliminary multi-page support. Breaks time marks though.
Daniel O'Connor <darius@dons.net.au>
parents: 30
diff changeset
83 for i in range(npdfs):
ea98c9507f47 Preliminary multi-page support. Breaks time marks though.
Daniel O'Connor <darius@dons.net.au>
parents: 30
diff changeset
84 pdf = reportlab.pdfgen.canvas.Canvas(file(outpat % (i + 1), 'w'),
ea98c9507f47 Preliminary multi-page support. Breaks time marks though.
Daniel O'Connor <darius@dons.net.au>
parents: 30
diff changeset
85 pagesize = (self.pdfwidth * mm, self.pageheight * mm))
11
9faad813e39e switch to PDF to avoid dealing with CorelDraw crashing
Daniel O'Connor <darius@dons.net.au>
parents: 9
diff changeset
86 pdfs.append(pdf)
0
0773354c7428 Initial commit, WIP.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
87
22
65e8298f5800 Remove extension and path name from title.
Daniel O'Connor <darius@dons.net.au>
parents: 21
diff changeset
88 title = os.path.basename(midifile)
65e8298f5800 Remove extension and path name from title.
Daniel O'Connor <darius@dons.net.au>
parents: 21
diff changeset
89 title, ext = os.path.splitext(title)
7
31db42ce72b8 Rework to be class-y
Daniel O'Connor <darius@dons.net.au>
parents: 5
diff changeset
90 for ev in midi:
38
9e8ed92b477c Re-jig note translation to only happen when we are going to emit a
Daniel O'Connor <darius@dons.net.au>
parents: 37
diff changeset
91 # Adjust pitch
9e8ed92b477c Re-jig note translation to only happen when we are going to emit a
Daniel O'Connor <darius@dons.net.au>
parents: 37
diff changeset
92 if hasattr(ev, 'note'):
9e8ed92b477c Re-jig note translation to only happen when we are going to emit a
Daniel O'Connor <darius@dons.net.au>
parents: 37
diff changeset
93 ev.note += self.noteoffset
9e8ed92b477c Re-jig note translation to only happen when we are going to emit a
Daniel O'Connor <darius@dons.net.au>
parents: 37
diff changeset
94 ctime += ev.time
9e8ed92b477c Re-jig note translation to only happen when we are going to emit a
Daniel O'Connor <darius@dons.net.au>
parents: 37
diff changeset
95 #print ctime, ev
9e8ed92b477c Re-jig note translation to only happen when we are going to emit a
Daniel O'Connor <darius@dons.net.au>
parents: 37
diff changeset
96 #Tracer()()
11
9faad813e39e switch to PDF to avoid dealing with CorelDraw crashing
Daniel O'Connor <darius@dons.net.au>
parents: 9
diff changeset
97
38
9e8ed92b477c Re-jig note translation to only happen when we are going to emit a
Daniel O'Connor <darius@dons.net.au>
parents: 37
diff changeset
98 if ev.type == 'text' and ctime == 0:
9e8ed92b477c Re-jig note translation to only happen when we are going to emit a
Daniel O'Connor <darius@dons.net.au>
parents: 37
diff changeset
99 title = ev.text
9e8ed92b477c Re-jig note translation to only happen when we are going to emit a
Daniel O'Connor <darius@dons.net.au>
parents: 37
diff changeset
100 if ev.type == 'note_on' and ev.velocity > 0:
9e8ed92b477c Re-jig note translation to only happen when we are going to emit a
Daniel O'Connor <darius@dons.net.au>
parents: 37
diff changeset
101 if ev.note in channels[ev.channel]:
9e8ed92b477c Re-jig note translation to only happen when we are going to emit a
Daniel O'Connor <darius@dons.net.au>
parents: 37
diff changeset
102 print 'Duplicate note_on message at %.1f sec channel %d note %d' % (ctime, ev.channel, ev.note)
9e8ed92b477c Re-jig note translation to only happen when we are going to emit a
Daniel O'Connor <darius@dons.net.au>
parents: 37
diff changeset
103 else:
9e8ed92b477c Re-jig note translation to only happen when we are going to emit a
Daniel O'Connor <darius@dons.net.au>
parents: 37
diff changeset
104 channels[ev.channel][ev.note] = ctime
9e8ed92b477c Re-jig note translation to only happen when we are going to emit a
Daniel O'Connor <darius@dons.net.au>
parents: 37
diff changeset
105 elif ev.type == 'note_off' or (ev.type == 'note_on' and ev.velocity == 0):
9e8ed92b477c Re-jig note translation to only happen when we are going to emit a
Daniel O'Connor <darius@dons.net.au>
parents: 37
diff changeset
106 if ev.note not in channels[ev.channel]:
9e8ed92b477c Re-jig note translation to only happen when we are going to emit a
Daniel O'Connor <darius@dons.net.au>
parents: 37
diff changeset
107 print 'note_off with no corresponding note_on at %.1f sec for channel %d note %d' % (ctime, ev.channel, ev.note)
9e8ed92b477c Re-jig note translation to only happen when we are going to emit a
Daniel O'Connor <darius@dons.net.au>
parents: 37
diff changeset
108 continue
0
0773354c7428 Initial commit, WIP.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
109 else:
38
9e8ed92b477c Re-jig note translation to only happen when we are going to emit a
Daniel O'Connor <darius@dons.net.au>
parents: 37
diff changeset
110 orignote = ev.note
9e8ed92b477c Re-jig note translation to only happen when we are going to emit a
Daniel O'Connor <darius@dons.net.au>
parents: 37
diff changeset
111 start = channels[ev.channel][orignote]
9e8ed92b477c Re-jig note translation to only happen when we are going to emit a
Daniel O'Connor <darius@dons.net.au>
parents: 37
diff changeset
112 evw = EVWrap(ev)
9e8ed92b477c Re-jig note translation to only happen when we are going to emit a
Daniel O'Connor <darius@dons.net.au>
parents: 37
diff changeset
113 # Find a slot (plus adjust pitch, attempt transposition etc)
9e8ed92b477c Re-jig note translation to only happen when we are going to emit a
Daniel O'Connor <darius@dons.net.au>
parents: 37
diff changeset
114 if hasattr(ev, 'note'):
9e8ed92b477c Re-jig note translation to only happen when we are going to emit a
Daniel O'Connor <darius@dons.net.au>
parents: 37
diff changeset
115 self.getslotfornote(evw, stats, ctime)
9e8ed92b477c Re-jig note translation to only happen when we are going to emit a
Daniel O'Connor <darius@dons.net.au>
parents: 37
diff changeset
116 # Check if it was unplayable
9e8ed92b477c Re-jig note translation to only happen when we are going to emit a
Daniel O'Connor <darius@dons.net.au>
parents: 37
diff changeset
117 if not evw.slot:
9e8ed92b477c Re-jig note translation to only happen when we are going to emit a
Daniel O'Connor <darius@dons.net.au>
parents: 37
diff changeset
118 continue
37
c490fecec0ef Have another crack at fixing transposition.
Daniel O'Connor <darius@dons.net.au>
parents: 36
diff changeset
119 notelen = ctime - start
38
9e8ed92b477c Re-jig note translation to only happen when we are going to emit a
Daniel O'Connor <darius@dons.net.au>
parents: 37
diff changeset
120 #print 'Note %s (%d) at %.2f length %.2f' % (evw.notename, ev.slot, start, notelen)
37
c490fecec0ef Have another crack at fixing transposition.
Daniel O'Connor <darius@dons.net.au>
parents: 36
diff changeset
121 self.emitnote(pdfs, evw.slot, start, notelen * self.notescale)
28
657bc32a0dfd Try transposing unplayable notes down or up an octave (in that order).
Daniel O'Connor <darius@dons.net.au>
parents: 27
diff changeset
122
38
9e8ed92b477c Re-jig note translation to only happen when we are going to emit a
Daniel O'Connor <darius@dons.net.au>
parents: 37
diff changeset
123 del channels[ev.channel][orignote]
9e8ed92b477c Re-jig note translation to only happen when we are going to emit a
Daniel O'Connor <darius@dons.net.au>
parents: 37
diff changeset
124 elif ev.type == 'end_of_track':
7
31db42ce72b8 Rework to be class-y
Daniel O'Connor <darius@dons.net.au>
parents: 5
diff changeset
125 print 'EOT, not flushing, check for missed notes'
31db42ce72b8 Rework to be class-y
Daniel O'Connor <darius@dons.net.au>
parents: 5
diff changeset
126 for chan in channels:
38
9e8ed92b477c Re-jig note translation to only happen when we are going to emit a
Daniel O'Connor <darius@dons.net.au>
parents: 37
diff changeset
127 for ev in chan:
9e8ed92b477c Re-jig note translation to only happen when we are going to emit a
Daniel O'Connor <darius@dons.net.au>
parents: 37
diff changeset
128 print ev
7
31db42ce72b8 Rework to be class-y
Daniel O'Connor <darius@dons.net.au>
parents: 5
diff changeset
129
37
c490fecec0ef Have another crack at fixing transposition.
Daniel O'Connor <darius@dons.net.au>
parents: 36
diff changeset
130 print 'Playable count:', stats.playablecount
c490fecec0ef Have another crack at fixing transposition.
Daniel O'Connor <darius@dons.net.au>
parents: 36
diff changeset
131 print 'Unplayable count:', stats.unplayablecount
30
f46cc9401e79 Make transposition optional and add note scale parameter (to get rearticulation)
Daniel O'Connor <darius@dons.net.au>
parents: 29
diff changeset
132 if self.trytranspose:
37
c490fecec0ef Have another crack at fixing transposition.
Daniel O'Connor <darius@dons.net.au>
parents: 36
diff changeset
133 print 'Transpose down:', stats.transposedowncount
c490fecec0ef Have another crack at fixing transposition.
Daniel O'Connor <darius@dons.net.au>
parents: 36
diff changeset
134 print 'Transpose up:', stats.transposeupcount
7
31db42ce72b8 Rework to be class-y
Daniel O'Connor <darius@dons.net.au>
parents: 5
diff changeset
135
31
ea98c9507f47 Preliminary multi-page support. Breaks time marks though.
Daniel O'Connor <darius@dons.net.au>
parents: 30
diff changeset
136 for pindx in range(npages):
ea98c9507f47 Preliminary multi-page support. Breaks time marks though.
Daniel O'Connor <darius@dons.net.au>
parents: 30
diff changeset
137 pdf = pdfs[pindx / self.pagesperpdf] # PDF for this page
ea98c9507f47 Preliminary multi-page support. Breaks time marks though.
Daniel O'Connor <darius@dons.net.au>
parents: 30
diff changeset
138 # Offset into PDF where the page starts
ea98c9507f47 Preliminary multi-page support. Breaks time marks though.
Daniel O'Connor <darius@dons.net.au>
parents: 30
diff changeset
139 pageofs = self.pagewidth * (self.pagesperpdf - (pindx % self.pagesperpdf) - 1)
13
5f4c21bb5140 Add lines and notes engraved on the paper.
Daniel O'Connor <darius@dons.net.au>
parents: 12
diff changeset
140 # Add title and page number
31
ea98c9507f47 Preliminary multi-page support. Breaks time marks though.
Daniel O'Connor <darius@dons.net.au>
parents: 30
diff changeset
141 Midi2PDF.textHelper(pdf, pageofs * mm, 1 * mm,
ea98c9507f47 Preliminary multi-page support. Breaks time marks though.
Daniel O'Connor <darius@dons.net.au>
parents: 30
diff changeset
142 ENGRAVE_COLOUR, True, self.fontname, self.fontsize,
ea98c9507f47 Preliminary multi-page support. Breaks time marks though.
Daniel O'Connor <darius@dons.net.au>
parents: 30
diff changeset
143 '%s (%d / %d)' % (title, pindx + 1, npages))
ea98c9507f47 Preliminary multi-page support. Breaks time marks though.
Daniel O'Connor <darius@dons.net.au>
parents: 30
diff changeset
144 pdf.saveState()
13
5f4c21bb5140 Add lines and notes engraved on the paper.
Daniel O'Connor <darius@dons.net.au>
parents: 12
diff changeset
145 pdf.setLineWidth(0)
17
c50427f1da2d - Draw vertical time lines.
Daniel O'Connor <darius@dons.net.au>
parents: 16
diff changeset
146
31
ea98c9507f47 Preliminary multi-page support. Breaks time marks though.
Daniel O'Connor <darius@dons.net.au>
parents: 30
diff changeset
147 # Draw time marks every 5 seconds
19
ffaf97818ce3 - Music needs to run right to left.
Daniel O'Connor <darius@dons.net.au>
parents: 18
diff changeset
148 if self.timemarks:
31
ea98c9507f47 Preliminary multi-page support. Breaks time marks though.
Daniel O'Connor <darius@dons.net.au>
parents: 30
diff changeset
149 pdfidx = pindx / self.pagesperpdf
ea98c9507f47 Preliminary multi-page support. Breaks time marks though.
Daniel O'Connor <darius@dons.net.au>
parents: 30
diff changeset
150 # Work out start and end times (pdf 1 is special due to leadin)
19
ffaf97818ce3 - Music needs to run right to left.
Daniel O'Connor <darius@dons.net.au>
parents: 18
diff changeset
151 tstart = self.leadin / self.timescale
31
ea98c9507f47 Preliminary multi-page support. Breaks time marks though.
Daniel O'Connor <darius@dons.net.au>
parents: 30
diff changeset
152 tend = (self.pagewidth * self.pagesperpdf) / self.timescale
18
cf93a76eda92 The laser cutter software barfs on these lines and stops processing
Daniel O'Connor <darius@dons.net.au>
parents: 17
diff changeset
153 if pindx > 0:
31
ea98c9507f47 Preliminary multi-page support. Breaks time marks though.
Daniel O'Connor <darius@dons.net.au>
parents: 30
diff changeset
154 tsize = self.pagewidth / self.timescale # Amount of time per pdf
ea98c9507f47 Preliminary multi-page support. Breaks time marks though.
Daniel O'Connor <darius@dons.net.au>
parents: 30
diff changeset
155 tstart = tend + tsize * pdfidx
ea98c9507f47 Preliminary multi-page support. Breaks time marks though.
Daniel O'Connor <darius@dons.net.au>
parents: 30
diff changeset
156 tend = tend + tsize * (pdfidx + 1)
18
cf93a76eda92 The laser cutter software barfs on these lines and stops processing
Daniel O'Connor <darius@dons.net.au>
parents: 17
diff changeset
157 for s in range(tstart, tend, 5):
19
ffaf97818ce3 - Music needs to run right to left.
Daniel O'Connor <darius@dons.net.au>
parents: 18
diff changeset
158 x = self.pagewidth - (float(s * self.timescale + self.leadin) % self.pagewidth)
24
71b78f06ff03 Highest notes are at the bottom not the top.
Daniel O'Connor <darius@dons.net.au>
parents: 23
diff changeset
159 pdf.line(x * mm, self.heel, x * mm, self.pageheight * mm)
18
cf93a76eda92 The laser cutter software barfs on these lines and stops processing
Daniel O'Connor <darius@dons.net.au>
parents: 17
diff changeset
160 Midi2PDF.textHelper(pdf, x * mm, 1 * mm, ENGRAVE_COLOUR, False, self.fontname, self.fontsize, str(s) + 's')
cf93a76eda92 The laser cutter software barfs on these lines and stops processing
Daniel O'Connor <darius@dons.net.au>
parents: 17
diff changeset
161
25
ce367392806c comment tweaks
Daniel O'Connor <darius@dons.net.au>
parents: 24
diff changeset
162 # Draw rectangle around page (upper and right hand ends don't seem to render though)
19
ffaf97818ce3 - Music needs to run right to left.
Daniel O'Connor <darius@dons.net.au>
parents: 18
diff changeset
163 if self.drawrect:
31
ea98c9507f47 Preliminary multi-page support. Breaks time marks though.
Daniel O'Connor <darius@dons.net.au>
parents: 30
diff changeset
164 pdf.rect((pindx % self.pagesperpdf) * self.pagewidth * mm, 0,
ea98c9507f47 Preliminary multi-page support. Breaks time marks though.
Daniel O'Connor <darius@dons.net.au>
parents: 30
diff changeset
165 self.pagewidth * mm, self.pageheight * mm, fill = False, stroke = True)
18
cf93a76eda92 The laser cutter software barfs on these lines and stops processing
Daniel O'Connor <darius@dons.net.au>
parents: 17
diff changeset
166
13
5f4c21bb5140 Add lines and notes engraved on the paper.
Daniel O'Connor <darius@dons.net.au>
parents: 12
diff changeset
167 # Draw lines per note
5f4c21bb5140 Add lines and notes engraved on the paper.
Daniel O'Connor <darius@dons.net.au>
parents: 12
diff changeset
168 for slot in sorted(self.slot2note.keys()):
26
f492b70f5e49 Fix notename/line drawing.
Daniel O'Connor <darius@dons.net.au>
parents: 25
diff changeset
169 ofs = self.pageheight - (self.heel + slot * self.pitch) - self.slotsize / 2
20
9bb72ae63651 - Make various things optional.
Daniel O'Connor <darius@dons.net.au>
parents: 19
diff changeset
170 if self.notelines:
31
ea98c9507f47 Preliminary multi-page support. Breaks time marks though.
Daniel O'Connor <darius@dons.net.au>
parents: 30
diff changeset
171 pdf.line(0, ofs * mm, self.pdfwidth * mm, ofs * mm)
13
5f4c21bb5140 Add lines and notes engraved on the paper.
Daniel O'Connor <darius@dons.net.au>
parents: 12
diff changeset
172 # Note name
20
9bb72ae63651 - Make various things optional.
Daniel O'Connor <darius@dons.net.au>
parents: 19
diff changeset
173 if self.notenames:
31
ea98c9507f47 Preliminary multi-page support. Breaks time marks though.
Daniel O'Connor <darius@dons.net.au>
parents: 30
diff changeset
174 Midi2PDF.textHelper(pdf, (self.pdfwidth - 10) * mm, (ofs + 0.5) * mm, ENGRAVE_COLOUR, False, self.fontname, self.fontsize, self.slot2note[slot])
ea98c9507f47 Preliminary multi-page support. Breaks time marks though.
Daniel O'Connor <darius@dons.net.au>
parents: 30
diff changeset
175 pdf.restoreState()
ea98c9507f47 Preliminary multi-page support. Breaks time marks though.
Daniel O'Connor <darius@dons.net.au>
parents: 30
diff changeset
176 for pdf in pdfs:
26
f492b70f5e49 Fix notename/line drawing.
Daniel O'Connor <darius@dons.net.au>
parents: 25
diff changeset
177 pdf.save()
7
31db42ce72b8 Rework to be class-y
Daniel O'Connor <darius@dons.net.au>
parents: 5
diff changeset
178
37
c490fecec0ef Have another crack at fixing transposition.
Daniel O'Connor <darius@dons.net.au>
parents: 36
diff changeset
179 def noteisplayable(self, midi):
c490fecec0ef Have another crack at fixing transposition.
Daniel O'Connor <darius@dons.net.au>
parents: 36
diff changeset
180 slot = None
c490fecec0ef Have another crack at fixing transposition.
Daniel O'Connor <darius@dons.net.au>
parents: 36
diff changeset
181 if midi in self.midi2note:
c490fecec0ef Have another crack at fixing transposition.
Daniel O'Connor <darius@dons.net.au>
parents: 36
diff changeset
182 notename = self.midi2note[midi]
c490fecec0ef Have another crack at fixing transposition.
Daniel O'Connor <darius@dons.net.au>
parents: 36
diff changeset
183 if notename in self.note2slot:
c490fecec0ef Have another crack at fixing transposition.
Daniel O'Connor <darius@dons.net.au>
parents: 36
diff changeset
184 slot = self.note2slot[notename]
c490fecec0ef Have another crack at fixing transposition.
Daniel O'Connor <darius@dons.net.au>
parents: 36
diff changeset
185
c490fecec0ef Have another crack at fixing transposition.
Daniel O'Connor <darius@dons.net.au>
parents: 36
diff changeset
186 return slot
c490fecec0ef Have another crack at fixing transposition.
Daniel O'Connor <darius@dons.net.au>
parents: 36
diff changeset
187
c490fecec0ef Have another crack at fixing transposition.
Daniel O'Connor <darius@dons.net.au>
parents: 36
diff changeset
188 def transposenote(self, evw, amount):
c490fecec0ef Have another crack at fixing transposition.
Daniel O'Connor <darius@dons.net.au>
parents: 36
diff changeset
189 evw.ev.note += amount
c490fecec0ef Have another crack at fixing transposition.
Daniel O'Connor <darius@dons.net.au>
parents: 36
diff changeset
190 evw.notename = self.midi2note[evw.ev.note]
c490fecec0ef Have another crack at fixing transposition.
Daniel O'Connor <darius@dons.net.au>
parents: 36
diff changeset
191 evw.slot = self.note2slot[evw.notename]
c490fecec0ef Have another crack at fixing transposition.
Daniel O'Connor <darius@dons.net.au>
parents: 36
diff changeset
192
c490fecec0ef Have another crack at fixing transposition.
Daniel O'Connor <darius@dons.net.au>
parents: 36
diff changeset
193 def getslotfornote(self, evw, stats, ctime):
c490fecec0ef Have another crack at fixing transposition.
Daniel O'Connor <darius@dons.net.au>
parents: 36
diff changeset
194 evw.slot = None
c490fecec0ef Have another crack at fixing transposition.
Daniel O'Connor <darius@dons.net.au>
parents: 36
diff changeset
195 evw.notename = None
c490fecec0ef Have another crack at fixing transposition.
Daniel O'Connor <darius@dons.net.au>
parents: 36
diff changeset
196
c490fecec0ef Have another crack at fixing transposition.
Daniel O'Connor <darius@dons.net.au>
parents: 36
diff changeset
197 # First off, is the note in our midi table?
c490fecec0ef Have another crack at fixing transposition.
Daniel O'Connor <darius@dons.net.au>
parents: 36
diff changeset
198 if evw.ev.note in self.midi2note:
c490fecec0ef Have another crack at fixing transposition.
Daniel O'Connor <darius@dons.net.au>
parents: 36
diff changeset
199 evw.notename = self.midi2note[evw.ev.note]
c490fecec0ef Have another crack at fixing transposition.
Daniel O'Connor <darius@dons.net.au>
parents: 36
diff changeset
200 # Is it playable?
c490fecec0ef Have another crack at fixing transposition.
Daniel O'Connor <darius@dons.net.au>
parents: 36
diff changeset
201 if self.noteisplayable(evw.ev.note) != None:
c490fecec0ef Have another crack at fixing transposition.
Daniel O'Connor <darius@dons.net.au>
parents: 36
diff changeset
202 evw.slot = self.note2slot[evw.notename]
c490fecec0ef Have another crack at fixing transposition.
Daniel O'Connor <darius@dons.net.au>
parents: 36
diff changeset
203 # Nope, maybe we can transpose?
c490fecec0ef Have another crack at fixing transposition.
Daniel O'Connor <darius@dons.net.au>
parents: 36
diff changeset
204 elif self.trytranspose:
c490fecec0ef Have another crack at fixing transposition.
Daniel O'Connor <darius@dons.net.au>
parents: 36
diff changeset
205 # Go for -3 to +3 octaves (going down first)
c490fecec0ef Have another crack at fixing transposition.
Daniel O'Connor <darius@dons.net.au>
parents: 36
diff changeset
206 for i in [-12, -24, -36, 12, 24, 36]:
c490fecec0ef Have another crack at fixing transposition.
Daniel O'Connor <darius@dons.net.au>
parents: 36
diff changeset
207 if self.noteisplayable(evw.ev.note + i) != None:
c490fecec0ef Have another crack at fixing transposition.
Daniel O'Connor <darius@dons.net.au>
parents: 36
diff changeset
208 self.transposenote(evw, i)
c490fecec0ef Have another crack at fixing transposition.
Daniel O'Connor <darius@dons.net.au>
parents: 36
diff changeset
209 if i < 0:
c490fecec0ef Have another crack at fixing transposition.
Daniel O'Connor <darius@dons.net.au>
parents: 36
diff changeset
210 stats.transposedowncount += 1
c490fecec0ef Have another crack at fixing transposition.
Daniel O'Connor <darius@dons.net.au>
parents: 36
diff changeset
211 tmp = 'down'
c490fecec0ef Have another crack at fixing transposition.
Daniel O'Connor <darius@dons.net.au>
parents: 36
diff changeset
212 else:
c490fecec0ef Have another crack at fixing transposition.
Daniel O'Connor <darius@dons.net.au>
parents: 36
diff changeset
213 stats.transposeupcount += 1
c490fecec0ef Have another crack at fixing transposition.
Daniel O'Connor <darius@dons.net.au>
parents: 36
diff changeset
214 tmp = 'up'
c490fecec0ef Have another crack at fixing transposition.
Daniel O'Connor <darius@dons.net.au>
parents: 36
diff changeset
215 print 'Transposed note at %.1f sec %s (%d) %s %d octave(s) to %s (%d)' % (
c490fecec0ef Have another crack at fixing transposition.
Daniel O'Connor <darius@dons.net.au>
parents: 36
diff changeset
216 ctime, self.midi2note[evw.ev.note - i], evw.ev.note - i, tmp,
c490fecec0ef Have another crack at fixing transposition.
Daniel O'Connor <darius@dons.net.au>
parents: 36
diff changeset
217 abs(i / 12), evw.notename, evw.ev.note)
c490fecec0ef Have another crack at fixing transposition.
Daniel O'Connor <darius@dons.net.au>
parents: 36
diff changeset
218 break
c490fecec0ef Have another crack at fixing transposition.
Daniel O'Connor <darius@dons.net.au>
parents: 36
diff changeset
219 if evw.slot != None:
c490fecec0ef Have another crack at fixing transposition.
Daniel O'Connor <darius@dons.net.au>
parents: 36
diff changeset
220 stats.playablecount += 1
c490fecec0ef Have another crack at fixing transposition.
Daniel O'Connor <darius@dons.net.au>
parents: 36
diff changeset
221 else:
c490fecec0ef Have another crack at fixing transposition.
Daniel O'Connor <darius@dons.net.au>
parents: 36
diff changeset
222 print 'Note at %.1f sec %d (%s) not playable' % (ctime, evw.ev.note, self.midi2note[evw.ev.note])
c490fecec0ef Have another crack at fixing transposition.
Daniel O'Connor <darius@dons.net.au>
parents: 36
diff changeset
223 stats.unplayablecount += 1
c490fecec0ef Have another crack at fixing transposition.
Daniel O'Connor <darius@dons.net.au>
parents: 36
diff changeset
224 else:
38
9e8ed92b477c Re-jig note translation to only happen when we are going to emit a
Daniel O'Connor <darius@dons.net.au>
parents: 37
diff changeset
225 print 'Note at %.1f sec, %d not in MIDI table' % (ctime, evw.ev.note)
37
c490fecec0ef Have another crack at fixing transposition.
Daniel O'Connor <darius@dons.net.au>
parents: 36
diff changeset
226 stats.unplayablecount += 1
c490fecec0ef Have another crack at fixing transposition.
Daniel O'Connor <darius@dons.net.au>
parents: 36
diff changeset
227
12
6e46ceee57a7 Use correct MIDI note generation, previous version did not agree with
Daniel O'Connor <darius@dons.net.au>
parents: 11
diff changeset
228 # http://newt.phys.unsw.edu.au/jw/notes.html
38
9e8ed92b477c Re-jig note translation to only happen when we are going to emit a
Daniel O'Connor <darius@dons.net.au>
parents: 37
diff changeset
229 # But this seems dumb since the lowest MIDI note is 0 which would be C-1..
7
31db42ce72b8 Rework to be class-y
Daniel O'Connor <darius@dons.net.au>
parents: 5
diff changeset
230 @staticmethod
27
87cf66e04ef9 Handle offsetting note pitch in a better way.
Daniel O'Connor <darius@dons.net.au>
parents: 26
diff changeset
231 def genmidi2note():
87cf66e04ef9 Handle offsetting note pitch in a better way.
Daniel O'Connor <darius@dons.net.au>
parents: 26
diff changeset
232 '''Create forward & reverse tables for midi number to note name (assuming 69 = A4 = A440)'''
7
31db42ce72b8 Rework to be class-y
Daniel O'Connor <darius@dons.net.au>
parents: 5
diff changeset
233 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']
31db42ce72b8 Rework to be class-y
Daniel O'Connor <darius@dons.net.au>
parents: 5
diff changeset
234 midi2note = {}
31db42ce72b8 Rework to be class-y
Daniel O'Connor <darius@dons.net.au>
parents: 5
diff changeset
235 note2midi = {}
38
9e8ed92b477c Re-jig note translation to only happen when we are going to emit a
Daniel O'Connor <darius@dons.net.au>
parents: 37
diff changeset
236 for midi in range(12, 128):
12
6e46ceee57a7 Use correct MIDI note generation, previous version did not agree with
Daniel O'Connor <darius@dons.net.au>
parents: 11
diff changeset
237 octave = midi / len(names) - 1
7
31db42ce72b8 Rework to be class-y
Daniel O'Connor <darius@dons.net.au>
parents: 5
diff changeset
238 index = midi % len(names)
31db42ce72b8 Rework to be class-y
Daniel O'Connor <darius@dons.net.au>
parents: 5
diff changeset
239 name = names[index] % (octave)
27
87cf66e04ef9 Handle offsetting note pitch in a better way.
Daniel O'Connor <darius@dons.net.au>
parents: 26
diff changeset
240 midi2note[midi] = name
87cf66e04ef9 Handle offsetting note pitch in a better way.
Daniel O'Connor <darius@dons.net.au>
parents: 26
diff changeset
241 note2midi[name] = midi
4
9f4fa5f231e6 Rework to use mido iterator and paginate.
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
242
7
31db42ce72b8 Rework to be class-y
Daniel O'Connor <darius@dons.net.au>
parents: 5
diff changeset
243 return midi2note, note2midi
31db42ce72b8 Rework to be class-y
Daniel O'Connor <darius@dons.net.au>
parents: 5
diff changeset
244
31db42ce72b8 Rework to be class-y
Daniel O'Connor <darius@dons.net.au>
parents: 5
diff changeset
245 @staticmethod
31db42ce72b8 Rework to be class-y
Daniel O'Connor <darius@dons.net.au>
parents: 5
diff changeset
246 def loadnote2slot(fname, note2midi):
31db42ce72b8 Rework to be class-y
Daniel O'Connor <darius@dons.net.au>
parents: 5
diff changeset
247 note2slot = {}
13
5f4c21bb5140 Add lines and notes engraved on the paper.
Daniel O'Connor <darius@dons.net.au>
parents: 12
diff changeset
248 slot2note = {}
7
31db42ce72b8 Rework to be class-y
Daniel O'Connor <darius@dons.net.au>
parents: 5
diff changeset
249 index = 0
31db42ce72b8 Rework to be class-y
Daniel O'Connor <darius@dons.net.au>
parents: 5
diff changeset
250
31db42ce72b8 Rework to be class-y
Daniel O'Connor <darius@dons.net.au>
parents: 5
diff changeset
251 for note in file(fname):
31db42ce72b8 Rework to be class-y
Daniel O'Connor <darius@dons.net.au>
parents: 5
diff changeset
252 note = note.strip()
31db42ce72b8 Rework to be class-y
Daniel O'Connor <darius@dons.net.au>
parents: 5
diff changeset
253 if note[0] == '#':
31db42ce72b8 Rework to be class-y
Daniel O'Connor <darius@dons.net.au>
parents: 5
diff changeset
254 continue
31db42ce72b8 Rework to be class-y
Daniel O'Connor <darius@dons.net.au>
parents: 5
diff changeset
255 if note not in note2midi:
31db42ce72b8 Rework to be class-y
Daniel O'Connor <darius@dons.net.au>
parents: 5
diff changeset
256 raise exceptions.ValueError('Note \'%s\' not valid' % note)
31db42ce72b8 Rework to be class-y
Daniel O'Connor <darius@dons.net.au>
parents: 5
diff changeset
257 note2slot[note] = index
13
5f4c21bb5140 Add lines and notes engraved on the paper.
Daniel O'Connor <darius@dons.net.au>
parents: 12
diff changeset
258 slot2note[index] = note
7
31db42ce72b8 Rework to be class-y
Daniel O'Connor <darius@dons.net.au>
parents: 5
diff changeset
259 index += 1
31db42ce72b8 Rework to be class-y
Daniel O'Connor <darius@dons.net.au>
parents: 5
diff changeset
260
13
5f4c21bb5140 Add lines and notes engraved on the paper.
Daniel O'Connor <darius@dons.net.au>
parents: 12
diff changeset
261 return note2slot, slot2note
4
9f4fa5f231e6 Rework to use mido iterator and paginate.
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
262
11
9faad813e39e switch to PDF to avoid dealing with CorelDraw crashing
Daniel O'Connor <darius@dons.net.au>
parents: 9
diff changeset
263 def emitnote(self, pdfs, slot, start, notelen):
19
ffaf97818ce3 - Music needs to run right to left.
Daniel O'Connor <darius@dons.net.au>
parents: 18
diff changeset
264 x = start * self.timescale + self.leadin # Convert start time to distance
31
ea98c9507f47 Preliminary multi-page support. Breaks time marks though.
Daniel O'Connor <darius@dons.net.au>
parents: 30
diff changeset
265 pdfidx = int(x / self.pdfwidth) # Determine which pdf
ea98c9507f47 Preliminary multi-page support. Breaks time marks though.
Daniel O'Connor <darius@dons.net.au>
parents: 30
diff changeset
266 x = x % self.pdfwidth # and where on that pdf
16
20337b22977d Add left margin and slot size support.
Daniel O'Connor <darius@dons.net.au>
parents: 14
diff changeset
267 h = self.slotsize
24
71b78f06ff03 Highest notes are at the bottom not the top.
Daniel O'Connor <darius@dons.net.au>
parents: 23
diff changeset
268 y = self.pageheight - (self.heel + slot * self.pitch - self.slotsize / 2) - self.slotsize
19
ffaf97818ce3 - Music needs to run right to left.
Daniel O'Connor <darius@dons.net.au>
parents: 18
diff changeset
269 w = notelen * self.timescale # Convert note length in time to distance
7
31db42ce72b8 Rework to be class-y
Daniel O'Connor <darius@dons.net.au>
parents: 5
diff changeset
270
37
c490fecec0ef Have another crack at fixing transposition.
Daniel O'Connor <darius@dons.net.au>
parents: 36
diff changeset
271 #print 'pdf = %d x = %.3f y = %.3f w = %.3f h = %.3f' % (pdfidx, x, y, w, h)
11
9faad813e39e switch to PDF to avoid dealing with CorelDraw crashing
Daniel O'Connor <darius@dons.net.au>
parents: 9
diff changeset
272 w1 = w
31
ea98c9507f47 Preliminary multi-page support. Breaks time marks though.
Daniel O'Connor <darius@dons.net.au>
parents: 30
diff changeset
273 # Check if the note crosses a pdf
ea98c9507f47 Preliminary multi-page support. Breaks time marks though.
Daniel O'Connor <darius@dons.net.au>
parents: 30
diff changeset
274 if x + w > self.pdfwidth:
ea98c9507f47 Preliminary multi-page support. Breaks time marks though.
Daniel O'Connor <darius@dons.net.au>
parents: 30
diff changeset
275 w1 = self.pdfwidth - x # Crop first note
19
ffaf97818ce3 - Music needs to run right to left.
Daniel O'Connor <darius@dons.net.au>
parents: 18
diff changeset
276 w2 = w - w1 # Calculate length of second note
31
ea98c9507f47 Preliminary multi-page support. Breaks time marks though.
Daniel O'Connor <darius@dons.net.au>
parents: 30
diff changeset
277 assert w2 <= self.pdfwidth, 'note extends for more than a pdf'
11
9faad813e39e switch to PDF to avoid dealing with CorelDraw crashing
Daniel O'Connor <darius@dons.net.au>
parents: 9
diff changeset
278 # Emit second half of note
37
c490fecec0ef Have another crack at fixing transposition.
Daniel O'Connor <darius@dons.net.au>
parents: 36
diff changeset
279 #print 'split note, pdf %d w2 = %.3f' % (pdfidx + 1, w2)
31
ea98c9507f47 Preliminary multi-page support. Breaks time marks though.
Daniel O'Connor <darius@dons.net.au>
parents: 30
diff changeset
280 Midi2PDF._emitnote(pdfs[pdfidx + 1], self.pdfwidth - w2, y, w2, h)
11
9faad813e39e switch to PDF to avoid dealing with CorelDraw crashing
Daniel O'Connor <darius@dons.net.au>
parents: 9
diff changeset
281
31
ea98c9507f47 Preliminary multi-page support. Breaks time marks though.
Daniel O'Connor <darius@dons.net.au>
parents: 30
diff changeset
282 Midi2PDF._emitnote(pdfs[pdfidx], self.pdfwidth - x - w1, y, w1, h)
7
31db42ce72b8 Rework to be class-y
Daniel O'Connor <darius@dons.net.au>
parents: 5
diff changeset
283
31db42ce72b8 Rework to be class-y
Daniel O'Connor <darius@dons.net.au>
parents: 5
diff changeset
284 @staticmethod
11
9faad813e39e switch to PDF to avoid dealing with CorelDraw crashing
Daniel O'Connor <darius@dons.net.au>
parents: 9
diff changeset
285 def _emitnote(pdf, x, y, w, h):
9faad813e39e switch to PDF to avoid dealing with CorelDraw crashing
Daniel O'Connor <darius@dons.net.au>
parents: 9
diff changeset
286 pdf.saveState()
9faad813e39e switch to PDF to avoid dealing with CorelDraw crashing
Daniel O'Connor <darius@dons.net.au>
parents: 9
diff changeset
287 pdf.setStrokeColor(CUT_COLOUR)
9faad813e39e switch to PDF to avoid dealing with CorelDraw crashing
Daniel O'Connor <darius@dons.net.au>
parents: 9
diff changeset
288 pdf.setLineWidth(0)
9faad813e39e switch to PDF to avoid dealing with CorelDraw crashing
Daniel O'Connor <darius@dons.net.au>
parents: 9
diff changeset
289 pdf.rect(x * mm, y * mm, w * mm, h * mm, fill = False, stroke = True)
9faad813e39e switch to PDF to avoid dealing with CorelDraw crashing
Daniel O'Connor <darius@dons.net.au>
parents: 9
diff changeset
290 pdf.restoreState()
0
0773354c7428 Initial commit, WIP.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
291
17
c50427f1da2d - Draw vertical time lines.
Daniel O'Connor <darius@dons.net.au>
parents: 16
diff changeset
292 @staticmethod
c50427f1da2d - Draw vertical time lines.
Daniel O'Connor <darius@dons.net.au>
parents: 16
diff changeset
293 def textHelper(pdf, x, y, colour, fill, fontname, fontsize, text):
c50427f1da2d - Draw vertical time lines.
Daniel O'Connor <darius@dons.net.au>
parents: 16
diff changeset
294 tobj = pdf.beginText()
c50427f1da2d - Draw vertical time lines.
Daniel O'Connor <darius@dons.net.au>
parents: 16
diff changeset
295 tobj.setTextOrigin(x, y)
c50427f1da2d - Draw vertical time lines.
Daniel O'Connor <darius@dons.net.au>
parents: 16
diff changeset
296 tobj.setFont(fontname, fontsize)
c50427f1da2d - Draw vertical time lines.
Daniel O'Connor <darius@dons.net.au>
parents: 16
diff changeset
297 tobj.setStrokeColor(colour)
c50427f1da2d - Draw vertical time lines.
Daniel O'Connor <darius@dons.net.au>
parents: 16
diff changeset
298 tobj.setFillColor(colour)
c50427f1da2d - Draw vertical time lines.
Daniel O'Connor <darius@dons.net.au>
parents: 16
diff changeset
299 if fill:
c50427f1da2d - Draw vertical time lines.
Daniel O'Connor <darius@dons.net.au>
parents: 16
diff changeset
300 tobj.setTextRenderMode(0)
c50427f1da2d - Draw vertical time lines.
Daniel O'Connor <darius@dons.net.au>
parents: 16
diff changeset
301 else:
c50427f1da2d - Draw vertical time lines.
Daniel O'Connor <darius@dons.net.au>
parents: 16
diff changeset
302 tobj.setTextRenderMode(1)
c50427f1da2d - Draw vertical time lines.
Daniel O'Connor <darius@dons.net.au>
parents: 16
diff changeset
303 tobj.textLine(text)
c50427f1da2d - Draw vertical time lines.
Daniel O'Connor <darius@dons.net.au>
parents: 16
diff changeset
304 pdf.drawText(tobj)
c50427f1da2d - Draw vertical time lines.
Daniel O'Connor <darius@dons.net.au>
parents: 16
diff changeset
305
0
0773354c7428 Initial commit, WIP.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
306 if __name__ == '__main__':
0773354c7428 Initial commit, WIP.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
307 main()