diff options
author | mescalinum <mescalinum@users.sourceforge.net> | 2009-09-25 17:19:25 +0000 |
---|---|---|
committer | mescalinum <mescalinum@users.sourceforge.net> | 2009-09-25 17:19:25 +0000 |
commit | f8ac52e520aa5e20a256a3fd9a649b461f3afeef (patch) | |
tree | 25198f6081892058a8ba46b838bfa1f14076c565 /composer | |
parent | 2815cb8c2ff0edd77efcc071b65fed1e60c1c6bc (diff) |
rewrite in C++
svn path=/trunk/externals/ffext/; revision=12451
Diffstat (limited to 'composer')
-rw-r--r-- | composer/Makefile | 58 | ||||
-rw-r--r-- | composer/Pattern.cpp | 81 | ||||
-rw-r--r-- | composer/Pattern.hpp | 33 | ||||
-rw-r--r-- | composer/PdClasses.cpp | 286 | ||||
-rw-r--r-- | composer/PdClasses.hpp | 40 | ||||
-rw-r--r-- | composer/Song.cpp | 42 | ||||
-rw-r--r-- | composer/Song.hpp | 31 | ||||
-rw-r--r-- | composer/TODO | 4 | ||||
-rw-r--r-- | composer/Track.cpp | 47 | ||||
-rw-r--r-- | composer/Track.hpp | 34 | ||||
-rw-r--r-- | composer/arraylist.h | 118 | ||||
-rw-r--r-- | composer/common.h | 199 | ||||
-rw-r--r-- | composer/composer.c | 91 | ||||
-rw-r--r-- | composer/editor.tk (renamed from composer/window.tk) | 0 | ||||
-rw-r--r-- | composer/makefile | 34 | ||||
-rw-r--r-- | composer/pattern.c | 165 | ||||
-rw-r--r-- | composer/song.c | 104 | ||||
-rw-r--r-- | composer/song_proxy.c | 402 | ||||
-rw-r--r-- | composer/track.c | 204 | ||||
-rw-r--r-- | composer/track_proxy.c | 441 |
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); -} |