Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNat <natcl@hotmail.com>2007-07-19 03:52:11 (GMT)
committer Nat <natcl@hotmail.com>2007-07-19 03:52:11 (GMT)
commit0c51f7abf29eb0b8534e6e47e4fddba7c0164142 (patch)
treeb8a8612a7044aa89f7524f2624bc7a3ea66db56d
parentff470209a9bb85095bb837f465f1c5d3cd9f1c93 (diff)
parent00178f104ce1c9a0cf449046b1e5d9a9dbf94b46 (diff)
Merge branch 'master' of git+ssh://natcl@dev.laptop.org/git/projects/tamtam
-rw-r--r--Config.py10
-rw-r--r--Resources/univorc.csd58
-rwxr-xr-xTamTam.py1
-rw-r--r--Util/CSoundClient.py7
-rw-r--r--Util/Clooper/aclient.cpp33
-rwxr-xr-xUtil/Clooper/aclient.sobin47718 -> 49464 bytes
-rw-r--r--Util/Instrument.py10
-rw-r--r--Util/LoopSettings.py65
-rw-r--r--Util/Network.py16
-rw-r--r--miniTamTam/GenRythm.py12
-rw-r--r--miniTamTam/KeyboardStandAlone.py89
-rwxr-xr-xminiTamTam/Loop.py7
-rw-r--r--miniTamTam/miniTamTamMain.py112
13 files changed, 316 insertions, 104 deletions
diff --git a/Config.py b/Config.py
index 97d95a7..0c9e95e 100644
--- a/Config.py
+++ b/Config.py
@@ -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
diff --git a/TamTam.py b/TamTam.py
index 4e31397..923dcef 100755
--- a/TamTam.py
+++ b/TamTam.py
@@ -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
index 5143f9d..b089412 100755
--- a/Util/Clooper/aclient.so
+++ b/Util/Clooper/aclient.so
Binary files differ
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 )