diff options
-rw-r--r-- | Config.py | 5 | ||||
-rwxr-xr-x | TamTam.py | 2 | ||||
-rw-r--r-- | Util/CSoundClient.py | 3 | ||||
-rw-r--r-- | Util/Clooper/aclient.cpp | 33 | ||||
-rwxr-xr-x | Util/Clooper/aclient.so | bin | 47718 -> 49464 bytes | |||
-rw-r--r-- | Util/Instrument.py | 10 | ||||
-rw-r--r-- | Util/Network.py | 14 | ||||
-rw-r--r-- | miniTamTam/GenRythm.py | 12 | ||||
-rw-r--r-- | miniTamTam/KeyboardStandAlone.py | 89 | ||||
-rwxr-xr-x | miniTamTam/Loop.py | 7 | ||||
-rw-r--r-- | miniTamTam/miniTamTamMain.py | 53 |
11 files changed, 149 insertions, 79 deletions
@@ -62,6 +62,11 @@ PLUGIN_NPERIODS = 2 ############## ## SOUNDS ############## +KIT_ELEMENT = 24 * [0] +for i in range(0,13): + KIT_ELEMENT += 2 * [i] +KIT_ELEMENT = tuple(KIT_ELEMENT) + class Instrument: def __init__( self, name, instrumentId, csoundInstrumentId, instrumentRegister, soundClass, category, loopStart, loopEnd, crossDur, kit = None ): self.name = name @@ -186,10 +186,8 @@ class TamTam(Activity): def onKeyPress(self, widget, event): if Config.DEBUG > 5: print 'DEBUG: TamTam::onKeyPress in TamTam.py' - print "hello" if event.state == gtk.gdk.MOD1_MASK: key = event.hardware_keycode - print key if key == 54: # j self.set_mode("jam") return diff --git a/Util/CSoundClient.py b/Util/CSoundClient.py index a018ac8..53a4788 100644 --- a/Util/CSoundClient.py +++ b/Util/CSoundClient.py @@ -41,6 +41,9 @@ class _CSoundClientPlugin: self.connect(False) sc_destroy() + def setChannel(self, name, val): + if self.on: + sc_setChannel(name, val) def setMasterVolume(self, volume): #self.masterVolume = volume diff --git a/Util/Clooper/aclient.cpp b/Util/Clooper/aclient.cpp index 861b590..baa7419 100644 --- a/Util/Clooper/aclient.cpp +++ b/Util/Clooper/aclient.cpp @@ -614,6 +614,26 @@ struct TamTamSound return csound != NULL; } + void setChannel(const char * name, MYFLT vol) + { + if (!csound) { + ll->printf(1, "skipping %s, csound==NULL\n", __FUNCTION__); + return; + } + if (!ThreadID) + { + if (_debug && (VERBOSE > 1)) fprintf(_debug, "skipping %s, ThreadID==NULL\n", __FUNCTION__); + return ; + } + MYFLT *p; + if (!(csoundGetChannelPtr(csound, &p, name, CSOUND_CONTROL_CHANNEL | CSOUND_INPUT_CHANNEL))) + *p = (MYFLT) vol; + else + { + if (_debug && (VERBOSE >0)) fprintf(_debug, "ERROR: failed to set channel: %s\n", name); + } + } + void setMasterVolume(MYFLT vol) { if (!csound) { @@ -825,6 +845,18 @@ DECL(sc_scoreEvent) //(char type, farray param) assert(!"not reached"); return NULL; } +DECL(sc_setChannel) //(float v) +{ + const char * str; + float v; + if (!PyArg_ParseTuple(args, "sf", &str,&v)) + { + return NULL; + } + sc_tt->setChannel(str,v); + Py_INCREF(Py_None); + return Py_None; +} DECL(sc_setMasterVolume) //(float v) { float v; @@ -1020,6 +1052,7 @@ static PyMethodDef SpamMethods[] = { MDECL(sc_start), MDECL(sc_stop), MDECL(sc_scoreEvent), + MDECL(sc_setChannel), MDECL(sc_setMasterVolume), MDECL(sc_setTrackVolume), MDECL(sc_setTrackpadX), diff --git a/Util/Clooper/aclient.so b/Util/Clooper/aclient.so Binary files differindex 5143f9d..b089412 100755 --- a/Util/Clooper/aclient.so +++ b/Util/Clooper/aclient.so diff --git a/Util/Instrument.py b/Util/Instrument.py index 3e4db27..159b736 100644 --- a/Util/Instrument.py +++ b/Util/Instrument.py @@ -19,8 +19,9 @@ class Instrument: def __init__( self, name, csoundInstrumentName, registerName, category, loopStart, loopEnd, crossDur, wav, img ): self.name = name self.instrumentId = len(INST) + self.csoundInstrumentName = csoundInstrumentName self.csoundInstrumentId = CSOUND_INSTRUMENT[csoundInstrumentName] - self.instrumentRegister = self.REGISTER[registerName] + self.register = registerName self.category = category self.loopStart = loopStart self.loopEnd = loopEnd @@ -170,6 +171,13 @@ else: Instrument( "guit2", 'inst_tied', 'mid', 'strings', .33, 1.1583, .02 , None, None) Instrument( "plane", 'inst_simp', 'mid', 'concret', 0, 0, 0 , None, None) Instrument( "slap", 'inst_simp', 'mid', 'concret', 0, 0, 0 , None, None) +INST_byId = {} +for i in INST: + INST_byId[ INST[i].instrumentId] = INST[i] + +KIT_ELEMENT = 24 * [0] +for i in range(0,13): + KIT_ELEMENT += 2 * [i] DRUM = {} drum_load_dynamic = 0 diff --git a/Util/Network.py b/Util/Network.py index a3df280..397110f 100644 --- a/Util/Network.py +++ b/Util/Network.py @@ -48,7 +48,7 @@ message_enum = [ ("PR_LATENCY_QUERY", 4), # test latency ("PR_SYNC_QUERY", 4), # test sync ("PR_TEMPO_QUERY", 0), # test sync -("PR_TEMPO_CHANGE", 4), # test sync +("PR_REQUEST_TEMPO_CHANGE", 4), # request tempo change ("MAX_MSG_ID", 0) ] @@ -80,7 +80,9 @@ class Listener( threading.Thread ): def run(self): while 1: # rely on the owner to kill us when necessary try: + print "Listerner:: select" inputReady, outputReady, exceptReady = select.select( self.inputSockets, self.outputSockets, self.exceptSockets ) + print "Listener:: inputready", inputReady if self.listenerSocket in inputReady: data, s = self.listenerSocket.recvfrom(MAX_SIZE) if data == "REFRESH": @@ -90,8 +92,10 @@ class Listener( threading.Thread ): continue else: break # exit thread + print "Listener:: threads_enter" gtk.gdk.threads_enter() self.owner._processSockets( inputReady, outputReady, exceptReady ) + print "Listener:: threads_leave" gtk.gdk.threads_leave() except socket.error, (value, message): print "Listener:: socket error: " + message @@ -389,12 +393,12 @@ class Network: if size >= 0: if length != size: - print "Network:: message wrong length! Got %d expected %d: %s %s" % (len(data), MSG_SIZE[message], MSG_NAME[message], data) + print "Network:: message wrong length! Got %d expected %d: %s" % (len(data), MSG_SIZE[message], MSG_NAME[message]) return msg = chr(message) + data elif size == -1: if length > 255: - print "Network:: oversized message! Got %d, max size 255: %s %s" % (length, MSG_NAME[message], data) + print "Network:: oversized message! Got %d, max size 255: %s" % (length, MSG_NAME[message]) return msg = chr(message) + chr(length) + data else: # size == -2 @@ -427,12 +431,12 @@ class Network: if size >= 0: if length != size: - print "Network:: message wrong length! Got %d expected %d: %s %s" % (MSG_SIZE[message], len(data), MSG_NAME[message], data) + print "Network:: message wrong length! Got %d expected %d: %s" % (MSG_SIZE[message], len(data), MSG_NAME[message]) return msg = chr(message) + data elif size == -1: if length > 255: - print "Network:: oversized message! Size %d, max size 255: %s %s" % (length, MSG_NAME[message], data) + print "Network:: oversized message! Size %d, max size 255: %s" % (length, MSG_NAME[message]) return msg = chr(message) + chr(length) + data else: # size == -2 diff --git a/miniTamTam/GenRythm.py b/miniTamTam/GenRythm.py index 5e4a873..a9d8f70 100644 --- a/miniTamTam/GenRythm.py +++ b/miniTamTam/GenRythm.py @@ -4,8 +4,10 @@ import Config from Generation.GenerationConstants import GenerationConstants from Generation.Utils import * +from Util import Instrument + class GenRythm: - def drumRythmSequence(self, instrument, nbeats, density, regularity ): + def drumRythmSequence(self, instrumentName, nbeats, density, regularity ): rythmSequence = [] binSelection = [] downBeats = [] @@ -14,28 +16,28 @@ class GenRythm: countDown = 0 onsetTime = None - if Config.INSTRUMENTS[ instrument ].instrumentRegister == Config.PUNCH: + if Instrument.INST[instrumentName].register == 'punch': registerDensity = 0.5 downBeatRecurence = 4 downBeats = [x for x in GenerationConstants.DRUM_PUNCH_ACCENTS[ nbeats ]] for downBeat in downBeats: upBeats.append( downBeat + Config.TICKS_PER_BEAT / 2 ) - if Config.INSTRUMENTS[ instrument ].instrumentRegister == Config.LOW: + if Instrument.INST[instrumentName].register == 'low': registerDensity =1 downBeatRecurence = 4 downBeats = [x for x in GenerationConstants.DRUM_LOW_ACCENTS[ nbeats ]] for downBeat in downBeats: upBeats.append( downBeat + Config.TICKS_PER_BEAT / 2 ) - if Config.INSTRUMENTS[ instrument ].instrumentRegister == Config.MID: + if Instrument.INST[instrumentName].register == 'mid': registerDensity = .75 downBeatRecurence = 1 downBeats = [x for x in GenerationConstants.DRUM_MID_ACCENTS[ nbeats ]] for downBeat in downBeats: upBeats.append( downBeat + Config.TICKS_PER_BEAT / 4 ) - if Config.INSTRUMENTS[ instrument ].instrumentRegister == Config.HIGH: + if Instrument.INST[instrumentName].register == 'high': registerDensity = 1.5 downBeatRecurence = 1 downBeats = [x for x in GenerationConstants.DRUM_HIGH_ACCENTS[ nbeats ]] diff --git a/miniTamTam/KeyboardStandAlone.py b/miniTamTam/KeyboardStandAlone.py index b783070..a5f7c49 100644 --- a/miniTamTam/KeyboardStandAlone.py +++ b/miniTamTam/KeyboardStandAlone.py @@ -7,9 +7,12 @@ from Generation.GenerationConstants import GenerationConstants from Util.NoteDB import Note from Util.CSoundNote import CSoundNote from Util.CSoundClient import new_csound_client +from Util import Instrument KEY_MAP_PIANO = Config.KEY_MAP_PIANO +log = file('/home/olpc/log.tamtam','w') + class KeyboardStandAlone: def __init__( self, recordingFunction, adjustDurationFunction, getCurrentTick, getPlayState, loop ): self.csnd = new_csound_client() @@ -58,53 +61,53 @@ class KeyboardStandAlone: self.trackCount += 1 # If the pressed key is in the keymap if KEY_MAP_PIANO.has_key(key): - # CsoundNote parameters + def playkey(pitch,duration,instrument): + # Create and play the note + self.key_dict[key] = CSoundNote(onset = 0, + pitch = pitch, + amplitude = volume, + pan = 0.5, + duration = duration, + trackId = track, + instrumentId = instrument.instrumentId, + reverbSend = self.reverb, + tied = True, + mode = 'mini') + self.csnd.play(self.key_dict[key], 0.3) + if self.getPlayState(): + recOnset = self.csnd.loopGetTick() + self.onset_dict[key] = recOnset + self.recording( CSoundNote( + onset = recOnset, + pitch = pitch, + amplitude = volume, + pan = 0.5, + duration = 100, + trackId = 0, + decay = .1, + instrumentId = instrument.instrumentId, + reverbSend = self.reverb, + tied = False, + mode = 'mini')) + + instrumentName = self.instrument + print >>log, 'instrumentName:', instrumentName pitch = KEY_MAP_PIANO[key] - duration = -1 - instrument = self.instrument - - if event.state == gtk.gdk.MOD1_MASK: - pitch = pitch+5 - if instrument[ 0: 4 ] == 'drum': - if GenerationConstants.DRUMPITCH.has_key( pitch ): - pitch = GenerationConstants.DRUMPITCH[ pitch ] + if instrumentName in Instrument.DRUM : + print >>log, 'kit_element: ', Config.KIT_ELEMENT[pitch] + playkey(36,100, Instrument.DRUM[instrumentName][ Config.KIT_ELEMENT[pitch] ] ) - if Config.INSTRUMENTS[instrument].kit != None: - instrument = Config.INSTRUMENTS[instrument].kit[pitch].name - pitch = 36 - duration = 100 + else: + if event.state == gtk.gdk.MOD1_MASK: + pitch += 5 - if Config.INSTRUMENTS[instrument].csoundInstrumentId == Config.INST_PERC: #Percussions resonance - duration = 60 + instrument = Instrument.INST[ instrumentName ] + if instrument.csoundInstrumentName == 'inst_perc': #Percussions resonance + playkey( pitch, 60, instrument) + else: + playkey( pitch, -1, instrument) - # Create and play the note - self.key_dict[key] = CSoundNote(onset = 0, - pitch = pitch, - amplitude = volume, - pan = 0.5, - duration = duration, - trackId = track, - instrumentId = Config.INSTRUMENTS[instrument].instrumentId, - reverbSend = self.reverb, - tied = True, - mode = 'mini') - self.csnd.play(self.key_dict[key], 0.3) - if self.getPlayState(): - recOnset = self.csnd.loopGetTick() - self.onset_dict[key] = recOnset - self.recording( CSoundNote( - onset = recOnset, - pitch = pitch, - amplitude = volume, - pan = 0.5, - duration = 100, - trackId = 0, - decay = .1, - instrumentId = Config.INSTRUMENTS[instrument].instrumentId, - reverbSend = self.reverb, - tied = False, - mode = 'mini')) def onKeyRelease(self,widget,event): key = event.hardware_keycode @@ -120,7 +123,7 @@ class KeyboardStandAlone: if KEY_MAP_PIANO.has_key(key): csnote = self.key_dict[key] - if Config.INSTRUMENTSID[ csnote.instrumentId ].csoundInstrumentId == Config.INST_TIED: + if Instrument.INST_byId[ csnote.instrumentId ].csoundInstrumentName == 'inst_tied': csnote.duration = .5 csnote.decay = 0.7 #csnote.amplitude = 1 diff --git a/miniTamTam/Loop.py b/miniTamTam/Loop.py index 4beee57..deb1cad 100755 --- a/miniTamTam/Loop.py +++ b/miniTamTam/Loop.py @@ -6,6 +6,7 @@ from Util.CSoundNote import CSoundNote from Util.CSoundClient import new_csound_client from Util.NoteDB import Note from Util.NoteDB import PARAMETER +from Util import Instrument from Generation.GenerationConstants import GenerationConstants class Loop: @@ -49,10 +50,10 @@ class Loop: pitch = i[1] gain = i[2]*self.volume duration = i[3] - if Config.INSTRUMENTS[instrument].kit != None: + if instrument in Instrument.DRUM: if GenerationConstants.DRUMPITCH.has_key(pitch): pitch = GenerationConstants.DRUMPITCH[pitch] - instrument = Config.INSTRUMENTS[instrument].kit[pitch].name + instrument = Instrument.DRUM[ KIT_ELEMENT[pitch] ].name pitch = 36 return CSoundNote( onset = onset, pitch = pitch, @@ -60,7 +61,7 @@ class Loop: pan = 0.5, duration = duration, trackId = 0, - instrumentId = Config.INSTRUMENTS[instrument].instrumentId, + instrumentId = Instrument.INST[instrument].instrumentId, reverbSend = reverb, tied = False, mode = 'mini') diff --git a/miniTamTam/miniTamTamMain.py b/miniTamTam/miniTamTamMain.py index 3829825..8ab939e 100644 --- a/miniTamTam/miniTamTamMain.py +++ b/miniTamTam/miniTamTamMain.py @@ -34,6 +34,7 @@ from RythmGenerator import * from SynthLab.SynthLabWindow import SynthLabWindow from Util.Trackpad import Trackpad from Util.InstrumentPanel import InstrumentPanel +from Util import Instrument Tooltips = Config.Tooltips @@ -121,7 +122,7 @@ class miniTamTamMain(SubActivity): self.network.connectMessage( Net.HT_TEMPO_UPDATE, self.processHT_TEMPO_UPDATE ) self.network.connectMessage( Net.PR_SYNC_QUERY, self.processPR_SYNC_QUERY ) self.network.connectMessage( Net.PR_TEMPO_QUERY, self.processPR_TEMPO_QUERY ) - self.network.connectMessage( Net.PR_TEMPO_CHANGE, self.processPR_TEMPO_CHANGE ) + self.network.connectMessage( Net.PR_REQUEST_TEMPO_CHANGE, self.processPR_REQUEST_TEMPO_CHANGE ) # data packing classes self.packer = xdrlib.Packer() @@ -139,8 +140,10 @@ class miniTamTamMain(SubActivity): if os.path.isfile("FORCE_SHARE"): # HOST r = random.random() - print "::::: Sharing as TTDBG%f :::::" % r - self.activity.set_title(_gettext("TTDBG%f" % r)) + #print "::::: Sharing as TTDBG%f :::::" % r + #self.activity.set_title(_gettext("TTDBG%f" % r)) + print "::::: Sharing as TamTam :::::" + self.activity.set_title(_gettext("TamTam")) self.activity.connect( "shared", self.shared ) self.activity.share() elif self.activity._shared_activity: # PEER @@ -251,7 +254,9 @@ class miniTamTamMain(SubActivity): self.tempoSliderBoxImgTop = gtk.Image() self.tempoSliderBoxImgTop.set_from_file(Config.IMAGE_ROOT + 'tempo5.png') self.tempoAdjustment = gtk.Adjustment(value=self.tempo, lower=Config.PLAYER_TEMPO_LOWER, upper=Config.PLAYER_TEMPO_UPPER, step_incr=1, page_incr=1, page_size=1) - tempoSlider = ImageVScale( Config.IMAGE_ROOT + "sliderbutvert.png", self.tempoAdjustment, 5) + #tempoSlider = ImageVScale( Config.IMAGE_ROOT + "sliderbutvert.png", self.tempoAdjustment, 5) + tempoSlider = gtk.VScale( self.tempoAdjustment) + #TEMP tempoSlider.set_inverted(True) tempoSlider.set_size_request(15,320) self.tempoAdjustmentHandler = self.tempoAdjustment.connect("value_changed" , self.handleTempoSliderChange) @@ -481,8 +486,7 @@ class miniTamTamMain(SubActivity): def handleTempoSliderChange(self,adj): print "handleTempoSliderChange" if self.network.isPeer(): - pass - #self.requestTempoChange(val) + self.requestTempoChange(int(adj.value)) else: self._updateTempo( int(adj.value), True ) @@ -557,7 +561,7 @@ class miniTamTamMain(SubActivity): #data is drum1kit, drum2kit, or drum3kit #print 'HANDLE: Generate Button' self.rythmInstrument = data - instrumentId = Config.INSTRUMENTS[data].instrumentId + instrumentId = Instrument.INST[data].instrumentId for (o,n) in self.noteList : self.csnd.loopUpdate(n, NoteDB.PARAMETER.INSTRUMENT, instrumentId, -1) self.drumFillin.setInstrument( self.rythmInstrument ) @@ -589,7 +593,7 @@ class miniTamTamMain(SubActivity): pan = 0.5, duration = 20, trackId = 1, - instrumentId = Config.INSTRUMENTS[instrument].instrumentId, + instrumentId = Instrument.INST[instrument].instrumentId, reverbSend = 0, tied = False, mode = 'mini'), @@ -631,11 +635,6 @@ class miniTamTamMain(SubActivity): 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) ) - return cleanInstrumentList + ['drum1kit', 'drum2kit', 'drum3kit'] - def onActivate( self, arg ): self.csnd.loopPause() self.csnd.loopClear() @@ -691,7 +690,10 @@ class miniTamTamMain(SubActivity): def buddy_joined( self, activity, buddy ): print "buddy joined " + str(buddy) - print buddy.props.ip4_address + try: + print buddy.props.ip4_address + except: + print "bad ip4_address" if self.network.isHost(): # TODO how do I figure out if this buddy is me? if buddy.props.ip4_address: @@ -724,8 +726,9 @@ class miniTamTamMain(SubActivity): self.network.send( Net.PR_TEMPO_QUERY ) def requestTempoChange( self, val ): + print "requestTempoChange", val self.packer.pack_int(val) - self.network.sendAll( Net.PR_TEMPO_CHANGE, self.packer.get_buffer() ) + self.network.send( Net.PR_REQUEST_TEMPO_CHANGE, self.packer.get_buffer() ) self.packer.reset() #-- Handlers ----------------------------------------------------------- @@ -753,14 +756,18 @@ class miniTamTamMain(SubActivity): self.syncQueryStart.pop(hash) def processHT_TEMPO_UPDATE( self, sock, message, data ): - #print "got tempo update" + print "got tempo update" self.unpacker.reset(data) - self.tempoAdjustment.signal_handler_block( self.tempoAdjustmentHandler ) + self.tempoAdjustment.handler_block( self.tempoAdjustmentHandler ) val = self.unpacker.unpack_int() + print "a" self.tempoAdjustment.set_value( val ) + time.sleep(0.01) + print "b" self._updateTempo( val ) - self.tempoAdjustment.signal_handler_unblock( self.tempoAdjustmentHandler ) + self.tempoAdjustment.handler_unblock( self.tempoAdjustmentHandler ) self.sendSyncQuery() + print "done" def processPR_SYNC_QUERY( self, sock, message, data ): self.packer.pack_float(self.nextHeartbeat()) @@ -768,15 +775,19 @@ class miniTamTamMain(SubActivity): self.packer.reset() def processPR_TEMPO_QUERY( self, sock, message, data ): + print "processPR_TEMPO_QUERY" self.packer.pack_int(self.tempo) self.network.send( Net.HT_TEMPO_UPDATE, self.packer.get_buffer(), to = sock ) self.packer.reset() + print "done" - def processPR_TEMPO_CHANGE( self, sock, message, data ): - print "got tempo change" + def processPR_REQUEST_TEMPO_CHANGE( self, sock, message, data ): self.unpacker.reset(data) val = self.unpacker.unpack_int() + print "got tempo change", val self.tempoAdjustment.set_value( val ) + time.sleep(0.01) + print "done" #----------------------------------------------------------------------- # Sync @@ -799,6 +810,8 @@ class miniTamTamMain(SubActivity): return self.ticksPerSecond*(delta % self.beatDuration) def updateSync( self ): + #TEMP + return False if self.network.isOffline(): return False elif self.network.isWaiting(): |