def __call__(self): # START and TIMINGCLOCK are added to globals during module # initialization - see a() defined and deleted above. if not self._started: self.midiOut.Write([[[START], pypm.Time()]]) self._started = True self.midiOut.Write([[[TIMINGCLOCK], pypm.Time()]])
def clear(self, col=None, row=None): '''Clears the value of a light in the MIDI device's grid.''' if col is None and row is None: t = pypm.Time() self.write_queue += [[[144, index, 0, 0], t] for index in range(8 * 16)] else: index = self.map_ui_to_midi(col, row) self.write_queue.append([[144, index, 0, 0], pypm.Time()])
def play(self): next_time = pypm.Time() step = -1 while True: if pypm.Time() >= next_time: step = (step + 1) % 16 self.trigger_step(step, next_time) if pypm.Time() - next_time > LATENCY: print 'WARNING: Inaccurate timing. Increase LATENCY.' next_time += self._step_time
def GameOfLife(MidiOut, MidiIn): led_array = [ 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 ] # led_array = [1,0,1,1,1,1,1,0,0,0, # 0,0,0,0,0,0,1,1,1,1, # 0,1,1,0,0,1,1,1,0,0, # 0,0,0,1,0,0,1,0] # led_array = [1,0,0,0,0,0,0,0,0,0, # 0,0,0,0,0,0,1,0,1,0, # 0,1,0,0,0,1,0,0,0,0, # 0,0,0,1,0,0,0,0] last_cycle_time = 0 i = 0 while True: while MidiIn.Poll(): # invert LEDs where touched MidiData = MidiIn.Read(1) if MidiData[0][0][0] == 0xB0: if MidiData[0][0][1] == 20: pos = MidiData[0][0][2] index_pos = int(float(pos) / 127.0 * 37.0) # print "index pos: ", index_pos if led_array[index_pos] == 1: led_array[index_pos] = 0 else: led_array[index_pos] = 1 if pypm.Time() - last_cycle_time > 100: last_cycle_time = pypm.Time() index_array = range(2, 35) new_array = list(led_array) # copy over 4 edge LEDs since they don't have 4 neighbors. new_array[0] = led_array[0] new_array[1] = led_array[1] new_array[36] = led_array[36] new_array[37] = led_array[37] for i in index_array: sum = led_array[i - 2] + led_array[i - 1] + led_array[ i + 1] + led_array[i + 2] if led_array[i] == 1: # live cell if sum < 1: new_array[i] = 0 # under population elif sum < 3: new_array[i] = 1 # just right else: new_array[i] = 0 # overcrowding else: # dead cell if sum == 2 or sum == 3: new_array[i] = 1 else: new_array[i] = 0 led_array = list(new_array) SendArray(led_array, MidiOut)
def ChaseDemo(MidiOut): x = 1 while True: MidiTime = pypm.Time() MidiOut.WriteShort(0xAD, x, x) MidiOut.WriteShort(0xAE, x, x) MidiOut.WriteShort(0xAF, x, x) x = x * 2 if x == 128: x = 1 while pypm.Time() < MidiTime + 100: pass
def PlayChord(chord, bpm): ChordList = [] MidiTime = pypm.Time() wait = 60.0 / bpm * 1000 print wait for i in range(len(chord)): ChordList.append([[0x90, chord[i], 100], MidiTime + wait * i]) MidiOut.Write(ChordList) while pypm.Time() < MidiTime + wait + len(chord) * wait: pass ChordList = [] # seems a little odd that they don't update MidiTime here... for i in range(len(chord)): ChordList.append([[0x90, chord[i], 0], MidiTime + wait * i]) MidiOut.Write(ChordList)
def set_threshold(self, threshold): # send CC # channel = sensor_index (1...) # number = threshold # value = 0:disable,1:enable,2:nada #self.O.Write([[[189, sensor_index, threshold, 2],0]])#pypm.Time()]]) self.O.Write([[[176, threshold, 2], pypm.Time()]]) # for sensor 1
def __init__(self, client, verbose=0): self.verbose = verbose #Init var self.midi_device_list = [] self.midi_device = None self.midi_in = None #setting looping task self.releaser = task.LoopingCall(self._get_input) #Launching RTP Client to call after midi time start in order to sync TS self.client = client #stats self.nbNotes = 0 self.fps_note = 0 #flag ( 1 == syncronyse with remote peer ) self.sync = 0 self.end_flag = True #check activity self.last_activity = 0 self.in_activity = False #value to set #in s (increase it when note frequency is high in order to reduce packet number) self.polling_interval = 0.015 #in ms #Time out must be > to polling self.time_out = 5 #Init time is for timestamp in RTP self.init_time = pypm.Time()
def ChaseDemo2(): # led_array = [1,0,1,0,1,0,1,0,1,0, # 1,0,1,0,1,0,1,0,1,0, # 1,0,1,0,1,0,1,0,1,0, # 1,0,1,0,1,0,1,0] # led_array_deque = deque(led_array) print(led_array_deque) SendArray(led_array_deque, MidiOut) timer_marker = pypm.Time() while True: timer_marker = pypm.Time() while pypm.Time() < timer_marker + 500: pass SendArray(led_array_deque, MidiOut) led_array_deque.rotate(1)
def send_note_off(self): """send Note Off all pitches and all channels """ midi_time = pypm.Time() #127 note off and 16 channels #TODO check problem: portMidi found host error (link to zynadd?) for i in range(NUM_MIDI_CHANS): for j in range(MIDI_MAX): self.midi_out.Write([[[NOTE_OFF + i, j, 0], 0]])
def test(): latency = 200 #latency is in ms, 0 means ignore timestamps dev = 0 MidiOut = pypm.Output(dev, latency) tempo = 100 dur = 60.0 / tempo / 2 notes = [60, 63, 67] n = 0 t = pypm.Time() #current time in ms while n < 10: t += 2 * dur * 1000 playChord(MidiOut, [notes[0] - 12], 1, 127, dur, t) playChord(MidiOut, notes, 0, 60, dur, t) n += 1 while pypm.Time() < t + 2 * dur * 1000: pass del MidiOut
def BinaryCounter(MidiOut): last_cycle_time = 0 counter = 0 led_array = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] while True: if pypm.Time() - last_cycle_time > 30: ## print "cycle" last_cycle_time = pypm.Time() temp_counter = counter counter = counter + 1 for i in range(20): led_array[i] = 0x01 & temp_counter temp_counter = temp_counter >> 1 SendArray(led_array, MidiOut)
def set_pattern(self, on): t = pypm.Time() data = [] for r in range(0, 113, 16): even = 127 if bool(on) else 0 odd = 0 if bool(on) else 127 on = not on for n in range(r, r + 8, 2): data.append([[144, n, even, 0], t]) data.append([[144, n + 1, odd, 0], t]) random.shuffle(data) self.out_device.Write(data)
def _get_input(self): """ Get input from selected device """ current_time = pypm.Time() #Reading Midi Input midi_data = self.midi_in.Read(1024) if self.verbose: print midi_data if len(midi_data) > 0: reactor.callFromThread(self.client.send_midi_data, midi_data, current_time)
def __init__(self, peer_address, sport=0, rport=0, latency=20, jitter_buffer_size=10, safe_keyboard=0, recovery=1, follow_standard=0, verbose=0): #Init mother class RTPSession.__init__(self, peer_address, sport, rport, PAYLOAD, jitter_buffer_size, TOOL_NAME) self.verbose = verbose if verbose: print("Your configuration:") print(" Latency:", latency, "ms") print(" Jitter Buffer Time:", jitter_buffer_size, "ms") #init midi if self.sport > 0: self.midi_in = MidiIn(self, verbose) #1 == Permisive mode (make this configurable) if self.rport > 0: self.midi_out = MidiOut(0, latency, safe_keyboard, verbose) #history of the feed self.packets_received_list = PacketCirc(HISTORY_SIZE) #Recovery utils self.recovery = 0 self.recovery_journal_system = None if recovery: self.recovery = 1 self.recovery_journal_system = RecoveryJournal(follow_standard) if verbose: print(" Recovery journal is running") if follow_standard: print(" Recovery is following standard") self.init_timestamp = None #Flag self.sending_data = 0 self.receiving_data = 0 #Timestamp story self.last_midi_time_sent = pypm.Time() self.timeouterLoop = None
def TestOutput(): latency = int(raw_input("Type latency: ")) print PrintDevices(OUTPUT) dev = int(raw_input("Type output number: ")) MidiOut = pypm.Output(dev, latency) print "Midi Output opened with ", latency, " latency" dummy = raw_input("ready to send program 1 change... (type RETURN):") MidiOut.Write([[[0xc0, 0, 0], pypm.Time()]]) dummy = raw_input("ready to note-on... (type RETURN):") MidiOut.Write([[[0x90, 60, 100], pypm.Time()]]) dummy = raw_input("read to note-off... (type RETURN):") MidiOut.Write([[[0x90, 60, 0], pypm.Time()]]) dummy = raw_input("ready to note-on (short form)... (type RETURN):") MidiOut.WriteShort(0x90, 60, 100) dummy = raw_input("ready to note-off (short form)... (type RETURN):") MidiOut.WriteShort(0x90, 60, 0) print print "chord will arpeggiate if latency > 0" dummy = raw_input("ready to chord-on/chord-off... (type RETURN):") chord = [60, 67, 76, 83, 90] ChordList = [] MidiTime = pypm.Time() for i in range(len(chord)): ChordList.append([[0x90, chord[i], 100], MidiTime + 1000 * i]) MidiOut.Write(ChordList) while pypm.Time() < MidiTime + 1000 + len(chord) * 1000: pass ChordList = [] # seems a little odd that they don't update MidiTime here... for i in range(len(chord)): ChordList.append([[0x90, chord[i], 0], MidiTime + 1000 * i]) MidiOut.Write(ChordList) print("Sending SysEx messages...") # sending with timestamp = 0 should be the same as sending with # timestamp = pypm.Time() dummy = raw_input( "ready to send a SysEx string with timestamp = 0 ... (type RETURN):") MidiOut.WriteSysEx( 0, '\xF0\x7D\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\xF7') dummy = raw_input( "ready to send a SysEx list with timestamp = pypm.Time() ... (type RETURN):" ) MidiOut.WriteSysEx(pypm.Time(), [0xF0, 0x7D, 0x10, 0x11, 0x12, 0x13, 0xF7]) dummy = raw_input("ready to close and terminate... (type RETURN):") del MidiOut
def publish_midi_notes(self): """Polling function for midi out""" def_p = defer.Deferred() # put in local scope to improve performance midi_cmd_list = self.midi_cmd_list play_midi_note = self.play_midi_note while self.publish_flag: """ if there are notes in the shared buffer Put the in the playing buffer """ while True: try: cur_data = midi_cmd_list.get_nowait() if VERBOSE: print cur_data self.playing_buffer.put(cur_data) except Queue.Empty: break if self.playing_buffer.len() > 0: current_time = pypm.Time() #if the first is in time #12 correspond to the polling interval on the #test machine and the jitter of thread #switching ( to test on others computers with #diff set up) #The problem is that scheduler taking time to #switch between process if ((self.playing_buffer.buffer[0][1] + self.latency - self.tolerance) <= current_time): reactor.callInThread(play_midi_note) #time.sleep(0.001) # this probably used to be the sleep below # don't hog the cpu time.sleep(0.001) return def_p
def disable(self, threshold): self.O.Write([[[176, threshold, 0], pypm.Time()]])
def ChaseDemoWithSpeedInput(MidiOut, MidiIn): x = 1 speed = 500 last_time = 0 last_speed_calc_time = 0 prev_pos = 0 pos = 0 prev_last_input_time = 0 last_input_time = 0 speed = 0.0 new_speed = 0.0 pos_array = [0, 0, 0, 0, 0] pos_array = deque(pos_array) time_array = deque([0, 0, 0, 0, 0]) print_time = 0 led_shift_time = 0 touch_state = 0 brake_time = 0 led_deque = deque([ 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]) SendArray(led_deque, MidiOut) EnableOnOffOutput(MidiOut) while True: while MidiIn.Poll(): # throw out all but the latest input MidiData = MidiIn.Read(1) if MidiData[0][0][0] == 0xB0: if MidiData[0][0][1] == 20: pos = MidiData[0][0][2] pos_array.appendleft(pos) # pos_array.pop() last_input_time = MidiData[0][1] time_array.appendleft(last_input_time) # time_array.pop() # print(last_input_time) elif MidiData[0][0][ 1] == 17: # on / off output. 127 is touch, 0 is release if MidiData[0][0][2] == 127: # print "touch" touch_state = 1 else: # print "release" touch_state = 0 if last_input_time > last_speed_calc_time: # calc speed last_speed_calc_time = pypm.Time() pos_delta = pos_array[0] - pos_array[4] time_delta = time_array[0] - time_array[4] if time_delta > 0: new_speed = float(pos_delta) / float(time_delta) speed = adjust_speed(new_speed, speed) # handle case where VMeter is being touched, but position isn't moving if touch_state == 1 and pypm.Time() - last_input_time > 100: # reduce speed to 0 if pypm.Time() - brake_time > 17: brake_time = pypm.Time() # print "braking" speed = adjust_speed(0.0, speed) if pypm.Time() - print_time > 150: print_time = pypm.Time() # if abs(speed) > .01: # print "speed: ", speed, ", per: ", 1.0 / speed if pypm.Time() - last_input_time > 100: # friction braking speed = adjust_speed(0.0, speed) if abs(speed) > .001 and pypm.Time() - led_shift_time > int( 2.5 / abs(speed)): led_shift_time = pypm.Time() if speed > 0.0: led_deque.rotate(1) else: led_deque.rotate(-1) SendArray(led_deque, MidiOut)
def BinaryClock(MidiOut): from datetime import datetime last_cycle_time = 0 led_array = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] update_time = 0 while True: if pypm.Time() - last_cycle_time > 500: last_cycle_time = pypm.Time() led_array[ 11] = update_time # marker for minutes, just blinks with seconds led_array[ 16] = update_time # marker for minutes, just blinks with seconds led_array[ 26] = update_time # marker for hours, just blinks with seconds led_array[ 31] = update_time # marker for hours, just blinks with seconds if update_time == 0: update_time = 1 else: update_time = 0 ## print "cycle" seconds = datetime.now().strftime('%S') seconds_first_digit = int(seconds[0]) seconds_second_digit = int(seconds[1]) minutes = datetime.now().strftime('%M') minutes_first_digit = int(minutes[0]) minutes_second_digit = int(minutes[1]) hours = datetime.now().strftime('%H') hours_first_digit = int(hours[0]) hours_seconds_digit = int(hours[1]) temp_counter = seconds_second_digit for i in range(4): led_array[i] = 0x01 & temp_counter temp_counter = temp_counter >> 1 temp_counter = seconds_first_digit for i in range(4): led_array[i + 4] = 0x01 & temp_counter temp_counter = temp_counter >> 1 temp_counter = minutes_second_digit for i in range(4): led_array[i + 12] = 0x01 & temp_counter temp_counter = temp_counter >> 1 temp_counter = minutes_first_digit for i in range(4): led_array[i + 17] = 0x01 & temp_counter temp_counter = temp_counter >> 1 temp_counter = hours_seconds_digit for i in range(4): led_array[i + 27] = 0x01 & temp_counter temp_counter = temp_counter >> 1 temp_counter = hours_first_digit for i in range(4): led_array[i + 32] = 0x01 & temp_counter temp_counter = temp_counter >> 1 print hours, minutes, seconds SendArray(led_array, MidiOut)
def get_module_time(self): return pyportmidi.Time()
def ProgramChange(prog): MidiOut.Write([[[0xc0, 0, 0], pypm.Time()]])
def clear(out_device): for i in range(9 * 16): out_device.Write([[[144, i, 0, 0], pypm.Time()]])
def set_all(self, value): t = pypm.Time() data = [] for n in range(0, 136): data.append([[144, n, value, 0], t]) self.out_device.Write(data)
def set(self, col, row, velocity=127): '''Sets the value of a light in the MIDI device's grid.''' index = self.map_ui_to_midi(col, row) self.write_queue.append([[144, index, velocity, 0], pypm.Time()])
def get_midi_time(self): return pypm.Time()
def play_midi_note(self): """PlayMidi Note Separate midi infos to choose the good function for the good action """ #getting time midi_time = pypm.Time() #getting notes midi_notes = self.playing_buffer.get_data(midi_time - self.latency, self.tolerance) self.nb_notes += len(midi_notes) if self.safe_k: midi_notes = self.safe_keyboard.check(midi_notes) if self.permissif: #Building list of lates notes in order to log it new_list = [ midi_notes[i][1] for i in range(len(midi_notes)) if (midi_time > (midi_notes[i][1] + self.latency)) ] if (len(new_list) > 0): self.nb_xrun += 1 if VERBOSE: line = "OUTPUT: time=" + str(midi_time) line += "ms can't play in time , " line += str(len(midi_notes)) line += " notes - late of " calc = (midi_time - (self.latency + new_list[0])) line += str(calc) + " ms" print line note_filtered = midi_notes else: # filter note off program change for notes that are late # if mode non permissif is on skip late notes except # note off, notes with velocitiy 0 or program change note_filtered = [ midi_notes[i] for i in range(len(midi_notes)) if midi_notes[i][1] + self.latency >= midi_time or ( midi_notes[i][0][0] == PROGRAM_CHANGE or midi_notes[i][0] [2] == 0 or midi_notes[i][0][0] == NOTE_OFF) ] if (len(note_filtered) < len(midi_notes)): if VERBOSE: line = "OUTPUT: time=" + str(pypm.Time()) line += "ms can't play in time, " line += str(len(midi_notes) - len(note_filtered)) line += " note(s) skipped, late of: " calc = (midi_time - (self.latency + midi_notes[0][1])) line += str(calc) + " ms" print line #Playing note on the midi device self.midi_out.Write(midi_notes)
def enable(self, threshold): self.O.Write([[[176, threshold, 1], pypm.Time()]])
def set_init_time(self): """Sync set the difference between local midi time and remote midi time in order to apply it to the notes """ self.init_time = pypm.Time()