aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormescalinum <mescalinum@users.sourceforge.net>2009-08-19 23:51:59 +0000
committermescalinum <mescalinum@users.sourceforge.net>2009-08-19 23:51:59 +0000
commit1bdf5157d0707e89b1bce0a939fbcfcf33047816 (patch)
tree57831761500dd95a51d6a0616ac7b7a71bb17625
parent6569fedbe695c5e6cb746ac972c467ca46b2f958 (diff)
[song] is born
svn path=/trunk/externals/ffext/; revision=11988
-rw-r--r--composer/arraylist.h6
-rw-r--r--composer/common.h29
-rw-r--r--composer/composer.c49
-rw-r--r--composer/pattern.c16
-rw-r--r--composer/song.c19
-rw-r--r--composer/song_proxy.c296
-rw-r--r--composer/track.c130
-rw-r--r--composer/track_proxy.c201
8 files changed, 585 insertions, 161 deletions
diff --git a/composer/arraylist.h b/composer/arraylist.h
index a4b4362..b625379 100644
--- a/composer/arraylist.h
+++ b/composer/arraylist.h
@@ -3,7 +3,7 @@
/* For information on usage and redistribution, and for a DISCLAIMER OF ALL */
/* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
/* */
-/* composer: a music composition framework for pure-data */
+/* arraylist.h: macro library for dynamic arrays */
/* */
/* This program is free software; you can redistribute it and/or */
/* modify it under the terms of the GNU General Public License */
@@ -21,7 +21,6 @@
/* along with this program; if not, write to the Free Software Foundation, */
/* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/* */
-/* Based on PureData by Miller Puckette and others. */
/* ------------------------------------------------------------------------ */
#include "common.h"
@@ -41,7 +40,8 @@
#define ArrayListInit(arrName, type, initSize) \
arrName ## _maxsize = initSize; \
- arrName = (type*)getbytes(sizeof(type) * (initSize)); \
+ if(initSize > 0) arrName = (type*)getbytes(sizeof(type) * (initSize)); \
+ else arrName = NULL; \
arrName ## _count = 0
#define ArrayListAdd(arrName, type, objToAdd) \
diff --git a/composer/common.h b/composer/common.h
index 516836f..f9005cf 100644
--- a/composer/common.h
+++ b/composer/common.h
@@ -55,6 +55,8 @@
#define TRACK_SELECTOR "#TRACK"
#define SONG_SELECTOR "#SONG"
+static void list_snconvf(char *buf, size_t bufsz, t_symbol* s, size_t argc, t_atom* argv);
+
struct _track;
struct _pattern;
@@ -62,6 +64,7 @@ typedef struct _song
{
t_symbol* x_name;
ArrayListDeclare(x_tracks, struct _track*, t_int);
+ struct _track* x_mastertrack;
} t_song;
typedef struct _song_proxy
@@ -70,6 +73,7 @@ typedef struct _song_proxy
t_outlet* outlet;
t_song* x_song;
t_int b_editor_open;
+ t_symbol* rcv;
} t_song_proxy;
typedef struct _track
@@ -99,20 +103,25 @@ typedef struct _pattern
} t_pattern;
static t_song* song_new(t_symbol* song_name);
+static void song_mastertrack_fix_cols(t_song* x);
static void song_free(t_song* x);
static t_song* song_get(t_symbol* song_name);
static int song_exists(t_symbol* song_name);
static t_track* track_new(t_symbol* song_name, t_symbol* track_name, t_int columns);
+static t_track* mastertrack_new(t_song* song, t_symbol* track_name, t_int columns);
+static t_track* song_create_track(t_song* x, t_symbol* track_name, t_int columns);
static void track_free(t_track* x);
static t_track* track_get(t_symbol* song_name, t_symbol* track_name);
static int track_exists(t_symbol* song_name, t_symbol* track_name);
+static void track_binbuf_save(t_track* x);
static t_pattern* pattern_new(t_track* track, t_symbol* name, t_int rows);
static t_pattern* pattern_clone(t_pattern* src, t_symbol* newname);
static void pattern_free(t_pattern* x);
static void pattern_rename(t_pattern* x, t_symbol* newname);
static void pattern_resize(t_pattern *x, t_int newsize);
+static void pattern_resize_cols(t_pattern* x, t_int newcols);
static void pattern_new_empty_row(t_pattern* x);
static t_atom* pattern_getrow(t_pattern* x, t_int row);
static t_atom* pattern_clone_row(t_pattern* x, t_atom* row);
@@ -127,7 +136,27 @@ static t_song_proxy* song_proxy_new(t_symbol* song_name);
static void song_proxy_free(t_song_proxy* x);
static void song_proxy_float(t_song_proxy* x, t_floatarg f);
static void song_proxy_properties(t_gobj* z, t_glist* owner);
+static void song_proxy_properties_close(t_gobj* z, t_glist* owner);
static void song_proxy_save(t_gobj* z, t_binbuf* b);
+static t_atom* song_proxy_gettracks(t_song_proxy* x);
+static void song_proxy_gettracks_o(t_song_proxy* x);
+static t_int song_proxy_gettracks_count(t_song_proxy* x);
+static void song_proxy_gettracks_count_o(t_song_proxy* x);
+static void song_proxy_anything(t_song_proxy* x, t_symbol* s, int argc, t_atom* argv);
+static void song_proxy_loaddata(t_song_proxy* x, t_symbol* s, int argc, t_atom* argv);
+static t_atom* song_proxy_getpatternlength(t_song_proxy* x, t_symbol* pat_name);
+static void song_proxy_editcmd(t_song_proxy* x, t_symbol* s_, int argc, t_atom* argv_);
+static void song_proxy_sendgui(t_song_proxy* x, t_symbol* s, int argc, t_atom* argv);
+static void song_proxy_setrow(t_song_proxy* x, t_symbol* sel, int argc, t_atom* argv);
+static t_atom* song_proxy_getrow(t_song_proxy* x, t_symbol* pat_name, t_floatarg rownum);
+static t_atom* song_proxy_getrow_with_header(t_song_proxy* x, t_symbol* pat_name, t_floatarg rownum);
+static void song_proxy_getrow_o(t_song_proxy* x, t_symbol* pat_name, t_floatarg rownum);
+static void song_proxy_setcell(t_song_proxy* x, t_symbol* sel, int argc, t_atom* argv);
+static t_atom* song_proxy_getcell(t_song_proxy* x, t_symbol* pat_name, t_floatarg rownum, t_floatarg colnum);
+static t_atom* song_proxy_getcell_with_header(t_song_proxy* x, t_symbol* pat_name, t_floatarg rownum, t_floatarg colnum);
+static void song_proxy_getcell_o(t_song_proxy* x, t_symbol* pat_name, t_floatarg rownum, t_floatarg colnum);
+static t_pattern* song_proxy_resizepattern(t_song_proxy* x, t_symbol* name, t_floatarg rows);
+static t_atom* song_proxy_get_track_names(t_song_proxy* x);
void track_proxy_setup(void);
static t_track_proxy* track_proxy_new(t_symbol* song_name, t_symbol* track_name, t_floatarg cols);
diff --git a/composer/composer.c b/composer/composer.c
index dd5ccab..6d86758 100644
--- a/composer/composer.c
+++ b/composer/composer.c
@@ -34,6 +34,55 @@
ArrayListDeclare(songs, t_song*, int);
+void list_snconvf(char *buf, size_t bufsz, t_symbol* s, size_t argc, t_atom* argv) {
+ static const unsigned int tmpsz = 80;
+ char* tmp;
+ size_t i,j,len;
+ if(bufsz < 1) goto list_snconvf_szbug;
+ buf[0] = '\0';
+ len = 0;
+ if(s != gensym("")) {
+ len += strlen(s->s_name) + 1;
+ if(bufsz <= len) goto list_snconvf_szbug;
+ strncat(buf, s->s_name, bufsz);
+ strncat(buf, " ", bufsz);
+ }
+ for(i = 0; i < argc; i++) {
+ if(i > 0) {
+ len += 1;
+ if(bufsz <= len) goto list_snconvf_szbug;
+ strncat(buf, " ", bufsz);
+ }
+ if(argv[i].a_type == A_FLOAT) {
+ tmp = (char*)getbytes(tmpsz*sizeof(char));
+ if(argv[i].a_w.w_float == (t_float)(t_int)argv[i].a_w.w_float)
+ sprintf(tmp, "%ld", (t_int)argv[i].a_w.w_float);
+ else
+ sprintf(tmp, "%f", argv[i].a_w.w_float);
+ len += strlen(tmp);
+ if(bufsz <= len) goto list_snconvf_szbug;
+ strncat(buf, tmp, bufsz);
+ freebytes(tmp, tmpsz*sizeof(char));
+ } else if(argv[i].a_type == A_SYMBOL) {
+ len += strlen(argv[i].a_w.w_symbol->s_name);
+ if(bufsz <= len) goto list_snconvf_szbug;
+ strncat(buf, argv[i].a_w.w_symbol->s_name, bufsz);
+ } else {
+ len += 4;
+ if(bufsz <= len) goto list_snconvf_szbug;
+ strncat(buf, "null", bufsz);
+ }
+ }
+ if(strlen(buf) >= bufsz) {
+ goto list_snconvf_szbug;
+ }
+ return;
+
+list_snconvf_szbug:
+ debugprint("track: BUG: list_snconvf_szbug (message too long)");
+ bug("track: BUG: list_snconvf_szbug (message too long)");
+}
+
void composer_setup(void) {
debugprint("loading composer library for pd");
sys_vgui("source {window.tk}\n");
diff --git a/composer/pattern.c b/composer/pattern.c
index 95afed2..819c585 100644
--- a/composer/pattern.c
+++ b/composer/pattern.c
@@ -28,7 +28,7 @@
static t_pattern* pattern_new(t_track* track, t_symbol* name, t_int rows) {
ArrayListGetByName(track->x_patterns, name, t_pattern*, obj);
- debugprint("pattern_new - object lookup {{%s}} => " PTR, name->s_name, obj);
+ debugprint("pattern_new - object lookup %s => " PTR, name->s_name, obj);
if(obj) return obj;
t_pattern* x = (t_pattern*)getbytes(sizeof(t_pattern));
@@ -86,6 +86,20 @@ static void pattern_resize(t_pattern *x, t_int newsize) {
debugprint("final size: %d", x->x_rows_count);
}
+/* WARNING: do not call this for track with more than 1 pattern!
+ * Works only for the mastertrack (song_proxy)
+ */
+static void pattern_resize_cols(t_pattern* x, t_int newcols) {
+ int j;
+ for(j = 0; j < x->x_rows_count; j++) {
+ if(&x->x_rows[j])
+ x->x_rows[j] = (t_atom*)resizebytes(x->x_rows[j], x->x_track->x_ncolumns, newcols);
+ else
+ x->x_rows[j] = (t_atom*)getbytes(sizeof(t_atom) * newcols);
+ }
+ x->x_track->x_ncolumns = newcols;
+}
+
static void pattern_new_empty_row(t_pattern* x) {
t_atom* rowdata = (t_atom*)getbytes(sizeof(t_atom) * x->x_track->x_ncolumns);
int j;
diff --git a/composer/song.c b/composer/song.c
index 7c99877..424c52c 100644
--- a/composer/song.c
+++ b/composer/song.c
@@ -28,15 +28,17 @@
static t_song* song_new(t_symbol* song_name) {
ArrayListGetByName(songs, song_name, t_song*, obj);
- debugprint("song_new - object lookup {{%s}} => " PTR, song_name->s_name, obj);
+ debugprint("song_new - object lookup %s => " PTR, song_name->s_name, obj);
if(obj) return obj;
t_song* x = (t_song*)getbytes(sizeof(t_song));
x->x_name = song_name;
- ArrayListInit(x->x_tracks, struct _track*, 16);
+ ArrayListInit(x->x_tracks, struct _track*, 16);
+ // mastertrack is named like the song
+ x->x_mastertrack = mastertrack_new(x, x->x_name, 0);
debugprint("created a song object (" PTR "), "
- "creation args: {{%s}}",
+ "creation args: %s",
x, x->x_name->s_name);
ArrayListAdd(songs, t_song*, x);
@@ -44,6 +46,17 @@ static t_song* song_new(t_symbol* song_name) {
return x;
}
+static void song_mastertrack_fix_cols(t_song* x) {
+ debugprint("song_mastertrack_fix_cols(" PTR "), new track count: %d", x, x->x_tracks_count);
+ debugprint("song='%s' mastertrack=" PTR, x->x_name->s_name, x->x_mastertrack);
+ debugprint("we have %d patterns, sir", x->x_mastertrack->x_patterns_count);
+ int j;
+ for(j = 0; j < x->x_mastertrack->x_patterns_count; j++) {
+ if(j > 0) post("WARNING: mastertrack with more than one pattern!");
+ pattern_resize_cols(x->x_mastertrack->x_patterns[j], x->x_tracks_count);
+ }
+}
+
static void song_free(t_song* x) {
// free tracks memory
ArrayListFree(x->x_tracks, t_track*);
diff --git a/composer/song_proxy.c b/composer/song_proxy.c
index 9d40215..e1fd85f 100644
--- a/composer/song_proxy.c
+++ b/composer/song_proxy.c
@@ -28,6 +28,11 @@
t_class* song_proxy_class;
+static t_atom response_pattern_length[2];
+static t_atom response_cell[4];
+static t_atom* response_row; // TODO: memory leaks check
+static size_t response_row_sz;
+
void song_proxy_setup(void) {
debugprint("registering 'song' class...");
song_proxy_class = class_new(
@@ -52,18 +57,309 @@ static t_song_proxy* song_proxy_new(t_symbol* song_name) {
x->outlet = outlet_new(&x->x_obj, &s_list);
x->x_song = song_new(song_name);
x->b_editor_open = 0;
+ char rcv_buf[80];
+ sprintf(rcv_buf, "track_proxy-%s-%s", x->x_song->x_name->s_name, x->x_song->x_mastertrack->x_name->s_name);
+ x->rcv = gensym(rcv_buf);
+ pd_bind(&x->x_obj.ob_pd, x->rcv);
+
debugprint("created an instance of t_song_proxy: " PTR, x);
return x;
+
+ song_proxy_properties_close((t_gobj*) x, NULL);
+
+ pd_bind(&x->x_obj.ob_pd, gensym(SONG_SELECTOR));
+
+ sys_vgui("pd::composer::init %s %s %s %d %d\n", x->rcv->s_name, x->x_song->x_name->s_name, x->x_song->x_mastertrack->x_name->s_name, x->x_song->x_mastertrack->x_ncolumns, DEBUG_BOOL);
+
+ return x;
}
static void song_proxy_free(t_song_proxy* x) {
+ song_proxy_properties_close((t_gobj*) x, NULL);
+
+ pd_unbind(&x->x_obj.ob_pd, gensym(SONG_SELECTOR));
+ /* LATER find a way to get SONG_SELECTOR unbound earlier (at end of load?) */
+ t_pd* x2;
+ while (x2 = pd_findbyclass(gensym(SONG_SELECTOR), song_proxy_class))
+ pd_unbind(x2, gensym(SONG_SELECTOR));
+
+ pd_unbind(&x->x_obj.ob_pd, x->rcv);
}
static void song_proxy_float(t_song_proxy* x, t_floatarg f) {
}
static void song_proxy_properties(t_gobj* z, t_glist* owner) {
+ t_song_proxy* x = (t_song_proxy*)z;
+ sys_vgui("pd::composer::openWindow %s\n", x->rcv->s_name);
+ x->b_editor_open = 1;
+}
+
+static void song_proxy_properties_close(t_gobj* z, t_glist* owner) {
+ t_song_proxy* x = (t_song_proxy*)z;
+ debugprint("song_proxy_properties_close(" PTR ", " PTR ") [editor is %s]", z, owner, x->b_editor_open ? "open" : "closed");
+ if(x->b_editor_open) {
+ debugprint("closing...");
+ sys_vgui("pd::composer::closeWindow %s\n", x->rcv->s_name);
+ x->b_editor_open = 0;
+ }
}
static void song_proxy_save(t_gobj* z, t_binbuf* b) {
+ t_track_proxy* x = (t_track_proxy*)z;
+ t_track* t = x->x_track;
+
+ binbuf_addv(b, "ssiisssi;", gensym("#X"), gensym("obj"),
+ (t_int)x->x_obj.te_xpix, (t_int)x->x_obj.te_ypix,
+ gensym("track"), t->x_song->x_name, t->x_name, t->x_ncolumns);
+
+ track_binbuf_save(t, gensym(TRACK_SELECTOR), b);
+}
+
+static t_atom* song_proxy_gettracks(t_song_proxy* x) {
+ if(response_row) {
+ freebytes(response_row, response_row_sz);
+ response_row = NULL;
+ response_row_sz = 0;
+ }
+ response_row_sz = sizeof(t_atom) * x->x_song->x_tracks_count;
+ response_row = (t_atom*)getbytes(response_row_sz);
+ int i;
+ for(i = 0; i < x->x_song->x_tracks_count; i++) {
+ SETSYMBOL(&response_row[i], x->x_song->x_tracks[i]->x_name);
+ }
+ return &response_row[0];
+}
+
+static void song_proxy_gettracks_o(t_song_proxy* x) {
+ t_atom* rsp = song_proxy_gettracks(x);
+ if(rsp)
+ outlet_list(x->outlet, &s_list, response_row_sz, rsp);
+}
+
+static t_int song_proxy_gettracks_count(t_song_proxy* x) {
+ return x->x_song->x_tracks_count;
+}
+
+static void song_proxy_gettracks_count_o(t_song_proxy* x) {
+ outlet_float(x->outlet, (t_float)song_proxy_gettracks_count(x));
+}
+
+static void song_proxy_anything(t_song_proxy* x, t_symbol* s, int argc, t_atom* argv) {
+ debugprint("song_proxy_anything(" PTR ", %s, %d, " PTR ")", x, s->s_name, argc, argv);
+
+ if(s == gensym("DATA")) {
+ song_proxy_loaddata(x, s, argc, argv);
+ return;
+ } else if(s == gensym("EDIT")) {
+ song_proxy_editcmd(x, s, argc, argv);
+ return;
+ } else {
+ error("unrecognized command for anything method: %s ", s->s_name);
+ return;
+ }
+}
+
+static void song_proxy_loaddata(t_song_proxy* x, t_symbol* s, int argc, t_atom* argv) {
+ track_loaddata(x->x_song->x_mastertrack, argc, argv);
+}
+
+static t_atom* song_proxy_getpatternlength(t_song_proxy* x, t_symbol* pat_name) {
+ ArrayListGetByName(x->x_song->x_mastertrack->x_patterns, pat_name, t_pattern*, pat);
+ if(!pat) {
+ error("song: getpatternlength: no such pattern: '%s'", pat_name->s_name);
+ return NULL;
+ }
+ SETSYMBOL(&response_pattern_length[0], pat->x_name);
+ SETFLOAT(&response_pattern_length[1], pat->x_rows_count);
+ return &response_pattern_length[0];
+}
+
+static void song_proxy_editcmd(t_song_proxy* x, t_symbol* s_, int argc, t_atom* argv_) {
+ if(argc < 1 || argv_[0].a_type != A_SYMBOL) {
+ error("track: editcmd: missing method selector");
+ return;
+ }
+ /*if(argc < 2) {
+ error("track: editcmd: missing data after selector");
+ return;
+ }*/
+
+ // route -> selector
+ t_symbol* s = argv_[0].a_w.w_symbol;
+ t_atom* argv = &argv_[1];
+ argc--;
+
+ t_symbol *s1 = (argc >= 1 && argv[0].a_type == A_SYMBOL) ? argv[0].a_w.w_symbol : NULL;
+ t_symbol *s2 = (argc >= 2 && argv[1].a_type == A_SYMBOL) ? argv[1].a_w.w_symbol : NULL;
+ t_float f2 = (argc >= 2 && argv[1].a_type == A_FLOAT) ? argv[1].a_w.w_float : 0;
+ t_float f3 = (argc >= 3 && argv[2].a_type == A_FLOAT) ? argv[2].a_w.w_float : 0;
+
+ t_pattern* p = NULL;
+ int i,j;
+
+ if(s == gensym("editor-open")) {
+ song_proxy_properties((t_gobj*) x, NULL);
+ } else if(s == gensym("editor-close")) {
+ song_proxy_properties_close((t_gobj*) x, NULL);
+ } else if(s == gensym("gettracks")) {
+ t_atom* rsp = song_proxy_get_track_names(x);
+ song_proxy_sendgui(x, gensym("tracks"), response_row_sz, rsp);
+ } else if(s == gensym("gettrackscount")) {
+ t_atom a;
+ SETFLOAT(&a, (t_float)song_proxy_gettracks_count(x));
+ song_proxy_sendgui(x, gensym("trackscount"), 1, &a);
+ } else if(s == gensym("getpatternlength")) {
+ song_proxy_sendgui(x, gensym("patternlength"), 2, song_proxy_getpatternlength(x, s1));
+ } else if(s == gensym("getrow")) {
+ song_proxy_sendgui(x, gensym("row"), 2 + x->x_song->x_mastertrack->x_ncolumns, song_proxy_getrow_with_header(x, s1, f2));
+ } else if(s == gensym("setrow")) {
+ song_proxy_setrow(x, s, argc, argv);
+ } else if(s == gensym("getcell")) {
+ song_proxy_sendgui(x, gensym("cell"), 4, song_proxy_getcell_with_header(x, s1, f2, f3));
+ } else if(s == gensym("setcell")) {
+ song_proxy_setcell(x, s, argc, argv);
+ } else if(s == gensym("resizepattern")) {
+ p = song_proxy_resizepattern(x, s1, f2);
+ if(p) {
+ song_proxy_sendgui(x, gensym("patternlength"), 2, song_proxy_getpatternlength(x, p->x_name));
+ }
+ } else {
+ error("track: editcmd: unknown command: %s", s->s_name);
+ }
+}
+
+static void song_proxy_sendgui(t_song_proxy* x, t_symbol* s, int argc, t_atom* argv) {
+ static const unsigned int bufsz = 8*MAXPDSTRING;
+ char buf[bufsz];
+ list_snconvf(buf, bufsz, s, argc, argv);
+ debugprint("pd::composer::dispatch %s %s", x->rcv->s_name, buf);
+ sys_vgui("pd::composer::dispatch %s %s\n", x->rcv->s_name, buf);
+}
+
+static void song_proxy_setrow(t_song_proxy* x, t_symbol* sel, int argc, t_atom* argv) {
+ if(argc < 2 || argv[0].a_type != A_SYMBOL || argv[1].a_type != A_FLOAT) {
+ error("song: setrow: usage: setrow <pattern_name> <row#> <atom0> <atom1> ...");
+ return;
+ }
+ if((argc - 2) != x->x_song->x_mastertrack->x_ncolumns) {
+ post("argc=%d, ncolumns=%d", argc, x->x_song->x_mastertrack->x_ncolumns);
+ error("track: setrow: input error: must provide exactly %d elements for the row", x->x_song->x_mastertrack->x_ncolumns);
+ return;
+ }
+ t_symbol* pat_name = argv[0].a_w.w_symbol;
+ t_int rownum = (t_int)argv[1].a_w.w_float;
+ ArrayListGetByName(x->x_song->x_mastertrack->x_patterns, pat_name, t_pattern*, pat);
+ if(!pat) {
+ error("track: setrow: no such pattern: '%s'", pat_name->s_name);
+ return;
+ }
+ pattern_setrow(pat, rownum, &argv[2]);
+}
+
+static t_atom* song_proxy_getrow(t_song_proxy* x, t_symbol* pat_name, t_floatarg rownum) {
+ ArrayListGetByName(x->x_song->x_mastertrack->x_patterns, pat_name, t_pattern*, pat);
+ if(!pat) {
+ error("song: getrow: no such pattern: '%s'", pat_name->s_name);
+ return NULL;
+ }
+ t_atom* row = pattern_getrow(pat, (t_int)rownum);
+ debugprint("song_proxy_getrow returning " PTR, row);
+ return row;
+}
+
+static t_atom* song_proxy_getrow_with_header(t_song_proxy* x, t_symbol* pat_name, t_floatarg rownum) {
+ if(response_row) {
+ freebytes(response_row, response_row_sz);
+ response_row = NULL;
+ response_row_sz = 0;
+ }
+
+ t_atom* row = song_proxy_getrow(x, pat_name, rownum);
+ if(!row) {
+ error("song: getrow: nu such patern: '%s'", pat_name->s_name);
+ return NULL;
+ }
+ response_row_sz = sizeof(t_atom) * (x->x_song->x_mastertrack->x_ncolumns + 2);
+ t_atom* response_row = (t_atom*)getbytes(response_row_sz);
+ SETSYMBOL(&response_row[0], pat_name);
+ SETFLOAT(&response_row[1], rownum);
+ memcpy(&response_row[2], row, sizeof(t_atom) * x->x_song->x_mastertrack->x_ncolumns);
+ return &response_row[0];
+}
+
+static void song_proxy_getrow_o(t_song_proxy* x, t_symbol* pat_name, t_floatarg rownum) {
+ t_atom* row = song_proxy_getrow(x, pat_name, rownum);
+ if(row)
+ outlet_list(x->outlet, &s_list, x->x_song->x_mastertrack->x_ncolumns, row);
+}
+
+static void song_proxy_setcell(t_song_proxy* x, t_symbol* sel, int argc, t_atom* argv) {
+ debugprint("song_proxy_setcell, s=%s", sel->s_name);
+ if(argc < 4 || argv[0].a_type != A_SYMBOL || argv[1].a_type != A_FLOAT || argv[2].a_type != A_FLOAT) {
+ error("song: setcell: usage: setcell <pattern_name> <row#> <col#> <atom>");
+ return;
+ }
+ t_symbol* pat_name = argv[0].a_w.w_symbol;
+ t_int rownum = (t_int)argv[1].a_w.w_float;
+ t_int colnum = (t_int)argv[2].a_w.w_float;
+ ArrayListGetByName(x->x_song->x_mastertrack->x_patterns, pat_name, t_pattern*, pat);
+ if(!pat) {
+ error("song: setcell: no such pattern: '%s'", pat_name->s_name);
+ return;
+ }
+ pattern_setcell(pat, (t_int)rownum, (t_int)colnum, &argv[3]);
+}
+
+static t_atom* song_proxy_getcell(t_song_proxy* x, t_symbol* pat_name, t_floatarg rownum, t_floatarg colnum) {
+ ArrayListGetByName(x->x_song->x_mastertrack->x_patterns, pat_name, t_pattern*, pat);
+ if(!pat) {
+ error("song: getcell: no such pattern: '%s'", pat_name->s_name);
+ return NULL;
+ }
+ return pattern_getcell(pat, (t_int)rownum, (t_int)colnum);
+}
+
+static t_atom* song_proxy_getcell_with_header(t_song_proxy* x, t_symbol* pat_name, t_floatarg rownum, t_floatarg colnum) {
+ t_atom* cell = song_proxy_getcell(x, pat_name, rownum, colnum);
+ if(!cell) {
+ error("song: getcell: nu such patern: '%s'", pat_name->s_name);
+ return NULL;
+ }
+ SETSYMBOL(&response_cell[0], pat_name);
+ SETFLOAT(&response_cell[1], rownum);
+ SETFLOAT(&response_cell[2], colnum);
+ memcpy(&response_cell[3], cell, sizeof(t_atom));
+ return &response_cell[0];
+}
+
+static void song_proxy_getcell_o(t_song_proxy* x, t_symbol* pat_name, t_floatarg rownum, t_floatarg colnum) {
+ t_atom* cell = song_proxy_getcell(x, pat_name, rownum, colnum);
+ if(cell)
+ outlet_list(x->outlet, &s_list, 1, cell);
+}
+
+static t_pattern* song_proxy_resizepattern(t_song_proxy* x, t_symbol* name, t_floatarg rows) {
+ ArrayListGetByName(x->x_song->x_mastertrack->x_patterns, name, t_pattern*, pat);
+ if(!pat) {
+ error("song: resizepattern: no such pattern: '%s'", name->s_name);
+ return NULL;
+ }
+ pattern_resize(pat, (t_int)rows);
+ return pat;
+}
+
+static t_atom* song_proxy_get_track_names(t_song_proxy* x) {
+ if(response_row) {
+ freebytes(response_row, response_row_sz);
+ response_row = NULL;
+ response_row_sz = 0;
+ }
+ response_row_sz = sizeof(t_atom) * x->x_song->x_tracks_count;
+ response_row = (t_atom*)getbytes(response_row_sz);
+ int i;
+ for(i = 0; i < x->x_song->x_tracks_count; i++) {
+ SETSYMBOL(&response_row[i], x->x_song->x_tracks[i]->x_name);
+ }
+ return &response_row[0];
}
diff --git a/composer/track.c b/composer/track.c
index a3f5ddc..269a1d9 100644
--- a/composer/track.c
+++ b/composer/track.c
@@ -27,10 +27,30 @@
#include "common.h"
static t_track* track_new(t_symbol* song_name, t_symbol* track_name, t_int columns) {
+ debugprint("track_new(%s, %s, %d)", song_name->s_name, track_name->s_name, columns);
t_song* song = song_new(song_name);
+ t_track* t = song_create_track(song, track_name, columns);
+ // add track to song's track list
+ ArrayListAdd(song->x_tracks, t_track*, t);
+ song_mastertrack_fix_cols(song);
+
+ return t;
+}
+
+static t_track* mastertrack_new(t_song* song, t_symbol* track_name, t_int columns) {
+ debugprint("mastertrack_new(%s, %s, %d)", song->x_name->s_name, track_name->s_name, columns);
+ t_track* t = song_create_track(song, track_name, columns);
+ debugprint("mastertrack_new add pattern");
+ ArrayListAdd(t->x_patterns, t_pattern*, pattern_new(t, gensym("Arrangement"), 16));
+ return t;
+}
+
+// both a song method and the track constructor:
+static t_track* song_create_track(t_song* song, t_symbol* track_name, t_int columns) {
ArrayListGetByName(song->x_tracks, track_name, t_track*, obj);
- debugprint("track_new - object lookup {{%s} {%s} {%d}} => " PTR, song_name->s_name, track_name->s_name, columns, obj);
+ debugprint("song_create_track - object lookup %s, %s, %d => " PTR,
+ song->x_name->s_name, track_name->s_name, columns, obj);
if(obj) return obj;
t_track* x = (t_track*)getbytes(sizeof(t_track));
@@ -41,11 +61,10 @@ static t_track* track_new(t_symbol* song_name, t_symbol* track_name, t_int colum
x->x_currentpat = 0;
debugprint("created a track object (" PTR "), "
- "creation args: {{%s} {%s} {%d}}",
+ "creation args: %s, %s, %d",
x, x->x_song->x_name->s_name, x->x_name->s_name, x->x_ncolumns);
- // att track to song's track list
- ArrayListAdd(song->x_tracks, t_track*, x);
+ debugprint("song_create_track returns " PTR, x);
return x;
}
@@ -77,3 +96,106 @@ static t_track* track_get(t_symbol* song_name, t_symbol* track_name) {
static int track_exists(t_symbol* song_name, t_symbol* track_name) {
return track_get(song_name, track_name) != 0L;
}
+
+static void track_loaddata(t_track* x, int argc, t_atom* argv) {
+ int i,base;
+ base = 0;
+
+ if(argc < (base+2) || argv[base].a_type != A_SYMBOL || argv[base+1].a_type != A_SYMBOL) {
+ error("track: data format error 1");
+ return;
+ }
+ t_symbol* song_name = argv[base+0].a_w.w_symbol;
+ t_symbol* track_name = argv[base+1].a_w.w_symbol;
+ base += 2;
+
+ if(x->x_song->x_name != song_name) {
+ debugprint("WARNING: discarding data from another song: %s", song_name->s_name);
+ return;
+ }
+
+ if(x->x_name != track_name) {
+ debugprint("WARNING: discarding data from another track: %s", track_name->s_name);
+ return;
+ }
+
+ t_song* song = song_get(song_name);
+ if(!song) {
+ error("track: song '%s' does not exist", song_name->s_name);
+ return;
+ }
+
+ if(argc < (base+1) || argv[base].a_type != A_FLOAT) {
+ error("track: data format error 2");
+ return;
+ }
+ t_int npatterns = (t_int)argv[base].a_w.w_float;
+ base += 1;
+
+ debugprint("track: %s-%s: %d patterns to read", song_name->s_name, track_name->s_name, npatterns);
+
+ t_symbol* patname;
+ t_int patrows;
+ t_pattern* pat;
+
+ debugprint("track_loaddata(" PTR ", %d, " PTR ")", x, argc, argv);
+ for(i = 0; i < npatterns; i++) {
+ debugprint("reading pattern %d...", i);
+ if(argc < (base + 2)) {
+ error("track: data format error 3 (i=%d)", i);
+ return;
+ }
+ if(argv[base+0].a_type != A_SYMBOL || argv[base+1].a_type != A_FLOAT) {
+ error("track: data format error 4 (i=%d)", i);
+ return;
+ }
+ patname = argv[base+0].a_w.w_symbol;
+ patrows = (t_int)argv[base+1].a_w.w_float;
+ debugprint("pattern %d: %s-%s-%s, length=%d, RxC=%d", i,
+ song_name->s_name, track_name->s_name, patname->s_name,
+ patrows, patrows * x->x_ncolumns);
+ base += 2;
+ if(argc >= (base + patrows * x->x_ncolumns) && patrows > 0) {
+ pat = pattern_new(x, patname, patrows);
+ debugprint("created new pattern " PTR " ('%s', %d rows) for track " PTR, pat, patname->s_name, patrows, x);
+ int j,h,k;
+ for(h = 0, j = base; j < (base + patrows * x->x_ncolumns); j += x->x_ncolumns, h++) {
+ debugprint(" working on row %d", h);
+ for(k = 0; k < x->x_ncolumns; k++) {
+ pattern_setcell(pat, h, k, &argv[j+k]);
+ }
+ }
+ base += patrows * x->x_ncolumns;
+ } else {
+ error("track: data format error 8 (i=%d)", i);
+ return;
+ }
+ }
+}
+
+static void track_binbuf_save(t_track* x, t_symbol* selector, t_binbuf* b) {
+ // data format:
+ // SELECTOR DATA <song_name> <track_name> <npatterns> [<pat_name> <pat rows> RxC_atoms]*n
+
+ binbuf_addv(b, "ssssi", selector, gensym("DATA"),
+ t->x_song->x_name, t->x_name, t->x_patterns_count);
+
+ int i,j,k;
+ for(i = 0; i < t->x_patterns_count; i++) {
+ t_pattern* pat = t->x_patterns[i];
+ binbuf_addv(b, "si", pat->x_name, pat->x_rows_count);
+ for(j = 0; j < pat->x_rows_count; j++) {
+ for(k = 0; k < t->x_ncolumns; k++) {
+ switch(pat->x_rows[j][k].a_type) {
+ case A_FLOAT: binbuf_addv(b, "f", pat->x_rows[j][k].a_w.w_float); break;
+ case A_SYMBOL: binbuf_addv(b, "s", pat->x_rows[j][k].a_w.w_symbol); break;
+ case A_NULL: binbuf_addv(b, "s", gensym("empty")); break;
+ default: binbuf_addv(b, "s", gensym("unknown")); break;
+ }
+ }
+ //binbuf_add(b, t->x_ncolumns, &pat->x_rows[j]);
+ }
+ }
+
+ binbuf_addv(b, ";");
+}
diff --git a/composer/track_proxy.c b/composer/track_proxy.c
index b4e57ce..e83e474 100644
--- a/composer/track_proxy.c
+++ b/composer/track_proxy.c
@@ -28,6 +28,11 @@
t_class* track_proxy_class;
+static t_atom response_pattern_length[2];
+static t_atom response_cell[4];
+static t_atom* response_row; // TODO: memory leaks check
+static size_t response_row_sz;
+
void track_proxy_setup(void) {
debugprint("registering 'track' class...");
ArrayListInit(songs, t_song*, 10);
@@ -106,13 +111,17 @@ static void track_proxy_free(t_track_proxy* x) {
pd_unbind(&x->x_obj.ob_pd, x->rcv);
}
-static void track_proxy_sendgui_pattern_names(t_track_proxy* x) {
- debugprint("track_proxy_sendgui_pattern_names(" PTR ")", x);
+static t_atom* track_proxy_get_pattern_names(t_track_proxy* x) {
t_int n = track_get_pattern_count(x->x_track);
- t_atom* a = (t_atom*)getbytes(sizeof(t_atom)*n);
- track_get_pattern_names(x->x_track, a);
- track_proxy_sendgui(x, gensym("patterns"), n, a);
- freebytes(a, sizeof(t_atom)*n);
+ if(response_row) {
+ freebytes(response_row, response_row_sz);
+ response_row = NULL;
+ response_row_sz = 0;
+ }
+ response_row_sz = sizeof(t_atom) * n;
+ response_row = (t_atom*)getbytes(response_row_sz);
+ track_get_pattern_names(x->x_track, response_row);
+ return response_row;
}
static void track_proxy_reload(t_track_proxy* x) {
@@ -143,30 +152,7 @@ static void track_proxy_save(t_gobj* z, t_binbuf* b) {
(t_int)x->x_obj.te_xpix, (t_int)x->x_obj.te_ypix,
gensym("track"), t->x_song->x_name, t->x_name, t->x_ncolumns);
- // data format:
- // TRACK_SELECTOR DATA <song_name> <track_name> <npatterns> [<pat_name> <pat rows> RxC_atoms]*n
-
- binbuf_addv(b, "ssssi", gensym(TRACK_SELECTOR), gensym("DATA"),
- t->x_song->x_name, t->x_name, t->x_patterns_count);
-
- int i,j,k;
- for(i = 0; i < t->x_patterns_count; i++) {
- t_pattern* pat = t->x_patterns[i];
- binbuf_addv(b, "si", pat->x_name, pat->x_rows_count);
- for(j = 0; j < pat->x_rows_count; j++) {
- for(k = 0; k < t->x_ncolumns; k++) {
- switch(pat->x_rows[j][k].a_type) {
- case A_FLOAT: binbuf_addv(b, "f", pat->x_rows[j][k].a_w.w_float); break;
- case A_SYMBOL: binbuf_addv(b, "s", pat->x_rows[j][k].a_w.w_symbol); break;
- case A_NULL: binbuf_addv(b, "s", gensym("empty")); break;
- default: binbuf_addv(b, "s", gensym("unknown")); break;
- }
- }
- //binbuf_add(b, t->x_ncolumns, &pat->x_rows[j]);
- }
- }
-
- binbuf_addv(b, ";");
+ track_binbuf_save(t, gensym(TRACK_SELECTOR), b);
}
static void track_proxy_sendrow(t_track_proxy* x, t_pattern* pat, t_int row) {
@@ -177,7 +163,7 @@ static void track_proxy_sendrow(t_track_proxy* x, t_pattern* pat, t_int row) {
}
static void track_proxy_anything(t_track_proxy* x, t_symbol* s, int argc, t_atom* argv) {
- debugprint("track_proxy_anything(" PTR ", %s, %d, " PTR ")", s, s->s_name, argc, argv);
+ debugprint("track_proxy_anything(" PTR ", %s, %d, " PTR ")", x, s->s_name, argc, argv);
if(s == gensym("DATA")) {
track_proxy_loaddata(x, s, argc, argv);
@@ -192,90 +178,18 @@ static void track_proxy_anything(t_track_proxy* x, t_symbol* s, int argc, t_atom
}
static void track_proxy_loaddata(t_track_proxy* x, t_symbol* s, int argc, t_atom* argv) {
- int i,base;
- base = 0;
-
- if(argc < (base+2) || argv[base].a_type != A_SYMBOL || argv[base+1].a_type != A_SYMBOL) {
- error("track: data format error 1");
- return;
- }
- t_symbol* song_name = argv[base+0].a_w.w_symbol;
- t_symbol* track_name = argv[base+1].a_w.w_symbol;
- base += 2;
-
- if(x->x_track->x_song->x_name != song_name) {
- debugprint("WARNING: discarding data from another song: %s", song_name->s_name);
- return;
- }
-
- if(x->x_track->x_name != track_name) {
- debugprint("WARNING: discarding data from another track: %s", track_name->s_name);
- return;
- }
-
- if(argc < (base+1) || argv[base].a_type != A_FLOAT) {
- error("track: data format error 2");
- return;
- }
- t_int npatterns = (t_int)argv[base].a_w.w_float;
- base += 1;
-
- debugprint("track: %s-%s: %d patterns to read", song_name->s_name, track_name->s_name, npatterns);
-
- t_symbol* patname;
- t_int patrows;
- t_pattern* pat;
-
- debugprint("track_proxy_loaddata(" PTR ", %s, %d, " PTR ")", x, s->s_name, argc, argv);
- for(i = 0; i < npatterns; i++) {
- debugprint("reading pattern %d...", i);
- if(argc < (base + 2)) {
- error("track: data format error 3 (i=%d)", i);
- return;
- }
- if(argv[base+0].a_type != A_SYMBOL || argv[base+1].a_type != A_FLOAT) {
- error("track: data format error 4 (i=%d)", i);
- return;
- }
- patname = argv[base+0].a_w.w_symbol;
- patrows = (t_int)argv[base+1].a_w.w_float;
- debugprint("pattern %d: %s-%s-%s, length=%d, RxC=%d", i,
- song_name->s_name, track_name->s_name, patname->s_name,
- patrows, patrows * x->x_track->x_ncolumns);
- base += 2;
- if(argc >= (base + patrows * x->x_track->x_ncolumns) && patrows > 0) {
- pat = pattern_new(x->x_track, patname, patrows);
- debugprint("created new pattern " PTR " ('%s', %d rows) for track " PTR, pat, patname->s_name, patrows, x->x_track);
- int j,h,k;
- for(h = 0, j = base; j < (base + patrows * x->x_track->x_ncolumns); j += x->x_track->x_ncolumns, h++) {
- debugprint(" working on row %d", h);
- for(k = 0; k < x->x_track->x_ncolumns; k++) {
- pattern_setcell(pat, h, k, &argv[j+k]);
- }
- }
- base += patrows * x->x_track->x_ncolumns;
- } else {
- error("track: data format error 8 (i=%d)", i);
- return;
- }
- }
+ track_loaddata(x->x_track, argc, argv);
}
static t_atom* track_proxy_getpatternlength(t_track_proxy* x, t_symbol* pat_name) {
- /*if(argc < 1 || argv[0].a_type != A_SYMBOL) {
- error("track: getpatternlength: usage: getpatternlength <pattern_name>");
- return NULL;
- }
- t_symbol* pat_name = argv[0].a_w.w_symbol;*/
ArrayListGetByName(x->x_track->x_patterns, pat_name, t_pattern*, pat);
if(!pat) {
error("track: getpatternlength: no such pattern: '%s'", pat_name->s_name);
return NULL;
}
- t_atom* pl = (t_atom*)getbytes(sizeof(t_atom) * 2);
- SETSYMBOL(&pl[0], pat->x_name);
- SETFLOAT(&pl[1], pat->x_rows_count);
- return pl;
+ SETSYMBOL(&response_pattern_length[0], pat->x_name);
+ SETFLOAT(&response_pattern_length[1], pat->x_rows_count);
+ return &response_pattern_length[0];
}
static void track_proxy_editcmd(t_track_proxy* x, t_symbol* s_, int argc, t_atom* argv_) {
@@ -306,11 +220,13 @@ static void track_proxy_editcmd(t_track_proxy* x, t_symbol* s_, int argc, t_atom
} else if(s == gensym("editor-close")) {
track_proxy_properties_close((t_gobj*) x, NULL);
} else if(s == gensym("getpatterns")) {
- track_proxy_sendgui_pattern_names(x);
+ t_atom* rsp = track_proxy_get_pattern_names(x);
+ track_proxy_sendgui(x, gensym("patterns"), response_row_sz, rsp);
} else if(s == gensym("getpatternlength")) {
track_proxy_sendgui(x, gensym("patternlength"), 2, track_proxy_getpatternlength(x, s1));
} else if(s == gensym("getrow")) {
- track_proxy_sendgui(x, gensym("row"), x->x_track->x_ncolumns + 2, track_proxy_getrow_with_header(x, s1, f2));
+ t_atom* rsp = track_proxy_getrow_with_header(x, s1, f2);
+ track_proxy_sendgui(x, gensym("row"), response_row_sz, rsp);
} else if(s == gensym("setrow")) {
track_proxy_setrow(x, s, argc, argv);
} else if(s == gensym("getcell")) {
@@ -320,12 +236,14 @@ static void track_proxy_editcmd(t_track_proxy* x, t_symbol* s_, int argc, t_atom
} else if(s == gensym("addpattern")) {
p = track_proxy_addpattern(x, s1, f2);
if(p) {
- track_proxy_sendgui_pattern_names(x);
+ t_atom* rsp = track_proxy_get_pattern_names(x);
+ track_proxy_sendgui(x, gensym("patterns"), response_row_sz, rsp);
}
} else if(s == gensym("removepattern")) {
j = track_proxy_removepattern(x, s1);
if(j) {
- track_proxy_sendgui_pattern_names(x);
+ t_atom* rsp = track_proxy_get_pattern_names(x);
+ track_proxy_sendgui(x, gensym("patterns"), response_row_sz, rsp);
}
} else if(s == gensym("resizepattern")) {
p = track_proxy_resizepattern(x, s1, f2);
@@ -335,12 +253,14 @@ static void track_proxy_editcmd(t_track_proxy* x, t_symbol* s_, int argc, t_atom
} else if(s == gensym("renamepattern")) {
p = track_proxy_renamepattern(x, s1, s2);
if(p) {
- track_proxy_sendgui_pattern_names(x);
+ t_atom* rsp = track_proxy_get_pattern_names(x);
+ track_proxy_sendgui(x, gensym("patterns"), response_row_sz, rsp);
}
} else if(s == gensym("copypattern")) {
p = track_proxy_copypattern(x, s1, s2);
if(p) {
- track_proxy_sendgui_pattern_names(x);
+ t_atom* rsp = track_proxy_get_pattern_names(x);
+ track_proxy_sendgui(x, gensym("patterns"), response_row_sz, rsp);
}
} else {
error("track: editcmd: unknown command: %s", s->s_name);
@@ -348,34 +268,9 @@ static void track_proxy_editcmd(t_track_proxy* x, t_symbol* s_, int argc, t_atom
}
static void track_proxy_sendgui(t_track_proxy* x, t_symbol* s, int argc, t_atom* argv) {
- static const unsigned int tmpsz = 80;
static const unsigned int bufsz = 8*MAXPDSTRING;
- char* tmp;
char buf[bufsz];
- int i,j;
- buf[0] = '\0';
- strncat(buf, s->s_name, bufsz);
- strncat(buf, " ", bufsz);
- for(i = 0; i < argc; i++) {
- if(i > 0) strncat(buf, " ", bufsz);
- if(argv[i].a_type == A_FLOAT) {
- tmp = (char*)getbytes(tmpsz*sizeof(char));
- if(argv[i].a_w.w_float == (t_float)(t_int)argv[i].a_w.w_float)
- sprintf(tmp, "%ld", (t_int)argv[i].a_w.w_float);
- else
- sprintf(tmp, "%f", argv[i].a_w.w_float);
- strncat(buf, tmp, bufsz);
- } else if(argv[i].a_type == A_SYMBOL) {
- strncat(buf, argv[i].a_w.w_symbol->s_name, bufsz);
- } else {
- strncat(buf, "null", bufsz);
- }
- }
- if(strlen(buf) >= bufsz) {
- debugprint("track: sendgui: message too long");
- bug("track: sendgui: message too long");
- return;
- }
+ list_snconvf(buf, bufsz, s, argc, argv);
debugprint("pd::composer::dispatch %s %s", x->rcv->s_name, buf);
sys_vgui("pd::composer::dispatch %s %s\n", x->rcv->s_name, buf);
}
@@ -425,16 +320,23 @@ static t_atom* track_proxy_getrow(t_track_proxy* x, t_symbol* pat_name, t_floata
}
static t_atom* track_proxy_getrow_with_header(t_track_proxy* x, t_symbol* pat_name, t_floatarg rownum) {
+ if(response_row) {
+ freebytes(response_row, response_row_sz);
+ response_row = NULL;
+ response_row_sz = 0;
+ }
+
t_atom* row = track_proxy_getrow(x, pat_name, rownum);
if(!row) {
error("track: getrow: nu such patern: '%s'", pat_name->s_name);
return NULL;
}
- t_atom* row_with_hdr = (t_atom*)getbytes(sizeof(t_atom) * (x->x_track->x_ncolumns + 2));
- SETSYMBOL(&row_with_hdr[0], pat_name);
- SETFLOAT(&row_with_hdr[1], rownum);
- memcpy(&row_with_hdr[2], row, sizeof(t_atom) * x->x_track->x_ncolumns);
- return row_with_hdr;
+ response_row_sz = sizeof(t_atom) * (x->x_track->x_ncolumns + 2);
+ t_atom* response_row = (t_atom*)getbytes(response_row_sz);
+ SETSYMBOL(&response_row[0], pat_name);
+ SETFLOAT(&response_row[1], rownum);
+ memcpy(&response_row[2], row, sizeof(t_atom) * x->x_track->x_ncolumns);
+ return &response_row[0];
}
static void track_proxy_getrow_o(t_track_proxy* x, t_symbol* pat_name, t_floatarg rownum) {
@@ -475,12 +377,11 @@ static t_atom* track_proxy_getcell_with_header(t_track_proxy* x, t_symbol* pat_n
error("track: getcell: nu such patern: '%s'", pat_name->s_name);
return NULL;
}
- t_atom* row_with_hdr = (t_atom*)getbytes(sizeof(t_atom) * 4);
- SETSYMBOL(&row_with_hdr[0], pat_name);
- SETFLOAT(&row_with_hdr[1], rownum);
- SETFLOAT(&row_with_hdr[2], colnum);
- memcpy(&row_with_hdr[3], cell, sizeof(t_atom));
- return row_with_hdr;
+ SETSYMBOL(&response_cell[0], pat_name);
+ SETFLOAT(&response_cell[1], rownum);
+ SETFLOAT(&response_cell[2], colnum);
+ memcpy(&response_cell[3], cell, sizeof(t_atom));
+ return &response_cell[0];
}
static void track_proxy_getcell_o(t_track_proxy* x, t_symbol* pat_name, t_floatarg rownum, t_floatarg colnum) {