diff options
author | Nat <natcl@hotmail.com> | 2007-07-19 03:52:11 (GMT) |
---|---|---|
committer | Nat <natcl@hotmail.com> | 2007-07-19 03:52:11 (GMT) |
commit | 0c51f7abf29eb0b8534e6e47e4fddba7c0164142 (patch) | |
tree | b8a8612a7044aa89f7524f2624bc7a3ea66db56d | |
parent | ff470209a9bb85095bb837f465f1c5d3cd9f1c93 (diff) | |
parent | 00178f104ce1c9a0cf449046b1e5d9a9dbf94b46 (diff) |
Merge branch 'master' of git+ssh://natcl@dev.laptop.org/git/projects/tamtam
-rw-r--r-- | Config.py | 10 | ||||
-rw-r--r-- | Resources/univorc.csd | 58 | ||||
-rwxr-xr-x | TamTam.py | 1 | ||||
-rw-r--r-- | Util/CSoundClient.py | 7 | ||||
-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/LoopSettings.py | 65 | ||||
-rw-r--r-- | Util/Network.py | 16 | ||||
-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 | 112 |
13 files changed, 316 insertions, 104 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 @@ -324,6 +329,9 @@ CSOUND_LOAD_INSTRUMENT = 'f%d 0 0 -1 "%s" 0 0 0' CSOUND_MIC_RECORD = 'i5201 0 5 %d' CSOUND_UNLOAD_TABLES = 'i%d 0 0.1 %d' % (INST_FREE, len(INSTRUMENTS)) CSOUND_NOTE_OFF = 'i %s.%s .2 0.01 1. 0. 0. 0.5 %d 0 0 0 0' %('%d','%d',INSTRUMENT_TABLE_OFFSET) +CSOUND_LOAD_LS_INSTRUMENT = 'f4999 0 0 -1 \"%s\" 0 0 0' +CSOUND_PLAY_LS_NOTE = 'i 5022 0 -1' +CSOUND_STOP_LS_NOTE = 'i 5022 0 0.5' #CSOUND COMMANDS - DEPRECATED @@ -336,7 +344,7 @@ PLAY_NOTE_COMMAND_MINUS_DELAY = \ "perf.InputMessage('i 5777 0.0 0.001 %d.%d %s %f %f %f %f %f %d %f %f %d %f')\n" PLAY_NOTE_OFF_COMMAND = \ "perf.InputMessage('i %s.%s .2 0.01 1. 0. 0. 0.5 %d 0 0 0 0')\n" \ - % ('%d', '%d', INSTRUMENT_TABLE_OFFSET ) + % ('%d', '%d', INSTRUMENT_TABLE_OFFSET ) MIC_RECORDING_COMMAND = \ "perf.InputMessage('i5201 0 5 %d')\n" UNLOAD_TABLES_COMMAND = \ diff --git a/Resources/univorc.csd b/Resources/univorc.csd index cd29064..e802ebc 100644 --- a/Resources/univorc.csd +++ b/Resources/univorc.csd @@ -720,6 +720,64 @@ turnoff endin +/************************* +Loop points editor +*************************/ +instr 5022 + +kstart chnget "lstart" +kend chnget "lend" +kdur chnget "ldur" + +idurfadein init 0.005 +idurfadeout init 0.095 +iampe0 init 1 +iampe1 init 1 +iampe2 init 1 + +itie tival +if itie == 1 igoto nofadein + +iampe0 init 0 +iskip = 1 + +nofadein: +iskip = 0 +igliss = 0.005 + +if p3 < 0 igoto nofadeout + +iampe2 init 0 + +nofadeout: + +idelta = idurfadein+idurfadeout +if idelta > abs(p3) then +idelta = abs(p3) +endif + +iampe0 = iampe0 +iampe2 = iampe2 +kenv linseg iampe0, idurfadein, iampe1, abs(p3)-idelta, iampe1, idurfadeout, iampe2 + + +ivibRand random 4.1, 5.7 + +kvibrato oscil .006, ivibRand, 1 + + tigoto tieskip + +a1 flooper2 1, 1+kvibrato, kstart, kend, kdur, 4999, 0, 0, 0, iskip + +a1 = a1*kenv + +gaoutL = a1*0.5+gaoutL +gaoutR = a1*0.5+gaoutR + +gainrev = a1*0.1+gainrev + + tieskip: +endin /**************************************************************** Soundfile player with miniTamTam's tied notes @@ -196,7 +196,6 @@ class TamTam(Activity): if Config.DEBUG > 5: print 'DEBUG: TamTam::onKeyPress in TamTam.py' 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 00aa452..242461f 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 @@ -72,6 +75,10 @@ class _CSoundClientPlugin: instrumentId = Config.INSTRUMENT_TABLE_OFFSET + Config.INSTRUMENTS[inst].instrumentId sc_inputMessage(Config.CSOUND_LOAD_INSTRUMENT % (instrumentId, fileName)) + def load_ls_instrument( self, inst ): + fileName = Config.PREF_DIR + '/' + inst + sc_inputMessage(Config.CSOUND_LOAD_LS_INSTRUMENT % fileName) + def load_instruments( self ): for instrumentSoundFile in Config.INSTRUMENTS.keys(): if instrumentSoundFile[0:3] == 'mic' or instrumentSoundFile[0:3] == 'lab': 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/LoopSettings.py b/Util/LoopSettings.py index acbdecf..a6ac667 100644 --- a/Util/LoopSettings.py +++ b/Util/LoopSettings.py @@ -1,15 +1,18 @@ import pygtk pygtk.require('2.0') import gtk +import os from Util.ThemeWidgets import * import Config Tooltips = Config.Tooltips() class LoopSettings( gtk.VBox ): - def __init__( self, popup ): + def __init__( self, popup, playFunction, setChannelFunction ): gtk.VBox.__init__( self ) self.tooltips = gtk.Tooltips() self.popup = popup + self.playFunction = playFunction + self.setChannel = setChannelFunction self.settingsBox = gtk.HBox() self.pack_start(self.settingsBox) @@ -38,18 +41,31 @@ class LoopSettings( gtk.VBox ): categoryBox = gtk.HBox() categoryMenu = gtk.MenuBar() - menu = gtk.Menu() + cmenu = gtk.Menu() for cat in Config.CATEGORIES: if cat != 'all': entry = gtk.MenuItem(cat) - menu.append(entry) + cmenu.append(entry) entry.connect("activate", self.handleCategory, cat) entry.show() - #categoryBox.pack_start(categoryMenu) self.categoryButton = gtk.Button("Category") - self.categoryButton.connect_object("event", self.categoryBtnPress, menu) + self.categoryButton.connect_object("event", self.categoryBtnPress, cmenu) categoryBox.pack_end(self.categoryButton) self.mainBox.pack_start(categoryBox, False, False, 5) + + registerBox = gtk.HBox() + registerMenu = gtk.MenuBar() + rmenu = gtk.Menu() + self.registerList = ['LOW', 'MID', 'HIGH', 'PUNCH'] + for reg in self.registerList: + entry = gtk.MenuItem(reg) + rmenu.append(entry) + entry.connect("activate", self.handleRegister, self.registerList.index(reg)) + entry.show() + self.registerButton = gtk.Button("Register") + self.registerButton.connect_object("event", self.registerBtnPress, rmenu) + registerBox.pack_end(self.registerButton) + self.mainBox.pack_start(registerBox, False, False, 5) startBox = gtk.VBox() self.startAdjust = gtk.Adjustment( 0.01, 0, 0.5, .01, .01, 0) @@ -88,14 +104,23 @@ class LoopSettings( gtk.VBox ): self.handleDur( self.durAdjust ) durBox.pack_start(self.GUI['durSlider'], True, True, 5) durBox.pack_start(self.durEntry, True, True, 5) - self.controlsBox.pack_start(durBox) + self.controlsBox.pack_start(durBox) - #self.mainBox.pack_start(nameBox) self.mainBox.pack_start(self.controlsBox, False, False, 5) + + previewBox = gtk.VBox() + self.playStopButton = ImageToggleButton(Config.IMAGE_ROOT + 'miniplay.png', Config.IMAGE_ROOT + 'stop.png') + self.playStopButton.connect('button-press-event' , self.handlePlayButton) + previewBox.pack_start(self.playStopButton) + self.mainBox.pack_start(previewBox, False, False, 5) + self.fixed.put( self.mainBox, 0, 0 ) self.show_all() + def set_name(self, name): + self.nameEntry.set_text(name) + def categoryBtnPress(self, widget, event): if event.type == gtk.gdk.BUTTON_PRESS: widget.popup(None, None, None, event.button, event.time) @@ -105,13 +130,31 @@ class LoopSettings( gtk.VBox ): def handleCategory(self, widget, category): self.category = category self.categoryButton.set_label(self.category) - + + def registerBtnPress(self, widget, event): + if event.type == gtk.gdk.BUTTON_PRESS: + widget.popup(None, None, None, event.button, event.time) + return True + return False + + def handleRegister(self, widget, register): + self.register = register + self.registerButton.set_label(self.registerList[self.register]) def handleStart(self, widget, data=None): - self.startEntry.set_text(str(self.startAdjust.value)) + self.start = self.startAdjust.value + self.startEntry.set_text(str(self.start)) + self.setChannel('lstart', self.start) def handleEnd(self, widget, data=None): - self.endEntry.set_text(str(self.endAdjust.value)) + self.end = self.endAdjust.value + self.endEntry.set_text(str(self.end)) + self.setChannel('lend', self.end) def handleDur(self, widget, data=None): - self.durEntry.set_text(str(self.durAdjust.value))
\ No newline at end of file + self.dur = self.durAdjust.value + self.durEntry.set_text(str(self.dur)) + self.setChannel('ldur', self.dur) + + def handlePlayButton(self, widget, data=None): + self.playFunction(widget.get_active())
\ No newline at end of file diff --git a/Util/Network.py b/Util/Network.py index a3df280..0daac85 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) ] @@ -389,12 +389,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 +427,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 @@ -517,7 +517,7 @@ class Network: def processStream( self, sock, newData = "" ): con = self.connection[sock] con.recvBuf += newData - + if con.waitingForData == -1: # message size in char con.waitingForData = ord(con.recvBuf[0]) con.recvBuf = con.recvBuf[1:] @@ -536,7 +536,7 @@ class Network: con.recvBuf = con.recvBuf[con.waitingForData:] con.waitingForData = 0 for func in self.processMessage[con.message]: - func( sock, con.message, data ) + gobject.idle_add( func, sock, con.message, data ) else: return # wait for more data @@ -545,7 +545,7 @@ class Network: if MSG_SIZE[con.message] == 0: con.recvBuf = con.recvBuf[1:] for func in self.processMessage[con.message]: - func( sock, con.message, "" ) + gobject.idle_add( func, sock, con.message, "" ) else: con.waitingForData = MSG_SIZE[con.message] con.recvBuf = con.recvBuf[1:] 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..fcbca15 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.KIT: + #print >>log, 'kit_element: ', Config.KIT_ELEMENT[pitch] + playkey(36,100, Instrument.KIT[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 d17d333..4355abf 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 @@ -67,7 +68,7 @@ class miniTamTamMain(SubActivity): self.loop = Loop(self.beat, sqrt( self.instVolume*0.01 )) self.csnd.loopSetTempo(self.tempo) self.noteList = [] - time.sleep(0.001) + time.sleep(0.001) # why? self.trackpad = Trackpad( self ) for i in range(21): self.csnd.setTrackVolume( 100, i ) @@ -95,7 +96,7 @@ class miniTamTamMain(SubActivity): self.loopSettingsPopup.set_modal(True) self.loopSettingsPopup.add_events( gtk.gdk.BUTTON_PRESS_MASK ) self.loopSettingsPopup.connect("button-release-event", lambda w,e:self.doneLoopSettingsPopup() ) - self.loopSettings = LoopSettings( self.loopSettingsPopup ) + self.loopSettings = LoopSettings( self.loopSettingsPopup, self.loopSettingsPlayStop, self.loopSettingsChannel ) self.loopSettingsPopup.add( self.loopSettings ) @@ -108,6 +109,7 @@ class miniTamTamMain(SubActivity): self.synthLabWindow = None + self.beatPickup = True #self.regenerate() @@ -121,7 +123,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 +141,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 @@ -246,6 +250,9 @@ class miniTamTamMain(SubActivity): beatSliderBox.pack_start(self.beatSliderBoxImgTop, False, padding=10) beatSliderBox.pack_start(self.beatSlider, True, 20) self.tooltips.set_tip(self.beatSlider,Tooltips.BEAT) + + self.delayedTempo = 0 # used to store tempo updates while the slider is active + self.tempoSliderActive = False tempoSliderBox = gtk.VBox() self.tempoSliderBoxImgTop = gtk.Image() @@ -255,6 +262,7 @@ class miniTamTamMain(SubActivity): tempoSlider.set_inverted(True) tempoSlider.set_size_request(15,320) self.tempoAdjustmentHandler = self.tempoAdjustment.connect("value_changed" , self.handleTempoSliderChange) + tempoSlider.connect("button-press-event", self.handleTempoSliderPress) tempoSlider.connect("button-release-event", self.handleTempoSliderRelease) tempoSliderBox.pack_start(self.tempoSliderBoxImgTop, False, padding=10) tempoSliderBox.pack_start(tempoSlider, True) @@ -325,17 +333,51 @@ class miniTamTamMain(SubActivity): self.rightBox.pack_start(slidersBox, True) self.rightBox.pack_start(geneButtonBox, True) + def loopSettingsChannel(self, channel, value): + self.csnd.setChannel(channel, value) + + def loopSettingsPlayStop(self, state): + if not state: + self.csnd.inputMessage(Config.CSOUND_PLAY_LS_NOTE) + else: + self.csnd.inputMessage(Config.CSOUND_STOP_LS_NOTE) + def doneLoopSettingsPopup(self): if self.loopSettingsBtn.get_active(): self.loopSettingsBtn.set_active(False) def handleLoopSettingsBtn(self, widget, data=None): if widget.get_active(): + + chooser = gtk.FileChooserDialog(title='Edit SoundFile Preference',action=gtk.FILE_CHOOSER_ACTION_OPEN, buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN,gtk.RESPONSE_OK)) + + #filter = gtk.FileFilter() + #filter.add_pattern('*.wav') + #chooser.set_filter(filter) + chooser.set_current_folder(Config.PREF_DIR) + + for f in chooser.list_shortcut_folder_uris(): + chooser.remove_shortcut_folder_uri(f) + + if chooser.run() == gtk.RESPONSE_OK: + try: + tempName = chooser.get_filename() + soundName = os.path.split(tempName)[1] + except IOError: + print 'ERROR: failed to load Sound from file %s' % chooser.get_filename() + chooser.destroy() + + self.loopSettings.set_name(soundName) self.loopSettingsPopup.show() - self.loopSettingsPopup.move( 600, 400 ) + self.loopSettingsPopup.move( 600, 200 ) + self.timeoutLoad = gobject.timeout_add(1000, self.load_ls_instrument, soundName) else: self.loopSettingsPopup.hide() - + + def load_ls_instrument(self, name): + self.csnd.load_ls_instrument(name) + gobject.source_remove( self.timeoutLoad ) + def drawInstrumentButtons(self): self.instrumentPanelBox = gtk.HBox() # InstrumentPanel(elf.setInstrument,self.playInstrumentNote, False, self.micRec, self.synthRec) @@ -424,7 +466,9 @@ class miniTamTamMain(SubActivity): def handleGenerationSliderRelease(self, widget, event): self.regularity = widget.get_adjustment().value + self.beatPickup = False self.regenerate() + self.beatPickup = True def pickupNewBeat(self): self.beat = random.randint(2, 12) @@ -451,22 +495,27 @@ class miniTamTamMain(SubActivity): self.regenerate() self.beatPickup = True + def handleTempoSliderPress(self, widget, event): + self.tempoSliderActive = True + def handleTempoSliderRelease(self, widget, event): - #self.tempo = int(widget.get_adjustment().value) - #self.csnd.loopSetTempo(self.tempo) - #self.sequencer.tempo = widget.get_adjustment().value - #self.drumFillin.setTempo(self.tempo) - pass + self.tempoSliderActive = False + if self.network.isPeer() and self.delayedTempo != 0: + if self.tempo != self.delayedTempo: + self.tempoAdjustment.handler_block( self.tempoAdjustmentHandler ) + self.tempoAdjustment.set_value( self.delayedTempo ) + self._updateTempo( self.delayedTempo ) + self.tempoAdjustment.handler_unblock( self.tempoAdjustmentHandler ) + self.delayedTempo = 0 + self.sendSyncQuery() 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 ) + self._updateTempo( int(adj.value) ) - def _updateTempo( self, val, propagate = False ): + def _updateTempo( self, val ): if self.network.isHost(): t = time.time() @@ -537,7 +586,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 ) @@ -568,7 +617,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'), @@ -604,11 +653,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() @@ -664,7 +708,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: @@ -698,7 +745,7 @@ class miniTamTamMain(SubActivity): def requestTempoChange( self, 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 ----------------------------------------------------------- @@ -726,13 +773,15 @@ class miniTamTamMain(SubActivity): self.syncQueryStart.pop(hash) def processHT_TEMPO_UPDATE( self, sock, message, data ): - #print "got tempo update" self.unpacker.reset(data) - self.tempoAdjustment.signal_handler_block( self.tempoAdjustmentHandler ) val = self.unpacker.unpack_int() + if self.tempoSliderActive: + self.delayedTempo = val + return + self.tempoAdjustment.handler_block( self.tempoAdjustmentHandler ) self.tempoAdjustment.set_value( val ) self._updateTempo( val ) - self.tempoAdjustment.signal_handler_unblock( self.tempoAdjustmentHandler ) + self.tempoAdjustment.handler_unblock( self.tempoAdjustmentHandler ) self.sendSyncQuery() def processPR_SYNC_QUERY( self, sock, message, data ): @@ -745,8 +794,9 @@ class miniTamTamMain(SubActivity): self.network.send( Net.HT_TEMPO_UPDATE, self.packer.get_buffer(), to = sock ) self.packer.reset() - def processPR_TEMPO_CHANGE( self, sock, message, data ): - print "got tempo change" + def processPR_REQUEST_TEMPO_CHANGE( self, sock, message, data ): + if self.tempoSliderActive: + return self.unpacker.reset(data) val = self.unpacker.unpack_int() self.tempoAdjustment.set_value( val ) |