aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormescalinum <mescalinum@users.sourceforge.net>2009-09-25 17:19:25 +0000
committermescalinum <mescalinum@users.sourceforge.net>2009-09-25 17:19:25 +0000
commitf8ac52e520aa5e20a256a3fd9a649b461f3afeef (patch)
tree25198f6081892058a8ba46b838bfa1f14076c565
parent2815cb8c2ff0edd77efcc071b65fed1e60c1c6bc (diff)
rewrite in C++
svn path=/trunk/externals/ffext/; revision=12451
-rw-r--r--composer/Makefile58
-rw-r--r--composer/Pattern.cpp81
-rw-r--r--composer/Pattern.hpp33
-rw-r--r--composer/PdClasses.cpp286
-rw-r--r--composer/PdClasses.hpp40
-rw-r--r--composer/Song.cpp42
-rw-r--r--composer/Song.hpp31
-rw-r--r--composer/TODO4
-rw-r--r--composer/Track.cpp47
-rw-r--r--composer/Track.hpp34
-rw-r--r--composer/arraylist.h118
-rw-r--r--composer/common.h199
-rw-r--r--composer/composer.c91
-rw-r--r--composer/editor.tk (renamed from composer/window.tk)0
-rw-r--r--composer/makefile34
-rw-r--r--composer/pattern.c165
-rw-r--r--composer/song.c104
-rw-r--r--composer/song_proxy.c402
-rw-r--r--composer/track.c204
-rw-r--r--composer/track_proxy.c441
20 files changed, 652 insertions, 1762 deletions
diff --git a/composer/Makefile b/composer/Makefile
new file mode 100644
index 0000000..dff36ef
--- /dev/null
+++ b/composer/Makefile
@@ -0,0 +1,58 @@
+#!/usr/bin/make
+
+DEBUG?=0
+OS := $(shell uname -s)
+TCL_VERSION := $(shell echo 'puts $$tcl_version' | tclsh)
+
+ifeq ($(DEBUG),0)
+ CFLAGS += -O2
+else
+ CFLAGS += -O0 -g -ggdb -DDEBUG
+endif
+ifeq ($(OS),Linux)
+ PDSUF = .pd_linux
+ PDBUNDLEFLAGS = -shared -rdynamic
+ LDSOFLAGS = -lm
+endif
+ifeq ($(OS),Darwin)
+ PDSUF = .pd_darwin
+ INCLUDES = -I/Library/Frameworks/Tcl.framework/Headers
+ PDBUNDLEFLAGS = -bundle -flat_namespace -undefined dynamic_lookup
+ LDSOFLAGS = -lm
+endif
+ifeq (MINGW,$(findstring MINGW,$(UNAME)))
+ PDSUF = .dll
+ PDBUNDLEFLAGS = -shared
+ LDSOFLAGS = -lm
+endif
+
+LIBNAME = composer
+INCLUDES = -I../../pd/src -I/usr/include #-I/usr/include/tcl$(TCL_VERSION)
+CFLAGS += -funroll-loops -fno-operator-names -fno-omit-frame-pointer -falign-functions=16 -Wall -fPIC
+CFLAGS += -DPDSUF=\"$(PDSUF)\"
+LDSHARED = $(CXX) $(PDBUNDLEFLAGS)
+
+all: $(LIBNAME)$(PDSUF)
+ @echo '-----------------------------------------------------------------------------'
+ @echo ' $(LIBNAME)$(PDSUF) ('`test $(DEBUG) -eq 1 && echo debug || echo release`' build) '\
+ '[size: '`ls -gGh $(LIBNAME)$(PDSUF) | cut -d " " -f 3`']'
+
+clean::
+ rm -f $(LIBNAME)$(PDSUF) *.o *~
+
+.SUFFIXES: .cpp .o
+
+SRCS = Song.cpp Pattern.cpp Track.cpp PdClasses.cpp
+OBJS = ${SRCS:.cpp=.o}
+
+Song.o: Song.cpp Song.hpp
+Pattern.o: Pattern.cpp Pattern.hpp
+Track.o: Track.cpp Track.hpp
+PdClass.o: PdClasses.cpp PdClasses.h
+
+.cpp.o: Makefile
+ $(CXX) $(CFLAGS) $(INCLUDES) -xc++ -c $<
+
+$(LIBNAME)$(PDSUF): Makefile $(OBJS)
+ $(LDSHARED) $(LDSOFLAGS) $(CFLAGS) -xnone $(OBJS) -o $(LIBNAME)$(PDSUF)
+
diff --git a/composer/Pattern.cpp b/composer/Pattern.cpp
new file mode 100644
index 0000000..69c60f4
--- /dev/null
+++ b/composer/Pattern.cpp
@@ -0,0 +1,81 @@
+#include "Pattern.hpp"
+
+#include <iostream>
+
+using std::cout;
+using std::cerr;
+using std::endl;
+
+Pattern::Pattern(int numRows, int numCols, string patternName)
+: name(patternName)
+{
+ Cell empty_cell;
+ Row empty_row;
+
+ SETSYMBOL(&empty_cell, gensym("empty"));
+
+ while(numCols-- > 0)
+ {
+ empty_row.push_back(empty_cell);
+ }
+
+ columns = empty_row.size();
+
+ while(numRows-- > 0)
+ {
+ Row row(empty_row);
+ rows.push_back(row);
+ }
+}
+
+void Pattern::print()
+{
+ cerr << "---- Pattern: " << name << " ----" << endl;
+
+ char buf[MAXPDSTRING];
+
+ for(unsigned int i = 0; i < rows.size(); i++)
+ {
+ cerr << " Row[" << i << "]: ";
+ for(unsigned int j = 0; j < rows[i].size(); j++)
+ {
+ if(j > 0) cerr << ", ";
+ atom_string(&rows[i][j], buf, MAXPDSTRING);
+ cerr << buf << endl;
+ }
+ }
+
+ cerr << "---- End pattern (" << name << ") ----" << endl;
+}
+
+void Pattern::resize(int numRows, int numCols)
+{
+ Cell empty_cell;
+ Row empty_row;
+
+ SETSYMBOL(&empty_cell, gensym("empty"));
+
+ while(numCols-- > 0)
+ {
+ empty_row.push_back(empty_cell);
+ }
+
+ rows.resize(numRows, empty_row);
+
+ for(unsigned int i = 0; i < rows.size(); i++)
+ {
+ rows[i].resize(empty_row.size(), empty_cell);
+ }
+
+ columns = empty_row.size();
+}
+
+void Pattern::setCell(int row, int col, Cell cell)
+{
+ rows[row][col] = cell;
+}
+
+Cell Pattern::getCell(int row, int col)
+{
+ return rows[row][col];
+}
diff --git a/composer/Pattern.hpp b/composer/Pattern.hpp
new file mode 100644
index 0000000..1607414
--- /dev/null
+++ b/composer/Pattern.hpp
@@ -0,0 +1,33 @@
+#ifndef COMPOSER_PATTERN_H_INCLUDED
+#define COMPOSER_PATTERN_H_INCLUDED
+
+#include <string>
+#include <vector>
+
+#include <m_pd.h>
+
+using std::string;
+using std::vector;
+
+typedef t_atom Cell;
+
+typedef vector<Cell> Row;
+
+class Pattern
+{
+private:
+ string name;
+ vector<Row> rows;
+ int columns;
+public:
+ Pattern(int numRows, int numCols, string patternName);
+ void print();
+ void resize(int numRows, int numCols);
+ void setCell(int row, int col, Cell cell);
+ Cell getCell(int row, int col);
+ inline const string &getName() {return name;}
+ inline unsigned int getRows() {return rows.size();}
+ inline unsigned int getColumns() {return columns;}
+};
+
+#endif // COMPOSER_PATTERN_H_INCLUDED
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 <iostream>
+
+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 <pattern#> <row#> <atom0> <atom1> ...");
+ 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();
+}
diff --git a/composer/PdClasses.hpp b/composer/PdClasses.hpp
new file mode 100644
index 0000000..acf261e
--- /dev/null
+++ b/composer/PdClasses.hpp
@@ -0,0 +1,40 @@
+#ifndef COMPOSER_PDCLASSES_H_INCLUDED
+#define COMPOSER_PDCLASSES_H_INCLUDED
+
+#include <m_pd.h>
+
+#define MAX_RESULT_SIZE 128
+
+#define TRACK_SELECTOR "#composer::track"
+#define SONG_SELECTOR "#composer::song"
+
+class Track;
+class Song;
+
+typedef struct _track_proxy
+{
+ t_object x_obj;
+ t_outlet *outlet;
+ Track *track;
+ t_int editor_open;
+ t_symbol *editor_recv;
+ t_symbol *editor_send;
+} t_track_proxy;
+
+void track_proxy_setup(void);
+static t_track_proxy *track_proxy_new(t_symbol *song_name, t_symbol *track_name);
+static void track_proxy_free(t_track_proxy *x);
+static void track_proxy_save(t_gobj *z, t_binbuf *b);
+static void track_proxy_send_result(t_track_proxy *x, int outlet, int editor);
+static int track_proxy_getpatterns(t_track_proxy *x);
+static int track_proxy_getpatternsize(t_track_proxy *x, t_floatarg pat);
+static int track_proxy_setrow(t_track_proxy *x, t_symbol *sel, int argc, t_atom *argv);
+static int track_proxy_getrow(t_track_proxy *x, t_floatarg pat, t_floatarg rownum);
+static int track_proxy_addpattern(t_track_proxy *x, t_symbol *name, t_floatarg rows, t_floatarg cols);
+static int track_proxy_removepattern(t_track_proxy *x, t_floatarg pat);
+static int track_proxy_resizepattern(t_track_proxy *x, t_floatarg pat, t_floatarg rows, t_floatarg cols);
+static int track_proxy_copypattern(t_track_proxy *x, t_symbol *src, t_symbol *dst);
+
+extern "C" void composer_setup(void);
+
+#endif // COMPOSER_PDCLASSES_H_INCLUDED
diff --git a/composer/Song.cpp b/composer/Song.cpp
new file mode 100644
index 0000000..c793504
--- /dev/null
+++ b/composer/Song.cpp
@@ -0,0 +1,42 @@
+#include "Song.hpp"
+
+#include <iostream>
+
+using std::cout;
+using std::cerr;
+using std::endl;
+
+map<string,Song *> Song::byname;
+
+Song::Song(string songName)
+: name(songName)
+{
+}
+
+Song *Song::byName(string songName)
+{
+ if(byname.find(songName) == byname.end())
+ byname[songName] = new Song(songName);
+
+ return byname[songName];
+}
+
+void Song::print()
+{
+ cerr << "---- Song: " << name << " ----" << endl;
+
+ for(map<string,Track *>::iterator i = tracks.begin(); i != tracks.end(); i++)
+ {
+ cerr << " Track[" << i->first << "]: " << i->first << endl;
+ }
+
+ cerr << "---- End song (" << name << ") ----" << endl;
+}
+
+Track *Song::getTrackByName(string trackName)
+{
+ if(tracks.find(trackName) == tracks.end())
+ return 0;
+ else
+ return tracks[trackName];
+}
diff --git a/composer/Song.hpp b/composer/Song.hpp
new file mode 100644
index 0000000..ead7285
--- /dev/null
+++ b/composer/Song.hpp
@@ -0,0 +1,31 @@
+#ifndef COMPOSER_SONG_H_INCLUDED
+#define COMPOSER_SONG_H_INCLUDED
+
+#include <map>
+#include <string>
+
+#include <m_pd.h>
+
+#include "Track.hpp"
+
+using std::map;
+using std::string;
+
+class Song
+{
+private:
+ static map<string,Song *> byname;
+public:
+ static Song *byName(string songName);
+private:
+ string name;
+ map<string,Track *> tracks;
+protected:
+ Song(string songName);
+public:
+ void print();
+ Track *getTrackByName(string trackName);
+ inline const string &getName() {return name;}
+};
+
+#endif // COMPOSER_SONG_H_INCLUDED
diff --git a/composer/TODO b/composer/TODO
deleted file mode 100644
index 9ccc4ae..0000000
--- a/composer/TODO
+++ /dev/null
@@ -1,4 +0,0 @@
-TODO:
- - optimize performance of symbol->index lookups, especially for patterns
- - check for memory leaks
- - compress in-patch data
diff --git a/composer/Track.cpp b/composer/Track.cpp
new file mode 100644
index 0000000..47ad81b
--- /dev/null
+++ b/composer/Track.cpp
@@ -0,0 +1,47 @@
+#include "Song.hpp"
+#include "Track.hpp"
+#include "Pattern.hpp"
+
+#include <iostream>
+
+using std::cout;
+using std::cerr;
+using std::endl;
+
+Track::Track(Song *_song, string trackName)
+: name(trackName), song(_song)
+{
+}
+
+Track *Track::byName(string songName, string trackName)
+{
+ Song *song = Song::byName(songName);
+
+ Track *track = song->getTrackByName(trackName);
+ if(!track) track = new Track(song, trackName);
+
+ return track;
+}
+
+void Track::print()
+{
+ cerr << "---- Track: " << name << " ----" << endl;
+
+ for(unsigned int i = 0; i < patterns.size(); i++)
+ {
+ cerr << " Pattern[" << patterns[i]->getName() << "]: " << patterns[i]->getName() << endl;
+ }
+
+ cerr << "---- End track (" << name << ") ----" << endl;
+}
+
+void Track::addPattern(int rows, int cols, string name)
+{
+ Pattern *pattern = new Pattern(rows, cols, name);
+ patterns.push_back(pattern);
+}
+
+Pattern *Track::getPattern(int n)
+{
+ return patterns[n];
+}
diff --git a/composer/Track.hpp b/composer/Track.hpp
new file mode 100644
index 0000000..3bd2135
--- /dev/null
+++ b/composer/Track.hpp
@@ -0,0 +1,34 @@
+#ifndef COMPOSER_TRACK_H_INCLUDED
+#define COMPOSER_TRACK_H_INCLUDED
+
+#include <string>
+#include <vector>
+
+#include <m_pd.h>
+
+using std::string;
+using std::vector;
+
+class Song;
+class Pattern;
+
+class Track
+{
+public:
+ static Track *byName(string songName, string trackName);
+private:
+ string name;
+ vector<Pattern *> patterns;
+ Song *song;
+protected:
+ Track(Song *_song, string trackName);
+public:
+ void print();
+ void addPattern(int rows, int cols, string name);
+ Pattern *getPattern(int n);
+ inline unsigned int getPatternCount() {return patterns.size();}
+ inline Song *getSong() {return song;}
+ inline const string &getName() {return name;}
+};
+
+#endif // COMPOSER_TRACK_H_INCLUDED
diff --git a/composer/arraylist.h b/composer/arraylist.h
deleted file mode 100644
index b625379..0000000
--- a/composer/arraylist.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/* ------------------------------------------------------------------------ */
-/* 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. */
-/* */
-/* 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 */
-/* 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. */
-/* */
-/* ------------------------------------------------------------------------ */
-
-#include "common.h"
-
-#ifndef __ARRAYLIST_H_INCLUDED_
-#define __ARRAYLIST_H_INCLUDED_
-
-#define ArrayListDeclare(name, type, sizetype) \
- type* name; \
- sizetype name ## _maxsize; \
- sizetype name ## _count
-
-#define ArrayListDeclareWithPrefix(prefix, name, type, sizetype) \
- prefix type* name; \
- prefix sizetype name ## _maxsize; \
- prefix sizetype name ## _count
-
-#define ArrayListInit(arrName, type, initSize) \
- arrName ## _maxsize = initSize; \
- if(initSize > 0) arrName = (type*)getbytes(sizeof(type) * (initSize)); \
- else arrName = NULL; \
- arrName ## _count = 0
-
-#define ArrayListAdd(arrName, type, objToAdd) \
- if(arrName ## _count >= arrName ## _maxsize) { \
- arrName = (type*)resizebytes(arrName, arrName ## _maxsize, (arrName ## _maxsize)*2); \
- }; \
- arrName[ arrName ## _count ++ ] = (type) objToAdd; \
-
-#define ArrayListRemove(arrName, objToRem) \
- { \
- int i,j; \
- for(i=0; i< arrName ## _count; i++) \
- if(arrName[i] == objToRem) { \
- for(j=i; j< arrName ## _count - 1; j++) { \
- arrName[j] = arrName[j+1]; \
- } \
- arrName[ arrName ## _count -- ] = 0L; \
- break; \
- } \
- }
-
-#define ArrayListRemoveByIndex(arrName, index) \
- { \
- int i,j; \
- for(i=0; i< arrName ## _count; i++) \
- if(i == index) { \
- for(j=i; j< arrName ## _count - 1; j++) { \
- arrName[j] = arrName[j+1]; \
- } \
- arrName[ arrName ## _count -- ] = 0L; \
- break; \
- } \
- }
-
-#define ArrayListRemoveByName(arrName, name) \
- { \
- int i,j; \
- for(i=0; i< arrName ## _count; i++) \
- if(arrName[i] && arrName[i]->x_name == name) { \
- for(j=i; j< arrName ## _count - 1; j++) { \
- arrName[j] = arrName[j+1]; \
- } \
- arrName[ arrName ## _count -- ] = 0L; \
- break; \
- } \
- }
-
-#define ArrayListGetByName(arrName, n, type, result) \
- type result = (type) 0L; \
- if(arrName) { \
- int i; \
- for(i=0; i< arrName ## _count; i++) { \
- if(arrName[i] && arrName[i]->x_name == n) { \
- result = arrName[i]; break; \
- } \
- } \
- }
-
-#define ArrayListGetIndexByName(arrName, n, type, result) \
- type result = (type) -1; \
- if(arrName) { \
- int i; \
- for(i=0; i< arrName ## _count; i++) { \
- if(arrName[i] && arrName[i]->x_name == n) { \
- result = i; \
- break; \
- } \
- } \
- }
-
-#define ArrayListFree(arrName, type) \
- freebytes(arrName, arrName ## _maxsize * sizeof(type))
-
-#endif // __ARRAYLIST_H_INCLUDED_
diff --git a/composer/common.h b/composer/common.h
deleted file mode 100644
index 1dc78c0..0000000
--- a/composer/common.h
+++ /dev/null
@@ -1,199 +0,0 @@
-/* ------------------------------------------------------------------------ */
-/* 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. */
-/* ------------------------------------------------------------------------ */
-
-#ifndef COMPOSER_COMMON_H_INCLUDED
-#define COMPOSER_COMMON_H_INCLUDED
-
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include "m_pd.h"
-#include "m_imp.h"
-#include "g_canvas.h"
-#include "s_stuff.h"
-#include "t_tk.h"
-#include <unistd.h>
-#include <stdio.h>
-#include "arraylist.h"
-
-#define PTR "0x%lx"
-#ifdef DEBUG
-#define debugprint(args...) post( args )
-#define DEBUG_BOOL 1
-#else
-#define debugprint(args...)
-#define DEBUG_BOOL 0
-#endif
-
-#define STRINGIFY(x) #x
-
-#define WRAP(v, w) (((v) < 0 ? (1+(int)((-(v))/(w)))*(w) : (v)) % w)
-
-#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;
-
-typedef struct _song
-{
- t_symbol* x_name;
- ArrayListDeclare(x_tracks, struct _track*, t_int);
- struct _track* x_mastertrack;
-} t_song;
-
-typedef struct _song_proxy
-{
- t_object x_obj;
- t_outlet* outlet;
- t_song* x_song;
- t_int b_editor_open;
- t_symbol* rcv;
-} t_song_proxy;
-
-typedef struct _track
-{
- t_symbol* x_name;
- t_song* x_song;
- t_int x_ncolumns;
- t_outlet* outlet;
- ArrayListDeclare(x_patterns, struct _pattern*, t_int);
- t_float x_currentpat;
-} t_track;
-
-typedef struct _track_proxy
-{
- t_object x_obj;
- t_outlet* outlet;
- t_track* x_track;
- t_int b_editor_open;
- t_symbol* rcv;
-} t_track_proxy;
-
-typedef struct _pattern
-{
- t_symbol* x_name;
- t_track* x_track;
- ArrayListDeclare(x_rows, t_atom*, t_int);
-} 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 void song_internal_resize_cols(t_song* x, t_int sz);
-static t_song* song_get(t_symbol* song_name);
-static int song_exists(t_symbol* song_name);
-static void song_loaddata(t_song* x, int argc, t_atom* argv);
-static void song_binbuf_save(t_song* t, t_symbol* selector, t_binbuf* b);
-
-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, t_symbol* selector, t_binbuf* b);
-
-
-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_init_cell(t_atom* a);
-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);
-static t_atom* pattern_getcell(t_pattern* x, t_int row, t_int col);
-static void pattern_setrow(t_pattern* x, t_int row, t_atom* rowdata);
-static void pattern_setcell(t_pattern* x, t_int row, t_int col, t_atom* a);
-static t_pattern* pattern_get(t_symbol* song_name, t_symbol* track_name, t_symbol* pattern_name);
-static int pattern_exists(t_symbol* song_name, t_symbol* track_name, t_symbol* pattern_name);
-
-void song_proxy_setup(void);
-static t_song_proxy* song_proxy_new(t_symbol* song_name);
-static void song_proxy_free(t_song_proxy* x);
-static t_atom* song_proxy_get_pattern_names(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_loadsonginfo(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);
-
-void track_proxy_setup(void);
-static t_track_proxy* track_proxy_new(t_symbol* song_name, t_symbol* track_name, t_floatarg cols);
-static void track_proxy_free(t_track_proxy* x);
-static void track_proxy_reload(t_track_proxy* x);
-static void track_proxy_properties(t_gobj* z, t_glist* owner);
-static void track_proxy_properties_close(t_gobj* z, t_glist* owner);
-static void track_proxy_save(t_gobj* z, t_binbuf* b);
-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);
-static void track_proxy_loaddata(t_track_proxy* x, t_symbol* s, int argc, t_atom* argv);
-static t_atom* track_proxy_getpatternlength(t_track_proxy* x, t_symbol* pat_name);
-static void track_proxy_editcmd(t_track_proxy* x, t_symbol* s, int argc, t_atom* argv);
-static void track_proxy_sendgui(t_track_proxy* x, t_symbol* s, int argc, t_atom* argv);
-static void track_proxy_float(t_track_proxy* x, t_floatarg f);
-static void track_proxy_setrow(t_track_proxy* x, t_symbol* sel, int argc, t_atom* argv);
-static t_atom* track_proxy_getrow(t_track_proxy* x, t_symbol* pat_name, t_floatarg rownum);
-static t_atom* track_proxy_getrow_with_header(t_track_proxy* x, t_symbol* pat_name, t_floatarg rownum);
-static void track_proxy_getrow_o(t_track_proxy* x, t_symbol* pat_name, t_floatarg rownum);
-static void track_proxy_setcell(t_track_proxy* x, t_symbol* sel, int argc, t_atom* argv);
-static t_atom* track_proxy_getcell(t_track_proxy* x, t_symbol* pat_name, t_floatarg rownum, t_floatarg colnum);
-static t_atom* track_proxy_getcell_with_header(t_track_proxy* x, t_symbol* pat_name, t_floatarg rownum, t_floatarg colnum);
-static void track_proxy_getcell_o(t_track_proxy* x, t_symbol* pat_name, t_floatarg rownum, t_floatarg colnum);
-static t_pattern* track_proxy_addpattern(t_track_proxy* x, t_symbol* name, t_floatarg rows);
-static int track_proxy_removepattern(t_track_proxy* x, t_symbol* name);
-static t_pattern* track_proxy_resizepattern(t_track_proxy* x, t_symbol* name, t_floatarg rows);
-static t_pattern* track_proxy_renamepattern(t_track_proxy* x, t_symbol* name, t_symbol* newname);
-static t_pattern* track_proxy_copypattern(t_track_proxy* x, t_symbol* src, t_symbol* dst);
-
-ArrayListDeclareWithPrefix(extern, songs, t_song*, int);
-
-void composer_setup(void);
-
-#endif // COMPOSER_COMMON_H_INCLUDED
diff --git a/composer/composer.c b/composer/composer.c
deleted file mode 100644
index 6d86758..0000000
--- a/composer/composer.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/* ------------------------------------------------------------------------ */
-/* 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"
-
-#include "song.c"
-#include "track.c"
-#include "pattern.c"
-#include "song_proxy.c"
-#include "track_proxy.c"
-
-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");
- song_proxy_setup();
- track_proxy_setup();
-}
diff --git a/composer/window.tk b/composer/editor.tk
index 1b90732..1b90732 100644
--- a/composer/window.tk
+++ b/composer/editor.tk
diff --git a/composer/makefile b/composer/makefile
deleted file mode 100644
index 9db256c..0000000
--- a/composer/makefile
+++ /dev/null
@@ -1,34 +0,0 @@
-DEBUG?=0
-
-all: pd_linux
-
-.SUFFIXES: .pd_linux
-
-pd_linux: composer.pd_linux
-
-LINUXCFLAGS = -DPD -DUNIX -DPIC -fPIC \
- -funroll-loops -fomit-frame-pointer \
- -Wall -W -Wno-shadow -Wstrict-prototypes \
- -Wno-unused -Wno-parentheses -Wno-switch
-LINUXINCLUDE = -I/usr/src/pd/0.41.4/src -I/usr/include
-LINUXLDFLAGS = -export_dynamic -shared
-
-ifeq ($(DEBUG),1)
- LINUXCFLAGS += -O0 -g -ggdb -DDEBUG
- STRIP=test -f
-else
- LINUXCFLAGS += -O2
- STRIP=strip --strip-unneeded
-endif
-
-composer.pd_linux: track.c pattern.c \
- track_proxy.c \
- composer.c common.h arraylist.h
- $(CC) $(LINUXCFLAGS) $(LINUXINCLUDE) -o composer.o -c composer.c
- $(LD) $(LINUXLDFLAGS) -o composer.pd_linux composer.o -lc -lm
- $(STRIP) composer.pd_linux
-
-clean:
- rm -f *.o *.pd_linux
-
-
diff --git a/composer/pattern.c b/composer/pattern.c
deleted file mode 100644
index 6772b6b..0000000
--- a/composer/pattern.c
+++ /dev/null
@@ -1,165 +0,0 @@
-/* ------------------------------------------------------------------------ */
-/* 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);
-}
-
-/* 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 i,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);
- }
- if(newcols > x->x_track->x_ncolumns) {
- for(j = 0; j < x->x_rows_count; j++) {
- for(i = x->x_track->x_ncolumns; i < newcols; i++)
- pattern_init_cell(&x->x_rows[j][i]);
- }
- }
- x->x_track->x_ncolumns = newcols;
-}
-
-static void pattern_init_cell(t_atom* a) {
- if(a) SETSYMBOL(a, gensym("empty"));
-}
-
-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;
- for(j = 0; j < x->x_track->x_ncolumns; j++)
- pattern_init_cell(&rowdata[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;
-}
diff --git a/composer/song.c b/composer/song.c
deleted file mode 100644
index 6129181..0000000
--- a/composer/song.c
+++ /dev/null
@@ -1,104 +0,0 @@
-/* ------------------------------------------------------------------------ */
-/* 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_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);
- 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);
- // 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",
- x, x->x_name->s_name);
-
- ArrayListAdd(songs, t_song*, x);
- debugprint("registered song object to global song collection");
- 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);
- if(x->x_mastertrack->x_patterns_count < x->x_mastertrack->x_ncolumns) {
- debugprint("song_mastertrack_fix_cols: still loading (apparently?), skipping.");
- return;
- }
- song_internal_resize_cols(x, x->x_tracks_count);
-}
-
-static void song_free(t_song* x) {
- // free tracks memory
- ArrayListFree(x->x_tracks, t_track*);
- // remove song from global song collection
- ArrayListRemove(songs, x);
-}
-
-static void song_internal_resize_cols(t_song* x, t_int sz) {
- 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], sz);
- }
-}
-
-static t_song* song_get(t_symbol* song_name) {
- ArrayListGetByName(songs, song_name, t_song*, result);
- return result;
-}
-
-static int song_exists(t_symbol* song_name) {
- return song_get(song_name) != 0L;
-}
-
-static void song_loaddata(t_song* x, int argc, t_atom* argv) {
- if(argc < 2) {
- error("song_loaddata: format error 1");
- return;
- }
- if(argv[0].a_type != A_SYMBOL || argv[1].a_type != A_FLOAT) {
- error("song_loaddata: format error 2");
- }
- t_symbol* name = argv[0].a_w.w_symbol;
- t_int ntracks = (t_int)argv[1].a_w.w_float;
- debugprint("song_loaddata: song='%s', tracks=%d", name->s_name, ntracks);
- song_internal_resize_cols(x, ntracks);
-}
-
-static void song_binbuf_save(t_song* t, t_symbol* selector, t_binbuf* b) {
- // data format:
- // SELECTOR DATA <song_name> <ntracks>
-
- binbuf_addv(b, "sssi", selector, gensym("SONGINFO"), t->x_name, t->x_tracks_count);
- binbuf_addv(b, ";");
-}
diff --git a/composer/song_proxy.c b/composer/song_proxy.c
deleted file mode 100644
index 00b1440..0000000
--- a/composer/song_proxy.c
+++ /dev/null
@@ -1,402 +0,0 @@
-/* ------------------------------------------------------------------------ */
-/* 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"
-
-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(
- gensym("song"),
- (t_newmethod)song_proxy_new,
- (t_method)song_proxy_free,
- sizeof(t_song_proxy),
- CLASS_DEFAULT, //0,
- A_SYMBOL,
- 0
- );
- class_addfloat(song_proxy_class, song_proxy_float);
- class_addanything(song_proxy_class, song_proxy_anything);
- class_addmethod(song_proxy_class, (t_method)song_proxy_properties, \
- gensym("editor-open"), 0);
- class_addmethod(song_proxy_class, (t_method)song_proxy_properties_close, \
- gensym("editor-close"), 0);
- class_addmethod(song_proxy_class, (t_method)song_proxy_setrow, \
- gensym("setrow"), A_GIMME, 0);
- class_addmethod(song_proxy_class, (t_method)song_proxy_getrow_o, \
- gensym("getrow"), A_SYMBOL, A_FLOAT, 0);
- class_addmethod(song_proxy_class, (t_method)song_proxy_setcell, \
- gensym("setcell"), A_GIMME, 0);
- class_addmethod(song_proxy_class, (t_method)song_proxy_getcell_o, \
- gensym("getcell"), A_SYMBOL, A_FLOAT, A_FLOAT, 0);
- class_addmethod(song_proxy_class, (t_method)song_proxy_resizepattern, \
- gensym("resizepattern"), A_SYMBOL, A_FLOAT, 0);
-#if PD_MINOR_VERSION >= 37
- class_setpropertiesfn(song_proxy_class, song_proxy_properties);
- class_setsavefn(song_proxy_class, song_proxy_save);
-#endif
- class_sethelpsymbol(song_proxy_class, gensym("song.pd"));
-}
-
-static t_song_proxy* song_proxy_new(t_symbol* song_name) {
- t_song_proxy *x = (t_song_proxy*)pd_new(song_proxy_class);
- 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, "song_proxy-%s", x->x_song->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);
-
- song_proxy_properties_close((t_gobj*) x, NULL);
-
- pd_bind(&x->x_obj.ob_pd, gensym(SONG_SELECTOR));
- pd_bind(&x->x_obj.ob_pd, gensym(TRACK_SELECTOR));
-
- debugprint("pd::composer::init %s %s %s %d %s %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, "Arrangement", DEBUG_BOOL);
- sys_vgui("pd::composer::init %s %s %s %d %s %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, "Arrangement", 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));
- pd_unbind(&x->x_obj.ob_pd, gensym(TRACK_SELECTOR));
-
- /* LATER find a way to get SONG_SELECTOR unbound earlier (at end of load?) */
- /* Was this code needed? for what?
- 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 t_atom* song_proxy_get_pattern_names(t_song_proxy* x) {
- if(response_row) {
- freebytes(response_row, response_row_sz * sizeof(t_atom));
- response_row = NULL;
- response_row_sz = 0;
- }
- response_row_sz = track_get_pattern_count(x->x_song->x_mastertrack);
- response_row = (t_atom*)getbytes(sizeof(t_atom) * response_row_sz);
- track_get_pattern_names(x->x_song->x_mastertrack, response_row);
- return response_row;
-}
-
-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_song_proxy* x = (t_song_proxy*)z;
- t_song* s = x->x_song;
- t_track* t = s->x_mastertrack;
-
- binbuf_addv(b, "ssiiss;", gensym("#X"), gensym("obj"),
- (t_int)x->x_obj.te_xpix, (t_int)x->x_obj.te_ypix,
- gensym("song"), s->x_name);
-
- song_binbuf_save(s, gensym(SONG_SELECTOR), b);
-
- 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 * sizeof(t_atom));
- response_row = NULL;
- response_row_sz = 0;
- }
- response_row_sz = x->x_song->x_tracks_count;
- response_row = (t_atom*)getbytes(response_row_sz * sizeof(t_atom));
- 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 if(s == gensym("SONGINFO")) {
- song_proxy_loadsonginfo(x, s, argc, argv);
- return;
- } else {
- error("unrecognized command for anything method: %s ", s->s_name);
- return;
- }
-}
-
-static void song_proxy_loadsonginfo(t_song_proxy* x, t_symbol* s, int argc, t_atom* argv) {
- song_loaddata(x->x_song, argc, argv);
-}
-
-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("getpatterns")) {
- t_atom* rsp = song_proxy_get_pattern_names(x);
- song_proxy_sendgui(x, gensym("patterns"), response_row_sz, rsp);
- } else if(s == gensym("gettracks")) {
- t_atom* rsp = song_proxy_gettracks(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 * sizeof(t_atom));
- response_row = NULL;
- response_row_sz = 0;
- }
-
- t_atom* row = song_proxy_getrow(x, pat_name, rownum);
- if(!row) {
- error("song: getrow: no such pattern: '%s'", pat_name->s_name);
- return NULL;
- }
- fprintf(stderr, "GOT A ROW " PTR ", 2 + %d (=? %d) columns, last a_type = %d\n", (long unsigned int)row, (int)x->x_song->x_mastertrack->x_ncolumns, (int)x->x_song->x_tracks_count, 0);
- response_row_sz = x->x_song->x_mastertrack->x_ncolumns + 2;
- t_atom* response_row = (t_atom*)getbytes(response_row_sz * sizeof(t_atom));
- 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);
- if(response_row[2].a_type == A_SYMBOL)
- fprintf(stderr, "VALUE[2] = %s\n", response_row[2].a_w.w_symbol->s_name);
- else if(response_row[2].a_type == A_FLOAT)
- fprintf(stderr, "VALUE[2] = %f\n", response_row[2].a_w.w_float);
- else
- fprintf(stderr, "VALUE[2] = ? (type = %d)\n", response_row[2].a_type);
-
- 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: no such pattern: '%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;
-}
diff --git a/composer/track.c b/composer/track.c
deleted file mode 100644
index 477fdfd..0000000
--- a/composer/track.c
+++ /dev/null
@@ -1,204 +0,0 @@
-/* ------------------------------------------------------------------------ */
-/* 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_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("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));
- x->x_name = track_name;
- x->x_song = song;
- x->x_ncolumns = columns;
- ArrayListInit(x->x_patterns, struct _pattern*, 4);
- x->x_currentpat = 0;
-
- debugprint("created a track object (" PTR "), "
- "creation args: %s, %s, %d",
- x, x->x_song->x_name->s_name, x->x_name->s_name, x->x_ncolumns);
-
- debugprint("song_create_track returns " PTR, x);
- return x;
-}
-
-static void track_free(t_track* x) {
- // free patterns memory
- ArrayListFree(x->x_patterns, t_pattern*);
- // remove track from song's track list
- ArrayListRemove(x->x_song->x_tracks, x);
-}
-
-static t_int track_get_pattern_count(t_track* x) {
- return x->x_patterns_count;
-}
-
-static void track_get_pattern_names(t_track* x, t_atom* /* OUT */ out) {
- int i;
- for(i = 0; i < x->x_patterns_count; i++) {
- SETSYMBOL(&out[i], x->x_patterns[i]->x_name);
- }
-}
-
-static t_track* track_get(t_symbol* song_name, t_symbol* track_name) {
- t_song* song = song_get(song_name);
- if(!song || !song->x_tracks) return (t_track*) 0L;
- ArrayListGetByName(song->x_tracks, track_name, t_track*, result);
- return result;
-}
-
-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) {
- debugprint("track_loaddata(" PTR ", %d, " PTR ")", x, argc, 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;
- }
-
- debugprint("track_loaddata: song='%s', track='%s'", song_name->s_name, track_name->s_name);
-
- 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_loaddata: %d patterns to read", 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* t, 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
deleted file mode 100644
index 509cccb..0000000
--- a/composer/track_proxy.c
+++ /dev/null
@@ -1,441 +0,0 @@
-/* ------------------------------------------------------------------------ */
-/* 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"
-
-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);
- track_proxy_class = class_new(
- gensym("track"),
- (t_newmethod)track_proxy_new,
- (t_method)track_proxy_free,
- sizeof(t_track_proxy),
- CLASS_DEFAULT, //0,
- A_SYMBOL, A_SYMBOL, A_FLOAT,
- 0
- );
- class_addfloat(track_proxy_class, track_proxy_float);
- class_addanything(track_proxy_class, track_proxy_anything);
- class_addmethod(track_proxy_class, (t_method)track_proxy_properties, \
- gensym("editor-open"), 0);
- class_addmethod(track_proxy_class, (t_method)track_proxy_properties_close, \
- gensym("editor-close"), 0);
- class_addmethod(track_proxy_class, (t_method)track_proxy_reload, \
- gensym("reload"), 0);
- class_addmethod(track_proxy_class, (t_method)track_proxy_setrow, \
- gensym("setrow"), A_GIMME, 0);
- class_addmethod(track_proxy_class, (t_method)track_proxy_getrow_o, \
- gensym("getrow"), A_SYMBOL, A_FLOAT, 0);
- class_addmethod(track_proxy_class, (t_method)track_proxy_setcell, \
- gensym("setcell"), A_GIMME, 0);
- class_addmethod(track_proxy_class, (t_method)track_proxy_getcell_o, \
- gensym("getcell"), A_SYMBOL, A_FLOAT, A_FLOAT, 0);
- class_addmethod(track_proxy_class, (t_method)track_proxy_addpattern, \
- gensym("addpattern"), A_SYMBOL, A_FLOAT, 0);
- class_addmethod(track_proxy_class, (t_method)track_proxy_removepattern, \
- gensym("removepattern"), A_SYMBOL, 0);
- class_addmethod(track_proxy_class, (t_method)track_proxy_resizepattern, \
- gensym("resizepattern"), A_SYMBOL, A_FLOAT, 0);
- class_addmethod(track_proxy_class, (t_method)track_proxy_renamepattern, \
- gensym("renamepattern"), A_SYMBOL, A_SYMBOL, 0);
- class_addmethod(track_proxy_class, (t_method)track_proxy_copypattern, \
- gensym("copypattern"), A_SYMBOL, A_SYMBOL, 0);
-#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_floatarg cols) {
- t_track_proxy *x = (t_track_proxy*)pd_new(track_proxy_class);
- x->outlet = outlet_new(&x->x_obj, &s_list);
- x->x_track = track_new(song_name, track_name, (t_int)cols);
- x->b_editor_open = 0;
- char rcv_buf[80];
- sprintf(rcv_buf, "track_proxy-%s-%s", x->x_track->x_song->x_name->s_name, x->x_track->x_name->s_name);
- x->rcv = gensym(rcv_buf);
- pd_bind(&x->x_obj.ob_pd, x->rcv);
- debugprint("created an instance of t_track_proxy " PTR ", to_track=" PTR ", n=%s",
- x, x->x_track, x->x_track->x_name->s_name);
-
- track_proxy_properties_close((t_gobj*) x, NULL);
-
- pd_bind(&x->x_obj.ob_pd, gensym(TRACK_SELECTOR));
-
- debugprint("pd::composer::init %s %s %s %d %s %d\n", x->rcv->s_name, x->x_track->x_song->x_name->s_name, x->x_track->x_name->s_name, x->x_track->x_ncolumns, "NULL", DEBUG_BOOL);
- sys_vgui("pd::composer::init %s %s %s %d %s %d\n", x->rcv->s_name, x->x_track->x_song->x_name->s_name, x->x_track->x_name->s_name, x->x_track->x_ncolumns, "NULL", DEBUG_BOOL);
-
- return x;
-}
-
-static void track_proxy_free(t_track_proxy* x) {
- track_proxy_properties_close((t_gobj*) x, NULL);
-
- 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->rcv);
-}
-
-static t_atom* track_proxy_get_pattern_names(t_track_proxy* x) {
- if(response_row) {
- freebytes(response_row, response_row_sz * sizeof(t_atom));
- response_row = NULL;
- response_row_sz = 0;
- }
- response_row_sz = track_get_pattern_count(x->x_track);
- response_row = (t_atom*)getbytes(sizeof(t_atom) * response_row_sz);
- track_get_pattern_names(x->x_track, response_row);
- return response_row;
-}
-
-static void track_proxy_reload(t_track_proxy* x) {
- sys_vgui("source {window.tk}\n");
-}
-
-static void track_proxy_properties(t_gobj* z, t_glist* owner) {
- t_track_proxy* x = (t_track_proxy*)z;
- sys_vgui("pd::composer::openWindow %s\n", x->rcv->s_name);
- x->b_editor_open = 1;
-}
-
-static void track_proxy_properties_close(t_gobj* z, t_glist* owner) {
- t_track_proxy* x = (t_track_proxy*)z;
- debugprint("track_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 track_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 void track_proxy_sendrow(t_track_proxy* x, t_pattern* pat, t_int row) {
- t_track* t = x->x_track;
- if(row < 0) row = 0;
- row = row % pat->x_rows_count;
- outlet_list(x->outlet, &s_list, t->x_ncolumns, pat->x_rows[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 ")", x, s->s_name, argc, argv);
-
- if(s == gensym("DATA")) {
- track_proxy_loaddata(x, s, argc, argv);
- return;
- } else if(s == gensym("EDIT")) {
- track_proxy_editcmd(x, s, argc, argv);
- return;
- } else {
- error("unrecognized command for anything method: %s ", s->s_name);
- return;
- }
-}
-
-static void track_proxy_loaddata(t_track_proxy* x, t_symbol* s, int argc, t_atom* argv) {
- track_loaddata(x->x_track, argc, argv);
-}
-
-static t_atom* track_proxy_getpatternlength(t_track_proxy* x, t_symbol* pat_name) {
- 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;
- }
- 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_) {
- 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")) {
- track_proxy_properties((t_gobj*) x, NULL);
- } else if(s == gensym("editor-close")) {
- track_proxy_properties_close((t_gobj*) x, NULL);
- } else if(s == gensym("getpatterns")) {
- 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")) {
- 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")) {
- track_proxy_sendgui(x, gensym("cell"), 4, track_proxy_getcell_with_header(x, s1, f2, f3));
- } else if(s == gensym("setcell")) {
- track_proxy_setcell(x, s, argc, argv);
- } else if(s == gensym("addpattern")) {
- p = track_proxy_addpattern(x, s1, f2);
- if(p) {
- 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) {
- 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);
- if(p) {
- track_proxy_sendgui(x, gensym("patternlength"), 2, track_proxy_getpatternlength(x, p->x_name));
- }
- } else if(s == gensym("renamepattern")) {
- p = track_proxy_renamepattern(x, s1, s2);
- if(p) {
- 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) {
- t_atom* rsp = track_proxy_get_pattern_names(x);
- track_proxy_sendgui(x, gensym("patterns"), response_row_sz, rsp);
- }
- } else if(s == gensym("gettracks")) {
- // dummy STFU
- } else {
- error("track: editcmd: unknown command: %s", s->s_name);
- }
-}
-
-static void track_proxy_sendgui(t_track_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 track_proxy_float(t_track_proxy* x, t_floatarg f) {
- t_track* t = x->x_track;
- if(t->x_patterns_count < 1) return;
-
- t_int curpat_i = (t_int) t->x_currentpat;
-
- if(curpat_i < 0) curpat_i = 0;
- curpat_i = curpat_i % t->x_patterns_count;
-
- t_pattern* curpat = t->x_patterns[curpat_i];
- track_proxy_sendrow(x, curpat, (t_int) f);
-}
-
-static void track_proxy_setrow(t_track_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("track: setrow: usage: setrow <pattern_name> <row#> <atom0> <atom1> ...");
- return;
- }
- if((argc - 2) != x->x_track->x_ncolumns) {
- post("argc=%d, ncolumns=%d", argc, x->x_track->x_ncolumns);
- error("track: setrow: input error: must provide exactly %d elements for the row", x->x_track->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_track->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* track_proxy_getrow(t_track_proxy* x, t_symbol* pat_name, t_floatarg rownum) {
- ArrayListGetByName(x->x_track->x_patterns, pat_name, t_pattern*, pat);
- if(!pat) {
- error("track: getrow: no such pattern: '%s'", pat_name->s_name);
- return NULL;
- }
- t_atom* row = pattern_getrow(pat, (t_int)rownum);
- debugprint("track_proxy_getrow returning " PTR, row);
- return row;
-}
-
-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 * sizeof(t_atom));
- response_row = NULL;
- response_row_sz = 0;
- }
-
- t_atom* row = track_proxy_getrow(x, pat_name, rownum);
- if(!row) {
- error("track: getrow: no such pattern: '%s'", pat_name->s_name);
- return NULL;
- }
- response_row_sz = x->x_track->x_ncolumns + 2;
- t_atom* response_row = (t_atom*)getbytes(response_row_sz * sizeof(t_atom));
- 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) {
- t_atom* row = track_proxy_getrow(x, pat_name, rownum);
- if(row)
- outlet_list(x->outlet, &s_list, x->x_track->x_ncolumns, row);
-}
-
-static void track_proxy_setcell(t_track_proxy* x, t_symbol* sel, int argc, t_atom* argv) {
- debugprint("track_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("track: 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_track->x_patterns, pat_name, t_pattern*, pat);
- if(!pat) {
- error("track: setcell: no such pattern: '%s'", pat_name->s_name);
- return;
- }
- pattern_setcell(pat, (t_int)rownum, (t_int)colnum, &argv[3]);
-}
-
-static t_atom* track_proxy_getcell(t_track_proxy* x, t_symbol* pat_name, t_floatarg rownum, t_floatarg colnum) {
- ArrayListGetByName(x->x_track->x_patterns, pat_name, t_pattern*, pat);
- if(!pat) {
- error("track: getcell: no such pattern: '%s'", pat_name->s_name);
- return NULL;
- }
- return pattern_getcell(pat, (t_int)rownum, (t_int)colnum);
-}
-
-static t_atom* track_proxy_getcell_with_header(t_track_proxy* x, t_symbol* pat_name, t_floatarg rownum, t_floatarg colnum) {
- t_atom* cell = track_proxy_getcell(x, pat_name, rownum, colnum);
- if(!cell) {
- error("track: getcell: no such pattern: '%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 track_proxy_getcell_o(t_track_proxy* x, t_symbol* pat_name, t_floatarg rownum, t_floatarg colnum) {
- t_atom* cell = track_proxy_getcell(x, pat_name, rownum, colnum);
- if(cell)
- outlet_list(x->outlet, &s_list, 1, cell);
-}
-
-static t_pattern* track_proxy_addpattern(t_track_proxy* x, t_symbol* name, t_floatarg rows) {
- return pattern_new(x->x_track, name, (t_int)rows);
-}
-
-static int track_proxy_removepattern(t_track_proxy* x, t_symbol* name) {
- ArrayListGetByName(x->x_track->x_patterns, name, t_pattern*, pat);
- if(!pat) {
- error("track: removepattern: no such pattern: '%s'", name->s_name);
- return 0; //FAIL
- }
- pattern_free(pat);
- return 1; //OK
-}
-
-static t_pattern* track_proxy_resizepattern(t_track_proxy* x, t_symbol* name, t_floatarg rows) {
- ArrayListGetByName(x->x_track->x_patterns, name, t_pattern*, pat);
- if(!pat) {
- error("track: resizepattern: no such pattern: '%s'", name->s_name);
- return NULL;
- }
- pattern_resize(pat, (t_int)rows);
- return pat;
-}
-
-static t_pattern* track_proxy_renamepattern(t_track_proxy* x, t_symbol* name, t_symbol* newname) {
- ArrayListGetByName(x->x_track->x_patterns, name, t_pattern*, pat);
- if(!pat) {
- error("track: renamepattern: no such pattern: '%s'", name->s_name);
- return NULL;
- }
- pattern_rename(pat, newname);
- return pat;
-}
-
-static t_pattern* track_proxy_copypattern(t_track_proxy* x, t_symbol* src, t_symbol* dst) {
- ArrayListGetByName(x->x_track->x_patterns, src, t_pattern*, pat);
- if(!pat) {
- error("track: copypattern: no such pattern: '%s'", src->s_name);
- return NULL;
- }
- ArrayListGetByName(x->x_track->x_patterns, dst, t_pattern*, pat2);
- if(pat2) {
- error("track: copypattern: destination '%s' exists", pat2->x_name->s_name);
- return NULL;
- }
- return pattern_clone(pat, dst);
-}