From 8b96e767aa50a0f496df8bd79ca2e1b0586f5e58 Mon Sep 17 00:00:00 2001 From: olipet Date: Wed, 03 Jan 2007 03:08:13 +0000 Subject: synthLab in mini-TamTam --- diff --git a/GUI/SynthLab/SynthLabParametersWindow.py b/GUI/SynthLab/SynthLabParametersWindow.py new file mode 100755 index 0000000..e40d07d --- /dev/null +++ b/GUI/SynthLab/SynthLabParametersWindow.py @@ -0,0 +1,185 @@ +import pygtk +pygtk.require('2.0') +import gtk + +from GUI.Core.KeyMapping import * +from GUI.Core.ThemeWidgets import * +from SynthLab.SynthLabConstants import SynthLabConstants +from Framework.Constants import Constants + + +class SynthLabParametersWindow( gtk.Window ): + def __init__( self, instanceID, synthObjectsParameters, writeTables, playNoteFunction ): + gtk.Window.__init__( self, gtk.WINDOW_TOPLEVEL ) + self.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_DIALOG) + self.set_title("SynthLab Parameters") + self.set_position( gtk.WIN_POS_CENTER ) + self.set_default_size(30, 300) + self.set_border_width(0) + self.set_decorated(False) + self.mainBox = RoundVBox(fillcolor='#8F9588', bordercolor='#ACB9A5') + self.mainBox.set_border_width(1) + self.mainBox.set_radius(10) + self.typeBox = gtk.HBox(False, 0) + self.sliderBox = gtk.HBox(False, 0) + self.add_events(gtk.gdk.KEY_PRESS_MASK) + self.add_events(gtk.gdk.KEY_RELEASE_MASK) + self.connect("key-press-event", self.onKeyPress) + self.connect("key-release-event", self.onKeyRelease) + self.instanceID = instanceID + self.objectType = self.instanceID / 4 + self.synthObjectsParameters = synthObjectsParameters + self.writeTables = writeTables + self.playNoteFunction = playNoteFunction + self.playingPitch = [] + + types = SynthLabConstants.CHOOSE_TYPE[self.objectType] + self.choosenType = self.synthObjectsParameters.types[self.instanceID] + + self.initRadioButton( types, self.typeCallback, self.typeBox, self.choosenType ) + self.mainBox.pack_start(self.typeBox) + + selectedType = SynthLabConstants.CHOOSE_TYPE[self.objectType][self.choosenType] + slider1Min = SynthLabConstants.TYPES[selectedType][4] + slider1Max = SynthLabConstants.TYPES[selectedType][5] + slider2Min = SynthLabConstants.TYPES[selectedType][6] + slider2Max = SynthLabConstants.TYPES[selectedType][7] + slider3Min = SynthLabConstants.TYPES[selectedType][8] + slider3Max = SynthLabConstants.TYPES[selectedType][9] + + slider1Step = SynthLabConstants.TYPES[selectedType][10][0] + slider1Digits = SynthLabConstants.TYPES[selectedType][10][1] + slider2Step = SynthLabConstants.TYPES[selectedType][11][0] + slider2Digits = SynthLabConstants.TYPES[selectedType][11][1] + slider3Step = SynthLabConstants.TYPES[selectedType][12][0] + slider3Digits = SynthLabConstants.TYPES[selectedType][12][1] + + parametersTable = self.synthObjectsParameters.choiceParamsSet[self.objectType] + tablePos = (self.instanceID % 4)*4 + slider1Init = parametersTable[tablePos] + slider2Init = parametersTable[tablePos+1] + slider3Init = parametersTable[tablePos+2] + slider4Init = parametersTable[tablePos+3] + + self.p1Adjust = gtk.Adjustment(slider1Init, slider1Min, slider1Max, slider1Step, slider1Step, 0) + self.p1Adjust.connect("value-changed", self.sendTables) + self.slider1 = ImageVScale(Constants.TAM_TAM_ROOT + '/Resources/Images/sliderbutred.png', self.p1Adjust, 7) + self.slider1.set_digits(slider1Digits) + self.slider1.set_value_pos(2) + self.slider1.set_inverted(True) + self.slider1.set_size_request(50, 150) + self.sliderBox.pack_start(self.slider1, True, False) + + self.p2Adjust = gtk.Adjustment(slider2Init, slider2Min, slider2Max, slider2Step, slider2Step, 0) + self.p2Adjust.connect("value-changed", self.sendTables) + self.slider2 = ImageVScale(Constants.TAM_TAM_ROOT + '/Resources/Images/sliderbutred.png', self.p2Adjust, 7) + self.slider2.set_digits(slider2Digits) + self.slider2.set_value_pos(2) + self.slider2.set_inverted(True) + self.slider2.set_size_request(50, 150) + self.sliderBox.pack_start(self.slider2, True, False) + + self.p3Adjust = gtk.Adjustment(slider3Init, slider3Min, slider3Max, slider3Step, slider3Step, 0) + self.p3Adjust.connect("value-changed", self.sendTables) + self.slider3 = ImageVScale(Constants.TAM_TAM_ROOT + '/Resources/Images/sliderbutred.png', self.p3Adjust, 7) + self.slider3.set_digits(slider3Digits) + self.slider3.set_value_pos(2) + self.slider3.set_inverted(True) + self.slider3.set_size_request(50, 150) + self.sliderBox.pack_start(self.slider3, True, False) + + self.p4Adjust = gtk.Adjustment(slider4Init, 0, 1, .01, .01, 0) + self.p4Adjust.connect("value-changed", self.sendTables) + self.slider4 = ImageVScale(Constants.TAM_TAM_ROOT + '/Resources/Images/sliderbutred.png', self.p4Adjust, 7) + self.slider4.set_digits(2) + self.slider4.set_value_pos(2) + self.slider4.set_inverted(True) + self.slider4.set_size_request(50, 150) + self.sliderBox.pack_start(self.slider4, True, False) + + self.mainBox.pack_start(self.sliderBox) + + closeButton = ImageButton(Constants.TAM_TAM_ROOT + '/Resources/Images/stop.png' ) + closeButton.connect('clicked', self.destroy ) + self.mainBox.pack_start(closeButton) + + self.add(self.mainBox) + self.show_all() + + def destroy( self, data ): + self.hide() + + def onKeyPress(self,widget,event): + midiPitch = KEY_MAP[event.hardware_keycode] + if midiPitch not in self.playingPitch: + self.playingPitch.append( midiPitch ) + self.playNoteFunction( midiPitch ) + + def onKeyRelease( self, widget, event ): + midiPitch = KEY_MAP[event.hardware_keycode] + if midiPitch in self.playingPitch: + self.playingPitch.remove( midiPitch ) + + def resize( self ): + selectedType = SynthLabConstants.CHOOSE_TYPE[self.objectType][self.choosenType] + + slider1Init = SynthLabConstants.TYPES[selectedType][0] + slider2Init = SynthLabConstants.TYPES[selectedType][1] + slider3Init = SynthLabConstants.TYPES[selectedType][2] + slider4Init = SynthLabConstants.TYPES[selectedType][3] + + slider1Min = SynthLabConstants.TYPES[selectedType][4] + slider1Max = SynthLabConstants.TYPES[selectedType][5] + slider2Min = SynthLabConstants.TYPES[selectedType][6] + slider2Max = SynthLabConstants.TYPES[selectedType][7] + slider3Min = SynthLabConstants.TYPES[selectedType][8] + slider3Max = SynthLabConstants.TYPES[selectedType][9] + + slider1Step = SynthLabConstants.TYPES[selectedType][10][0] + slider1Digits = SynthLabConstants.TYPES[selectedType][10][1] + slider2Step = SynthLabConstants.TYPES[selectedType][11][0] + slider2Digits = SynthLabConstants.TYPES[selectedType][11][1] + slider3Step = SynthLabConstants.TYPES[selectedType][12][0] + slider3Digits = SynthLabConstants.TYPES[selectedType][12][1] + + self.slider1.set_digits(slider1Digits) + self.slider2.set_digits(slider2Digits) + self.slider3.set_digits(slider3Digits) + + self.p1Adjust.set_all(slider1Init, slider1Min, slider1Max, slider1Step, slider1Step, 0) + self.p2Adjust.set_all(slider2Init, slider2Min, slider2Max, slider2Step, slider2Step, 0) + self.p3Adjust.set_all(slider3Init, slider3Min, slider3Max, slider3Step, slider3Step, 0) + self.p4Adjust.set_all(slider4Init, 0, 1, 0.01, 0.01, 0) + + + def typeCallback( self, widget, choosenType ): + if widget.get_active(): + self.choosenType = choosenType + self.resize() + + def sendTables( self, data ): + self.synthObjectsParameters.setType(self.instanceID, self.choosenType) + sliderListValue = [ self.p1Adjust.value, self.p2Adjust.value, self.p3Adjust.value, self.p4Adjust.value ] + if self.objectType == 0: + for i in range(4): + self.synthObjectsParameters.setControlParameter((self.instanceID % 4)*4+i, sliderListValue[i]) + elif self.objectType == 1: + for i in range(4): + self.synthObjectsParameters.setSourceParameter((self.instanceID % 4)*4+i, sliderListValue[i]) + elif self.objectType == 2: + for i in range(4): + self.synthObjectsParameters.setFxParameter((self.instanceID % 4)*4+i, sliderListValue[i]) + + self.writeTables( self.synthObjectsParameters.types, self.synthObjectsParameters.controlsParameters, + self.synthObjectsParameters.sourcesParameters, self.synthObjectsParameters.fxsParameters ) + + def initRadioButton( self, labelList, methodCallback, box, active ): + for i in range( len( labelList ) ): + if i == 0: + button = gtk.RadioButton( None, labelList[ i ] ) + else: + button = gtk.RadioButton( button, labelList[ i ] ) + if i == active: + button.set_active(True) + button.connect( "toggled", methodCallback, i ) + box.pack_start( button, False, False ) diff --git a/GUI/SynthLab/SynthLabWindow.py b/GUI/SynthLab/SynthLabWindow.py new file mode 100755 index 0000000..f9b71d1 --- /dev/null +++ b/GUI/SynthLab/SynthLabWindow.py @@ -0,0 +1,498 @@ +import pygtk +pygtk.require('2.0') +import gtk +import time +import shelve + +from GUI.Core.KeyMapping import * +from GUI.Core.ThemeWidgets import * +from Framework.CSound.CSoundClient import CSoundClient +from Framework.Constants import Constants +from GUI.SynthLab.SynthLabParametersWindow import SynthLabParametersWindow +from SynthLab.SynthObjectsParameters import SynthObjectsParameters +from SynthLab.SynthLabConstants import SynthLabConstants + +class SynthLabWindow( gtk.Window ): + def __init__( self, client ): + gtk.Window.__init__( self, gtk.WINDOW_TOPLEVEL ) + color = gtk.gdk.color_parse('#FFFFFF') + self.modify_bg(gtk.STATE_NORMAL, color) + self.set_border_width(10) + self.csnd = client + self.set_decorated(False) + self.synthObjectsParameters = SynthObjectsParameters() + self.locations = SynthLabConstants.INIT_LOCATIONS[:] + self.buttonState = 0 + self.duration = 1 + self.playingPitch = [] + self.connections = [] + self.straightConnections = [] + self.cablesPoints = [] + self.pix = 8 + self.add_events(gtk.gdk.KEY_PRESS_MASK) + self.add_events(gtk.gdk.KEY_RELEASE_MASK) + self.connect("key-press-event", self.onKeyPress) + self.connect("key-release-event", self.onKeyRelease) + self.setupWindow() + + def setupWindow( self ): + self.set_position( gtk.WIN_POS_CENTER_ON_PARENT ) + self.set_title("Synth Lab") + self.set_border_width(0) + self.mainBox = gtk.VBox(spacing=2) + self.mainBox.set_border_width(2) + self.drawingBox = RoundVBox(fillcolor='#ACB9A5', spacing=1) + self.drawingBox.set_border_width(1) + self.drawingBox.set_radius(10) + self.mainBox.pack_start(self.drawingBox) + self.commandBox = gtk.HBox(spacing=2) + self.sliderBox = RoundHBox(fillcolor='#8F9588', spacing=1) + self.sliderBox.set_border_width(1) + self.sliderBox.set_radius(10) + self.commandBox.pack_start(self.sliderBox) + self.buttonBox = RoundHBox(fillcolor='#8F9588', spacing=1) + self.buttonBox.set_border_width(1) + self.buttonBox.set_radius(10) + self.commandBox.pack_start(self.buttonBox) + self.mainBox.pack_start(self.commandBox) + + self.drawingArea = gtk.DrawingArea() + self.drawingArea.set_size_request(1200, 830) + self.col = gtk.gdk.color_parse('#ACB9A5') + self.drawingArea.modify_bg(gtk.STATE_NORMAL, self.col) + self.drawingArea.add_events(gtk.gdk.BUTTON_PRESS_MASK) + self.drawingArea.add_events(gtk.gdk.BUTTON_RELEASE_MASK) + self.drawingArea.add_events(gtk.gdk.POINTER_MOTION_MASK) + self.drawingArea.connect( "button-press-event", self.handleButtonPress ) + self.drawingArea.connect( "button-release-event", self.handleButtonRelease ) + self.drawingArea.connect( "motion-notify-event", self.handleMotion ) + self.drawingArea.connect("expose-event", self.draw) + self.drawingBox.pack_start(self.drawingArea, False, False, 5) + + self.durAdjust = gtk.Adjustment(1, .5, 4, .01, .01, 0) + self.durAdjust.connect("value-changed", self.handleDuration) + self.durationSlider = ImageHScale( Constants.TAM_TAM_ROOT + "/Resources/Images/sliderbutviolet.png", self.durAdjust, 7 ) + self.durationSlider.set_digits(2) + self.durationSlider.set_value_pos(1) + self.durationSlider.set_inverted(False) + self.durationSlider.set_size_request(600, 30) + self.sliderBox.pack_start(self.durationSlider, True, True, 5) + + saveButton = ImageButton(Constants.TAM_TAM_ROOT + '/Resources/Images/record.png') + saveButton.set_size_request(100, 50) + saveButton.connect("clicked", self.handleSave, None) + self.buttonBox.pack_start(saveButton, False, False, 2) + + loadButton = ImageButton(Constants.TAM_TAM_ROOT + '/Resources/Images/record.png') + loadButton.set_size_request(100, 50) + loadButton.connect("clicked", self.handleLoad, None) + self.buttonBox.pack_start(loadButton, False, False, 2) + + recordButton = ImageButton(Constants.TAM_TAM_ROOT + '/Resources/Images/record.png') + recordButton.set_size_request(100, 50) + recordButton.connect("clicked", self.recordSound) + self.buttonBox.pack_start(recordButton, False, False, 2) + + resetButton = ImageButton(Constants.TAM_TAM_ROOT + '/Resources/Images/record.png') + resetButton.set_size_request(100, 50) + resetButton.connect("clicked", self.handleReset, None) + self.buttonBox.pack_start(resetButton, False, False, 2) + + closeButton = ImageButton(Constants.TAM_TAM_ROOT + '/Resources/Images/record.png') + closeButton.set_size_request(100, 50) + closeButton.connect("clicked", self.handleClose, None) + self.buttonBox.pack_start(closeButton, False, False, 2) + + self.add(self.mainBox) + + self.writeTables( self.synthObjectsParameters.types, self.synthObjectsParameters.controlsParameters, + self.synthObjectsParameters.sourcesParameters, self.synthObjectsParameters.fxsParameters ) + + def onKeyPress(self,widget,event): + midiPitch = KEY_MAP[event.hardware_keycode] + if midiPitch not in self.playingPitch: + self.playingPitch.append( midiPitch ) + self.playNote( midiPitch ) + + def onKeyRelease( self, widget, event ): + midiPitch = KEY_MAP[event.hardware_keycode] + if midiPitch in self.playingPitch: + self.playingPitch.remove( midiPitch ) + + def handleDuration( self, data ): + self.duration = self.durAdjust.value + + def playNote( self, midiPitch ): + cpsPitch = 261.626*pow(1.0594633, midiPitch-36) + mess = "perf.InputMessage('i5203 0 " + str(self.duration) + " " + str(cpsPitch) + "')" + self.csnd.sendText( mess ) + + def handleClose( self, widget, data ): + self.hide() + + def handleReset( self, widget, data ): + self.locations = SynthLabConstants.INIT_LOCATIONS[:] + self.duration = 1 + self.connections = [] + self.synthObjectsParameters.__init__() + self.writeTables( self.synthObjectsParameters.types, self.synthObjectsParameters.controlsParameters, + self.synthObjectsParameters.sourcesParameters, self.synthObjectsParameters.fxsParameters ) + self.synthObjectsParameters.update() + time.sleep(.01) + self.allConnections() + self.controlToSrcConnections() + time.sleep(.01) + self.controlToFxConnections() + time.sleep(.01) + self.audioConnections() + time.sleep(.01) + self.queue_draw() + + def handleButtonRelease( self, widget, event ): + if self.buttonState: + self.buttonState = 0 + self.queue_draw() + + def handleButtonPress( self, widget, event): + if event.button == 1: + for i in self.locations: + if (i[0]-self.pix) < event.x < (i[0]+self.pix) and (i[1]+(SynthLabConstants.HALF_SIZE-self.pix)) < event.y < (i[1]+(SynthLabConstants.HALF_SIZE+self.pix)) and self.locations.index(i) < 12: + self.setConnection( 1, event, self.locations.index(i) ) + gate = 0 + break + elif (i[0]-SynthLabConstants.HALF_SIZE) < event.x < (i[0]+SynthLabConstants.HALF_SIZE) and (i[1]-(SynthLabConstants.HALF_SIZE+self.pix)) < event.y < (i[1]-(SynthLabConstants.HALF_SIZE-self.pix)) and 3 < self.locations.index(i) < 8: + self.setConnection( 2, event, self.locations.index(i) ) + gate = 0 + break + elif (i[0]+(SynthLabConstants.HALF_SIZE-self.pix)) < event.x < (i[0]+(SynthLabConstants.HALF_SIZE+self.pix)) and (i[1]-SynthLabConstants.HALF_SIZE) < event.y < (i[1]+SynthLabConstants.HALF_SIZE) and self.locations.index(i) > 7: + self.setConnection( 2, event, self.locations.index(i) ) + gate = 0 + break + elif (i[0]-self.pix) < event.x < (i[0]+self.pix) and (i[1]-(SynthLabConstants.HALF_SIZE+self.pix)) < event.y < (i[1]-(SynthLabConstants.HALF_SIZE-self.pix)) and self.locations.index(i) > 7: + self.setConnection( 2, event, self.locations.index(i) ) + gate = 0 + break + elif (i[0]-SynthLabConstants.HALF_SIZE) < event.x < (i[0]+SynthLabConstants.HALF_SIZE) and (i[1]-SynthLabConstants.HALF_SIZE) < event.y < (i[1]+SynthLabConstants.HALF_SIZE): + self.buttonState = 1 + self.choosen = self.locations.index(i) + gate = 0 + break + else: + gate = 1 + if gate: + self.deleteCable( event ) + elif event.button == 3: + for i in self.locations: + if (i[0]-SynthLabConstants.HALF_SIZE) < event.x < (i[0]+SynthLabConstants.HALF_SIZE) and (i[1]-SynthLabConstants.HALF_SIZE) < event.y < (i[1]+SynthLabConstants.HALF_SIZE): + instanceID = self.locations.index(i) + self.synthLabParametersWindow = SynthLabParametersWindow( instanceID, self.synthObjectsParameters, self.writeTables, self.playNote ) + + def handleMotion( self, widget, event ): + if self.buttonState == 1 and self.choosen != 12: + if 0+SynthLabConstants.HALF_SIZE < event.x < 1200-SynthLabConstants.HALF_SIZE: + X = event.x + if 0+SynthLabConstants.HALF_SIZE < event.y < 820-SynthLabConstants.HALF_SIZE: + Y = event.y + self.mouse = [ X, Y ] + self.locations[self.choosen] = [ X, Y ] + if Y > 720: + self.queue_draw_area(0,710, 1200, 120) + else: + self.queue_draw_area(X-40, Y-40, 80, 80) + + def setConnection( self, gate, event, sourceLocation ): + if gate == 1: # output connection + self.temp = [] + self.temp.append( (sourceLocation, 0, SynthLabConstants.HALF_SIZE ) ) + if gate == 2: + # source control parameter input connection + if self.temp[0][0] < 4 and sourceLocation < 8: + first = self.nearest(event.x - self.locations[sourceLocation][0], [-18, -6, 7, 20]) + second = -SynthLabConstants.HALF_SIZE + self.temp.append( (sourceLocation, first, second, 0) ) + self.connections.append( self.temp ) + # fx control parameter input connection + if self.temp[0][0] < 4 and 7 < sourceLocation < 12: + first = SynthLabConstants.HALF_SIZE + second = self.nearest(event.y - self.locations[sourceLocation][1], [-15, -5, 5, 15]) + self.temp.append( (sourceLocation, first, second, 0) ) + self.connections.append( self.temp ) + # source and fx to fx and out connection + if self.temp[0][0] > 3 and self.temp[0][0] < 12 and sourceLocation > 7: + refused = self.connectionGating() + if sourceLocation not in refused: + first = 0 + second = -SynthLabConstants.HALF_SIZE + else: + print 'refused' + self.temp.append( (sourceLocation, first, second, 0) ) + self.connections.append( self.temp ) + self.allConnections() + self.controlToSrcConnections() + time.sleep(.01) + self.controlToFxConnections() + time.sleep(.01) + self.audioConnections() + time.sleep(.01) + lastTable = [0]*12 + for i in range(12): + if i in self.outputs: + lastTable[i] = (self.synthObjectsParameters.types[i]+1) + mess = "perf.InputMessage('f5203 0 16 -2 " + " " .join([str(n) for n in lastTable]) + " 0 0 0 0')" + self.csnd.sendText( mess ) + time.sleep(.01) + self.queue_draw() + + def nearest( self, val, mainList ): + diffList = [abs(i-val) for i in mainList] + return mainList[diffList.index(min(diffList))] + + def draw( self, widget, event ): + context = self.drawingArea.window.cairo_create() + context.set_line_width( 2 ) + context.move_to(0, 740) + context.line_to(1200, 740) + if self.buttonState == 1: + for i in self.locations: + X, Y = i[0], i[1] + context.move_to(X-20, Y-20) + context.line_to(X+20, Y-20) + context.line_to(X+20, Y+20) + context.line_to(X-20, Y+20) + context.line_to(X-20, Y-20) + elif self.buttonState == 0: + for i in self.locations: + if i[1] > 740: + ind = self.locations.index(i) + self.locations[ind][0] = SynthLabConstants.INIT_LOCATIONS[ind][0] + self.locations[ind][1] = SynthLabConstants.INIT_LOCATIONS[ind][1] + for i in self.locations: + index = self.locations.index(i) + context.set_source_pixbuf(self.pixbufs[index], i[0]-SynthLabConstants.HALF_SIZE, i[1]-SynthLabConstants.HALF_SIZE) + context.paint() + if self.connections and not self.buttonState: + for i in self.connections: + context.move_to( self.locations[i[0][0]][0]+i[0][1], self.locations[i[0][0]][1]+i[0][2]) + context.line_to( self.locations[i[1][0]][0]+i[1][1], self.locations[i[1][0]][1]+i[1][2]) + context.set_source_rgb( .5, .5, .5 ) + context.stroke() + + def connectionGating( self ): + self.straightConnections = [[i[0][0], i[1][0]] for i in self.connections] + self.fxConnections = [i for i in self.straightConnections if 7 < i[0] < 12 and 7 < i[1] < 12] + + fxConnectionRefused = [i[0] for i in self.fxConnections if i[1] == self.temp[0][0]] + fxConnectionRefused2 = [k[0] for j in fxConnectionRefused for k in self.fxConnections if k[1] == j] + fxConnectionRefused.extend(fxConnectionRefused2) + + return fxConnectionRefused + + def writeTables( self, typesTable, controlParametersTable, sourceParametersTable, fxParametersTable ): + mess = "perf.InputMessage('f5200 0 16 -2 " + " " .join([str(n) for n in controlParametersTable]) + "')" + self.csnd.sendText( mess ) + time.sleep(.01) + mess = "perf.InputMessage('f5201 0 16 -2 " + " " .join([str(n) for n in sourceParametersTable]) + "')" + self.csnd.sendText( mess ) + time.sleep(.01) + mess = "perf.InputMessage('f5202 0 16 -2 " + " " .join([str(n) for n in fxParametersTable]) + "')" + self.csnd.sendText( mess ) + time.sleep(.01) + lastTable = [0]*12 + self.allConnections() + for i in range(12): + if i in self.outputs: + lastTable[i] = (typesTable[i]+1) + mess = "perf.InputMessage('f5203 0 16 -2 " + " " .join([str(n) for n in lastTable]) + " 0 0 0 0')" + self.csnd.sendText( mess ) + time.sleep(.01) + self.loadPixbufs() + + def recordSound( self, data ): + self.csnd.sendText( "perf.InputMessage('i5204 0.01 1 75')") + time.sleep(0.01) + self.playNote( 36 ) + + def allConnections( self ): + self.straightConnections = [] + self.outputs = [] + self.inputs = [] + self.checkConnections = [] + self.cablesPoints = [] + for i in self.connections: + first = i[0][0] + second = i[1][0] + self.straightConnections.append([first, second]) + self.outputs.append(first) + self.inputs.append(second) + self.checkConnections.extend([first, second]) + firstX = self.locations[i[0][0]][0] + i[0][1] + firstY = self.locations[i[0][0]][1] + i[0][2] + secondX = self.locations[i[1][0]][0] + i[1][1] + secondY = self.locations[i[1][0]][1] + i[1][2] + XPoint = [int(firstX), int(secondX)] + YPoint = [int(firstY), int(secondY)] + self.cablesPoints.append([XPoint, YPoint]) + + def deleteCable( self, event ): + if self.cablesPoints: + gate = 1 + for point in self.cablesPoints: + Xmin = min(point[0]) + Xmax = max(point[0]) + Ymin = min(point[1]) + Ymax = max(point[1]) + if event.x in range(Xmin, Xmax) and event.y in range(Ymin, Ymax): + XDiff = (event.x - Xmin) / (Xmax - Xmin) + YDiff = (event.y - Ymin) / (Ymax - Ymin) + if Xmin == point[0][0] and Ymin == point[1][0] or Xmax == point[0][0] and Ymax == point[1][0]: + if -.08 < (XDiff - YDiff) < .08: + if gate: + del self.connections[self.cablesPoints.index(point)] + self.connectAndDraw() + gate = 0 + else: + if .92 < (XDiff + YDiff) < 1.08: + if gate: + del self.connections[self.cablesPoints.index(point)] + self.connectAndDraw() + gate = 0 + + def connectAndDraw( self ): + self.allConnections() + self.controlToSrcConnections() + time.sleep(.01) + self.controlToFxConnections() + time.sleep(.01) + self.audioConnections() + time.sleep(.01) + self.queue_draw_area(0, 0, 1200, 790) + + def controlToSrcConnections( self ): + self.contSrcConnections = [] + for i in self.connections: + if i[0][0] < 4 and 3 < i[1][0] < 8: + offset = (SynthLabConstants.HALF_SIZE+i[1][1]) / (SynthLabConstants.PIC_SIZE/4) + self.contSrcConnections.append([i[0][0], i[1][0], offset]) + table = [0 for i in range(16)] + sources = [source for source in range(4,8) if source in self.outputs] + for source in sources: + for entre in range(4): + value = sum([2**(li[0]+1) for li in self.contSrcConnections if li[1] == source and li[2] == entre], 1) + table[(source % 4) * 4 + entre] = value + mess = "perf.InputMessage('f5204 0 16 -2 " + " " .join([str(n) for n in table]) + "')" + self.csnd.sendText( mess ) + + def controlToFxConnections( self ): + self.contFxConnections = [] + for i in self.connections: + if i[0][0] < 4 and 7 < i[1][0] < 12: + offset = ((SynthLabConstants.HALF_SIZE/2)+i[1][2]) / (SynthLabConstants.PIC_SIZE/6) + self.contFxConnections.append([i[0][0], i[1][0], offset]) + table = [0 for i in range(16)] + fxs = [fx for fx in range(8,12) if fx in self.outputs] + for fx in fxs: + for entre in range(4): + value = sum([2**(li[0]+1) for li in self.contFxConnections if li[1] == fx and li[2] == entre], 1) + table[(fx % 4) * 4 + entre] = value + mess = "perf.InputMessage('f5205 0 16 -2 " + " " .join([str(n) for n in table]) + "')" + self.csnd.sendText( mess ) + + def audioConnections( self ): + self.srcFxConnections = [i for i in self.straightConnections if 3 < i[0] < 8 and 7 < i[1] < 12] + self.fxConnections = [i for i in self.straightConnections if 7 < i[0] < 12 and 7 < i[1] < 12] + self.outConnections = [i[0] for i in self.straightConnections if i[1] == 12] + + table = [] + for fx in range(8, 12): + value = 0 + for li in self.srcFxConnections: + if li[1] == fx: + value += pow(2, li[0]-4) + table.append(value) + + for fx in range(8, 12): + value = 0 + for li in self.fxConnections: + if li[1] == fx: + value += pow(2, li[0]-8) + table.append(value) + + for sig in range(4, 12): + value = 0 + if sig in self.outConnections: + value = 1 + table.append(value) + mess = "perf.InputMessage('f5206 0 16 -2 " + " " .join([str(n) for n in table]) + "')" + self.csnd.sendText( mess ) + + def loadPixbufs( self ): + self.pixbufs = [] + for i in self.locations: + if self.locations.index(i) < 4: + self.pixbufs.append(gtk.gdk.pixbuf_new_from_file(Constants.TAM_TAM_ROOT + '/Resources/Images/control.png')) + elif self.locations.index(i) < 8: + self.pixbufs.append(gtk.gdk.pixbuf_new_from_file(Constants.TAM_TAM_ROOT + '/Resources/Images/source.png')) + elif self.locations.index(i) < 12: + self.pixbufs.append(gtk.gdk.pixbuf_new_from_file(Constants.TAM_TAM_ROOT + '/Resources/Images/filtre.png')) + else: + self.pixbufs.append(gtk.gdk.pixbuf_new_from_file(Constants.TAM_TAM_ROOT + '/Resources/Images/speaker.png')) + + def handleSave(self, widget, data): + chooser = gtk.FileChooserDialog(title=None,action=gtk.FILE_CHOOSER_ACTION_SAVE, buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_SAVE,gtk.RESPONSE_OK)) + + if chooser.run() == gtk.RESPONSE_OK: + try: + print 'INFO: save SynthLab file %s' % chooser.get_filename() + f = shelve.open( chooser.get_filename(), 'n') + self.saveState(f) + f.close() + except IOError: + print 'ERROR: failed to save SynthLab to file %s' % chooser.get_filename() + + chooser.destroy() + + def handleLoad(self, widget, data): + chooser = gtk.FileChooserDialog(title=None,action=gtk.FILE_CHOOSER_ACTION_OPEN, buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN,gtk.RESPONSE_OK)) + + if chooser.run() == gtk.RESPONSE_OK: + try: + print 'INFO: load SynthLab state from file %s' % chooser.get_filename() + f = shelve.open( chooser.get_filename(), 'r') + self.loadState(f) + f.close() + except IOError: + print 'ERROR: failed to load SynthLab state from file %s' % chooser.get_filename() + + chooser.destroy() + + def saveState( self, state ): + state['types'] = self.synthObjectsParameters.types + state['controls'] = self.synthObjectsParameters.controlsParameters + state['sources'] = self.synthObjectsParameters.sourcesParameters + state['fxs'] = self.synthObjectsParameters.fxsParameters + state['locations'] = self.locations + state['connections'] = self.connections + state['duration'] = self.duration + + def loadState( self, state ): + self.synthObjectsParameters.types = state['types'] + self.synthObjectsParameters.controlsParameters = state['controls'] + self.synthObjectsParameters.sourcesParameters = state['sources'] + self.synthObjectsParameters.fxsParameters = state['fxs'] + self.locations = state['locations'] + self.connections = state['connections'] + self.duration = state['duration'] + + self.writeTables( self.synthObjectsParameters.types, self.synthObjectsParameters.controlsParameters, + self.synthObjectsParameters.sourcesParameters, self.synthObjectsParameters.fxsParameters ) + self.synthObjectsParameters.update() + time.sleep(.01) + self.allConnections() + self.controlToSrcConnections() + time.sleep(.01) + self.controlToFxConnections() + time.sleep(.01) + self.audioConnections() + time.sleep(.01) + self.queue_draw() + diff --git a/GUI/SynthLab/__init__.py b/GUI/SynthLab/__init__.py new file mode 100755 index 0000000..e69de29 --- /dev/null +++ b/GUI/SynthLab/__init__.py diff --git a/Resources/Images/control.png b/Resources/Images/control.png new file mode 100755 index 0000000..8435cfb --- /dev/null +++ b/Resources/Images/control.png Binary files differ diff --git a/Resources/Images/filtre.png b/Resources/Images/filtre.png new file mode 100755 index 0000000..705b930 --- /dev/null +++ b/Resources/Images/filtre.png Binary files differ diff --git a/Resources/Images/source.png b/Resources/Images/source.png new file mode 100755 index 0000000..4b1faca --- /dev/null +++ b/Resources/Images/source.png Binary files differ diff --git a/Resources/Images/speaker.png b/Resources/Images/speaker.png new file mode 100755 index 0000000..bf39d6d --- /dev/null +++ b/Resources/Images/speaker.png Binary files differ diff --git a/SynthLab/SynthLabConstants.py b/SynthLab/SynthLabConstants.py new file mode 100755 index 0000000..d60faba --- /dev/null +++ b/SynthLab/SynthLabConstants.py @@ -0,0 +1,33 @@ +class SynthLabConstants: + + PIC_SIZE = 60 + HALF_SIZE = PIC_SIZE / 2 + + INIT_LOCATIONS = [ [100,790], [160,790], [220,790], [280, 790], [510,790], [570,790], + [630,790], [690, 790], [920,790], [980,790], [1040,790], [1100, 790], [600, 670]] + + FLOAT = [.01, 2] + INTEGER = [1, 0] + + # s1 s2 s3 s4 s1min s1max s2min s2max s3min s3max [s1step s1digits] [s2step s2digits] [s3step s3digits] + TYPES = { 'LFO': [.5, 1, 0, 1, 0, 1, 0, 20, 0, 5, FLOAT, FLOAT, INTEGER], + 'random': [.5, 1.5, 2, 1, 0, 2, 0, 2, 0, 20, FLOAT, FLOAT, FLOAT], + 'ADSR': [.02, .05, .8, .1, 0, 1, 0, 1, 0, 1, FLOAT, FLOAT, FLOAT], + 'FM': [1, .5, 5, 1, 0, 2, 0, 2, 0, 10, FLOAT, FLOAT, FLOAT], + 'buzz': [1, 30, .85, 1, 0, 2, 0, 40, 0, 1, FLOAT, INTEGER, FLOAT], + 'vco': [1, 1, .2, 1, 0, 2, 0, 2, 0, .5, FLOAT, INTEGER, FLOAT], + 'pluck': [1, 0, 0, 1, 0, 2, 0, 0, 0, 0, FLOAT, INTEGER, INTEGER], + 'noise': [1, 0, 0, 1, 0, 2, 0, 0, 0, 0, INTEGER, INTEGER, INTEGER], + 'samples': [1, 5, 0, 1, 0, 2, 0, 75, 0, 0, FLOAT, INTEGER, INTEGER], + 'voice': [1, 3, 0, 1, 0, 2, 0, 15, 0, 0, FLOAT, INTEGER, INTEGER], + 'wguide': [100, 3000, .8, 1, 0, 200, 100, 5000, 0, 1, FLOAT, FLOAT, FLOAT], + 'distortion': [800, .7, .7, 1, 0, 1000, 0, 1, 0, 1, FLOAT, FLOAT, FLOAT], + 'filter': [1000, .6, 0, 1, 200, 5000, 0, 1, 0, 2, FLOAT, FLOAT, INTEGER], + 'ringMod': [500, 1, 0, 1, 0, 1000, 0, 1, 0, 0, FLOAT, FLOAT, INTEGER], + 'reverb': [.8, .8, .5, 1, 0, 1, 0, 1, 0, 1, FLOAT, FLOAT, FLOAT], + 'harmon': [1.25, .5, 0, 1, 0, 2, 0, 1, 0, 0, FLOAT, FLOAT, INTEGER]} + + CONTROL_TYPES = ['LFO', 'random', 'ADSR'] + SOURCE_TYPES = ['FM', 'buzz', 'vco', 'pluck', 'noise', 'samples', 'voice'] + FX_TYPES = ['wguide', 'distortion','filter', 'ringMod', 'reverb', 'harmon'] + CHOOSE_TYPE = [CONTROL_TYPES, SOURCE_TYPES, FX_TYPES] diff --git a/SynthLab/SynthObjectsParameters.py b/SynthLab/SynthObjectsParameters.py new file mode 100755 index 0000000..cfb64b6 --- /dev/null +++ b/SynthLab/SynthObjectsParameters.py @@ -0,0 +1,35 @@ +class SynthObjectsParameters: + + def __init__( self ): + self.types = [0,0,0,0,0,0,0,0,0,0,0,0] + self.controlsParameters = [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] + self.sourcesParameters = [1,.5,5,1,1,.5,5,1,1,.5,5,1,1,.5,5,1] + self.fxsParameters = [100,3000,.8,1,100,3000,.8,1,100,3000,.8,1,100,3000,.8,1] + self.choiceParamsSet = [self.controlsParameters, self.sourcesParameters, self.fxsParameters] + + def update( self ): + self.choiceParamsSet = [self.controlsParameters, self.sourcesParameters, self.fxsParameters] + + def getTypes( self ): + return self.types + + def getControlsParameters( self ): + return self.controlsParameters + + def getSourcesParameters( self ): + return self.sourcesParameters + + def getFxsParameters( self ): + return self.fxsParameters + + def setType( self, pos, value ): + self.types[pos] = value + + def setControlParameter( self, pos, value ): + self.controlsParameters[pos] = value + + def setSourceParameter( self, pos, value ): + self.sourcesParameters[pos] = value + + def setFxParameter( self, pos, value ): + self.fxsParameters[pos] = value diff --git a/SynthLab/__init__.py b/SynthLab/__init__.py new file mode 100755 index 0000000..e69de29 --- /dev/null +++ b/SynthLab/__init__.py -- cgit v0.9.1