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@localhost.localdomain>2007-02-19 06:46:31 (GMT)
committer James <olpc@localhost.localdomain>2007-02-19 06:46:31 (GMT)
commit85619d4504d98ee44a08ef0a1ae3a8c74dcaf9c8 (patch)
tree5621dc50a256cc77669a08ad6c4da46a6a45c979 /Util/Clooper
parent6205108acf91e48f7ea9c193ffc4a537afb976e0 (diff)
slightly better notes playback
Diffstat (limited to 'Util/Clooper')
-rw-r--r--Util/Clooper/Makefile38
-rw-r--r--Util/Clooper/SClient.py1
-rw-r--r--Util/Clooper/SoundClient.cpp378
-rw-r--r--Util/Clooper/SoundClient.h3
-rwxr-xr-xUtil/Clooper/_SClient.sobin133980 -> 173881 bytes
-rwxr-xr-xUtil/Clooper/sclient.sobin0 -> 137048 bytes
6 files changed, 295 insertions, 125 deletions
diff --git a/Util/Clooper/Makefile b/Util/Clooper/Makefile
index 87caf59..c2a246d 100644
--- a/Util/Clooper/Makefile
+++ b/Util/Clooper/Makefile
@@ -4,39 +4,11 @@ CFLAGS+=-g -Wall -Werror -fPIC -O3 -finline
PYTHON=/usr/include/python2.4
-all : _SClient.so cmd_csound
+all : sclient.so
-%.o: %.c %.h
- $(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@
-
-%.o: %.c
- $(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@
-
-%.o: %.cpp %.h
- $(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@
-
-clean :
- rm -f *.o _ttest.so _SClient.so
-
-cmd_csound: cmd_csound.cpp SoundClient.o
- g++ -o $@ $^ -lcsound
-
-SoundClient_wrap.c: SoundClient.i SoundClient.h
- swig -python $<
-
-SoundClient_wrap.o: SoundClient_wrap.c
- gcc -fPIC -I$(PYTHON) -o $@ -c $<
-
-_SClient.so : SoundClient_wrap.o SoundClient.o
- g++ -shared -o $@ $^ -lcsound
-
-ttest_wrap.c: ttest.i
- swig -python ttest.i
-
-ttest_wrap.o: ttest_wrap.c
- gcc -fPIC -I$(PYTHON) -o $@ -c $<
-
-_ttest.so : ttest_wrap.o ttest.o
- gcc -shared -o $@ $^
+sclient.so : SoundClient.cpp
+ g++ $(CFLAGS) -shared -o $@ $< -lpython2.4 -lcsound
+clean :
+ rm sclient.so
diff --git a/Util/Clooper/SClient.py b/Util/Clooper/SClient.py
index d27472b..70f4e0c 100644
--- a/Util/Clooper/SClient.py
+++ b/Util/Clooper/SClient.py
@@ -59,6 +59,7 @@ sc_inputMessage = _SClient.sc_inputMessage
sc_scoreEvent4 = _SClient.sc_scoreEvent4
sc_scoreEvent15 = _SClient.sc_scoreEvent15
sc_loop_addScoreEvent15 = _SClient.sc_loop_addScoreEvent15
+sc_loop_delScoreEvent = _SClient.sc_loop_delScoreEvent
sc_loop_clear = _SClient.sc_loop_clear
sc_loop_getTick = _SClient.sc_loop_getTick
sc_loop_playing = _SClient.sc_loop_playing
diff --git a/Util/Clooper/SoundClient.cpp b/Util/Clooper/SoundClient.cpp
index 6bc92eb..71dc705 100644
--- a/Util/Clooper/SoundClient.cpp
+++ b/Util/Clooper/SoundClient.cpp
@@ -1,3 +1,5 @@
+#include <python2.4/Python.h>
+
#include <pthread.h>
#include <stdio.h>
#include <time.h>
@@ -5,13 +7,18 @@
#include <sys/time.h>
#include <csound/csound.hpp>
-#include "SoundClient.h"
+//#include "SoundClient.h"
#include <vector>
#include <map>
#include <cmath>
using namespace std;
+static double pytime(const struct timeval * tv)
+{
+ return (double) tv->tv_sec + (double) tv->tv_usec / 1000000.0;
+}
+
struct ev_t
{
char type;
@@ -21,30 +28,18 @@ struct ev_t
MYFLT duration, attack, decay;
std::vector<MYFLT> param;
- ev_t(char type, bool in_ticks, MYFLT p1, MYFLT p2, MYFLT p3, MYFLT p4, MYFLT p5, MYFLT p6, MYFLT p7, MYFLT p8, MYFLT p9, MYFLT p10, MYFLT p11, MYFLT p12, MYFLT p13, MYFLT p14, MYFLT p15)
- : type(type), onset(0), time_in_ticks(in_ticks), param(15)
+ ev_t(char type, MYFLT * p, int np, bool in_ticks)
+ : type(type), onset(0), time_in_ticks(in_ticks), param(np)
{
- onset = (int) p2;
- duration = p3;
- attack = p9;
- decay = p10;
+ assert(np >= 4);
+ onset = (int) p[1];
+ duration = p[2];
+ attack = np > 8 ? p[8]: 0.0; //attack
+ decay = np > 9 ? p[9]: 0.0; //decay
prev_secs_per_tick = -1.0;
+ for (int i = 0; i < np; ++i) param[i] = p[i];
- param[0] = p1;
param[1] = 0.0; //onset
- param[2] = p3; //duration
- param[3] = p4; //pitch
- param[4] = p5; //reverbSend
- param[5] = p6; //amplitude
- param[6] = p7; //pan
- param[7] = p8; //table
- param[8] = p9; //attack
- param[9] = p10; //decay
- param[10] = p11;//filterType
- param[11] = p12;//filterCutoff
- param[12] = p13;//loopStart
- param[13] = p14;//loopEnd
- param[14] = p15;//crossDur
}
bool operator<(const ev_t &e) const
{
@@ -72,6 +67,8 @@ struct ev_t
};
struct EvLoop
{
+ FILE * _debug;
+
int tick_prev;
int tickMax;
MYFLT rtick;
@@ -79,12 +76,15 @@ struct EvLoop
MYFLT ticks_per_ksmp;
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;
- EvLoop(CSOUND * cs) : tick_prev(0), tickMax(1), rtick(0.0), ev(), ev_pos(ev.end()), csound(cs), mutex(NULL)
+ EvLoop(CSOUND * cs) : _debug(stderr), tick_prev(0), tickMax(1), rtick(0.0), ev(), ev_pos(ev.end()), csound(cs), mutex(NULL)
{
setTickDuration(0.05);
mutex = csoundCreateMutex(0);
@@ -180,12 +180,51 @@ struct EvLoop
tick_prev = tick;
if (logf && (events >= eventMax)) fprintf(logf, "WARNING: %i/%i events at once (%i, %i)\n", events,ev.size(),loop0,loop1);
}
- void addEvent(ev_t *e)
+ void addEvent(int id, char type, MYFLT * p, int np, bool in_ticks)
{
- csoundLockMutex(mutex);
- ev.insert(pair_t(e->onset, e));
- ev_pos = ev.upper_bound( tick_prev );
- csoundUnlockMutex(mutex);
+ ev_t * e = new ev_t(type, p, np, in_ticks);
+
+ 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) fprintf(_debug, "ERROR: skipping request to add duplicate note %i\n", id);
+ }
+ }
+ void delEvent(int id)
+ {
+ idmap_t id_iter = idmap.find(id);
+ if (id_iter == idmap.end())
+ {
+ if (_debug) fprintf(_debug, "ERROR: delEvent request for unknown note %i\n", id);
+ }
+ else
+ {
+ //this is a new id
+ csoundLockMutex(mutex);
+ iter_t e_iter = id_iter->second;//idmap[id];
+
+ delete e_iter->second;
+ ev.erase(e_iter);
+ idmap.erase(id_iter);
+
+ //TODO: optimize by thinking about whether to do ev_pos = e_iter
+ ev_pos = ev.upper_bound( tick_prev );
+
+ csoundUnlockMutex(mutex);
+ }
}
};
struct TamTamSound
@@ -226,10 +265,6 @@ struct TamTamSound
free(csound_orc);
if (_debug) fclose(_debug);
}
- static double pytime(const struct timeval * tv)
- {
- return (double) tv->tv_sec + (double) tv->tv_usec / 1000000.0;
- }
uintptr_t thread_fn()
{
struct timeval tv;
@@ -396,109 +431,270 @@ struct TamTamSound
TamTamSound * sc_tt = NULL;
-//call once at startup, should return 0
-int sc_initialize(char * csd)
+static void cleanup(void)
{
- sc_tt = new TamTamSound(csd);
- atexit(&sc_destroy);
- if (sc_tt->good()) return 0;
- else return -1;
+ if (sc_tt)
+ {
+ delete sc_tt;
+ sc_tt = NULL;
+ }
}
+
+#define DECL(s) static PyObject * s(PyObject * self, PyObject *args)
+#define RetNone Py_INCREF(Py_None); return Py_None;
+
//call once at end
-void sc_destroy()
+DECL(sc_destroy)
{
+ if (!PyArg_ParseTuple(args, ""))
+ {
+ return NULL;
+ }
if (sc_tt)
{
delete sc_tt;
sc_tt = NULL;
}
+ RetNone;
+}
+//call once at startup, should return 0
+DECL(sc_initialize) //(char * csd)
+{
+ char * str;
+ if (!PyArg_ParseTuple(args, "s", &str ))
+ {
+ return NULL;
+ }
+ sc_tt = new TamTamSound(str);
+ atexit(&cleanup);
+ if (sc_tt->good())
+ return Py_BuildValue("i", 0);
+ else
+ return Py_BuildValue("i", -1);
}
//compile the score, connect to device, start a sound rendering thread
-int sc_start()
+DECL(sc_start)
{
- return sc_tt->start();
+ if (!PyArg_ParseTuple(args, "" ))
+ {
+ return NULL;
+ }
+ return Py_BuildValue("i", sc_tt->start());
}
//stop csound rendering thread, disconnect from sound device, clear tables.
-int sc_stop()
+DECL(sc_stop)
{
- return sc_tt->stop();
+ if (!PyArg_ParseTuple(args, "" ))
+ {
+ return NULL;
+ }
+ return Py_BuildValue("i", sc_tt->stop());
}
-//set the output volume to given level. max volume is 100.0
-void sc_setMasterVolume(MYFLT v)
+DECL(sc_scoreEvent) //(char type, farray param)
{
+ char ev_type;
+ PyObject *o;
+ if (!PyArg_ParseTuple(args, "cO", &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)))
+ {
+ if (o->ob_type->tp_as_buffer->bf_getreadbuffer)
+ {
+ void * ptr;
+ size_t len;
+ len = o->ob_type->tp_as_buffer->bf_getreadbuffer(o, 0, &ptr);
+ fprintf(stderr, "writeable buffer of length %zu at %p\n", len, ptr);
+ float * fptr = (float*)ptr;
+ size_t flen = len / sizeof(float);
+ sc_tt->scoreEvent(ev_type, fptr, flen);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ else
+ {
+ assert(!"asdf");
+ }
+ }
+ assert(!"not reached");
+ return NULL;
+}
+DECL(sc_setMasterVolume) //(float v)
+{
+ float v;
+ if (!PyArg_ParseTuple(args, "f", &v))
+ {
+ return NULL;
+ }
sc_tt->setMasterVolume(v);
+ Py_INCREF(Py_None);
+ return Py_None;
}
-
-void sc_setTrackpadX(MYFLT v)
+DECL(sc_setTrackpadX) //(float v)
{
+ float v;
+ if (!PyArg_ParseTuple(args, "f", &v))
+ {
+ return NULL;
+ }
sc_tt->setTrackpadX(v);
+ Py_INCREF(Py_None);
+ return Py_None;
}
-
-void sc_setTrackpadY(MYFLT v)
+DECL(sc_setTrackpadY) //(float v)
{
+ float v;
+ if (!PyArg_ParseTuple(args, "f", &v))
+ {
+ return NULL;
+ }
sc_tt->setTrackpadY(v);
+ Py_INCREF(Py_None);
+ return Py_None;
}
-
-void sc_inputMessage(const char *msg)
+DECL(sc_loop_getTick) // -> int
{
- sc_tt->inputMessage(msg);
+ if (!PyArg_ParseTuple(args, "" ))
+ {
+ return NULL;
+ }
+ return Py_BuildValue("i", sc_tt->loop->getTick());
}
-void sc_scoreEvent4(char type, MYFLT p0, MYFLT p1, MYFLT p2, MYFLT p3)
+DECL(sc_loop_setNumTicks) //(int nticks)
{
- MYFLT p[4];
- p[0] = p0;
- p[1] = p1;
- p[2] = p2;
- p[3] = p3;
- sc_tt->scoreEvent(type, p, 4);
+ int nticks;
+ if (!PyArg_ParseTuple(args, "i", &nticks ))
+ {
+ return NULL;
+ }
+ sc_tt->loop->setNumTicks(nticks);
+ RetNone;
}
-void sc_scoreEvent15(char type, MYFLT p1, MYFLT p2, MYFLT p3, MYFLT p4, MYFLT p5, MYFLT p6, MYFLT p7, MYFLT p8, MYFLT p9, MYFLT p10, MYFLT p11, MYFLT p12, MYFLT p13, MYFLT p14, MYFLT p15)
+DECL(sc_loop_setTick) // (int ctick)
{
- MYFLT p[15];
- p[0] = p1;
- p[1] = p2;
- p[2] = p3;
- p[3] = p4;
- p[4] = p5;
- p[5] = p6;
- p[6] = p7;
- p[7] = p8;
- p[8] = p9;
- p[9] = p10;
- p[10] = p11;
- p[11] = p12;
- p[12] = p13;
- p[13] = p14;
- p[14] = p15;
- sc_tt->scoreEvent(type, p, 15);
+ int ctick;
+ if (!PyArg_ParseTuple(args, "i", &ctick ))
+ {
+ return NULL;
+ }
+ sc_tt->loop->setTick(ctick);
+ RetNone;
}
-
-int sc_loop_getTick()
+DECL(sc_loop_setTickDuration) // (MYFLT secs_per_tick)
{
- return sc_tt->loop->getTick();
+ float spt;
+ if (!PyArg_ParseTuple(args, "f", &spt ))
+ {
+ return NULL;
+ }
+ sc_tt->loop->setTickDuration(spt);
+ RetNone;
}
-void sc_loop_setNumTicks(int nticks)
+DECL(sc_loop_addScoreEvent) // (int id, int duration_in_ticks, char type, farray param)
{
- sc_tt->loop->setNumTicks(nticks);
+ int qid;
+ int inticks;
+ char ev_type;
+ PyObject *o;
+ if (!PyArg_ParseTuple(args, "iicO", &qid, &inticks, &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)))
+ {
+ if (o->ob_type->tp_as_buffer->bf_getreadbuffer)
+ {
+ void * ptr;
+ size_t len;
+ len = o->ob_type->tp_as_buffer->bf_getreadbuffer(o, 0, &ptr);
+ fprintf(stderr, "writeable buffer of length %zu at %p\n", len, ptr);
+ float * fptr = (float*)ptr;
+ size_t flen = len / sizeof(float);
+ sc_tt->loop->addEvent(qid, ev_type, fptr, flen, inticks);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ else
+ {
+ assert(!"asdf");
+ }
+ }
+ assert(!"not reached");
+ return NULL;
}
-void sc_loop_setTick(int ctick)
+DECL(sc_loop_delScoreEvent) // (int id)
{
- sc_tt->loop->setTick(ctick);
+ int id;
+ if (!PyArg_ParseTuple(args, "i", &id ))
+ {
+ return NULL;
+ }
+ sc_tt->loop->delEvent(id);
+ RetNone;
}
-void sc_loop_setTickDuration(MYFLT secs_per_tick)
+DECL(sc_loop_clear)
{
- sc_tt->loop->setTickDuration(secs_per_tick);
+ if (!PyArg_ParseTuple(args, "" ))
+ {
+ return NULL;
+ }
+ sc_tt->loop->clear();
+ RetNone;
}
-void sc_loop_addScoreEvent15(int in_ticks, char type, MYFLT p1, MYFLT p2, MYFLT p3, MYFLT p4, MYFLT p5, MYFLT p6, MYFLT p7, MYFLT p8, MYFLT p9, MYFLT p10, MYFLT p11, MYFLT p12, MYFLT p13, MYFLT p14, MYFLT p15)
+DECL(sc_loop_playing) // (int tf)
{
- sc_tt->loop->addEvent( new ev_t(type, in_ticks, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15));
+ int i;
+ if (!PyArg_ParseTuple(args, "i", &i ))
+ {
+ return NULL;
+ }
+ sc_tt->thread_playloop = i;
+ RetNone;
}
-void sc_loop_clear()
+DECL (sc_inputMessage) //(const char *msg)
{
- sc_tt->loop->clear();
+ char * msg;
+ if (!PyArg_ParseTuple(args, "s", &msg ))
+ {
+ return NULL;
+ }
+ sc_tt->inputMessage(msg);
+ RetNone;
}
-void sc_loop_playing(int tf)
+
+#define MDECL(s) {""#s, s, METH_VARARGS, "documentation of "#s"... nothing!"},
+static PyMethodDef SpamMethods[] = {
+ {"sc_destroy", sc_destroy, METH_VARARGS,""},
+ {"sc_initialize", sc_initialize, METH_VARARGS,""},
+ {"sc_start", sc_start, METH_VARARGS,""},
+ {"sc_stop", sc_stop, METH_VARARGS,""},
+ {"sc_scoreEvent", sc_scoreEvent, METH_VARARGS, ""},
+ {"sc_setMasterVolume", sc_setMasterVolume, METH_VARARGS, ""},
+ {"sc_setTrackpadX", sc_setTrackpadX, METH_VARARGS, ""},
+ {"sc_setTrackpadY", sc_setTrackpadY, METH_VARARGS, ""},
+ MDECL(sc_loop_getTick)
+ MDECL(sc_loop_setNumTicks)
+ MDECL(sc_loop_setTick)
+ MDECL(sc_loop_setTickDuration)
+ MDECL(sc_loop_delScoreEvent)
+ MDECL(sc_loop_addScoreEvent) // (int id, int duration_in_ticks, char type, farray param)
+ MDECL(sc_loop_clear)
+ MDECL(sc_loop_playing)
+ MDECL(sc_inputMessage)
+ {NULL, NULL, 0, NULL} /*end of list */
+};
+
+PyMODINIT_FUNC
+initsclient(void)
{
- sc_tt->thread_playloop = tf;
+ (void) Py_InitModule("sclient", SpamMethods);
}
+
diff --git a/Util/Clooper/SoundClient.h b/Util/Clooper/SoundClient.h
index 561529b..ccfb04b 100644
--- a/Util/Clooper/SoundClient.h
+++ b/Util/Clooper/SoundClient.h
@@ -19,7 +19,8 @@ extern "C"
void sc_scoreEvent4(char type, MYFLT p0, MYFLT p1, MYFLT p2, MYFLT p3);
void sc_scoreEvent15(char type, MYFLT p1, MYFLT p2, MYFLT p3, MYFLT p4, MYFLT p5, MYFLT p6, MYFLT p7, MYFLT p8, MYFLT p9, MYFLT p10, MYFLT p11, MYFLT p12, MYFLT p13, MYFLT p14, MYFLT p15);
- void sc_loop_addScoreEvent15(int in_ticks, char type, MYFLT p1, MYFLT p2, MYFLT p3, MYFLT p4, MYFLT p5, MYFLT p6, MYFLT p7, MYFLT p8, MYFLT p9, MYFLT p10, MYFLT p11, MYFLT p12, MYFLT p13, MYFLT p14, MYFLT p15);
+ void sc_loop_addScoreEvent15(int id, int in_ticks, char type, MYFLT p1, MYFLT p2, MYFLT p3, MYFLT p4, MYFLT p5, MYFLT p6, MYFLT p7, MYFLT p8, MYFLT p9, MYFLT p10, MYFLT p11, MYFLT p12, MYFLT p13, MYFLT p14, MYFLT p15);
+ void sc_loop_delScoreEvent(int id);
void sc_loop_clear();
int sc_loop_getTick();
void sc_loop_playing(int tf);
diff --git a/Util/Clooper/_SClient.so b/Util/Clooper/_SClient.so
index 66074a6..da097ed 100755
--- a/Util/Clooper/_SClient.so
+++ b/Util/Clooper/_SClient.so
Binary files differ
diff --git a/Util/Clooper/sclient.so b/Util/Clooper/sclient.so
new file mode 100755
index 0000000..f2d3b36
--- /dev/null
+++ b/Util/Clooper/sclient.so
Binary files differ