def onBtnChangeInstrument(self, y, btn): # in this version, we'll actually modify the midi object. unclear if this is the best design. track = self.objMidi.tracks[y] theEvt = None for evt in track.events: if evt.type=='PROGRAM_CHANGE': theEvt = evt break if theEvt is None: return dlg = midirender_choose_midi_voice.ChooseMidiInstrumentDialog(self.frameGrid, 'Choose Instrument', min(theEvt.data,127)) midiNumber = dlg.result if midiNumber is None: return theEvt.data = midiNumber btn['text'] = str(midiNumber) + ' (' + bmidilib.getInstrumentName(midiNumber) + ')'
def onBtnChangeInstrument(self, y, btn): #As of now, this actually modifies the midi object. For good. track = self.objMidi.tracks[y] theEvt = None for evt in track.events: if evt.type=='PROGRAM_CHANGE': theEvt = evt break if theEvt==None: return dlg = midirender_choose_midi_voice.ChooseMidiInstrumentDialog(self.frameGrid, 'Choose Instrument', min(theEvt.data,127)) midiNumber = dlg.result if midiNumber==None: return theEvt.data = midiNumber btn['text'] = str(midiNumber) + ' (' + bmidilib.getInstrumentName(midiNumber) + ')'
def onBtnChangeInstrument(self, y, btn): # in this version, we'll actually modify the midi object. unclear if this is the best design. track = self.objMidi.tracks[y] theEvt = None for evt in track.events: if evt.type == 'PROGRAM_CHANGE': theEvt = evt break if theEvt is None: return dlg = midirender_choose_midi_voice.ChooseMidiInstrumentDialog( self.frameGrid, 'Choose Instrument', min(theEvt.data, 127)) midiNumber = dlg.result if midiNumber is None: return theEvt.data = midiNumber btn['text'] = str(midiNumber) + ' (' + bmidilib.getInstrumentName( midiNumber) + ')'
def loadMidiObj(self, newmidi): self.objMidi = newmidi if self.player.isPlaying(): return False if not self.haveDrawnHeaders: self.drawColumnHeaders() if not self.isMidiLoaded: # check if Timidity is installed if sys.platform != 'win32': if not midirender_runtimidity.isTimidityInstalled(): midirender_util.alert('It appears that the program Timidity is not installed. This program is required for playing and rendering music.\n\nYou could try running something corresponding to "sudo apt-get install timidity" or "sudo yum install timidity++" in a terminal.') self.isMidiLoaded = True # close any open views for key in self.listviews: self.listviews[key].destroy() for key in self.scoreviews: self.scoreviews[key].destroy() self.listviews = {} self.scoreviews = {} self.clearModifications() # hide all of the old widgets for key in self.gridwidgets: w = self.gridwidgets[key] if w.master.is_smallframe==1: w.master.grid_forget() for key in self.gridbuttons: self.gridbuttons[key].grid_forget() def addLabel(text, y, x, isButton=False): # only create a new widget when necessary. This way, don't need to allocate every time a file is opened. if (x, y+1) not in self.gridwidgets: smallFrame = Frame(self.frameGrid, borderwidth=1, relief=RIDGE) smallFrame.is_smallframe=1 if isButton: btn = Button(smallFrame, text=text, relief=GROOVE,anchor='w') btn.config(command=midirender_util.Callable(self.onBtnChangeInstrument, y,btn)) btn.pack(anchor='w', fill=BOTH) btn['disabledforeground'] = 'black' # means that when it is disabled, looks just like a label. sweet. thewidget = btn else: lbl = Label(smallFrame, text=text) lbl.pack(anchor='w') thewidget = lbl self.gridwidgets[(x,y+1)] = thewidget self.gridwidgets[(x,y+1)]['text'] = text self.gridwidgets[(x,y+1)].master.grid(row=y+1, column=x, sticky='nsew') return self.gridwidgets[(x,y+1)] lengthTimer = bmiditools.BMidiSecondsLength(self.objMidi) overallLengthSeconds = lengthTimer.getOverallLength(self.objMidi) self.sliderTime['to'] = max(1.0, overallLengthSeconds+1.0) self.player.load(max(1.0, overallLengthSeconds+1.0)) # "loading" will also set position to 0.0 warnMultipleChannels = False for rownum in range(len(self.objMidi.tracks)): trackobj = self.objMidi.tracks[rownum] # Track Number addLabel( str(rownum), rownum, 0) # Track Name defaultname = 'Condtrack' if rownum==0 else ('Track %d'%rownum) searchFor = {'TRACKNAME':defaultname, 'INSTRUMENTS':1 } res = bmiditools.getTrackInformation(trackobj, searchFor) addLabel(res['TRACKNAME'], rownum, 1) # Track Channel(s) chanarray = self.findNoteChannels(trackobj) if len(chanarray)==0: channame='None' elif len(chanarray)>1: channame='(Many)'; warnMultipleChannels=True else: channame = str(chanarray[0]) addLabel(channame, rownum, 2) countednoteevts = len(trackobj.notelist) # this assumes notelist is valid, and notelist is only valid if we've just read from a file # Track Instrument(s) instarray = res['INSTRUMENTS'] if len(instarray)==0: instname='None' elif len(instarray)>1: instname='(Many)' else: instname = str(instarray[0]) + ' (' + bmidilib.getInstrumentName(instarray[0]) + ')' if channame == '10': instname = '(Percussion channel)' btn = addLabel( instname, rownum, 3, isButton=True) # add a button (not a label) isEnabled = channame!='10' and instname!='None' and instname!='(Many)' # countednoteevts>0 if isEnabled: btn['state'] = NORMAL btn['relief'] = GROOVE else: btn['state'] = DISABLED btn['relief'] = FLAT # if there are multiple inst. changes in a track, we don't let you change instruments because there isn't a convenient way to do that. # Track Time if len(trackobj.notelist)==0: strTime = lengthTimer.secondsToString(0) else: strTime = lengthTimer.secondsToString(lengthTimer.ticksToSeconds(trackobj.notelist[0].time)) addLabel( strTime, rownum, 4) # Track Notes addLabel( str(countednoteevts), rownum, 5) # Buttons if (rownum, 0) not in self.gridbuttons: btn = Button(self.frameGrid, text='Mixer', command=self.openMixerView) self.gridbuttons[(rownum, 0)] = btn self.gridbuttons[(rownum, 0)].grid(row=rownum+1, column=6) if (rownum, 1) not in self.gridbuttons: btn = Button(self.frameGrid, text='Score', command=midirender_util.Callable(self.openScoreView, rownum)) self.gridbuttons[(rownum, 1)] = btn self.gridbuttons[(rownum, 1)].grid(row=rownum+1, column=7) if (rownum, 2) not in self.gridbuttons: btn = Button(self.frameGrid, text='List', command=midirender_util.Callable(self.openListView, rownum)) self.gridbuttons[(rownum, 2)] = btn self.gridbuttons[(rownum, 2)].grid(row=rownum+1, column=8) if warnMultipleChannels: resp = midirender_util.ask_yesno('This midi file has notes from different channels in the same track (format 0). Click "yes" (recommended) to import it as a format 1 file, or "no" to leave it. ') if resp: newmidi = bmiditools.restructureMidi(self.objMidi) newmidi.format = 1 self.loadMidiObj(newmidi) return
def loadMidiObj(self, newmidi): self.objMidi = newmidi if self.player.isPlaying(): return False if not self.haveDrawnHeaders: self.drawColumnHeaders() if not self.isMidiLoaded: # check if Timidity is installed if sys.platform != 'win32': if not midirender_runtimidity.isTimidityInstalled(): midirender_util.alert( 'It appears that the program Timidity is not installed. This program is required for playing and rendering music.\n\nYou could try running something corresponding to "sudo apt-get install timidity" or "sudo yum install timidity++" in a terminal.' ) self.isMidiLoaded = True # close any open views for key in self.listviews: self.listviews[key].destroy() for key in self.scoreviews: self.scoreviews[key].destroy() self.listviews = {} self.scoreviews = {} self.clearModifications() # hide all of the old widgets for key in self.gridwidgets: w = self.gridwidgets[key] if w.master.is_smallframe == 1: w.master.grid_forget() for key in self.gridbuttons: self.gridbuttons[key].grid_forget() def addLabel(text, y, x, isButton=False): # only create a new widget when necessary. This way, don't need to allocate every time a file is opened. if (x, y + 1) not in self.gridwidgets: smallFrame = Frame(self.frameGrid, borderwidth=1, relief=RIDGE) smallFrame.is_smallframe = 1 if isButton: btn = Button(smallFrame, text=text, relief=GROOVE, anchor='w') btn.config(command=midirender_util.Callable( self.onBtnChangeInstrument, y, btn)) btn.pack(anchor='w', fill=BOTH) btn['disabledforeground'] = 'black' # means that when it is disabled, looks just like a label. sweet. thewidget = btn else: lbl = Label(smallFrame, text=text) lbl.pack(anchor='w') thewidget = lbl self.gridwidgets[(x, y + 1)] = thewidget self.gridwidgets[(x, y + 1)]['text'] = text self.gridwidgets[(x, y + 1)].master.grid(row=y + 1, column=x, sticky='nsew') return self.gridwidgets[(x, y + 1)] lengthTimer = bmiditools.BMidiSecondsLength(self.objMidi) overallLengthSeconds = lengthTimer.getOverallLength(self.objMidi) self.sliderTime['to'] = max(1.0, overallLengthSeconds + 1.0) self.player.load(max(1.0, overallLengthSeconds + 1.0)) # "loading" will also set position to 0.0 warnMultipleChannels = False for rownum in range(len(self.objMidi.tracks)): trackobj = self.objMidi.tracks[rownum] # Track Number addLabel(str(rownum), rownum, 0) # Track Name defaultname = 'Condtrack' if rownum == 0 else ('Track %d' % rownum) searchFor = {'TRACKNAME': defaultname, 'INSTRUMENTS': 1} res = bmiditools.getTrackInformation(trackobj, searchFor) addLabel(res['TRACKNAME'], rownum, 1) # Track Channel(s) chanarray = self.findNoteChannels(trackobj) if len(chanarray) == 0: channame = 'None' elif len(chanarray) > 1: channame = '(Many)' warnMultipleChannels = True else: channame = str(chanarray[0]) addLabel(channame, rownum, 2) countednoteevts = len( trackobj.notelist ) # this assumes notelist is valid, and notelist is only valid if we've just read from a file # Track Instrument(s) instarray = res['INSTRUMENTS'] if len(instarray) == 0: instname = 'None' elif len(instarray) > 1: instname = '(Many)' else: instname = str( instarray[0]) + ' (' + bmidilib.getInstrumentName( instarray[0]) + ')' if channame == '10': instname = '(Percussion channel)' btn = addLabel(instname, rownum, 3, isButton=True) # add a button (not a label) isEnabled = channame != '10' and instname != 'None' and instname != '(Many)' # countednoteevts>0 if isEnabled: btn['state'] = NORMAL btn['relief'] = GROOVE else: btn['state'] = DISABLED btn['relief'] = FLAT # if there are multiple inst. changes in a track, we don't let you change instruments because there isn't a convenient way to do that. # Track Time if len(trackobj.notelist) == 0: strTime = lengthTimer.secondsToString(0) else: strTime = lengthTimer.secondsToString( lengthTimer.ticksToSeconds(trackobj.notelist[0].time)) addLabel(strTime, rownum, 4) # Track Notes addLabel(str(countednoteevts), rownum, 5) # Buttons if (rownum, 0) not in self.gridbuttons: btn = Button(self.frameGrid, text='Mixer', command=self.openMixerView) self.gridbuttons[(rownum, 0)] = btn self.gridbuttons[(rownum, 0)].grid(row=rownum + 1, column=6) if (rownum, 1) not in self.gridbuttons: btn = Button(self.frameGrid, text='Score', command=midirender_util.Callable( self.openScoreView, rownum)) self.gridbuttons[(rownum, 1)] = btn self.gridbuttons[(rownum, 1)].grid(row=rownum + 1, column=7) if (rownum, 2) not in self.gridbuttons: btn = Button(self.frameGrid, text='List', command=midirender_util.Callable( self.openListView, rownum)) self.gridbuttons[(rownum, 2)] = btn self.gridbuttons[(rownum, 2)].grid(row=rownum + 1, column=8) if warnMultipleChannels: resp = midirender_util.ask_yesno( 'This midi file has notes from different channels in the same track (format 0). Click "yes" (recommended) to import it as a format 1 file, or "no" to leave it. ' ) if resp: newmidi = bmiditools.restructureMidi(self.objMidi) newmidi.format = 1 self.loadMidiObj(newmidi) return