From 608fdb2e7f7a62e08b7e29a6ba28ff6326638be9 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 17 Sep 2007 07:14:39 +0000 Subject: SynthLab split --- (limited to 'TamTamSynthLab.activity') diff --git a/TamTamSynthLab.activity/MANIFEST b/TamTamSynthLab.activity/MANIFEST new file mode 100644 index 0000000..a773564 --- /dev/null +++ b/TamTamSynthLab.activity/MANIFEST @@ -0,0 +1,568 @@ +MANIFEST +NEWS +setup.py +TamTamSynthLab.py +activity/activity-tamtamsynthlab.svg +activity/activity.info +icons/accept.svg +icons/cancel.svg +icons/preset10.svg +icons/preset1.svg +icons/preset2.svg +icons/preset3.svg +icons/preset4.svg +icons/preset5.svg +icons/preset6.svg +icons/preset7.svg +icons/preset8.svg +icons/preset9.svg +icons/rec1.svg +icons/rec2.svg +icons/rec3.svg +icons/rec4.svg +icons/rec5.svg +icons/rec6.svg +icons/sl-addSynth-menu.svg +icons/sl-addSynth+.svg +icons/sl-adsr-menu.svg +icons/sl-adsr+.svg +icons/sl-buzz-menu.svg +icons/sl-buzz+.svg +icons/sl-chorus-menu.svg +icons/sl-chorus+.svg +icons/sl-distort-menu.svg +icons/sl-distort+.svg +icons/sl-eq4band-menu.svg +icons/sl-eq4band+.svg +icons/sl-filter-menu.svg +icons/sl-filter+.svg +icons/sl-fm-menu.svg +icons/sl-fm+.svg +icons/sl-grain-menu.svg +icons/sl-grain+.svg +icons/sl-harmon-menu.svg +icons/sl-harmon+.svg +icons/sl-lfo-menu.svg +icons/sl-lfo+.svg +icons/sl-noise-menu.svg +icons/sl-noise+.svg +icons/sl-pluck-menu.svg +icons/sl-pluck+.svg +icons/sl-rand-menu.svg +icons/sl-rand+.svg +icons/sl-reset.svg +icons/sl-reverb-menu.svg +icons/sl-reverb+.svg +icons/sl-ring-menu.svg +icons/sl-ring+.svg +icons/sl-sample-menu.svg +icons/sl-sample+.svg +icons/sl-speaker.svg +icons/sl-trackpadX-menu.svg +icons/sl-trackpadX+.svg +icons/sl-trackpadY-menu.svg +icons/sl-trackpadY+.svg +icons/sl-vco-menu.svg +icons/sl-vco+.svg +icons/sl-voice-menu.svg +icons/sl-voice+.svg +icons/sl-wguide-menu.svg +icons/sl-wguide+.svg +icons/tam-help.svg +icons/XYButDownClick.svg +icons/XYButDown.svg +icons/XYBut.svg +SynthLab/__init__.py +SynthLab/SynthLabConstants.py +SynthLab/SynthLabMain.py +SynthLab/SynthLabToolbars.py +SynthLab/SynthObjectsParameters.py +common/__init__.py +common/Config.py +common/Util/CSoundClient.py +common/Util/CSoundNote.py +common/Util/ControlStream.py +common/Util/Credits.py +common/Util/InstrumentDB.py +common/Util/InstrumentPanel.py +common/Util/Instrument_.py +common/Util/KeyboardWindow.py +common/Util/LoopSettings.py +common/Util/Network.py +common/Util/NoteDB.py +common/Util/NoteLooper.py +common/Util/Profiler.py +common/Util/Sound.py +common/Util/ThemeWidgets.py +common/Util/Trackpad.py +common/Util/__init__.py +common/Util/Clooper/Makefile +common/Util/Clooper/SoundClient.i +common/Util/Clooper/__init__.py +common/Util/Clooper/aclient.cpp +common/Util/Clooper/aclient.so +common/Util/Clooper/audio.cpp +common/Util/Clooper/cmd_csound.cpp +common/Util/Clooper/log.cpp +common/Util/Clooper/ttest.c +common/Util/Clooper/ttest.h +common/Util/Clooper/ttest.i +common/Util/Clooper/ttest.py +common/Util/Clooper/ttest_wrap.c +common/Generation/Drunk.py +common/Generation/GenerationConstants.py +common/Generation/GenerationParametersWindow.py +common/Generation/GenerationPitch.py +common/Generation/GenerationRythm.py +common/Generation/Generator.py +common/Generation/Utils.py +common/Generation/VariationPitch.py +common/Generation/VariationRythm.py +common/Generation/__init__.py +common/Generation/bList.py +common/Resources/__init__.py +common/Resources/crop.csd +common/Resources/tamtamorc.csd +common/Resources/tooltips_en.py +common/Resources/tooltips_fr.py +common/Resources/Desktops/desktop0 +common/Resources/Desktops/desktop1 +common/Resources/Desktops/desktop2 +common/Resources/Desktops/desktop3 +common/Resources/Desktops/desktop4 +common/Resources/Desktops/desktop5 +common/Resources/Desktops/desktop6 +common/Resources/Desktops/desktop7 +common/Resources/Desktops/desktop8 +common/Resources/Desktops/desktop9 +common/Resources/Images/TamTam.png +common/Resources/Images/acguit.png +common/Resources/Images/acguitsel.png +common/Resources/Images/alarm.png +common/Resources/Images/alarmsel.png +common/Resources/Images/all.png +common/Resources/Images/allsel.png +common/Resources/Images/animals.png +common/Resources/Images/animalssel.png +common/Resources/Images/arrowEditDown.png +common/Resources/Images/arrowEditDownDown.png +common/Resources/Images/arrowEditDownOver.png +common/Resources/Images/arrowEditLeft.png +common/Resources/Images/arrowEditLeftDown.png +common/Resources/Images/arrowEditLeftOver.png +common/Resources/Images/arrowEditRight.png +common/Resources/Images/arrowEditRightDown.png +common/Resources/Images/arrowEditRightOver.png +common/Resources/Images/arrowEditUp.png +common/Resources/Images/arrowEditUpDown.png +common/Resources/Images/arrowEditUpOver.png +common/Resources/Images/basse.png +common/Resources/Images/bassesel.png +common/Resources/Images/beat1.png +common/Resources/Images/beat10.png +common/Resources/Images/beat11.png +common/Resources/Images/beat2.png +common/Resources/Images/beat3.png +common/Resources/Images/beat4.png +common/Resources/Images/beat5.png +common/Resources/Images/beat6.png +common/Resources/Images/beat7.png +common/Resources/Images/beat8.png +common/Resources/Images/beat9.png +common/Resources/Images/bird.png +common/Resources/Images/birdsel.png +common/Resources/Images/bottle.png +common/Resources/Images/bottlesel.png +common/Resources/Images/bubbles.png +common/Resources/Images/bubblessel.png +common/Resources/Images/byke.png +common/Resources/Images/bykesel.png +common/Resources/Images/camera.png +common/Resources/Images/camerasel.png +common/Resources/Images/car.png +common/Resources/Images/carsel.png +common/Resources/Images/cat.png +common/Resources/Images/catsel.png +common/Resources/Images/cello.png +common/Resources/Images/cellosel.png +common/Resources/Images/check.png +common/Resources/Images/checkOff.svg +common/Resources/Images/checkOn.svg +common/Resources/Images/chimes.png +common/Resources/Images/chimessel.png +common/Resources/Images/clang.png +common/Resources/Images/clangsel.png +common/Resources/Images/clarinette.png +common/Resources/Images/clarinettesel.png +common/Resources/Images/cling.png +common/Resources/Images/clingsel.png +common/Resources/Images/complex1.png +common/Resources/Images/complex2.png +common/Resources/Images/complex3.png +common/Resources/Images/complex4.png +common/Resources/Images/complex5.png +common/Resources/Images/complex6.png +common/Resources/Images/complex7.png +common/Resources/Images/complex8.png +common/Resources/Images/concret.png +common/Resources/Images/concretsel.png +common/Resources/Images/crash.png +common/Resources/Images/crashsel.png +common/Resources/Images/dice.png +common/Resources/Images/diceProp.png +common/Resources/Images/dicePropSel.png +common/Resources/Images/diceblur.png +common/Resources/Images/diceinst.png +common/Resources/Images/diceinstsel.png +common/Resources/Images/didjeridu.png +common/Resources/Images/didjeridusel.png +common/Resources/Images/dog.png +common/Resources/Images/dogsel.png +common/Resources/Images/door.png +common/Resources/Images/doorsel.png +common/Resources/Images/dru0.png +common/Resources/Images/dru1.png +common/Resources/Images/dru2.png +common/Resources/Images/dru3.png +common/Resources/Images/dru4.png +common/Resources/Images/drum1kit.png +common/Resources/Images/drum1kitsel.png +common/Resources/Images/drum1kitselgen.png +common/Resources/Images/drum2kit.png +common/Resources/Images/drum2kitsel.png +common/Resources/Images/drum2kitselgen.png +common/Resources/Images/drum3kit.png +common/Resources/Images/drum3kitsel.png +common/Resources/Images/drum3kitselgen.png +common/Resources/Images/drum4kit.png +common/Resources/Images/drum4kitsel.png +common/Resources/Images/drum4kitselgen.png +common/Resources/Images/drum5kit.png +common/Resources/Images/drum5kitsel.png +common/Resources/Images/drum5kitselgen.png +common/Resources/Images/duck.png +common/Resources/Images/duck2.png +common/Resources/Images/duck2sel.png +common/Resources/Images/ducksel.png +common/Resources/Images/editTam.png +common/Resources/Images/editTamDown.png +common/Resources/Images/editTamOver.png +common/Resources/Images/electronic.png +common/Resources/Images/electronicsel.png +common/Resources/Images/flute.png +common/Resources/Images/flutesel.png +common/Resources/Images/gam.png +common/Resources/Images/gamsel.png +common/Resources/Images/generic.png +common/Resources/Images/genericsel.png +common/Resources/Images/guit.png +common/Resources/Images/guit2.png +common/Resources/Images/guit2sel.png +common/Resources/Images/guitsel.png +common/Resources/Images/harmonica.png +common/Resources/Images/harmonicasel.png +common/Resources/Images/harmonium.png +common/Resources/Images/harmoniumsel.png +common/Resources/Images/helpShow1.jpg +common/Resources/Images/helpShow2.jpg +common/Resources/Images/helpShow3.jpg +common/Resources/Images/helpShow4.jpg +common/Resources/Images/helpShow5.jpg +common/Resources/Images/helpShow6.jpg +common/Resources/Images/helpShow7.jpg +common/Resources/Images/helpShow8.jpg +common/Resources/Images/helpShow9.jpg +common/Resources/Images/helpTam.png +common/Resources/Images/helpTamDown.png +common/Resources/Images/helpTamOver.png +common/Resources/Images/hit.png +common/Resources/Images/hitSelected.png +common/Resources/Images/horse.png +common/Resources/Images/horsesel.png +common/Resources/Images/instr0.png +common/Resources/Images/instr1.png +common/Resources/Images/instr2.png +common/Resources/Images/instr3.png +common/Resources/Images/instr4.png +common/Resources/Images/jam-blockMask.png +common/Resources/Images/kalimba.png +common/Resources/Images/kalimbasel.png +common/Resources/Images/keyboard.png +common/Resources/Images/keyboardsel.png +common/Resources/Images/koto.png +common/Resources/Images/kotosel.png +common/Resources/Images/laugh.png +common/Resources/Images/laughsel.png +common/Resources/Images/mando.png +common/Resources/Images/mandosel.png +common/Resources/Images/marimba.png +common/Resources/Images/marimbasel.png +common/Resources/Images/marquis.png +common/Resources/Images/mic1.png +common/Resources/Images/mic1sel.png +common/Resources/Images/mic2.png +common/Resources/Images/mic2sel.png +common/Resources/Images/mic3.png +common/Resources/Images/mic3sel.png +common/Resources/Images/mic4.png +common/Resources/Images/mic4sel.png +common/Resources/Images/miniTam.png +common/Resources/Images/miniTamDown.png +common/Resources/Images/miniTamOver.png +common/Resources/Images/miniplay.png +common/Resources/Images/mysounds.png +common/Resources/Images/mysoundssel.png +common/Resources/Images/note.png +common/Resources/Images/noteSelected.png +common/Resources/Images/ocarina.png +common/Resources/Images/ocarinasel.png +common/Resources/Images/ounk.png +common/Resources/Images/ounksel.png +common/Resources/Images/ow.png +common/Resources/Images/owsel.png +common/Resources/Images/pageThumbnailBG.png +common/Resources/Images/pageThumbnailBG0.png +common/Resources/Images/pageThumbnailBG1.png +common/Resources/Images/pageThumbnailBG2.png +common/Resources/Images/pageThumbnailBG3.png +common/Resources/Images/pageThumbnailBut0.png +common/Resources/Images/pageThumbnailBut0Down.png +common/Resources/Images/pageThumbnailBut1.png +common/Resources/Images/pageThumbnailBut1Down.png +common/Resources/Images/pageThumbnailBut2.png +common/Resources/Images/pageThumbnailBut2Down.png +common/Resources/Images/pageThumbnailBut3.png +common/Resources/Images/pageThumbnailBut3Down.png +common/Resources/Images/pageThumbnailMask.png +common/Resources/Images/people.png +common/Resources/Images/peoplesel.png +common/Resources/Images/percussions.png +common/Resources/Images/percussionssel.png +common/Resources/Images/piano.png +common/Resources/Images/pianosel.png +common/Resources/Images/plane.png +common/Resources/Images/planesel.png +common/Resources/Images/reverb0.png +common/Resources/Images/reverb1.png +common/Resources/Images/reverb2.png +common/Resources/Images/reverb3.png +common/Resources/Images/reverb4.png +common/Resources/Images/reverb5.png +common/Resources/Images/rhodes.png +common/Resources/Images/rhodessel.png +common/Resources/Images/sampleBG.png +common/Resources/Images/sampleNoteMask.png +common/Resources/Images/saxo.png +common/Resources/Images/saxosel.png +common/Resources/Images/scrollBar.png +common/Resources/Images/sheep.png +common/Resources/Images/sheepsel.png +common/Resources/Images/shenai.png +common/Resources/Images/shenaisel.png +common/Resources/Images/sitar.png +common/Resources/Images/sitarsel.png +common/Resources/Images/slap.png +common/Resources/Images/slapsel.png +common/Resources/Images/sliderDrum.png +common/Resources/Images/sliderEditTempo.png +common/Resources/Images/sliderEditVolume.png +common/Resources/Images/sliderInst1.png +common/Resources/Images/sliderInst2.png +common/Resources/Images/sliderInst3.png +common/Resources/Images/sliderInst4.png +common/Resources/Images/sliderbutbleu.png +common/Resources/Images/sliderbutjaune.png +common/Resources/Images/sliderbutred.png +common/Resources/Images/sliderbutvert.png +common/Resources/Images/sliderbutviolet.png +common/Resources/Images/sliderlong.png +common/Resources/Images/slidershort.png +common/Resources/Images/stop.png +common/Resources/Images/strings.png +common/Resources/Images/stringssel.png +common/Resources/Images/synthTam.png +common/Resources/Images/synthTamDown.png +common/Resources/Images/synthTamOver.png +common/Resources/Images/synthlabMask.png +common/Resources/Images/tchiwo.png +common/Resources/Images/tchiwosel.png +common/Resources/Images/tempo1.png +common/Resources/Images/tempo2.png +common/Resources/Images/tempo3.png +common/Resources/Images/tempo4.png +common/Resources/Images/tempo5.png +common/Resources/Images/tempo6.png +common/Resources/Images/tempo7.png +common/Resources/Images/tempo8.png +common/Resources/Images/trackBG.png +common/Resources/Images/trackBGDrum.png +common/Resources/Images/trackBGDrumSelected.png +common/Resources/Images/trackBGSelected.png +common/Resources/Images/triangle.png +common/Resources/Images/trianglesel.png +common/Resources/Images/trumpet.png +common/Resources/Images/trumpetsel.png +common/Resources/Images/tuba.png +common/Resources/Images/tubasel.png +common/Resources/Images/violin.png +common/Resources/Images/violinsel.png +common/Resources/Images/voix.png +common/Resources/Images/voixsel.png +common/Resources/Images/volume0.png +common/Resources/Images/volume1.png +common/Resources/Images/volume2.png +common/Resources/Images/volume3.png +common/Resources/Images/water.png +common/Resources/Images/watersel.png +common/Resources/Images/winds.png +common/Resources/Images/windssel.png +common/Resources/Images/zap.png +common/Resources/Images/zapsel.png +common/Resources/Loops/loop1.ttl +common/Resources/Loops/loop2.ttl +common/Resources/Loops/loop3.ttl +common/Resources/Sounds/acguit +common/Resources/Sounds/alarm +common/Resources/Sounds/banjo +common/Resources/Sounds/basse +common/Resources/Sounds/bird +common/Resources/Sounds/bottle +common/Resources/Sounds/bubbles +common/Resources/Sounds/byke +common/Resources/Sounds/camera +common/Resources/Sounds/car +common/Resources/Sounds/cat +common/Resources/Sounds/cello +common/Resources/Sounds/chimes +common/Resources/Sounds/clang +common/Resources/Sounds/clarinette +common/Resources/Sounds/cling +common/Resources/Sounds/crash +common/Resources/Sounds/diceinst +common/Resources/Sounds/didjeridu +common/Resources/Sounds/dog +common/Resources/Sounds/door +common/Resources/Sounds/drum1chine +common/Resources/Sounds/drum1crash +common/Resources/Sounds/drum1floortom +common/Resources/Sounds/drum1hardride +common/Resources/Sounds/drum1hatpedal +common/Resources/Sounds/drum1hatshoulder +common/Resources/Sounds/drum1kick +common/Resources/Sounds/drum1ridebell +common/Resources/Sounds/drum1snare +common/Resources/Sounds/drum1snaresidestick +common/Resources/Sounds/drum1splash +common/Resources/Sounds/drum1tom +common/Resources/Sounds/drum2darbukadoom +common/Resources/Sounds/drum2darbukafinger +common/Resources/Sounds/drum2darbukapied +common/Resources/Sounds/drum2darbukapiedsoft +common/Resources/Sounds/drum2darbukaroll +common/Resources/Sounds/drum2darbukaslap +common/Resources/Sounds/drum2darbukatak +common/Resources/Sounds/drum2hatflanger +common/Resources/Sounds/drum2hatpied +common/Resources/Sounds/drum2hatpied2 +common/Resources/Sounds/drum2tambourinepied +common/Resources/Sounds/drum2tambourinepiedsoft +common/Resources/Sounds/drum3cowbell +common/Resources/Sounds/drum3cowbelltip +common/Resources/Sounds/drum3cup +common/Resources/Sounds/drum3djembelow +common/Resources/Sounds/drum3djembemid +common/Resources/Sounds/drum3djembesidestick +common/Resources/Sounds/drum3djembeslap +common/Resources/Sounds/drum3djembestickmid +common/Resources/Sounds/drum3metalstand +common/Resources/Sounds/drum3pedalperc +common/Resources/Sounds/drum3rainstick +common/Resources/Sounds/drum3tambourinehigh +common/Resources/Sounds/drum3tambourinelow +common/Resources/Sounds/drum4afrofeet +common/Resources/Sounds/drum4fingersn +common/Resources/Sounds/drum4mutecuic +common/Resources/Sounds/drum4stompbass +common/Resources/Sounds/drum4tambouri +common/Resources/Sounds/drum4tr707clap +common/Resources/Sounds/drum4tr707open +common/Resources/Sounds/drum4tr808closed +common/Resources/Sounds/drum4tr808sn +common/Resources/Sounds/drum4tr909bass +common/Resources/Sounds/drum4tr909kick +common/Resources/Sounds/drum4tr909sn +common/Resources/Sounds/drum5agogoaigu +common/Resources/Sounds/drum5agogograve +common/Resources/Sounds/drum5bongoaiguouvert +common/Resources/Sounds/drum5bongograveouvert +common/Resources/Sounds/drum5congaaiguouvert +common/Resources/Sounds/drum5congagraveferme +common/Resources/Sounds/drum5congagraveouvert +common/Resources/Sounds/drum5guiroretour +common/Resources/Sounds/drum5quicaaigu +common/Resources/Sounds/drum5quicamedium +common/Resources/Sounds/drum5timablesaiguslap +common/Resources/Sounds/drum5timablesslap +common/Resources/Sounds/drum5vibraslap +common/Resources/Sounds/duck +common/Resources/Sounds/duck2 +common/Resources/Sounds/flute +common/Resources/Sounds/gam +common/Resources/Sounds/guidice1 +common/Resources/Sounds/guidice10 +common/Resources/Sounds/guidice2 +common/Resources/Sounds/guidice3 +common/Resources/Sounds/guidice4 +common/Resources/Sounds/guidice5 +common/Resources/Sounds/guidice6 +common/Resources/Sounds/guidice7 +common/Resources/Sounds/guidice8 +common/Resources/Sounds/guidice9 +common/Resources/Sounds/guit +common/Resources/Sounds/guit2 +common/Resources/Sounds/harmonica +common/Resources/Sounds/harmonium +common/Resources/Sounds/horse +common/Resources/Sounds/kalimba +common/Resources/Sounds/koto +common/Resources/Sounds/lab1 +common/Resources/Sounds/lab2 +common/Resources/Sounds/lab3 +common/Resources/Sounds/lab4 +common/Resources/Sounds/lab5 +common/Resources/Sounds/lab6 +common/Resources/Sounds/laugh +common/Resources/Sounds/mando +common/Resources/Sounds/marimba +common/Resources/Sounds/mic1 +common/Resources/Sounds/mic2 +common/Resources/Sounds/mic3 +common/Resources/Sounds/mic4 +common/Resources/Sounds/ocarina +common/Resources/Sounds/ounk +common/Resources/Sounds/ow +common/Resources/Sounds/piano +common/Resources/Sounds/plane +common/Resources/Sounds/rhodes +common/Resources/Sounds/saxo +common/Resources/Sounds/sheep +common/Resources/Sounds/shenai +common/Resources/Sounds/sitar +common/Resources/Sounds/slap +common/Resources/Sounds/triangle +common/Resources/Sounds/trumpet +common/Resources/Sounds/tuba +common/Resources/Sounds/violin +common/Resources/Sounds/voix +common/Resources/Sounds/water +common/Resources/Sounds/zap +common/Resources/SynthFiles/synthFile1 +common/Resources/SynthFiles/synthFile2 +common/Resources/SynthFiles/synthFile3 +common/Resources/SynthFiles/synthFile4 +common/Resources/SynthFiles/synthFile5 +common/Resources/SynthFiles/synthFile6 +common/Resources/SynthFiles/synthFile7 +common/Resources/SynthFiles/synthFile8 +common/Resources/SynthFiles/synthFile9 +common/Resources/SynthFiles/synthFile10 diff --git a/TamTamSynthLab.activity/SynthLab/SynthLabMain.py b/TamTamSynthLab.activity/SynthLab/SynthLabMain.py new file mode 100644 index 0000000..b5e330f --- /dev/null +++ b/TamTamSynthLab.activity/SynthLab/SynthLabMain.py @@ -0,0 +1,1393 @@ +import pygtk +pygtk.require('2.0') +import gtk + +from common.Util.Profiler import TP + +import gobject +import time +import shelve +from gettext import gettext as _ +import os + +from sugar.graphics.toolcombobox import ToolComboBox +from common.Util.ThemeWidgets import BigComboBox + +import common.Config as Config +from common.Util.ThemeWidgets import * +from common.Util.CSoundClient import new_csound_client +from SynthLab.SynthObjectsParameters import SynthObjectsParameters +from SynthLab.SynthLabConstants import SynthLabConstants +from SynthLab.SynthLabToolbars import mainToolbar +from SynthLab.SynthLabToolbars import presetToolbar +from common.Util.Trackpad import Trackpad + +as_window = False + +class SynthLabMain(gtk.EventBox): + def __init__( self, activity ): + gtk.EventBox.__init__(self) + if as_window: + color = gtk.gdk.color_parse(Config.PANEL_BCK_COLOR) + self.modify_bg(gtk.STATE_NORMAL, color) + self.set_border_width(Config.MAIN_WINDOW_PADDING) + self.set_keep_above(False) + self.set_decorated(False) + self.activity = activity + self.csnd = new_csound_client() + self.trackpad = Trackpad( self ) + self.synthObjectsParameters = SynthObjectsParameters() + self.resetLocations() + self.objectCount = len(self.locations) + self.connections = [] + self.initializeConnections() + self.bounds = [] + for i in range(self.objectCount): + self.bounds.append([0,0,0,0]) + self.updateBounds(i) + self.instanceOpen = 0 + self.recordWait = 0 + self.recCount = 0 + self.new = True + self.duration = 2 + self.viewType = '' + self.viewParam = '' + self.curSlider = 1 + self.durString = '%.2f' % self.duration + self.playingPitch = [] + self.journalCalled = True + + #Toolbars + self.activity.activity_toolbar.keep.show() + self._mainToolbar = mainToolbar(self.activity.toolbox, self) + self._presetToolbar = presetToolbar(self.activity.toolbox, self) + self.activity.toolbox.add_toolbar(_('Main'), self._mainToolbar) + self.activity.toolbox.add_toolbar(_('Presets'), self._presetToolbar) + self.activity.toolbox.set_current_toolbar(1) + self._mainToolbar.show() + self._presetToolbar.show() + + loopPointsTable = [] + sample_names = [name for i in range( len( Config.INSTRUMENTS ) ) for name in Config.INSTRUMENTS.keys() if Config.INSTRUMENTS[ name ].instrumentId == i ] + for inst in sample_names: + loopStart = Config.INSTRUMENTS[ inst ].loopStart + loopEnd = Config.INSTRUMENTS[ inst ].loopEnd + crossDur = Config.INSTRUMENTS[ inst ].crossDur + loopPointsTable.extend( [ loopStart, loopEnd, crossDur ] ) + mess = "f5755 0 512 -2 " + " " .join([str(n) for n in loopPointsTable]) + self.csnd.inputMessage( mess ) + + self.lineWidth = 3 + self.lineWidthMUL2 = self.lineWidth*2 + self.lineWidthMUL4 = self.lineWidth*4 + self.lineWidthMUL4SQ = self.lineWidthMUL4*self.lineWidthMUL4 + self.clockStart = 0 + self.sample_names = [name for i in range( len( Config.INSTRUMENTS ) ) for name in Config.INSTRUMENTS.keys() if Config.INSTRUMENTS[ name ].instrumentId == i ] + if as_window: + self.add_events(gtk.gdk.KEY_PRESS_MASK|gtk.gdk.KEY_RELEASE_MASK) + + self.action = None + self.dragObject = None + self.overWire = None + self.overGate = None + self.overGateObj = None + self.overGateReject = False + self.overGateSize = 32 + self.overGateSizeDIV2 = self.overGateSize//2 + self.overLineWidth = self.lineWidth*2 + self.overLineWidthMUL2 = self.overLineWidth*2 + + self.gatePoint = SynthLabConstants.GATE_POINT + self.gateMap = SynthLabConstants.GATE_MAP + # look up gate type to find the matching gate type + self.gateMatch = [ SynthLabConstants.GT_CONTROL_INPUT, + SynthLabConstants.GT_CONTROL_OUTPUT, + SynthLabConstants.GT_SOUND_INPUT, + SynthLabConstants.GT_SOUND_OUTPUT ] + + # set up window + if as_window: + self.set_position( gtk.WIN_POS_CENTER_ON_PARENT ) + self.set_title("Synth Lab") + self.mainBox = gtk.HBox() + self.subBox = gtk.HBox() + self.drawingBox = RoundVBox( 10, Config.PANEL_COLOR, Config.PANEL_COLOR ) + self.drawingBox.set_border_width(0) + self.infoBox = RoundVBox( 10, Config.TOOLBAR_BCK_COLOR, Config.TOOLBAR_BCK_COLOR ) + self.infoBox.set_border_width(Config.PANEL_SPACING) + self.infoBox.set_size_request(300, 750) + self.subBox.pack_start(self.drawingBox, True, True) + self.subBox.pack_start(self.infoBox, True, True) + self.mainBox.pack_start(self.subBox) + + menuBox = gtk.HBox() + self.objComboBox = BigComboBox() + self.objComboBox.append_item(0, 'Envelope', Config.TAM_TAM_ROOT + '/icons/sl-adsr-menu.svg') + self.objComboBox.set_active(0) + self.objComboBox.connect('changed', self.changeObject) + comboMenu = ToolComboBox(self.objComboBox) + menuBox.pack_start(comboMenu) + self.infoBox.pack_start(menuBox, False, False, 5) + + slidersBox = gtk.HBox() + + self.instanceID = 12 # object number + self.objectType = self.instanceID / 4 #(control, source, fx, output) + self.choosenType = 0 # self.synthObjectsParameters.types[self.instanceID] module as an index + selectedType = SynthLabConstants.CHOOSE_TYPE[self.objectType][self.choosenType] #module as a string + + 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] + slider4Min = SynthLabConstants.TYPES[selectedType][10] + slider4Max = SynthLabConstants.TYPES[selectedType][11] + + slider1Step = SynthLabConstants.TYPES[selectedType][12][0] + slider1Snap = SynthLabConstants.TYPES[selectedType][12][1] + slider2Step = SynthLabConstants.TYPES[selectedType][13][0] + slider2Snap = SynthLabConstants.TYPES[selectedType][13][1] + slider3Step = SynthLabConstants.TYPES[selectedType][14][0] + slider3Snap = SynthLabConstants.TYPES[selectedType][14][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] + + sliderTextColor = gtk.gdk.color_parse(Config.WHITE_COLOR) + sliderHeight = 240 + + self.p1Adjust = gtk.Adjustment(slider1Init, slider1Min, slider1Max, slider1Step, slider1Step, 0) + self.p1Adjust.connect("value-changed", self.sendTables, 1) + self.slider1 = gtk.VScale(self.p1Adjust) + self.slider1.connect("button-release-event", self.handleSliderRelease) + self.slider1.connect("enter-notify-event", self.handleSliderEnter, 1) + self.slider1.set_digits(slider1Snap) + self.slider1.set_inverted(True) + self.slider1.set_size_request(55, sliderHeight) + self.slider1.modify_fg(gtk.STATE_NORMAL, sliderTextColor) + slidersBox.pack_start(self.slider1, True, False) + + self.p2Adjust = gtk.Adjustment(slider2Init, slider2Min, slider2Max, slider2Step, slider2Step, 0) + self.p2Adjust.connect("value-changed", self.sendTables, 2) + self.slider2 = gtk.VScale(self.p2Adjust) + self.slider2.connect("button-release-event", self.handleSliderRelease) + self.slider2.connect("enter-notify-event", self.handleSliderEnter, 2) + self.slider2.set_digits(slider2Snap) + self.slider2.set_inverted(True) + self.slider2.set_size_request(55, sliderHeight) + self.slider2.modify_fg(gtk.STATE_NORMAL, sliderTextColor) + slidersBox.pack_start(self.slider2, True, False) + + self.p3Adjust = gtk.Adjustment(slider3Init, slider3Min, slider3Max, slider3Step, slider3Step, 0) + self.p3Adjust.connect("value-changed", self.sendTables, 3) + self.slider3 = gtk.VScale(self.p3Adjust) + self.slider3.connect("button-release-event", self.handleSliderRelease) + self.slider3.connect("enter-notify-event", self.handleSliderEnter, 3) + self.slider3.set_digits(slider3Snap) + self.slider3.set_inverted(True) + self.slider3.set_size_request(55, sliderHeight) + self.slider3.modify_fg(gtk.STATE_NORMAL, sliderTextColor) + slidersBox.pack_start(self.slider3, True, False) + + self.p4Adjust = gtk.Adjustment(slider4Init, slider4Min, slider4Max, .01, .01, 0) + self.p4Adjust.connect("value-changed", self.sendTables, 4) + self.slider4 = gtk.VScale(self.p4Adjust) + self.slider4.connect("button-release-event", self.handleSliderRelease) + self.slider4.connect("enter-notify-event", self.handleSliderEnter, 4) + self.slider4.set_digits(2) + self.slider4.set_inverted(True) + self.slider4.set_size_request(55, sliderHeight) + self.slider4.modify_fg(gtk.STATE_NORMAL, sliderTextColor) + slidersBox.pack_start(self.slider4, True, False) + + self.infoBox.pack_start(slidersBox, False, False, 5) + + self.infoText = 'ADSR envelope apply on the overall signal' + textBox = gtk.HBox() + text_color = gtk.gdk.color_parse(Config.WHITE_COLOR) + text_bg_color = gtk.gdk.color_parse(Config.TOOLBAR_BCK_COLOR) + textScroller = gtk.ScrolledWindow() + textScroller.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC) + textScroller.set_size_request(270, 301) + self.textBuf = gtk.TextBuffer(None) + self.textBuf.set_text(self.infoText) + self.textViewer = gtk.TextView(self.textBuf) + self.textViewer.modify_text(gtk.STATE_NORMAL, text_color) + self.textViewer.modify_base(gtk.STATE_NORMAL, text_bg_color) + self.textViewer.set_border_window_size(gtk.TEXT_WINDOW_LEFT, 1) + self.textViewer.set_border_window_size(gtk.TEXT_WINDOW_RIGHT, 1) + self.textViewer.set_border_window_size(gtk.TEXT_WINDOW_TOP, 1) + self.textViewer.set_border_window_size(gtk.TEXT_WINDOW_BOTTOM, 1) + self.textViewer.set_wrap_mode(gtk.WRAP_WORD) + self.textViewer.set_editable(False) + self.textViewer.set_overwrite(True) + self.textViewer.set_cursor_visible(False) + self.textViewer.set_left_margin(10) + self.textViewer.set_right_margin(10) + self.textViewer.set_pixels_above_lines(7) + self.textViewer.set_justification(gtk.JUSTIFY_LEFT) + textScroller.add(self.textViewer) + textBox.pack_start(textScroller, False, False, 10) + self.infoBox.pack_start(textBox, False, False, 5) + + self.infoLabel = gtk.Label() + self.infoBox.pack_end(self.infoLabel, False, False, 20) + textColor = gtk.gdk.color_parse(Config.WHITE_COLOR) + self.infoLabel.set_justify(gtk.JUSTIFY_LEFT) + self.infoLabel.modify_fg(gtk.STATE_NORMAL, textColor) + + self.drawingAreaWidth = 900 + self.drawingAreaHeight = 750 + self.separatorY = 660 + + self.clearMask = gtk.gdk.Rectangle(0,0,self.drawingAreaWidth,self.drawingAreaHeight) + + win = gtk.gdk.get_default_root_window() + self.gc = gtk.gdk.GC( win ) + self.gc.set_line_attributes( self.lineWidth, gtk.gdk.LINE_SOLID, gtk.gdk.CAP_BUTT, gtk.gdk.JOIN_MITER ) + + + self.dirtyRectToAdd = gtk.gdk.Rectangle() + self.dirty = False + + self.screenBuf = gtk.gdk.Pixmap( win, self.drawingAreaWidth, self.drawingAreaHeight ) + self.screenBufDirtyRect = gtk.gdk.Rectangle() + self.screenBufDirty = False + + self.drawingArea = gtk.DrawingArea() + self.drawingArea.set_size_request( self.drawingAreaWidth, self.drawingAreaHeight ) + self.col = gtk.gdk.color_parse(Config.PANEL_COLOR) + colormap = self.drawingArea.get_colormap() + self.bgColor = colormap.alloc_color( Config.PANEL_COLOR, True, True ) + self.lineColor = colormap.alloc_color( Config.SL_LINE_COLOR, True, True ) + self.highlightColor = colormap.alloc_color( Config.SL_HIGHLIGHT_COLOR, True, True ) + self.overWireColor = colormap.alloc_color( Config.SL_OVER_WIRE_COLOR, True, True ) + self.overGateColor = colormap.alloc_color( Config.SL_OVER_GATE_COLOR, True, True ) + self.overGateRejectColor = colormap.alloc_color( Config.SL_OVER_GATE_REJECT_COLOR, True, True ) + self.drawingArea.modify_bg(gtk.STATE_NORMAL, self.col) + + self.loadPixmaps() + + self.drawingArea.add_events( gtk.gdk.BUTTON_PRESS_MASK + | gtk.gdk.BUTTON_RELEASE_MASK + | gtk.gdk.POINTER_MOTION_MASK + | gtk.gdk.POINTER_MOTION_HINT_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, 0) + + tempFile = 'synthTemp' + if tempFile in os.listdir(Config.PREF_DIR): + self.handleLoadTemp() + else: + self.presetCallback(None,1) + self.add(self.mainBox) + self.show_all() + + def onDestroy(self): + pass + + def select(self, i): + if i == self.instanceID: + return + self.new = False + if self.instanceID > 0: + self.invalidate_rect( self.bounds[self.instanceID][0], self.bounds[self.instanceID][1]-2, SynthLabConstants.PIC_SIZE, SynthLabConstants.PIC_SIZE_HIGHLIGHT ) + self.instanceID = i + self.invalidate_rect( self.bounds[i][0], self.bounds[i][1]-2, SynthLabConstants.PIC_SIZE, SynthLabConstants.PIC_SIZE_HIGHLIGHT ) + + if self.instanceID / 4 != self.objectType: + self.objectType = self.instanceID / 4 + self.objComboBox.remove_all() + for i in range(len(SynthLabConstants.CHOOSE_TYPE[self.objectType])): + self.objComboBox.append_item(i, SynthLabConstants.SYNTHTYPES[self.objectType][i], Config.TAM_TAM_ROOT + '/icons/sl-' + SynthLabConstants.CHOOSE_TYPE[self.objectType][i] + '-menu.svg') + + oldChoosen = self.choosenType + if self.instanceID != 12: + self.choosenType = self.synthObjectsParameters.types[self.instanceID] + else: + self.choosenType = 0 + + self.objComboBox.set_active(self.choosenType) + #Not sure about this + self.slider1.grab_focus() + self.sendTables(self.slider1, 1) + + def changeObject(self, widget): + self.choosenType = widget.props.value + self.resize() + if self.instanceID != 12: + self.synthObjectsParameters.setType(self.instanceID, self.choosenType) + self.invalidate_rect( self.bounds[self.instanceID][0], self.bounds[self.instanceID][1]-2, SynthLabConstants.PIC_SIZE, SynthLabConstants.PIC_SIZE_HIGHLIGHT ) + if self.new: + self.writeTables( self.synthObjectsParameters.types, + self.synthObjectsParameters.controlsParameters, + self.synthObjectsParameters.sourcesParameters, + self.synthObjectsParameters.fxsParameters ) + + def updateViewer(self): + selectedType = SynthLabConstants.CHOOSE_TYPE[self.objectType][self.choosenType] + infoType = SynthLabConstants.SYNTHPARA[selectedType][4] + infoPara = SynthLabConstants.SYNTHPARA[selectedType][4+self.curSlider] + #infoPara = "Parameter's info not yet set" + self.infoText = infoType + '\n\n' + SynthLabConstants.SYNTHPARA[selectedType][self.curSlider-1] + ': ' + infoPara + self.textBuf.set_text(self.infoText) + + def recallSliderValue( self, num ): + if num == 1: + if SynthLabConstants.SYNTHTYPES[self.objectType][self.choosenType] == SynthLabConstants.NOISE: + return SynthLabConstants.NOISE_TYPES[int(self.slider1Val)] + else: + return '%.2f' % self.slider1Val + if num == 2: + if SynthLabConstants.SYNTHTYPES[self.objectType][self.choosenType] == SynthLabConstants.VCO: + return SynthLabConstants.VCO_WAVEFORMS[int(self.slider2Val)] + elif SynthLabConstants.SYNTHTYPES[self.objectType][self.choosenType] == SynthLabConstants.SAMPLE or SynthLabConstants.SYNTHTYPES[self.objectType][self.choosenType] == SynthLabConstants.GRAIN: + return self.sample_names[int(self.slider2Val)] + elif SynthLabConstants.SYNTHTYPES[self.objectType][self.choosenType] == SynthLabConstants.VOICE: + return SynthLabConstants.VOWEL_TYPES[int(self.slider2Val)] + else: + return '%.2f' % self.slider2Val + if num == 3: + if SynthLabConstants.SYNTHTYPES[self.objectType][self.choosenType] == SynthLabConstants.LFO: + return SynthLabConstants.LFO_WAVEFORMS[int(self.slider3Val)] + elif SynthLabConstants.SYNTHTYPES[self.objectType][self.choosenType] == SynthLabConstants.TRACKPADX: + return SynthLabConstants.SCALING_TYPES[int(self.slider3Val)] + elif SynthLabConstants.SYNTHTYPES[self.objectType][self.choosenType] == SynthLabConstants.TRACKPADY: + return SynthLabConstants.SCALING_TYPES[int(self.slider3Val)] + elif SynthLabConstants.SYNTHTYPES[self.objectType][self.choosenType] == SynthLabConstants.FILTER: + return SynthLabConstants.FILTER_TYPES[int(self.slider3Val)] + elif SynthLabConstants.SYNTHTYPES[self.objectType][self.choosenType] == SynthLabConstants.RINGMOD: + return SynthLabConstants.LFO_WAVEFORMS[int(self.slider3Val)] + else: + return '%.2f' % self.slider3Val + if num == 4: return '%.2f' % self.slider4Val + + def resize( self ): + selectedType = SynthLabConstants.CHOOSE_TYPE[self.objectType][self.choosenType] + if self.new: + slider1Init = SynthLabConstants.TYPES[selectedType][0] + slider2Init = SynthLabConstants.TYPES[selectedType][1] + slider3Init = SynthLabConstants.TYPES[selectedType][2] + slider4Init = SynthLabConstants.TYPES[selectedType][3] + else: + 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] + + 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] + slider4Min = SynthLabConstants.TYPES[selectedType][10] + slider4Max = SynthLabConstants.TYPES[selectedType][11] + + slider1Step = SynthLabConstants.TYPES[selectedType][12][0] + slider1Snap = SynthLabConstants.TYPES[selectedType][12][1] + slider2Step = SynthLabConstants.TYPES[selectedType][13][0] + slider2Snap = SynthLabConstants.TYPES[selectedType][13][1] + slider3Step = SynthLabConstants.TYPES[selectedType][14][0] + slider3Snap = SynthLabConstants.TYPES[selectedType][14][1] + + 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, slider4Min, slider4Max, 0.01, 0.01, 0) + + self.slider1.set_digits(slider1Snap) + self.slider2.set_digits(slider2Snap) + self.slider3.set_digits(slider3Snap) + + self.new = True + + def sendTables( self, widget, data ): + self.curSlider = data + self.slider1Val = self.p1Adjust.value + self.slider2Val = self.p2Adjust.value + self.slider3Val = self.p3Adjust.value + self.slider4Val = self.p4Adjust.value + if self.instanceID != 12: + 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]) + elif self.objectType == 3: + for i in range(4): + self.synthObjectsParameters.setOutputParameter(i, sliderListValue[i]) + self.updateViewer() + selectedType = SynthLabConstants.CHOOSE_TYPE[self.objectType][self.choosenType] + _str = SynthLabConstants.SYNTHTYPES[self.objectType][self.choosenType] + '\n' + SynthLabConstants.SYNTHPARA[selectedType][self.curSlider-1] + ': ' + self.recallSliderValue(self.curSlider) + self.parameterUpdate(_str) + + def handleSliderRelease(self, widget, data=None): + if self.instanceID != 12: + self.writeTables( self.synthObjectsParameters.types, self.synthObjectsParameters.controlsParameters, + self.synthObjectsParameters.sourcesParameters, self.synthObjectsParameters.fxsParameters ) + + def handleSliderEnter(self, widget, data, slider): + widget.grab_focus() + self.sendTables(widget, slider) + + #selectedType = SynthLabConstants.CHOOSE_TYPE[self.objectType][self.choosenType] + #_str = SynthLabConstants.SYNTHTYPES[self.objectType][self.choosenType] + '\n' + SynthLabConstants.SYNTHPARA[selectedType][self.curSlider-1] + ': ' + self.recallSliderValue(self.curSlider) + #self.parameterUpdate(_str) + + def onKeyPress(self,widget,event): + key = event.hardware_keycode + if key not in Config.KEY_MAP: + return + midiPitch = Config.KEY_MAP[key] + if midiPitch not in self.playingPitch: + if self.recordWait == 0: + self.playingPitch.append( midiPitch ) + self.playNote( midiPitch, 0 ) + else: + self.recordWait = 0 + self.playingPitch.append( midiPitch ) + self.playNote( midiPitch, self.table ) + self.waitRecording() + + def resetRecord( self ): + gobject.source_remove( self.wait ) + self.recordButton.set_active(False) + inst = 'lab' + str(self.table-85) + self.csnd.load_synth_instrument(inst) + self.table = 0 + return True + + def waitRecording(self): + self.wait = gobject.timeout_add(int(self.duration*1000) , self.resetRecord ) + + def onKeyRelease( self, widget, event ): + key = event.hardware_keycode + if key not in Config.KEY_MAP: + return + midiPitch = Config.KEY_MAP[key] + if midiPitch in self.playingPitch: + self.playingPitch.remove( midiPitch ) + + def handleDuration( self, adjustment ): + self.duration = adjustment.value + + def parameterUpdate( self, string ): + self.infoLabel.set_text(string) + + def playNote( self, midiPitch, table ): + cpsPitch = 261.626*pow(1.0594633, midiPitch-36) + self.recCount += 1 + mess = "i5203." + str(self.recCount) + " 0 " + str(self.duration) + " " + str(cpsPitch) + " " + str(table) + " " + " " .join([str(n) for n in self.synthObjectsParameters.getOutputParameters()]) + self.csnd.inputMessage( mess ) + if self.recCount >= 9: self.recCount = 0 + + def handleClose( self, widget, data ): + if self.journalCalled: + self.activity.close() + return + if as_window: + self.set_keep_above(False) + self.hide() + + def resetLocations( self ): + # deep copy the list + self.locations = [ loc[:] for loc in SynthLabConstants.INIT_LOCATIONS ] + + def handleReset( self, widget, data = None): + self.resetLocations() + self.objectCount = len(self.locations) + for i in range(self.objectCount): + self.updateBounds( i ) + self.duration = 2 + self._mainToolbar.durationSliderAdj.set_value(self.duration) + self.connections = [] + self.synthObjectsParameters.__init__() + self.writeTables( self.synthObjectsParameters.types, self.synthObjectsParameters.controlsParameters, self.synthObjectsParameters.sourcesParameters, self.synthObjectsParameters.fxsParameters ) + self.synthObjectsParameters.update() + self.initializeConnections() + self.invalidate_rect( 0, 0, self.drawingAreaWidth, self.drawingAreaHeight ) + time.sleep(.01) + self.controlToSrcConnections() + time.sleep(.01) + self.controlToFxConnections() + time.sleep(.01) + self.audioConnections() + time.sleep(.01) + + def setAction( self, action ): + self.action = action + + def doneAction( self ): + if self.action == "drag-object": self.doneDragObject() + self.action = None + + def handleButtonRelease( self, widget, event ): + + self.highlightWire( None ) + self.highlightGate( None ) + + if self.action == "drag-object": + self.doneAction() + elif self.action == "draw-wire": + for i in range(self.objectCount): + if self.bounds[i][0] < event.x < self.bounds[i][2] and self.bounds[i][1] < event.y < self.bounds[i][3]: + if i == self.wireObj: + break + gate = self.testGates( i, event.x-self.locations[i][0], event.y-self.locations[i][1] ) + if gate: + self.connectWire( i, gate ) + break + # if we don't connect the wire here they can try to click it somewhere, so don't end the action + + def handleButtonPress( self, widget, event): + self.clickLoc = (int(event.x),int(event.y)) + + self.highlightWire( None ) + self.highlightGate( None ) + + if event.button == 1: + for i in range(self.objectCount-1,-1,-1): + if self.bounds[i][0] < event.x < self.bounds[i][2] and self.bounds[i][1] < event.y < self.bounds[i][3]: + if self.locations[i][1] == SynthLabConstants.INIT_LOCATIONS[i][1] \ + and i != self.objectCount-1: + gate = False + else: + gate = self.testGates( i, event.x-self.locations[i][0], event.y-self.locations[i][1] ) + if gate: + if self.action == "draw-wire": + self.connectWire( i, gate ) + else: + self.startWire( i, gate ) + else: + if self.action == "draw-wire": + self.doneWire() + if i != self.objectCount-1: + self.startDragObject( i ) + else: + self.select( i ) + return + if self.action == "draw-wire": # didn't hit anything + self.doneWire() + else: + # check if we clicked a wire + i = self.wireUnderLoc( event.x, event.y ) + if i >= 0: self.deleteWire( i ) + + + def handleMotion( self, widget, event ): + + if event.is_hint: + x, y, state = widget.window.get_pointer() + event.x = float(x) + event.y = float(y) + event.state = state + + if self.action == "drag-object": + self.updateDragObject( int(event.x), int(event.y) ) + elif self.action == "draw-wire": + self.updateWire( int(event.x), int(event.y) ) + for i in range(self.objectCount): + if self.locations[i] == SynthLabConstants.INIT_LOCATIONS[i] \ + and i != self.objectCount-1: continue + if self.bounds[i][0] < event.x < self.bounds[i][2] and self.bounds[i][1] < event.y < self.bounds[i][3]: + gate = self.testGates( i, event.x-self.locations[i][0], event.y-self.locations[i][1] ) + if gate and ( gate != self.wireGate or i != self.wireObj ): + if gate[0] == SynthLabConstants.GT_CONTROL_OUTPUT or gate[0] == SynthLabConstants.GT_SOUND_OUTPUT: + ok = self.testConnection( i, gate, self.wireObj, self.wireGate ) + else: + ok = self.testConnection( self.wireObj, self.wireGate, i, gate ) + self.highlightGate( i, gate, not ok ) + else: self.highlightGate( None ) + return + self.highlightGate( None ) + else: # check for mouse overs + for i in range(self.objectCount): + if self.locations[i] == SynthLabConstants.INIT_LOCATIONS[i] \ + and i != self.objectCount-1: continue + + if self.bounds[i][0] < event.x < self.bounds[i][2] and self.bounds[i][1] < event.y < self.bounds[i][3]: + gate = self.testGates( i, event.x-self.locations[i][0], event.y-self.locations[i][1] ) + if gate: + self.highlightGate( i, gate ) + else: + self.highlightGate( None ) + self.highlightWire( None ) + return + # didn't find a gate + self.highlightGate( None ) + # check for wires + i = self.wireUnderLoc( event.x, event.y ) + if i >= 0: self.highlightWire( i ) + else: self.highlightWire( None ) + + def testGates( self, i, x, y ): + oT = i >> 2 + for gT in range(len(self.gateMap[oT])): + for n in range(len(self.gateMap[oT][gT])): + if self.gateMap[oT][gT][n][0] <= x <= self.gateMap[oT][gT][n][2] \ + and self.gateMap[oT][gT][n][1] <= y <= self.gateMap[oT][gT][n][3]: + return ( gT, n, self.gateMap[oT][gT][n][4], self.gatePoint[oT][gT][n] ) # type, index, wire loc, center loc + return False + + def startWire( self, obj, gate ): + self.wireObj = obj + self.wireGate = gate + x = gate[2][0] + self.locations[obj][0] + y = gate[2][1] + self.locations[obj][1] + self.wirePoint = [ [ x, y ], [ x, y ] ] + self.wireRect = [ 0, 0, 0, 0 ] + self.setAction( "draw-wire" ) + + def updateWire( self, x, y ): + if x < 0: x = 0 + elif x > self.drawingAreaWidth: x = self.drawingAreaWidth + if y < 0: y = 0 + elif y > self.separatorY: y = self.separatorY + self.invalidate_rect( self.wireRect[0], self.wireRect[1], self.wireRect[2], self.wireRect[3], False ) + if x < self.wirePoint[0][0]: self.wireRect[0], self.wireRect[2] = x-self.lineWidth, self.wirePoint[0][0]-x+self.lineWidthMUL2 + else: self.wireRect[0], self.wireRect[2] = self.wirePoint[0][0]-self.lineWidth, x-self.wirePoint[0][0]+self.lineWidthMUL2 + if y < self.wirePoint[0][1]: self.wireRect[1], self.wireRect[3] = y-self.lineWidth, self.wirePoint[0][1]-y+self.lineWidthMUL2 + else: self.wireRect[1], self.wireRect[3] = self.wirePoint[0][1]-self.lineWidth, y-self.wirePoint[0][1]+self.lineWidthMUL2 + self.wirePoint[1][0] = x + self.wirePoint[1][1] = y + self.invalidate_rect( self.wireRect[0], self.wireRect[1], self.wireRect[2], self.wireRect[3], False ) + + def connectWire( self, obj, gate ): + if gate[0] == SynthLabConstants.GT_CONTROL_OUTPUT or gate[0] == SynthLabConstants.GT_SOUND_OUTPUT: + bObj, eObj = obj, self.wireObj + bGate, eGate = gate, self.wireGate + else: + bObj, eObj = self.wireObj, obj + bGate, eGate = self.wireGate, gate + + i = self.newConnection( bObj, bGate, eObj, eGate ) + if i >= 0: # successful connection + self.invalidate_rect( self.cBounds[i][0], self.cBounds[i][1], self.cBounds[i][2], self.cBounds[i][3] ) + self.doneWire() + + def deleteWire( self, i ): + self.invalidate_rect( self.cBounds[i][0], self.cBounds[i][1], self.cBounds[i][2], self.cBounds[i][3] ) + self.delConnection( i ) + + def doneWire( self ): + self.invalidate_rect( self.wireRect[0], self.wireRect[1], self.wireRect[2], self.wireRect[3] ) + self.doneAction() + + def wireUnderLoc( self, x, y ): + for i in range(len(self.connections)): + if x < self.cBounds[i][0] or x > self.cBounds[i][4]: continue + if y < self.cBounds[i][1] or y > self.cBounds[i][5]: continue + if self.cPoints[i][0] == self.cPoints[i][2]: # vertical line + if abs(x-self.cPoints[i][0]) < self.lineWidthMUL4: + return i + else: + slope = (self.cPoints[i][3]-self.cPoints[i][1])/float(self.cPoints[i][2]-self.cPoints[i][0]) + if abs(slope) < 1: + yy = self.cPoints[i][1] + (x-self.cPoints[i][0])*slope + if abs(y-yy) < self.lineWidthMUL4: + return i + else: + xx = self.cPoints[i][0] + (y-self.cPoints[i][1])/slope + if abs(x-xx) < self.lineWidthMUL4: + return i + return -1 # nothing found + + # pass in i = None to clear + def highlightWire( self, i ): + if self.overWire != i: + if self.overWire != None: + self.invalidate_rect( self.cBounds[self.overWire][0], self.cBounds[self.overWire][1], self.cBounds[self.overWire][2], self.cBounds[self.overWire][3] ) + self.overWire = i + if self.overWire != None: + self.invalidate_rect( self.cBounds[self.overWire][0], self.cBounds[self.overWire][1], self.cBounds[self.overWire][2], self.cBounds[self.overWire][3] ) + + # pass in obj = None to clear + def highlightGate( self, obj, gate = None, reject = False ): + if obj == None: + self.parameterUpdate('') + if self.overGateObj != obj or self.overGate != gate or self.overGateReject != reject: + if self.overGate != None: + self.invalidate_rect( self.overGateLoc[0], self.overGateLoc[1], self.overGateSize, self.overGateSize ) + self.overGateObj = obj + self.overGate = gate + self.overGateReject = reject + if self.overGate != None: + oT = self.overGateObj//4 + x = self.locations[self.overGateObj][0] + self.overGate[3][0] - self.overGateSizeDIV2 + y = self.locations[self.overGateObj][1] + self.overGate[3][1] - self.overGateSizeDIV2 + self.overGateLoc = ( x, y ) + self.invalidate_rect( self.overGateLoc[0], self.overGateLoc[1], self.overGateSize, self.overGateSize ) + if True: #obj != 12: + if gate[0] == 0: + _str = SynthLabConstants.SYNTHTYPES[obj/4][self.typesTable[obj]] + _(': controller output') + elif gate[0] == 1: + choosen = SynthLabConstants.CHOOSE_TYPE[obj/4][self.typesTable[obj]] + parametersTable = self.synthObjectsParameters.choiceParamsSet[obj/4] + tablePos = (obj % 4)*4+gate[1] + paraVal = '%.2f' % parametersTable[tablePos] + _str = SynthLabConstants.SYNTHTYPES[obj/4][self.typesTable[obj]] + '\n' + SynthLabConstants.SYNTHPARA[choosen][gate[1]] + ': ' + paraVal + if self.overGateObj == self.instanceID: + gateNum = self.overGate[1]+1 + exec 'self.slider%s.grab_focus()' % str(gateNum) + exec 'self.sendTables(self.slider%s, %d)' % (str(gateNum), gateNum) + elif gate[0] == 2: + _str = SynthLabConstants.SYNTHTYPES[obj/4][self.typesTable[obj]] + _(': sound output') + elif gate[0] == 3: + if obj != 12: + _str = SynthLabConstants.SYNTHTYPES[obj/4][self.typesTable[obj]] + _(': sound input') + else: + _str = _('Send sound to the speakers') + self.parameterUpdate( _str ) + + def startDragObject( self, i ): + self.dragObject = i + self.dragInitialLoc = (self.locations[i][0],self.locations[i][1]) + self.potentialDisconnect = False + self.invalidate_rect( self.bounds[i][0], self.bounds[i][1]-2, SynthLabConstants.PIC_SIZE, SynthLabConstants.PIC_SIZE_HIGHLIGHT ) + for i in self.outputMap[self.dragObject]: + self.invalidate_rect( self.cBounds[i][0], self.cBounds[i][1], self.cBounds[i][2], self.cBounds[i][3] ) + for i in self.inputMap[self.dragObject]: + self.invalidate_rect( self.cBounds[i][0], self.cBounds[i][1], self.cBounds[i][2], self.cBounds[i][3] ) + self.setAction( "drag-object" ) + + def updateDragObject( self, x, y ): + delta = [ x-self.clickLoc[0], y-self.clickLoc[1] ] + x = self.dragInitialLoc[0]+delta[0] + if x-SynthLabConstants.HALF_SIZE < 0: x = SynthLabConstants.HALF_SIZE + elif x+SynthLabConstants.HALF_SIZE > self.drawingAreaWidth: x = self.drawingAreaWidth - SynthLabConstants.HALF_SIZE + y = self.dragInitialLoc[1]+delta[1] + if y-SynthLabConstants.HALF_SIZE < 0: y = SynthLabConstants.HALF_SIZE + elif y+SynthLabConstants.HALF_SIZE > self.drawingAreaHeight: y = self.drawingAreaHeight - SynthLabConstants.HALF_SIZE + + self.invalidate_rect(self.bounds[self.dragObject][0], self.bounds[self.dragObject][1]-2, SynthLabConstants.PIC_SIZE, SynthLabConstants.PIC_SIZE_HIGHLIGHT, False ) + if not self.potentialDisconnect: + for i in self.outputMap[self.dragObject]: + self.invalidate_rect( self.cBounds[i][0], self.cBounds[i][1], self.cBounds[i][2], self.cBounds[i][3], False ) + for i in self.inputMap[self.dragObject]: + self.invalidate_rect( self.cBounds[i][0], self.cBounds[i][1], self.cBounds[i][2], self.cBounds[i][3], False ) + + if y > (self.separatorY-5): self.potentialDisconnect = True + else: self.potentialDisconnect = False + + self.locations[self.dragObject][0] = int( x ) + self.locations[self.dragObject][1] = int( y ) + self.updateBounds(self.dragObject) + + self.invalidate_rect(self.bounds[self.dragObject][0], self.bounds[self.dragObject][1]-2, SynthLabConstants.PIC_SIZE, SynthLabConstants.PIC_SIZE_HIGHLIGHT, False ) + if not self.potentialDisconnect: + for i in self.outputMap[self.dragObject]: + self.invalidate_rect( self.cBounds[i][0], self.cBounds[i][1], self.cBounds[i][2], self.cBounds[i][3], False ) + for i in self.inputMap[self.dragObject]: + self.invalidate_rect( self.cBounds[i][0], self.cBounds[i][1], self.cBounds[i][2], self.cBounds[i][3], False ) + + def doneDragObject( self ): + if self.potentialDisconnect: + self.invalidate_rect( self.bounds[self.dragObject][0], self.bounds[self.dragObject][1]-2, SynthLabConstants.PIC_SIZE, SynthLabConstants.PIC_SIZE_HIGHLIGHT, False ) + m = self.outputMap[self.dragObject][:] + m.sort(reverse=True) + for i in m: self.delConnection( i ) + m = self.inputMap[self.dragObject][:] + m.sort(reverse=True) + for i in m: self.delConnection( i ) + self.locations[self.dragObject][0] = SynthLabConstants.INIT_LOCATIONS[self.dragObject][0] + self.locations[self.dragObject][1] = SynthLabConstants.INIT_LOCATIONS[self.dragObject][1] + self.updateBounds( self.dragObject ) + #self.invalidate_rect(self.bounds[self.dragObject][0], self.bounds[self.dragObject][1]-2, SynthLabConstants.PIC_SIZE, SynthLabConstants.PIC_SIZE_HIGHLIGHT ) + else: + #self.invalidate_rect( self.bounds[self.dragObject][0], self.bounds[self.dragObject][1]-2, SynthLabConstants.PIC_SIZE, SynthLabConstants.PIC_SIZE_HIGHLIGHT ) + for i in self.outputMap[self.dragObject]: + self.invalidate_rect( self.cBounds[i][0], self.cBounds[i][1], self.cBounds[i][2], self.cBounds[i][3] ) + for i in self.inputMap[self.dragObject]: + self.invalidate_rect( self.cBounds[i][0], self.cBounds[i][1], self.cBounds[i][2], self.cBounds[i][3] ) + + # NOTE: select function invalidates the rect so no need to do it above + self.select( self.dragObject ) + + self.dragObject = None + self.handleSaveTemp() + + def updateBounds( self, i ): + self.bounds[i][0] = self.locations[i][0]-SynthLabConstants.HALF_SIZE + self.bounds[i][1] = self.locations[i][1]-SynthLabConstants.HALF_SIZE + self.bounds[i][2] = self.locations[i][0]+SynthLabConstants.HALF_SIZE + self.bounds[i][3] = self.locations[i][1]+SynthLabConstants.HALF_SIZE + + for c in self.outputMap[i]: + self.updateConnection( c ) + for c in self.inputMap[i]: + self.updateConnection( c ) + + def updateConnection( self, i ): + c = self.connections[i] + oT = c[0][0]//4 + x1 = self.locations[c[0][0]][0] + self.gateMap[oT][c[0][1]][c[0][2]][4][0] + y1 = self.locations[c[0][0]][1] + self.gateMap[oT][c[0][1]][c[0][2]][4][1] + oT = c[1][0]//4 + x2 = self.locations[c[1][0]][0] + self.gateMap[oT][c[1][1]][c[1][2]][4][0] + y2 = self.locations[c[1][0]][1] + self.gateMap[oT][c[1][1]][c[1][2]][4][1] + self.cPoints[i][0], self.cPoints[i][1], self.cPoints[i][2], self.cPoints[i][3] = ( x1, y1, x2, y2 ) + if x1 > x2: x1, x2 = ( x2, x1 ) + if y1 > y2: y1, y2 = ( y2, y1 ) + self.cBounds[i][0], self.cBounds[i][1], self.cBounds[i][2], self.cBounds[i][3], self.cBounds[i][4], self.cBounds[i][5] = ( x1-self.lineWidth, y1-self.lineWidth, x2-x1+self.lineWidthMUL2, y2-y1+self.lineWidthMUL2, x2+self.lineWidth, y2+self.lineWidth ) + + def findRecursive( self, obj, target ): + if obj == target: return True + for c in self.outputMap[obj]: + if self.findRecursive( self.straightConnections[c][1], target ): + return True + return False + + def testConnection( self, bObj, bGate, eObj, eGate ): + if self.gateMatch[bGate[0]] != eGate[0]: + return False # type mismatch + + for c in self.inputMap[eObj]: + if self.connections[c][1][1] == eGate[0] \ + and self.connections[c][1][2] == eGate[1] : # same type and port + if self.connections[c][0][0] == bObj: + return False # connections already exists + + if self.findRecursive( eObj, bObj ): + return False # loop + + return True + + def newConnection( self, bObj, bGate, eObj, eGate ): + if not self.testConnection( bObj, bGate, eObj, eGate ): + return -1 # connection failed + + ind = len(self.connections) + # connection format: [ ( outputObject, gate type, gate num ), ( inputObject, gate type, gate num ) ] + self.connections.append ( [ ( bObj, bGate[0], bGate[1] ), + ( eObj, eGate[0], eGate[1] ) ] ) + self.straightConnections.append( ( bObj, eObj ) ) + self.outputMap[bObj].append(ind) + self.inputMap[eObj].append(ind) + self.outputs.append( bObj ) + self.cPoints.append( [ 0, 0, 0, 0 ] ) + self.cBounds.append( [ 0, 0, 0, 0, 0, 0 ] ) + self.updateConnection( ind ) + + self.updateSound() + + self.handleSaveTemp() + + return ind + + def delConnection( self, i ): + b = self.straightConnections[i][0] + e = self.straightConnections[i][1] + self.straightConnections.pop(i) + self.outputMap[b].remove(i) + self.inputMap[e].remove(i) + self.outputs.pop(i) + self.cPoints.pop(i) + self.cBounds.pop(i) + self.connections.pop(i) + for o in range(self.objectCount): + for m in range(len(self.outputMap[o])): + if self.outputMap[o][m] > i: self.outputMap[o][m] -= 1 + for m in range(len(self.inputMap[o])): + if self.inputMap[o][m] > i: self.inputMap[o][m] -= 1 + + self.updateSound() + + self.handleSaveTemp() + + def initializeConnections( self ): + self.straightConnections = [] + self.outputMap = [ [] for i in self.locations ] + self.inputMap = [ [] for i in self.locations ] + self.outputs = [] + self.cPoints = [] + self.cBounds = [] + for i in range(len(self.connections)): + c = self.connections[i] + first = c[0][0] + second = c[1][0] + self.straightConnections.append([first, second]) + self.outputMap[first].append(i) + self.inputMap[second].append(i) + self.outputs.append(first) + self.cPoints.append( [ 0, 0, 0, 0 ] ) + self.cBounds.append( [ 0, 0, 0, 0, 0, 0 ] ) + self.updateConnection( i ) + + self.updateSound() + + def predraw( self, buf ): + startX = self.screenBufDirtyRect.x + startY = self.screenBufDirtyRect.y + stopX = self.screenBufDirtyRect.x + self.screenBufDirtyRect.width + stopY = self.screenBufDirtyRect.y + self.screenBufDirtyRect.height + + # draw bg + self.gc.foreground = self.bgColor + buf.draw_rectangle( self.gc, True, startX, startY, self.screenBufDirtyRect.width, self.screenBufDirtyRect.height ) + + # draw separator + self.gc.foreground = self.lineColor + buf.draw_line( self.gc, startX, 1, stopX, 1 ) + buf.draw_line( self.gc, startX, self.separatorY, stopX, self.separatorY ) + + # draw objects + types = self.synthObjectsParameters.getTypes() + [0] # speaker + self.gc.set_clip_mask( self.clipMask ) + for i in range(self.objectCount): + if i == self.dragObject or i == self.instanceID: + continue + if startX > self.bounds[i][2] or stopX < self.bounds[i][0] or startY > self.bounds[i][3] or stopY < self.bounds[i][1]: + continue + type = i >> 2 + self.gc.set_clip_origin( self.bounds[i][0]-SynthLabConstants.PIC_SIZE*type, self.bounds[i][1] ) + buf.draw_drawable( self.gc, self.pixmap[type][types[i]], 0, 0, self.bounds[i][0], self.bounds[i][1], SynthLabConstants.PIC_SIZE, SynthLabConstants.PIC_SIZE ) + + if self.dragObject != self.instanceID: + i = self.instanceID + type = i >> 2 + #draw object + self.gc.set_clip_origin( self.bounds[i][0]-SynthLabConstants.PIC_SIZE*type, self.bounds[i][1] ) + buf.draw_drawable( self.gc, self.pixmap[type][types[i]], 0, 0, self.bounds[i][0], self.bounds[i][1], SynthLabConstants.PIC_SIZE, SynthLabConstants.PIC_SIZE ) + # draw selectionHighlight + self.gc.set_clip_origin( self.bounds[i][0]-SynthLabConstants.PIC_SIZE*type, self.bounds[i][1]-82 ) + self.gc.foreground = self.highlightColor + buf.draw_rectangle( self.gc, True, self.bounds[i][0], self.bounds[i][1]-2, SynthLabConstants.PIC_SIZE, SynthLabConstants.PIC_SIZE_HIGHLIGHT ) + self.gc.foreground = self.lineColor + + self.gc.set_clip_rectangle( self.clearMask ) + + # draw wires + for c in range(len(self.connections)): + if self.straightConnections[c][0] == self.dragObject or self.straightConnections[c][1] == self.dragObject: + continue + if startX > self.cBounds[c][4] or stopX < self.cBounds[c][0] or startY > self.cBounds[c][5] or stopY < self.cBounds[c][1]: + continue + buf.draw_line( self.gc, self.cPoints[c][0], self.cPoints[c][1], + self.cPoints[c][2], self.cPoints[c][3] ) + + self.screenBufDirty = False + + def draw( self, widget, event ): + #TP.ProfileBegin("SL::draw") + startX = event.area.x + startY = event.area.y + stopX = event.area.x + event.area.width + stopY = event.area.y + event.area.height + + if self.screenBufDirty: + self.predraw( self.screenBuf ) + + # draw base + widget.window.draw_drawable( self.gc, self.screenBuf, startX, startY, startX, startY, event.area.width, event.area.height ) + + if self.action == "drag-object": + # draw dragObject + types = self.synthObjectsParameters.getTypes() + self.gc.set_clip_mask( self.clipMask ) + type = self.dragObject >> 2 + self.gc.set_clip_origin( self.bounds[self.dragObject][0]-SynthLabConstants.PIC_SIZE*type, self.bounds[self.dragObject][1] ) + widget.window.draw_drawable( self.gc, self.pixmap[type][types[self.dragObject]], 0, 0, self.bounds[self.dragObject][0], self.bounds[self.dragObject][1], SynthLabConstants.PIC_SIZE, SynthLabConstants.PIC_SIZE ) + + if self.instanceID == self.dragObject: + # draw selectionHighlight + self.gc.set_clip_origin( self.bounds[self.dragObject][0]-SynthLabConstants.PIC_SIZE*type, self.bounds[self.dragObject][1]-82 ) + self.gc.foreground = self.highlightColor + widget.window.draw_rectangle( self.gc, True, self.bounds[self.dragObject][0], self.bounds[self.dragObject][1]-2, SynthLabConstants.PIC_SIZE, SynthLabConstants.PIC_SIZE_HIGHLIGHT ) + + self.gc.set_clip_rectangle( self.clearMask ) + + # draw wires + if not self.potentialDisconnect: + self.gc.foreground = self.lineColor + for c in self.outputMap[self.dragObject]: + if startX > self.cBounds[c][4] or stopX < self.cBounds[c][0] or startY > self.cBounds[c][5] or stopY < self.cBounds[c][1]: + continue + widget.window.draw_line( self.gc, self.cPoints[c][0], self.cPoints[c][1], + self.cPoints[c][2], self.cPoints[c][3] ) + for c in self.inputMap[self.dragObject]: + if startX > self.cBounds[c][4] or stopX < self.cBounds[c][0] or startY > self.cBounds[c][5] or stopY < self.cBounds[c][1]: + continue + widget.window.draw_line( self.gc, self.cPoints[c][0], self.cPoints[c][1], + self.cPoints[c][2], self.cPoints[c][3] ) + elif self.action == "draw-wire": + # draw the wire + self.gc.foreground = self.lineColor + widget.window.draw_line( self.gc, self.wirePoint[0][0], self.wirePoint[0][1], + self.wirePoint[1][0], self.wirePoint[1][1] ) + + # draw highlights + if self.overWire != None: + self.gc.foreground = self.overWireColor + widget.window.draw_line( self.gc, self.cPoints[self.overWire][0], self.cPoints[self.overWire][1], + self.cPoints[self.overWire][2], self.cPoints[self.overWire][3] ) + elif self.overGate != None: + self.gc.set_line_attributes( self.overLineWidth, gtk.gdk.LINE_SOLID, gtk.gdk.CAP_BUTT, gtk.gdk.JOIN_MITER ) + if self.overGateReject: + self.gc.foreground = self.overGateRejectColor + widget.window.draw_line( self.gc, self.overGateLoc[0]+self.overLineWidth, self.overGateLoc[1]+self.overLineWidth, self.overGateLoc[0]+self.overGateSize-self.overLineWidth, self.overGateLoc[1]+self.overGateSize-self.overLineWidth ) + widget.window.draw_line( self.gc, self.overGateLoc[0]+self.overLineWidth, self.overGateLoc[1]+self.overGateSize-self.overLineWidth, self.overGateLoc[0]+self.overGateSize-self.overLineWidth, self.overGateLoc[1]+self.overLineWidth ) + else: + self.gc.foreground = self.overGateColor + widget.window.draw_arc( self.gc, False, self.overGateLoc[0]+self.overLineWidth, self.overGateLoc[1]+self.overLineWidth, self.overGateSize-self.overLineWidthMUL2, self.overGateSize-self.overLineWidthMUL2, 0, 23040 ) + self.gc.set_line_attributes( self.lineWidth, gtk.gdk.LINE_SOLID, gtk.gdk.CAP_BUTT, gtk.gdk.JOIN_MITER ) + + #print TP.ProfileEndAndPrint("SL::draw") + return True + + def invalidate_rect( self, x, y, w, h, dirtyScreenBuf = True ): + self.dirtyRectToAdd.x = x + self.dirtyRectToAdd.y = y + self.dirtyRectToAdd.width = w + self.dirtyRectToAdd.height = h + + if dirtyScreenBuf: + if self.screenBufDirty: + self.screenBufDirtyRect = self.screenBufDirtyRect.union(self.dirtyRectToAdd) + else: + self.screenBufDirtyRect.x = x + self.screenBufDirtyRect.y = y + self.screenBufDirtyRect.width = w + self.screenBufDirtyRect.height = h + self.screenBufDirty = True + + if self.drawingArea.window != None: + self.drawingArea.window.invalidate_rect( self.dirtyRectToAdd, True ) + + self.dirty = True + + def writeTables( self, typesTable, controlParametersTable, sourceParametersTable, fxParametersTable ): + mess = 'f5200 0 16 -2 ' + " ".join([str(n) for n in controlParametersTable]) + self.csnd.inputMessage( mess ) + time.sleep(0.001) + mess = "f5201 0 16 -2 " + " " .join([str(n) for n in sourceParametersTable]) + self.csnd.inputMessage( mess ) + time.sleep(.001) + mess = "f5202 0 16 -2 " + " " .join([str(n) for n in fxParametersTable]) + self.csnd.inputMessage( mess ) + time.sleep(.001) + self.typesTable = typesTable + lastTable = [0]*12 + for i in range(12): + if i in self.outputs: + lastTable[i] = (typesTable[i]+1) + mess = "f5203 0 16 -2 " + " " .join([str(n) for n in lastTable]) + " 0 0 0 0" + self.csnd.inputMessage( mess ) + time.sleep(.001) + if lastTable[4] == 8: + snd = Config.SOUNDS_DIR + '/' + self.sample_names[int(sourceParametersTable[1])] + mess = "f5501 0 32768 -1 " + "\"%s\" 0 0 0" % snd + self.csnd.inputMessage( mess ) + if lastTable[5] == 8: + snd = Config.SOUNDS_DIR + '/' + self.sample_names[int(sourceParametersTable[5])] + mess = "f5502 0 32768 -1 " + "\"%s\" 0 0 0" % snd + self.csnd.inputMessage( mess ) + if lastTable[6] == 8: + snd = Config.SOUNDS_DIR + '/' + self.sample_names[int(sourceParametersTable[9])] + mess = "f5503 0 32768 -1 " + "\"%s\" 0 0 0" % snd + self.csnd.inputMessage( mess ) + if lastTable[7] == 8: + snd = Config.SOUNDS_DIR + '/' + self.sample_names[int(sourceParametersTable[13])] + mess = "f5504 0 32768 -1 " + "\"%s\" 0 0 0" % snd + self.csnd.inputMessage( mess ) + time.sleep(.005) + + def recordSound( self, widget, data ): + if widget.get_active() == True: + self.recordButton = widget + self.recordWait = 1 + os.system('rm ' + Config.SNDS_DIR + '/lab' + str(data)) + self.table = 85 + data + else: + self.recordWait = 0 + + def updateSound( self ): + 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 = "f5203 0 16 -2 " + " " .join([str(n) for n in lastTable]) + " 0 0 0 0" + self.csnd.inputMessage( mess ) + time.sleep(.01) + + def updateTables( self ): + self.writeTables( self.synthObjectsParameters.types, self.synthObjectsParameters.controlsParameters, self.synthObjectsParameters.sourcesParameters, self.synthObjectsParameters.fxsParameters ) + + def controlToSrcConnections( self ): + self.contSrcConnections = [] + for i in self.connections: + if i[0][0] < 4 and 3 < i[1][0] < 8: + offset = i[1][2] + 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 = "f5204 0 16 -2 " + " " .join([str(n) for n in table]) + self.csnd.inputMessage( mess ) + + def controlToFxConnections( self ): + self.contFxConnections = [] + for i in self.connections: + if i[0][0] < 4 and 7 < i[1][0] < 12: + offset = i[1][2] + 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 = "f5205 0 16 -2 " + " " .join([str(n) for n in table]) + self.csnd.inputMessage( 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 = "f5206 0 16 -2 " + " " .join([str(n) for n in table]) + self.csnd.inputMessage( mess ) + + def loadPixmaps( self ): + win = gtk.gdk.get_default_root_window() + gc = gtk.gdk.GC( win ) + gc.foreground = self.bgColor + self.pixmap = [ [], [], [], [] ] + + def loadImg( type, img ): + pix = gtk.gdk.pixbuf_new_from_file(Config.TAM_TAM_ROOT + '/icons/sl-' + img + '.svg') + map = gtk.gdk.Pixmap( win, pix.get_width(), pix.get_height() ) + map.draw_rectangle( gc, True, 0, 0, pix.get_width(), pix.get_height() ) + map.draw_pixbuf( gc, pix, 0, 0, 0, 0, pix.get_width(), pix.get_height(), gtk.gdk.RGB_DITHER_NONE ) + self.pixmap[type].append(map) + + for i in range(len(SynthLabConstants.CONTROL_TYPES_PLUS)): + loadImg( 0, SynthLabConstants.CONTROL_TYPES_PLUS[i] ) + for i in range(len(SynthLabConstants.SOURCE_TYPES_PLUS)): + loadImg( 1, SynthLabConstants.SOURCE_TYPES_PLUS[i] ) + for i in range(len(SynthLabConstants.FX_TYPES_PLUS)): + loadImg( 2, SynthLabConstants.FX_TYPES_PLUS[i] ) + loadImg( 3, "speaker" ) + + pix = gtk.gdk.pixbuf_new_from_file(Config.IMAGE_ROOT+'synthlabMask.png') + pixels = pix.get_pixels() + stride = pix.get_rowstride() + channels = pix.get_n_channels() + bitmap = "" + byte = 0 + shift = 0 + for j in range(pix.get_height()): + offset = stride*j + for i in range(pix.get_width()): + r = pixels[i*channels+offset] + if r != "\0": byte += 1 << shift + shift += 1 + if shift > 7: + bitmap += "%c" % byte + byte = 0 + shift = 0 + if shift > 0: + bitmap += "%c" % byte + byte = 0 + shift = 0 + self.clipMask = gtk.gdk.bitmap_create_from_data( None, bitmap, pix.get_width(), pix.get_height() ) + + def handleSave(self, widget, data): + chooser = gtk.FileChooserDialog(title='Save SynthLab Preset',action=gtk.FILE_CHOOSER_ACTION_SAVE, buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_SAVE,gtk.RESPONSE_OK)) + filter = gtk.FileFilter() + filter.add_pattern('*.syn') + chooser.set_filter(filter) + chooser.set_current_folder(Config.SYNTH_DIR) + + for f in chooser.list_shortcut_folder_uris(): + chooser.remove_shortcut_folder_uri(f) + + if chooser.run() == gtk.RESPONSE_OK: + ofilename = chooser.get_filename() + if ofilename[-4:] != '.syn': + ofilename += '.syn' + try: + print 'INFO: save SynthLab file %s' % chooser.get_filename() + f = shelve.open(ofilename, 'n') + self.saveState(f) + f.close() + except IOError: + print 'ERROR: failed to save SynthLab to file %s' % chooser.get_filename() + + chooser.destroy() + + def handleJournalSave(self, file_path): + f = shelve.open(file_path, 'n') + self.saveState(f) + f.close() + + def handleLoad(self, widget, data): + chooser = gtk.FileChooserDialog(title='Load SynthLab Preset',action=gtk.FILE_CHOOSER_ACTION_OPEN, buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN,gtk.RESPONSE_OK)) + + filter = gtk.FileFilter() + filter.add_pattern('*.syn') + chooser.set_filter(filter) + chooser.set_current_folder(Config.SYNTH_DIR) + + for f in chooser.list_shortcut_folder_uris(): + chooser.remove_shortcut_folder_uri(f) + + 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 handleJournalLoad(self, file_path): + f = shelve.open( file_path, 'r') + self.loadState(f) + f.close() + + def handleSaveTemp( self ): + file = Config.PREF_DIR + '/synthTemp' + f = shelve.open(file, 'n') + self.saveState(f) + f.close() + + def handleLoadTemp( self ): + file = Config.PREF_DIR + '/synthTemp' + f = shelve.open(file, 'r') + self.loadState(f) + f.close() + + 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['envelope'] = self.synthObjectsParameters.outputParameters + state['locations'] = self.locations + state['connections'] = self.connections + state['duration'] = self.duration + + def tempVerifyLocations(self): + for l in self.locations: + l[0] = int(l[0]) + l[1] = int(l[1]) + + def tempVerifyConnectionFormat(self): + for c in self.connections: + if c[0][1] > 3 or c[0][2] > 3 \ + or c[1][1] > 3 or c[1][2] > 3: + print "old format" + print c + i = c[0] + if i[1] == 0 and i[2] == 40: + if i[0] < 4: t,n = 0,0 # control output + else: t,n = 2,0 # sound output + else: + print "unhandled loc" + t,n = i[1],i[2] + c[0] = ( c[0][0], t, n ) + i = c[1] + if i[1] == 0 and i[2] == -40: t,n = 3,0 + elif i[1] == 40 and i[2] == -19: t,n = 1,0 + elif i[1] == -25 and i[2] == -40: t,n = 1,0 + elif i[1] == -9 and i[2] == -40: t,n = 1,1 + elif i[1] == 8 and i[2] == -40: t,n = 1,2 + elif i[1] == 25 and i[2] == -40: t,n = 1,3 + else: + print "unhandled loc" + t,n = i[1],i[2] + c[1] = ( c[1][0], t, n ) + + 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.synthObjectsParameters.outputParameters = state['envelope'] + self.locations = state['locations'] + #self.tempVerifyLocations() + self.objectCount = len(self.locations) + for i in range(self.objectCount): + self.updateBounds( i ) + self.connections = state['connections'] + #self.tempVerifyConnectionFormat() + self.duration = state['duration'] + self._mainToolbar.durationSliderAdj.set_value(self.duration) + + self.initializeConnections() + self.controlToSrcConnections() + time.sleep(.01) + self.controlToFxConnections() + time.sleep(.01) + self.audioConnections() + time.sleep(.01) + self.synthObjectsParameters.update() + self.writeTables( self.synthObjectsParameters.types, self.synthObjectsParameters.controlsParameters, self.synthObjectsParameters.sourcesParameters, self.synthObjectsParameters.fxsParameters ) + time.sleep(.01) + self.invalidate_rect( 0, 0, self.drawingAreaWidth, self.drawingAreaHeight ) + + def presetCallback( self, widget, data ): + preset = 'synthFile' + str(data) + f = shelve.open( Config.TAM_TAM_ROOT + '/common/Resources/SynthFiles/' + preset, 'r') + self.loadState(f) + f.close() + self.handleSaveTemp() + + def initRadioButton( self, labelList, methodCallback, box ): + for i in range( len( labelList ) ): + label = labelList[i] + if i == 0: + button = ImageRadioButton( group = None, mainImg_path = Config.IMAGE_ROOT + label + '.png', altImg_path = Config.IMAGE_ROOT + label + 'sel.png' ) + else: + button = ImageRadioButton( group = button, mainImg_path = Config.IMAGE_ROOT + label + '.png', altImg_path = Config.IMAGE_ROOT + label + 'sel.png' ) + button.connect( "toggled", methodCallback, i ) + box.pack_start( button, True, True ) diff --git a/TamTamSynthLab.activity/SynthLab/SynthLabToolbars.py b/TamTamSynthLab.activity/SynthLab/SynthLabToolbars.py index 8b535eb..7b995b5 100644 --- a/TamTamSynthLab.activity/SynthLab/SynthLabToolbars.py +++ b/TamTamSynthLab.activity/SynthLab/SynthLabToolbars.py @@ -1,7 +1,7 @@ #!/usr/bin/env python import gtk -import Config +import common.Config as Config from sugar.graphics.toolbutton import ToolButton from sugar.graphics.toggletoolbutton import ToggleToolButton diff --git a/TamTamSynthLab.activity/TamTamSynthLab.py b/TamTamSynthLab.activity/TamTamSynthLab.py new file mode 100644 index 0000000..1381a65 --- /dev/null +++ b/TamTamSynthLab.activity/TamTamSynthLab.py @@ -0,0 +1,134 @@ +import locale +locale.setlocale(locale.LC_NUMERIC, 'C') +import signal , time , sys , os, shutil +import pygtk +pygtk.require( '2.0' ) +import gtk + +import gobject +import time + +import common.Config as Config +from common.Util.CSoundClient import new_csound_client +from common.Util.Profiler import TP + +from SynthLab.SynthLabMain import SynthLabMain +from common.Util.Trackpad import Trackpad +from gettext import gettext as _ +import commands +from sugar.activity import activity + +class TamTamSynthLab(activity.Activity): + def __init__(self, handle): + activity.Activity.__init__(self, handle) + self.ensure_dirs() + + color = gtk.gdk.color_parse(Config.WS_BCK_COLOR) + self.modify_bg(gtk.STATE_NORMAL, color) + + self.set_title('TamTam SynthLab') + self.set_resizable(False) + + self.trackpad = Trackpad( self ) + + self.preloadTimeout = None + + self.focusInHandler = self.connect('focus_in_event',self.onFocusIn) + self.focusOutHandler = self.connect('focus_out_event',self.onFocusOut) + self.connect('notify::active', self.onActive) + self.connect('destroy', self.onDestroy) + self.connect( "key-press-event", self.onKeyPress ) + self.connect( "key-release-event", self.onKeyRelease ) + + #load the sugar toolbar + self.toolbox = activity.ActivityToolbox(self) + self.set_toolbox(self.toolbox) + + self.activity_toolbar = self.toolbox.get_activity_toolbar() + self.activity_toolbar.share.hide() + self.activity_toolbar.keep.hide() + + self.toolbox.show() + + self.trackpad.setContext('synthLab') + self.synthLab = SynthLabMain(self) + + self.set_canvas( self.synthLab ) + + #self.synthLab.onActivate(arg = None) + self.show() + + def onPreloadTimeout( self ): + if Config.DEBUG > 4: print "TamTam::onPreloadTimeout", self.preloadList + + t = time.time() + if self.preloadList[0].load( t + 0.100 ): # finished preloading this object + self.preloadList.pop(0) + if not len(self.preloadList): + if Config.DEBUG > 1: print "TamTam::finished preloading", time.time() - t + self.preloadTimeout = False + return False # finished preloading everything + + if Config.DEBUG > 4: print "TamTam::preload returned after", time.time() - t + + return True + + def onFocusIn(self, event, data=None): + if Config.DEBUG > 3: print 'DEBUG: TamTam::onFocusOut in TamTam.py' + csnd = new_csound_client() + csnd.connect(True) + #csnd.load_instruments() + + def onFocusOut(self, event, data=None): + if Config.DEBUG > 3: print 'DEBUG: TamTam::onFocusOut in TamTam.py' + csnd = new_csound_client() + csnd.connect(False) + + def onActive(self, widget = None, event = None): + pass + + def onKeyPress(self, widget, event): + pass + + def onKeyRelease(self, widget, event): + pass + + def onDestroy(self, arg2): + if Config.DEBUG: print 'DEBUG: TamTam::onDestroy()' + os.system('rm -f ' + Config.PREF_DIR + '/synthTemp*') + + self.synthLab.onDestroy() + + csnd = new_csound_client() + csnd.connect(False) + csnd.destroy() + + gtk.main_quit() + + def ensure_dir(self, dir, perms=0777, rw=os.R_OK|os.W_OK): + if not os.path.isdir( dir ): + try: + os.makedirs(dir, perms) + except OSError, e: + print 'ERROR: failed to make dir %s: %i (%s)\n' % (dir, e.errno, e.strerror) + if not os.access(dir, rw): + print 'ERROR: directory %s is missing required r/w access\n' % dir + + def ensure_dirs(self): + self.ensure_dir(Config.TUNE_DIR) + self.ensure_dir(Config.SYNTH_DIR) + self.ensure_dir(Config.SNDS_DIR) + self.ensure_dir(Config.SCRATCH_DIR) + + if not os.path.isdir(Config.PREF_DIR): + os.mkdir(Config.PREF_DIR) + os.system('chmod 0777 ' + Config.PREF_DIR + ' &') + for snd in ['mic1','mic2','mic3','mic4','lab1','lab2','lab3','lab4', 'lab5', 'lab6']: + shutil.copyfile(Config.SOUNDS_DIR + '/' + snd , Config.SNDS_DIR + '/' + snd) + os.system('chmod 0777 ' + Config.SNDS_DIR + '/' + snd + ' &') + + def read_file(self,file_path): + self.synthLab.handleJournalLoad(file_path) + + def write_file(self,file_path): + self.synthLab.handleJournalSave(file_path) diff --git a/TamTamSynthLab.activity/activity/activity.info b/TamTamSynthLab.activity/activity/activity.info index 7a64eec..1b45e4f 100644 --- a/TamTamSynthLab.activity/activity/activity.info +++ b/TamTamSynthLab.activity/activity/activity.info @@ -2,5 +2,5 @@ name = TamTamSynthLab service_name = org.laptop.TamTamSynthLab icon = activity-tamtamsynthlab -class = TamTam.TamTamSynthLab +class = TamTamSynthLab.TamTamSynthLab activity_version = 40 diff --git a/TamTamSynthLab.activity/setup.py b/TamTamSynthLab.activity/setup.py index 5b21f11..c58f78c 100644 --- a/TamTamSynthLab.activity/setup.py +++ b/TamTamSynthLab.activity/setup.py @@ -17,5 +17,14 @@ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA from sugar.activity import bundlebuilder +import shutil +import os -bundlebuilder.start('TamTam') +#We are removing the symlink to common and replacing it with the real common folder +os.system('unlink common') +shutil.copytree('../common', 'common') + +bundlebuilder.start('TamTamSynthLab') +#Restore the symlink +os.system('rm -rf common') +os.system('ln -s ../common common') -- cgit v0.9.1