#!/usr/bin/python from simplemidi.midiplayer import MidiPlayer, _Event, sortTime from simplemidi.midiio import MidiOutputPort from simplemidi.midimessage import MidiType, MidiMessage, NoteOn, NoteOff, MidiVoiceMessage from pad import Pad from simplemidi.options import * import time from simplemidi.midieventtrigger import * class PadHelper(MidiPlayer, Pad): _DEFAULT_PARAMS=dictAssign(MidiPlayer._DEFAULT_PARAMS, Pad._DEFAULT_PARAMS,{ 'port_in': { 'client_name' : 'Pad Helper', 'port_name' : 'Pad In' }, 'port_out': { 'client_name' : 'Pad Helper', 'port_name' : 'Pad Out' }, 'port_sound_out': { 'client_name' : 'MidiPlayer' }, 'pad_track': -1, 'pad_translate' : 0, 'n_color' : 1 }) def __init__(self, adapter, path, params): param=initParams(PadHelper._DEFAULT_PARAMS, params) Pad.__init__(self, adapter, param) MidiPlayer.__init__(self, path, param) self.padTrack = param['pad_track'] self.padTranslate=param['pad_translate'] self.nColor=param['n_color'] if self.padTrack==-1: if self.nTotalTracks>1: self.padTrack=1 else: self.padTrack=0 def setPadTrack(self, n): self.padTrack=n self._load_track_event() def setNKColor(self, n): self.nColor=n self._load_track_event() def setPadTranslate(self, n): self.padTranslate=n def onNoteOn(self, ch, idx, val): self.port.noteOn(ch, idx-self.padTranslate, val) def onNoteOff(self, ch, idx, val): self.port.noteOff(ch, idx-self.padTranslate, val) def send(self, evt) : if evt.track==self.padTrack : if evt.type==MidiType.NOTE_ON: if (evt.key+self.padTranslate+self.transposeNote) in self.ledbuttons: self[evt.key+self.padTranslate+self.transposeNote]=evt.evt.velocity else: MidiPlayer.send(self, evt) def __note_to_notify(self, track, evt, delta, value): ch=evt.channel key=evt.key return _Event(track, ( evt.tick-delta, NoteOn.new(1, key, value))) #return _Event(track, ( evt.tick-delta, NoteOn.new(ch, key, value))) def __notify_off(self, track, evt): return self.__note_to_notify(track, evt, 0, 0) def __notify_on(self, track, evt): return self.__note_to_notify(track, evt, 0, 1) def __notify_croche(self, track, evt): return self.__note_to_notify(track, evt, self.tickCroche(), 5) def __notify_noire(self, track, evt): return self.__note_to_notify(track, evt, self.tickNoire(), 3) def __notify_blanche(self, track, evt): return self.__note_to_notify(track, evt, self.tickBlanche(), 4) def _load_track_event(self): self.events=[] track=self.padTrack for evt in self.tracks[track]: e=_Event(track, evt) if e.type==MidiType.NOTE_ON: if self.nColor>=0: self.events.append(self.__notify_on(track,e)) if self.nColor>=1: self.events.append(self.__notify_croche(track,e)) if self.nColor>=2: self.events.append(self.__notify_noire(track,e)) if self.nColor>=3: self.events.append(self.__notify_blanche(track,e)) if e.type==MidiType.NOTE_OFF: self.events.append(self.__notify_off(track,e)) for track in range(len(self.tracks)): if track==self.padTrack: continue for evt in self.tracks[track]: self.events.append(_Event(track, evt)) self.events.sort(key=sortTime) def onControlChange(self, ch, key, value): if ( ch==1 and key==56): rmin=0.25 rmax=4 if value==0: ratio=rmin else: ratio=(value/127.0)*(rmax-rmin)+rmin self.setBpmRatio(ratio) DEBUG("BPM ratio: %.0f" % ratio, " BPM: %.0f" % (self.bpm*ratio)) def play(self): self._load_track_event() self.tick=0 self.startTime=time.time() for evt in self.events: evt=evt.transpose(self.transposeNote) self.waitForEvent(evt) #if evt.track==self.padTrack and evt.type==MidiType.NOTE_ON: # self[evt.key+self.padTranslate]=evt.evt.velocity self.send(evt)