From f8ac52e520aa5e20a256a3fd9a649b461f3afeef Mon Sep 17 00:00:00 2001 From: mescalinum Date: Fri, 25 Sep 2009 17:19:25 +0000 Subject: rewrite in C++ svn path=/trunk/externals/ffext/; revision=12451 --- composer/PdClasses.cpp | 286 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 286 insertions(+) create mode 100644 composer/PdClasses.cpp (limited to 'composer/PdClasses.cpp') diff --git a/composer/PdClasses.cpp b/composer/PdClasses.cpp new file mode 100644 index 0000000..d8ca17a --- /dev/null +++ b/composer/PdClasses.cpp @@ -0,0 +1,286 @@ +#include "PdClasses.hpp" +#include "Song.hpp" +#include "Track.hpp" +#include "Pattern.hpp" + +#include + +using std::cout; +using std::cerr; +using std::endl; + +#define IS_A_FLOAT(atom,index) ((atom+index)->a_type == A_FLOAT) + +t_atom result_argv[MAX_RESULT_SIZE]; +int result_argc; + +t_class *track_proxy_class; +t_class *song_proxy_class; + +void track_proxy_setup(void) +{ + track_proxy_class = class_new( + gensym("track"), + (t_newmethod)track_proxy_new, + (t_method)track_proxy_free, + sizeof(t_track_proxy), + CLASS_DEFAULT, + A_SYMBOL, A_SYMBOL, A_NULL + ); + class_addmethod(track_proxy_class, (t_method)track_proxy_getpatterns, \ + gensym("getpatterns"), A_NULL); + class_addmethod(track_proxy_class, (t_method)track_proxy_getpatternsize, \ + gensym("getpatternsize"), A_FLOAT, A_NULL); + class_addmethod(track_proxy_class, (t_method)track_proxy_setrow, \ + gensym("setrow"), A_GIMME, A_NULL); + class_addmethod(track_proxy_class, (t_method)track_proxy_getrow, \ + gensym("getrow"), A_FLOAT, A_FLOAT, A_NULL); + class_addmethod(track_proxy_class, (t_method)track_proxy_addpattern, \ + gensym("addpattern"), A_SYMBOL, A_FLOAT, A_FLOAT, A_NULL); + class_addmethod(track_proxy_class, (t_method)track_proxy_removepattern, \ + gensym("removepattern"), A_FLOAT, A_NULL); + class_addmethod(track_proxy_class, (t_method)track_proxy_resizepattern, \ + gensym("resizepattern"), A_FLOAT, A_FLOAT, A_FLOAT, A_NULL); + class_addmethod(track_proxy_class, (t_method)track_proxy_copypattern, \ + gensym("copypattern"), A_SYMBOL, A_SYMBOL, A_NULL); + /* class_addmethod(track_proxy_class, (t_method)track_proxy_data, \ + gensym("data"), A_GIMME, A_NULL);*/ +#if PD_MINOR_VERSION >= 37 + //class_setpropertiesfn(track_proxy_class, track_proxy_properties); + class_setsavefn(track_proxy_class, track_proxy_save); +#endif + class_sethelpsymbol(track_proxy_class, gensym("track.pd")); +} + +static t_track_proxy *track_proxy_new(t_symbol *song_name, t_symbol *track_name) +{ + t_track_proxy *x = (t_track_proxy*)pd_new(track_proxy_class); + x->outlet = outlet_new(&x->x_obj, &s_list); + x->editor_open = 0; + + // get or create Track object: + x->track = Track::byName(song_name->s_name, track_name->s_name); + + // set send/recv for communication with editor + Song *song = x->track->getSong(); + string base_name = "track_proxy-" + song->getName() + "-" + x->track->getName(); + string recv_name = base_name + "-r"; + string send_name = base_name + "-s"; + x->editor_recv = gensym(recv_name.c_str()); + x->editor_send = gensym(send_name.c_str()); + pd_bind(&x->x_obj.ob_pd, x->editor_recv); + + // bind to TRACK_SELECTOR for loading in-patch data + pd_bind(&x->x_obj.ob_pd, gensym(TRACK_SELECTOR)); + + return x; +} + +static void track_proxy_free(t_track_proxy *x) +{ + pd_unbind(&x->x_obj.ob_pd, gensym(TRACK_SELECTOR)); + /* LATER find a way to get TRACK_SELECTOR unbound earlier (at end of load?) */ + t_pd* x2; + while((x2 = pd_findbyclass(gensym(TRACK_SELECTOR), track_proxy_class))) + pd_unbind(x2, gensym(TRACK_SELECTOR)); + + pd_unbind(&x->x_obj.ob_pd, x->editor_recv); +} + +static void track_proxy_save(t_gobj *z, t_binbuf *b) +{ + t_track_proxy *x = (t_track_proxy*)z; + Track *t = x->track; + Song *s = t->getSong(); + + binbuf_addv(b, "ssiisss;", gensym("#X"), gensym("obj"), + (t_int)x->x_obj.te_xpix, (t_int)x->x_obj.te_ypix, + gensym("track"), gensym(s->getName().c_str()), + gensym(t->getName().c_str())); + + for(unsigned int p = 0; p < t->getPatternCount(); p++) + { + binbuf_addv(b, "ss", gensym(TRACK_SELECTOR), gensym("data")); + Pattern *pattern = t->getPattern(p); + t_int r = pattern->getRows(); + t_int c = pattern->getColumns(); + binbuf_addv(b, "siii", gensym(pattern->getName().c_str()), p, r, c); + t_atom tmp; + for(unsigned int j = 0; j < r; j++) + { + for(unsigned int k = 0; k < c; k++) + { + tmp = pattern->getCell(j, k); + switch(tmp.a_type) + { + case A_SYMBOL: + binbuf_addv(b, "s", tmp.a_w.w_symbol); + break; + case A_FLOAT: + binbuf_addv(b, "f", tmp.a_w.w_float); + break; + default: + binbuf_addv(b, "s", gensym("?")); + break; + } + } + } + binbuf_addv(b, ";"); + } + + binbuf_addv(b, "sss;", gensym(TRACK_SELECTOR), gensym("data"), gensym("end")); +} + +static void track_proxy_send_result(t_track_proxy *x, int outlet, int editor) +{ + if(result_argc <= 0) return; + if(outlet) + { + outlet_list(x->outlet, &s_list, result_argc, &result_argv[0]); + } + if(editor) + { + } +} + +static int track_proxy_getpatterns(t_track_proxy *x) +{ + SETSYMBOL(&result_argv[0], gensym("patternnames")); + result_argc = 1; + for(unsigned int i = 0; i < x->track->getPatternCount(); i++) + { + if(result_argc >= MAX_RESULT_SIZE) + { + pd_error(x, "getpatternnames: result too long"); + return -2; + } + Pattern *pattern = x->track->getPattern(i); + if(!pattern) + { + pd_error(x, "getpatternnames: no such pattern: %d", i); + return -1; + } + SETSYMBOL(&result_argv[result_argc], gensym(pattern->getName().c_str())); + result_argc++; + } + return 0; +} + +static int track_proxy_getpatternsize(t_track_proxy *x, t_floatarg pat) +{ + t_int p = (t_int) pat; + Pattern *pattern = x->track->getPattern(p); + if(!pattern) + { + pd_error(x, "getpatternsize: no such pattern: %d", p); + return -1; + } + SETSYMBOL(&result_argv[0], gensym("patternsize")); + SETFLOAT(&result_argv[1], (t_float) p); + SETFLOAT(&result_argv[2], pattern->getRows()); + SETFLOAT(&result_argv[3], pattern->getColumns()); + result_argc = 4; + return 0; +} + +static int track_proxy_setrow(t_track_proxy *x, t_symbol *sel, int argc, t_atom *argv) +{ + if(argc < 2 || !IS_A_FLOAT(argv,0) || !IS_A_FLOAT(argv,1)) + { + pd_error(x, "setrow: usage: setrow ..."); + return -1; + } + t_int p = (t_int) argv[0].a_w.w_float; + t_int r = (t_int) argv[1].a_w.w_float; + Pattern *pattern = x->track->getPattern(p); + if(!pattern) + { + pd_error(x, "setrow: no such pattern: %d", p); + return -2; + } + if((argc - 2) != pattern->getColumns()) + { + pd_error(x, "setrow: input error: must provide exactly %d elements for a row", pattern->getColumns()); + return -3; + } + for(unsigned int i = 2; i < argc; i++) + { + pattern->setCell(r, i - 2, argv[i]); + } + result_argc = 0; + return 0; +} + +static int track_proxy_getrow(t_track_proxy *x, t_floatarg pat, t_floatarg rownum) +{ + t_int p = (t_int) pat; + t_int r = (t_int) rownum; + Pattern *pattern = x->track->getPattern(p); + if(!pattern) + { + pd_error(x, "getrow: no such pattern: %d", p); + return -2; + } + SETSYMBOL(&result_argv[0], gensym("patternrow")); + SETFLOAT(&result_argv[1], (t_float) p); + SETFLOAT(&result_argv[2], (t_float) r); + result_argc = 3; + for(unsigned int i = 0; i < pattern->getColumns(); i++) + { + if(result_argc >= MAX_RESULT_SIZE) + { + pd_error(x, "getrow: result too long"); + return -2; + } + result_argv[result_argc] = pattern->getCell(r, i); + result_argc++; + } + return 0; +} + +static int track_proxy_addpattern(t_track_proxy *x, t_symbol *name, t_floatarg rows, t_floatarg cols) +{ + t_int r = (t_int) rows; + t_int c = (t_int) cols; + x->track->addPattern(r, c, string(name->s_name)); + return 0; +} + +static int track_proxy_removepattern(t_track_proxy *x, t_floatarg pat) +{ + t_int p = (t_int) pat; + Pattern *pattern = x->track->getPattern(p); + if(!pattern) + { + pd_error(x, "removepattern: no such pattern: %d", p); + return -2; + } + pd_error(x, "removepattern: not implemented yet"); + return -9; +} + +static int track_proxy_resizepattern(t_track_proxy *x, t_floatarg pat, t_floatarg rows, t_floatarg cols) +{ + t_int p = (t_int) pat; + t_int r = (t_int) rows; + t_int c = (t_int) cols; + Pattern *pattern = x->track->getPattern(p); + if(!pattern) + { + pd_error(x, "resizepattern: no such pattern: %d", p); + return -2; + } + pattern->resize(r, c); + return 0; +} + +static int track_proxy_copypattern(t_track_proxy *x, t_symbol *src, t_symbol *dst) +{ + pd_error(x, "copypattern: not implemented yet"); + return -9; +} + +void composer_setup() +{ + track_proxy_setup(); +} -- cgit v1.2.1