def body(self, top): frTop = Frame(top) frTop.grid(row=0, column=0, columnspan=2) Label(frTop, text="Choose instrument:").pack(side=TOP) self.lbPatchChoose = midirender_util.ScrolledListbox(frTop, selectmode=SINGLE, width=30, height=15) self.lbPatchChoose.pack(side=TOP) #fill with all of the voices for instnum in range(128): s = '%03d %s' % (instnum, bmidilib.getInstrumentName(instnum)) self.lbPatchChoose.insert(END, s) self.lbPatchChoose.selection_set(self.defaultInst) self.lbPatchChoose.see(self.defaultInst) self.bind('<MouseWheel>', self.scroll) #binding for Windows self.bind('<Button-4>', self.scroll) #binding for Linux self.bind('<Button-5>', self.scroll) return None # initial focus
def onChangeLbProgChanges(self): index = self.getListboxIndex() state = self.arCustomizationState[index] self.lblInstname.config(text = '%03d %s'%(state['instrument'], bmidilib.getInstrumentName(state['instrument']))) if state['soundfont'].endswith('.pat'): self.lblInstsf.config(text='Soundfont: %s'%(state['soundfont'])) elif state['soundfont'].endswith('.cfg'): self.lblInstsf.config(text='Using patch file specified in:\n %s'%(state['soundfont'])) else: self.lblInstsf.config(text='Soundfont: %s\n bank %d program %d'%(state['soundfont'],state['sf_bank'],state['sf_program']))
def openCustomize(self): self.frameCustomize = Frame(self.frameTop) frameLeft = Frame(self.frameCustomize, border=3, relief=GROOVE, padx=9, pady=9) frameLeft.grid(row=1, column=0, sticky='nsew') frameRight = Frame(self.frameCustomize, border=3, relief=GROOVE, padx=9, pady=9) frameRight.grid(row=1, column=1, sticky='nsew') self.frameCustomize.grid_columnconfigure(0, weight=1, minsize=20) self.frameCustomize.grid_rowconfigure(0, weight=0, minsize=20) Label(frameLeft, text='Instruments').pack(side=TOP) self.lbProgChanges = midirender_util.ScrolledListbox(frameLeft, selectmode=SINGLE, width=25, height=7, exportselection=0) self.lbProgChanges.pack(side=TOP, expand=YES, fill=BOTH) frInst = Frame(frameRight) self.lblInstname = pack(Label(frInst, text='001 Acoustic Grand Piano'), side=LEFT) frInst.pack(side=TOP) self.lblInstsf = pack(Label(frameRight, text='Soundfont: default.sf2 bank 0 program 0'), side=TOP, pady=20) frBtns = Frame(frameRight) Button(frBtns, text='Choose soundfont...',command=self.onBtnChooseSoundfont).pack(side=LEFT, anchor='s') Button(frBtns, text='Choose voice within soundfont...',command=self.onBtnChooseWithinSoundfont).pack(side=LEFT, anchor='s') frBtns.pack(side=TOP) frPrev = Frame(frameRight) Label(frPrev, text='Preview solo:').pack(side=LEFT, anchor='s') Button(frPrev, text='Start',command=self.onBtnPlayStart).pack(side=LEFT, anchor='s') Button(frPrev, text='Stop',command=self.onBtnPlayStop).pack(side=LEFT, anchor='s') frPrev.pack(side=TOP, pady=5) Label(frameRight,text='\n\nChanges remain in effect while this dialog is open.').pack(side=TOP) #fill up self.lbProgChanges for instnum, tracknum in self.objProgramsInMidi : s = '%s (track %d)'%(bmidilib.getInstrumentName(instnum), tracknum) self.lbProgChanges.insert(END, s) self.lbProgChanges.selection_set(0) #create customizationState. note that in self.objProgramsInMidi, instruments are unique, which is nice. self.arCustomizationState = [] for instnum, tracknum in self.objProgramsInMidi: state = {} state['instrument'] = instnum state['soundfont'] = self.main_soundfont_reference[0] state['sf_program'] = instnum state['sf_bank'] = 0 state['originating_track'] = tracknum self.arCustomizationState.append(state) self.current=None self.pollLbProgChanges() #begin polling the listbox. will call first change.
def onChangeLbProgChanges(self): index = self.getListboxIndex() state = self.arCustomizationState[index] self.lblInstname.config( text='%03d %s' % (state['instrument'], bmidilib.getInstrumentName(state['instrument']))) if state['soundfont'].endswith('.pat'): self.lblInstsf.config(text='Soundfont: %s' % (state['soundfont'])) elif state['soundfont'].endswith('.cfg'): self.lblInstsf.config(text='Using patch file specified in:\n %s' % (state['soundfont'])) else: self.lblInstsf.config( text='Soundfont: %s\n bank %d program %d' % (state['soundfont'], state['sf_bank'], state['sf_program']))
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 body(self, top): frTop = Frame(top) frTop.grid(row=0, column=0, columnspan=2) Label(frTop, text="Choose instrument:").pack(side=TOP) self.lbPatchChoose = midirender_util.ScrolledListbox(frTop, selectmode=SINGLE, width=30, height=15) self.lbPatchChoose.pack(side=TOP) #fill with all of the voices for instnum in range(128): s = '%03d %s'%(instnum, bmidilib.getInstrumentName(instnum)) self.lbPatchChoose.insert(END, s) self.lbPatchChoose.selection_set(self.defaultInst) self.lbPatchChoose.see(self.defaultInst) self.bind('<MouseWheel>',self.scroll) #binding for Windows self.bind('<Button-4>',self.scroll) #binding for Linux self.bind('<Button-5>',self.scroll) return None # initial focus
def openCustomize(self): self.frameCustomize = Frame(self.frameTop) frameLeft = Frame(self.frameCustomize, border=3, relief=GROOVE, padx=9, pady=9) frameLeft.grid(row=1, column=0, sticky='nsew') frameRight = Frame(self.frameCustomize, border=3, relief=GROOVE, padx=9, pady=9) frameRight.grid(row=1, column=1, sticky='nsew') self.frameCustomize.grid_columnconfigure(0, weight=1, minsize=20) self.frameCustomize.grid_rowconfigure(0, weight=0, minsize=20) Label(frameLeft, text='Instruments').pack(side=TOP) self.lbProgChanges = midirender_util.ScrolledListbox(frameLeft, selectmode=SINGLE, width=25, height=7, exportselection=0) self.lbProgChanges.pack(side=TOP, expand=YES, fill=BOTH) frInst = Frame(frameRight) self.lblInstname = pack(Label(frInst, text='001 Acoustic Grand Piano'), side=LEFT) frInst.pack(side=TOP) self.lblInstsf = pack(Label( frameRight, text='Soundfont: default.sf2 bank 0 program 0'), side=TOP, pady=20) frBtns = Frame(frameRight) Button(frBtns, text='Choose soundfont...', command=self.onBtnChooseSoundfont).pack(side=LEFT, anchor='s') Button(frBtns, text='Choose voice within soundfont...', command=self.onBtnChooseWithinSoundfont).pack(side=LEFT, anchor='s') frBtns.pack(side=TOP) frAdvanced = Frame(frameRight) Label(frAdvanced, text='Amplify:').pack(side=LEFT, anchor='s') self.varParamAmp = StringVar() self.varParamAmp.set('100') en = Entry(frAdvanced, textvariable=self.varParamAmp, width=5) en.pack(side=LEFT, padx=3) Label(frAdvanced, text='Random delays (ms):').pack(side=LEFT, anchor='s') self.varParamRndDelays = StringVar() self.varParamRndDelays.set('0') en = Entry(frAdvanced, textvariable=self.varParamRndDelays, width=5) en.pack(side=LEFT) frAdvanced.pack(side=TOP, pady=5) frPrev = Frame(frameRight) Label(frPrev, text='Preview solo:').pack(side=LEFT, anchor='s') Button(frPrev, text='Start', command=self.onBtnPlayStart).pack(side=LEFT, anchor='s') Button(frPrev, text='Stop', command=self.onBtnPlayStop).pack(side=LEFT, anchor='s') frPrev.pack(side=TOP, pady=5) Label(frameRight, text='\n\nChanges remain in effect while this dialog is open.' ).pack(side=TOP) #fill up self.lbProgChanges for instnum, tracknum in self.objProgramsInMidi: s = '%s (track %d)' % (bmidilib.getInstrumentName(instnum), tracknum) self.lbProgChanges.insert(END, s) self.lbProgChanges.selection_set(0) #create customizationState. note that in self.objProgramsInMidi, instruments are unique, which is nice. self.arCustomizationState = [] for instnum, tracknum in self.objProgramsInMidi: state = {} state['instrument'] = instnum state['soundfont'] = self.main_soundfont_reference[0] state['sf_program'] = instnum state['sf_bank'] = 0 state['originating_track'] = tracknum state['param_amp'] = '100' state['param_rnddelay'] = '0' self.arCustomizationState.append(state) self.current = None self.pollLbProgChanges( ) #begin polling the listbox. will call first change.
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 conveniant 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) self.loadMidiObj(newmidi) return