# HG changeset patch # User Daniel O'Connor # Date 1461660018 -34200 # Node ID ffaf97818ce3039570288b5a14944469a21b6bf8 # Parent cf93a76eda92611e32728c5f5d270e671c021996 - Music needs to run right to left. - Rename margin to leadin to be clearer (although too much leadin makes it barf) - Make time marks and rectangle drawing options diff -r cf93a76eda92 -r ffaf97818ce3 musiccutter.py --- a/musiccutter.py Wed Apr 20 08:38:38 2016 +0930 +++ b/musiccutter.py Tue Apr 26 18:10:18 2016 +0930 @@ -17,12 +17,13 @@ if filename == None: filename = 'test.midi' # Card layout from http://www.orgues-de-barbarie.com/wp-content/uploads/2014/09/format-cartons.pdf - m = Midi2PDF('notes', 200, 155, 5.5, 3.0, 6.0, 20, 10, 'Helvetica', 12) + # Notes are read from right to left + m = Midi2PDF('notes', 130, 155, 5.5, 3.0, 6.0, 0, False, False, 10, 'Helvetica', 12) base, ext = os.path.splitext(filename) m.processMidi(filename, base + '-%02d.pdf') class Midi2PDF(object): - def __init__(self, notefile, pagewidth, pageheight, pitch, slotsize, offset, lmargin, timescale, fontname, fontsize): + def __init__(self, notefile, pagewidth, pageheight, pitch, slotsize, offset, leadin, timemarks, drawrect, timescale, fontname, fontsize): self.midi2note, self.note2midi = Midi2PDF.genmidi2note() self.note2slot, self.slot2note = Midi2PDF.loadnote2slot(notefile, self.note2midi) self.pagewidth = pagewidth # Dimensions are in millimetres @@ -30,7 +31,9 @@ self.pitch = pitch # Distance between each slot self.slotsize = slotsize # Size of each slot cut out self.offset = offset # Bottom margin - self.lmargin = lmargin # Left margin + self.leadin = leadin # Extra at the start + self.timemarks = timemarks # Draw vertical time lines + self.drawrect = drawrect # Draw rectangle around each page self.timescale = timescale # Width per second self.fontname = fontname self.fontsize = fontsize # Points @@ -44,7 +47,7 @@ for i in range(16): channels.append({}) - npages = int(math.ceil(((midi.length * self.timescale) + self.lmargin) / self.pagewidth)) + npages = int(math.ceil(((midi.length * self.timescale) + self.leadin) / self.pagewidth)) print 'npages', npages pdfs = [] for i in range(npages): @@ -92,26 +95,26 @@ for pindx in range(len(pdfs)): pdf = pdfs[pindx] # Add title and page number - Midi2PDF.textHelper(pdf, 25 * mm, 1 * mm, ENGRAVE_COLOUR, True, self.fontname, self.fontsize, '%s (%d / %d)' % (title, pindx + 1, npages)) + Midi2PDF.textHelper(pdf, 0 * mm, 1 * mm, ENGRAVE_COLOUR, True, self.fontname, self.fontsize, '%s (%d / %d)' % (title, pindx + 1, npages)) pdf.saveState() # Not really necessary since this is last thing we do pdf.setLineWidth(0) # Draw time marks - if False: - tstart = 0 - tend = (self.pagewidth - self.lmargin) / self.timescale + if self.timemarks: + tstart = self.leadin / self.timescale + tend = self.pagewidth / self.timescale if pindx > 0: tsize = self.pagewidth / self.timescale tstart = tend + tsize * pindx tend = tend + tsize * (pindx + 1) for s in range(tstart, tend, 5): - x = float(s * self.timescale + self.lmargin) % self.pagewidth + x = self.pagewidth - (float(s * self.timescale + self.leadin) % self.pagewidth) pdf.line(x * mm, self.offset, x * mm, self.pageheight * mm) Midi2PDF.textHelper(pdf, x * mm, 1 * mm, ENGRAVE_COLOUR, False, self.fontname, self.fontsize, str(s) + 's') # Draw rectangle around page - if False: + if self.drawrect: pdf.rect(0, 0, self.pagewidth * mm, self.pageheight * mm, fill = False, stroke = True) pdf.line(0, 0, 0, self.pagewidth * mm) pdf.line(0, self.pagewidth * mm, self.pagewidth * mm, self.pageheight * mm) @@ -123,7 +126,7 @@ ofs = (self.offset + slot * self.pitch) * mm pdf.line(0, ofs, self.pagewidth * mm, ofs) # Note name - Midi2PDF.textHelper(pdf, 0 * mm, ofs + 1 * mm, ENGRAVE_COLOUR, False, self.fontname, self.fontsize, self.slot2note[slot]) + Midi2PDF.textHelper(pdf, (self.pagewidth - 10) * mm, ofs + 1 * mm, ENGRAVE_COLOUR, False, self.fontname, self.fontsize, self.slot2note[slot]) pdf.restoreState() pdf.save() @@ -162,25 +165,25 @@ return note2slot, slot2note def emitnote(self, pdfs, slot, start, notelen): - x = start * self.timescale + self.lmargin - pageidx = int(x / self.pagewidth) - x = x % self.pagewidth - y = self.offset + slot * self.pitch + (self.pitch - self.slotsize) / 2 - w = notelen * self.timescale + x = start * self.timescale + self.leadin # Convert start time to distance + pageidx = int(x / self.pagewidth) # Determine which page + x = x % self.pagewidth # and where on that page h = self.slotsize + y = self.offset + slot * self.pitch + (self.pitch - h) / 2 + w = notelen * self.timescale # Convert note length in time to distance print 'page = %d x = %.3f y = %.3f w = %.3f h = %.3f' % (pageidx, x, y, w, h) w1 = w # Check if the note crosses a page if x + w > self.pagewidth: - w1 = x - self.pagewidth # Crop first note - w2 = w - w1 - assert w1 <= self.pagewidth, 'note extends for more than a page' + w1 = self.pagewidth - x # Crop first note + w2 = w - w1 # Calculate length of second note + assert w2 <= self.pagewidth, 'note extends for more than a page' # Emit second half of note print 'split note, page %d w2 = %.3f' % (pageidx + 1, w2) - Midi2PDF._emitnote(pdfs[pageidx + 1], 0, y, w2, h) + Midi2PDF._emitnote(pdfs[pageidx + 1], self.pagewidth - w2, y, w2, h) - Midi2PDF._emitnote(pdfs[pageidx], x, y, w1, h) + Midi2PDF._emitnote(pdfs[pageidx], self.pagewidth - x - w1, y, w1, h) @staticmethod def _emitnote(pdf, x, y, w, h):