Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/Util/Clooper
diff options
context:
space:
mode:
authorJames <olpc@xo-05-28-3A.localdomain>2007-08-26 01:57:04 (GMT)
committer James <olpc@xo-05-28-3A.localdomain>2007-08-26 01:57:04 (GMT)
commit24f776ab43f85160f05de7f67539a5b27f9b650e (patch)
treebf931076f35c4a5ffbad79ed90213f55a40793a3 /Util/Clooper
parentbb8b6f9157c4a53c8ac024e66e71a30bc554427d (diff)
clooper modifs to support multiple independent loops.... compiles
Diffstat (limited to 'Util/Clooper')
-rw-r--r--Util/Clooper/aclient.cpp561
-rw-r--r--Util/Clooper/audio.cpp5
-rw-r--r--Util/Clooper/log.cpp4
3 files changed, 352 insertions, 218 deletions
diff --git a/Util/Clooper/aclient.cpp b/Util/Clooper/aclient.cpp
index 6ba2a72..b17e848 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; //this is locked when changing ev
- int steps; //
- TamTamSound * tt;
+ // 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;
+ 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()
+ ~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;
}
- csoundUnlockMutex(mutex);
- csoundDestroyMutex(mutex);
- }
- void clear()
- {
- csoundLockMutex(mutex);
- 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); //not really necessary I think
for (iter_t i = ev.begin(); i != ev.end(); ++i)
{
i->second->activate_cmd(0);
}
- csoundUnlockMutex(mutex);
- }
- int getTick()
- {
- return (int)rtick % tickMax;
}
- float getTickf(bool mod)
+ MYFLT getTickf()
{
- 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,246 @@ 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 (id_iter != idmap.end())
{
- if (_debug && (VERBOSE > 0)) fprintf(_debug, "ERROR: delEvent request for unknown note %i\n", id);
- }
- else
- {
- csoundLockMutex(mutex);
iter_t e_iter = id_iter->second;//idmap[id];
if (e_iter == ev_pos) ++ev_pos;
delete e_iter->second;
ev.erase(e_iter);
idmap.erase(id_iter);
-
- csoundUnlockMutex(mutex);
+ }
+ 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()
+ {
+ 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 +498,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 +514,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 +560,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 +574,11 @@ struct TamTamSound
if (sys_stuff) delete sys_stuff;
delete ll;
}
+ bool good()
+ {
+ return csound != NULL;
+ }
+
uintptr_t thread_fn()
{
assert(csound);
@@ -482,6 +605,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 +653,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 +711,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 +731,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 +746,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,31 +767,30 @@ struct TamTamSound
}
}
- 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;
}
}
@@ -683,10 +804,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;
@@ -716,9 +837,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);
@@ -731,7 +853,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)
@@ -740,7 +862,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)
{
@@ -761,7 +883,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;
@@ -782,36 +904,41 @@ DECL(sc_setChannel) //(float v)
{
return NULL;
}
- sc_tt->setChannel(str,v);
+ g_tt->setChannel(str,v);
Py_INCREF(Py_None);
return Py_None;
}
-DECL(sc_loop_getTick) // -> float
+DECL(sc_getTickf) // () -> float
{
- if (!PyArg_ParseTuple(args, "" ))
+ if (!PyArg_ParseTuple(args, ""))
{
return NULL;
}
- return Py_BuildValue("f", sc_tt->loop ? sc_tt->loop->getTickf(true):-1.0f);
+ return Py_BuildValue("f", g_tt->getTickf());
}
-DECL(sc_loop_setNumTicks) //(int nticks)
+DECL(sc_loop_getTickf) // (int loopIdx) -> float
{
- int nticks;
- if (!PyArg_ParseTuple(args, "i", &nticks ))
+ int idx;
+ if (!PyArg_ParseTuple(args, "i", &idx ))
{
return NULL;
}
- if (sc_tt->loop) sc_tt->loop->setNumTicks(nticks);
+ return Py_BuildValue("f", g_music->getTickf(idx));
+}
+DECL(sc_loop_setNumTicks) //(int loopIdx, int nticks)
+{
+ int loopIdx;
+ int nticks;
+ if (!PyArg_ParseTuple(args, "ii", &loopIdx, &nticks )) return NULL;
+ g_music->setNumTicks(loopIdx, nticks);
RetNone;
}
-DECL(sc_loop_setTick) // (int ctick)
+DECL(sc_loop_setTickf) // (int loopIdx, float pos)
{
- int ctick;
- if (!PyArg_ParseTuple(args, "i", &ctick ))
- {
- return NULL;
- }
- if (sc_tt->loop) sc_tt->loop->setTick(ctick);
+ int loopIdx;
+ MYFLT pos;
+ if (!PyArg_ParseTuple(args, "if", &loopIdx, &pos )) return NULL;
+ g_music->setTickf(loopIdx, pos);
RetNone;
}
DECL(sc_loop_setTickDuration) // (MYFLT secs_per_tick)
@@ -821,28 +948,26 @@ DECL(sc_loop_setTickDuration) // (MYFLT secs_per_tick)
{
return NULL;
}
- sc_tt->setTickDuration(spt);
+ g_tt->setTickDuration(spt);
RetNone;
}
-DECL(sc_loop_adjustTick) // (MYFLT ntick)
+DECL(sc_adjustTick) // (MYFLT ntick)
{
float spt;
if (!PyArg_ParseTuple(args, "f", &spt ))
{
return NULL;
}
- sc_tt->adjustTick(spt);
+ g_tt->adjustTick(spt);
RetNone;
}
DECL(sc_loop_addScoreEvent) // (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)))
@@ -854,10 +979,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
{
@@ -869,53 +994,48 @@ DECL(sc_loop_addScoreEvent) // (int id, int duration_in_ticks, char type, farray
}
DECL(sc_loop_delScoreEvent) // (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)
{
- 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_new)
{
- if (!PyArg_ParseTuple(args, "" ))
- {
- return NULL;
- }
- if (sc_tt->loop) sc_tt->loop->clear();
+ if (!PyArg_ParseTuple(args, "" )) return NULL;
+ return Py_BuildValue("i", g_music->alloc());
+}
+DECL(sc_loop_delete)
+{
+ int loopIdx;
+ if (!PyArg_ParseTuple(args, "i", &loopIdx )) return NULL;
+ g_music->destroy(loopIdx);
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);
+ int loopIdx, tf;
+ if (!PyArg_ParseTuple(args, "i", &loopIdx, &tf )) return NULL;
+ g_music->playing(loopIdx, tf);
RetNone;
}
DECL (sc_inputMessage) //(const char *msg)
@@ -925,7 +1045,7 @@ DECL (sc_inputMessage) //(const char *msg)
{
return NULL;
}
- sc_tt->inputMessage(msg);
+ g_tt->inputMessage(msg);
RetNone;
}
@@ -935,20 +1055,25 @@ static PyMethodDef SpamMethods[] = {
MDECL(sc_initialize),
MDECL(sc_start),
MDECL(sc_stop),
- MDECL(sc_scoreEvent),
+
MDECL(sc_setChannel),
- MDECL(sc_loop_getTick),
+ MDECL(sc_inputMessage),
+ MDECL(sc_scoreEvent),
+
+ MDECL(sc_getTickf),
+ MDECL(sc_adjustTick),
+
+ 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/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