import time

import music21
import OpenFL.Printer as P

def midi_live(midifilename, quarternote_s=0.5, skip_leading_rests=True):
    """ Given a MIDI file, play it live on the printer
    """
    p = P.Printer()
    if p.state() != P.State.MACHINE_READY_TO_PRINT:
        p.initialize()
    else:
        # We still want to ensure we start in a known state, with z at the limit:
        import OpenFL.FLP as FLP
        # Move z up by more than the z height at 15 mm/s.
        p.move_z(FLP.ZMove.usteps_up_per_mm * 200.0, 
                 feedrate=FLP.ZMove.usteps_up_per_mm * 15.0)

    # Use a class as a local namespace to capture variables
    class Position:
        z = 0   # This is our current Z position in microsteps
        direction = -1  # This is the direction of travel (negative = down)

    # Local function that handles note direction and timing
    def play_note(freq, time_s):
        # Turn around if we're about to hit the top or bottom
        steps = freq * time_s
        if not (-80000 <= Position.z + Position.direction * steps <= 0):
            Position.direction *= -1

        # Send a blocking motor move
        p.move_z(Position.direction * freq * time_s, freq, 80)

        # Update the dead-reckoning Z position
        Position.z += Position.direction * steps

    mf = music21.midi.MidiFile()
    mf.open(midifilename)
    mf.read()
    soundstream = music21.midi.translate.midiFileToStream(mf)

    for track in soundstream.elements:
        for i in track.flat.elements:
            # Play a note on the printer (and clear the skip rests flag)
            if isinstance(i, music21.note.Note):
                play_note(i.pitch.frequency,
                          i.duration.quarterLength * quarternote_s)
                skip_leading_rests = False
            # Pause the correct amount of time for a rest
            elif isinstance(i, music21.note.Rest):
                if not skip_leading_rests:
                    time.sleep(i.duration.quarterLength * quarternote_s)

@@ -1,12 +1,34 @@
+#!/usr/bin/env python%0A
 import time%0A
@@ -50,23 +50,95 @@
 %0Aimport 
-OpenFL.
+sys%0Aimport os%0Asys.path.append(os.path.abspath('../OpenFL'))%0Afrom OpenFL import 
 Printer 
@@ -171,16 +171,31 @@
 lename, 
+%0A              
 quartern
@@ -205,16 +205,67 @@
 _s=0.5, 
+%0A              frequency_factor=1.0,%0A              
 skip_lea
@@ -807,86 +807,410 @@
     
-class Position:%0A        z = 0   # This is our current Z position in microsteps
+p.move_z(FLP.ZMove.usteps_up_per_mm * -10.0, %0A             feedrate=FLP.ZMove.usteps_up_per_mm * 15.0)%0A    class Position:%0A        zbounds_mm = (-10, -150)%0A        zbounds_ustep = (zbounds_mm%5B0%5D * FLP.ZMove.usteps_up_per_mm,%0A                         zbounds_mm%5B1%5D * FLP.ZMove.usteps_up_per_mm)%0A        # This is our current Z position in microsteps:%0A        z_ustep = FLP.ZMove.usteps_up_per_mm * -10.0
 %0A   
@@ -1282,16 +1282,26 @@
 = down)%0A
+        %0A%0A
 %0A    # L
@@ -1490,24 +1490,24 @@
     
-if not (-80000 %3C
+next_z_would_be 
 = Po
@@ -1514,16 +1514,22 @@
 sition.z
+_ustep
  + Posit
@@ -1548,21 +1548,238 @@
 n * 
-steps %3C= 0):%0A
+freq * time_s%0A        if Position.direction %3C 0:%0A            if next_z_would_be %3C min(Position.zbounds_ustep):%0A                Position.direction = 1%0A        else:%0A            if next_z_would_be %3E max(Position.zbounds_ustep):%0A    
     
@@ -1805,17 +1805,16 @@
 rection 
-*
 = -1%0A%0A  
@@ -1977,16 +1977,22 @@
 sition.z
+_ustep
  += Posi
@@ -2150,16 +2150,51 @@
 eam(mf)%0A
+    print len(soundstream.elements)
 %0A    for
@@ -2428,16 +2428,35 @@
 requency
+ * frequency_factor
 ,%0A      
@@ -2765,28 +2765,745 @@
 rterLength * quarternote_s)%0A
+%0Aif __name__ == '__main__':%0A    import argparse%0A    parser = argparse.ArgumentParser(description='Play a midi file on your Form 1 or Form 1+.')%0A    parser.add_argument('midifile', type=str,%0A                        help='A midi file to play')%0A    parser.add_argument('--quarternote_s',%0A                        type=float,%0A                        default=0.5,%0A                        help='Duration for a quarternote.')%0A    parser.add_argument('--frequency_factor', type=float, default=1.0,%0A                        help='Scale frequency by this factor.')%0A    args = parser.parse_args()%0A    midi_live(args.midifile, %0A              quarternote_s=args.quarternote_s, %0A              frequency_factor=args.frequency_factor)%0A

Add argparse to midi_live.py.