aboutsummaryrefslogtreecommitdiff
path: root/composer/pattern.c
diff options
context:
space:
mode:
Diffstat (limited to 'composer/pattern.c')
-rw-r--r--composer/pattern.c142
1 files changed, 142 insertions, 0 deletions
diff --git a/composer/pattern.c b/composer/pattern.c
new file mode 100644
index 0000000..134b802
--- /dev/null
+++ b/composer/pattern.c
@@ -0,0 +1,142 @@
+/* ------------------------------------------------------------------------ */
+/* Copyright (c) 2009 Federico Ferri. */
+/* 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 */
+/* */
+/* This program is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU General Public License */
+/* as published by the Free Software Foundation; either version 2 */
+/* of the License, or (at your option) any later version. */
+/* */
+/* See file LICENSE for further informations on licensing terms. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* 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"
+
+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);
+ if(obj) return obj;
+
+ t_pattern* x = (t_pattern*)getbytes(sizeof(t_pattern));
+ x->x_name = name;
+ x->x_track = track;
+ ArrayListInit(x->x_rows, t_atom*, rows);
+
+ int i;
+ for(i = 0; i < rows; i++) {
+ debugprint("x->x_rows[%d] = " PTR, i, x->x_rows[i]);
+ pattern_new_empty_row(x);
+ debugprint("x->x_rows[%d] <- " PTR, i, x->x_rows[i]);
+ }
+
+ debugprint("created new pattern " PTR " with %d rows (x_rows = " PTR ")", x, x->x_rows_count, x->x_rows);
+
+ // add pattern to track's pattern list
+ ArrayListAdd(x->x_track->x_patterns, t_pattern*, x);
+ return x;
+}
+
+static t_pattern* pattern_clone(t_pattern* src, t_symbol* newname) {
+ t_pattern* x = (t_pattern*)getbytes(sizeof(t_pattern));
+ x->x_name = newname;
+ x->x_track = src->x_track;
+ ArrayListInit(x->x_rows, t_atom*, src->x_rows_count);
+
+ int i;
+ for(i = 0; i < src->x_rows_count; i++) {
+ ArrayListAdd(x->x_rows, t_atom*, pattern_clone_row(x, src->x_rows[i]));
+ }
+
+ ArrayListAdd(x->x_track->x_patterns, t_pattern*, x);
+ return x;
+}
+
+static void pattern_free(t_pattern* x) {
+ // free rows memory
+ ArrayListFree(x->x_rows, t_atom*);
+ // remove pattern from track's pattern list
+ ArrayListRemove(x->x_track->x_patterns, x);
+}
+
+static void pattern_rename(t_pattern* x, t_symbol* newname) {
+ x->x_name = newname;
+}
+
+static void pattern_resize(t_pattern *x, t_int newsize) {
+ debugprint("pattern_resize(" PTR ", %d)", x, newsize);
+ debugprint("initial size: %d", x->x_rows_count);
+ while(x->x_rows_count < newsize)
+ pattern_new_empty_row(x);
+ while(x->x_rows_count > newsize)
+ ArrayListRemoveByIndex(x->x_rows, x->x_rows_count - 1);
+ debugprint("final size: %d", x->x_rows_count);
+}
+
+static void pattern_new_empty_row(t_pattern* x) {
+ t_atom* rowdata = (t_atom*)getbytes(sizeof(t_atom) * x->x_track->x_ncolumns);
+ SETSYMBOL(&(rowdata[0]), gensym("test"));
+ int j;
+ for(j = 1; j < x->x_track->x_ncolumns; j++)
+ SETFLOAT(&(rowdata[j]), j);
+ ArrayListAdd(x->x_rows, t_atom*, rowdata);
+}
+
+static t_atom* pattern_getrow(t_pattern* x, t_int row) {
+ debugprint("pattern_getrow(" PTR ", %d)", x, row);
+ row = WRAP(row, x->x_rows_count);
+ t_atom* rowdata = x->x_rows[row];
+ return rowdata;
+}
+
+static t_atom* pattern_clone_row(t_pattern* x, t_atom* rowdata) {
+ debugprint("pattern_clone_row(" PTR ", " PTR ")", x, rowdata);
+ t_atom* clone = (t_atom*)copybytes(rowdata, sizeof(t_atom) * x->x_track->x_ncolumns);
+ return clone;
+}
+
+static t_atom* pattern_getcell(t_pattern* x, t_int row, t_int col) {
+ row = WRAP(row, x->x_rows_count);
+ col = WRAP(col, x->x_track->x_ncolumns);
+ return &(x->x_rows[row][col]);
+}
+
+static void pattern_setrow(t_pattern* x, t_int row, t_atom* rowdata) {
+ debugprint("pattern_setrow(" PTR ", %d, " PTR ")", x, row, rowdata);
+ row = WRAP(row, x->x_rows_count);
+ debugprint("x->x_rows[%d] = " PTR, row, x->x_rows[row]);
+ t_atom *myrowdata = x->x_rows[row];
+ memcpy(myrowdata, rowdata, sizeof(t_atom) * x->x_track->x_ncolumns);
+ debugprint("x->x_rows[%d] <- " PTR, row, x->x_rows[row]);
+}
+
+static void pattern_setcell(t_pattern* x, t_int row, t_int col, t_atom* a) {
+ row = WRAP(row, x->x_rows_count);
+ col = WRAP(col, x->x_track->x_ncolumns);
+ debugprint("about to write an atom (size=%d) at address " PTR, sizeof(t_atom), &(x->x_rows[row][col]));
+ memcpy(&(x->x_rows[row][col]), a, sizeof(t_atom));
+}
+
+static t_pattern* pattern_get(t_symbol* song_name, t_symbol* track_name, t_symbol* pattern_name) {
+ t_track* track = track_get(song_name, track_name);
+ if(!track || !track->x_patterns) return (t_pattern*) 0L;
+ ArrayListGetByName(track->x_patterns, pattern_name, t_pattern*, result);
+ return result;
+}
+
+static int pattern_exists(t_symbol* song_name, t_symbol* track_name, t_symbol* pattern_name) {
+ return pattern_get(song_name, track_name, pattern_name) != 0L;
+}