aboutsummaryrefslogtreecommitdiff
path: root/tms5220~
diff options
context:
space:
mode:
Diffstat (limited to 'tms5220~')
-rw-r--r--tms5220~/Makefile3
-rw-r--r--tms5220~/tms5220~-help.pd260
-rw-r--r--tms5220~/tms5220~.c181
3 files changed, 334 insertions, 110 deletions
diff --git a/tms5220~/Makefile b/tms5220~/Makefile
index 4c72e4d..eb775d4 100644
--- a/tms5220~/Makefile
+++ b/tms5220~/Makefile
@@ -32,6 +32,7 @@ MANUAL =
# automatically included
EXTRA_DIST =
+LIBS = -lsamplerate
#------------------------------------------------------------------------------#
@@ -58,7 +59,7 @@ INSTALL_DIR = $(INSTALL) -p -m 755 -d
CFLAGS = -DPD -I$(PD_PATH)/src -Wall -W -g
LDFLAGS =
-LIBS =
+#LIBS =
ALLSOURCES := $(SOURCES) $(SOURCES_android) $(SOURCES_cygwin) $(SOURCES_macosx) \
$(SOURCES_iphoneos) $(SOURCES_linux) $(SOURCES_windows)
diff --git a/tms5220~/tms5220~-help.pd b/tms5220~/tms5220~-help.pd
index d1dcbd0..edf216a 100644
--- a/tms5220~/tms5220~-help.pd
+++ b/tms5220~/tms5220~-help.pd
@@ -1,109 +1,179 @@
-#N canvas 4 100 590 524 10;
-#X obj 283 167 tms5220~;
-#X obj 283 456 dac~;
-#X obj 350 409 hsl 128 15 0 1 0 0 empty empty OUTPUT_LEVEL -2 -8 0
+#N canvas 221 103 826 512 10;
+#X obj 53 93 tms5220~;
+#X obj 53 382 dac~;
+#X obj 120 335 hsl 128 15 0 1 0 0 empty empty OUTPUT_LEVEL -2 -8 0
10 -262144 -1 -1 12700 1;
-#X obj 283 408 *~ 0;
-#X msg 347 449 \; pd dsp 1;
-#X text 377 199 <-- interrupt;
-#X text 376 221 <-- ready;
-#X text 376 244 <-- status bits;
-#X msg 310 127 reset;
+#X obj 53 334 *~ 0;
+#X msg 117 375 \; pd dsp 1;
+#X text 147 125 <-- interrupt;
+#X text 146 147 <-- ready;
+#X text 146 170 <-- status bits;
+#X msg 80 62 reset;
#X text 43 473 (C) Federico Ferri - 2010;
-#X obj 47 316 * 16;
-#X msg 47 79 0;
-#X text 85 76 nop;
-#X text 133 43 (check the TMS5220 datasheet for description of commands)
-;
-#X obj 47 357 |;
-#X obj 139 221 vradio 8 1 0 16 empty empty empty 0 -8 0 10 -262144
--1 -1 4;
-#X text 162 274 << address;
-#X msg 47 99 1;
-#X msg 47 119 2;
-#X msg 47 139 3;
-#X msg 47 159 4;
-#X msg 47 179 5;
-#X msg 47 199 6;
-#X msg 47 219 7;
-#X text 85 96 read byte;
-#X text 85 116 nop;
-#X text 85 136 read & branch;
-#X text 85 156 load address;
-#X text 85 176 speak;
-#X text 85 196 speak external;
-#X text 85 216 reset;
-#X text 46 45 COMMANDS:;
-#X obj 298 242 t a a a;
-#X obj 298 339 & 16;
-#X obj 317 300 & 32;
-#X obj 337 261 & 64;
-#X obj 328 196 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0
+#X obj 68 168 t a a a;
+#X obj 68 265 & 16;
+#X obj 87 226 & 32;
+#X obj 107 187 & 64;
+#X obj 98 122 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0
1;
-#X obj 313 219 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 1
+#X obj 83 145 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 1
1;
-#X obj 337 280 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 64
+#X obj 107 206 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 64
64;
-#X obj 317 319 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 32
+#X obj 87 245 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 32
32;
-#X obj 298 358 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0
+#X obj 68 284 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0
1;
-#X text 368 280 <-- talk_status;
-#X text 348 318 <-- buffer_low;
-#X text 327 359 <-- buffer_empty;
-#N canvas 761 102 450 299 rand.test 0;
-#X obj 50 37 inlet;
-#X obj 52 162 random 16;
-#X obj 51 125 until;
-#X obj 62 270 outlet;
-#X msg 138 105 96;
-#X obj 54 188 | 64;
-#X msg 54 101 9;
-#X obj 57 68 t b b b;
-#X msg 181 105 reset;
-#X msg 47 221 write \$1;
-#X connect 0 0 7 0;
-#X connect 1 0 5 0;
-#X connect 2 0 1 0;
-#X connect 4 0 9 0;
-#X connect 5 0 9 0;
-#X connect 6 0 2 0;
-#X connect 7 0 6 0;
-#X connect 7 1 4 0;
-#X connect 7 2 8 0;
-#X connect 8 0 3 0;
-#X connect 9 0 3 0;
-#X restore 77 411 pd rand.test;
-#X obj 77 385 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1
+#X text 138 206 <-- talk_status;
+#X text 118 244 <-- buffer_low;
+#X text 97 285 <-- buffer_empty;
+#X obj 53 35 r \$0.in;
+#X obj 344 123 s \$0.in;
+#X msg 344 36 silent;
+#X msg 361 64 stop;
+#X msg 334 273 repeat \$1 \$2;
+#X obj 334 299 s \$0.in;
+#X obj 382 223 hsl 64 15 0 63 0 0 empty empty PITCH -2 -8 0 10 -262144
+-1 -1 2600 1;
+#X obj 337 194 hsl 64 15 1 14 0 0 empty empty ENERGY -2 -8 0 10 -262144
+-1 -1 4400 1;
+#X obj 334 248 pack f f;
+#X obj 491 379 s \$0.in;
+#X obj 539 78 hsl 64 15 0 63 0 0 empty empty PITCH -2 -8 0 10 -262144
+-1 -1 1400 1;
+#X obj 494 49 hsl 64 15 1 14 0 0 empty empty ENERGY -2 -8 0 10 -262144
+-1 -1 600 1;
+#X obj 491 103 pack f f;
+#X obj 431 74 metro 25;
+#X obj 430 50 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0
+1;
+#X obj 491 139 list append;
+#X obj 566 139 hsl 64 15 0 31 0 1 empty empty kn -2 -8 0 10 -262144
+-1 -1 0 1;
+#X obj 567 159 hsl 64 15 0 31 0 1 empty empty kn -2 -8 0 10 -262144
+-1 -1 1900 1;
+#X obj 567 179 hsl 64 15 0 15 0 1 empty empty kn -2 -8 0 10 -262144
+-1 -1 5100 1;
+#X obj 568 199 hsl 64 15 0 15 0 1 empty empty kn -2 -8 0 10 -262144
+-1 -1 1600 1;
+#X obj 491 159 list append;
+#X obj 491 179 list append;
+#X obj 491 199 list append;
+#X obj 568 219 hsl 64 15 0 15 0 1 empty empty kn -2 -8 0 10 -262144
+-1 -1 3500 1;
+#X obj 491 219 list append;
+#X obj 568 239 hsl 64 15 0 15 0 1 empty empty kn -2 -8 0 10 -262144
+-1 -1 1500 1;
+#X obj 491 239 list append;
+#X obj 568 259 hsl 64 15 0 15 0 1 empty empty kn -2 -8 0 10 -262144
+-1 -1 2700 1;
+#X obj 491 259 list append;
+#X obj 568 279 hsl 64 15 0 7 0 1 empty empty kn -2 -8 0 10 -262144
+-1 -1 0 1;
+#X obj 491 279 list append;
+#X obj 568 299 hsl 64 15 0 7 0 1 empty empty kn -2 -8 0 10 -262144
+-1 -1 100 1;
+#X obj 491 299 list append;
+#X obj 568 319 hsl 64 15 0 7 0 1 empty empty kn -2 -8 0 10 -262144
+-1 -1 600 1;
+#X obj 491 319 list append;
+#X obj 491 338 list prepend voiced;
+#X obj 491 359 list trim;
+#X obj 651 379 s \$0.in;
+#X obj 699 78 hsl 64 15 0 63 0 0 empty empty PITCH -2 -8 0 10 -262144
+-1 -1 3300 1;
+#X obj 654 49 hsl 64 15 1 14 0 0 empty empty ENERGY -2 -8 0 10 -262144
+-1 -1 6300 1;
+#X obj 651 103 pack f f;
+#X obj 651 139 list append;
+#X obj 726 139 hsl 64 15 0 31 0 1 empty empty kn -2 -8 0 10 -262144
+-1 -1 4100 1;
+#X obj 727 159 hsl 64 15 0 31 0 1 empty empty kn -2 -8 0 10 -262144
+-1 -1 0 1;
+#X obj 727 179 hsl 64 15 0 15 0 1 empty empty kn -2 -8 0 10 -262144
+-1 -1 5800 1;
+#X obj 728 199 hsl 64 15 0 15 0 1 empty empty kn -2 -8 0 10 -262144
+-1 -1 0 1;
+#X obj 651 159 list append;
+#X obj 651 179 list append;
+#X obj 651 199 list append;
+#X obj 651 359 list trim;
+#X obj 651 338 list prepend unvoiced;
+#X obj 621 71 metro 25;
+#X obj 620 47 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0
+1;
+#X obj 297 220 metro 25;
+#X obj 296 196 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0
+1;
+#X obj 503 74 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1
+-1;
+#X obj 677 75 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1
-1;
-#X obj 283 69 r \$0.in;
-#X obj 47 443 s \$0.in;
#X connect 0 0 3 0;
-#X connect 0 1 32 0;
-#X connect 0 2 37 0;
-#X connect 0 3 36 0;
+#X connect 0 1 10 0;
+#X connect 0 2 15 0;
+#X connect 0 3 14 0;
#X connect 2 0 3 1;
#X connect 2 0 4 0;
#X connect 3 0 1 0;
#X connect 3 0 1 1;
#X connect 8 0 0 0;
-#X connect 10 0 14 0;
-#X connect 11 0 10 0;
-#X connect 14 0 47 0;
-#X connect 15 0 14 1;
-#X connect 17 0 10 0;
-#X connect 18 0 10 0;
-#X connect 19 0 10 0;
-#X connect 20 0 10 0;
-#X connect 21 0 10 0;
-#X connect 22 0 10 0;
-#X connect 23 0 10 0;
-#X connect 32 0 33 0;
-#X connect 32 1 34 0;
-#X connect 32 2 35 0;
-#X connect 33 0 40 0;
-#X connect 34 0 39 0;
-#X connect 35 0 38 0;
-#X connect 44 0 47 0;
-#X connect 45 0 44 0;
-#X connect 46 0 0 0;
+#X connect 10 0 11 0;
+#X connect 10 1 12 0;
+#X connect 10 2 13 0;
+#X connect 11 0 18 0;
+#X connect 12 0 17 0;
+#X connect 13 0 16 0;
+#X connect 22 0 0 0;
+#X connect 24 0 23 0;
+#X connect 25 0 23 0;
+#X connect 26 0 27 0;
+#X connect 28 0 30 1;
+#X connect 29 0 30 0;
+#X connect 30 0 26 0;
+#X connect 32 0 34 1;
+#X connect 33 0 34 0;
+#X connect 34 0 37 0;
+#X connect 35 0 34 0;
+#X connect 36 0 35 0;
+#X connect 37 0 42 0;
+#X connect 38 0 37 1;
+#X connect 39 0 42 1;
+#X connect 40 0 43 1;
+#X connect 41 0 44 1;
+#X connect 42 0 43 0;
+#X connect 43 0 44 0;
+#X connect 44 0 46 0;
+#X connect 45 0 46 1;
+#X connect 46 0 48 0;
+#X connect 47 0 48 1;
+#X connect 48 0 50 0;
+#X connect 49 0 50 1;
+#X connect 50 0 52 0;
+#X connect 51 0 52 1;
+#X connect 52 0 54 0;
+#X connect 53 0 54 1;
+#X connect 54 0 56 0;
+#X connect 55 0 56 1;
+#X connect 56 0 57 0;
+#X connect 57 0 58 0;
+#X connect 58 0 31 0;
+#X connect 60 0 62 1;
+#X connect 61 0 62 0;
+#X connect 62 0 63 0;
+#X connect 63 0 68 0;
+#X connect 64 0 63 1;
+#X connect 65 0 68 1;
+#X connect 66 0 69 1;
+#X connect 67 0 70 1;
+#X connect 68 0 69 0;
+#X connect 69 0 70 0;
+#X connect 70 0 72 0;
+#X connect 71 0 59 0;
+#X connect 72 0 71 0;
+#X connect 73 0 62 0;
+#X connect 74 0 73 0;
+#X connect 75 0 30 0;
+#X connect 76 0 75 0;
+#X connect 77 0 34 0;
+#X connect 78 0 62 0;
diff --git a/tms5220~/tms5220~.c b/tms5220~/tms5220~.c
index ae9e630..5ef85a5 100644
--- a/tms5220~/tms5220~.c
+++ b/tms5220~/tms5220~.c
@@ -4,6 +4,18 @@
#include "tms5220/tms5220.c"
+#define USE_LIBSAMPLERATE
+//#define DEBUG_TMS5220_TILDE
+
+// rate at which tms5220 emulator produces samples (according to datasheet)
+#define TMS5220_SAMPLE_RATE 8000
+
+#ifdef USE_LIBSAMPLERATE
+#define SRC_TYPE SRC_LINEAR //fastest
+//#define SRC_TYPE SRC_SINC_BEST_QUALITY
+#include <samplerate.h>
+#endif
+
#include "m_pd.h"
static t_class *tms5220_tilde_class;
@@ -11,6 +23,16 @@ static t_class *tms5220_tilde_class;
typedef struct _tms5220_tilde {
t_object x_obj;
+ // sample rate
+ t_float sr;
+ t_float resample_factor;
+
+#ifdef USE_LIBSAMPLERATE
+ SRC_STATE* src;
+#else
+#error Missing alternative implementation of sample rate converter. Please use libsamplerate.
+#endif
+
// status outlets
t_int status;
t_outlet *x_status;
@@ -22,6 +44,8 @@ typedef struct _tms5220_tilde {
t_float dummy;
} t_tms5220_tilde;
+
+
void tms5220_tilde_reset(t_tms5220_tilde *x) {
tms5220_reset();
}
@@ -31,9 +55,6 @@ void *tms5220_tilde_new(t_symbol *s, int argc, t_atom *argv) {
x->status = x->ready = x->interrupt = 0;
- //inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
- //floatinlet_new(&x->x_obj, &x->f_x);
-
outlet_new(&x->x_obj, &s_signal);
x->x_status = outlet_new(&x->x_obj, &s_float);
x->x_ready = outlet_new(&x->x_obj, &s_float);
@@ -41,16 +62,105 @@ void *tms5220_tilde_new(t_symbol *s, int argc, t_atom *argv) {
tms5220_tilde_reset(x);
+#ifdef USE_LIBSAMPLERATE
+ if(x->src) src_delete(x->src);
+
+ int err = -1;
+ x->src = src_new(SRC_TYPE, 1, &err);
+
+ if(x->src == NULL) {
+ error("Failed libsamplerate initialization.");
+ post("libsamplerate returned error code %d (%s).", err, src_strerror(err));
+ } else {
+#ifdef DEBUG_TMS5220_TILDE
+ post("tms5220~: DEBUG: Initialized sample rate converter '%s'", src_get_name(SRC_TYPE));
+#endif
+ }
+#endif
+
return (void *)x;
}
void tms5220_tilde_free(t_tms5220_tilde *x) {
+#ifdef USE_LIBSAMPLERATE
+ // deallocate sample rate converter object
+ if(x->src) {
+ src_delete(x->src);
+#ifdef DEBUG_TMS5220_TILDE
+ post("tms5220~: DEBUG: Destroyed sample rate converter '%s'", src_get_name(SRC_TYPE));
+#endif
+ }
+#endif
}
void tms5220_tilde_write(t_tms5220_tilde *x, t_floatarg data) {
tms5220_data_write((int)data);
}
+#define CHECK_ARGS(argcvar, num, errmsg) if(argcvar != num) { error(errmsg); return; }
+#define CLIP_VAL(v, min, max) (((v) < (min)) ? (min) : (((v) > (max)) ? (max) : (v)))
+
+void tms5220_tilde_framefunc(t_tms5220_tilde *x, t_symbol *s, int argc, t_atom *argv) {
+ int energy, pitch, k[10], i;
+
+ energy = argc > 0 ? argv[0].a_w.w_float : -1;
+ pitch = argc > 1 ? argv[1].a_w.w_float : -1;
+ for(i = 2; i < 12; i++) k[i - 2] = argc > i ? argv[i].a_w.w_float : -1;
+
+ energy = CLIP_VAL(energy, 1, 14);
+ pitch = CLIP_VAL(pitch, 0, 63);
+ k[0] = CLIP_VAL(k[0], 0, 31);
+ k[1] = CLIP_VAL(k[1], 0, 31);
+ k[2] = CLIP_VAL(k[2], 0, 15);
+ k[3] = CLIP_VAL(k[3], 0, 15);
+ k[4] = CLIP_VAL(k[4], 0, 15);
+ k[5] = CLIP_VAL(k[5], 0, 15);
+ k[6] = CLIP_VAL(k[6], 0, 15);
+ k[7] = CLIP_VAL(k[7], 0, 7);
+ k[8] = CLIP_VAL(k[8], 0, 7);
+ k[9] = CLIP_VAL(k[9], 0, 7);
+
+ unsigned char data[8];
+ memset(&data[0], 0, 8);
+
+ data[0] = 0x60; //speak external
+
+ if(energy == 0 || energy == 15) { error("illegal value for energy"); return; }
+
+ if(s == gensym("silent")) {
+ CHECK_ARGS(argc, 0, "usage: silent");
+ data[1] = 0;
+ } else if(s == gensym("stop")) {
+ CHECK_ARGS(argc, 0, "usage: stop");
+ data[1] = 0xf0;
+ } else if(s == gensym("repeat")) {
+ CHECK_ARGS(argc, 2, "usage: repeat <energy> <pitch>");
+ data[1] = ((energy << 4) | (1 << 3) | ((pitch & 56) >> 3));
+ data[2] = (((pitch & 7) << 5));
+ } else if(s == gensym("unvoiced")) {
+ CHECK_ARGS(argc, 6, "usage: repeat <energy> <pitch> <k1> <k2> <k3> <k4>");
+ data[1] = ((energy << 4) | 0 | 0);
+ data[2] = (k[0]);
+ data[3] = ((k[1] << 3) | ((k[2] & 14) >> 1));
+ data[4] = (((k[2] & 1) << 7) | (k[3] << 3));
+ } else if(s == gensym("voiced")) {
+ CHECK_ARGS(argc, 12, "usage: repeat <energy> <pitch> <k1> <k2> <k3> <k4> <k5> <k6> <k7> <k8> <k9> <k10>");
+ data[1] = ((energy << 4) | 0 | 0);
+ data[2] = (k[0]);
+ data[3] = ((k[1] << 3) | ((k[2] & 14) >> 1));
+ data[4] = (((k[2] & 1) << 7) | (k[3] << 3) | ((k[4] & 14) >> 1));
+ data[5] = (((k[4] & 1) << 7) | (k[5] << 3) | ((k[6] & 14) >> 1));
+ data[6] = (((k[6] & 1) << 7) | (k[7] << 4) | (k[8] << 1) | ((k[9] & 4) >> 2));
+ data[7] = (((k[9] & 3) << 6));
+ } else {
+ error("unknown method called: %s", s->s_name);
+ return;
+ }
+ //tms5220_reset();
+ for(i = 0; i < 8; i++) tms5220_data_write(data[i]);
+ //tms5220_data_write(0);
+}
+
void tms5220_tilde_update_status(t_tms5220_tilde *x) {
t_int new_status, new_ready, new_interrupt;
@@ -80,24 +190,53 @@ t_int *tms5220_tilde_perform(t_int *w) {
t_sample *out = (t_sample *)(w[3]);
int n = (int)(w[4]);
- //TODO: figure out proper resampling here:
-#define RESAMPLE_FACTOR 8
- int rc = 0; // resample counter
+ int m = (int)(0.0 + n / x->resample_factor);
- unsigned char *bytebuf = (unsigned char *)malloc(sizeof(unsigned char)*n/RESAMPLE_FACTOR);
+ unsigned char *bytebuf = (unsigned char *)malloc(sizeof(unsigned char) * m);
+ if(!bytebuf) {error("FATAL: cannot allocate signal buffer (byte)"); return w;}
- if(!bytebuf) {error("FATAL: cannot allocate signal buffer"); return w;}
+ float *floatbuf = (float *)malloc(sizeof(float) * m);
+ if(!floatbuf) {error("FATAL: cannot allocate signal buffer (float)"); return w;}
- tms5220_process(bytebuf, n/RESAMPLE_FACTOR);
+ tms5220_process(bytebuf, m);
unsigned char *pb = bytebuf;
+ float *fb = floatbuf;
+ int m1 = m;
+ while (m1--) *fb++ = (0.5 + ((t_sample) *pb++)) / 127.5;
+ free(bytebuf);
- while (n--) {
- //FIXME: resampling without alias, please
- *out++ = (0.5 + ((t_sample) *pb)) / 127.5;
- if(!(rc = ((rc + 1) % RESAMPLE_FACTOR))) pb++;
+#ifdef USE_LIBSAMPLERATE
+ if(x->src != NULL) {
+ SRC_DATA src_data;
+ src_data.data_in = floatbuf;
+ src_data.input_frames = m;
+ src_data.data_out = out;
+ src_data.output_frames = n;
+ src_data.src_ratio = x->resample_factor;
+ src_data.end_of_input = 0;
+ int err;
+ if(0 != (err = src_process(x->src, &src_data))) {
+ error("error during resample (libsamplerate)");
+ post("error code: %d (%s)", err, src_strerror(err));
+ }
+#ifdef DEBUG_TMS5220_TILDE
+ // check residual:
+ if(src_data.input_frames_used < m) {
+ error("used only %d input frames, instead of %d", src_data.input_frames_used, m);
+ }
+ if(src_data.output_frames_gen < n) {
+ error("generated only %d output frames, instead of %d", src_data.output_frames_gen, n);
+ }
+#endif
+ } else {
+ error("libsamplerate not initialized.");
}
+#else
+ // missing implementation of poor man's sample rate converter
+ // use libsamplerate for now
+#endif
- free(bytebuf);
+ free(floatbuf);
tms5220_tilde_update_status(x);
@@ -105,6 +244,14 @@ t_int *tms5220_tilde_perform(t_int *w) {
}
void tms5220_tilde_dsp(t_tms5220_tilde *x, t_signal **sp) {
+ // update sample rate & resample factor:
+ x->resample_factor = sp[0]->s_sr / TMS5220_SAMPLE_RATE;
+#ifdef DEBUG_TMS5220_TILDE
+ if(sp[0]->s_sr != x->sr)
+ post("tms5220~: DEBUG: samplerate has changed to %f; new resample factor is %f.", sp[0]->s_sr, (float)x->resample_factor);
+#endif
+ x->sr = sp[0]->s_sr;
+
dsp_add(tms5220_tilde_perform, 4, x, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
}
@@ -121,6 +268,12 @@ void tms5220_tilde_setup(void) {
//class_addfloat(tms5220_tilde_class, (t_method)tms5220_tilde_write);
class_addmethod(tms5220_tilde_class, (t_method)tms5220_tilde_write, gensym("write"), A_DEFFLOAT, 0);
class_addmethod(tms5220_tilde_class, (t_method)tms5220_tilde_reset, gensym("reset"), 0);
+ // frame building commands:
+ class_addmethod(tms5220_tilde_class, (t_method)tms5220_tilde_framefunc, gensym("silent"), A_GIMME, 0);
+ class_addmethod(tms5220_tilde_class, (t_method)tms5220_tilde_framefunc, gensym("stop"), A_GIMME, 0);
+ class_addmethod(tms5220_tilde_class, (t_method)tms5220_tilde_framefunc, gensym("repeat"), A_GIMME, 0);
+ class_addmethod(tms5220_tilde_class, (t_method)tms5220_tilde_framefunc, gensym("unvoiced"), A_GIMME, 0);
+ class_addmethod(tms5220_tilde_class, (t_method)tms5220_tilde_framefunc, gensym("voiced"), A_GIMME, 0);
post("tms5220~: TSM5220 IC emulation");
post("tms5220~: external by Federico Ferri <mescalinum@gmail.com>");