class FxBallControls(wx.Frame): def __init__(self, parent, fxball, sg_audio, size=(270, 200)): title = "%s Controls" % FX_BALL_TITLES[fxball.getFx()] wx.Frame.__init__(self, parent, -1, title, size=size) self.parent = parent self.fxball = fxball self.sg_audio = sg_audio menuBar = wx.MenuBar() self.menu = wx.Menu() self.menu.Append(200, 'Close\tCtrl+W', "") menuBar.Append(self.menu, "&File") self.SetMenuBar(menuBar) self.Bind(wx.EVT_CLOSE, self.handleClose) self.Bind(wx.EVT_MENU, self.handleClose, id=200) self.panel = wx.Panel(self, -1) self.panel.SetBackgroundColour(BACKGROUND_COLOUR) self.box = wx.BoxSizer(wx.VERTICAL) sl1values = FX_BALL_SLIDER_1_INIT[fxball.getFx()] sl2values = FX_BALL_SLIDER_2_INIT[fxball.getFx()] text = wx.StaticText(self.panel, -1, sl1values[0]) font, psize = text.GetFont(), text.GetFont().GetPointSize() font.SetPointSize(psize - 1) text.SetFont(font) self.box.Add(text, 0, wx.LEFT | wx.RIGHT | wx.TOP, 10) self.box.AddSpacer(2) self.slider1 = ControlSlider(self.panel, sl1values[1], sl1values[2], sl1values[3], log=sl1values[4], size=(250, 16), outFunction=self.handleSlider1) self.box.Add(self.slider1, 0, wx.LEFT | wx.RIGHT, 10) text = wx.StaticText(self.panel, -1, sl2values[0]) text.SetFont(font) self.box.Add(text, 0, wx.LEFT | wx.RIGHT | wx.TOP, 10) self.box.AddSpacer(2) self.slider2 = ControlSlider(self.panel, sl2values[1], sl2values[2], sl2values[3], log=sl2values[4], size=(250, 16), outFunction=self.handleSlider2) self.box.Add(self.slider2, 0, wx.LEFT | wx.RIGHT, 10) text = wx.StaticText(self.panel, -1, "Amplitude") text.SetFont(font) self.box.Add(text, 0, wx.LEFT | wx.RIGHT | wx.TOP, 10) self.box.AddSpacer(2) self.slider3 = ControlSlider(self.panel, 0, 2, 1, size=(250, 16), outFunction=self.handleMul) self.box.Add(self.slider3, 0, wx.LEFT | wx.RIGHT, 10) text = wx.StaticText(self.panel, -1, "Pan") text.SetFont(font) self.box.Add(text, 0, wx.LEFT | wx.RIGHT | wx.TOP, 10) self.box.AddSpacer(2) self.slider4 = ControlSlider(self.panel, 0, 1, 0.5, size=(250, 16), outFunction=self.handlePan) self.box.Add(self.slider4, 0, wx.LEFT | wx.RIGHT | wx.BOTTOM, 10) self.panel.SetSizerAndFit(self.box) if PLATFORM == "win32": X, Y = self.GetSize()[0], self.GetSize()[1] + 50 elif PLATFORM.startswith("linux"): X, Y = self.GetSize()[0], self.GetSize()[1] + 30 else: X, Y = self.GetSize()[0], self.GetSize()[1] + 20 self.SetMinSize((X, Y)) self.SetMaxSize((X, Y)) wx.CallAfter(self.SetSize, (X, Y)) def handleClose(self, event): self.Show(False) def handleSlider1(self, val): self.sg_audio.handleFxSlider1(self.fxball.getFx(), self.fxball.getId(), val) def handleSlider2(self, val): self.sg_audio.handleFxSlider2(self.fxball.getFx(), self.fxball.getId(), val) def handleMul(self, val): self.sg_audio.handleFxMul(self.fxball.getId(), val) def handlePan(self, val): self.sg_audio.handleFxPan(self.fxball.getId(), val) def save(self): return { "slider1": self.slider1.GetValue(), "slider2": self.slider2.GetValue(), "slider3": self.slider3.GetValue(), "slider4": self.slider4.GetValue() } def load(self, dict): self.slider1.SetValue(dict["slider1"]) self.handleSlider1(self.slider1.GetValue()) self.slider2.SetValue(dict["slider2"]) self.handleSlider2(self.slider2.GetValue()) self.slider3.SetValue(dict["slider3"]) self.handleMul(self.slider3.GetValue()) self.slider4.SetValue(dict["slider4"]) self.handlePan(self.slider4.GetValue())
class InsertDialog(wx.Dialog): def __init__(self, parent, id, title, actual_dur, snd_dur): wx.Dialog.__init__(self, parent, id, title) self.SetBackgroundColour(BACKGROUND_COLOUR) vbox = wx.BoxSizer(wx.VERTICAL) stline = wx.StaticText(self, -1, 'Starting point in seconds:') vbox.Add(stline, 1, wx.ALIGN_CENTER_HORIZONTAL | wx.TOP, 10) self.startSlider = ControlSlider(self, 0, snd_dur, 0, outFunction=self.handleStart) vbox.Add(self.startSlider, 0, wx.ALL, 5) stline = wx.StaticText(self, -1, 'Ending point in seconds:') vbox.Add(stline, 1, wx.ALIGN_CENTER_HORIZONTAL | wx.TOP, 10) self.endSlider = ControlSlider(self, 0, snd_dur, snd_dur, outFunction=self.handleEnd) vbox.Add(self.endSlider, 0, wx.ALL, 5) stline = wx.StaticText(self, -1, 'Insertion point in seconds:') vbox.Add(stline, 1, wx.ALIGN_CENTER_HORIZONTAL | wx.TOP, 10) self.insertSlider = ControlSlider(self, 0, actual_dur, 0) vbox.Add(self.insertSlider, 0, wx.ALL, 5) stline = wx.StaticText(self, -1, 'Crossfade time in seconds:') vbox.Add(stline, 1, wx.ALIGN_CENTER_HORIZONTAL | wx.TOP, 10) self.crossfadeSlider = ControlSlider(self, 0.001, snd_dur * 0.5, 0, outFunction=self.handleCross) vbox.Add(self.crossfadeSlider, 0, wx.ALL, 5) sizer = self.CreateButtonSizer(wx.CANCEL | wx.OK) vbox.Add(sizer, 0, wx.ALL, 10) self.SetSizerAndFit(vbox) def handleStart(self, val): start = self.startSlider.GetValue() end = self.endSlider.GetValue() cross = self.crossfadeSlider.GetValue() if start >= (end - .1): self.endSlider.SetValue(start + .1, False) rng = (end - start) * 0.5 if cross > rng: self.crossfadeSlider.SetValue(rng, False) def handleEnd(self, val): start = self.startSlider.GetValue() end = self.endSlider.GetValue() cross = self.crossfadeSlider.GetValue() if end <= (start + .1): self.startSlider.SetValue(end - .1, False) rng = (end - start) * 0.5 if cross > rng: self.crossfadeSlider.SetValue(rng, False) def handleCross(self, val): start = self.startSlider.GetValue() end = self.endSlider.GetValue() cross = self.crossfadeSlider.GetValue() rng = (end - start) * 0.5 if cross > rng: self.crossfadeSlider.SetValue(rng, False) def getValues(self): return (self.startSlider.GetValue(), self.endSlider.GetValue(), self.insertSlider.GetValue(), self.crossfadeSlider.GetValue())
class MidiSettings(wx.Frame): def __init__(self, parent, surface, sg_audio, miDriver): wx.Frame.__init__(self, parent, -1, "Midi Settings") menuBar = wx.MenuBar() self.menu = wx.Menu() self.menu.Append(2010, 'Close\tCtrl+W', "") self.menu.AppendSeparator() self.menu.Append(2011, "Run\tCtrl+R", "", wx.ITEM_CHECK) menuBar.Append(self.menu, "&File") self.SetMenuBar(menuBar) self.Bind(wx.EVT_CLOSE, self.handleClose) self.Bind(wx.EVT_MENU, self.handleClose, id=2010) self.parent = parent self.surface = surface self.sg_audio = sg_audio self.panel = wx.Panel(self, -1) self.panel.SetBackgroundColour(BACKGROUND_COLOUR) mainBox = wx.BoxSizer(wx.VERTICAL) box = wx.BoxSizer(wx.VERTICAL) box.Add(wx.StaticText(self.panel, id=-1, label="Midi Interface"), 0, wx.CENTER | wx.ALL, 2) self.interfaceList, self.interfaceIndexes, selected = checkForMidiDrivers( ) self.interfaceList = [ ensureNFD(driver) for driver in self.interfaceList ] if self.interfaceList != []: self.interfaceList.append("All") self.interfaceIndexes.append(99) if miDriver == None: self.selectedInterface = selected else: if miDriver in self.interfaceList: self.selectedInterface = self.interfaceIndexes[ self.interfaceList.index(miDriver)] else: self.selectedInterface = selected self.popupInterface = wx.Choice(self.panel, id=-1, size=(200, -1), choices=self.interfaceList) if self.selectedInterface: self.popupInterface.SetSelection( self.interfaceIndexes.index(self.selectedInterface)) self.popupInterface.Bind(wx.EVT_CHOICE, self.changeInterface) self.parent.controls.midiInterface = self.selectedInterface else: self.selectedInterface = None self.popupInterface = wx.Choice(self.panel, id=-1, size=(200, -1), choices=["No interface"]) self.popupInterface.SetSelection(0) box.Add(self.popupInterface, 0, wx.LEFT | wx.RIGHT | wx.BOTTOM, 5) box.Add(wx.StaticText(self.panel, id=-1, label="Add / Remove Method"), 0, wx.CENTER | wx.ALL, 2) self.popupMethod = wx.Choice( self.panel, id=-1, size=(200, -1), choices=["Noteon / Noteoff", "Noteon / Noteon"]) self.popupMethod.SetSelection(0) self.popupMethod.Bind(wx.EVT_CHOICE, self.handleMethod) box.Add(self.popupMethod, 0, wx.LEFT | wx.RIGHT | wx.BOTTOM, 5) box.Add(wx.StaticLine(self.panel, size=(200, 1)), 0, wx.ALL, 5) box.Add(wx.StaticText(self.panel, id=-1, label="Pitch Mapping"), 0, wx.CENTER | wx.ALL, 5) self.xTranspo = wx.CheckBox(self.panel, label="Transposition") self.xTranspo.SetValue(True) self.xTranspo.Bind(wx.EVT_CHECKBOX, self.handleTranspo) box.Add(self.xTranspo, 0, wx.ALL, 5) self.xPosition = wx.CheckBox(self.panel, label="X Axis Position") self.xPosition.Bind(wx.EVT_CHECKBOX, self.handlePosition) box.Add(self.xPosition, 0, wx.ALL, 5) box.Add( wx.StaticText(self.panel, id=-1, label="X Position Octave Spread"), 0, wx.CENTER | wx.ALL, 2) self.octaveSpread = ControlSlider(self.panel, 1, 4, 2, size=(200, 16), outFunction=self.handleSpread) self.enableOctaveSpread(self.xPosition.GetValue()) box.Add(self.octaveSpread, 0, wx.LEFT | wx.RIGHT | wx.BOTTOM, 5) mainBox.Add(box, 0, wx.ALL, 10) self.panel.SetSizerAndFit(mainBox) size = (230, 300) self.SetMinSize(size) self.SetMaxSize(size) self.SetPosition( (self.parent.GetPosition()[0] + self.parent.GetSize()[0], self.parent.GetPosition()[1])) self.Show(False) wx.CallAfter(self.SetSize, size) def show(self): self.Show() def handleClose(self, event): self.Show(False) def getInterface(self): if self.selectedInterface == None: return None else: return self.interfaceList[self.interfaceIndexes.index( self.selectedInterface)] def changeInterface(self, evt): status, path = self.parent.checkForMixedSound() if not status: for i, driver in enumerate(self.interfaceList): if driver == self.interfaceList[self.interfaceIndexes.index( self.selectedInterface)]: self.popupInterface.SetSelection(i) return if "Mixed sound" in self.parent.controls.sndPath: self.parent.controls.sndPath = path if path == "": self.parent.panel.sndBitmap = None self.parent.panel.needBitmap = True wx.CallAfter(self.parent.panel.Refresh) selectedInterface = self.popupInterface.GetStringSelection() self.selectedInterface = self.interfaceIndexes[ self.interfaceList.index(selectedInterface)] self.parent.controls.midiInterface = self.selectedInterface self.parent.controls.shutdownServer() self.parent.controls.bootServer() # TODO: replace handle, set and get method with events def handleMethod(self, evt): self.sg_audio.setMidiMethod(self.popupMethod.GetSelection()) def setMethod(self, met): self.popupMethod.SetSelection(met) self.sg_audio.setMidiMethod(met) def getMethod(self): return self.popupMethod.GetSelection() def handleTranspo(self, evt): self.surface.setMidiTranspose(self.xTranspo.GetValue()) def setTranspo(self, value): self.xTranspo.SetValue(value) self.surface.setMidiTranspose(value) def getTranspo(self): return self.xTranspo.GetValue() def handlePosition(self, evt): state = self.xPosition.GetValue() self.surface.setMidiXposition(state) self.enableOctaveSpread(state) def setPosition(self, value): self.xPosition.SetValue(value) self.surface.setMidiXposition(value) self.enableOctaveSpread(value) def getPosition(self): return self.xPosition.GetValue() def enableOctaveSpread(self, state): if state: self.octaveSpread.Enable() else: self.octaveSpread.Disable() def handleSpread(self, value): self.surface.setMidiOctaveSpread(value) def setSpread(self, value): self.octaveSpread.SetValue(value) def getSpread(self): return self.octaveSpread.GetValue() def save(self): return { "method": self.getMethod(), "transpo": self.getTranspo(), "position": self.getPosition(), "spread": self.getSpread() } def load(self, dict): if dict != None: self.setMethod(dict["method"]) self.setTranspo(dict["transpo"]) self.setPosition(dict["position"]) self.setSpread(dict["spread"])
class ControlPanel(scrolled.ScrolledPanel): def __init__(self, parent, surface): scrolled.ScrolledPanel.__init__(self, parent, -1) self.SetBackgroundColour(BACKGROUND_COLOUR) self.parent = parent self.surface = surface self.type = 0 self.selected = 0 self.selectedOkToChange = True self.sndPath = "" self.sndDur = 0.0 self.amplitude = 1 self.nchnls = 2 self.samplingRate = 44100 self.fileformat = 0 self.sampletype = 0 self.tempState = None box = wx.BoxSizer(wx.VERTICAL) box.Add(wx.StaticText(self, -1, "Trajectories"), 0, wx.CENTER | wx.TOP, 3) typeBox = wx.BoxSizer(wx.HORIZONTAL) popupBox = wx.BoxSizer(wx.VERTICAL) self.trajType = wx.Choice(self, -1, choices=['Free', 'Circle', 'Oscil', 'Line']) self.trajType.SetSelection(0) popupBox.Add(self.trajType) typeBox.Add(popupBox, 0, wx.CENTER | wx.RIGHT, 5) # TODO: Check the size of this button on Windows and OSX self.closedToggle = wx.ToggleButton(self, -1, 'Closed', size=self.trajType.GetSize()) font = self.closedToggle.GetFont() if PLATFORM.startswith('linux') or PLATFORM == 'win32': font = wx.Font(8, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL) self.closedToggle.SetFont(font) typeBox.Add(self.closedToggle, wx.CENTER | wx.RIGHT, 5) box.Add(typeBox, 0, wx.CENTER | wx.ALL, 5) self.notebook = wx.Notebook(self, -1, style=wx.BK_DEFAULT | wx.EXPAND) self.notebook.SetBackgroundColour(BACKGROUND_COLOUR) self.drawing = DrawingParameters(self.notebook) self.playback = PlaybackParameters(self.notebook) self.notebook.AddPage(self.drawing, "Drawing") self.notebook.AddPage(self.playback, "Playback") box.Add(self.notebook, 0, wx.ALL, 5) # EQ eqTitle = wx.StaticText(self, id=-1, label="4 Bands Equalizer") box.Add(eqTitle, 0, wx.CENTER) eqFreqBox = wx.BoxSizer(wx.HORIZONTAL) self.knobEqF1 = ControlKnob(self, 40, 250, 100, label='Freq 1', outFunction=self.changeEqF1) eqFreqBox.Add(self.knobEqF1, 0, wx.LEFT | wx.RIGHT, 20) self.knobEqF1.setFloatPrecision(2) self.knobEqF2 = ControlKnob(self, 300, 1000, 500, label='Freq 2', outFunction=self.changeEqF2) eqFreqBox.Add(self.knobEqF2, 0, wx.LEFT | wx.RIGHT, 4) self.knobEqF2.setFloatPrecision(2) self.knobEqF3 = ControlKnob(self, 1200, 5000, 2000, label='Freq 3', outFunction=self.changeEqF3) eqFreqBox.Add(self.knobEqF3, 0, wx.LEFT | wx.RIGHT, 20) self.knobEqF3.setFloatPrecision(2) box.Add(eqFreqBox) eqGainBox = wx.BoxSizer(wx.HORIZONTAL) self.knobEqA1 = ControlKnob(self, -40, 18, 0, label='B1 gain', outFunction=self.changeEqA1) eqGainBox.Add(self.knobEqA1, 0, wx.LEFT | wx.RIGHT, 5) self.knobEqA2 = ControlKnob(self, -40, 18, 0, label='B2 gain', outFunction=self.changeEqA2) eqGainBox.Add(self.knobEqA2, 0, wx.LEFT | wx.RIGHT, 5) self.knobEqA3 = ControlKnob(self, -40, 18, 0, label='B3 gain', outFunction=self.changeEqA3) eqGainBox.Add(self.knobEqA3, 0, wx.LEFT | wx.RIGHT, 5) self.knobEqA4 = ControlKnob(self, -40, 18, 0, label='B4 gain', outFunction=self.changeEqA4) eqGainBox.Add(self.knobEqA4, 0, wx.LEFT | wx.RIGHT, 5) box.Add(eqGainBox) box.Add(wx.StaticLine(self, size=(210, 1)), 0, wx.ALL, 5) #Compress compTitle = wx.StaticText(self, id=-1, label="Dynamic Compressor") box.Add(compTitle, 0, wx.CENTER) cpKnobBox = wx.BoxSizer(wx.HORIZONTAL) self.knobComp1 = ControlKnob(self, -60, 0, -3, label='Thresh', outFunction=self.changeComp1) cpKnobBox.Add(self.knobComp1, 0, wx.LEFT | wx.RIGHT, 5) self.knobComp2 = ControlKnob(self, 1, 10, 2, label='Ratio', outFunction=self.changeComp2) cpKnobBox.Add(self.knobComp2, 0, wx.LEFT | wx.RIGHT, 5) self.knobComp3 = ControlKnob(self, 0.001, 0.5, 0.05, label='Rise', outFunction=self.changeComp3) cpKnobBox.Add(self.knobComp3, 0, wx.LEFT | wx.RIGHT, 5) self.knobComp4 = ControlKnob(self, 0.01, 1, .2, label='Fall', outFunction=self.changeComp4) cpKnobBox.Add(self.knobComp4, 0, wx.LEFT | wx.RIGHT, 5) box.Add(cpKnobBox) box.Add(wx.StaticLine(self, size=(210, 1)), 0, wx.ALL, 5) box.Add(wx.StaticText(self, -1, "Global amplitude (dB)"), 0, wx.LEFT | wx.TOP, 10) ampBox = wx.BoxSizer(wx.HORIZONTAL) self.sl_amp = ControlSlider(self, -60, 18, 0, size=(200, 16), outFunction=self.handleAmp) ampBox.Add(self.sl_amp, 0, wx.LEFT | wx.RIGHT, 5) box.Add(ampBox, 0, wx.LEFT | wx.RIGHT, 5) box.AddSpacer(10) self.meter = VuMeter(self, size=(200, 11)) self.meter.setNumSliders(self.nchnls) box.Add(self.meter, 0, wx.LEFT, 10) box.AddSpacer(5) box.Add(wx.StaticLine(self, size=(210, 1)), 0, wx.ALL, 5) box.Add(wx.StaticText(self, -1, "Project Settings"), 0, wx.CENTER | wx.ALL, 5) projSettingsBox = wx.BoxSizer(wx.HORIZONTAL) srBox = wx.BoxSizer(wx.VERTICAL) srText = wx.StaticText(self, -1, "Rate") srBox.Add(srText, 0, wx.CENTER | wx.LEFT | wx.RIGHT, 5) self.pop_sr = wx.Choice(self, -1, choices=['44100', '48000', '96000'], size=(80, -1)) self.pop_sr.SetSelection(0) self.pop_sr.Bind(wx.EVT_CHOICE, self.handleSamplingRate) srBox.Add(self.pop_sr, 0, wx.LEFT | wx.RIGHT, 5) chnlsBox = wx.BoxSizer(wx.VERTICAL) chnlsText = wx.StaticText(self, -1, "Chnls") chnlsBox.Add(chnlsText, 0, wx.CENTER | wx.LEFT | wx.RIGHT, 5) self.tx_chnls = wx.TextCtrl(self, -1, "2", size=(60, -1), style=wx.TE_PROCESS_ENTER) self.tx_chnls.Bind(wx.EVT_TEXT_ENTER, self.handleNchnls) chnlsBox.Add(self.tx_chnls, 0, wx.LEFT | wx.RIGHT, 5) projSettingsBox.Add(srBox, 0, wx.LEFT | wx.RIGHT | wx.BOTTOM, 5) projSettingsBox.Add(chnlsBox, 0, wx.LEFT | wx.RIGHT | wx.BOTTOM, 5) box.Add(projSettingsBox, 0, wx.ALIGN_CENTER, 5) box.Add(wx.StaticLine(self, size=(210, 1)), 0, wx.ALL, 5) soundBox = wx.BoxSizer(wx.HORIZONTAL) self.tog_audio = wx.ToggleButton(self, -1, "Start", size=(80, -1)) self.tog_audio.SetFont(font) self.tog_audio.Disable() soundBox.Add(self.tog_audio, 0, wx.CENTER | wx.LEFT | wx.RIGHT, 5) box.Add(soundBox, 0, wx.CENTER | wx.ALL, 5) box.Add(wx.StaticLine(self, size=(210, 1)), 0, wx.ALL, 5) box.Add(wx.StaticText(self, -1, "Record Settings"), 0, wx.CENTER | wx.ALL, 5) recSettingsBox = wx.BoxSizer(wx.HORIZONTAL) fileformatBox = wx.BoxSizer(wx.VERTICAL) fileformatText = wx.StaticText(self, -1, "Format") fileformatBox.Add(fileformatText, 0, wx.CENTER | wx.LEFT | wx.RIGHT, 5) self.pop_fileformat = wx.Choice(self, -1, choices=EXPORT_FORMATS, size=(80, -1)) self.pop_fileformat.SetSelection(0) self.pop_fileformat.Bind(wx.EVT_CHOICE, self.handleFileFormat) fileformatBox.Add(self.pop_fileformat, 0, wx.LEFT | wx.RIGHT, 5) sampletypeBox = wx.BoxSizer(wx.VERTICAL) sampletypeText = wx.StaticText(self, -1, "Type") sampletypeBox.Add(sampletypeText, 0, wx.CENTER | wx.LEFT | wx.RIGHT, 5) self.pop_sampletype = wx.Choice(self, -1, choices=EXPORT_TYPES) self.pop_sampletype.SetSelection(0) self.pop_sampletype.Bind(wx.EVT_CHOICE, self.handleSampleType) sampletypeBox.Add(self.pop_sampletype, 0, wx.LEFT | wx.RIGHT, 5) recSettingsBox.Add(fileformatBox, 0, wx.LEFT | wx.RIGHT | wx.BOTTOM, 5) recSettingsBox.Add(sampletypeBox, 0, wx.LEFT | wx.RIGHT | wx.BOTTOM, 5) box.Add(recSettingsBox, 0, wx.ALIGN_CENTER | wx.BOTTOM, 5) rec1Box = wx.BoxSizer(wx.HORIZONTAL) self.tx_rec_folder = wx.TextCtrl(self, -1, "~/Desktop", size=(120, -1)) rec1Box.Add(self.tx_rec_folder, 0, wx.LEFT | wx.RIGHT, 10) self.but_folder = wx.ToggleButton(self, -1, "Choose", size=(65, -1)) self.but_folder.SetFont(font) rec1Box.Add(self.but_folder, 1, wx.ALIGN_CENTER_VERTICAL | wx.EXPAND | wx.RIGHT, 10) rec2Box = wx.BoxSizer(wx.HORIZONTAL) self.tx_output = wx.TextCtrl(self, -1, "snd", size=(120, -1)) rec2Box.Add(self.tx_output, 0, wx.LEFT | wx.RIGHT, 10) self.tog_record = wx.ToggleButton(self, -1, "Start Rec", size=(65, -1)) self.tog_record.SetFont(font) rec2Box.Add(self.tog_record, 1, wx.ALIGN_CENTER_VERTICAL | wx.EXPAND | wx.RIGHT, 10) box.Add(wx.StaticText(self, -1, "Destination"), 0, wx.LEFT | wx.RIGHT, 17) box.Add(rec1Box, 0, wx.EXPAND | wx.BOTTOM | wx.LEFT | wx.RIGHT, 5) box.Add(wx.StaticText(self, -1, "Filename"), 0, wx.LEFT | wx.RIGHT, 17) box.Add(rec2Box, 0, wx.EXPAND | wx.BOTTOM | wx.LEFT | wx.RIGHT, 5) self.Bind(wx.EVT_CHOICE, self.handleType, self.trajType) self.Bind(wx.EVT_TOGGLEBUTTON, self.handleClosed, self.closedToggle) self.Bind(wx.EVT_TOGGLEBUTTON, self.handleAudio, self.tog_audio) self.tx_output.Bind(wx.EVT_CHAR, self.handleOutput) self.tx_rec_folder.Bind(wx.EVT_CHAR, self.handleOutput) self.Bind(wx.EVT_TOGGLEBUTTON, self.handleRecord, self.tog_record) self.Bind(wx.EVT_TOGGLEBUTTON, self.chooseRecFolder, self.but_folder) self.SetAutoLayout(True) self.SetSizerAndFit(box) self.SetupScrolling(scroll_x=False) def changeEqF1(self, x): self.parent.sg_audio.setEqFreq(0, x) def changeEqF2(self, x): self.parent.sg_audio.setEqFreq(1, x) def changeEqF3(self, x): self.parent.sg_audio.setEqFreq(2, x) def getEqFreqs(self): return [ self.knobEqF1.GetValue(), self.knobEqF2.GetValue(), self.knobEqF3.GetValue() ] def setEqFreqs(self, freqs): self.knobEqF1.SetValue(freqs[0]) self.knobEqF2.SetValue(freqs[1]) self.knobEqF3.SetValue(freqs[2]) def changeEqA1(self, x): self.parent.sg_audio.setEqGain(0, math.pow(10.0, x * 0.05)) def changeEqA2(self, x): self.parent.sg_audio.setEqGain(1, math.pow(10.0, x * 0.05)) def changeEqA3(self, x): self.parent.sg_audio.setEqGain(2, math.pow(10.0, x * 0.05)) def changeEqA4(self, x): self.parent.sg_audio.setEqGain(3, math.pow(10.0, x * 0.05)) def getEqAmps(self): return [ self.knobEqA1.GetValue(), self.knobEqA2.GetValue(), self.knobEqA3.GetValue(), self.knobEqA4.GetValue() ] def setEqAmps(self, amps): self.knobEqA1.SetValue(amps[0]) self.knobEqA2.SetValue(amps[1]) self.knobEqA3.SetValue(amps[2]) self.knobEqA4.SetValue(amps[3]) def changeComp1(self, x): self.parent.sg_audio.setCompParam("thresh", x) def changeComp2(self, x): self.parent.sg_audio.setCompParam("ratio", x) def changeComp3(self, x): self.parent.sg_audio.setCompParam("risetime", x) def changeComp4(self, x): self.parent.sg_audio.setCompParam("falltime", x) def getCompValues(self): return [ self.knobComp1.GetValue(), self.knobComp2.GetValue(), self.knobComp3.GetValue(), self.knobComp4.GetValue() ] def setCompValues(self, vals): self.knobComp1.SetValue(vals[0]) self.knobComp2.SetValue(vals[1]) self.knobComp3.SetValue(vals[2]) self.knobComp4.SetValue(vals[3]) def checkEnableWidgets(self): if self.type == 0: self.closedToggle.Enable() else: self.closedToggle.Disable() if self.type == 2: self.drawing.sl_period.Enable() self.drawing.sl_scaling.Enable() else: self.drawing.sl_period.Disable() self.drawing.sl_scaling.Disable() # TODO: replace all these handle, get, set, with single event def handleType(self, event): self.processType(event.GetInt()) def getType(self): return self.type def setType(self, type): self.trajType.SetSelection(type) self.processType(type) def processType(self, type): self.type = type self.surface.setMode(type) self.checkEnableWidgets() def handleClosed(self, event): self.surface.setClosed(event.GetInt()) def getClosed(self): return self.closedToggle.GetValue() def setClosed(self, closed): self.closedToggle.SetValue(closed) self.surface.setClosed(closed) def handleCutoff(self, val): for traj in self.surface.getAllTrajectories(): traj.setFilterFreq(val) def getCutoff(self): return self.drawing.sl_cutoff.GetValue() def setCutoff(self, cutoff): self.drawing.sl_cutoff.SetValue(cutoff) for traj in self.surface.getAllTrajectories(): traj.setFilterFreq(cutoff) def handleQ(self, val): for traj in self.surface.getAllTrajectories(): traj.setFilterQ(val) def getQ(self): return self.drawing.sl_q.GetValue() def setQ(self, q): self.drawing.sl_q.SetValue(q) for traj in self.surface.getAllTrajectories(): traj.setFilterQ(q) def handlePeriod(self, val): self.surface.setOscilPeriod(val) def getPeriod(self): return self.surface.getOscilPeriod() def setPeriod(self, period): self.drawing.sl_period.SetValue(period) self.surface.setOscilPeriod(period) def handleScaling(self, val): self.surface.setOscilScaling(val) def getScaling(self): return self.surface.getOscilScaling() def setScaling(self, scaling): self.drawing.sl_scaling.SetValue(scaling) self.surface.setOscilScaling(scaling) def resetPlaybackSliders(self): selToMax = False if self.selected == MAX_STREAMS: self.selected = 0 selToMax = True timeSpeed = self.surface.getTrajectory(self.selected).getTimeSpeed() self.setTimerSpeed(timeSpeed) step = self.surface.getTrajectory(self.selected).getStep() self.setStep(step) amp = self.surface.getTrajectory(self.selected).getAmplitude() self.setTrajAmp(amp) if selToMax: self.selected = MAX_STREAMS self.surface.needBitmap = True def handleSelected(self, event): if event.GetInt() != self.selected: self.selected = event.GetInt() self.selectedOkToChange = False if self.selected == MAX_STREAMS: self.selectedOkToChange = False self.resetPlaybackSliders() def setSelected(self, selected): self.playback.tog_traj.SetSelection(selected) self.selected = selected self.surface.setSelectedById(selected) self.resetPlaybackSliders() def getSelected(self): return self.selected def handlePopupFocus(self, evt): self.selectedOkToChange = False evt.Skip() def handleTimerSpeed(self, val): if self.selectedOkToChange: if self.selected == MAX_STREAMS: for t in self.surface.getActiveTrajectories(): t.setTimeSpeed(val) else: self.surface.getTrajectory(self.selected).setTimeSpeed(val) else: self.selectedOkToChange = True def setTimerSpeed(self, timeSpeed): self.playback.sl_timespeed.SetValue(timeSpeed, self.selectedOkToChange) def sendTrajSpeed(self, which, speed): self.parent.sg_audio.setMetroTime(which, speed * 0.001) def handleStep(self, val): if self.selectedOkToChange: if self.selected == MAX_STREAMS: for t in self.surface.getActiveTrajectories(): t.setStep(val) else: self.surface.getTrajectory(self.selected).setStep(val) else: self.selectedOkToChange = True def setStep(self, step): self.playback.sl_step.SetValue(step, self.selectedOkToChange) def handleTrajAmp(self, val): val = pow(10.0, float(val) * 0.05) if self.selectedOkToChange: if self.selected == MAX_STREAMS: for t in self.surface.getActiveTrajectories(): t.setAmplitude(val) self.parent.sg_audio.setTrajAmplitude(t.label - 1, val) else: self.surface.getTrajectory(self.selected).setAmplitude(val) self.parent.sg_audio.setTrajAmplitude(self.selected, val) else: self.selectedOkToChange = True def setTrajAmp(self, val): if val <= 0.0: val = 0.0001 self.playback.sl_amp.SetValue(20.0 * math.log10(val), self.selectedOkToChange) def handleAmp(self, val): self.amplitude = pow(10.0, float(val) * 0.05) self.sendAmp() def getAmp(self): return self.amplitude def setAmp(self, amp): if amp <= 0.0: amp = 0.0001 self.sl_amp.SetValue(20.0 * math.log10(amp)) self.amplitude = amp def sendAmp(self): self.parent.sg_audio.setGlobalAmp(self.amplitude) def handleLoad(self): dlg = wx.FileDialog(self, message="Choose a sound file", defaultDir=self.parent.lastAudioPath, wildcard=AUDIO_WILDCARD, style=wx.FD_OPEN) if dlg.ShowModal() == wx.ID_OK: sndPath = dlg.GetPath() self.loadSound(ensureNFD(sndPath)) self.parent.lastAudioPath = os.path.split(sndPath)[0] dlg.Destroy() def handleInsert(self): ok = False dlg = wx.FileDialog(self, message="Choose a sound file to insert", defaultDir=self.parent.lastAudioPath, wildcard=AUDIO_WILDCARD, style=wx.FD_OPEN) if dlg.ShowModal() == wx.ID_OK: ok = True sndPath = dlg.GetPath() self.parent.lastAudioPath = os.path.split(sndPath)[0] dlg.Destroy() if ok: self.insertSound(ensureNFD(sndPath), True) def loadSound(self, sndPath, force=False): if sndPath: if os.path.isfile(sndPath): self.sndPath = sndPath self.parent.sg_audio.loadSnd(self.sndPath) chnls, samprate, dur = soundInfo(self.sndPath) self.sndDur = dur self.chnls = chnls self.sndInfoStr = u'Loaded sound: %s, Sr: %i Hz, Channels: %s, Duration: %.3f sec' % ( self.sndPath, int(samprate), chnls, dur) if self.parent.draw: if not self.sndPath in self.surface.bitmapDict.keys( ) or force: self.parent.log("Drawing waveform...") self.surface.analyse(self.sndPath) else: self.surface.list = self.surface.bitmapDict[ self.sndPath] self.surface.create_bitmap() self.logSndInfo() elif os.path.isfile( os.path.join(self.parent.currentPath, os.path.split(sndPath)[1])): self.loadSound( os.path.join(self.parent.currentPath, os.path.split(sndPath)[1]), force) elif ":\\" in sndPath: # Handle windows path... self.loadSound( os.path.join(self.parent.currentPath, sndPath.split("\\")[-1]), force) else: self.parent.log('Sound file "%s" does not exist!' % sndPath) else: self.parent.log("") def insertSound(self, sndPath, force=False): if not self.sndPath: self.loadSound(sndPath) return if sndPath: if os.path.isfile(sndPath): self.sndPath = "Mixed sound " + str(random.randint(0, 10000)) chnls, samprate, dur = soundInfo(sndPath) dlg = InsertDialog(self, -1, 'Insert sound settings', actual_dur=self.sndDur, snd_dur=dur) refpos = self.surface.GetPosition() refsize = self.surface.GetSize() dlgsize = dlg.GetSize() X = refpos[0] + (refsize[0] / 2 - dlgsize[0] / 2) Y = refpos[1] + (refsize[1] / 2 - dlgsize[1] / 2) dlg.SetPosition((X, Y)) if dlg.ShowModal() == wx.ID_OK: start, end, point, cross = dlg.getValues() ok = True else: ok = False dlg.Destroy() if not ok: return self.parent.sg_audio.insertSnd(sndPath, start, end, point, cross) self.sndDur = self.parent.sg_audio.getTableDuration() self.sndInfoStr = u'Loaded sound: %s, Sr: %s Hz, Channels: %s, Duration: %s sec' % ( self.sndPath, samprate, self.chnls, self.sndDur) if self.parent.draw: if not self.sndPath in self.surface.bitmapDict.keys( ) or force: self.parent.log("Drawing waveform...") self.surface.analyse(self.sndPath) else: self.surface.list = self.surface.bitmapDict[ self.sndPath] self.surface.create_bitmap() self.logSndInfo() elif os.path.isfile( os.path.join(self.parent.currentPath, os.path.split(sndPath)[1])): self.insertSound( os.path.join(self.parent.currentPath, os.path.split(sndPath)[1]), force) elif ":\\" in sndPath: # Handle windows path... self.insertSound( os.path.join(self.parent.currentPath, sndPath.split("\\")[-1]), force) else: self.parent.log('Sound file "%s" does not exist!' % sndPath) def drawWaveform(self): if self.surface.sndBitmap and self.parent.draw: self.surface.analyse(self.sndPath) def getNchnls(self): return self.nchnls def setNchnls(self, x): if x != self.nchnls: self.nchnls = x self.tx_chnls.SetValue(str(x)) self.meter.setNumSliders(self.nchnls) self.shutdownServer() self.bootServer() def handleNchnls(self, event): x = int(self.tx_chnls.GetValue()) if x != self.nchnls: status, path = self.parent.checkForMixedSound() if not status: self.tx_chnls.SetValue(str(self.nchnls)) return if "Mixed sound" in self.sndPath: self.sndPath = path self.nchnls = x self.meter.setNumSliders(self.nchnls) self.shutdownServer() self.bootServer() def getSamplingRate(self): return self.samplingRate def setSamplingRate(self, x): SR = {44100: 0, 48000: 1, 96000: 2} if x != self.samplingRate: self.samplingRate = x self.pop_sr.SetSelection(SR[self.samplingRate]) self.shutdownServer() self.bootServer() def handleSamplingRate(self, event): SR = {0: 44100, 1: 48000, 2: 96000} x = SR[event.GetInt()] if x != self.samplingRate: status, path = self.parent.checkForMixedSound() if not status: SR = {44100: 0, 48000: 1, 96000: 2} self.pop_sr.SetSelection(SR[self.samplingRate]) return if "Mixed sound" in self.sndPath: self.sndPath = path self.samplingRate = x self.shutdownServer() self.bootServer() def getFileFormat(self): return self.fileformat def setFileFormat(self, x): self.fileformat = x self.pop_fileformat.SetSelection(self.fileformat) def handleFileFormat(self, event): self.fileformat = event.GetInt() def getSampleType(self): return self.sampletype def setSampleType(self, x): self.sampletype = x self.pop_sampletype.SetSelection(self.sampletype) def handleSampleType(self, event): self.sampletype = event.GetInt() def bootServer(self): self.parent.sg_audio.boot(self.parent.audioDriver, self.nchnls, self.samplingRate) self.tog_audio.Enable() if self.sndPath != "" and self.tempState == None: self.loadSound(self.sndPath) if self.tempState != None: self.parent.setState(self.tempState) self.tempState = None def shutdownServer(self): self.tempState = self.parent.getState() self.parent.sg_audio.shutdown() self.tog_audio.Disable() self.surface.Refresh() def handleAudio(self, event): if event.GetInt() == 1: if self.sndPath == "": self.parent.log('*** No sound loaded! ***') self.tog_audio.SetValue(0) self.parent.menu.Check(7, False) else: self.tx_chnls.Disable() self.tx_chnls.SetBackgroundColour("#EEEEEE") self.pop_sr.Disable() self.parent.enableDrivers(False) self.tog_audio.SetLabel('Stop') self.tog_audio.SetValue(1) self.parent.menu.Check(7, True) for t in self.surface.getAllTrajectories(): t.initCounter() self.parent.sg_audio.start() else: self.tx_chnls.Enable() self.tx_chnls.SetBackgroundColour("#FFFFFF") self.pop_sr.Enable() self.parent.enableDrivers(True) self.tog_audio.SetLabel('Start') self.tog_audio.SetValue(0) self.parent.menu.Check(7, False) self.tog_record.SetValue(0) self.tog_record.SetLabel('Start Rec') self.parent.sg_audio.stop() def handleOutput(self, event): key = event.GetKeyCode() if key == wx.WXK_TAB or key == wx.WXK_RETURN: self.surface.SetFocus() event.Skip() def setRecordFolder(self, str): self.tx_rec_folder.SetValue(str) def setRecordFilename(self, str): self.tx_output.SetValue(str) def handleRecord(self, event): if event.GetInt() == 1: folder = self.tx_rec_folder.GetValue() if folder.startswith("~"): folder = folder.replace("~", os.path.expanduser("~"), 1) if os.path.isdir(folder): filename = os.path.join(folder, self.tx_output.GetValue()) else: filename = os.path.join(os.path.expanduser('~'), "Desktop", self.tx_output.GetValue()) self.parent.sg_audio.recStart(filename, self.fileformat, self.sampletype) self.tog_record.SetLabel('Stop Rec') else: self.tog_record.SetLabel('Start Rec') self.parent.sg_audio.recStop() def chooseRecFolder(self, evt): dlg = wx.DirDialog( self, message="Choose a folder to save Soundgrain's output sounds...", defaultPath=os.path.expanduser("~")) if dlg.ShowModal() == wx.ID_OK: path = dlg.GetPath() self.tx_rec_folder.SetValue(ensureNFD(path)) dlg.Destroy() self.but_folder.SetValue(0) def logSndInfo(self): self.parent.log(self.sndInfoStr)