# notes2MUP 10th October 2011 # Author: Charles Cave charlesweb@optusnet.com.au # http://charuzu.wordpress.com # This program reads the CSV file created by the Musescore ExportNotes # plugin and creates an XML file (SVG) showing the notes in a piano roll view # Each staff is shown in a different colour. # The CSV file has the following format. # Header section - Keyword and value # Score Title,TEXT # Score Subtitle,TEXT # Score Composer,TEXT # Score Poet,TEXT # Staves,INT # Key Signature,INT -7 (flats) to +7 (sharps) # Measures,INT # Measure Duration ticks, Empty Currently Unavailable # needs to be added to the file before running this script # for example, 4/4 time is 4 * 480 = 1920 # Time Signature,INT # MIDI ticks per quarter note, INT # Staff,INT # Voice,I INT # Chord (always followed by 1 or more notes) # cursortick, ticklen, number of notes, chordtype # Note # cursortick, name, tied, pitch, pitch class, visible, useraccidental, # velocity, notehead # Rest # cursortick, restduration # Example: (indentations to show structure # Chord,5280,480,3,0 # Note,5280,Bb,0,58,12,true,0,90,67 # Note,5280,D,0,62,16,true,0,90,67 # Note,5280,G,0,67,15,true,0,90,67 # Rest,29040,240 # Chord,29280,1440,1,0 # Note,29280,G,0,67,15,true,5,90,66 import sys argv = len(sys.argv) if argv < 2: print "Syntax is python notes2mup.py CSVFILE" sys.exit(1); infile = sys.argv[1] ###################################################### def draw_note(start_beat, duration, pitch, staffnum): """ Pitch a number between 0 and 127 """ style = "stroke:#000000; fill: #dddddd" # Black default # # Add more tests for staffnum 3, 4, etc with more colours if staffnum == 0: style = "stroke:#0000dd; fill: #0000dd" # Blue if staffnum == 1: style = "stroke:#dd0000; fill: #dd0000" # Red if staffnum == 2: style = "stroke:#000000; fill: #ffee00" ypitch = 5*(128 - int(pitch)) # five pixel row height print "" % (style) return xml_head = """ """ xml_foot = """ """ f = open(infile, "r") ctr = 0 print xml_head qtrNote = 0 # Ticks per quarter note for l in f.readlines(): l = l[:-1] tok = l.split(',') if tok[0] == "Staff": staff_no = int(tok[1]) if tok[0] == "MIDI ticks per quarter note": qtrNote = int(tok[1]) base_unit = qtrNote / 8 ### make this a paramater # currently the smallest interval shown on the # output will be a 1/32nd note if tok[0] == "Chord": tick_start = int(tok[1]) tick_dur = int(tok[2]) ctrNotes = int(tok[3]) if tok[0] == "Note": note = tok[4] note_name = tok[2] note_length = tick_dur / base_unit draw_note(tick_start / base_unit, tick_dur / base_unit, tok[4], staff_no) ctr += 1 print xml_foot