def insert_pause_before(layer, zJog_mm=100, buttonPressMessage="Press to continue."): """ Jog up and wait on button press then resume. This is done when the tilt motor is at its lowest. """ import numpy as np tiltMoves = [x for x in layer if isinstance(x, FLP.TiltMove)] bestAfter = np.argmax(np.cumsum([move.usteps for move in tiltMoves])) lowestTiltMove_i = layer.index(tiltMoves[bestAfter]) insertBefore_i = None zSpeed_usteps_per_s = None zCurrent = None for x in layer[:lowestTiltMove_i]: if isinstance(x, FLP.ZFeedRate): zSpeed_usteps_per_s = x.feedrate if isinstance(x, FLP.ZCurrent): zCurrent = x.current for i in range(lowestTiltMove_i, len(layer)): if isinstance(layer[i], FLP.WaitForMovesToComplete): insertBefore_i = 1 + i break assert insertBefore_i is not None # Now we know where the motors are stopped and tilt is at its lowest. pauseCycle = FLP.Packets() zJog_usteps = int(zJog_mm * FLP.ZMove.usteps_up_per_mm) zJog_mmps = 10.0 pauseCycle.append(FLP.ZCurrent(FLP.ZCurrent.moving_current)) pauseCycle.append(FLP.ZFeedRate(zJog_mmps * abs(FLP.ZMove.usteps_up_per_mm))) pauseCycle.append(FLP.ZMove(zJog_usteps)) pauseCycle.append(FLP.WaitForMovesToComplete()) pauseCycle.append(FLP.WaitButtonPress(buttonPressMessage)) pauseCycle.append(FLP.ZMove(-zJog_usteps)) pauseCycle.append(FLP.WaitForMovesToComplete()) # Restore settings: pauseCycle.append(FLP.ZCurrent(zCurrent)) if zSpeed_usteps_per_s is not None: pauseCycle.append(FLP.ZFeedRate(zSpeed_usteps_per_s)) newLayer = layer[:insertBefore_i] + pauseCycle + layer[insertBefore_i:] return newLayer
def midi2flp(midifilename, quarternote_s=0.25, skip_leading_rests=True): """ Given a midi file, return a list of FLP.Packets objects, one for each track. """ mf = music21.midi.MidiFile() mf.open(midifilename) mf.read() soundstream = music21.midi.translate.midiFileToStream(mf) tracks = [] for track in soundstream.elements: x = [ x for x in track.flat.elements if isinstance(x, (music21.note.Note, music21.note.Rest)) ] pitchtime = [] for thing in x: if isinstance(thing, music21.note.Rest): pitchtime.append((0, float(thing.duration.quarterLength))) else: pitchtime.append((thing.pitch.frequency, float(thing.duration.quarterLength))) packets = F.Packets([ F.ZCurrent(80), ]) for i, (Hz, time) in enumerate(pitchtime): time *= quarternote_s if Hz == 0: if i != 0 and skip_leading_rests: # Don't start with a rest. packets.append(F.Dwell(s=time)) else: ufreq = Hz * 8 packets += [ F.ZFeedRate(ufreq), F.ZMove(-int(ufreq * 0.5 * float(time))), F.WaitForMovesToComplete(), F.ZMove(int(ufreq * 0.5 * float(time))), F.WaitForMovesToComplete() ] tracks.append(packets) return tracks