diff options
author | James <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) |
commit | 24f776ab43f85160f05de7f67539a5b27f9b650e (patch) | |
tree | bf931076f35c4a5ffbad79ed90213f55a40793a3 | |
parent | bb8b6f9157c4a53c8ac024e66e71a30bc554427d (diff) |
clooper modifs to support multiple independent loops.... compiles
-rw-r--r-- | Util/Clooper/aclient.cpp | 561 | ||||
-rw-r--r-- | Util/Clooper/audio.cpp | 5 | ||||
-rw-r--r-- | Util/Clooper/log.cpp | 4 |
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 |