Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Edit/EditToolbars.py4
-rw-r--r--Edit/MainWindow.py6
-rw-r--r--Jam/JamMain.py2
-rw-r--r--[-rwxr-xr-x]Resources/Images/pageThumbnailBG0.pngbin1084 -> 1068 bytes
-rw-r--r--[-rwxr-xr-x]Resources/Images/pageThumbnailBG1.pngbin1069 -> 1073 bytes
-rw-r--r--[-rwxr-xr-x]Resources/Images/pageThumbnailBG2.pngbin1083 -> 1037 bytes
-rw-r--r--[-rwxr-xr-x]Resources/Images/pageThumbnailBG3.pngbin1075 -> 1094 bytes
-rw-r--r--Util/CSoundClient.py272
-rw-r--r--Util/Clooper/aclient.cpp724
-rwxr-xr-xUtil/Clooper/aclient.sobin49464 -> 59030 bytes
-rw-r--r--Util/Clooper/audio.cpp5
-rw-r--r--Util/Clooper/log.cpp4
-rw-r--r--miniTamTam/miniTamTamMain.py6
13 files changed, 524 insertions, 499 deletions
diff --git a/Edit/EditToolbars.py b/Edit/EditToolbars.py
index 10c47e8..76264e4 100644
--- a/Edit/EditToolbars.py
+++ b/Edit/EditToolbars.py
@@ -828,8 +828,8 @@ class propertiesPalette(Palette):
self.pageColorBox = gtk.HBox()
self.pageColorLabel = gtk.Label(_('Page color: '))
self.pageColorComboBox = BigComboBox()
- for color in self.colors:
- self.pageColorComboBox.append_item(self.colors.index(color), color)
+ for color in (0,1,2,3):
+ self.pageColorComboBox.append_item(color, text = None, icon_name = Config.IMAGE_ROOT + 'pageThumbnailBG' + str(color) + '.png', size = (30,40))
self.pageColorComboBox.set_active(0)
self.pageColorComboBox.connect('changed', self.handleColor)
self.pageColorBox.pack_start(self.pageColorLabel, False, False, padding = 5)
diff --git a/Edit/MainWindow.py b/Edit/MainWindow.py
index 1be07df..76c85ae 100644
--- a/Edit/MainWindow.py
+++ b/Edit/MainWindow.py
@@ -702,7 +702,7 @@ class MainWindow( SubActivity ):
self.csnd.loopSetNumTicks( numticks )
self.csnd.loopSetTick( self.page_onset[startPage] + startTick )
- self.csnd.loopSetTempo(self._data['tempo'])
+ self.csnd.setTempo(self._data['tempo'])
if (Config.DEBUG > 3): print "starting from tick", startTick, 'at tempo', self._data['tempo']
self.csnd.loopStart()
@@ -865,7 +865,7 @@ class MainWindow( SubActivity ):
img = min(7,int(8*(self._data["tempo"]-widget.lower)/(widget.upper-widget.lower)))+1# tempo 1-8
#self.GUI["2tempoImage"].set_from_file( Config.IMAGE_ROOT+"tempo"+str(img)+".png" )
if self.playing:
- self.csnd.loopSetTempo(self._data['tempo'])
+ self.csnd.setTempo(self._data['tempo'])
def handleToolClick( self, widget, mode ):
if widget.get_active(): self.trackInterface.setInterfaceMode( mode )
@@ -1415,7 +1415,7 @@ class MainWindow( SubActivity ):
def waitToSet(self):
self.csnd.setMasterVolume(self._data['volume'])
- self.csnd.loopSetTempo(self._data['tempo'])
+ self.csnd.setTempo(self._data['tempo'])
self.initTrackVolume()
def handleSave(self, widget):
diff --git a/Jam/JamMain.py b/Jam/JamMain.py
index 8751c74..9ef3fc3 100644
--- a/Jam/JamMain.py
+++ b/Jam/JamMain.py
@@ -46,7 +46,7 @@ class JamMain(SubActivity):
for i in range(1,9):
self.csnd.setTrackVolume( 100, i )
self.csnd.setMasterVolume( self.volume )
- self.csnd.loopSetTempo( self.tempo )
+ self.csnd.setTempo( self.tempo )
#-- Drawing -------------------------------------------
def darken( colormap, hex ):
diff --git a/Resources/Images/pageThumbnailBG0.png b/Resources/Images/pageThumbnailBG0.png
index d40b7e8..db2c684 100755..100644
--- a/Resources/Images/pageThumbnailBG0.png
+++ b/Resources/Images/pageThumbnailBG0.png
Binary files differ
diff --git a/Resources/Images/pageThumbnailBG1.png b/Resources/Images/pageThumbnailBG1.png
index eb57c00..f0c14ce 100755..100644
--- a/Resources/Images/pageThumbnailBG1.png
+++ b/Resources/Images/pageThumbnailBG1.png
Binary files differ
diff --git a/Resources/Images/pageThumbnailBG2.png b/Resources/Images/pageThumbnailBG2.png
index 080027c..4969241 100755..100644
--- a/Resources/Images/pageThumbnailBG2.png
+++ b/Resources/Images/pageThumbnailBG2.png
Binary files differ
diff --git a/Resources/Images/pageThumbnailBG3.png b/Resources/Images/pageThumbnailBG3.png
index d444c5f..839b741 100755..100644
--- a/Resources/Images/pageThumbnailBG3.png
+++ b/Resources/Images/pageThumbnailBG3.png
Binary files differ
diff --git a/Util/CSoundClient.py b/Util/CSoundClient.py
index 0555929..2bab169 100644
--- a/Util/CSoundClient.py
+++ b/Util/CSoundClient.py
@@ -12,6 +12,16 @@ from Generation.GenerationConstants import GenerationConstants
from Util.Clooper.aclient import *
from Util import NoteDB
+
+_note_template = array.array('f', [0] * 19 )
+def _new_note_array():
+ return _note_template.__copy__()
+
+def _noteid(dbnote):
+ return (dbnote.page << 16) + dbnote.id
+
+_loop_default=0
+
class _CSoundClientPlugin:
#array index constants for csound
@@ -37,31 +47,27 @@ class _CSoundClientPlugin:
self.on = False
#self.masterVolume = 80.0
self.periods_per_buffer = 2
+ global _loop_default
+ _loop_default = self.loopCreate()
def __del__(self):
self.connect(False)
sc_destroy()
def setChannel(self, name, val):
- if self.on:
- sc_setChannel(name, val)
+ sc_setChannel(name, val)
def setMasterVolume(self, volume):
- #self.masterVolume = volume
- if self.on:
- sc_setMasterVolume(volume)
+ sc_setChannel( 'masterVolume', volume)
def setTrackVolume( self, volume, trackId ):
- self.trackVolume = volume
- sc_setTrackVolume(volume, trackId+1)
+ sc_setChannel( 'trackVolume' + str(trackId + 1), volume )
def setTrackpadX( self, value ):
- trackpadX = value
- sc_setTrackpadX(trackpadX)
+ sc_setChannel( 'trackpadX', value)
def setTrackpadY( self, value ):
- trackpadY = value
- sc_setTrackpadY(trackpadY)
+ sc_setChannel( 'trackpadY', value)
def micRecording( self, table ):
sc_inputMessage( Config.CSOUND_MIC_RECORD % table )
@@ -113,37 +119,61 @@ class _CSoundClientPlugin:
def inputMessage(self,msg):
sc_inputMessage(msg)
- def loopClear(self):
- 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 loopPause(self):
- sc_loop_playing(0)
- def loopSetTick(self,t):
- sc_loop_setTick(t)
- def loopGetTick(self):
- return sc_loop_getTick()
- def loopSetNumTicks(self,n):
- sc_loop_setNumTicks(n)
- def loopSetTickDuration(self,d):
- sc_loop_setTickDuration(d)
- def loopAdjustTick(self,d):
- sc_loop_adjustTick(d)
- def loopSetTempo(self,t):
+ def getTick( self ):
+ return sc_getTickf()
+
+ def adjustTick( self, amt ):
+ sc_adjustTick(amt)
+
+ def setTempo(self,t):
if (Config.DEBUG > 3) : print 'INFO: loop tempo: %f -> %f' % (t, 60.0 / (Config.TICKS_PER_BEAT * t))
- sc_loop_setTickDuration( 60.0 / (Config.TICKS_PER_BEAT * t))
+ sc_setTickDuration( 60.0 / (Config.TICKS_PER_BEAT * t))
+
+
+ def loopCreate(self):
+ return sc_loop_new()
+
+ def loopDestroy(self, loopId):
+ sc_loop_delete(loopId)
+
+ def loopClear(self):
+ global _loop_default
+ sc_loop_delete(_loop_default)
+ _loop_default = sc_loop_new()
+
+ # this is function deletes an Event from a loop
+ # TODO: rename this function
+ def loopDelete(self, dbnote, loopId=_loop_default):
+ sc_loop_delScoreEvent( loopId, _noteid(dbnote))
+
+ def loopDelete1(self, page, id, loopId=_loop_default):
+ sc_loop_delScoreEvent( loopId, (page << 16) + id)
+
+ def loopStart(self, loopId=_loop_default):
+ sc_loop_playing(loopId, 1)
- def loopDeactivate(self, note = None):
- if note == None:
- sc_loop_deactivate_all()
+ def loopPause(self, loopId=_loop_default):
+ sc_loop_playing(loopId, 0)
+
+ def loopSetTick(self,t, loopId=_loop_default):
+ sc_loop_setTickf(loopId, t)
+
+ def loopGetTick(self, loopId=_loop_default):
+ return sc_loop_getTickf(loopId)
+
+ def loopSetNumTicks(self,n, loopId=_loop_default):
+ sc_loop_setNumTicks(loopId, n)
+
+ def loopSetTickDuration(self,d, loopId=_loop_default):
+ sc_loop_setTickDuration(loopId, d)
+
+ def loopDeactivate(self, note = 'all', loopId=_loop_default):
+ if note == 'all':
+ sc_loop_deactivate_all(loopId)
else:
if (Config.DEBUG > 0) : print 'ERROR: deactivating a single note is not implemented'
- def loopUpdate(self, note, parameter, value,cmd):
+ def loopUpdate(self, note, parameter, value,cmd, loopId=_loop_default):
page = note.page
track = note.track
id = note.id
@@ -156,7 +186,7 @@ class _CSoundClientPlugin:
instrument_id_offset = 100
if (parameter == NoteDB.PARAMETER.ONSET):
if (Config.DEBUG > 2): print 'INFO: updating onset', (page<<16)+id, value
- sc_loop_updateEvent( (page<<16)+id, 1, value, cmd)
+ sc_loop_updateEvent( loopId, (page<<16)+id, 1, value, cmd)
elif (parameter == NoteDB.PARAMETER.PITCH):
if (Config.DEBUG > 2): print 'INFO: updating pitch', (page<<16)+id, value
pitch = value
@@ -165,18 +195,18 @@ class _CSoundClientPlugin:
csoundInstId = instrument.csoundInstrumentId
csoundTable = Config.INSTRUMENT_TABLE_OFFSET + instrument.instrumentId
if (Config.DEBUG > 2): print 'INFO: updating drum instrument (pitch)', (page<<16)+id, instrument.name, csoundInstId
- sc_loop_updateEvent( (page<<16)+id, 0, (csoundInstId + instrument_id_offset) + note.track * 0.01, -1 )
- sc_loop_updateEvent( (page<<16)+id, 7, csoundTable , -1 )
+ sc_loop_updateEvent( loopId, (page<<16)+id, 0, (csoundInstId + instrument_id_offset) + note.track * 0.01, -1 )
+ sc_loop_updateEvent( loopId, (page<<16)+id, 7, csoundTable , -1 )
pitch = 1
else:
pitch = GenerationConstants.TRANSPOSE[ pitch - 24 ]
- sc_loop_updateEvent( (page<<16)+id, 3, pitch, cmd)
+ sc_loop_updateEvent( loopId, (page<<16)+id, 3, pitch, cmd)
elif (parameter == NoteDB.PARAMETER.AMPLITUDE):
if (Config.DEBUG > 2): print 'INFO: updating amp', (page<<16)+id, value
- sc_loop_updateEvent( (page<<16)+id, 5, value, cmd)
+ sc_loop_updateEvent( loopId, (page<<16)+id, 5, value, cmd)
elif (parameter == NoteDB.PARAMETER.DURATION):
if (Config.DEBUG > 2): print 'INFO: updating duration', (page<<16)+id, value
- sc_loop_updateEvent( (page<<16)+id, self.DURATION, value, cmd)
+ sc_loop_updateEvent( loopId, (page<<16)+id, self.DURATION, value, cmd)
elif (parameter == NoteDB.PARAMETER.INSTRUMENT):
pitch = note.cs.pitch
instrument = Config.INSTRUMENTSID[value]
@@ -188,42 +218,43 @@ class _CSoundClientPlugin:
loopEnd = instrument.loopEnd
crossDur = instrument.crossDur
if (Config.DEBUG > 2): print 'INFO: updating instrument', (page<<16)+id, instrument.name, csoundInstId
- sc_loop_updateEvent( (page<<16)+id, 0, (csoundInstId + (track+1) + instrument_id_offset) + note.track * 0.01, cmd )
- sc_loop_updateEvent( (page<<16)+id, 7, csoundTable, -1 )
- sc_loop_updateEvent( (page<<16)+id, 12, loopStart, -1 )
- sc_loop_updateEvent( (page<<16)+id, 13, loopEnd, -1 )
- sc_loop_updateEvent( (page<<16)+id, 14, crossDur , -1 )
+ sc_loop_updateEvent( loopId, (page<<16)+id, 0, (csoundInstId + (track+1) + instrument_id_offset) + note.track * 0.01, cmd )
+ sc_loop_updateEvent( loopId, (page<<16)+id, 7, csoundTable, -1 )
+ sc_loop_updateEvent( loopId, (page<<16)+id, 12, loopStart, -1 )
+ sc_loop_updateEvent( loopId, (page<<16)+id, 13, loopEnd, -1 )
+ sc_loop_updateEvent( loopId, (page<<16)+id, 14, crossDur , -1 )
elif (parameter == NoteDB.PARAMETER.PAN):
- sc_loop_updateEvent( (page<<16)+id, self.PAN, value, cmd)
+ sc_loop_updateEvent( loopId, (page<<16)+id, self.PAN, value, cmd)
elif (parameter == NoteDB.PARAMETER.REVERB):
- sc_loop_updateEvent( (page<<16)+id, self.REVERBSEND, value, cmd)
+ sc_loop_updateEvent( loopId, (page<<16)+id, self.REVERBSEND, value, cmd)
elif (parameter == NoteDB.PARAMETER.ATTACK):
- sc_loop_updateEvent( (page<<16)+id, self.ATTACK, value, cmd)
+ sc_loop_updateEvent( loopId, (page<<16)+id, self.ATTACK, value, cmd)
elif (parameter == NoteDB.PARAMETER.DECAY):
- sc_loop_updateEvent( (page<<16)+id, self.DECAY, value, cmd)
+ sc_loop_updateEvent( loopId, (page<<16)+id, self.DECAY, value, cmd)
elif (parameter == NoteDB.PARAMETER.FILTERTYPE):
- sc_loop_updateEvent( (page<<16)+id, self.FILTERTYPE, value, cmd)
+ sc_loop_updateEvent( loopId, (page<<16)+id, self.FILTERTYPE, value, cmd)
elif (parameter == NoteDB.PARAMETER.FILTERCUTOFF):
- sc_loop_updateEvent( (page<<16)+id, self.FILTERCUTOFF, value, cmd)
+ sc_loop_updateEvent( loopId, (page<<16)+id, self.FILTERCUTOFF, value, cmd)
elif (parameter == NoteDB.PARAMETER.INSTRUMENT2):
- sc_loop_updateEvent( (page<<16)+id, self.INSTRUMENT2, value, cmd)
+ sc_loop_updateEvent( loopId, (page<<16)+id, self.INSTRUMENT2, value, cmd)
else:
if (Config.DEBUG > 0): print 'ERROR: loopUpdate(): unsupported parameter change'
-
- def loopPlay(self, dbnote, active):
+ def loopPlay(self, dbnote, active, storage=_new_note_array(),
+ loopId=_loop_default ):
qid = (dbnote.page << 16) + dbnote.id
- sc_loop_addScoreEvent( qid, 1, active, 'i', self.csnote_to_array(dbnote.cs))
+ sc_loop_addScoreEvent( loopId, qid, 1, active, 'i',
+ self.csnote_to_array( dbnote.cs, storage))
- def play(self, csnote, secs_per_tick):
- a = self.csnote_to_array(csnote)
+ def play(self, csnote, secs_per_tick, storage=_new_note_array()):
+ a = self.csnote_to_array(csnote, storage)
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(
+ def csnote_to_array(self, csnote, storage):
+ return self._csnote_to_array1(storage,
csnote.onset,
csnote.pitch,
csnote.amplitude,
@@ -240,22 +271,11 @@ class _CSoundClientPlugin:
csnote.mode,
csnote.instrumentId2 )
- def csnote_to_array1( self, onset,
- pitch,
- amplitude,
- pan,
- duration,
- trackId,
- attack = 0.002,
- decay = 0.098,
- reverbSend = 0.1,
- filterType = 0,
- filterCutoff = 1000,
- tied = False,
- instrumentId = Config.INSTRUMENTS["flute"].instrumentId,
- mode = 'edit',
- instrumentId2 = -1 ):
+ def _csnote_to_array1( self, storage, onset, pitch, amplitude, pan, duration,
+ trackId, attack, decay, reverbSend, filterType, filterCutoff,
+ tied, instrumentId, mode, instrumentId2 = -1):
+ rval=storage
instrument = Config.INSTRUMENTSID[instrumentId]
if instrument.kit != None:
instrument = instrument.kit[pitch]
@@ -267,63 +287,61 @@ class _CSoundClientPlugin:
instrument_id_offset = 0
# condition for tied notes
- if instrument.csoundInstrumentId == Config.INST_TIED and tied and mode == 'mini':
- duration = -1
- instrument_id_offset = 0
- elif instrument.csoundInstrumentId == Config.INST_TIED and not tied and mode == 'mini':
- instrument_id_offset = 0
- elif instrument.csoundInstrumentId == Config.INST_TIED and tied and mode == 'edit' and duration < 0:
- duration = -1
- instrument_id_offset = 0
- elif instrument.csoundInstrumentId == Config.INST_TIED and tied and mode == 'edit' and duration > 0:
- instrument_id_offset = 0
- elif instrument.csoundInstrumentId == Config.INST_TIED and not tied and mode == 'edit':
- instrument_id_offset = 100
-
- if instrument.csoundInstrumentId == Config.INST_SIMP and mode == 'mini':
- instrument_id_offset = 0
- elif instrument.csoundInstrumentId == Config.INST_SIMP and mode == 'edit':
- if instrument.soundClass == 'drum':
- instrument_id_offset = 0
+ if instrument.csoundInstrumentId == Config.INST_TIED:
+ if tied:
+ if mode == 'mini':
+ duration = -1
+ instrument_id_offset = 0
+ elif mode == 'edit':
+ instrument_id_offset = 0
+ if duration < 0:
+ duration = -1
else:
- instrument_id_offset = 100
+ if mode == 'mini':
+ instrument_id_offset = 0
+ elif mode == 'edit':
+ instrument_id_offset = 100
+
+ if instrument.csoundInstrumentId == Config.INST_SIMP:
+ if mode == 'mini':
+ instrument_id_offset = 0
+ elif mode == 'edit':
+ if instrument.soundClass == 'drum':
+ instrument_id_offset = 0
+ else:
+ instrument_id_offset = 100
+
+ rval[0] = (instrument.csoundInstrumentId + \
+ (trackId+1) + instrument_id_offset) + trackId * 0.01
+ rval[1] = onset
+ rval[2] = duration
+ rval[3] = pitch
+ rval[4] = reverbSend
+ rval[5] = amplitude
+ rval[6] = pan
+ rval[7] = Config.INSTRUMENT_TABLE_OFFSET + instrument.instrumentId
+ rval[8] = attack
+ rval[9] = decay
+ rval[10]= filterType
+ rval[11]= filterCutoff
+ rval[12]= instrument.loopStart
+ rval[13]= instrument.loopEnd
+ rval[14]= instrument.crossDur
if instrumentId2 != -1:
instrument2 = Config.INSTRUMENTSID[instrumentId2]
csInstrumentId2 = (instrument2.csoundInstrumentId + 100) * 0.0001
- secondInstrument = Config.INSTRUMENT_TABLE_OFFSET + instrumentId2 + csInstrumentId2
- loopStart2 = instrument2.loopStart
- loopEnd2 = instrument2.loopEnd
- crossDur2 = instrument2.crossDur
+ rval[15] = Config.INSTRUMENT_TABLE_OFFSET + instrumentId2 + csInstrumentId2
+ rval[16] = instrument2.loopStart
+ rval[17] = instrument2.loopEnd
+ rval[18] = instrument2.crossDur
else:
- secondInstrument = -1
- loopStart2 = 0
- loopEnd2 = 0
- crossDur2 = 0
-
- a = array.array('f')
- a.extend( [
- (instrument.csoundInstrumentId + (trackId+1) + instrument_id_offset) + trackId * 0.01,
- onset,
- duration,
- pitch,
- reverbSend,
- amplitude,
- pan,
- Config.INSTRUMENT_TABLE_OFFSET + instrument.instrumentId,
- attack,
- decay,
- filterType,
- filterCutoff,
- instrument.loopStart,
- instrument.loopEnd,
- instrument.crossDur,
- secondInstrument,
- loopStart2,
- loopEnd2,
- crossDur2])
- return a
+ rval[15] = -1
+ rval[16] = 0
+ rval[17] = 0
+ rval[18] = 0
+ return rval
_Client = None
diff --git a/Util/Clooper/aclient.cpp b/Util/Clooper/aclient.cpp
index 1755438..1146c3b 100644
--- a/Util/Clooper/aclient.cpp
+++ b/Util/Clooper/aclient.cpp
@@ -27,22 +27,22 @@ static double pytime(const struct timeval * tv)
#include "log.cpp"
#include "audio.cpp"
-#define ERROR_HERE if (_debug && (VERBOSE > 0)) fprintf(_debug, "ERROR: %s:%i\n", __FILE__, __LINE__)
-
-#define IF_DEBUG(N) if (_debug && (VERBOSE > N))
#define FLOAT_TO_SHORT(in,out) __asm__ __volatile__ ("fistps %0" : "=m" (out) : "t" (in) : "st") ;
int VERBOSE = 3;
FILE * _debug = NULL;
struct TamTamSound;
-TamTamSound * sc_tt = NULL;
+struct Music;
+TamTamSound * g_tt = NULL;
+Music * g_music = NULL;
log_t * g_log = NULL;
+const int STEP_eventMax = 16; //this is the most events that will be queued by a loop per step()
/**
- * ev_t is the type of event that Clooper puts in the loop buffer.
+ * Event is the type of event that Clooper puts in the loop buffer.
* It corresponds to a line of csound that starts with an 'i'
*/
-struct ev_t
+struct Event
{
char type; ///< if this event were listed in a csound file, the line would begin with this letter
int onset; ///< the onset time of this event (its temporal position)
@@ -52,7 +52,7 @@ struct ev_t
MYFLT duration, attack, decay;///< canonical values of some tempo-dependent parameters
std::vector<MYFLT> param; ///< parameter buffer for csound
- ev_t(char type, MYFLT * p, int param_count, bool in_ticks, bool active)
+ Event(char type, MYFLT * p, int param_count, bool in_ticks, bool active)
: type(type), onset(0), time_in_ticks(in_ticks), active(active), param(param_count)
{
assert(param_count >= 4);
@@ -66,7 +66,7 @@ struct ev_t
param[1] = 0.0; //onset
}
/*
- bool operator<(const ev_t &e) const
+ bool operator<(const Event &e) const
{
return onset < e.onset;
}
@@ -111,9 +111,9 @@ struct ev_t
}
}
/**
- * An ev_t instance can be in an active or inactive state. If an ev_t instance
+ * An Event instance can be in an active or inactive state. If an Event instance
* is active, then event() will call a corresponding csoundScoreEvent(). If an
- * ev_t instance is inactive, then event() is a noop.
+ * Event instance is inactive, then event() is a noop.
*/
void activate_cmd(int cmd)
{
@@ -150,117 +150,80 @@ struct ev_t
/**
*
- * EvLoop is a repeat-able loop of ev_t instances.
+ * Loop is a repeat-able loop of Event instances.
* */
-struct EvLoop
+struct Loop
{
+ typedef int onset_t;
+ typedef int id_t;
+ typedef std::pair<onset_t, Event *> pair_t;
+ typedef std::multimap<onset_t, Event *>::iterator iter_t;
+ typedef std::map<id_t, iter_t>::iterator idmap_t;
+
int tick_prev;
int tickMax;
MYFLT rtick;
- MYFLT secs_per_tick;
- 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;
+ // a container of all events, sorted by onset time
+ // used for efficient playback
+ std::multimap<onset_t, Event *> ev;
+ // the playback head
+ std::multimap<onset_t, Event *>::iterator ev_pos;
+ // a container of pointers into ev, indexed by note id
+ // used for deleting, updating notes
+ std::map<id_t, iter_t> idmap;
int steps;
- TamTamSound * tt;
+ int playing; //true means that step() works, else step() is no-op
- EvLoop(CSOUND * cs, TamTamSound * tt) : tick_prev(0), tickMax(1), rtick(0.0), ev(), ev_pos(ev.end()), csound(cs), mutex(NULL), steps(0), tt(tt)
+ Loop() : tick_prev(0), tickMax(1), rtick(0.0), ev(), ev_pos(ev.end()), steps(0), playing(0)
{
- setTickDuration(0.05);
- mutex = csoundCreateMutex(0);
- }
- ~EvLoop()
- {
- csoundLockMutex(mutex);
- for (iter_t i = ev.begin(); i != ev.end(); ++i)
- {
- delete i->second;
- }
- csoundUnlockMutex(mutex);
- csoundDestroyMutex(mutex);
}
- void clear()
+ ~Loop()
{
- csoundLockMutex(mutex);
+ //TODO: send these events to a recycling queue, don't erase them
for (iter_t i = ev.begin(); i != ev.end(); ++i)
{
delete i->second;
}
- ev.erase(ev.begin(), ev.end());
- ev_pos = ev.end();
- idmap.erase(idmap.begin(), idmap.end());
- csoundUnlockMutex(mutex);
}
void deactivateAll()
{
- csoundLockMutex(mutex);
for (iter_t i = ev.begin(); i != ev.end(); ++i)
{
i->second->activate_cmd(0);
}
- csoundUnlockMutex(mutex);
}
- int getTick()
+ MYFLT getTickf()
{
- return (int)rtick % tickMax;
- }
- float getTickf(bool mod)
- {
- if (mod)
- {
- return fmod(rtick, (MYFLT)tickMax);
- }
- else
- {
- return rtick;
- }
+ return fmod(rtick, (MYFLT)tickMax);
}
void setNumTicks(int nticks)
{
tickMax = nticks;
- if ((int)rtick > nticks)
+ MYFLT fnticks = nticks;
+ if (rtick > fnticks)
{
- int t = (int)rtick % nticks;
- rtick = t;
+ rtick = fmodf(rtick, fnticks);
}
}
- void setTick(int t)
+ void setTickf(float t)
{
- t = t % tickMax;
- rtick = (MYFLT)(t % tickMax);
- //TODO: binary search would be faster
- csoundLockMutex(mutex);
- ev_pos = ev.lower_bound( t );
- csoundUnlockMutex(mutex);
- }
- void setTickDuration(MYFLT d)
- {
- if (!csound) {
- if (_debug && (VERBOSE > 1)) fprintf(_debug, "skipping setTickDuration, csound==NULL\n");
- return;
- }
- secs_per_tick = d;
+ rtick = fmodf(t, (MYFLT) tickMax);
+ ev_pos = ev.lower_bound( (int) rtick );
}
/** advance in play loop by rtick_inc ticks, possibly generate some
* csoundScoreEvent calls.
*/
- void step(MYFLT rtick_inc )
+ void step(MYFLT rtick_inc, MYFLT secs_per_tick , CSOUND * csound)
{
+ if (!playing) return;
rtick += rtick_inc;
int tick = (int)rtick % tickMax;
if (tick == tick_prev) return;
- csoundLockMutex(mutex);
int events = 0;
int loop0 = 0;
int loop1 = 0;
- const int eventMax = 8; //NOTE: events beyond this number will be ignored!!!
if (!ev.empty())
{
if (steps && (tick < tick_prev)) // should be true only after the loop wraps (not after insert)
@@ -268,7 +231,7 @@ struct EvLoop
while (ev_pos != ev.end())
{
if (_debug && (VERBOSE > 3)) ev_pos->second->ev_print(_debug);
- if (events < eventMax) ev_pos->second->event(csound, secs_per_tick);
+ if (events < STEP_eventMax) ev_pos->second->event(csound, secs_per_tick);
++ev_pos;
++events;
++loop0;
@@ -278,92 +241,250 @@ struct EvLoop
while ((ev_pos != ev.end()) && (tick >= ev_pos->first))
{
if (_debug && (VERBOSE > 3)) ev_pos->second->ev_print(_debug);
- if (events < eventMax) ev_pos->second->event(csound, secs_per_tick);
+ if (events < STEP_eventMax) ev_pos->second->event(csound, secs_per_tick);
++ev_pos;
++events;
++loop1;
}
}
- csoundUnlockMutex(mutex);
tick_prev = tick;
- if (_debug && (VERBOSE>1) && (events >= eventMax)) fprintf(_debug, "WARNING: %i/%i events at once (%i, %i)\n", events,ev.size(),loop0,loop1);
+ if (_debug && (VERBOSE>1) && (events >= STEP_eventMax)) fprintf(_debug, "WARNING: %i/%i events at once (%i, %i)\n", events,ev.size(),loop0,loop1);
++steps;
}
void addEvent(int id, char type, MYFLT * p, int np, bool in_ticks, bool active)
{
- ev_t * e = new ev_t(type, p, np, in_ticks, active);
+ Event * e = new Event(type, p, np, in_ticks, active);
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 && (VERBOSE > 0)) fprintf(_debug, "ERROR: skipping request to add duplicate note %i\n", id);
+ g_log->printf(1, "%s duplicate note %i\n", __FUNCTION__, id);
}
}
void delEvent(int id)
{
idmap_t id_iter = idmap.find(id);
- if (id_iter == idmap.end())
- {
- if (_debug && (VERBOSE > 0)) fprintf(_debug, "ERROR: delEvent request for unknown note %i\n", id);
- }
- else
+ if (id_iter != idmap.end())
{
- 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);
+ }
+ else
+ {
+ g_log->printf( 1, "%s unknown note %i\n", __FUNCTION__, id);
}
}
void updateEvent(int id, int idx, float val, int activate_cmd)
{
idmap_t id_iter = idmap.find(id);
- if (id_iter == idmap.end())
+ if (id_iter != idmap.end())
{
- if (_debug && (VERBOSE > 0)) fprintf(_debug, "ERROR: updateEvent request for unknown note %i\n", id);
- return;
- }
+ //this is a new id
+ iter_t e_iter = id_iter->second;
+ Event * e = e_iter->second;
+ int onset = e->onset;
+ e->update(idx, val);
+ e->activate_cmd(activate_cmd);
+ if (onset != e->onset)
+ {
+ ev.erase(e_iter);
- //this is a new id
- csoundLockMutex(mutex);
- iter_t e_iter = id_iter->second;
- ev_t * e = e_iter->second;
- int onset = e->onset;
- e->update(idx, val);
- e->activate_cmd(activate_cmd);
- if (onset != e->onset)
+ 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;
+ }
+ }
+ else
{
- ev.erase(e_iter);
+ g_log->printf(1, "%s unknown note %i\n", __FUNCTION__, id);
+ }
+ }
+ void reset()
+ {
+ steps = 0;
+ }
+ void setPlaying(int tf)
+ {
+ playing = tf;
+ }
+};
- e_iter = ev.insert(pair_t(e->onset, e));
+/** management of loops */
+struct Music
+{
+ typedef int loopIdx_t;
+ typedef std::map<int, Loop * > eventMap_t;
- //TODO: optimize by thinking about whether to do ev_pos = e_iter
- ev_pos = ev.upper_bound( tick_prev );
- idmap[id] = e_iter;
+ eventMap_t loop;
+ int loop_nextIdx;
+ void * mutex; //modification and playing of loops cannot be interwoven
+
+ Music() :
+ loop(),
+ loop_nextIdx(0),
+ mutex(csoundCreateMutex(0))
+ {
+ }
+ ~Music()
+ {
+ for (eventMap_t::iterator i = loop.begin(); i != loop.end(); ++i)
+ {
+ delete i->second;
+ }
+ csoundDestroyMutex(mutex);
+ }
+
+ void step(MYFLT amt, MYFLT secs_per_tick, CSOUND * csound)
+ {
+ csoundLockMutex(mutex);
+ for (eventMap_t::iterator i = loop.begin(); i != loop.end(); ++i)
+ {
+ i->second->step(amt, secs_per_tick, csound);
}
csoundUnlockMutex(mutex);
}
- void reset()
+
+ /** allocate a new loop, and return its index */
+ loopIdx_t alloc()
{
- steps = 0;
+ csoundLockMutex(mutex);
+ //find a loop_nextIdx that isn't in loop map already
+ while ( loop.find( loop_nextIdx) != loop.end()) ++loop_nextIdx;
+ loop[loop_nextIdx] = new Loop();
+ csoundUnlockMutex(mutex);
+ return loop_nextIdx;
+ }
+ /** de-allocate a loop */
+ void destroy(loopIdx_t loopIdx)
+ {
+ if (loop.find(loopIdx) != loop.end())
+ {
+ csoundLockMutex(mutex);
+ //TODO: save the note events to a cache for recycling
+ delete loop[loopIdx];
+ loop.erase(loopIdx);
+ csoundUnlockMutex(mutex);
+ }
+ else
+ {
+ g_log->printf(1, "%s() called on non-existant loop %i\n", __FUNCTION__ , loopIdx);
+ }
+ }
+ /** set the playing flag of the given loop */
+ void playing(loopIdx_t loopIdx, int tf)
+ {
+ if (loop.find(loopIdx) != loop.end())
+ {
+ csoundLockMutex(mutex);
+ loop[loopIdx]->setPlaying(tf);
+ csoundUnlockMutex(mutex);
+ }
+ else
+ {
+ g_log->printf(1, "%s() called on non-existant loop %i\n", __FUNCTION__ , loopIdx);
+ }
+ }
+ /** set the playing flag of the given loop */
+ void addEvent(loopIdx_t loopIdx, int eventId, char type, MYFLT * p, int np, bool in_ticks, bool active)
+ {
+ if (loop.find(loopIdx) != loop.end())
+ {
+ csoundLockMutex(mutex);
+ loop[loopIdx]->addEvent(eventId, type, p, np, in_ticks, active);
+ csoundUnlockMutex(mutex);
+ }
+ else
+ {
+ g_log->printf(1, "%s() called on non-existant loop %i\n", __FUNCTION__ , loopIdx);
+ }
+ }
+ void delEvent(loopIdx_t loopIdx, int eventId)
+ {
+ if (loop.find(loopIdx) != loop.end())
+ {
+ csoundLockMutex(mutex);
+ loop[loopIdx]->delEvent(eventId);
+ csoundUnlockMutex(mutex);
+ }
+ else
+ {
+ g_log->printf(1, "%s() called on non-existant loop %i\n", __FUNCTION__ , loopIdx);
+ }
+ }
+ void updateEvent(loopIdx_t loopIdx, int eventId, int pIdx, float pVal, int activate_cmd)
+ {
+ if (loop.find(loopIdx) != loop.end())
+ {
+ csoundLockMutex(mutex);
+ loop[loopIdx]->updateEvent(eventId, pIdx, pVal, activate_cmd);
+ csoundUnlockMutex(mutex);
+ }
+ else
+ {
+ g_log->printf(1, "%s() called on non-existant loop %i\n", __FUNCTION__ , loopIdx);
+ }
+ }
+ MYFLT getTickf(loopIdx_t loopIdx)
+ {
+ if (loop.find(loopIdx) != loop.end())
+ {
+ return loop[loopIdx]->getTickf();
+ }
+ else
+ {
+ g_log->printf(1, "%s() called on non-existant loop %i\n", __FUNCTION__ , loopIdx);
+ return 0.0;
+ }
}
+ void setTickf(loopIdx_t loopIdx, MYFLT tickf)
+ {
+ if (loop.find(loopIdx) != loop.end())
+ {
+ loop[loopIdx]->setTickf(tickf);
+ }
+ else
+ {
+ g_log->printf(1, "%s() called on non-existant loop %i\n", __FUNCTION__ , loopIdx);
+ }
+ }
+ void setNumTicks(loopIdx_t loopIdx, int numTicks)
+ {
+ if (loop.find(loopIdx) != loop.end())
+ {
+ loop[loopIdx]->setNumTicks(numTicks);
+ }
+ else
+ {
+ g_log->printf(1, "%s() called on non-existant loop %i\n", __FUNCTION__ , loopIdx);
+ }
+ }
+ void deactivateAll(loopIdx_t loopIdx)
+ {
+ if (loop.find(loopIdx) != loop.end())
+ {
+ loop[loopIdx]->deactivateAll();
+ }
+ else
+ {
+ g_log->printf(1, "%s() called on non-existant loop %i\n", __FUNCTION__ , loopIdx);
+ }
+ }
+
};
/**
@@ -381,10 +502,13 @@ struct TamTamSound
enum {CONTINUE, STOP} PERF_STATUS;
/** our csound object, NULL iff there was a problem creating it */
CSOUND * csound;
+ /** our note sources */
+ Music music;
- EvLoop * loop;
- /** a flag, true iff the thread should play&advance the loop */
- int thread_playloop;
+ MYFLT secs_per_tick;
+ MYFLT ticks_per_period;
+ MYFLT tick_adjustment; //the default time increment in thread_fn
+ MYFLT tick_total;
/** the upsampling ratio from csound */
unsigned int csound_ksmps;
@@ -394,21 +518,20 @@ struct TamTamSound
unsigned int period_per_buffer; //should be 2
int up_ratio; //if the hardware only supports a small integer multiple of our effective samplerate, do a real-time conversion
- MYFLT ticks_per_period, tick_adjustment; //the default time increment in thread_fn
-
log_t * ll;
SystemStuff * sys_stuff;
TamTamSound(log_t * ll, char * orc, snd_pcm_uframes_t period0, unsigned int ppb, int ksmps, int framerate )
: ThreadID(NULL), PERF_STATUS(STOP), csound(NULL),
- loop(NULL), thread_playloop(0),
+ music(),
+ ticks_per_period(0.0),
+ tick_adjustment(0.0),
+ tick_total(0.0),
csound_ksmps(ksmps), //must agree with the orchestra file
csound_frame_rate(framerate), //must agree with the orchestra file
period0(period0),
period_per_buffer(ppb),
up_ratio(1),
- ticks_per_period(1.0),
- tick_adjustment(0.0),
ll( ll ),
sys_stuff(NULL)
{
@@ -441,14 +564,13 @@ struct TamTamSound
ll->printf( "ERROR: csoundCompile of orchestra %s failed with code %i\n", orc, result);
}
free(argv);
- loop = new EvLoop(csound, this);
+ setTickDuration(0.05);
}
~TamTamSound()
{
if (csound)
{
stop();
- delete loop;
ll->printf(2, "Going for csoundDestroy\n");
csoundDestroy(csound);
}
@@ -456,6 +578,11 @@ struct TamTamSound
if (sys_stuff) delete sys_stuff;
delete ll;
}
+ bool good()
+ {
+ return csound != NULL;
+ }
+
uintptr_t thread_fn()
{
assert(csound);
@@ -482,6 +609,8 @@ struct TamTamSound
int up_pos = 0;
int ratio_pos = 0;
+ tick_total = 0.0f;
+
while (PERF_STATUS == CONTINUE)
{
if ( do_upsample ) //fill one period of audio buffer data by 0 or more calls to csound
@@ -528,17 +657,16 @@ struct TamTamSound
if (0 > sys_stuff->writebuf(csound_nframes,upbuf)) break;
}
- if (thread_playloop)
+ if (tick_adjustment > - ticks_per_period)
{
- if (tick_adjustment > - ticks_per_period)
- {
- loop->step(ticks_per_period + tick_adjustment);
- tick_adjustment = 0.0;
- }
- else
- {
- tick_adjustment += ticks_per_period;
- }
+ MYFLT tick_inc = ticks_per_period + tick_adjustment;
+ music.step( tick_inc, secs_per_tick, csound);
+ tick_adjustment = 0.0;
+ tick_total += tick_inc;
+ }
+ else
+ {
+ tick_adjustment += ticks_per_period;
}
++nloops;
}
@@ -587,6 +715,7 @@ struct TamTamSound
return 1;
}
+ /** pass an array event straight through to csound. only works if perf. thread is running */
void scoreEvent(char type, MYFLT * p, int np)
{
if (!csound) {
@@ -606,6 +735,7 @@ struct TamTamSound
}
csoundScoreEvent(csound, type, p, np);
}
+ /** pass a string event straight through to csound. only works if perf. thread is running */
void inputMessage(const char * msg)
{
if (!csound) {
@@ -620,11 +750,7 @@ struct TamTamSound
if (_debug &&(VERBOSE > 3)) fprintf(_debug, "%s\n", msg);
csoundInputMessage(csound, msg);
}
- bool good()
- {
- return csound != NULL;
- }
-
+ /** pass a setChannel command through to csound. only works if perf. thread is running */
void setChannel(const char * name, MYFLT vol)
{
if (!csound) {
@@ -645,113 +771,30 @@ struct TamTamSound
}
}
- void setMasterVolume(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, "masterVolume", CSOUND_CONTROL_CHANNEL | CSOUND_INPUT_CHANNEL)))
- *p = (MYFLT) vol;
- else
- {
- if (_debug && (VERBOSE >0)) fprintf(_debug, "ERROR: failed to set master volume\n");
- }
- }
-
- void setTrackVolume(MYFLT vol, int Id)
- {
- 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;
- char buf[128];
- sprintf( buf, "trackVolume%i", Id);
- if (_debug && (VERBOSE > 10)) fprintf(_debug, "DEBUG: setTrackvolume string [%s]\n", buf);
- if (!(csoundGetChannelPtr(csound, &p, buf, CSOUND_CONTROL_CHANNEL | CSOUND_INPUT_CHANNEL)))
- *p = (MYFLT) vol;
- else
- {
- if (_debug) fprintf(_debug, "ERROR: failed to set track volume\n");
- }
- }
-
- void setTrackpadX(MYFLT value)
- {
- 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, "trackpadX", CSOUND_CONTROL_CHANNEL | CSOUND_INPUT_CHANNEL)))
- *p = (MYFLT) value;
- else
- {
- if (_debug && (VERBOSE > 0)) fprintf(_debug, "ERROR: failed to set trackpad X value\n");
- }
- }
-
- void setTrackpadY(MYFLT value)
- {
- 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, "trackpadY", CSOUND_CONTROL_CHANNEL | CSOUND_INPUT_CHANNEL)))
- *p = (MYFLT) value;
- else
- {
- if (_debug && (VERBOSE >0)) fprintf(_debug, "ERROR: failed to set trackpad Y value\n");
- }
- }
- void loopPlaying(int tf)
+ /** adjust the global tick value by this much */
+ void adjustTick(MYFLT dtick)
{
- thread_playloop= tf;
- if (tf) loop->reset();
+ tick_adjustment += dtick;
}
-
- void setTickDuration(MYFLT secs_per_tick )
+ void setTickDuration(MYFLT d )
{
- if (loop) loop->setTickDuration( secs_per_tick);
+ secs_per_tick = d;
ticks_per_period = csound_period_size / ( secs_per_tick * csound_frame_rate);
ll->printf( 3, "INFO: duration %lf := ticks_per_period %lf\n", secs_per_tick , ticks_per_period);
}
- void adjustTick(MYFLT dtick)
+ MYFLT getTickf()
{
- tick_adjustment += dtick;
+ return tick_total + tick_adjustment;
}
};
static void cleanup(void)
{
- if (sc_tt)
+ if (g_tt)
{
- delete sc_tt;
- sc_tt = NULL;
+ delete g_tt;
+ g_tt = NULL;
}
}
@@ -765,10 +808,10 @@ DECL(sc_destroy)
{
return NULL;
}
- if (sc_tt)
+ if (g_tt)
{
- delete sc_tt;
- sc_tt = NULL;
+ delete g_tt;
+ g_tt = NULL;
if (_debug) fclose(_debug);
}
RetNone;
@@ -798,9 +841,10 @@ DECL(sc_initialize) //(char * csd)
fprintf(stderr, "Logging disabled on purpose\n");
}
g_log = new log_t(_debug, VERBOSE);
- sc_tt = new TamTamSound(g_log, str, period, ppb, ksmps, framerate);
+ g_tt = new TamTamSound(g_log, str, period, ppb, ksmps, framerate);
+ g_music = & g_tt->music;
atexit(&cleanup);
- if (sc_tt->good())
+ if (g_tt->good())
return Py_BuildValue("i", 0);
else
return Py_BuildValue("i", -1);
@@ -813,7 +857,7 @@ DECL(sc_start)
{
return NULL;
}
- return Py_BuildValue("i", sc_tt->start(ppb));
+ return Py_BuildValue("i", g_tt->start(ppb));
}
//stop csound rendering thread, disconnect from sound device, clear tables.
DECL(sc_stop)
@@ -822,7 +866,7 @@ DECL(sc_stop)
{
return NULL;
}
- return Py_BuildValue("i", sc_tt->stop());
+ return Py_BuildValue("i", g_tt->stop());
}
DECL(sc_scoreEvent) //(char type, farray param)
{
@@ -843,7 +887,7 @@ DECL(sc_scoreEvent) //(char type, farray param)
len = o->ob_type->tp_as_buffer->bf_getreadbuffer(o, 0, &ptr);
float * fptr = (float*)ptr;
size_t flen = len / sizeof(float);
- sc_tt->scoreEvent(ev_type, fptr, flen);
+ g_tt->scoreEvent(ev_type, fptr, flen);
Py_INCREF(Py_None);
return Py_None;
@@ -856,120 +900,100 @@ DECL(sc_scoreEvent) //(char type, farray param)
assert(!"not reached");
return NULL;
}
-DECL(sc_setChannel) //(float v)
+DECL (sc_inputMessage) //(const char *msg)
{
- const char * str;
- float v;
- if (!PyArg_ParseTuple(args, "sf", &str,&v))
+ char * msg;
+ if (!PyArg_ParseTuple(args, "s", &msg ))
{
return NULL;
}
- sc_tt->setChannel(str,v);
- Py_INCREF(Py_None);
- return Py_None;
+ g_tt->inputMessage(msg);
+ RetNone;
}
-DECL(sc_setMasterVolume) //(float v)
+DECL(sc_setChannel) //(string name, float value)
{
+ const char * str;
float v;
- if (!PyArg_ParseTuple(args, "f", &v))
+ if (!PyArg_ParseTuple(args, "sf", &str,&v))
{
return NULL;
}
- sc_tt->setMasterVolume(v);
+ g_tt->setChannel(str,v);
Py_INCREF(Py_None);
return Py_None;
}
-DECL(sc_setTrackVolume) //(float v)
+DECL(sc_getTickf) // () -> float
{
- float v;
- int i;
- if (!PyArg_ParseTuple(args, "fi", &v, &i))
+ if (!PyArg_ParseTuple(args, ""))
{
return NULL;
}
- sc_tt->setTrackVolume(v,i);
- Py_INCREF(Py_None);
- return Py_None;
+ return Py_BuildValue("f", g_tt->getTickf());
}
-DECL(sc_setTrackpadX) //(float v)
+DECL(sc_adjustTick) // (MYFLT ntick)
{
- float v;
- if (!PyArg_ParseTuple(args, "f", &v))
+ float spt;
+ if (!PyArg_ParseTuple(args, "f", &spt ))
{
return NULL;
}
- sc_tt->setTrackpadX(v);
- Py_INCREF(Py_None);
- return Py_None;
+ g_tt->adjustTick(spt);
+ RetNone;
}
-DECL(sc_setTrackpadY) //(float v)
+DECL(sc_setTickDuration) // (MYFLT secs_per_tick)
{
- float v;
- if (!PyArg_ParseTuple(args, "f", &v))
+ float spt;
+ if (!PyArg_ParseTuple(args, "f", &spt ))
{
return NULL;
}
- sc_tt->setTrackpadY(v);
- Py_INCREF(Py_None);
- return Py_None;
+ g_tt->setTickDuration(spt);
+ RetNone;
}
-DECL(sc_loop_getTick) // -> float
+DECL(sc_loop_new) // () -> int
{
- if (!PyArg_ParseTuple(args, "" ))
- {
- return NULL;
- }
- return Py_BuildValue("f", sc_tt->loop ? sc_tt->loop->getTickf(true):-1.0f);
+ if (!PyArg_ParseTuple(args, "" )) return NULL;
+ return Py_BuildValue("i", g_music->alloc());
}
-DECL(sc_loop_setNumTicks) //(int nticks)
+DECL(sc_loop_delete) // (int loopIdx)
{
- int nticks;
- if (!PyArg_ParseTuple(args, "i", &nticks ))
- {
- return NULL;
- }
- if (sc_tt->loop) sc_tt->loop->setNumTicks(nticks);
+ int loopIdx;
+ if (!PyArg_ParseTuple(args, "i", &loopIdx )) return NULL;
+ g_music->destroy(loopIdx);
RetNone;
}
-DECL(sc_loop_setTick) // (int ctick)
+DECL(sc_loop_getTickf) // (int loopIdx) -> float
{
- int ctick;
- if (!PyArg_ParseTuple(args, "i", &ctick ))
+ int idx;
+ if (!PyArg_ParseTuple(args, "i", &idx ))
{
return NULL;
}
- if (sc_tt->loop) sc_tt->loop->setTick(ctick);
- RetNone;
+ return Py_BuildValue("f", g_music->getTickf(idx));
}
-DECL(sc_loop_setTickDuration) // (MYFLT secs_per_tick)
+DECL(sc_loop_setNumTicks) //(int loopIdx, int nticks)
{
- float spt;
- if (!PyArg_ParseTuple(args, "f", &spt ))
- {
- return NULL;
- }
- sc_tt->setTickDuration(spt);
+ int loopIdx;
+ int nticks;
+ if (!PyArg_ParseTuple(args, "ii", &loopIdx, &nticks )) return NULL;
+ g_music->setNumTicks(loopIdx, nticks);
RetNone;
}
-DECL(sc_loop_adjustTick) // (MYFLT ntick)
+DECL(sc_loop_setTickf) // (int loopIdx, float pos)
{
- float spt;
- if (!PyArg_ParseTuple(args, "f", &spt ))
- {
- return NULL;
- }
- sc_tt->adjustTick(spt);
+ int loopIdx;
+ MYFLT pos;
+ if (!PyArg_ParseTuple(args, "if", &loopIdx, &pos )) return NULL;
+ g_music->setTickf(loopIdx, pos);
RetNone;
}
-DECL(sc_loop_addScoreEvent) // (int id, int duration_in_ticks, char type, farray param)
+DECL(sc_loop_addScoreEvent) // (int loopIdx, int id, int duration_in_ticks, char type, farray param)
{
- int qid, inticks, active;
+ int loopIdx, qid, inticks, active;
char ev_type;
PyObject *o;
- if (!PyArg_ParseTuple(args, "iiicO", &qid, &inticks, &active, &ev_type, &o ))
- {
- return NULL;
- }
+ if (!PyArg_ParseTuple(args, "iiiicO", &loopIdx, &qid, &inticks, &active, &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)))
@@ -981,10 +1005,10 @@ DECL(sc_loop_addScoreEvent) // (int id, int duration_in_ticks, char type, farray
len = o->ob_type->tp_as_buffer->bf_getreadbuffer(o, 0, &ptr);
float * fptr = (float*)ptr;
size_t flen = len / sizeof(float);
- if (sc_tt->loop) sc_tt->loop->addEvent(qid, ev_type, fptr, flen, inticks, active);
- Py_INCREF(Py_None);
- return Py_None;
+ g_music->addEvent(loopIdx, qid, ev_type, fptr, flen, inticks, active);
+
+ RetNone;
}
else
{
@@ -994,65 +1018,38 @@ DECL(sc_loop_addScoreEvent) // (int id, int duration_in_ticks, char type, farray
assert(!"not reached");
return NULL;
}
-DECL(sc_loop_delScoreEvent) // (int id)
+DECL(sc_loop_delScoreEvent) // (int loopIdx, int id)
{
- int id;
- if (!PyArg_ParseTuple(args, "i", &id ))
+ int loopIdx, id;
+ if (!PyArg_ParseTuple(args, "ii", &loopIdx, &id ))
{
return NULL;
}
- if (sc_tt->loop) sc_tt->loop->delEvent(id);
+ g_music->delEvent(loopIdx, id);
RetNone;
}
-DECL(sc_loop_updateEvent) // (int id)
+DECL(sc_loop_updateEvent) // (int loopIdx, int id, int paramIdx, float paramVal, int activate_cmd))
{
- int id;
+ int loopIdx, eventId;
int idx;
float val;
int cmd;
- if (!PyArg_ParseTuple(args, "iifi", &id, &idx, &val, &cmd))
- {
- return NULL;
- }
- if (sc_tt->loop) sc_tt->loop->updateEvent(id, idx, val, cmd);
+ if (!PyArg_ParseTuple(args, "iiifi", &loopIdx, &eventId, &idx, &val, &cmd)) return NULL;
+ g_music->updateEvent(loopIdx, eventId, idx, val, cmd);
RetNone;
}
DECL(sc_loop_deactivate_all) // (int id)
{
- if (!PyArg_ParseTuple(args, ""))
- {
- return NULL;
- }
- if (sc_tt->loop) sc_tt->loop->deactivateAll();
+ int loopIdx;
+ if (!PyArg_ParseTuple(args, "i", &loopIdx)) return NULL;
+ g_music->deactivateAll(loopIdx);
RetNone;
}
-DECL(sc_loop_clear)
+DECL(sc_loop_playing) // (int loopIdx, int tf)
{
- if (!PyArg_ParseTuple(args, "" ))
- {
- return NULL;
- }
- if (sc_tt->loop) sc_tt->loop->clear();
- RetNone;
-}
-DECL(sc_loop_playing) // (int tf)
-{
- int i;
- if (!PyArg_ParseTuple(args, "i", &i ))
- {
- return NULL;
- }
- if (sc_tt->loop) sc_tt->loopPlaying(i);
- RetNone;
-}
-DECL (sc_inputMessage) //(const char *msg)
-{
- char * msg;
- if (!PyArg_ParseTuple(args, "s", &msg ))
- {
- return NULL;
- }
- sc_tt->inputMessage(msg);
+ int loopIdx, tf;
+ if (!PyArg_ParseTuple(args, "ii", &loopIdx, &tf )) return NULL;
+ g_music->playing(loopIdx, tf);
RetNone;
}
@@ -1062,24 +1059,25 @@ static PyMethodDef SpamMethods[] = {
MDECL(sc_initialize),
MDECL(sc_start),
MDECL(sc_stop),
- MDECL(sc_scoreEvent),
+
MDECL(sc_setChannel),
- MDECL(sc_setMasterVolume),
- MDECL(sc_setTrackVolume),
- MDECL(sc_setTrackpadX),
- MDECL(sc_setTrackpadY),
- MDECL(sc_loop_getTick),
+ MDECL(sc_inputMessage),
+ MDECL(sc_scoreEvent),
+
+ MDECL(sc_getTickf),
+ MDECL(sc_adjustTick),
+ MDECL(sc_setTickDuration),
+
+ MDECL(sc_loop_new),
+ MDECL(sc_loop_delete),
+ MDECL(sc_loop_getTickf),
+ MDECL(sc_loop_setTickf),
MDECL(sc_loop_setNumTicks),
- MDECL(sc_loop_setTick),
- MDECL(sc_loop_setTickDuration),
- MDECL(sc_loop_adjustTick),
MDECL(sc_loop_delScoreEvent),
MDECL(sc_loop_addScoreEvent),
MDECL(sc_loop_updateEvent),
- MDECL(sc_loop_clear),
MDECL(sc_loop_deactivate_all),
MDECL(sc_loop_playing),
- MDECL(sc_inputMessage),
{NULL, NULL, 0, NULL} /*end of list */
};
diff --git a/Util/Clooper/aclient.so b/Util/Clooper/aclient.so
index 97c9cbb..996e9e3 100755
--- a/Util/Clooper/aclient.so
+++ b/Util/Clooper/aclient.so
Binary files differ
diff --git a/Util/Clooper/audio.cpp b/Util/Clooper/audio.cpp
index e93ea54..343bc99 100644
--- a/Util/Clooper/audio.cpp
+++ b/Util/Clooper/audio.cpp
@@ -1,3 +1,6 @@
+#ifndef AUDIO_HXX
+#define AUDIO_HXX
+
/*
* Latency test program
*
@@ -216,3 +219,5 @@ open_error:
}
};
#undef ERROR_HERE
+
+#endif
diff --git a/Util/Clooper/log.cpp b/Util/Clooper/log.cpp
index 269433d..d4a8c72 100644
--- a/Util/Clooper/log.cpp
+++ b/Util/Clooper/log.cpp
@@ -1,3 +1,5 @@
+#ifndef LOG_HXX
+#define LOG_HXX
#include <stdarg.h>
#include <stdio.h>
@@ -46,3 +48,5 @@ struct log_t
}
}
};
+
+#endif
diff --git a/miniTamTam/miniTamTamMain.py b/miniTamTam/miniTamTamMain.py
index f8e3232..ac134d6 100644
--- a/miniTamTam/miniTamTamMain.py
+++ b/miniTamTam/miniTamTamMain.py
@@ -70,7 +70,7 @@ class miniTamTamMain(SubActivity):
self.drumFillin = Fillin( self.beat, self.tempo, self.rythmInstrument, self.reverb, self.drumVolume )
self.sequencer= MiniSequencer(self.recordStateButton, self.recordOverSensitivity)
self.loop = Loop(self.beat, sqrt( self.instVolume*0.01 ))
- self.csnd.loopSetTempo(self.tempo)
+ self.csnd.setTempo(self.tempo)
self.noteList = []
time.sleep(0.001) # why?
self.trackpad = Trackpad( self )
@@ -503,7 +503,7 @@ class miniTamTamMain(SubActivity):
self.tempo = val
self.beatDuration = 60.0/self.tempo
self.ticksPerSecond = Config.TICKS_PER_BEAT*self.tempo/60.0
- self.csnd.loopSetTempo(self.tempo)
+ self.csnd.setTempo(self.tempo)
self.sequencer.tempo = self.tempo
self.drumFillin.setTempo(self.tempo)
@@ -831,7 +831,7 @@ class miniTamTamMain(SubActivity):
correct += ticksPerLoop
#print "correct:: %f ticks, %f ticks in, %f expected, %f err, correct %f" % (curTick, curTicksIn, ticksIn, err, correct)
if abs(err) > 0.25:
- self.csnd.loopAdjustTick(-err)
+ self.csnd.adjustTick(-err)
if __name__ == "__main__":