diff options
141 files changed, 1243 insertions, 1066 deletions
@@ -193,15 +193,15 @@ INST_TIED = 5001 INST_PERC = 5002 INST_SIMP = 5003 - +CATEGORIES = ['all','animals','concret','electronic','keyboard','people','percussions','strings','winds'] INSTRUMENTS = { OUNK : Instrument( 0, INST_SIMP, MID, 'melo', 'animals', 0, 0, 0 ), - GAM : Instrument( 1, INST_TIED, HIGH, 'melo', 'musicInst', .69388, .7536, .02922 ), - GONG : Instrument( 2, INST_SIMP, LOW, 'melo', 'musicInst', 0, 0, 0 ), - GUIT : Instrument( 3, INST_TIED, MID, 'melo', 'musicInst', .08592, .75126, .33571 ), - KOTO : Instrument( 4, INST_TIED, HIGH, 'melo', 'musicInst', .56523, .70075, .05954 ), - CLARINETTE : Instrument( 5, INST_TIED, MID, 'melo', 'musicInst', .57905, .73319, .04934 ), - FLUTE : Instrument( 6, INST_TIED, MID, 'melo', 'musicInst', .47169, .53693, .02481 ), + GAM : Instrument( 1, INST_TIED, HIGH, 'melo', 'percussions', .69388, .7536, .02922 ), + GONG : Instrument( 2, INST_SIMP, LOW, 'melo', 'percussions', 0, 0, 0 ), + GUIT : Instrument( 3, INST_TIED, MID, 'melo', 'strings', .08592, .75126, .33571 ), + KOTO : Instrument( 4, INST_TIED, HIGH, 'melo', 'strings', .56523, .70075, .05954 ), + CLARINETTE : Instrument( 5, INST_TIED, MID, 'melo', 'winds', .57905, .73319, .04934 ), + FLUTE : Instrument( 6, INST_TIED, MID, 'melo', 'winds', .47169, .53693, .02481 ), MIC1: Instrument( 7, INST_TIED, MID, 'melo', 'mic', .1, .9, .1 ), MIC2: Instrument( 8, INST_TIED, MID, 'melo', 'mic', .1, .9, .1 ), MIC3: Instrument( 9, INST_TIED, MID, 'melo', 'mic', .1, .9, .1 ), @@ -218,7 +218,7 @@ INSTRUMENTS = { DRUM1FLOORTOM: Instrument( 20, INST_SIMP, LOW, 'drum', 'drum', 0, 0, 0), DRUM1CHINE: Instrument( 21, INST_SIMP, PUNCH, 'drum', 'drum', 0, 0, 0 ), DRUM1KICK: Instrument( 22, INST_SIMP, LOW, 'drum', 'drum', 0, 0, 0 ), - PIANO: Instrument( 23, INST_TIED, MID, 'melo', 'musicInst', 2.39418, 2.53339, .01323 ), + PIANO: Instrument( 23, INST_TIED, MID, 'melo', 'keyboard', 2.39418, 2.53339, .01323 ), DOG: Instrument( 24, INST_SIMP, MID, 'melo', 'animals', 0, 0, 0 ), DUCK: Instrument( 25, INST_SIMP, MID, 'melo', 'animals', 0, 0, 0 ), DRUM2DARBUKADOOM: Instrument( 26, INST_SIMP, LOW, 'drum', 'drum', 0, 0 ,0 ), @@ -246,7 +246,7 @@ INSTRUMENTS = { DRUM3RAINSTICK: Instrument( 48, INST_SIMP, PUNCH, 'drum', 'drum', 0, 0, 0 ), DRUM3TAMBOURINEHIGH: Instrument( 49, INST_SIMP, PUNCH, 'drum', 'drum', 0, 0, 0 ), DRUM3TAMBOURINELOW: Instrument( 50, INST_SIMP, PUNCH, 'drum', 'drum', 0, 0, 0 ), - HARMONICA: Instrument( 51, INST_TIED, MID, 'melo', 'electronic', .1531, .19188, .01792 ), + HARMONICA: Instrument( 51, INST_TIED, MID, 'melo', 'winds', .1531, .19188, .01792 ), FM2: Instrument( 52, INST_TIED, MID, 'melo', 'electronic', .43443, .5784, .05127 ), BIRD: Instrument( 53, INST_TIED, MID, 'melo', 'animals', .1, 1, .05 ), CAT: Instrument( 54, INST_SIMP, MID, 'melo', 'animals', 0, 0, 0 ), @@ -257,44 +257,44 @@ INSTRUMENTS = { SHEEP: Instrument( 59, INST_SIMP, MID, 'melo', 'animals', 0, 0, 0 ), WATER: Instrument( 60, INST_SIMP, MID, 'melo', 'concret', 0, 0, 0 ), ZAP: Instrument( 61, INST_TIED, MID, 'melo', 'electronic', .299, .7323, .09895 ), - TRUMPET: Instrument( 62, INST_TIED, MID, 'melo', 'musicInst', .39934, .45537, .02729), - MARACAS: Instrument( 63, INST_SIMP, MID, "melo", 'musicInst', 0, 0, 0), - MARIMBA: Instrument( 64, INST_TIED, MID, "melo", 'musicInst', .26545, .33098, .03087), - TRIANGLE: Instrument( 65, INST_TIED, MID, "melo", 'musicInst', 1.21002, 1.31805, .01268), + TRUMPET: Instrument( 62, INST_TIED, MID, 'melo', 'winds', .39934, .45537, .02729), + MARACAS: Instrument( 63, INST_SIMP, MID, "melo", 'percussions', 0, 0, 0), + MARIMBA: Instrument( 64, INST_TIED, MID, "melo", 'percussions', .26545, .33098, .03087), + TRIANGLE: Instrument( 65, INST_TIED, MID, "melo", 'percussions', 1.21002, 1.31805, .01268), LAUGH: Instrument( 66, INST_SIMP, MID, 'melo', 'people', 0, 0, 0 ), VOIX: Instrument( 67, INST_TIED, MID, 'melo', 'people', .89608, .96092, .02343 ), CLING: Instrument( 68, INST_TIED, MID, 'melo', 'electronic', .09096, .7878, .18026 ), TCHIWO: Instrument( 69, INST_TIED, MID, 'melo', 'electronic', .91515, 1.00094, .02122 ), DOOR: Instrument( 70, INST_SIMP, MID, 'melo', 'concret', 0, 0, 0 ), - BASSE : Instrument( 71, INST_TIED, MID, 'melo', 'musicInst', .58455, .67433, .03638 ), - ACGUIT : Instrument( 72, INST_TIED, MID, 'melo', 'musicInst', .58503, .8667, .13699 ), - DICEINST : Instrument( 73, INST_SIMP, MID, 'melo', 'musicInst', 0, 0, 0 ), - DIDJERIDU : Instrument( 74, INST_TIED, LOW, 'melo', 'musicInst', .55669, 1.73704, .09178 ), - HARMONIUM : Instrument( 75, INST_TIED, MID, 'melo', 'musicInst', .04674, .41073, .18384 ), + BASSE : Instrument( 71, INST_TIED, MID, 'melo', 'strings', .58455, .67433, .03638 ), + ACGUIT : Instrument( 72, INST_TIED, MID, 'melo', 'strings', .58503, .8667, .13699 ), + DICEINST : Instrument( 73, INST_SIMP, MID, 'melo', 'concret', 0, 0, 0 ), + DIDJERIDU : Instrument( 74, INST_TIED, LOW, 'melo', 'winds', .55669, 1.73704, .09178 ), + HARMONIUM : Instrument( 75, INST_TIED, MID, 'melo', 'keyboard', .04674, .41073, .18384 ), HORSE : Instrument( 76, INST_SIMP, MID, 'melo', 'animals', 0, 0, 0 ), - KALIMBA : Instrument( 77, INST_TIED, MID, 'melo', 'musicInst', .20751, .30161, .04658 ), - MANDO : Instrument( 78, INST_TIED, MID, 'melo', 'musicInst', .50167, .54401, .01984 ), - OCARINA : Instrument( 79, INST_TIED, MID, 'melo', 'musicInst', .12122, .18965, .02205 ), - RHODES : Instrument( 80, INST_TIED, MID, 'melo', 'musicInst', .65013, .71429, .02205 ), - SAXO : Instrument( 81, INST_TIED, MID, 'melo', 'musicInst', .53722, .6583, .05264 ), - SHENAI : Instrument( 82, INST_TIED, MID, 'melo', 'musicInst', .29003, .33072, .00634 ), - SITAR : Instrument( 83, INST_TIED, MID, 'melo', 'musicInst', .63187, .67882, .01654 ), - TUBA : Instrument( 84, INST_TIED, LOW, 'melo', 'musicInst', .51063, .58384, .035 ), - VIOLIN : Instrument( 85, INST_TIED, MID, 'melo', 'musicInst', .55094, .82054, .14498 ), - LAB1 : Instrument( 86, INST_SIMP, MID, 'melo', 'musicInst', 0, 0, 0 ), - LAB2 : Instrument( 87, INST_SIMP, MID, 'melo', 'musicInst', 0, 0, 0 ), - LAB3 : Instrument( 88, INST_SIMP, MID, 'melo', 'musicInst', 0, 0, 0 ), - LAB4 : Instrument( 89, INST_SIMP, MID, 'melo', 'musicInst', 0, 0, 0 ), - GUIDICE1: Instrument( 90, INST_SIMP, MID, 'melo', 'concret', 0, 0, 0 ), - GUIDICE2: Instrument( 91, INST_SIMP, MID, 'melo', 'concret', 0, 0, 0 ), - GUIDICE3: Instrument( 92, INST_SIMP, MID, 'melo', 'concret', 0, 0, 0 ), - GUIDICE4: Instrument( 93, INST_SIMP, MID, 'melo', 'concret', 0, 0, 0 ), - GUIDICE5: Instrument( 94, INST_SIMP, MID, 'melo', 'concret', 0, 0, 0 ), - GUIDICE6: Instrument( 95, INST_SIMP, MID, 'melo', 'concret', 0, 0, 0 ), - GUIDICE7: Instrument( 96, INST_SIMP, MID, 'melo', 'concret', 0, 0, 0 ), - GUIDICE8: Instrument( 97, INST_SIMP, MID, 'melo', 'concret', 0, 0, 0 ), - GUIDICE9: Instrument( 98, INST_SIMP, MID, 'melo', 'concret', 0, 0, 0 ), - GUIDICE10: Instrument( 99, INST_SIMP, MID, 'melo', 'concret', 0, 0, 0 )} + KALIMBA : Instrument( 77, INST_TIED, MID, 'melo', 'percussions', .20751, .30161, .04658 ), + MANDO : Instrument( 78, INST_TIED, MID, 'melo', 'strings', .50167, .54401, .01984 ), + OCARINA : Instrument( 79, INST_TIED, MID, 'melo', 'winds', .12122, .18965, .02205 ), + RHODES : Instrument( 80, INST_TIED, MID, 'melo', 'keyboard', .65013, .71429, .02205 ), + SAXO : Instrument( 81, INST_TIED, MID, 'melo', 'winds', .53722, .6583, .05264 ), + SHENAI : Instrument( 82, INST_TIED, MID, 'melo', 'winds', .29003, .33072, .00634 ), + SITAR : Instrument( 83, INST_TIED, MID, 'melo', 'strings', .63187, .67882, .01654 ), + TUBA : Instrument( 84, INST_TIED, LOW, 'melo', 'winds', .51063, .58384, .035 ), + VIOLIN : Instrument( 85, INST_TIED, MID, 'melo', 'strings', .55094, .82054, .14498 ), + LAB1 : Instrument( 86, INST_SIMP, MID, 'melo', 'lab', 0, 0, 0 ), + LAB2 : Instrument( 87, INST_SIMP, MID, 'melo', 'lab', 0, 0, 0 ), + LAB3 : Instrument( 88, INST_SIMP, MID, 'melo', 'lab', 0, 0, 0 ), + LAB4 : Instrument( 89, INST_SIMP, MID, 'melo', 'lab', 0, 0, 0 ), + GUIDICE1: Instrument( 90, INST_SIMP, MID, 'melo', 'concret', 0, 0, 0 ), + GUIDICE2: Instrument( 91, INST_SIMP, MID, 'melo', 'concret', 0, 0, 0 ), + GUIDICE3: Instrument( 92, INST_SIMP, MID, 'melo', 'concret', 0, 0, 0 ), + GUIDICE4: Instrument( 93, INST_SIMP, MID, 'melo', 'concret', 0, 0, 0 ), + GUIDICE5: Instrument( 94, INST_SIMP, MID, 'melo', 'concret', 0, 0, 0 ), + GUIDICE6: Instrument( 95, INST_SIMP, MID, 'melo', 'concret', 0, 0, 0 ), + GUIDICE7: Instrument( 96, INST_SIMP, MID, 'melo', 'concret', 0, 0, 0 ), + GUIDICE8: Instrument( 97, INST_SIMP, MID, 'melo', 'concret', 0, 0, 0 ), + GUIDICE9: Instrument( 98, INST_SIMP, MID, 'melo', 'concret', 0, 0, 0 ), + GUIDICE10: Instrument( 99, INST_SIMP, MID, 'melo', 'concret', 0, 0, 0 )} DRUM1INSTRUMENTS = { 24 : DRUM1KICK, @@ -379,6 +379,9 @@ LANGUAGE = 'En' IMAGE_ROOT = TAM_TAM_ROOT + '/Resources/Images/' MAIN_WINDOW_PADDING = 5 + +BG_COLOR = "#8CAF97" + NOTE_HEIGHT = 9 # pixels NOTE_IMAGE_PADDING = 6 NOTE_IMAGE_PADDING_MUL2 = NOTE_IMAGE_PADDING*2 @@ -433,6 +436,9 @@ SL_OVER_GATE_REJECT_COLOR = "#B30000" PANEL_RADIUS = 10 PANEL_SPACING = 2 +###Welcome Screen Specific### +WS_PANEL_COLOR = '#72785B' +WS_BCK_COLOR = '#DFE5C5' # hardware keycodes for mod keys MOD_LSHIFT = 50 diff --git a/Docs/SynthLab.txt b/Docs/SynthLab.txt new file mode 100644 index 0000000..a4436a0 --- /dev/null +++ b/Docs/SynthLab.txt @@ -0,0 +1,2 @@ +SynthLab Documentation + diff --git a/Edit/MainWindow.py b/Edit/MainWindow.py index 785303f..a19a84c 100644 --- a/Edit/MainWindow.py +++ b/Edit/MainWindow.py @@ -3,7 +3,12 @@ pygtk.require( '2.0' ) import gtk import gobject + from Util.ThemeWidgets import * +from Util.Profiler import TP +from Util.NoteDB import NoteDB +from Util.CSoundClient import new_csound_client +from Util.InstrumentPanel import InstrumentPanel import time @@ -17,12 +22,9 @@ import Config from Edit.MixerWindow import MixerWindow from Generation.GenerationConstants import GenerationConstants from Generation.GenerationParametersWindow import GenerationParametersWindow -from Util.NoteDB import NoteDB from Edit.TrackInterface import TrackInterface, TrackInterfaceParasite from Edit.TuneInterface import TuneInterface, TuneInterfaceParasite -from Util.Profiler import TP - from Generation.Generator import generator1, variate #----------------------------------- @@ -30,8 +32,8 @@ from Generation.Generator import generator1, variate #----------------------------------- class MainWindow( gtk.EventBox ): - def __init__( self, CSoundClient ): - self.csnd = CSoundClient + def __init__( self ): + self.csnd = new_csound_client() def init_data( ): self._data = {} @@ -61,7 +63,7 @@ class MainWindow( gtk.EventBox ): self.trackSelected = [ 0 for i in range(Config.NUMBER_OF_TRACKS) ] self.noteDB = NoteDB() - self.noteDB.addListener( self, page=True ) # register for page notifications + self.noteDB.addListener( self, page=True, note=True ) # register for page notifications def formatRoundBox( box, fillcolor ): box.set_radius( 7 ) @@ -71,6 +73,8 @@ class MainWindow( gtk.EventBox ): return box def init_GUI(): + self.instrumentPanel = InstrumentPanel( self.donePickInstrument, enterMode = True ) + self.GUI = {} self.GUI["2main"] = gtk.HBox() @@ -97,7 +101,7 @@ class MainWindow( gtk.EventBox ): if 1: # + instrument panel self.GUI["2instrumentPanel"] = gtk.VBox() # + + instrument 1 box - self.GUI["2instrument1Box"] = formatRoundBox( RoundHBox(), "#6C9790" ) + self.GUI["2instrument1Box"] = formatRoundBox( RoundHBox(), Config.BG_COLOR ) self.GUI["2instrument1Box"].set_size_request( -1, 137 ) self.GUI["2instrument1volumeAdjustment"] = gtk.Adjustment( self._data["track_volume"][1], 0, 100, 1, 1, 0 ) self.GUI["2instrument1volumeAdjustment"].connect( "value_changed", self.onTrackVolumeChanged, 0 ) @@ -106,12 +110,13 @@ class MainWindow( gtk.EventBox ): self.GUI["2instrument1volumeSlider"].set_size_request( 30, -1 ) self.GUI["2instrument1volumeAdjustment"].connect( "value-changed", self.handleTrackVolume, 0 ) self.GUI["2instrument1Box"].pack_start( self.GUI["2instrument1volumeSlider"], False, False, 0 ) - #self.GUI["2instrument1Button"] = gtk.Button("Inst 1") - #self.GUI["2instrument1Box"].pack_start( self.GUI["2instrument1Button"] ) - self.GUI["2instrument1Box"].pack_start( track_menu(0,'?') ) + self.GUI["2instrument1Button"] = gtk.Button("Inst 1") + self.GUI["2instrument1Button"].connect("pressed", self.pickInstrument, 0 ) + self.GUI["2instrument1Box"].pack_start( self.GUI["2instrument1Button"] ) + #self.GUI["2instrument1Box"].pack_start( track_menu(0,'?') ) self.GUI["2instrumentPanel"].pack_start( self.GUI["2instrument1Box"] ) # + + instrument 2 box - self.GUI["2instrument2Box"] = formatRoundBox( RoundHBox(), "#6C9790" ) + self.GUI["2instrument2Box"] = formatRoundBox( RoundHBox(), Config.BG_COLOR ) self.GUI["2instrument2Box"].set_size_request( -1, 137 ) self.GUI["2instrument2volumeAdjustment"] = gtk.Adjustment( self._data["track_volume"][1], 0, 100, 1, 1, 0 ) self.GUI["2instrument2volumeAdjustment"].connect( "value_changed", self.onTrackVolumeChanged, 1 ) @@ -125,7 +130,7 @@ class MainWindow( gtk.EventBox ): self.GUI["2instrument2Box"].pack_start( track_menu(1,'?') ) self.GUI["2instrumentPanel"].pack_start( self.GUI["2instrument2Box"] ) # + + instrument 3 box - self.GUI["2instrument3Box"] = formatRoundBox( RoundHBox(), "#6C9790" ) + self.GUI["2instrument3Box"] = formatRoundBox( RoundHBox(), Config.BG_COLOR ) self.GUI["2instrument3Box"].set_size_request( -1, 137 ) self.GUI["2instrument3volumeAdjustment"] = gtk.Adjustment( self._data["track_volume"][2], 0, 100, 1, 1, 0 ) self.GUI["2instrument3volumeAdjustment"].connect( "value_changed", self.onTrackVolumeChanged, 2 ) @@ -139,7 +144,7 @@ class MainWindow( gtk.EventBox ): self.GUI["2instrument3Box"].pack_start( track_menu(2,'?') ) self.GUI["2instrumentPanel"].pack_start( self.GUI["2instrument3Box"] ) # + + instrument 4 box - self.GUI["2instrument4Box"] = formatRoundBox( RoundHBox(), "#6C9790" ) + self.GUI["2instrument4Box"] = formatRoundBox( RoundHBox(), Config.BG_COLOR ) self.GUI["2instrument4Box"].set_size_request( -1, 137 ) self.GUI["2instrument4volumeAdjustment"] = gtk.Adjustment( self._data["track_volume"][3], 0, 100, 1, 1, 0 ) self.GUI["2instrument4volumeAdjustment"].connect( "value_changed", self.onTrackVolumeChanged, 3 ) @@ -153,7 +158,7 @@ class MainWindow( gtk.EventBox ): self.GUI["2instrument4Box"].pack_start( track_menu(3,'?') ) self.GUI["2instrumentPanel"].pack_start( self.GUI["2instrument4Box"] ) # + + drum box - self.GUI["2drumBox"] = formatRoundBox( RoundHBox(), "#6C9790" ) + self.GUI["2drumBox"] = formatRoundBox( RoundHBox(), Config.BG_COLOR ) self.GUI["2drumBox"].set_size_request( -1, 165 ) self.GUI["2drumvolumeAdjustment"] = gtk.Adjustment( self._data["track_volume"][4], 0, 100, 1, 1, 0 ) self.GUI["2drumvolumeAdjustment"].connect( "value_changed", self.onTrackVolumeChanged, 4 ) @@ -168,7 +173,7 @@ class MainWindow( gtk.EventBox ): self.GUI["2instrumentPanel"].pack_start( self.GUI["2drumBox"] ) self.GUI["2leftPanel"].pack_start( self.GUI["2instrumentPanel"], False ) # + volume panel - self.GUI["2volumePanel"] = formatRoundBox( RoundHBox(), "#6C9790" ) + self.GUI["2volumePanel"] = formatRoundBox( RoundHBox(), Config.BG_COLOR ) # + + volume box self.GUI["2volumeBox"] = gtk.VBox() self.GUI["2volumeImage"] = gtk.Image() @@ -198,7 +203,7 @@ class MainWindow( gtk.EventBox ): # right panel self.GUI["2rightPanel"] = gtk.VBox() if 1: # + track interface - #self.GUI["2XYSliderFixed"] = formatRoundBox( RoundFixed(), "#6C9790" ) + #self.GUI["2XYSliderFixed"] = formatRoundBox( RoundFixed(), Config.BG_COLOR ) #self.GUI["2XYSliderFixed"].set_size_request( -1, 713 ) #self.GUI["2XYSliderButton"] = ImageToggleButton( Config.IMAGE_ROOT+"pointer.png", Config.IMAGE_ROOT+"pointerDown.png" ) #self.GUI["2XYSliderXAdjustment"] = gtk.Adjustment( 650, 500, 1000, 1, 1, 1 ) @@ -210,115 +215,122 @@ class MainWindow( gtk.EventBox ): self.trackInterface.set_size_request( -1, 713 ) self.GUI["2rightPanel"].pack_start( self.trackInterface, False, False, 0 ) # + tool panel + toolPanelHeight = 75 self.GUI["2toolPanel"] = gtk.HBox() - self.GUI["2toolPanel"].set_size_request( -1, 75 ) + self.GUI["2toolPanel"].set_size_request( -1, toolPanelHeight ) # + + tool box - self.GUI["2toolBox"] = formatRoundBox( RoundHBox(), "#6C9790" ) + self.GUI["2toolBox"] = formatRoundBox( RoundHBox(), Config.BG_COLOR ) self.GUI["2toolBox"].set_size_request( 154, -1 ) - self.GUI["2toolPointerButton"] = ImageRadioButton( None, Config.IMAGE_ROOT+"pointer.png", Config.IMAGE_ROOT+"pointerDown.png", backgroundFill = "#6C9790" ) + self.GUI["2toolPointerButton"] = ImageRadioButton( None, Config.IMAGE_ROOT+"pointer.png", Config.IMAGE_ROOT+"pointerDown.png", backgroundFill = Config.BG_COLOR ) self.GUI["2toolPointerButton"].connect( "clicked", self.handleToolClick , "default" ) self.GUI["2toolBox"].pack_start( self.GUI["2toolPointerButton"] ) - self.GUI["2toolPencilButton"] = ImageRadioButton( self.GUI["2toolPointerButton"], Config.IMAGE_ROOT+"pencil.png", Config.IMAGE_ROOT+"pencilDown.png", backgroundFill = "#6C9790" ) + self.GUI["2toolPencilButton"] = ImageRadioButton( self.GUI["2toolPointerButton"], Config.IMAGE_ROOT+"pencil.png", Config.IMAGE_ROOT+"pencilDown.png", backgroundFill = Config.BG_COLOR ) self.GUI["2toolPencilButton"].connect( "clicked", self.handleToolClick , "draw" ) self.GUI["2toolBox"].pack_start( self.GUI["2toolPencilButton"] ) self.GUI["2toolPanel"].pack_start( self.GUI["2toolBox"], False, False ) self.GUI["2rightPanel"].pack_start( self.GUI["2toolPanel"], False ) # + + context box (for context sensitive buttons, nothing to do with CAIRO) contextWidth = 674 - self.GUI["2contextBox"] = formatRoundBox( RoundFixed(), "#6C9790" ) + self.GUI["2contextBox"] = formatRoundBox( RoundFixed(), Config.BG_COLOR ) self.GUI["2contextBox"].set_size_request( contextWidth, -1 ) - self.GUI["2contextPrevButton"] = gtk.Button("<") + self.GUI["2contextPrevButton"] = ImageButton( Config.IMAGE_ROOT+"arrowEditLeft.png", backgroundFill = Config.BG_COLOR ) + self.GUI["2contextPrevButton"].set_size_request( 25, toolPanelHeight ) self.GUI["2contextPrevButton"].connect( "clicked", lambda a1:self.prevContext() ) self.GUI["2contextBox"].put( self.GUI["2contextPrevButton"], 0, 0 ) - self.GUI["2contextNextButton"] = gtk.Button(">") + self.GUI["2contextNextButton"] = ImageButton( Config.IMAGE_ROOT+"arrowEditRight.png", backgroundFill = Config.BG_COLOR ) + self.GUI["2contextNextButton"].set_size_request( 25, toolPanelHeight ) self.GUI["2contextNextButton"].connect( "clicked", lambda a1:self.nextContext() ) self.GUI["2contextBox"].put( self.GUI["2contextNextButton"], contextWidth-25, 0 ) # + + + page box self.GUI["2pageBox"] = gtk.HBox() - self.GUI["2pageBox"].set_size_request( contextWidth-50, -1 ) - self.GUI["2pageGenerateButton"] = gtk.Button("Gen") + self.GUI["2pageBox"].set_size_request( contextWidth-50, 73 ) + self.GUI["2pageGenerateButton"] = ImageButton( Config.IMAGE_ROOT+"genPage.png", Config.IMAGE_ROOT+"genPageDown.png", Config.IMAGE_ROOT+"genPageOver.png", backgroundFill = Config.BG_COLOR ) self.GUI["2pageGenerateButton"].connect( "clicked", lambda a1:self.pageGenerate() ) self.GUI["2pageBox"].pack_start( self.GUI["2pageGenerateButton"] ) - self.GUI["2pagePropertiesButton"] = gtk.Button("Prop") + self.GUI["2pagePropertiesButton"] = ImageButton( Config.IMAGE_ROOT+"propPage.png", Config.IMAGE_ROOT+"propPageDown.png", Config.IMAGE_ROOT+"propPageOver.png", backgroundFill = Config.BG_COLOR ) self.GUI["2pagePropertiesButton"].connect( "clicked", lambda a1:self.pageProperties() ) self.GUI["2pageBox"].pack_start( self.GUI["2pagePropertiesButton"] ) - self.GUI["2pageDeleteButton"] = gtk.Button("Delete") + self.GUI["2pageDeleteButton"] = ImageButton( Config.IMAGE_ROOT+"delPage.png", Config.IMAGE_ROOT+"delPageDown.png", Config.IMAGE_ROOT+"delPageOver.png", backgroundFill = Config.BG_COLOR ) self.GUI["2pageDeleteButton"].connect( "clicked", lambda a1:self.pageDelete() ) self.GUI["2pageBox"].pack_start( self.GUI["2pageDeleteButton"] ) - self.GUI["2pageDuplicateButton"] = gtk.Button("Duplicate") + self.GUI["2pageDuplicateButton"] = ImageButton( Config.IMAGE_ROOT+"dupPage.png", Config.IMAGE_ROOT+"dupPageDown.png", Config.IMAGE_ROOT+"dupPageOver.png", backgroundFill = Config.BG_COLOR ) self.GUI["2pageDuplicateButton"].connect( "clicked", lambda a1:self.pageDuplicate() ) self.GUI["2pageBox"].pack_start( self.GUI["2pageDuplicateButton"] ) - self.GUI["2pageNewButton"] = gtk.Button("New") + self.GUI["2pageNewButton"] = ImageButton( Config.IMAGE_ROOT+"addPage.png", Config.IMAGE_ROOT+"addPageDown.png", Config.IMAGE_ROOT+"addPageOver.png", backgroundFill = Config.BG_COLOR ) self.GUI["2pageNewButton"].connect( "clicked", lambda a1:self.pageAdd() ) self.GUI["2pageBox"].pack_start( self.GUI["2pageNewButton"] ) - self.GUI["2pageBeatsButton"] = gtk.Button("Beats") + self.GUI["2pageBeatsButton"] = ImageButton( Config.IMAGE_ROOT+"beatPage.png", Config.IMAGE_ROOT+"beatPageDown.png", Config.IMAGE_ROOT+"beatPageOver.png", backgroundFill = Config.BG_COLOR ) self.GUI["2pageBeatsButton"].connect( "clicked", lambda a1:self.pageBeats() ) self.GUI["2pageBox"].pack_start( self.GUI["2pageBeatsButton"] ) self.GUI["2contextBox"].put( self.GUI["2pageBox"], 25, 0 ) # + + + track box self.GUI["2trackBox"] = gtk.HBox() - self.GUI["2trackBox"].set_size_request( contextWidth-50, -1 ) - self.GUI["2trackGenerateButton"] = gtk.Button("tGen") + self.GUI["2trackBox"].set_size_request( contextWidth-50, 73 ) + self.GUI["2trackGenerateButton"] = ImageButton( Config.IMAGE_ROOT+"genTrack.png", Config.IMAGE_ROOT+"genTrackDown.png", Config.IMAGE_ROOT+"genTrackOver.png", backgroundFill = Config.BG_COLOR ) self.GUI["2trackGenerateButton"].connect( "clicked", lambda a1:self.trackGenerate() ) self.GUI["2trackBox"].pack_start( self.GUI["2trackGenerateButton"] ) - self.GUI["2trackPropertiesButton"] = gtk.Button("tProp") + self.GUI["2trackPropertiesButton"] = ImageButton( Config.IMAGE_ROOT+"propTrack.png", Config.IMAGE_ROOT+"propTrackDown.png", Config.IMAGE_ROOT+"propTrackOver.png", backgroundFill = Config.BG_COLOR ) self.GUI["2trackPropertiesButton"].connect( "clicked", lambda a1:self.trackProperties() ) self.GUI["2trackBox"].pack_start( self.GUI["2trackPropertiesButton"] ) - self.GUI["2trackDeleteButton"] = gtk.Button("tDelete") + self.GUI["2trackDeleteButton"] = ImageButton( Config.IMAGE_ROOT+"delTrack.png", Config.IMAGE_ROOT+"delTrackDown.png", Config.IMAGE_ROOT+"delTrackOver.png", backgroundFill = Config.BG_COLOR ) self.GUI["2trackDeleteButton"].connect( "clicked", lambda a1:self.trackDelete() ) self.GUI["2trackBox"].pack_start( self.GUI["2trackDeleteButton"] ) - self.GUI["2trackDuplicateButton"] = gtk.ToggleButton("tDuplicate") - self.GUI["2trackDuplicateButton"].connect( "toggled", lambda a1:self.trackDuplicate() ) + self.GUI["2trackDuplicateButton"] = ImageToggleButton( Config.IMAGE_ROOT+"dupTrack.png", Config.IMAGE_ROOT+"dupTrackDown.png", Config.IMAGE_ROOT+"dupTrackOver.png", backgroundFill = Config.BG_COLOR ) + self.GUI["2trackDuplicateButton"].connect( "toggled", self.trackDuplicateWidget ) self.GUI["2trackBox"].pack_start( self.GUI["2trackDuplicateButton"] ) self.GUI["2contextBox"].put( self.GUI["2trackBox"], 25, 0 ) # + + + note box self.GUI["2noteBox"] = gtk.HBox() - self.GUI["2noteBox"].set_size_request( contextWidth-50, -1 ) - self.GUI["2notePropertiesButton"] = gtk.Button("nProp") + self.GUI["2noteBox"].set_size_request( contextWidth-50, 73 ) + self.GUI["2notePropertiesButton"] = ImageButton( Config.IMAGE_ROOT+"propNote.png", Config.IMAGE_ROOT+"propNoteDown.png", Config.IMAGE_ROOT+"propNoteOver.png", backgroundFill = Config.BG_COLOR ) self.GUI["2notePropertiesButton"].connect( "clicked", lambda a1:self.noteProperties() ) self.GUI["2noteBox"].pack_start( self.GUI["2notePropertiesButton"] ) - self.GUI["2noteDeleteButton"] = gtk.Button("nDelete") + self.GUI["2noteDeleteButton"] = ImageButton( Config.IMAGE_ROOT+"delNote.png", Config.IMAGE_ROOT+"delNoteDown.png", Config.IMAGE_ROOT+"delNoteOver.png", backgroundFill = Config.BG_COLOR ) self.GUI["2noteDeleteButton"].connect( "clicked", lambda a1:self.noteDelete() ) self.GUI["2noteBox"].pack_start( self.GUI["2noteDeleteButton"] ) - self.GUI["2noteDuplicateButton"] = gtk.ToggleButton("nDuplicate") + self.GUI["2noteDuplicateButton"] = ImageToggleButton( Config.IMAGE_ROOT+"dupNote.png", Config.IMAGE_ROOT+"dupNoteDown.png", Config.IMAGE_ROOT+"dupNoteOver.png", backgroundFill = Config.BG_COLOR ) self.GUI["2noteDuplicateButton"].connect( "toggled", self.noteDuplicateWidget ) self.GUI["2noteBox"].pack_start( self.GUI["2noteDuplicateButton"] ) - self.GUI["2noteOnsetBox"] = gtk.HBox() - self.GUI["2noteOnsetMinusButton"] = gtk.Button("<") + self.GUI["2noteOnsetBox"] = gtk.HBox( False ) + self.GUI["2noteOnsetBox"].set_size_request( 72, -1 ) + self.GUI["2noteOnsetMinusButton"] = ImageButton( Config.IMAGE_ROOT+"editOnsetLeft.png", Config.IMAGE_ROOT+"editOnsetDownLeft.png", Config.IMAGE_ROOT+"editOnsetOverLeft.png", backgroundFill = Config.BG_COLOR ) self.GUI["2noteOnsetMinusButton"].connect( "clicked", lambda a1:self.trackInterface.noteStepOnset(-1) ) - self.GUI["2noteOnsetBox"].pack_start( self.GUI["2noteOnsetMinusButton"] ) - self.GUI["2noteOnsetPlusButton"] = gtk.Button(">") + self.GUI["2noteOnsetBox"].pack_start( self.GUI["2noteOnsetMinusButton"], False, False ) + self.GUI["2noteOnsetPlusButton"] = ImageButton( Config.IMAGE_ROOT+"editOnsetRight.png", Config.IMAGE_ROOT+"editOnsetDownRight.png", Config.IMAGE_ROOT+"editOnsetOverRight.png", backgroundFill = Config.BG_COLOR ) self.GUI["2noteOnsetPlusButton"].connect( "clicked", lambda a1:self.trackInterface.noteStepOnset(1) ) - self.GUI["2noteOnsetBox"].pack_start( self.GUI["2noteOnsetPlusButton"] ) + self.GUI["2noteOnsetBox"].pack_start( self.GUI["2noteOnsetPlusButton"], False, False ) self.GUI["2noteBox"].pack_start( self.GUI["2noteOnsetBox"] ) self.GUI["2notePitchBox"] = gtk.VBox() - self.GUI["2notePitchPlusButton"] = gtk.Button("^") + self.GUI["2notePitchBox"].set_size_request( 72, -1 ) + self.GUI["2notePitchPlusButton"] = ImageButton( Config.IMAGE_ROOT+"editPitchTop.png", Config.IMAGE_ROOT+"editPitchDownTop.png", Config.IMAGE_ROOT+"editPitchOverTop.png", backgroundFill = Config.BG_COLOR ) self.GUI["2notePitchPlusButton"].connect( "clicked", lambda a1:self.trackInterface.noteStepPitch(1) ) self.GUI["2notePitchBox"].pack_start( self.GUI["2notePitchPlusButton"] ) - self.GUI["2notePitchMinusButton"] = gtk.Button("v") + self.GUI["2notePitchMinusButton"] = ImageButton( Config.IMAGE_ROOT+"editPitchBot.png", Config.IMAGE_ROOT+"editPitchDownBot.png", Config.IMAGE_ROOT+"editPitchOverBot.png", backgroundFill = Config.BG_COLOR ) self.GUI["2notePitchMinusButton"].connect( "clicked", lambda a1:self.trackInterface.noteStepPitch(-1) ) self.GUI["2notePitchBox"].pack_start( self.GUI["2notePitchMinusButton"] ) self.GUI["2noteBox"].pack_start( self.GUI["2notePitchBox"] ) - self.GUI["2noteDurationBox"] = gtk.HBox() - self.GUI["2noteDurationMinusButton"] = gtk.Button("<") + self.GUI["2noteDurationBox"] = gtk.HBox( False ) + self.GUI["2noteDurationBox"].set_size_request( 72, -1 ) + self.GUI["2noteDurationMinusButton"] = ImageButton( Config.IMAGE_ROOT+"editDurLeft.png", Config.IMAGE_ROOT+"editDurDownLeft.png", Config.IMAGE_ROOT+"editDurOverLeft.png", backgroundFill = Config.BG_COLOR ) self.GUI["2noteDurationMinusButton"].connect( "clicked", lambda a1:self.trackInterface.noteStepDuration(-1) ) - self.GUI["2noteDurationBox"].pack_start( self.GUI["2noteDurationMinusButton"] ) - self.GUI["2noteDurationPlusButton"] = gtk.Button(">") + self.GUI["2noteDurationBox"].pack_start( self.GUI["2noteDurationMinusButton"], False, False ) + self.GUI["2noteDurationPlusButton"] = ImageButton( Config.IMAGE_ROOT+"editDurRight.png", Config.IMAGE_ROOT+"editDurDownRight.png", Config.IMAGE_ROOT+"editDurOverRight.png", backgroundFill = Config.BG_COLOR ) self.GUI["2noteDurationPlusButton"].connect( "clicked", lambda a1:self.trackInterface.noteStepDuration(1) ) - self.GUI["2noteDurationBox"].pack_start( self.GUI["2noteDurationPlusButton"] ) + self.GUI["2noteDurationBox"].pack_start( self.GUI["2noteDurationPlusButton"], False, False ) self.GUI["2noteBox"].pack_start( self.GUI["2noteDurationBox"] ) self.GUI["2noteVolumeBox"] = gtk.VBox() - self.GUI["2noteVolumePlusButton"] = gtk.Button("^") + self.GUI["2noteVolumeBox"].set_size_request( 72, -1 ) + self.GUI["2noteVolumePlusButton"] = ImageButton( Config.IMAGE_ROOT+"editAmpTop.png", Config.IMAGE_ROOT+"editAmpDownTop.png", Config.IMAGE_ROOT+"editAmpOverTop.png", backgroundFill = Config.BG_COLOR ) self.GUI["2noteVolumePlusButton"].connect( "clicked", lambda a1:self.trackInterface.noteStepVolume(0.05) ) self.GUI["2noteVolumeBox"].pack_start( self.GUI["2noteVolumePlusButton"] ) - self.GUI["2noteVolumeMinusButton"] = gtk.Button("v") + self.GUI["2noteVolumeMinusButton"] = ImageButton( Config.IMAGE_ROOT+"editAmpBot.png", Config.IMAGE_ROOT+"editAmpDownBot.png", Config.IMAGE_ROOT+"editAmpOverBot.png", backgroundFill = Config.BG_COLOR ) self.GUI["2noteVolumeMinusButton"].connect( "clicked", lambda a1:self.trackInterface.noteStepVolume(-0.05) ) self.GUI["2noteVolumeBox"].pack_start( self.GUI["2noteVolumeMinusButton"] ) self.GUI["2noteBox"].pack_start( self.GUI["2noteVolumeBox"] ) self.GUI["2contextBox"].put( self.GUI["2noteBox"], 25, 0 ) self.GUI["2toolPanel"].pack_start( self.GUI["2contextBox"], False ) # + + transport box - self.GUI["2transportBox"] = formatRoundBox( RoundHBox(), "#6C9790" ) + self.GUI["2transportBox"] = formatRoundBox( RoundHBox(), Config.BG_COLOR ) self.GUI["2recordButton"] = gtk.ToggleButton("R") self.GUI["2transportBox"].pack_start( self.GUI["2recordButton"] ) self.GUI["2playButton"] = gtk.ToggleButton("P") @@ -328,7 +340,7 @@ class MainWindow( gtk.EventBox ): self.GUI["2transportBox"].pack_start( self.GUI["2loopButton"] ) self.GUI["2toolPanel"].pack_start( self.GUI["2transportBox"] ) # + tune box - self.GUI["2tuneBox"] = formatRoundBox( RoundVBox(), "#6C9790" ) + self.GUI["2tuneBox"] = formatRoundBox( RoundVBox(), Config.BG_COLOR ) self.GUI["2tuneScrolledWindow"] = gtk.ScrolledWindow() self.GUI["2tuneScrolledWindow"].set_policy( gtk.POLICY_ALWAYS, gtk.POLICY_NEVER ) self.GUI["2tuneScrolledWindow"].set_shadow_type(gtk.SHADOW_NONE) @@ -341,6 +353,8 @@ class MainWindow( gtk.EventBox ): self.add( self.GUI["2main"] ) + self.skipCleanup = "" # used when jumping between duplicate note/track + self.generationParametersWindow = GenerationParametersWindow( self.generate, self.variate, self.handleCloseGenerationParametersWindow ) #=================================================== @@ -391,6 +405,21 @@ class MainWindow( gtk.EventBox ): self.GUI["2noteBox"].hide() self.setContext( CONTEXT.PAGE ) + self.tempPopup = gtk.Window(gtk.WINDOW_POPUP) + self.tempPopup.set_modal(True) + self.tempPopup.add_events( gtk.gdk.BUTTON_PRESS_MASK ) + self.tempPopup.connect("button-press-event", self.tempPopPress ) + #self.tempPopup.set_decorated(False) + b = gtk.Button("hello") + self.tempPopup.add(b) + self.tempPopup.move( 100, 100 ) + self.tempPopup.resize( 300, 100 ) + #self.tempPopup.show_all() + + def tempPopPress( self, w, event ): + print "pressed", event.x, event.y + self.tempPopup.hide() + def updateFPS( self ): t = time.time() dt = t - self.fpsLastTime @@ -418,20 +447,11 @@ class MainWindow( gtk.EventBox ): trackset = set( [ i for i in range(Config.NUMBER_OF_TRACKS) if self.trackSelected[i] ] ) - notes = [] - if len(trackset) == 0 or len(trackset) == Config.NUMBER_OF_TRACKS: - for page in self.pages_playing: - notes += self.noteDB.getCSNotesByPage( page ) - else: - for page in self.pages_playing: - for track in trackset: - notes += self.noteDB.getCSNotesByTrack( page, track ) - self.playing = True if self.predrawTimeout: gobject.source_remove( self.predrawTimeout ) self.predrawTimeout = False - self.playbackTimeout = gobject.timeout_add( 50, self.onTimeout ) + self.playbackTimeout = gobject.timeout_add( 20, self.onTimeout ) if len(self.pages_playing) > 1: self.displayPage( self.pages_playing[0], self.pages_playing[1] ) @@ -439,11 +459,20 @@ class MainWindow( gtk.EventBox ): self.displayPage( self.pages_playing[0] ) numticks = 0 - page_onset = {} + self.page_onset = {} for pid in self.pages_playing: - page_onset[pid] = numticks + self.page_onset[pid] = numticks numticks += self.noteDB.getPage(pid).ticks + notes = [] + if len(trackset) == 0 or len(trackset) == Config.NUMBER_OF_TRACKS: + for page in self.pages_playing: + notes += self.noteDB.getNotesByPage( page ) + else: + for page in self.pages_playing: + for track in trackset: + notes += self.noteDB.getNotesByTrack( page, track ) + print 'play!' print 'pages : ', self.pages_playing print 'trackset : ', trackset @@ -451,10 +480,9 @@ class MainWindow( gtk.EventBox ): print 'notes : ', len(notes), 'notes' self.csnd.loopClear() for n in notes: - n.onset += page_onset[n.pageId] - self.csnd.loopAdd(notes) - for n in notes: - n.onset -= page_onset[n.pageId] + n.cs.onset += self.page_onset[n.page] + self.csnd.loopPlay(n) #the tempo parameter is not used in loop mode + n.cs.onset -= self.page_onset[n.page] self.csnd.loopSetTick(0) self.csnd.loopSetNumTicks( numticks ) self.csnd.loopSetTempo(self._data['tempo']) @@ -488,9 +516,11 @@ class MainWindow( gtk.EventBox ): if self.pages_playing[curIdx] != self.displayedPage: if curIdx + 1 < len(self.pages_playing): predraw = self.pages_playing[curIdx+1] else: predraw = self.pages_playing[0] + if not self.trackInterface.predrawPage( time.time() ): + print 'WARNING: predraw incomplete' self.displayPage( self.pages_playing[curIdx], predraw ) else: - self.trackInterface.predrawPage( time.time() + 0.020 ) # 20 ms time limit + self.trackInterface.predrawPage( time.time() + 0.020 ) # 10 ms time limit return True @@ -537,6 +567,12 @@ class MainWindow( gtk.EventBox ): def handleTrackVolume( self, widget, track ): self._data["track_volume"][track] = round( widget.get_value() ) + def getTrackInstrument( self, track ): + return self._data["track_inst"][track] + + def getTrackVolume( self, track ): + return self._data["track_volume"][track] + def handleTempo( self, widget ): self._data['tempo'] = round( widget.get_value() ) img = min(7,int(8*(self._data["tempo"]-widget.lower)/(widget.upper-widget.lower)))+1# tempo 1-8 @@ -557,6 +593,17 @@ class MainWindow( gtk.EventBox ): self.kb_record = self.GUI["playButton"].get_active() and self.GUI["2recordButton"].get_active() + def pickInstrument( self, widget, num ): + print "pickInstrument", widget, num + self.GUI["2main"].remove( self.GUI["2rightPanel"] ) + self.GUI["2main"].pack_start( self.instrumentPanel ) + + def donePickInstrument( self, instrumentName ): + print "picked", instrumentName + self.GUI["2main"].remove( self.instrumentPanel ) + self.GUI["2main"].pack_start( self.GUI["2rightPanel"] ) + #self.instrumentPanel.destroy() + #----------------------------------- # generation functions #----------------------------------- @@ -645,9 +692,9 @@ class MainWindow( gtk.EventBox ): return self.noteDB.pasteClipboard( pages, offset, trackMap ) def cleanupClipboard( self ): - if self.GUI["2noteDuplicateButton"].get_active(): + if self.skipCleanup != "note" and self.GUI["2noteDuplicateButton"].get_active(): self.GUI["2noteDuplicateButton"].set_active(False) - if self.GUI["2trackDuplicateButton"].get_active(): + if self.skipCleanup != "track" and self.GUI["2trackDuplicateButton"].get_active(): self.GUI["2trackDuplicateButton"].set_active(False) self.trackInterface.donePaste() @@ -677,8 +724,10 @@ class MainWindow( gtk.EventBox ): if not N: continue stream += [ self.displayedPage, t, N ] + ids[t] if len(stream): + self.skipCleanup = "note" if self.GUI["2trackDuplicateButton"].get_active(): self.GUI["2trackDuplicateButton"].set_active( False ) + self.skipCleanup = "" self.noteDB.notesToClipboard( stream + [-1] ) self.trackInterface.setInterfaceMode("paste_notes") return True @@ -688,9 +737,11 @@ class MainWindow( gtk.EventBox ): if widget.get_active(): if self.noteDuplicate(): # duplicate succeeded return - # cancel duplicate - self.trackInterface.setInterfaceMode("tool") - widget.set_active(False) + # cancel duplicate + widget.set_active(False) + self.trackInterface.setInterfaceMode("tool") + else: + self.trackInterface.setInterfaceMode("tool") def noteOnset( self, step ): self.trackInterface.noteStepOnset( step ) @@ -767,8 +818,10 @@ class MainWindow( gtk.EventBox ): if trackIds == -1: trackIds = [ i for i in range(Config.NUMBER_OF_TRACKS) if self.trackSelected[i] ] if len(trackIds): + self.skipCleanup = "track" if self.GUI["2noteDuplicateButton"].get_active(): self.GUI["2noteDuplicateButton"].set_active( False ) + self.skipCleanup = "" self.noteDB.tracksToClipboard( pageIds, trackIds ) self.trackInterface.setInterfaceMode("paste_tracks") return True @@ -778,9 +831,11 @@ class MainWindow( gtk.EventBox ): if widget.get_active(): if self.trackDuplicate(): # duplicate succeeded return - # cancel duplicate - self.trackInterface.setInterfaceMode("tool") - widget.set_active(False) + # cancel duplicate + widget.set_active(False) + self.trackInterface.setInterfaceMode("tool") + else: + self.trackInterface.setInterfaceMode("tool") #----------------------------------- # tune/page functions @@ -811,6 +866,10 @@ class MainWindow( gtk.EventBox ): self.generationParametersWindow.show_all() def pageProperties( self, pageIds = -1 ): + #print "hello", self.tempPopup.has_toplevel_focus() + self.tempPopup.show_all() + #self.tempPopup.unfullscreen() + #self.menu.popup( None, None, None, self.GUI["2pagePropertiesButton"], 0 ) if pageIds == -1: pageIds = self.tuneInterface.getSelectedIds() @@ -858,6 +917,23 @@ class MainWindow( gtk.EventBox ): def notifyPageMove( self, which, low, high ): return + def notifyNoteAdd( self, page, track, id ): + if self.playing: + print 'INFO: adding note to loop', page, track, id + n = self.noteDB.getNote(page, track, id) + n.cs.onset = n.cs.onset + self.page_onset[n.page] + self.csnd.loopPlay(n) + n.cs.onset = n.cs.onset - self.page_onset[n.page] + def notifyNoteDelete( self, page, track, id ): + if self.playing: + print 'INFO: deleting note from loop', page, track, id + self.csnd.loopDelete1(page,id) + def notifyNoteUpdate( self, page, track, id, parameter, value ): + if self.playing: + print 'INFO: updating note ', page, id, parameter, value + note = self.noteDB.getNote(page, track, id) + self.csnd.loopUpdate(note, parameter, value) + #----------------------------------- # load and save functions #----------------------------------- diff --git a/Edit/NoteInterface.py b/Edit/NoteInterface.py index c923013..6b0a8c9 100644 --- a/Edit/NoteInterface.py +++ b/Edit/NoteInterface.py @@ -5,6 +5,7 @@ import gtk import Config from Util.NoteDB import PARAMETER +from Util.CSoundClient import new_csound_client class NoteInterface: @@ -88,7 +89,7 @@ class NoteInterface: self.imgX = self.x - Config.NOTE_IMAGE_PADDING self.oldOnset = self.note.cs.onset if self.end != self.oldEnd or self.note.cs.onset != self.oldOnset: - self.width = self.owner.ticksToPixels( self.noteDB.getPage( self.note.page).beats, self.end ) - self.x - self.origin[0] + self.width = self.owner.ticksToPixels( self.noteDB.getPage( self.note.page).beats, self.end ) - self.x + self.origin[0] self.imgWidth = self.width + Config.NOTE_IMAGE_PADDING_MUL2 self.oldEnd = self.end if self.note.cs.pitch != self.oldPitch: @@ -128,11 +129,20 @@ class NoteInterface: self.basePitch = self.note.cs.pitch self.baseDuration = self.note.cs.duration - def updateSampleNote( self, pitch ): - return + def playSampleNote( self, full=True ): + secs_per_tick = 0.025 + csnd = new_csound_client() - def clearSampleNote( self ): - return + if full: + onset = self.note.cs.onset + self.note.cs.onset = 0 + csnd.play( self.note.cs, 0.024) + self.note.cs.onset = onset + else: + (onset,duration) = ( self.note.cs.onset, self.note.cs.duration) + ( self.note.cs.onset, self.note.cs.duration) = (0, 10) + csnd.play( self.note.cs, 0.024) + ( self.note.cs.onset, self.note.cs.duration) = (onset,duration) #======================================================= # Events @@ -175,7 +185,7 @@ class NoteInterface: self.potentialDeselect = True else: emitter.selectNotes( { self.note.track: [ self ] } ) - self.updateSampleNote( self.note.cs.pitch ) + self.playSampleNote( ) percent = eX/self.width if percent < 0.3: emitter.setCurrentAction( "note-drag-onset", self ) @@ -190,7 +200,7 @@ class NoteInterface: self.potentialDeselect = False emitter.deselectNotes( { self.note.track: [ self ] } ) - self.clearSampleNote() + self.playSampleNote() emitter.doneCurrentAction() @@ -207,6 +217,7 @@ class NoteInterface: if dp != self.lastDragP: self.lastDragP = dp stream += [ self.note.id, self.basePitch + dp ] + self.playSampleNote(False) def noteDragDuration( self, dd, stream ): self.potentialDeselect = False @@ -223,7 +234,7 @@ class NoteInterface: self.lastDragP = 0 self.lastDragD = 0 - self.clearSampleNote() + self.playSampleNote() def noteDecOnset( self, step, leftBound, stream ): if self.selected: diff --git a/Edit/TrackInterface.py b/Edit/TrackInterface.py index ce3ad6e..364a68f 100644 --- a/Edit/TrackInterface.py +++ b/Edit/TrackInterface.py @@ -11,6 +11,7 @@ from Edit.HitInterface import HitInterface from Edit.MainWindow import CONTEXT from Util.NoteDB import PARAMETER +from Util.CSoundNote import CSoundNote from Util.Profiler import TP @@ -65,6 +66,7 @@ class TrackInterface( gtk.EventBox ): self.curAction = False # stores the current mouse action self.curActionObject = False # stores the object that in handling the action + self.clickButton = 0 # used in release and motion events to make sure we where actually the widget originally clicked. (hack for popup windows) self.buttonPressCount = 1 # used on release events to indicate double/triple releases self.clickLoc = [0,0] # location of the last click self.marqueeLoc = False # current drag location of the marquee @@ -288,6 +290,15 @@ class TrackInterface( gtk.EventBox ): TP.ProfileBegin( "TI::handleButtonPress" ) + self.clickButton = event.button + + if event.button != 1: + print "Should bring up some note parameters or something!" + #self.noteParameters = NoteParametersWindow( self.trackDictionary, self.getNoteParameters ) + #self.setCurrentAction( "noteParameters", False ) + TP.ProfileEnd( "TI::handleButtonPress" ) + return + if event.type == gtk.gdk._2BUTTON_PRESS: self.buttonPressCount = 2 elif event.type == gtk.gdk._3BUTTON_PRESS: self.buttonPressCount = 3 else: self.buttonPressCount = 1 @@ -329,20 +340,46 @@ class TrackInterface( gtk.EventBox ): break if self.interfaceMode == INTERFACEMODE.DRAW: - if handled == -1: # event occured before this note and didn't overlap with the previous note, so we can draw - print "draw a note" + if not handled or handled == -1: # event didn't overlap any notes, so we can draw + if i == self.drumIndex: pitch = min( self.pixelsToPitchDrumFloor( self.clickLoc[1] - self.trackLimits[i][1] + Config.HIT_HEIGHT//2 )//Config.PITCH_STEP_DRUM, Config.NUMBER_OF_POSSIBLE_PITCHES_DRUM-1)*Config.PITCH_STEP_DRUM + Config.MINIMUM_PITCH_DRUM + else: pitch = min( self.pixelsToPitchFloor( self.clickLoc[1] - self.trackLimits[i][1] + Config.NOTE_HEIGHT//2 ), Config.NUMBER_OF_POSSIBLE_PITCHES-1) + Config.MINIMUM_PITCH + print "draw a note", self.curPage, i, self.pixelsToTicksFloor( self.curBeats, self.clickLoc[0] ), pitch + cs = CSoundNote( self.pixelsToTicksFloor( self.curBeats, self.clickLoc[0] - self.trackRect[i].x ), + pitch, + 0.75, + 0, + 1, + i, + instrument = self.owner.getTrackInstrument(i), + instrumentFlag = self.owner.getTrackInstrument(i) ) + cs.pageId = self.curPage + id = self.noteDB.addNote( self.curPage, i, cs ) + n = self.noteDB.getNote( self.curPage, i, id, self ) + self.selectNotes( { i:[n] }, True ) + if i != self.drumIndex: # switch to drag duration + self.updateDragLimits() + self.clickLoc[0] += self.ticksToPixels( self.curBeats, 1 ) + self.setCurrentAction( "note-drag-duration", n ) + self.setCursor("drag-duration") + else: + self.curAction = True # we handled this, but there's no real action - if event.button == 3: - print "Should bring up some note parameters or something!" - #self.noteParameters = NoteParametersWindow( self.trackDictionary, self.getNoteParameters ) - #self.setCurrentAction( "noteParameters", False ) + TP.ProfileEnd( "TI::handleButtonPress" ) + return TP.ProfileEnd( "TI::handleButtonPress" ) def handleButtonRelease( self, widget, event ): + if not self.clickButton: return # we recieved this event but were never clicked! (probably a popup window was open) + self.clickButton = 0 + TP.ProfileBegin( "TI::handleButtonRelease" ) + if event.button != 1: + TP.ProfileEnd( "TI::handleButtonRelease" ) + return + if not self.curAction: #do track selection stuff here so that we can also handle marquee selection for i in range(Config.NUMBER_OF_TRACKS): if self.trackLimits[i][0] > event.y: break @@ -385,6 +422,12 @@ class TrackInterface( gtk.EventBox ): TP.ProfileEnd( "TI::handleMotion::Common" ) + if not self.clickButton and self.curAction != "paste": # we recieved this event but were never clicked! (probably a popup window was open) + TP.ProfileBegin( "TI::handleMotion::Hover" ) + self.updateTooltip( event ) + TP.ProfileEnd( "TI::handleMotion::Hover" ) + return + if self.curAction == "paste": TP.ProfileBegin( "TI::handleMotion::Paste" ) top = Config.NUMBER_OF_TRACKS @@ -393,7 +436,7 @@ class TrackInterface( gtk.EventBox ): if self.trackLimits[i][1] < event.y: continue top = i break - self.updatePaste( self.pixelsToTicks( self.curBeats, event.x ), top ) + self.updatePaste( self.pixelsToTicksFloor( self.curBeats, event.x ), top ) TP.ProfileEnd( "TI::handleMotion::Paste" ) elif event.state & gtk.gdk.BUTTON1_MASK: TP.ProfileBegin( "TI::handleMotion::Drag" ) @@ -1079,11 +1122,23 @@ class TrackInterface( gtk.EventBox ): return int(round( ticks * self.pixelsPerTick[beats] )) def pixelsToTicks( self, beats, pixels ): return int(round( pixels * self.ticksPerPixel[beats] )) + def ticksToPixelsFloor( self, beats, ticks ): + return int( ticks * self.pixelsPerTick[beats] ) + def pixelsToTicksFloor( self, beats, pixels ): + return int( pixels * self.ticksPerPixel[beats] ) def pitchToPixels( self, pitch ): - return int(round( ( Config.MAXIMUM_PITCH - pitch ) * self.pixelsPerPitch )) + return int(round( ( Config.MAXIMUM_PITCH - pitch ) * self.pixelsPerPitch )) def pixelsToPitch( self, pixels ): return int(round(-pixels*self.pitchPerPixel)) + def pitchToPixelsFloor( self, pitch ): + return int(( Config.MAXIMUM_PITCH - pitch ) * self.pixelsPerPitch ) + def pixelsToPitchFloor( self, pixels ): + return int(-pixels*self.pitchPerPixel) def pitchToPixelsDrum( self, pitch ): - return int(round( ( Config.MAXIMUM_PITCH_DRUM - pitch ) * self.pixelsPerPitchDrum )) + return int(round( ( Config.MAXIMUM_PITCH_DRUM - pitch ) * self.pixelsPerPitchDrum )) def pixelsToPitchDrum( self, pixels ): return int(round(-pixels*self.pitchPerPixelDrum)) + def pitchToPixelsDrumFloor( self, pitch ): + return int( ( Config.MAXIMUM_PITCH_DRUM - pitch ) * self.pixelsPerPitchDrum ) + def pixelsToPitchDrumFloor( self, pixels ): + return int(-pixels*self.pitchPerPixelDrum) diff --git a/Edit/TuneInterface.py b/Edit/TuneInterface.py index d1d5481..ce61dd3 100644 --- a/Edit/TuneInterface.py +++ b/Edit/TuneInterface.py @@ -90,6 +90,10 @@ class TuneInterface( gtk.EventBox ): self.set_size_request( max( self.baseWidth, width), -1 ) def handleButtonPress( self, widget, event ): + if event.button != 1: + # bring up properties or something + return + ind = int(event.x-self.pageOffset)//self.pageSpacing if ind >= self.noteDB.getPageCount(): if self.dragMode != self.DRAG_MOVE: @@ -101,10 +105,6 @@ class TuneInterface( gtk.EventBox ): id = self.noteDB.getPageByIndex( ind ) - if event.state & gtk.gdk.BUTTON2_MASK: - # bring up properties or something - return - if event.type == gtk.gdk._3BUTTON_PRESS: # triple click -> select all self.selectAll() self.owner.displayPage( id ) @@ -130,8 +130,10 @@ class TuneInterface( gtk.EventBox ): self.owner.setContext( CONTEXT.PAGE ) def handleButtonRelease( self, widget, event ): - if self.dragMode == self.DRAG_MOVE \ - and event.button == 1: + if event.button != 1: + return + + if self.dragMode == self.DRAG_MOVE: self.invalidate_rect( 0, 0, self.width, self.height ) # drop head if self.dropAt > 0: after = self.noteDB.getPageByIndex( self.dropAt-1 ) diff --git a/Player/StandalonePlayerOld.py b/Player/StandalonePlayerOld.py deleted file mode 100644 index f388663..0000000 --- a/Player/StandalonePlayerOld.py +++ /dev/null @@ -1,178 +0,0 @@ -import pygtk -pygtk.require( '2.0' ) -import gtk -import os - -from Framework.Constants import Constants -from Framework.CSound.CSoundClient import CSoundClient -from Framework.CSound.CSoundConstants import CSoundConstants -from Player.KeyboardStandAlone import KeyboardStandAlone -from Player.NoteStdAlone import NoteStdAlone - -raise 'dont use this class, its the old one' - -class StandAlonePlayer( gtk.Window ): - - def __init__(self): - gtk.Window.__init__( self, gtk.WINDOW_TOPLEVEL ) - self.set_title('TamTam Player') - self.set_resizable(False) - - self.instrument = self.getInstrumentList()[0] - #self.setInstrument(self.instrument) - - CSoundClient.initialize() - CSoundClient.setMasterVolume(100) - - self.connect( "destroy" , self.destroy ) - self.mainWindowBox = gtk.VBox() - self.add(self.mainWindowBox) - - self.enableKeyboard() - self.drawMainInstrumentButton() - self.drawMicButton() - self.drawReverb() - self.drawInstrumentWindow() - - self.show_all() - - def drawMicButton( self ): - micButtonImg = gtk.Image() - micButtonImg.set_from_file(Constants.TAM_TAM_ROOT + '/GUI/Core/images/record.png') - - self.micButton = gtk.Button() - self.micButton.set_image(micButtonImg) - self.micButton.connect('clicked' , self.handleMicButtonClick) - self.mainWindowBox.add(self.micButton) - self.micButton.set_no_show_all(True) - self.micButton.hide() - - def drawReverb( self ): - reverbAdjustment = gtk.Adjustment(value=0, lower=0, upper=1, step_incr=0.1, page_incr=0, page_size=0) - reverbSlider = gtk.HScale(adjustment = reverbAdjustment) - reverbSlider.set_draw_value(False) - reverbAdjustment.connect("value_changed" , self.setReverb) - - reverbLabel = gtk.Label("Reverb") - self.mainWindowBox.add(reverbSlider) - self.mainWindowBox.add(reverbLabel) - - def drawMainInstrumentButton(self): - self.mainInstrumentButtonImg = gtk.Image() - self.mainInstrumentButtonImg.set_from_file(Constants.TAM_TAM_ROOT + '/GUI/Core/images/' + self.getInstrumentList()[0] + '.png') - instrumentButton = gtk.Button(label=None) - instrumentButton.set_image(self.mainInstrumentButtonImg) - instrumentButton.connect('clicked' , self.handleMainInstrumentButton, 'clicked') - self.mainWindowBox.add(instrumentButton) - - def drawInstrumentWindow(self): - ROW_LEN = 4 - self.instrumentWindow = gtk.Window() - self.instrumentWindow.set_decorated(False) - self.instrumentWindow.set_keep_above(True) - - vBox = gtk.VBox() - - intrumentNum = len(self.getInstrumentList()) - rows = ( intrumentNum / ROW_LEN ) - if intrumentNum % ROW_LEN is not 0: #S'il y a un reste - rows = rows + 1 - - for row in range(rows): - hBox = gtk.HBox() - for instrument in self.getInstrumentList()[row*ROW_LEN:(row+1)*ROW_LEN]: - instImage = gtk.Image() - instButton = gtk.Button(label=None) - instImage.set_from_file(Constants.TAM_TAM_ROOT + '/GUI/Core/images/' + instrument + '.png') - instButton.set_image(instImage) - #instButton.set_relief(gtk.RELIEF_NONE) - instButton.connect('clicked' , self.handleWindowButtonsClick , instrument) - instButton.connect('enter' , self.handleWindowButtonsEnter , instrument) - hBox.add(instButton) - vBox.add(hBox) - self.instrumentWindow.add(vBox) - - def handleMainInstrumentButton(self , widget , data): - if self.instrumentWindow.get_property('visible') is True: - if self.instrument[0:3] is not 'mic': - self.micButton.hide() - self.instrumentWindow.hide() - return - pos = self.get_position() - self.instrumentWindow.move(pos[0] + 68 , pos[1] + 24) - self.instrumentWindow.show_all() - - def handleWindowButtonsClick(self , widget , instrument): - if instrument[0:3] == 'mic': - self.micButton.show() - else: - self.micButton.hide() - self.instrumentWindow.hide() - - - def handleWindowButtonsEnter(self , widget , instrument): - self.mainInstrumentButtonImg.set_from_file(Constants.TAM_TAM_ROOT + '/GUI/Core/images/' + instrument + '.png') - self.setInstrument(instrument) - self.playInstrumentNote(instrument) - - def handleMicButtonClick(self , widget , data = None): - if self.instrument == 'mic1': - CSoundClient.micRecording(7) - elif self.instrument == 'mic2': - CSoundClient.micRecording(8) - elif self.instrument == 'mic3': - CSoundClient.micRecording(9) - elif self.instrument == 'mic4': - CSoundClient.micRecording(10) - else: - print 'Bad instrument' - - def enableKeyboard( self ): - self.keyboardStandAlone = KeyboardStandAlone() - - self.add_events(gtk.gdk.BUTTON_PRESS_MASK) - self.connect( "key-press-event", self.keyboardStandAlone.onKeyPress ) - self.connect( "key-release-event", self.keyboardStandAlone.onKeyRelease ) - #self.connect( "button-press-event", self.button ) - - def setInstrument( self , instrument ): - self.instrument = instrument - self.keyboardStandAlone.setInstrument(instrument) - - def setReverb(self,adj): - self.keyboardStandAlone.setReverb(adj.value) - - def playInstrumentNote(self , instrument): - note = NoteStdAlone( onset = 0, - pitch = 36, - amplitude = 1, - pan = 0.5, - duration = 20, - trackId = 1, - fullDuration = False, - instrument = instrument, - instrumentFlag = instrument, - reverbSend = 0) - note.play() - - def getInstrumentList(self): - CSoundInstruments = CSoundConstants.INSTRUMENTS.keys() - cleanInstrumentList = [] - for instrumentName in CSoundInstruments: - if not instrumentName[0: 4] == 'drum' and not instrumentName[0: 3] == 'mic': - cleanInstrumentList.append( instrumentName ) - cleanInstrumentList.append('drum1kit') - cleanInstrumentList.append('drum2kit') - cleanInstrumentList.append('drum3kit') - cleanInstrumentList.sort() - for n in range(4): - cleanInstrumentList.append('mic' + str(n+1)) - return cleanInstrumentList - - def destroy( self, widget ): - gtk.main_quit() - -if __name__ == "__main__": - standAlonePlayer = StandAlonePlayer() - #start the gtk event loop - gtk.main() diff --git a/Resources/Images/TamTam.png b/Resources/Images/TamTam.png Binary files differnew file mode 100755 index 0000000..6219932 --- /dev/null +++ b/Resources/Images/TamTam.png diff --git a/Resources/Images/addPage.png b/Resources/Images/addPage.png Binary files differnew file mode 100755 index 0000000..87e6b4a --- /dev/null +++ b/Resources/Images/addPage.png diff --git a/Resources/Images/addPageDown.png b/Resources/Images/addPageDown.png Binary files differnew file mode 100755 index 0000000..062e71f --- /dev/null +++ b/Resources/Images/addPageDown.png diff --git a/Resources/Images/addPageODOwn.png b/Resources/Images/addPageODOwn.png Binary files differnew file mode 100755 index 0000000..80e6c22 --- /dev/null +++ b/Resources/Images/addPageODOwn.png diff --git a/Resources/Images/addPageOver.png b/Resources/Images/addPageOver.png Binary files differnew file mode 100755 index 0000000..43df982 --- /dev/null +++ b/Resources/Images/addPageOver.png diff --git a/Resources/Images/arrowEditLeft.png b/Resources/Images/arrowEditLeft.png Binary files differnew file mode 100755 index 0000000..dfdc5b4 --- /dev/null +++ b/Resources/Images/arrowEditLeft.png diff --git a/Resources/Images/arrowEditRight.png b/Resources/Images/arrowEditRight.png Binary files differnew file mode 100755 index 0000000..8330d2c --- /dev/null +++ b/Resources/Images/arrowEditRight.png diff --git a/Resources/Images/beatOver.png b/Resources/Images/beatOver.png Binary files differnew file mode 100755 index 0000000..6a6b5db --- /dev/null +++ b/Resources/Images/beatOver.png diff --git a/Resources/Images/beatPage.png b/Resources/Images/beatPage.png Binary files differnew file mode 100755 index 0000000..59c7668 --- /dev/null +++ b/Resources/Images/beatPage.png diff --git a/Resources/Images/beatPageDown.png b/Resources/Images/beatPageDown.png Binary files differnew file mode 100755 index 0000000..013798d --- /dev/null +++ b/Resources/Images/beatPageDown.png diff --git a/Resources/Images/beatPageOver.png b/Resources/Images/beatPageOver.png Binary files differnew file mode 100755 index 0000000..a348c3e --- /dev/null +++ b/Resources/Images/beatPageOver.png diff --git a/Resources/Images/beatslidPage.png b/Resources/Images/beatslidPage.png Binary files differnew file mode 100755 index 0000000..7866cad --- /dev/null +++ b/Resources/Images/beatslidPage.png diff --git a/Resources/Images/delNote.png b/Resources/Images/delNote.png Binary files differnew file mode 100755 index 0000000..af04020 --- /dev/null +++ b/Resources/Images/delNote.png diff --git a/Resources/Images/delNoteDown.png b/Resources/Images/delNoteDown.png Binary files differnew file mode 100755 index 0000000..70d136b --- /dev/null +++ b/Resources/Images/delNoteDown.png diff --git a/Resources/Images/delNoteOver.png b/Resources/Images/delNoteOver.png Binary files differnew file mode 100755 index 0000000..5625b4f --- /dev/null +++ b/Resources/Images/delNoteOver.png diff --git a/Resources/Images/delPage.png b/Resources/Images/delPage.png Binary files differnew file mode 100755 index 0000000..feab32a --- /dev/null +++ b/Resources/Images/delPage.png diff --git a/Resources/Images/delPageDown.png b/Resources/Images/delPageDown.png Binary files differnew file mode 100755 index 0000000..a83eb3f --- /dev/null +++ b/Resources/Images/delPageDown.png diff --git a/Resources/Images/delPageOver.png b/Resources/Images/delPageOver.png Binary files differnew file mode 100755 index 0000000..67c5ba7 --- /dev/null +++ b/Resources/Images/delPageOver.png diff --git a/Resources/Images/delTrack.png b/Resources/Images/delTrack.png Binary files differnew file mode 100755 index 0000000..78117d4 --- /dev/null +++ b/Resources/Images/delTrack.png diff --git a/Resources/Images/delTrackDown.png b/Resources/Images/delTrackDown.png Binary files differnew file mode 100755 index 0000000..862e5a8 --- /dev/null +++ b/Resources/Images/delTrackDown.png diff --git a/Resources/Images/delTrackOver.png b/Resources/Images/delTrackOver.png Binary files differnew file mode 100755 index 0000000..5da2949 --- /dev/null +++ b/Resources/Images/delTrackOver.png diff --git a/Resources/Images/deletePage.png b/Resources/Images/deletePage.png Binary files differnew file mode 100755 index 0000000..03862b5 --- /dev/null +++ b/Resources/Images/deletePage.png diff --git a/Resources/Images/dupNote.png b/Resources/Images/dupNote.png Binary files differnew file mode 100755 index 0000000..2fcd0e9 --- /dev/null +++ b/Resources/Images/dupNote.png diff --git a/Resources/Images/dupNoteDown.png b/Resources/Images/dupNoteDown.png Binary files differnew file mode 100755 index 0000000..97d5766 --- /dev/null +++ b/Resources/Images/dupNoteDown.png diff --git a/Resources/Images/dupNoteOver.png b/Resources/Images/dupNoteOver.png Binary files differnew file mode 100755 index 0000000..516c1f5 --- /dev/null +++ b/Resources/Images/dupNoteOver.png diff --git a/Resources/Images/dupPage.png b/Resources/Images/dupPage.png Binary files differnew file mode 100755 index 0000000..1cd5b84 --- /dev/null +++ b/Resources/Images/dupPage.png diff --git a/Resources/Images/dupPageDown.png b/Resources/Images/dupPageDown.png Binary files differnew file mode 100755 index 0000000..7582b19 --- /dev/null +++ b/Resources/Images/dupPageDown.png diff --git a/Resources/Images/dupPageOver.png b/Resources/Images/dupPageOver.png Binary files differnew file mode 100755 index 0000000..b3514ab --- /dev/null +++ b/Resources/Images/dupPageOver.png diff --git a/Resources/Images/dupTrack.png b/Resources/Images/dupTrack.png Binary files differnew file mode 100755 index 0000000..3eae1b1 --- /dev/null +++ b/Resources/Images/dupTrack.png diff --git a/Resources/Images/dupTrackDown.png b/Resources/Images/dupTrackDown.png Binary files differnew file mode 100755 index 0000000..014d713 --- /dev/null +++ b/Resources/Images/dupTrackDown.png diff --git a/Resources/Images/dupTrackOver.png b/Resources/Images/dupTrackOver.png Binary files differnew file mode 100755 index 0000000..b3db0a7 --- /dev/null +++ b/Resources/Images/dupTrackOver.png diff --git a/Resources/Images/ebeat10.png b/Resources/Images/ebeat10.png Binary files differnew file mode 100755 index 0000000..c5a2c2d --- /dev/null +++ b/Resources/Images/ebeat10.png diff --git a/Resources/Images/ebeat10Up.png b/Resources/Images/ebeat10Up.png Binary files differnew file mode 100755 index 0000000..c62394f --- /dev/null +++ b/Resources/Images/ebeat10Up.png diff --git a/Resources/Images/ebeat11.png b/Resources/Images/ebeat11.png Binary files differnew file mode 100755 index 0000000..19bf84c --- /dev/null +++ b/Resources/Images/ebeat11.png diff --git a/Resources/Images/ebeat11Up.png b/Resources/Images/ebeat11Up.png Binary files differnew file mode 100755 index 0000000..7041a61 --- /dev/null +++ b/Resources/Images/ebeat11Up.png diff --git a/Resources/Images/ebeat12.png b/Resources/Images/ebeat12.png Binary files differnew file mode 100755 index 0000000..c04c76f --- /dev/null +++ b/Resources/Images/ebeat12.png diff --git a/Resources/Images/ebeat12Up.png b/Resources/Images/ebeat12Up.png Binary files differnew file mode 100755 index 0000000..a5c814b --- /dev/null +++ b/Resources/Images/ebeat12Up.png diff --git a/Resources/Images/ebeat13.png b/Resources/Images/ebeat13.png Binary files differnew file mode 100755 index 0000000..cb7f7a2 --- /dev/null +++ b/Resources/Images/ebeat13.png diff --git a/Resources/Images/ebeat13Up.png b/Resources/Images/ebeat13Up.png Binary files differnew file mode 100755 index 0000000..cf798e1 --- /dev/null +++ b/Resources/Images/ebeat13Up.png diff --git a/Resources/Images/ebeat14.png b/Resources/Images/ebeat14.png Binary files differnew file mode 100755 index 0000000..16ba4e8 --- /dev/null +++ b/Resources/Images/ebeat14.png diff --git a/Resources/Images/ebeat14Up.png b/Resources/Images/ebeat14Up.png Binary files differnew file mode 100755 index 0000000..79616c7 --- /dev/null +++ b/Resources/Images/ebeat14Up.png diff --git a/Resources/Images/ebeat15.png b/Resources/Images/ebeat15.png Binary files differnew file mode 100755 index 0000000..1d202d7 --- /dev/null +++ b/Resources/Images/ebeat15.png diff --git a/Resources/Images/ebeat15Up.png b/Resources/Images/ebeat15Up.png Binary files differnew file mode 100755 index 0000000..9eca1c9 --- /dev/null +++ b/Resources/Images/ebeat15Up.png diff --git a/Resources/Images/ebeat16.png b/Resources/Images/ebeat16.png Binary files differnew file mode 100755 index 0000000..03144ff --- /dev/null +++ b/Resources/Images/ebeat16.png diff --git a/Resources/Images/ebeat16Up.png b/Resources/Images/ebeat16Up.png Binary files differnew file mode 100755 index 0000000..d64af31 --- /dev/null +++ b/Resources/Images/ebeat16Up.png diff --git a/Resources/Images/ebeat2.png b/Resources/Images/ebeat2.png Binary files differnew file mode 100755 index 0000000..0331dca --- /dev/null +++ b/Resources/Images/ebeat2.png diff --git a/Resources/Images/ebeat2Up.png b/Resources/Images/ebeat2Up.png Binary files differnew file mode 100755 index 0000000..ce56d53 --- /dev/null +++ b/Resources/Images/ebeat2Up.png diff --git a/Resources/Images/ebeat3.png b/Resources/Images/ebeat3.png Binary files differnew file mode 100755 index 0000000..8595d53 --- /dev/null +++ b/Resources/Images/ebeat3.png diff --git a/Resources/Images/ebeat3Up.png b/Resources/Images/ebeat3Up.png Binary files differnew file mode 100755 index 0000000..387e7c4 --- /dev/null +++ b/Resources/Images/ebeat3Up.png diff --git a/Resources/Images/ebeat4.png b/Resources/Images/ebeat4.png Binary files differnew file mode 100755 index 0000000..cd7da6d --- /dev/null +++ b/Resources/Images/ebeat4.png diff --git a/Resources/Images/ebeat4Up.png b/Resources/Images/ebeat4Up.png Binary files differnew file mode 100755 index 0000000..d0544fa --- /dev/null +++ b/Resources/Images/ebeat4Up.png diff --git a/Resources/Images/ebeat5.png b/Resources/Images/ebeat5.png Binary files differnew file mode 100755 index 0000000..e480033 --- /dev/null +++ b/Resources/Images/ebeat5.png diff --git a/Resources/Images/ebeat5Up.png b/Resources/Images/ebeat5Up.png Binary files differnew file mode 100755 index 0000000..226868a --- /dev/null +++ b/Resources/Images/ebeat5Up.png diff --git a/Resources/Images/ebeat6.png b/Resources/Images/ebeat6.png Binary files differnew file mode 100755 index 0000000..92f3bb6 --- /dev/null +++ b/Resources/Images/ebeat6.png diff --git a/Resources/Images/ebeat6Up.png b/Resources/Images/ebeat6Up.png Binary files differnew file mode 100755 index 0000000..5b7938c --- /dev/null +++ b/Resources/Images/ebeat6Up.png diff --git a/Resources/Images/ebeat7.png b/Resources/Images/ebeat7.png Binary files differnew file mode 100755 index 0000000..2f5398a --- /dev/null +++ b/Resources/Images/ebeat7.png diff --git a/Resources/Images/ebeat7Up.png b/Resources/Images/ebeat7Up.png Binary files differnew file mode 100755 index 0000000..0997c1c --- /dev/null +++ b/Resources/Images/ebeat7Up.png diff --git a/Resources/Images/ebeat8.png b/Resources/Images/ebeat8.png Binary files differnew file mode 100755 index 0000000..2190c84 --- /dev/null +++ b/Resources/Images/ebeat8.png diff --git a/Resources/Images/ebeat8Up.png b/Resources/Images/ebeat8Up.png Binary files differnew file mode 100755 index 0000000..50d4f83 --- /dev/null +++ b/Resources/Images/ebeat8Up.png diff --git a/Resources/Images/ebeat9.png b/Resources/Images/ebeat9.png Binary files differnew file mode 100755 index 0000000..0eae788 --- /dev/null +++ b/Resources/Images/ebeat9.png diff --git a/Resources/Images/ebeat9Up.png b/Resources/Images/ebeat9Up.png Binary files differnew file mode 100755 index 0000000..abbd9bb --- /dev/null +++ b/Resources/Images/ebeat9Up.png diff --git a/Resources/Images/editAmpBot.png b/Resources/Images/editAmpBot.png Binary files differnew file mode 100755 index 0000000..4469401 --- /dev/null +++ b/Resources/Images/editAmpBot.png diff --git a/Resources/Images/editAmpDownBot.png b/Resources/Images/editAmpDownBot.png Binary files differnew file mode 100755 index 0000000..d72385b --- /dev/null +++ b/Resources/Images/editAmpDownBot.png diff --git a/Resources/Images/editAmpDownTop.png b/Resources/Images/editAmpDownTop.png Binary files differnew file mode 100755 index 0000000..d8b351a --- /dev/null +++ b/Resources/Images/editAmpDownTop.png diff --git a/Resources/Images/editAmpOverBot.png b/Resources/Images/editAmpOverBot.png Binary files differnew file mode 100755 index 0000000..deb2309 --- /dev/null +++ b/Resources/Images/editAmpOverBot.png diff --git a/Resources/Images/editAmpOverTop.png b/Resources/Images/editAmpOverTop.png Binary files differnew file mode 100755 index 0000000..03a0b55 --- /dev/null +++ b/Resources/Images/editAmpOverTop.png diff --git a/Resources/Images/editAmpTop.png b/Resources/Images/editAmpTop.png Binary files differnew file mode 100755 index 0000000..bf46783 --- /dev/null +++ b/Resources/Images/editAmpTop.png diff --git a/Resources/Images/editDurDownLeft.png b/Resources/Images/editDurDownLeft.png Binary files differnew file mode 100755 index 0000000..1fad77e --- /dev/null +++ b/Resources/Images/editDurDownLeft.png diff --git a/Resources/Images/editDurDownRight.png b/Resources/Images/editDurDownRight.png Binary files differnew file mode 100755 index 0000000..8dc9102 --- /dev/null +++ b/Resources/Images/editDurDownRight.png diff --git a/Resources/Images/editDurLeft.png b/Resources/Images/editDurLeft.png Binary files differnew file mode 100755 index 0000000..79ff5ea --- /dev/null +++ b/Resources/Images/editDurLeft.png diff --git a/Resources/Images/editDurOverLeft.png b/Resources/Images/editDurOverLeft.png Binary files differnew file mode 100755 index 0000000..7dcaf71 --- /dev/null +++ b/Resources/Images/editDurOverLeft.png diff --git a/Resources/Images/editDurOverRight.png b/Resources/Images/editDurOverRight.png Binary files differnew file mode 100755 index 0000000..3156991 --- /dev/null +++ b/Resources/Images/editDurOverRight.png diff --git a/Resources/Images/editDurRight.png b/Resources/Images/editDurRight.png Binary files differnew file mode 100755 index 0000000..c3eba1e --- /dev/null +++ b/Resources/Images/editDurRight.png diff --git a/Resources/Images/editOnsetDownLeft.png b/Resources/Images/editOnsetDownLeft.png Binary files differnew file mode 100755 index 0000000..a514a23 --- /dev/null +++ b/Resources/Images/editOnsetDownLeft.png diff --git a/Resources/Images/editOnsetDownRight.png b/Resources/Images/editOnsetDownRight.png Binary files differnew file mode 100755 index 0000000..4737ad8 --- /dev/null +++ b/Resources/Images/editOnsetDownRight.png diff --git a/Resources/Images/editOnsetLeft.png b/Resources/Images/editOnsetLeft.png Binary files differnew file mode 100755 index 0000000..6eed2ee --- /dev/null +++ b/Resources/Images/editOnsetLeft.png diff --git a/Resources/Images/editOnsetOverLeft.png b/Resources/Images/editOnsetOverLeft.png Binary files differnew file mode 100755 index 0000000..d9bc04b --- /dev/null +++ b/Resources/Images/editOnsetOverLeft.png diff --git a/Resources/Images/editOnsetOverRight.png b/Resources/Images/editOnsetOverRight.png Binary files differnew file mode 100755 index 0000000..adb0eb0 --- /dev/null +++ b/Resources/Images/editOnsetOverRight.png diff --git a/Resources/Images/editOnsetRight.png b/Resources/Images/editOnsetRight.png Binary files differnew file mode 100755 index 0000000..77e42eb --- /dev/null +++ b/Resources/Images/editOnsetRight.png diff --git a/Resources/Images/editPitchBot.png b/Resources/Images/editPitchBot.png Binary files differnew file mode 100755 index 0000000..efd84e2 --- /dev/null +++ b/Resources/Images/editPitchBot.png diff --git a/Resources/Images/editPitchDown.png b/Resources/Images/editPitchDown.png Binary files differnew file mode 100755 index 0000000..83407de --- /dev/null +++ b/Resources/Images/editPitchDown.png diff --git a/Resources/Images/editPitchDownBot.png b/Resources/Images/editPitchDownBot.png Binary files differnew file mode 100755 index 0000000..c4b4a0b --- /dev/null +++ b/Resources/Images/editPitchDownBot.png diff --git a/Resources/Images/editPitchDownDown.png b/Resources/Images/editPitchDownDown.png Binary files differnew file mode 100755 index 0000000..d330505 --- /dev/null +++ b/Resources/Images/editPitchDownDown.png diff --git a/Resources/Images/editPitchDownOver.png b/Resources/Images/editPitchDownOver.png Binary files differnew file mode 100755 index 0000000..8800f62 --- /dev/null +++ b/Resources/Images/editPitchDownOver.png diff --git a/Resources/Images/editPitchDownTop.png b/Resources/Images/editPitchDownTop.png Binary files differnew file mode 100755 index 0000000..0a8825c --- /dev/null +++ b/Resources/Images/editPitchDownTop.png diff --git a/Resources/Images/editPitchOverBot.png b/Resources/Images/editPitchOverBot.png Binary files differnew file mode 100755 index 0000000..7d9e602 --- /dev/null +++ b/Resources/Images/editPitchOverBot.png diff --git a/Resources/Images/editPitchOverTop.png b/Resources/Images/editPitchOverTop.png Binary files differnew file mode 100755 index 0000000..2f2aa34 --- /dev/null +++ b/Resources/Images/editPitchOverTop.png diff --git a/Resources/Images/editPitchTop.png b/Resources/Images/editPitchTop.png Binary files differnew file mode 100755 index 0000000..2084acd --- /dev/null +++ b/Resources/Images/editPitchTop.png diff --git a/Resources/Images/editPitchUp.png b/Resources/Images/editPitchUp.png Binary files differnew file mode 100755 index 0000000..6c49101 --- /dev/null +++ b/Resources/Images/editPitchUp.png diff --git a/Resources/Images/editPitchUpDown.png b/Resources/Images/editPitchUpDown.png Binary files differnew file mode 100755 index 0000000..29c99fb --- /dev/null +++ b/Resources/Images/editPitchUpDown.png diff --git a/Resources/Images/editPitchUpOver.png b/Resources/Images/editPitchUpOver.png Binary files differnew file mode 100755 index 0000000..cf9acaa --- /dev/null +++ b/Resources/Images/editPitchUpOver.png diff --git a/Resources/Images/editTam.png b/Resources/Images/editTam.png Binary files differnew file mode 100755 index 0000000..e4728e5 --- /dev/null +++ b/Resources/Images/editTam.png diff --git a/Resources/Images/genPage.png b/Resources/Images/genPage.png Binary files differnew file mode 100755 index 0000000..b48a691 --- /dev/null +++ b/Resources/Images/genPage.png diff --git a/Resources/Images/genPageDown.png b/Resources/Images/genPageDown.png Binary files differnew file mode 100755 index 0000000..6c336ee --- /dev/null +++ b/Resources/Images/genPageDown.png diff --git a/Resources/Images/genPageOver.png b/Resources/Images/genPageOver.png Binary files differnew file mode 100755 index 0000000..40e2cc7 --- /dev/null +++ b/Resources/Images/genPageOver.png diff --git a/Resources/Images/genTrack.png b/Resources/Images/genTrack.png Binary files differnew file mode 100755 index 0000000..04fa722 --- /dev/null +++ b/Resources/Images/genTrack.png diff --git a/Resources/Images/genTrackDown.png b/Resources/Images/genTrackDown.png Binary files differnew file mode 100755 index 0000000..a4e9a1d --- /dev/null +++ b/Resources/Images/genTrackDown.png diff --git a/Resources/Images/genTrackOver.png b/Resources/Images/genTrackOver.png Binary files differnew file mode 100755 index 0000000..fa11a9a --- /dev/null +++ b/Resources/Images/genTrackOver.png diff --git a/Resources/Images/miniTam.png b/Resources/Images/miniTam.png Binary files differnew file mode 100755 index 0000000..acccadb --- /dev/null +++ b/Resources/Images/miniTam.png diff --git a/Resources/Images/propNote.png b/Resources/Images/propNote.png Binary files differnew file mode 100755 index 0000000..ef79c88 --- /dev/null +++ b/Resources/Images/propNote.png diff --git a/Resources/Images/propNoteDown.png b/Resources/Images/propNoteDown.png Binary files differnew file mode 100755 index 0000000..7601a72 --- /dev/null +++ b/Resources/Images/propNoteDown.png diff --git a/Resources/Images/propNoteOver.png b/Resources/Images/propNoteOver.png Binary files differnew file mode 100755 index 0000000..7268a66 --- /dev/null +++ b/Resources/Images/propNoteOver.png diff --git a/Resources/Images/propPage.png b/Resources/Images/propPage.png Binary files differnew file mode 100755 index 0000000..549ff94 --- /dev/null +++ b/Resources/Images/propPage.png diff --git a/Resources/Images/propPageDown.png b/Resources/Images/propPageDown.png Binary files differnew file mode 100755 index 0000000..3b2372f --- /dev/null +++ b/Resources/Images/propPageDown.png diff --git a/Resources/Images/propPageOver.png b/Resources/Images/propPageOver.png Binary files differnew file mode 100755 index 0000000..0180a0a --- /dev/null +++ b/Resources/Images/propPageOver.png diff --git a/Resources/Images/propTrack.png b/Resources/Images/propTrack.png Binary files differnew file mode 100755 index 0000000..0cecb41 --- /dev/null +++ b/Resources/Images/propTrack.png diff --git a/Resources/Images/propTrackDown.png b/Resources/Images/propTrackDown.png Binary files differnew file mode 100755 index 0000000..91280f1 --- /dev/null +++ b/Resources/Images/propTrackDown.png diff --git a/Resources/Images/propTrackOver.png b/Resources/Images/propTrackOver.png Binary files differnew file mode 100755 index 0000000..130c094 --- /dev/null +++ b/Resources/Images/propTrackOver.png diff --git a/Resources/Images/scrollBar.png b/Resources/Images/scrollBar.png Binary files differnew file mode 100755 index 0000000..d95783e --- /dev/null +++ b/Resources/Images/scrollBar.png diff --git a/Resources/Images/synthTam.png b/Resources/Images/synthTam.png Binary files differnew file mode 100755 index 0000000..3e2f40a --- /dev/null +++ b/Resources/Images/synthTam.png diff --git a/Resources/Images/typeTam.png b/Resources/Images/typeTam.png Binary files differnew file mode 100755 index 0000000..4160d4d --- /dev/null +++ b/Resources/Images/typeTam.png diff --git a/SynthLab/SynthLabParametersWindow.py b/SynthLab/SynthLabParametersWindow.py index 499ffcb..45aff9f 100644 --- a/SynthLab/SynthLabParametersWindow.py +++ b/SynthLab/SynthLabParametersWindow.py @@ -129,7 +129,7 @@ class SynthLabParametersWindow( gtk.Window ): self.mainBox.pack_start(self.sliderBox) - closeButton = ImageButton(Config.TAM_TAM_ROOT + '/Resources/Images/close.png' ) + closeButton = ImageButton(Config.IMAGE_ROOT + 'close.png' ) closeButton.connect('clicked', self.destroy ) self.mainBox.pack_start(closeButton) diff --git a/SynthLab/SynthLabWindow.py b/SynthLab/SynthLabWindow.py index c1ddbe5..398e135 100644 --- a/SynthLab/SynthLabWindow.py +++ b/SynthLab/SynthLabWindow.py @@ -11,7 +11,7 @@ import os import Config from Util.ThemeWidgets import * -from Util.CSoundClient import CSoundClient +from Util.CSoundClient import new_csound_client from SynthLab.SynthLabParametersWindow import SynthLabParametersWindow from SynthLab.SynthObjectsParameters import SynthObjectsParameters from SynthLab.SynthLabConstants import SynthLabConstants @@ -20,13 +20,13 @@ from Util.Trackpad import Trackpad Tooltips = Config.Tooltips class SynthLabWindow( gtk.Window ): - def __init__( self, client, table, closeCallback ): + def __init__( self, table, closeCallback ): gtk.Window.__init__( self, gtk.WINDOW_TOPLEVEL ) 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.csnd = client + self.csnd = new_csound_client() self.trackpad = Trackpad( self, self.csnd ) self.table = table self.closeCallback = closeCallback @@ -149,11 +149,11 @@ class SynthLabWindow( gtk.Window ): self.sliderBox.pack_start(self.durationSlider, True, True, 5) self.sliderBox.pack_start(self.durLabel, False, padding=10) - saveButton = ImageButton(Config.TAM_TAM_ROOT + '/Resources/Images/save.png') + saveButton = ImageButton(Config.IMAGE_ROOT + 'save.png') saveButton.connect("clicked", self.handleSave, None) self.buttonBox.pack_start(saveButton, False, False, 2) - loadButton = ImageButton(Config.TAM_TAM_ROOT + '/Resources/Images/load.png') + loadButton = ImageButton(Config.IMAGE_ROOT + 'load.png') loadButton.connect("clicked", self.handleLoad, None) self.buttonBox.pack_start(loadButton, False, False, 2) @@ -161,11 +161,11 @@ class SynthLabWindow( gtk.Window ): self.recordButton.connect("clicked", self.recordSound) self.buttonBox.pack_start(self.recordButton, False, False, 2) - resetButton = ImageButton(Config.TAM_TAM_ROOT + '/Resources/Images/reset.png') + resetButton = ImageButton(Config.IMAGE_ROOT + 'reset.png') resetButton.connect("clicked", self.handleReset, None) self.buttonBox.pack_start(resetButton, False, False, 2) - closeButton = ImageButton(Config.TAM_TAM_ROOT + '/Resources/Images/close.png') + closeButton = ImageButton(Config.IMAGE_ROOT + 'close.png') closeButton.connect("clicked", self.handleClose, None) self.buttonBox.pack_start(closeButton, False, False, 2) @@ -6,25 +6,15 @@ import gtk import Config import Util.CSoundClient as CSoundClient from Util.Profiler import TP -from Player.StandalonePlayer import StandAlonePlayer +from miniTamTam.miniTamTamMain import miniTamTamMain from Edit.MainWindow import MainWindow -from Util.Clooper.SClient import * +from Util.Clooper.sclient import * try : from sugar.activity.Activity import Activity except ImportError: print "No Sugar for you" -def init_csound(): - #csnd = CSoundClient.CSoundClientSocket( Config.SERVER_ADDRESS, Config.SERVER_PORT, os.getpid() ) - #csnd = CSoundClient.CSoundClientPerf( '/usr/share/olpc-csound-server/univorc.csd' ) - #csnd = CSoundClient.CSoundClientPerf( Config.TAM_TAM_ROOT + '/Resources/univorc.csd' ) - csnd = CSoundClient.CSoundClientPlugin( Config.TAM_TAM_ROOT + '/Resources/univorc.csd' ) - csnd.connect(True) - csnd.setMasterVolume(100.0) - CSoundClient.CSoundClient = csnd #Dodgy move: TODO: remove this global variable. - return csnd - if not os.path.isdir(Config.PREF_DIR): os.mkdir(Config.PREF_DIR) os.system('chmod 0777 ' + Config.PREF_DIR + ' &') @@ -33,10 +23,8 @@ if not os.path.isdir(Config.PREF_DIR): os.system('chmod 0777 ' + Config.PREF_DIR + '/' + snd + ' &') if __name__ == "__main__": - csnd = init_csound() - def run_non_sugar_mode(): - tamtam = StandAlonePlayer(csnd) + tamtam = miniTamTamMain() mainwin = gtk.Window(gtk.WINDOW_TOPLEVEL) color = gtk.gdk.color_parse('#FFFFFF') mainwin.modify_bg(gtk.STATE_NORMAL, color) @@ -49,14 +37,15 @@ if __name__ == "__main__": mainwin.add(tamtam) tamtam.show() mainwin.show() - csnd.load_instruments() gtk.main() - + def run_edit_mode(): - tamtam = MainWindow(csnd) + tamtam = MainWindow() mainwin = gtk.Window(gtk.WINDOW_TOPLEVEL) mainwin.set_title('TamTam Player') - mainwin.set_geometry_hints( None, 1200, 900, 1200, 900, 1200, 900 ) + display = mainwin.get_display() + screen = gtk.gdk.Display.get_default_screen(display) + mainwin.set_geometry_hints( None, screen.get_width(), screen.get_height(), screen.get_width(), screen.get_height(), screen.get_width(), screen.get_height() ) #mainwin.fullscreen() # don't need to specify full screen, it seem to sit properly anyway mainwin.set_resizable(False) mainwin.connect('destroy' , tamtam.destroy ) @@ -67,7 +56,6 @@ if __name__ == "__main__": mainwin.add(tamtam) tamtam.show() mainwin.show() - csnd.load_instruments() gtk.main() if len(sys.argv) > 1 and sys.argv[1] == 'edit': @@ -81,8 +69,6 @@ if __name__ == "__main__": else: run_non_sugar_mode() - csnd.connect(False) - csnd.destroy() sys.exit(0) class TamTam(Activity): @@ -92,30 +78,29 @@ class TamTam(Activity): color = gtk.gdk.color_parse('#FFFFFF') self.modify_bg(gtk.STATE_NORMAL, color) - self.csnd = init_csound() - self.tamtam = StandAlonePlayer(self.csnd) + self.tamtam = miniTamTamMain() self.connect('focus_in_event',self.handleFocusIn) self.connect('focus_out_event',self.handleFocusOut) self.connect('destroy', self.do_quit) self.add(self.tamtam) self.tamtam.show() - self.csnd.load_instruments() self.set_title('TamTam') self.set_resizable(False) self.connect( "key-press-event", self.tamtam.keyboardStandAlone.onKeyPress ) self.connect( "key-release-event", self.tamtam.keyboardStandAlone.onKeyRelease ) def handleFocusIn(self, event, data=None): - self.csnd.connect(True) - self.csnd.load_instruments() + csnd = new_csound_client() + csnd.connect(True) + csnd.load_instruments() def handleFocusOut(self, event, data=None): if self.tamtam.synthLabWindowOpen(): return - self.csnd.connect(False) + csnd = new_csound_client() + csnd.connect(False) def do_quit(self, arg2): os.system('rm ' + Config.PREF_DIR + '/synthTemp*') - self.csnd.destroy() del self.tamtam diff --git a/Util/CSoundClient.py b/Util/CSoundClient.py index 5b3802c..4d3bfef 100644 --- a/Util/CSoundClient.py +++ b/Util/CSoundClient.py @@ -5,167 +5,26 @@ import select import sys import threading import time +import array import Config -#---------------------------------------------------------------------- -# A CSound client used to send messages to the CSound server -# CSoundClient is a singleton -#---------------------------------------------------------------------- -CSoundClient = None -class CSoundClientBase: - def setMasterVolume(self, volume): - self.sendText("csound.SetChannel('masterVolume', %f)\n" % volume) - - def micRecording( self, table ): - mess = Config.MIC_RECORDING_COMMAND % table - self.sendText( mess ) - - def load_mic_instrument( self, inst ): - fileName = Config.PREF_DIR + '/' + inst - instrumentId = Config.INSTRUMENT_TABLE_OFFSET + int(fileName[-1]) + 6 - mess = Config.LOAD_INSTRUMENT_COMMAND % ( instrumentId, fileName ) - self.sendText( mess ) - - def load_instruments( self ): - for instrumentSoundFile in Config.INSTRUMENTS.keys(): - if instrumentSoundFile[0:3] == 'mic' or instrumentSoundFile[0:3] == 'lab': - fileName = Config.PREF_DIR + '/' + instrumentSoundFile - else: - fileName = Config.SOUNDS_DIR + "/" + instrumentSoundFile - instrumentId = Config.INSTRUMENT_TABLE_OFFSET + Config.INSTRUMENTS[ instrumentSoundFile ].instrumentId - mess = Config.LOAD_INSTRUMENT_COMMAND % ( instrumentId, fileName ) - self.sendText( mess ) - - def startTime(self): - raise 'dont do this anymore' - self.sendText("perf.InputMessage('i 5999 0.0 60000000')") - # if any other message arrives to csound at the same time as this one, - # then the global variables will not be set up right in the orcestra - # - # NB: match this to the constant in the instrument 5777 of the csound orcestra - time.sleep(0.1) - - def sendText(self, txt): - raise 'noImpl' - - def connect(self, flag): - raise 'noImpl' +from Generation.GenerationConstants import GenerationConstants +from Util.Clooper.sclient import * +from Util import NoteDB - def destroy(self): - pass - - - -class CSoundClientSocket( CSoundClientBase ): - def __init__( self, serverAddress, serverPort, clientId ): - self.clientId = clientId - self.serverInfo = ( serverAddress, serverPort ) - self.connected = False - - def sendText( self, text ): - #print "Sending to CSound server: %s" % text - try: - self.socket.send( text ) - except socket.error: - if Config.SERVER_REQUIRED : - print 'ERROR: no CSound server. Ignoring message: %s' % text - - def connect( self, init = True ): - if init : - n = Config.INIT_ATTEMPTS - self.socket = socket.socket() - self.connected = False - while n > 0 and not self.connected: - try: - self.socket.connect( self.serverInfo ) - self.connected = True - self.load_instruments() - except socket.error: - if Config.SERVER_REQUIRED : - print 'ERROR: no CSound server. Ignoring connection request.' - time.sleep(Config.INIT_DELAY) - n = n - 1 - else : #un-init - self.sendText( Config.UNLOAD_TABLES_COMMAND ) - del self.socket - -class CSoundClientPerf( CSoundClientBase ): +class _CSoundClientPlugin: def __init__(self, orc): - self.orc = orc + sc_initialize(orc) self.on = False - self.csound = csnd.Csound() - def connect( self, init = True ): - if init: - if self.on : return - self.on = True - self.perf = csnd.CsoundPerformanceThread(self.csound) - self.csound.Compile( self.orc ) - self.perf.Play() - self.load_instruments() - print 'CSoundClient = True' - else: - if not self.on : return - self.on = False - #self.csound.SetChannel('udprecv.0.on', 0) - #print Config.UNLOAD_TABLES_COMMAND - self.sendText( Config.UNLOAD_TABLES_COMMAND ) - #print 'PERF STOP' - self.perf.Stop() - #print 'SLEEP' - #time.sleep(1) - #print 'JOIN' - #time.sleep(1) - rval = self.perf.Join() - #print 'Join returned ', rval - #del self.perf - #time.sleep(1) - #print 'STOP' - #self.csound.Stop() - #print 'RESET' - self.csound.Reset() - print 'CSoundClient = False' - #careful how much cleaning up we do... don't cause a segault! - # better to leave a segfault for the automatic cleanning at the end of the prog - - #self.csound.Cleanup() - #print 'STOPPED' - #time.sleep(1) - #del self.csound - #print 'DELETED' - #time.sleep(1) - def setMasterVolume(self, volume): - self.csound.SetChannel('masterVolume',volume ) + self.masterVolume = 80.0 - def sendText(self, txt): - #print txt - perf = self.perf - csound = self.csound - if 'csound' in txt: - print txt - import sys - sys.exit(0) - exec txt - -class CSoundClientPipe( CSoundClientBase ): - def __init__(self, orc): - self.orc = orc - def connect( self, init = True ): - if init: - (self.child_out, self.child_in) = os.popen2('csound ' + self.orc) - else: - self.child_in.close() - self.child_out.close() + def __del__(self): + self.connect(False) + sc_destroy() - def sendText(self, txt): - str = txt[19:-3] - if len(str) == 0: return - #print 'tosend:[%s]' % (str,) - self.child_out.write(str) -from Util.Clooper.SClient import * -class CSoundClientPlugin( CSoundClientBase ): def setMasterVolume(self, volume): self.masterVolume = volume if self.on: @@ -187,11 +46,6 @@ class CSoundClientPlugin( CSoundClientBase ): instrumentId = Config.INSTRUMENT_TABLE_OFFSET + int(fileName[-1]) + 6 sc_inputMessage(Config.CSOUND_LOAD_INSTRUMENT % (instrumentId, fileName)) - def __init__(self, orc): - sc_initialize(orc) - self.on = False - self.masterVolume = 80.0 - def load_instruments( self ): for instrumentSoundFile in Config.INSTRUMENTS.keys(): if instrumentSoundFile[0:3] == 'mic' or instrumentSoundFile[0:3] == 'lab': @@ -246,16 +100,12 @@ class CSoundClientPlugin( CSoundClientBase ): for (o,n) in onset_note: n.playLoop() # a special non-documented CSoundNote function! - def loopAdd(self, notelist ): - for n in notelist: - n.playLoop() # a special non-documented CSoundNote function! - def loopClear(self): sc_loop_clear() - def loopDel( self, notelist ): - print 'ERROR: CSoundClient::loopDel() note removing is not implemented, clearing instead' - sc_loop_clear() - + def loopDelete(self, dbnote): + sc_loop_delScoreEvent( (dbnote.page << 16) + dbnote.id) + def loopDelete1(self, page, id): + sc_loop_delScoreEvent( (page << 16) + id) def loopStart(self): sc_loop_playing(1) def loopStop(self): @@ -272,3 +122,150 @@ class CSoundClientPlugin( CSoundClientBase ): print 'INFO: loop tempo: %f -> %f' % (t, 60.0 / (Config.TICKS_PER_BEAT * t)) sc_loop_setTickDuration( 60.0 / (Config.TICKS_PER_BEAT * t)) + def loopUpdate(self, note, parameter, value): + page = note.page + id = note.id + if (parameter == NoteDB.PARAMETER.ONSET): + print 'INFO: updating onset', (page<<16)+id, value + sc_loop_updateEvent( (page<<16)+id, 1, value) + elif (parameter == NoteDB.PARAMETER.PITCH): + print 'INFO: updating pitch', (page<<16)+id, value + pitch = value + instr = note.cs.instrumentFlag + if instr[0:4] == 'drum': + if pitch in GenerationConstants.DRUMPITCH: + key = GenerationConstants.DRUMPITCH[ pitch ] + else: + key = pitch + + if instr == 'drum1kit': + instr = Config.DRUM1INSTRUMENTS[ key ] + if instr == 'drum2kit': + instr = Config.DRUM2INSTRUMENTS[ key ] + if instr == 'drum3kit': + instr = Config.DRUM3INSTRUMENTS[ key ] + pitch = 1 + else: + pitch = GenerationConstants.TRANSPOSE[ pitch - 24 ] + sc_loop_updateEvent( (page<<16)+id, 3, pitch) + elif (parameter == NoteDB.PARAMETER.AMPLITUDE): + print 'INFO: updating amp', (page<<16)+id, value + sc_loop_updateEvent( (page<<16)+id, 5, value) + elif (parameter == NoteDB.PARAMETER.DURATION): + print 'INFO: updating duration', (page<<16)+id, value + sc_loop_updateEvent( (page<<16)+id, 2, value) + else: + print 'ERROR: loopUpdate(): unsupported parameter change' + def loopPlay(self, dbnote): + qid = (dbnote.page << 16) + dbnote.id + sc_loop_addScoreEvent( qid, 1, 'i', self.csnote_to_array(dbnote.cs)) + def play(self, csnote, secs_per_tick): + a = self.csnote_to_array(csnote) + a[self.DURATION] = a[self.DURATION] * secs_per_tick + a[self.ATTACK] = max(a[self.ATTACK]*a[self.DURATION], 0.002) + a[self.DECAY] = max(a[self.DECAY]*a[self.DURATION], 0.002) + sc_scoreEvent( 'i', a) + + def csnote_to_array(self, csnote): + return self.csnote_to_array1( + csnote.onset, + csnote.pitch, + csnote.amplitude, + csnote.pan, + csnote.duration, + csnote.trackId, + csnote.fullDuration, + csnote.attack, + csnote.decay, + csnote.reverbSend, + csnote.filterType, + csnote.filterCutoff, + csnote.tied, + csnote.overlap, + csnote.instrumentFlag) + + INSTR_TRACK=0 + ONSET=1 + DURATION=2 + PITCH=3 + AMPLITUDE=5 + ATTACK=8 + DECAY=9 + def csnote_to_array1( self, onset, + pitch, + amplitude, + pan, + duration, + trackId, + fullDuration = False, + attack = 0.002, + decay = 0.098, + reverbSend = 0.1, + filterType = 0, + filterCutoff = 1000, + tied = False, + overlap = False, + instr = Config.FLUTE ): + + if instr[0:4] == 'drum': + if pitch in GenerationConstants.DRUMPITCH: + key = GenerationConstants.DRUMPITCH[ pitch ] + else: + key = pitch + + if instr == 'drum1kit': + instr = Config.DRUM1INSTRUMENTS[ key ] + if instr == 'drum2kit': + instr = Config.DRUM2INSTRUMENTS[ key ] + if instr == 'drum3kit': + instr = Config.DRUM3INSTRUMENTS[ key ] + pitch = 1 + time_in_ticks = 0 + else: + pitch = GenerationConstants.TRANSPOSE[ pitch - 24 ] + + # condition for tied notes + if Config.INSTRUMENTS[ instr ].csoundInstrumentId == 101 and tied and fullDuration: + duration= -1.0 + # condition for overlaped notes + if Config.INSTRUMENTS[ instr ].csoundInstrumentId == 102 and overlap: + duration += 1.0 + time_in_ticks = 1 + + # condition for tied notes + if Config.INSTRUMENTS[ instr].csoundInstrumentId == Config.INST_TIED and tied and fullDuration: + duration = -1 + # condition for overlaped notes + if Config.INSTRUMENTS[ instr ].csoundInstrumentId == Config.INST_PERC and overlap: + duration = duration + 1.0 + + a = array.array('f') + a.extend( [ + Config.INSTRUMENTS[ instr ].csoundInstrumentId + trackId * 0.01, + onset, + duration, + pitch, + reverbSend, + amplitude, + pan, + Config.INSTRUMENT_TABLE_OFFSET + Config.INSTRUMENTS[instr].instrumentId, + attack, + decay, + filterType, + filterCutoff, + Config.INSTRUMENTS[ instr ].loopStart, + Config.INSTRUMENTS[ instr ].loopEnd, + Config.INSTRUMENTS[ instr ].crossDur ]) + return a + + +_Client = None + +def new_csound_client(): + global _Client + if _Client == None: + _Client = _CSoundClientPlugin( Config.TAM_TAM_ROOT + '/Resources/univorc.csd' ) + _Client.connect(True) + _Client.setMasterVolume(100.0) + _Client.load_instruments() + return _Client diff --git a/Util/CSoundNote.py b/Util/CSoundNote.py index 6e3424d..8cc1257 100644 --- a/Util/CSoundNote.py +++ b/Util/CSoundNote.py @@ -1,103 +1,6 @@ import Config -from Util.CSoundClient import CSoundClient from Generation.GenerationConstants import GenerationConstants -from Util.Clooper.SClient import * - -def CSound_loadInstruments( ): - for instrumentSoundFile in Config.INSTRUMENTS.keys(): - if instrumentSoundFile[0:3] == 'mic' or instrumentSoundFile[0:3] == 'lab': - fileName = Config.PREF_DIR + '/' + instrumentSoundFile - else: - fileName = Config.SOUNDS_DIR + "/" + instrumentSoundFile - instrumentId = Config.INSTRUMENT_TABLE_OFFSET + Config.INSTRUMENTS[ instrumentSoundFile ].instrumentId - sc_instrumentLoad(instrumentId, fileName) - -def CSound_playNote( loopMode, secs_per_tick, - onset, - pitch, - amplitude, - pan, - duration, - trackId, - fullDuration = False, - attack = 0.002, - decay = 0.098, - reverbSend = 0.1, - filterType = 0, - filterCutoff = 1000, - tied = False, - overlap = False, - instr = Config.FLUTE ): - - if not loopMode: duration = secs_per_tick * duration - - if instr[0:4] == 'drum': - if pitch in GenerationConstants.DRUMPITCH: - key = GenerationConstants.DRUMPITCH[ pitch ] - else: - key = pitch - - if instr == 'drum1kit': - instr = Config.DRUM1INSTRUMENTS[ key ] - if instr == 'drum2kit': - instr = Config.DRUM2INSTRUMENTS[ key ] - if instr == 'drum3kit': - instr = Config.DRUM3INSTRUMENTS[ key ] - pitch = 1 - time_in_ticks = 0 - else: - pitch = GenerationConstants.TRANSPOSE[ pitch - 24 ] - - # condition for tied notes - if Config.INSTRUMENTS[ instr ].csoundInstrumentId == 101 and tied and fullDuration: - duration= -1.0 - # condition for overlaped notes - if Config.INSTRUMENTS[ instr ].csoundInstrumentId == 102 and overlap: - duration += 1.0 - time_in_ticks = 1 - - # condition for tied notes - if Config.INSTRUMENTS[ instr].csoundInstrumentId == Config.INST_TIED and tied and fullDuration: - duration = -1 - # condition for overlaped notes - if Config.INSTRUMENTS[ instr ].csoundInstrumentId == Config.INST_PERC and overlap: - duration = duration + 1.0 - if loopMode : - sc_loop_addScoreEvent15( time_in_ticks, 'i', - Config.INSTRUMENTS[ instr ].csoundInstrumentId + trackId * 0.01, - onset, - duration, - pitch, - reverbSend, - amplitude, - pan, - Config.INSTRUMENT_TABLE_OFFSET + Config.INSTRUMENTS[instr].instrumentId, - attack, - decay, - filterType, - filterCutoff, - Config.INSTRUMENTS[ instr ].loopStart, - Config.INSTRUMENTS[ instr ].loopEnd, - Config.INSTRUMENTS[ instr ].crossDur ) - else: - sc_scoreEvent15( 'i', - Config.INSTRUMENTS[ instr ].csoundInstrumentId + trackId * 0.01, - onset * secs_per_tick, - duration, - pitch, - reverbSend, - amplitude, - pan, - Config.INSTRUMENT_TABLE_OFFSET + Config.INSTRUMENTS[instr].instrumentId, - max(attack*duration, 0.002), - max(decay *duration, 0.002), - filterType, - filterCutoff, - Config.INSTRUMENTS[ instr ].loopStart, - Config.INSTRUMENTS[ instr ].loopEnd, - Config.INSTRUMENTS[ instr ].crossDur ) - class CSoundNote : NOTE_ID_COUNTER = 0 #----------------------------------- @@ -236,38 +139,3 @@ class CSoundNote : Config.INSTRUMENTS[ self.instrumentFlag ].loopEnd, Config.INSTRUMENTS[ self.instrumentFlag ].crossDur ) - def playNow(self, secs_per_tick): - CSound_playNote( False, secs_per_tick, - self.onset, - self.pitch, - self.amplitude, - self.pan, - self.duration, - self.trackId, - self.fullDuration, - self.attack, - self.decay, - self.reverbSend, - self.filterType, - self.filterCutoff, - self.tied, - self.overlap, - self.instrumentFlag) - def playLoop(self): - CSound_playNote( True, 1.0, - self.onset, - self.pitch, - self.amplitude, - self.pan, - self.duration, - self.trackId, - self.fullDuration, - self.attack, - self.decay, - self.reverbSend, - self.filterType, - self.filterCutoff, - self.tied, - self.overlap, - self.instrumentFlag) - diff --git a/Util/Clooper/Makefile b/Util/Clooper/Makefile index 87caf59..c2a246d 100644 --- a/Util/Clooper/Makefile +++ b/Util/Clooper/Makefile @@ -4,39 +4,11 @@ CFLAGS+=-g -Wall -Werror -fPIC -O3 -finline PYTHON=/usr/include/python2.4 -all : _SClient.so cmd_csound +all : sclient.so -%.o: %.c %.h - $(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@ - -%.o: %.c - $(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@ - -%.o: %.cpp %.h - $(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@ - -clean : - rm -f *.o _ttest.so _SClient.so - -cmd_csound: cmd_csound.cpp SoundClient.o - g++ -o $@ $^ -lcsound - -SoundClient_wrap.c: SoundClient.i SoundClient.h - swig -python $< - -SoundClient_wrap.o: SoundClient_wrap.c - gcc -fPIC -I$(PYTHON) -o $@ -c $< - -_SClient.so : SoundClient_wrap.o SoundClient.o - g++ -shared -o $@ $^ -lcsound - -ttest_wrap.c: ttest.i - swig -python ttest.i - -ttest_wrap.o: ttest_wrap.c - gcc -fPIC -I$(PYTHON) -o $@ -c $< - -_ttest.so : ttest_wrap.o ttest.o - gcc -shared -o $@ $^ +sclient.so : SoundClient.cpp + g++ $(CFLAGS) -shared -o $@ $< -lpython2.4 -lcsound +clean : + rm sclient.so diff --git a/Util/Clooper/SClient.py b/Util/Clooper/SClient.py deleted file mode 100644 index d27472b..0000000 --- a/Util/Clooper/SClient.py +++ /dev/null @@ -1,69 +0,0 @@ -# This file was automatically generated by SWIG (http://www.swig.org). -# Version 1.3.31 -# -# Don't modify this file, modify the SWIG interface instead. -# This file is compatible with both classic and new-style classes. - -import _SClient -import new -new_instancemethod = new.instancemethod -try: - _swig_property = property -except NameError: - pass # Python < 2.2 doesn't have 'property'. -def _swig_setattr_nondynamic(self,class_type,name,value,static=1): - if (name == "thisown"): return self.this.own(value) - if (name == "this"): - if type(value).__name__ == 'PySwigObject': - self.__dict__[name] = value - return - method = class_type.__swig_setmethods__.get(name,None) - if method: return method(self,value) - if (not static) or hasattr(self,name): - self.__dict__[name] = value - else: - raise AttributeError("You cannot add attributes to %s" % self) - -def _swig_setattr(self,class_type,name,value): - return _swig_setattr_nondynamic(self,class_type,name,value,0) - -def _swig_getattr(self,class_type,name): - if (name == "thisown"): return self.this.own() - method = class_type.__swig_getmethods__.get(name,None) - if method: return method(self) - raise AttributeError,name - -def _swig_repr(self): - try: strthis = "proxy of " + self.this.__repr__() - except: strthis = "" - return "<%s.%s; %s >" % (self.__class__.__module__, self.__class__.__name__, strthis,) - -import types -try: - _object = types.ObjectType - _newclass = 1 -except AttributeError: - class _object : pass - _newclass = 0 -del types - - -sc_destroy = _SClient.sc_destroy -sc_initialize = _SClient.sc_initialize -sc_start = _SClient.sc_start -sc_stop = _SClient.sc_stop -sc_setMasterVolume = _SClient.sc_setMasterVolume -sc_setTrackpadX = _SClient.sc_setTrackpadX -sc_setTrackpadY = _SClient.sc_setTrackpadY -sc_inputMessage = _SClient.sc_inputMessage -sc_scoreEvent4 = _SClient.sc_scoreEvent4 -sc_scoreEvent15 = _SClient.sc_scoreEvent15 -sc_loop_addScoreEvent15 = _SClient.sc_loop_addScoreEvent15 -sc_loop_clear = _SClient.sc_loop_clear -sc_loop_getTick = _SClient.sc_loop_getTick -sc_loop_playing = _SClient.sc_loop_playing -sc_loop_setNumTicks = _SClient.sc_loop_setNumTicks -sc_loop_setTick = _SClient.sc_loop_setTick -sc_loop_setTickDuration = _SClient.sc_loop_setTickDuration - - diff --git a/Util/Clooper/SoundClient.cpp b/Util/Clooper/SoundClient.cpp index 6bc92eb..a1bedd1 100644 --- a/Util/Clooper/SoundClient.cpp +++ b/Util/Clooper/SoundClient.cpp @@ -1,3 +1,5 @@ +#include <python2.4/Python.h> + #include <pthread.h> #include <stdio.h> #include <time.h> @@ -5,13 +7,18 @@ #include <sys/time.h> #include <csound/csound.hpp> -#include "SoundClient.h" +//#include "SoundClient.h" #include <vector> #include <map> #include <cmath> using namespace std; +static double pytime(const struct timeval * tv) +{ + return (double) tv->tv_sec + (double) tv->tv_usec / 1000000.0; +} + struct ev_t { char type; @@ -21,30 +28,18 @@ struct ev_t MYFLT duration, attack, decay; std::vector<MYFLT> param; - ev_t(char type, bool in_ticks, MYFLT p1, MYFLT p2, MYFLT p3, MYFLT p4, MYFLT p5, MYFLT p6, MYFLT p7, MYFLT p8, MYFLT p9, MYFLT p10, MYFLT p11, MYFLT p12, MYFLT p13, MYFLT p14, MYFLT p15) - : type(type), onset(0), time_in_ticks(in_ticks), param(15) + ev_t(char type, MYFLT * p, int np, bool in_ticks) + : type(type), onset(0), time_in_ticks(in_ticks), param(np) { - onset = (int) p2; - duration = p3; - attack = p9; - decay = p10; + assert(np >= 4); + onset = (int) p[1]; + duration = p[2]; + attack = np > 8 ? p[8]: 0.0; //attack + decay = np > 9 ? p[9]: 0.0; //decay prev_secs_per_tick = -1.0; + for (int i = 0; i < np; ++i) param[i] = p[i]; - param[0] = p1; param[1] = 0.0; //onset - param[2] = p3; //duration - param[3] = p4; //pitch - param[4] = p5; //reverbSend - param[5] = p6; //amplitude - param[6] = p7; //pan - param[7] = p8; //table - param[8] = p9; //attack - param[9] = p10; //decay - param[10] = p11;//filterType - param[11] = p12;//filterCutoff - param[12] = p13;//loopStart - param[13] = p14;//loopEnd - param[14] = p15;//crossDur } bool operator<(const ev_t &e) const { @@ -56,6 +51,30 @@ struct ev_t for (size_t i = 0; i < param.size(); ++i) fprintf(f, "%lf ", param[i]); fprintf(f, "\n"); } + void update(int idx, MYFLT val) + { + if ( (unsigned)idx >= param.size()) + { + fprintf(stderr, "ERROR: updateEvent request for too-high parameter %i\n", idx); + return; + } + if (time_in_ticks) + { + switch(idx) + { + case 1: onset = (int) val; break; + case 2: duration = val; break; + case 8: attack = val; break; + case 9: decay = val; break; + default: param[idx] = val; break; + } + prev_secs_per_tick = -1.0; //force recalculation + } + else + { + param[idx] = val; + } + } void event(CSOUND * csound, MYFLT secs_per_tick) { @@ -72,6 +91,8 @@ struct ev_t }; struct EvLoop { + FILE * _debug; + int tick_prev; int tickMax; MYFLT rtick; @@ -79,12 +100,15 @@ struct EvLoop MYFLT ticks_per_ksmp; typedef std::pair<int, ev_t *> pair_t; typedef std::multimap<int, ev_t *>::iterator iter_t; + typedef std::map<int, iter_t>::iterator idmap_t; + std::multimap<int, ev_t *> ev; std::multimap<int, ev_t *>::iterator ev_pos; + std::map<int, iter_t> idmap; CSOUND * csound; void * mutex; - EvLoop(CSOUND * cs) : tick_prev(0), tickMax(1), rtick(0.0), ev(), ev_pos(ev.end()), csound(cs), mutex(NULL) + EvLoop(CSOUND * cs) : _debug(stderr), tick_prev(0), tickMax(1), rtick(0.0), ev(), ev_pos(ev.end()), csound(cs), mutex(NULL) { setTickDuration(0.05); mutex = csoundCreateMutex(0); @@ -108,6 +132,7 @@ struct EvLoop } ev.erase(ev.begin(), ev.end()); ev_pos = ev.end(); + idmap.erase(idmap.begin(), idmap.end()); csoundUnlockMutex(mutex); } int getTick() @@ -180,11 +205,74 @@ struct EvLoop tick_prev = tick; if (logf && (events >= eventMax)) fprintf(logf, "WARNING: %i/%i events at once (%i, %i)\n", events,ev.size(),loop0,loop1); } - void addEvent(ev_t *e) + void addEvent(int id, char type, MYFLT * p, int np, bool in_ticks) + { + ev_t * e = new ev_t(type, p, np, in_ticks); + + idmap_t id_iter = idmap.find(id); + if (id_iter == idmap.end()) + { + //this is a new id + csoundLockMutex(mutex); + + iter_t e_iter = ev.insert(pair_t(e->onset, e)); + + //TODO: optimize by thinking about whether to do ev_pos = e_iter + ev_pos = ev.upper_bound( tick_prev ); + idmap[id] = e_iter; + + csoundUnlockMutex(mutex); + } + else + { + if (_debug) fprintf(_debug, "ERROR: skipping request to add duplicate note %i\n", id); + } + } + void delEvent(int id) + { + idmap_t id_iter = idmap.find(id); + if (id_iter == idmap.end()) + { + if (_debug) fprintf(_debug, "ERROR: delEvent request for unknown note %i\n", id); + } + else + { + csoundLockMutex(mutex); + iter_t e_iter = id_iter->second;//idmap[id]; + if (e_iter == ev_pos) ++ev_pos; + + delete e_iter->second; + ev.erase(e_iter); + idmap.erase(id_iter); + + csoundUnlockMutex(mutex); + } + } + void updateEvent(int id, int idx, float val) { + idmap_t id_iter = idmap.find(id); + if (id_iter == idmap.end()) + { + if (_debug) fprintf(_debug, "ERROR: updateEvent request for unknown note %i\n", id); + return; + } + + //this is a new id csoundLockMutex(mutex); - ev.insert(pair_t(e->onset, e)); - ev_pos = ev.upper_bound( tick_prev ); + iter_t e_iter = id_iter->second; + ev_t * e = e_iter->second; + int onset = e->onset; + e->update(idx, val); + if (onset != e->onset) + { + ev.erase(e_iter); + + e_iter = ev.insert(pair_t(e->onset, e)); + + //TODO: optimize by thinking about whether to do ev_pos = e_iter + ev_pos = ev.upper_bound( tick_prev ); + idmap[id] = e_iter; + } csoundUnlockMutex(mutex); } }; @@ -201,7 +289,7 @@ struct TamTamSound EvLoop * loop; TamTamSound(char * orc) - : ThreadID(NULL), csound(NULL), PERF_STATUS(STOP), verbosity(3), _debug(NULL), thread_playloop(0), thread_measurelag(0), loop(NULL) + : ThreadID(NULL), csound(NULL), PERF_STATUS(STOP), verbosity(3), _debug(stderr), thread_playloop(0), thread_measurelag(0), loop(NULL) { if (1) { @@ -226,10 +314,6 @@ struct TamTamSound free(csound_orc); if (_debug) fclose(_debug); } - static double pytime(const struct timeval * tv) - { - return (double) tv->tv_sec + (double) tv->tv_usec / 1000000.0; - } uintptr_t thread_fn() { struct timeval tv; @@ -396,109 +480,283 @@ struct TamTamSound TamTamSound * sc_tt = NULL; -//call once at startup, should return 0 -int sc_initialize(char * csd) +static void cleanup(void) { - sc_tt = new TamTamSound(csd); - atexit(&sc_destroy); - if (sc_tt->good()) return 0; - else return -1; + if (sc_tt) + { + delete sc_tt; + sc_tt = NULL; + } } + +#define DECL(s) static PyObject * s(PyObject * self, PyObject *args) +#define RetNone Py_INCREF(Py_None); return Py_None; + //call once at end -void sc_destroy() +DECL(sc_destroy) { + if (!PyArg_ParseTuple(args, "")) + { + return NULL; + } if (sc_tt) { delete sc_tt; sc_tt = NULL; } + RetNone; +} +//call once at startup, should return 0 +DECL(sc_initialize) //(char * csd) +{ + char * str; + if (!PyArg_ParseTuple(args, "s", &str )) + { + return NULL; + } + sc_tt = new TamTamSound(str); + atexit(&cleanup); + if (sc_tt->good()) + return Py_BuildValue("i", 0); + else + return Py_BuildValue("i", -1); } //compile the score, connect to device, start a sound rendering thread -int sc_start() +DECL(sc_start) { - return sc_tt->start(); + if (!PyArg_ParseTuple(args, "" )) + { + return NULL; + } + return Py_BuildValue("i", sc_tt->start()); } //stop csound rendering thread, disconnect from sound device, clear tables. -int sc_stop() +DECL(sc_stop) { - return sc_tt->stop(); + if (!PyArg_ParseTuple(args, "" )) + { + return NULL; + } + return Py_BuildValue("i", sc_tt->stop()); } -//set the output volume to given level. max volume is 100.0 -void sc_setMasterVolume(MYFLT v) +DECL(sc_scoreEvent) //(char type, farray param) { + char ev_type; + PyObject *o; + if (!PyArg_ParseTuple(args, "cO", &ev_type, &o )) + { + return NULL; + } + if (o->ob_type + && o->ob_type->tp_as_buffer + && (1 == o->ob_type->tp_as_buffer->bf_getsegcount(o, NULL))) + { + if (o->ob_type->tp_as_buffer->bf_getreadbuffer) + { + void * ptr; + size_t len; + len = o->ob_type->tp_as_buffer->bf_getreadbuffer(o, 0, &ptr); + fprintf(stderr, "writeable buffer of length %zu at %p\n", len, ptr); + float * fptr = (float*)ptr; + size_t flen = len / sizeof(float); + sc_tt->scoreEvent(ev_type, fptr, flen); + + Py_INCREF(Py_None); + return Py_None; + } + else + { + assert(!"asdf"); + } + } + assert(!"not reached"); + return NULL; +} +DECL(sc_setMasterVolume) //(float v) +{ + float v; + if (!PyArg_ParseTuple(args, "f", &v)) + { + return NULL; + } sc_tt->setMasterVolume(v); + Py_INCREF(Py_None); + return Py_None; } - -void sc_setTrackpadX(MYFLT v) +DECL(sc_setTrackpadX) //(float v) { + float v; + if (!PyArg_ParseTuple(args, "f", &v)) + { + return NULL; + } sc_tt->setTrackpadX(v); + Py_INCREF(Py_None); + return Py_None; } - -void sc_setTrackpadY(MYFLT v) +DECL(sc_setTrackpadY) //(float v) { + float v; + if (!PyArg_ParseTuple(args, "f", &v)) + { + return NULL; + } sc_tt->setTrackpadY(v); + Py_INCREF(Py_None); + return Py_None; } - -void sc_inputMessage(const char *msg) +DECL(sc_loop_getTick) // -> int { - sc_tt->inputMessage(msg); + if (!PyArg_ParseTuple(args, "" )) + { + return NULL; + } + return Py_BuildValue("i", sc_tt->loop->getTick()); } -void sc_scoreEvent4(char type, MYFLT p0, MYFLT p1, MYFLT p2, MYFLT p3) +DECL(sc_loop_setNumTicks) //(int nticks) { - MYFLT p[4]; - p[0] = p0; - p[1] = p1; - p[2] = p2; - p[3] = p3; - sc_tt->scoreEvent(type, p, 4); + int nticks; + if (!PyArg_ParseTuple(args, "i", &nticks )) + { + return NULL; + } + sc_tt->loop->setNumTicks(nticks); + RetNone; } -void sc_scoreEvent15(char type, MYFLT p1, MYFLT p2, MYFLT p3, MYFLT p4, MYFLT p5, MYFLT p6, MYFLT p7, MYFLT p8, MYFLT p9, MYFLT p10, MYFLT p11, MYFLT p12, MYFLT p13, MYFLT p14, MYFLT p15) +DECL(sc_loop_setTick) // (int ctick) { - MYFLT p[15]; - p[0] = p1; - p[1] = p2; - p[2] = p3; - p[3] = p4; - p[4] = p5; - p[5] = p6; - p[6] = p7; - p[7] = p8; - p[8] = p9; - p[9] = p10; - p[10] = p11; - p[11] = p12; - p[12] = p13; - p[13] = p14; - p[14] = p15; - sc_tt->scoreEvent(type, p, 15); + int ctick; + if (!PyArg_ParseTuple(args, "i", &ctick )) + { + return NULL; + } + sc_tt->loop->setTick(ctick); + RetNone; } - -int sc_loop_getTick() +DECL(sc_loop_setTickDuration) // (MYFLT secs_per_tick) { - return sc_tt->loop->getTick(); + float spt; + if (!PyArg_ParseTuple(args, "f", &spt )) + { + return NULL; + } + sc_tt->loop->setTickDuration(spt); + RetNone; } -void sc_loop_setNumTicks(int nticks) +DECL(sc_loop_addScoreEvent) // (int id, int duration_in_ticks, char type, farray param) { - sc_tt->loop->setNumTicks(nticks); + int qid; + int inticks; + char ev_type; + PyObject *o; + if (!PyArg_ParseTuple(args, "iicO", &qid, &inticks, &ev_type, &o )) + { + return NULL; + } + if (o->ob_type + && o->ob_type->tp_as_buffer + && (1 == o->ob_type->tp_as_buffer->bf_getsegcount(o, NULL))) + { + if (o->ob_type->tp_as_buffer->bf_getreadbuffer) + { + void * ptr; + size_t len; + len = o->ob_type->tp_as_buffer->bf_getreadbuffer(o, 0, &ptr); + fprintf(stderr, "writeable buffer of length %zu at %p\n", len, ptr); + float * fptr = (float*)ptr; + size_t flen = len / sizeof(float); + sc_tt->loop->addEvent(qid, ev_type, fptr, flen, inticks); + + Py_INCREF(Py_None); + return Py_None; + } + else + { + assert(!"asdf"); + } + } + assert(!"not reached"); + return NULL; } -void sc_loop_setTick(int ctick) +DECL(sc_loop_delScoreEvent) // (int id) { - sc_tt->loop->setTick(ctick); + int id; + if (!PyArg_ParseTuple(args, "i", &id )) + { + return NULL; + } + sc_tt->loop->delEvent(id); + RetNone; } -void sc_loop_setTickDuration(MYFLT secs_per_tick) +DECL(sc_loop_updateEvent) // (int id) { - sc_tt->loop->setTickDuration(secs_per_tick); + int id; + int idx; + float val; + if (!PyArg_ParseTuple(args, "iif", &id, &idx, &val )) + { + return NULL; + } + sc_tt->loop->updateEvent(id, idx, val); + RetNone; } -void sc_loop_addScoreEvent15(int in_ticks, char type, MYFLT p1, MYFLT p2, MYFLT p3, MYFLT p4, MYFLT p5, MYFLT p6, MYFLT p7, MYFLT p8, MYFLT p9, MYFLT p10, MYFLT p11, MYFLT p12, MYFLT p13, MYFLT p14, MYFLT p15) +DECL(sc_loop_clear) { - sc_tt->loop->addEvent( new ev_t(type, in_ticks, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15)); + if (!PyArg_ParseTuple(args, "" )) + { + return NULL; + } + sc_tt->loop->clear(); + RetNone; } -void sc_loop_clear() +DECL(sc_loop_playing) // (int tf) { - sc_tt->loop->clear(); + int i; + if (!PyArg_ParseTuple(args, "i", &i )) + { + return NULL; + } + sc_tt->thread_playloop = i; + RetNone; +} +DECL (sc_inputMessage) //(const char *msg) +{ + char * msg; + if (!PyArg_ParseTuple(args, "s", &msg )) + { + return NULL; + } + sc_tt->inputMessage(msg); + RetNone; } -void sc_loop_playing(int tf) + +#define MDECL(s) {""#s, s, METH_VARARGS, "documentation of "#s"... nothing!"}, +static PyMethodDef SpamMethods[] = { + {"sc_destroy", sc_destroy, METH_VARARGS,""}, + {"sc_initialize", sc_initialize, METH_VARARGS,""}, + {"sc_start", sc_start, METH_VARARGS,""}, + {"sc_stop", sc_stop, METH_VARARGS,""}, + {"sc_scoreEvent", sc_scoreEvent, METH_VARARGS, ""}, + {"sc_setMasterVolume", sc_setMasterVolume, METH_VARARGS, ""}, + {"sc_setTrackpadX", sc_setTrackpadX, METH_VARARGS, ""}, + {"sc_setTrackpadY", sc_setTrackpadY, METH_VARARGS, ""}, + MDECL(sc_loop_getTick) + MDECL(sc_loop_setNumTicks) + MDECL(sc_loop_setTick) + MDECL(sc_loop_setTickDuration) + MDECL(sc_loop_delScoreEvent) + MDECL(sc_loop_addScoreEvent) // (int id, int duration_in_ticks, char type, farray param) + MDECL(sc_loop_updateEvent) // (int id) + MDECL(sc_loop_clear) + MDECL(sc_loop_playing) + MDECL(sc_inputMessage) + {NULL, NULL, 0, NULL} /*end of list */ +}; + +PyMODINIT_FUNC +initsclient(void) { - sc_tt->thread_playloop = tf; + (void) Py_InitModule("sclient", SpamMethods); } + diff --git a/Util/Clooper/SoundClient.h b/Util/Clooper/SoundClient.h index 561529b..ccfb04b 100644 --- a/Util/Clooper/SoundClient.h +++ b/Util/Clooper/SoundClient.h @@ -19,7 +19,8 @@ extern "C" void sc_scoreEvent4(char type, MYFLT p0, MYFLT p1, MYFLT p2, MYFLT p3); void sc_scoreEvent15(char type, MYFLT p1, MYFLT p2, MYFLT p3, MYFLT p4, MYFLT p5, MYFLT p6, MYFLT p7, MYFLT p8, MYFLT p9, MYFLT p10, MYFLT p11, MYFLT p12, MYFLT p13, MYFLT p14, MYFLT p15); - void sc_loop_addScoreEvent15(int in_ticks, char type, MYFLT p1, MYFLT p2, MYFLT p3, MYFLT p4, MYFLT p5, MYFLT p6, MYFLT p7, MYFLT p8, MYFLT p9, MYFLT p10, MYFLT p11, MYFLT p12, MYFLT p13, MYFLT p14, MYFLT p15); + void sc_loop_addScoreEvent15(int id, int in_ticks, char type, MYFLT p1, MYFLT p2, MYFLT p3, MYFLT p4, MYFLT p5, MYFLT p6, MYFLT p7, MYFLT p8, MYFLT p9, MYFLT p10, MYFLT p11, MYFLT p12, MYFLT p13, MYFLT p14, MYFLT p15); + void sc_loop_delScoreEvent(int id); void sc_loop_clear(); int sc_loop_getTick(); void sc_loop_playing(int tf); diff --git a/Util/Clooper/_SClient.so b/Util/Clooper/_SClient.so Binary files differdeleted file mode 100755 index 66074a6..0000000 --- a/Util/Clooper/_SClient.so +++ /dev/null diff --git a/Util/Clooper/sclient.so b/Util/Clooper/sclient.so Binary files differnew file mode 100755 index 0000000..5d7583b --- /dev/null +++ b/Util/Clooper/sclient.so diff --git a/Util/InstrumentPanel.py b/Util/InstrumentPanel.py new file mode 100644 index 0000000..5788760 --- /dev/null +++ b/Util/InstrumentPanel.py @@ -0,0 +1,184 @@ +#!/usr/bin/env python + +import pygtk +pygtk.require( '2.0' ) +import gtk + +import Config +from Util.ThemeWidgets import * +Tooltips = Config.Tooltips + +class InstrumentPanel(gtk.EventBox): + def __init__(self,setInstrument = None, playInstrument = None, enterMode = False, micRec = None, synthRec = None): + gtk.EventBox.__init__(self) + color = gtk.gdk.color_parse('#000000') + self.modify_bg(gtk.STATE_NORMAL, color) + + self.tooltips = gtk.Tooltips() + + self.setInstrument = setInstrument + self.playInstrument = playInstrument + self.micRec = micRec + self.synthRec = synthRec + self.enterMode = enterMode + self.scrollWin = None + self.recstate = False + self.instDic = {} + + self.generateInstDic() + + self.mainVBox = RoundVBox(fillcolor = Config.PANEL_COLOR, bordercolor = Config.PANEL_COLOR, radius = Config.PANEL_RADIUS) + self.draw_toolbar() + self.draw_instruments_panel() + self.draw_mic_lab_box() + self.add(self.mainVBox) + self.show_all() + + def draw_toolbar(self): + toolbarBox = RoundHBox(fillcolor = Config.PANEL_COLOR, bordercolor = Config.PANEL_COLOR, radius = Config.PANEL_RADIUS) + for category in Config.CATEGORIES: + btn = gtk.Button(label=category) + btn.connect('clicked',self.handleToolbarBtnPress,category) + toolbarBox.add(btn) + + self.mainVBox.pack_start(toolbarBox,False,False) + + def handleToolbarBtnPress(self, widget, category): + self.draw_instruments_panel(category) + + def draw_instruments_panel(self,category = 'all'): + + if self.scrollWin != None: + for child in self.instTable.get_children(): + self.instTable.remove(child) + for child in self.scrollWin.get_children(): + self.scrollWin.remove(child) + self.scrollWin.destroy() + + instrumentNum = len(self.getInstrumentList(category)) + instruments = self.getInstrumentList(category) + + cols = 8 + if instrumentNum < cols: + cols = instrumentNum + rows = (instrumentNum // cols) + if instrumentNum % cols is not 0: #S'il y a un reste + rows = rows + 1 + + self.scrollWin = gtk.ScrolledWindow() + self.scrollWin.set_policy(gtk.POLICY_NEVER,gtk.POLICY_AUTOMATIC) + + self.instTable = gtk.Table(rows,cols,True) + self.instTable.set_row_spacings(0) + self.instTable.set_col_spacings(0) + + for row in range(rows): + for col in range(cols): + if row*cols+col >= instrumentNum: + break + instBox = self.instDic[instruments[row*cols+col]] + self.instTable.attach(instBox, col, col+1, row, row+1, gtk.SHRINK, gtk.SHRINK, 0, 0) + + tableEventBox = gtk.EventBox() + color = gtk.gdk.color_parse(Config.PANEL_COLOR) + tableEventBox.modify_bg(gtk.STATE_NORMAL, color) + tableEventBox.add(self.instTable) + self.scrollWin.add_with_viewport(tableEventBox) + self.mainVBox.pack_start(self.scrollWin) + self.show_all() + + def handleInstrumentButtonClick(self,widget,instrument): + if widget.get_active() is True and self.recstate == False: + if self.setInstrument: self.setInstrument(instrument) + if self.playInstrument: self.playInstrument(instrument) + if self.enterMode: + pass #Close the window + + def handleInstrumentButtonEnter(self,widget,instrument): + if self.playInstrument: self.playInstrument(instrument) + + def draw_mic_lab_box(self): + hbox = gtk.HBox() + + for n in ['mic1','mic2','mic3','mic4']: + vbox1 = RoundVBox(fillcolor = Config.INST_BCK_COLOR, bordercolor = Config.PANEL_COLOR, radius = Config.PANEL_RADIUS) + vbox1.set_border_width(Config.PANEL_SPACING) + + micBtn = ImageRadioButton(self.firstInstButton, Config.IMAGE_ROOT + n + '.png' , Config.IMAGE_ROOT + n + 'sel.png', Config.IMAGE_ROOT + n + 'sel.png') + micRecBtn = ImageButton(Config.IMAGE_ROOT + 'record.png' , Config.IMAGE_ROOT + 'recordhi.png', Config.IMAGE_ROOT + 'recordsel.png') + self.tooltips.set_tip(micRecBtn,Tooltips.RECMIC) + + micBtn.connect('clicked', self.handleInstrumentButtonClick, n) + micRecBtn.connect('clicked', self.handleMicRecButtonClick, n) + micRecBtn.connect('pressed', self.handleRecButtonPress, micBtn) + + vbox1.pack_start(micRecBtn,False,False) + vbox1.pack_start(micBtn,False,False) + hbox.pack_start(vbox1,False,False) + + for n in ['lab1','lab2','lab3','lab4']: + vbox2 = RoundVBox(fillcolor = Config.INST_BCK_COLOR, bordercolor = Config.PANEL_COLOR, radius = Config.PANEL_RADIUS) + vbox2.set_border_width(Config.PANEL_SPACING) + + synthBtn = ImageRadioButton(self.firstInstButton, Config.IMAGE_ROOT + n + '.png', Config.IMAGE_ROOT + n + 'sel.png', Config.IMAGE_ROOT + n + 'sel.png') + synthRecBtn = ImageButton(Config.IMAGE_ROOT + 'record.png' , Config.IMAGE_ROOT + 'recordhi.png', Config.IMAGE_ROOT + 'recordsel.png') + self.tooltips.set_tip(synthRecBtn,Tooltips.RECLAB) + + synthBtn.connect('clicked', self.handleInstrumentButtonClick, n) + synthRecBtn.connect('clicked', self.handleSynthRecButtonClick, n) + synthRecBtn.connect('pressed', self.handleRecButtonPress, synthBtn) + + vbox2.pack_start(synthRecBtn,False,False) + vbox2.pack_start(synthBtn,False,False) + hbox.pack_start(vbox2,False,False) + + self.mainVBox.pack_end(hbox,False,False) + + def handleMicRecButtonClick(self,widget,mic): + self.recstate = False + self.setInstrument(mic) + self.micRec(mic) + + def handleSynthRecButtonClick(self,widget,lab): + self.recstate = False + self.setInstrument(lab) + self.synthRec(lab) + + def handleRecButtonPress(self,widget,btn): + self.recstate = True + btn.set_active(True) + + def generateInstDic(self): + self.firstInstButton = None + for instrument in self.getInstrumentList(): + instBox = RoundVBox(fillcolor = Config.INST_BCK_COLOR, bordercolor = Config.PANEL_COLOR, radius = Config.PANEL_RADIUS) + instBox.set_border_width(Config.PANEL_SPACING) + instButton = ImageRadioButton(self.firstInstButton, Config.IMAGE_ROOT + instrument + '.png' , Config.IMAGE_ROOT + instrument + 'sel.png', Config.IMAGE_ROOT + instrument + 'sel.png') + instButton.connect('clicked',self.handleInstrumentButtonClick, instrument) + if self.enterMode: + instButton.connect('enter',self.handleInstrumentButtonEnter, instrument) + instBox.pack_start(instButton) + self.instDic[instrument] = instBox + if self.firstInstButton == None: + self.firstInstButton = instButton + + def getInstrumentList(self,category = 'all'): + instrumentList = [instrument for instrument in Config.INSTRUMENTS.keys() if instrument[0:4] != 'drum' and instrument[0:3] != 'mic' and instrument[0:3] != 'lab' and instrument[0:4] != 'guid'] + ['drum1kit', 'drum2kit', 'drum3kit'] + + if self.enterMode: + instrumentList = [instrument for instrument in Config.INSTRUMENTS.keys() if instrument[0:4] != 'drum' and instrument[0:3] != 'mic' and instrument[0:3] != 'lab' and instrument[0:4] != 'guid'] + + if category != 'all': + instrumentList = [instrument for instrument in Config.INSTRUMENTS.keys() if instrument[0:4] != 'drum' and instrument[0:3] != 'mic' and instrument[0:3] != 'lab' and instrument[0:4] != 'guid' and Config.INSTRUMENTS[instrument].category == category] + if category == 'percussions' and not self.enterMode: + instrumentList = ['drum1kit', 'drum2kit', 'drum3kit'] + instrumentList + #instrumentList = instrumentList.sort(lambda g,l: cmp(Config.INSTRUMENTS[g].category, Config.INSTRUMENTS[l].category) ) + return instrumentList + +if __name__ == "__main__": + win = gtk.Window() + wc = InstrumentPanel() + win.add(wc) + win.show() + #start the gtk event loop + gtk.main() diff --git a/Util/NoteDB.py b/Util/NoteDB.py index 0ed1c2d..37335d6 100644 --- a/Util/NoteDB.py +++ b/Util/NoteDB.py @@ -27,6 +27,27 @@ class Page: # TODO think of how to handle this!? return self.nextNoteId +class PageListener: + def notifyPageAdd( self, id, at ): + pass + + def notifyPageDelete( self, which, safe ): + pass + + def notifyPageDuplicate( self, new, at ): + pass + + def notifyPageMove( self, which, low, high ): + pass + +class NoteListener: + def notifyNoteAdd( self, page, track, id ): + pass + def notifyNoteDelete( self, page, track, id ): + pass + def notifyNoteUpdate( self, page, track, id, parameter, value ): + pass + class NoteDB: def __init__( self ): self.noteD = {} # bins containing all the notes by page, track, and id @@ -194,7 +215,7 @@ class NoteDB: while at > 0: onset = self.noteS[page][track][at-1].cs.onset if onset <= cs.onset: - if onset < cs.onset: break + if onset <= cs.onset: break elif self.noteS[page][track][at-1].cs.pitch <= cs.pitch: break at -= 1 last = len(self.noteS[page][track]) @@ -202,7 +223,7 @@ class NoteDB: onset = self.noteS[page][track][at].cs.onset if onset >= cs.onset: if onset > cs.onset: break - elif self.noteS[page][track][at].cs.pitch >= cs.pitch: break + elif self.noteS[page][track][at].cs.pitch > cs.pitch: break at += 1 self.noteS[page][track].insert( at, n ) @@ -215,7 +236,7 @@ class NoteDB: if hint: hint[0] = at + 1 # assume the next note will fall after this one for l in self.noteListeners: - l.notifyNoteAdd( id ) + l.notifyNoteAdd( page, track, id ) return id @@ -254,7 +275,7 @@ class NoteDB: del self.noteD[page][track][id] for l in self.noteListeners: - l.notifyNoteDelete( id ) + l.notifyNoteDelete( page, track, id ) # stream format: # page id @@ -332,7 +353,7 @@ class NoteDB: self.parasiteD[page][track][par][id].updateParameter( parameter, value ) for l in self.noteListeners: - l.notifyNoteUpdate( id, parameter, value ) + l.notifyNoteUpdate( page, track, id, parameter, value ) # stream format: # page id diff --git a/Util/ThemeWidgets.py b/Util/ThemeWidgets.py index e4cdccd..cfc1130 100644 --- a/Util/ThemeWidgets.py +++ b/Util/ThemeWidgets.py @@ -719,7 +719,7 @@ class RoundFixed( gtk.Fixed ): return False class ImageButton(gtk.Button): - def __init__(self , mainImg_path, enterImg_path = None, clickImg_path = None, backgroundFill = None ): + def __init__( self, mainImg_path, clickImg_path = None, enterImg_path = None, backgroundFill = None ): gtk.Button.__init__(self) self.alloc = None win = gtk.gdk.get_default_root_window() @@ -757,8 +757,8 @@ class ImageButton(gtk.Button): if enterImg_path != None: prepareImage( "enter", enterImg_path ) - self.connect('enter',self.on_btn_enter, None) - self.connect('leave',self.on_btn_leave, None) + self.connect('enter-notify-event',self.on_btn_enter) + self.connect('leave-notify-event',self.on_btn_leave) if clickImg_path != None: prepareImage( "click", clickImg_path ) self.connect('pressed',self.on_btn_press, None) @@ -770,8 +770,8 @@ class ImageButton(gtk.Button): self.iwidthDIV2["enter"] = self.iwidthDIV2["main"] self.iheight["enter"] = self.iheight["main"] self.iheightDIV2["enter"] = self.iheightDIV2["main"] - self.connect('enter',self.on_btn_enter, None) - self.connect('leave',self.on_btn_leave, None) + self.connect('enter-notify-event',self.on_btn_enter) + self.connect('leave-notify-event',self.on_btn_leave) self.curImage = self.upImage = "main" self.down = False @@ -788,9 +788,9 @@ class ImageButton(gtk.Button): def expose(self, widget, event): if self.itype[self.curImage] == ITYPE.PIXBUF: - self.window.draw_pixbuf( self.gc, self.image[self.curImage], 0, 0, self.drawX - self.iwidthDIV2[self.curImage], self.drawY - self.iwidthDIV2[self.curImage], self.iwidth[self.curImage], self.iheight[self.curImage], gtk.gdk.RGB_DITHER_NONE) + self.window.draw_pixbuf( self.gc, self.image[self.curImage], 0, 0, self.drawX - self.iwidthDIV2[self.curImage], self.drawY - self.iheightDIV2[self.curImage], self.iwidth[self.curImage], self.iheight[self.curImage], gtk.gdk.RGB_DITHER_NONE) else: - self.window.draw_drawable( self.gc, self.image[self.curImage], 0, 0, self.drawX - self.iwidthDIV2[self.curImage], self.drawY - self.iwidthDIV2[self.curImage], self.iwidth[self.curImage], self.iheight[self.curImage] ) + self.window.draw_drawable( self.gc, self.image[self.curImage], 0, 0, self.drawX - self.iwidthDIV2[self.curImage], self.drawY - self.iheightDIV2[self.curImage], self.iwidth[self.curImage], self.iheight[self.curImage] ) return True def on_btn_press(self, widget, event): @@ -799,14 +799,16 @@ class ImageButton(gtk.Button): self.queue_draw() def on_btn_enter(self, widget, event): - self.upImage = "enter" - if self.down: self.curImage = "click" - else: self.curImage = "enter" - self.queue_draw() + if event.mode == gtk.gdk.CROSSING_NORMAL: + self.upImage = "enter" + if self.down: self.curImage = "click" + else: self.curImage = "enter" + self.queue_draw() def on_btn_leave(self, widget, event): - self.curImage = self.upImage = "main" - self.queue_draw() + if event.mode == gtk.gdk.CROSSING_NORMAL: + self.curImage = self.upImage = "main" + self.queue_draw() def on_btn_release(self, widget, event): self.curImage = self.upImage @@ -818,6 +820,7 @@ class ImageToggleButton(gtk.ToggleButton): def __init__(self , mainImg_path, altImg_path, enterImg_path = None, backgroundFill = None ): gtk.ToggleButton.__init__(self) self.alloc = None + self.within = False win = gtk.gdk.get_default_root_window() self.gc = gtk.gdk.GC( win ) @@ -855,8 +858,8 @@ class ImageToggleButton(gtk.ToggleButton): if enterImg_path != None: prepareImage( "enter", enterImg_path ) - self.connect('enter',self.on_btn_enter, None) - self.connect('leave',self.on_btn_leave, None) + self.connect('enter-notify-event',self.on_btn_enter) + self.connect('leave-notify-event',self.on_btn_leave) self.connect('toggled',self.toggleImage, None) self.connect('expose-event', self.expose) @@ -873,33 +876,45 @@ class ImageToggleButton(gtk.ToggleButton): def expose(self, widget, event): if self.itype[self.curImage] == ITYPE.PIXBUF: - self.window.draw_pixbuf( self.gc, self.image[self.curImage], 0, 0, self.drawX - self.iwidthDIV2[self.curImage], self.drawY - self.iwidthDIV2[self.curImage], self.iwidth[self.curImage], self.iheight[self.curImage], gtk.gdk.RGB_DITHER_NONE) + self.window.draw_pixbuf( self.gc, self.image[self.curImage], 0, 0, self.drawX - self.iwidthDIV2[self.curImage], self.drawY - self.iheightDIV2[self.curImage], self.iwidth[self.curImage], self.iheight[self.curImage], gtk.gdk.RGB_DITHER_NONE) else: - self.window.draw_drawable( self.gc, self.image[self.curImage], 0, 0, self.drawX - self.iwidthDIV2[self.curImage], self.drawY - self.iwidthDIV2[self.curImage], self.iwidth[self.curImage], self.iheight[self.curImage] ) + self.window.draw_drawable( self.gc, self.image[self.curImage], 0, 0, self.drawX - self.iwidthDIV2[self.curImage], self.drawY - self.iheightDIV2[self.curImage], self.iwidth[self.curImage], self.iheight[self.curImage] ) return True def toggleImage(self, widget, event): if not self.get_active(): - self.curImage = "main" + if self.within and self.image.has_key("enter"): + self.curImage = "enter" + else: + self.curImage = "main" else: self.curImage = "alt" self.queue_draw() def on_btn_enter(self, widget, event): - self.curImage = "enter" - self.queue_draw() + if event.mode == gtk.gdk.CROSSING_NORMAL: + self.within = True + if not self.get_active(): + self.curImage = "enter" + else: + self.curImage = "alt" + self.queue_draw() def on_btn_leave(self, widget, event): - if not self.get_active(): - self.curImage = "main" - else: - self.curImage = "alt" - self.queue_draw() + if event.mode == gtk.gdk.CROSSING_NORMAL: + self.within = False + if not self.get_active(): + self.curImage = "main" + else: + self.curImage = "alt" + self.queue_draw() class ImageRadioButton(gtk.RadioButton): + def __init__( self, group, mainImg_path, altImg_path, enterImg_path = None, backgroundFill = None ): gtk.RadioButton.__init__(self, group) self.alloc = None + self.within = False win = gtk.gdk.get_default_root_window() self.gc = gtk.gdk.GC( win ) @@ -937,8 +952,8 @@ class ImageRadioButton(gtk.RadioButton): if enterImg_path != None: prepareImage( "enter", enterImg_path ) - self.connect('enter',self.on_btn_enter, None) - self.connect('leave',self.on_btn_leave, None) + self.connect('enter-notify-event',self.on_btn_enter) + self.connect('leave-notify-event',self.on_btn_leave) self.connect("toggled", self.toggleImage, None ) self.connect('expose-event', self.expose) @@ -962,18 +977,28 @@ class ImageRadioButton(gtk.RadioButton): def toggleImage(self, widget, event): if not self.get_active(): - self.curImage = "main" + if self.within and self.image.has_key("enter"): + self.curImage = "enter" + else: + self.curImage = "main" else: self.curImage = "alt" self.queue_draw() def on_btn_enter(self, widget, event): - self.curImage = "enter" - self.queue_draw() + if event.mode == gtk.gdk.CROSSING_NORMAL: + self.within = True + if not self.get_active(): + self.curImage = "enter" + else: + self.curImage = "alt" + self.queue_draw() def on_btn_leave(self, widget, event): - if not self.get_active(): - self.curImage = "main" - else: - self.curImage = "alt" - self.queue_draw() + if event.mode == gtk.gdk.CROSSING_NORMAL: + self.within = False + if not self.get_active(): + self.curImage = "main" + else: + self.curImage = "alt" + self.queue_draw() diff --git a/Welcome.py b/Welcome.py new file mode 100644 index 0000000..56910a3 --- /dev/null +++ b/Welcome.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python +import pygtk +pygtk.require( '2.0' ) +import gtk + +import Config +from Util.ThemeWidgets import * + +class Welcome(gtk.EventBox): + + def __init__(self): + gtk.EventBox.__init__(self) + + self.draw() + self.show_all() + + def draw(self): + + actVBox = RoundVBox(fillcolor = Config.WS_BCK_COLOR, bordercolor = Config.WS_BCK_COLOR, radius = Config.PANEL_RADIUS) + actHBox = gtk.HBox() + + for activity in ['mini','edit','type','synth']: + actBtnBox = RoundVBox(fillcolor = Config.WS_PANEL_COLOR, bordercolor = Config.WS_BCK_COLOR, radius = Config.PANEL_RADIUS) + actBtnBox.set_size_request(200,200) + actBtnBox.set_border_width(Config.PANEL_SPACING) + actBtn = ImageButton(Config.IMAGE_ROOT + activity +'Tam.png') + actBtnBox.pack_start(actBtn,True,False,0) + actHBox.pack_start(actBtnBox,True,False,0) + + title = gtk.Image() + title.set_from_file(Config.IMAGE_ROOT + 'TamTam.png') + + actVBox.pack_start(actHBox,False,False, 100) + actVBox.pack_start(title,False,False, 30) + self.add(actVBox) + +if __name__ == "__main__": + win = gtk.Window() + wc = Welcome() + win.add(wc) + win.show() + #start the gtk event loop + gtk.main() + +
\ No newline at end of file diff --git a/Player/GenRythm.py b/miniTamTam/GenRythm.py index 0cba969..0cba969 100644 --- a/Player/GenRythm.py +++ b/miniTamTam/GenRythm.py diff --git a/Player/KeyboardStandAlone.py b/miniTamTam/KeyboardStandAlone.py index 0931e19..1848971 100644 --- a/Player/KeyboardStandAlone.py +++ b/miniTamTam/KeyboardStandAlone.py @@ -5,14 +5,15 @@ import gtk import Config #TODO: this is a suprising dependency... what's up?? from Generation.GenerationConstants import GenerationConstants +from Util.NoteDB import Note from Util.CSoundNote import CSoundNote -from Util.Clooper.SClient import sc_loop_getTick +from Util.CSoundClient import new_csound_client KEY_MAP_PIANO = Config.KEY_MAP_PIANO class KeyboardStandAlone: - def __init__( self, client, recordingFunction, adjustDurationFunction, getCurrentTick, getPlayState ): - self.csnd = client + def __init__( self, recordingFunction, adjustDurationFunction, getCurrentTick, getPlayState ): + self.csnd = new_csound_client() self.recording = recordingFunction self.adjustDuration = adjustDurationFunction # self.getCurrentTick = getCurrentTick @@ -76,10 +77,11 @@ class KeyboardStandAlone: fullDuration = False, instrument = instrument, instrumentFlag = instrument, - reverbSend = self.reverb) - self.key_dict[key].playNow(0.3) + reverbSend = self.reverb) + self.csnd.play(self.key_dict[key], 0.3) + #self.key_dict[key].playNow(0.3) if self.getPlayState(): - recOnset = sc_loop_getTick() / 3 + recOnset = self.csnd.loopGetTick() / 3 self.onset_dict[key] = recOnset self.recording( CSoundNote( onset = recOnset, @@ -98,16 +100,15 @@ class KeyboardStandAlone: key = event.hardware_keycode if KEY_MAP_PIANO.has_key(key): - if Config.INSTRUMENTS[ self.key_dict[key].instrument].csoundInstrumentId == Config.INST_TIED: - self.key_dict[key].duration = .5 - self.key_dict[key].decay = 0.7 - self.key_dict[key].amplitude = 1 - self.key_dict[key].playNow(0.3) + csnote = self.key_dict[key] + if Config.INSTRUMENTS[ csnote.instrument].csoundInstrumentId == Config.INST_TIED: + csnote.duration = .5 + csnote.decay = 0.7 + csnote.amplitude = 1 + self.csnd.play(csnote, 0.3) if self.getPlayState(): - self.adjustDuration(self.key_dict[key].pitch, self.onset_dict[key]) - del self.key_dict[key] - else: - del self.key_dict[key] + self.adjustDuration(csnote.pitch, self.onset_dict[key]) + del self.key_dict[key] if self.getPlayState(): if self.onset_dict.has_key(key): del self.onset_dict[key] diff --git a/Player/NoteStdAlone.py b/miniTamTam/NoteStdAlone.py index 1afeb11..1afeb11 100644 --- a/Player/NoteStdAlone.py +++ b/miniTamTam/NoteStdAlone.py diff --git a/Player/RythmGenerator.py b/miniTamTam/RythmGenerator.py index b917b84..64c1410 100644 --- a/Player/RythmGenerator.py +++ b/miniTamTam/RythmGenerator.py @@ -4,9 +4,9 @@ import math import Config from Util.CSoundNote import CSoundNote from Generation.GenerationConstants import GenerationConstants -from Player.GenRythm import GenRythm +from GenRythm import GenRythm -def generator( instrument, nbeats, regularity, reverbSend, client ): +def generator( instrument, nbeats, regularity, reverbSend ): def makePitchSequence(length, drumPitch): pitchSequence = [] diff --git a/Player/RythmPlayer.py b/miniTamTam/RythmPlayer.py index 9872243..9b67f7b 100644 --- a/Player/RythmPlayer.py +++ b/miniTamTam/RythmPlayer.py @@ -5,17 +5,17 @@ import gobject import time import Config from Util.CSoundNote import CSoundNote -from Util.Clooper.SClient import sc_loop_getTick +from Util.CSoundClient import new_csound_client class RythmPlayer: - def __init__( self, client, recordButtonState ): + def __init__( self, recordButtonState ): self.notesList = [] self.sequencer = [] self.pitchs = [] self.tempo = 120 self.tickDuration = 60. / self.tempo / 12. self.tick = 15 - self.csnd = client + self.csnd = new_csound_client() self.sequencerPlayback = 0 self.startLooking = 0 self.recordState = 0 @@ -24,9 +24,6 @@ class RythmPlayer: self.beat = 4 self.playState = 0 - def getCurrentTick( self ): - return sc_loop_getTick() - def setTempo( self, tempo ): self.tempo = tempo self.tickDuration = 60. / self.tempo / 12. @@ -65,7 +62,7 @@ class RythmPlayer: def adjustDuration( self, pitch, onset ): if pitch in self.pitchs: - offset = self.getCurrentTick() / 3 + offset = self.csnd.loopGetTick() / 3 for note in self.sequencer: if note.pitch == pitch and note.onset == onset: if offset > note.onset: @@ -78,8 +75,9 @@ class RythmPlayer: self.pitchs.remove( pitch ) def handleClock( self ): - if self.tick != self.getCurrentTick() / 3: - self.tick = self.getCurrentTick() / 3 + t = self.csnd.loopGetTick() / 3 + if self.tick != t: + self.tick = t # if self.sequencer and self.sequencerPlayback: # for note in self.sequencer: # if self.realTick[note.onset] == self.tick: diff --git a/Player/StandalonePlayer.py b/miniTamTam/StandalonePlayer.py index f99bde2..e40f6d3 100644 --- a/Player/StandalonePlayer.py +++ b/miniTamTam/StandalonePlayer.py @@ -13,10 +13,12 @@ from Util.ThemeWidgets import * from Util.Credits import Credits #from Util.NoteLooper import NoteLooper from Util.CSoundNote import CSoundNote +from Util.NoteDB import Note +from Util.CSoundClient import new_csound_client -from Player.KeyboardStandAlone import KeyboardStandAlone -from Player.RythmPlayer import RythmPlayer -from Player.RythmGenerator import * +from miniTamTam.KeyboardStandAlone import KeyboardStandAlone +from miniTamTam.RythmPlayer import RythmPlayer +from miniTamTam.RythmGenerator import * from SynthLab.SynthLabWindow import SynthLabWindow from Util.Trackpad import Trackpad @@ -24,11 +26,11 @@ Tooltips = Config.Tooltips class StandAlonePlayer( gtk.EventBox ): - def __init__(self, client): + def __init__(self): gtk.EventBox.__init__( self) self.set_border_width(Config.MAIN_WINDOW_PADDING) - self.csnd = client + self.csnd = new_csound_client() self.instrument = self.getInstrumentList()[0] self.timeout_ms = 50 @@ -38,7 +40,7 @@ class StandAlonePlayer( gtk.EventBox ): self.beat = 4 self.tempo = Config.PLAYER_TEMPO self.rythmInstrument = 'drum1kit' - self.rythmPlayer = RythmPlayer(self.csnd, self.recordStateButton) + self.rythmPlayer = RythmPlayer(self.recordStateButton) self.regenerate() self.csnd.loopSetTempo(self.tempo) self.notesList = [] @@ -333,7 +335,6 @@ class StandAlonePlayer( gtk.EventBox ): self.synthLabWindow =None self.synthLabWindow = SynthLabWindow( - self.csnd, {'lab1':86, 'lab2':87, 'lab3':88, 'lab4':89}[data], self.closeSynthLab) self.synthLabWindow.show_all() @@ -349,10 +350,15 @@ class StandAlonePlayer( gtk.EventBox ): for l in ll: rval += l return rval - self.notesList = [(x.onset, x) for x in flatten( generator(self.rythmInstrument, self.beat, self.regularity, self.reverb, None) )] - self.notesList.sort() + i = 0 + self.noteList= [] + self.csnd.loopClear() + for x in flatten( generator(self.rythmInstrument, self.beat, self.regularity, self.reverb) ): + n = Note(0, x.trackId, i, x) + self.noteList.append( (x.onset, n) ) + i = i + 1 + self.csnd.loopPlay(n) self.csnd.loopSetNumTicks( self.beat * Config.TICKS_PER_BEAT) - self.csnd.loopSet_onset_note( self.notesList) def handleGenerationSlider(self, adj): img = int(adj.value * 7)+1 @@ -374,7 +380,6 @@ class StandAlonePlayer( gtk.EventBox ): def handleTempoSliderRelease(self, widget, event): #self.tempo = int(widget.get_adjustment().value) #self.csnd.loopSetTempo(self.tempo) - self.rythmPlayer.tempo = widget.get_adjustment().value pass def handleTempoSliderChange(self,adj): @@ -423,7 +428,7 @@ class StandAlonePlayer( gtk.EventBox ): self.playStartupSound() def enableKeyboard( self ): - self.keyboardStandAlone = KeyboardStandAlone( self.csnd, self.rythmPlayer.recording, self.rythmPlayer.adjustDuration, self.rythmPlayer.getCurrentTick, self.rythmPlayer.getPlayState ) + self.keyboardStandAlone = KeyboardStandAlone( self.rythmPlayer.recording, self.rythmPlayer.adjustDuration, self.csnd.loopGetTick, self.rythmPlayer.getPlayState ) self.add_events(gtk.gdk.BUTTON_PRESS_MASK) def setInstrument( self , instrument ): @@ -431,7 +436,8 @@ class StandAlonePlayer( gtk.EventBox ): self.keyboardStandAlone.setInstrument(instrument) def playInstrumentNote(self , instrument, secs_per_tick = 0.025): - note = CSoundNote( onset = 0, + self.csnd.play( + CSoundNote( onset = 0, pitch = 36, amplitude = 1, pan = 0.5, @@ -440,8 +446,8 @@ class StandAlonePlayer( gtk.EventBox ): fullDuration = False, instrument = instrument, instrumentFlag = instrument, - reverbSend = 0) - note.playNow(secs_per_tick) + reverbSend = 0), + secs_per_tick) def handleKeyboard(self, widget, event): if event.hardware_keycode == 65: diff --git a/Player/__init__.py b/miniTamTam/__init__.py index e69de29..e69de29 100644 --- a/Player/__init__.py +++ b/miniTamTam/__init__.py diff --git a/Player/StandalonePlayer.py b/miniTamTam/miniTamTamMain.py index f99bde2..d92d9ae 100644 --- a/Player/StandalonePlayer.py +++ b/miniTamTam/miniTamTamMain.py @@ -10,25 +10,26 @@ from types import * import Config from Util.ThemeWidgets import * -from Util.Credits import Credits -#from Util.NoteLooper import NoteLooper from Util.CSoundNote import CSoundNote +from Util.NoteDB import Note +from Util.CSoundClient import new_csound_client -from Player.KeyboardStandAlone import KeyboardStandAlone -from Player.RythmPlayer import RythmPlayer -from Player.RythmGenerator import * +from KeyboardStandAlone import KeyboardStandAlone +from RythmPlayer import RythmPlayer +from RythmGenerator import * from SynthLab.SynthLabWindow import SynthLabWindow from Util.Trackpad import Trackpad +from Util.InstrumentPanel import InstrumentPanel Tooltips = Config.Tooltips -class StandAlonePlayer( gtk.EventBox ): +class miniTamTamMain( gtk.EventBox ): - def __init__(self, client): + def __init__(self): gtk.EventBox.__init__( self) self.set_border_width(Config.MAIN_WINDOW_PADDING) - self.csnd = client + self.csnd = new_csound_client() self.instrument = self.getInstrumentList()[0] self.timeout_ms = 50 @@ -38,7 +39,7 @@ class StandAlonePlayer( gtk.EventBox ): self.beat = 4 self.tempo = Config.PLAYER_TEMPO self.rythmInstrument = 'drum1kit' - self.rythmPlayer = RythmPlayer(self.csnd, self.recordStateButton) + self.rythmPlayer = RythmPlayer(self.recordStateButton) self.regenerate() self.csnd.loopSetTempo(self.tempo) self.notesList = [] @@ -60,9 +61,6 @@ class StandAlonePlayer( gtk.EventBox ): self.rythmPlayer.beat = self.beat self.tooltips = gtk.Tooltips() - - self.creditsOpen = False - self.recstate = False self.mainWindowBox = gtk.HBox() self.leftBox = gtk.VBox() @@ -76,7 +74,6 @@ class StandAlonePlayer( gtk.EventBox ): self.setInstrument(self.instrument) self.drawInstrumentButtons() - self.drawMicBox() self.drawSliders() #self.drawLogo() self.drawGeneration() @@ -84,23 +81,6 @@ class StandAlonePlayer( gtk.EventBox ): self.playStartupSound() self.synthLabWindow = None - - def drawLogo(self): - eventbox = gtk.EventBox() - eventbox.connect('button-press-event', self.handleLogoPress) - logo = gtk.Image() - logo.set_from_file(Config.IMAGE_ROOT + 'tamtam_rouge.png') - eventbox.add(logo) - self.middleBox.add(eventbox) - - def handleLogoPress(self, widget, event): - pos = widget.window.get_origin() - if self.creditsOpen is False: - credits = Credits(self.handleCreditsClose , pos) - self.handleCreditsClose(True) - - def handleCreditsClose(self , state): - self.creditsOpen = state def drawSliders( self ): mainSliderBox = RoundHBox(fillcolor = Config.PANEL_COLOR, bordercolor = Config.PANEL_BCK_COLOR, radius = Config.PANEL_RADIUS) @@ -133,7 +113,7 @@ class StandAlonePlayer( gtk.EventBox ): mainSliderBox.pack_start(volumeSliderBox, True, True, 5) mainSliderBox.pack_start(reverbSliderBox, True, True, 5) - self.leftBox.add(mainSliderBox) + self.leftBox.pack_start(mainSliderBox,False,False) def drawGeneration( self ): @@ -228,116 +208,43 @@ class StandAlonePlayer( gtk.EventBox ): self.rightBox.pack_start(geneButtonBox, True) self.rightBox.pack_start(transportBox, True) - def drawInstrumentButtons(self): - ROW_LEN = 8 - - vBox = gtk.VBox() - - intrumentNum = len(self.getInstrumentList()) - rows = ( intrumentNum // ROW_LEN ) - if intrumentNum % ROW_LEN is not 0: #S'il y a un reste - rows = rows + 1 - - self.firstInstButton = None - for row in range(rows): - hBox = gtk.HBox() - for instrument in self.getInstrumentList()[row*ROW_LEN:(row+1)*ROW_LEN]: - instBox = RoundVBox(fillcolor = Config.INST_BCK_COLOR, bordercolor = Config.PANEL_BCK_COLOR, radius = Config.PANEL_RADIUS) - instBox.set_border_width(Config.PANEL_SPACING) - instButton = ImageRadioButton(self.firstInstButton, Config.IMAGE_ROOT + instrument + '.png' , Config.IMAGE_ROOT + instrument + 'sel.png', Config.IMAGE_ROOT + instrument + 'sel.png') - if self.firstInstButton == None: - self.firstInstButton = instButton - instButton.connect('clicked' , self.handleInstrumentButtonClick , instrument) - instBox.add(instButton) - hBox.add(instBox) - vBox.add(hBox) - self.leftBox.add(vBox) - - def drawMicBox( self ): - hbox = gtk.HBox() - - for n in ['mic1','mic2','mic3','mic4']: - vbox1 = RoundVBox(fillcolor = Config.INST_BCK_COLOR, bordercolor = Config.PANEL_BCK_COLOR, radius = Config.PANEL_RADIUS) - vbox1.set_border_width(Config.PANEL_SPACING) - - micBtn = ImageRadioButton(self.firstInstButton, Config.IMAGE_ROOT + n + '.png' , Config.IMAGE_ROOT + n + 'sel.png', Config.IMAGE_ROOT + n + 'sel.png') - micRecBtn = ImageButton(Config.IMAGE_ROOT + 'record.png' , Config.IMAGE_ROOT + 'recordhi.png', Config.IMAGE_ROOT + 'recordsel.png') - self.tooltips.set_tip(micRecBtn,Tooltips.RECMIC) - - micBtn.connect('clicked', self.handleInstrumentButtonClick, n) - micRecBtn.connect('clicked', self.handleMicButtonClick, n) - micRecBtn.connect('pressed', self.handleRecButtonPress, micBtn) - - vbox1.add(micRecBtn) - vbox1.add(micBtn) - hbox.add(vbox1) - - for n in ['lab1','lab2','lab3','lab4']: - vbox2 = RoundVBox(fillcolor = Config.INST_BCK_COLOR, bordercolor = Config.PANEL_BCK_COLOR, radius = Config.PANEL_RADIUS) - vbox2.set_border_width(Config.PANEL_SPACING) - - synthBtn = ImageRadioButton(self.firstInstButton, Config.IMAGE_ROOT + n + '.png', Config.IMAGE_ROOT + n + 'sel.png', Config.IMAGE_ROOT + n + 'sel.png') - synthRecBtn = ImageButton(Config.IMAGE_ROOT + 'record.png' , Config.IMAGE_ROOT + 'recordhi.png', Config.IMAGE_ROOT + 'recordsel.png') - self.tooltips.set_tip(synthRecBtn,Tooltips.RECLAB) - - synthBtn.connect('clicked', self.handleInstrumentButtonClick, n) - synthRecBtn.connect('clicked', self.handleSynthButtonClick, n) - synthRecBtn.connect('pressed', self.handleRecButtonPress, synthBtn) - - vbox2.add(synthRecBtn) - vbox2.add(synthBtn) - hbox.add(vbox2) - - self.leftBox.add(hbox) + self.instPanel = InstrumentPanel(self.setInstrument,self.playInstrumentNote, False, self.micRec, self.synthRec) + self.leftBox.pack_start(self.instPanel,True,True) - def recordStateButton( self, state ): - self.seqRecordButton.set_active( state ) - - def handleInstrumentButtonClick(self , widget , instrument): - if widget.get_active() == True and self.recstate == False: - self.setInstrument(instrument) - self.playInstrumentNote(instrument) - - def handleRecButtonPress(self, widget, recBtn): - self.recstate = True - recBtn.set_active(True) - - def synthLabWindowOpen(self): - return self.synthLabWindow != None and self.synthLabWindow.get_property('visible') - - def handleMicButtonClick(self , widget , data): - self.recstate = False - self.setInstrument(data) - os.system('rm ' + Config.PREF_DIR + '/' + data) - if data == 'mic1': + def micRec(self,mic): + os.system('rm ' + Config.PREF_DIR + '/' + mic) + if mic == 'mic1': self.csnd.micRecording(7) - elif data == 'mic2': + elif mic == 'mic2': self.csnd.micRecording(8) - elif data == 'mic3': + elif mic == 'mic3': self.csnd.micRecording(9) - elif data == 'mic4': + elif mic == 'mic4': self.csnd.micRecording(10) else: return - self.micTimeout = gobject.timeout_add(5000, self.loadMicInstrument, data) - - def loadMicInstrument( self, data ): - self.csnd.load_mic_instrument( data ) - - def handleSynthButtonClick(self , widget , data): - self.recstate = False - self.setInstrument(data) + self.micTimeout = gobject.timeout_add(5000, self.loadMicInstrument, mic) + + def synthRec(self,lab): if self.synthLabWindow != None: self.synthLabWindow.destroy() self.synthLabWindow =None self.synthLabWindow = SynthLabWindow( - self.csnd, - {'lab1':86, 'lab2':87, 'lab3':88, 'lab4':89}[data], + {'lab1':86, 'lab2':87, 'lab3':88, 'lab4':89}[lab], self.closeSynthLab) self.synthLabWindow.show_all() + def recordStateButton( self, state ): + self.seqRecordButton.set_active( state ) + + def synthLabWindowOpen(self): + return self.synthLabWindow != None and self.synthLabWindow.get_property('visible') + + def loadMicInstrument( self, data ): + self.csnd.load_mic_instrument( data ) + def closeSynthLab(self): if self.synthLabWindow != None: self.synthLabWindow.destroy() @@ -349,10 +256,15 @@ class StandAlonePlayer( gtk.EventBox ): for l in ll: rval += l return rval - self.notesList = [(x.onset, x) for x in flatten( generator(self.rythmInstrument, self.beat, self.regularity, self.reverb, None) )] - self.notesList.sort() + i = 0 + self.noteList= [] + self.csnd.loopClear() + for x in flatten( generator(self.rythmInstrument, self.beat, self.regularity, self.reverb) ): + n = Note(0, x.trackId, i, x) + self.noteList.append( (x.onset, n) ) + i = i + 1 + self.csnd.loopPlay(n) self.csnd.loopSetNumTicks( self.beat * Config.TICKS_PER_BEAT) - self.csnd.loopSet_onset_note( self.notesList) def handleGenerationSlider(self, adj): img = int(adj.value * 7)+1 @@ -386,7 +298,6 @@ class StandAlonePlayer( gtk.EventBox ): 1,8)) self.tempoSliderBoxImgTop.set_from_file(Config.IMAGE_ROOT + 'tempo' + str(img) + '.png') - def handleVolumeSlider(self, adj): self.volume = int(adj.value) self.csnd.setMasterVolume(self.volume) @@ -408,7 +319,6 @@ class StandAlonePlayer( gtk.EventBox ): self.csnd.loopSetTick(0) self.csnd.loopStart() - def handleGenerationDrumBtn(self , widget , data): #data is drum1kit, drum2kit, or drum3kit self.rythmInstrument = data @@ -423,7 +333,7 @@ class StandAlonePlayer( gtk.EventBox ): self.playStartupSound() def enableKeyboard( self ): - self.keyboardStandAlone = KeyboardStandAlone( self.csnd, self.rythmPlayer.recording, self.rythmPlayer.adjustDuration, self.rythmPlayer.getCurrentTick, self.rythmPlayer.getPlayState ) + self.keyboardStandAlone = KeyboardStandAlone( self.rythmPlayer.recording, self.rythmPlayer.adjustDuration, self.csnd.loopGetTick, self.rythmPlayer.getPlayState ) self.add_events(gtk.gdk.BUTTON_PRESS_MASK) def setInstrument( self , instrument ): @@ -431,7 +341,8 @@ class StandAlonePlayer( gtk.EventBox ): self.keyboardStandAlone.setInstrument(instrument) def playInstrumentNote(self , instrument, secs_per_tick = 0.025): - note = CSoundNote( onset = 0, + self.csnd.play( + CSoundNote( onset = 0, pitch = 36, amplitude = 1, pan = 0.5, @@ -440,8 +351,8 @@ class StandAlonePlayer( gtk.EventBox ): fullDuration = False, instrument = instrument, instrumentFlag = instrument, - reverbSend = 0) - note.playNow(secs_per_tick) + reverbSend = 0), + secs_per_tick) def handleKeyboard(self, widget, event): if event.hardware_keycode == 65: @@ -453,7 +364,7 @@ class StandAlonePlayer( gtk.EventBox ): def playStartupSound(self): r = str(random.randrange(1,11)) self.playInstrumentNote('guidice' + r) - + def getInstrumentList(self): cleanInstrumentList = [instrument for instrument in Config.INSTRUMENTS.keys() if instrument[0:4] != 'drum' and instrument[0:3] != 'mic' and instrument[0:3] != 'lab' and instrument[0:4] != 'guid'] cleanInstrumentList.sort(lambda g,l: cmp(Config.INSTRUMENTS[g].category, Config.INSTRUMENTS[l].category) ) @@ -484,6 +395,6 @@ class StandAlonePlayer( gtk.EventBox ): return result if __name__ == "__main__": - standAlonePlayer = StandAlonePlayer() + MiniTamTam = miniTamTam() #start the gtk event loop gtk.main() |