aboutsummaryrefslogtreecommitdiff
path: root/composer/track.c
diff options
context:
space:
mode:
Diffstat (limited to 'composer/track.c')
-rw-r--r--composer/track.c130
1 files changed, 126 insertions, 4 deletions
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, ";");
+}