diff --git a/build/rtbuf/Makefile b/build/rtbuf/Makefile
index 7c57a76..3f677d2 100644
--- a/build/rtbuf/Makefile
+++ b/build/rtbuf/Makefile
@@ -7,8 +7,9 @@ CFLAGS = -O0 -ggdb -W -Wall -Werror
LDFLAGS = -L${SRCDIR}/../cli/build/so
LIBS = -lcli -lpthread
-HEADERS = rtbuf.h rtbuf_lib.h symbol.h
-OBJECTS = rtbuf.o rtbuf_lib.o rtbuf_cli.o rtbuf_fun.o symbol.o
+HEADERS = symbol.h rtbuf_defs.h rtbuf_type.h rtbuf_fun.h rtbuf.h rtbuf_lib.h
+OBJECTS = symbol.o rtbuf_type.o rtbuf_fun.o rtbuf.o rtbuf_lib.o \
+ rtbuf_cli.o
SRC = ${HEADERS} ${OBJECTS:%.o=%.c}
diff --git a/build/rtbuf_glfw3/Makefile b/build/rtbuf_glfw3/Makefile
index 90e9d80..da617ec 100644
--- a/build/rtbuf_glfw3/Makefile
+++ b/build/rtbuf_glfw3/Makefile
@@ -7,7 +7,8 @@ CFLAGS = -O0 -ggdb -W -Wall -Werror -fpic
LDFLAGS = -fPIC -shared
LIBS = -lsndio
-HEADERS = rtbuf.h rtbuf_lib.h rtbuf_signal.h rtbuf_music.h rtbuf_glfw3.h
+HEADERS = symbol.h rtbuf_defs.h rtbuf_type.h rtbuf_fun.h rtbuf.h \
+ rtbuf_lib.h rtbuf_signal.h rtbuf_music.h rtbuf_glfw3.h
OBJECTS = rtbuf_glfw3.o rtbuf_music.o
SRC = ${HEADERS} ${OBJECTS:%.o=%.c}
diff --git a/build/rtbuf_signal/Makefile b/build/rtbuf_signal/Makefile
index 5dc2446..4bbd92d 100644
--- a/build/rtbuf_signal/Makefile
+++ b/build/rtbuf_signal/Makefile
@@ -7,7 +7,8 @@ CFLAGS = -O0 -ggdb -W -Wall -Werror -fpic
LDFLAGS = -fPIC -shared
LIBS = -lm
-HEADERS = rtbuf.h rtbuf_lib.h rtbuf_signal.h
+HEADERS = rtbuf_defs.h rtbuf_type.h rtbuf_fun.h rtbuf.h rtbuf_lib.h \
+ rtbuf_music.h rtbuf_signal.h
OBJECTS = rtbuf_signal.o rtbuf_signal_sinus.o rtbuf_signal_square.o
SRC = ${HEADERS} ${OBJECTS:%.o=%.c}
diff --git a/build/rtbuf_sndio/Makefile b/build/rtbuf_sndio/Makefile
index 55f76bc..39b87c0 100644
--- a/build/rtbuf_sndio/Makefile
+++ b/build/rtbuf_sndio/Makefile
@@ -7,7 +7,8 @@ CFLAGS = -O0 -ggdb -W -Wall -Werror -fpic
LDFLAGS = -fPIC -shared
LIBS = -lsndio
-HEADERS = rtbuf.h rtbuf_lib.h rtbuf_signal.h rtbuf_sndio.h
+HEADERS = rtbuf_defs.h rtbuf_type.h rtbuf_fun.h rtbuf.h rtbuf_lib.h \
+ rtbuf_music.h rtbuf_signal.h rtbuf_sndio.h
OBJECTS = rtbuf_sndio.o rtbuf_sndio_input.o rtbuf_sndio_output.o
SRC = ${HEADERS} ${OBJECTS:%.o=%.c}
diff --git a/rtbuf.c b/rtbuf.c
index cc404d2..a5ca52d 100644
--- a/rtbuf.c
+++ b/rtbuf.c
@@ -44,34 +44,58 @@ int rtbuf_next ()
int rtbuf_new (s_rtbuf_fun *rf)
{
- int rtb;
+ int i;
+ s_rtbuf *rtb;
+ void *data;
unsigned int j = 0;
assert(rf);
- if ((rtb = rtbuf_next()) < 0)
+ if ((i = rtbuf_next()) < 0)
return -1;
- g_rtbuf[rtb].data = calloc(rf->nmemb, rf->size);
- g_rtbuf[rtb].fun = rf;
- g_rtbuf[rtb].var = calloc(rf->var_n, sizeof(int));
- while (j < rf->var_n)
- g_rtbuf[rtb].var[j++] = -1;
+ rtb = &g_rtbuf[i];
+ bzero(rtb, sizeof(s_rtbuf));
+ data = malloc(rf->out_bytes);
+ if (!data)
+ return rtbuf_err("malloc failed");
+ bzero(data, rf->out_bytes);
+ rtb->data = data;
+ rtb->fun = rf;
+ while (j < RTBUF_FUN_VAR_MAX) {
+ rtb->var[j].rtb = rtb->var[j].out = -1;
+ j++;
+ }
g_rtbuf_sort = 1;
- return rtb;
+ return i;
}
-void rtbuf_var_unbind (s_rtbuf *rtb, unsigned int i)
+void rtbuf_delete (s_rtbuf *rtb)
{
- if (rtb->var[i] >= 0)
- g_rtbuf[rtb->var[i]].refc--;
- rtb->var[i] = -1;
+ rtbuf_unbind(rtb);
+ free(rtb->data);
+ rtb->data = 0;
+ g_rtbuf_n--;
+ g_rtbuf_sort = 1;
}
-void rtbuf_var_bind (s_rtbuf *rtb, unsigned int i, int target)
+void rtbuf_var_unbind (s_rtbuf *rtb, unsigned int var)
{
- if (rtb->var[i] == target)
+ s_rtbuf_binding *rb = &rtb->var[var];
+ if (rb->rtb >= 0) {
+ g_rtbuf[rb->rtb].refc--;
+ rb->rtb = -1;
+ rtb->var_n--;
+ }
+}
+
+void rtbuf_var_bind (s_rtbuf *rtb, unsigned int var,
+ unsigned int target, unsigned int target_out)
+{
+ s_rtbuf_binding *rb = &rtb->var[var];
+ if ((unsigned int) rb->rtb == target && rb->out == target_out)
return;
- if (rtb->var[i] >= 0)
- g_rtbuf[rtb->var[i]].refc--;
- rtb->var[i] = target;
+ rtbuf_var_unbind(rtb, var);
+ rb->rtb = target;
+ rb->out = target_out;
+ rtb->var_n++;
g_rtbuf[target].refc++;
g_rtbuf_sort = 1;
}
@@ -83,16 +107,6 @@ void rtbuf_unbind (s_rtbuf *rtb)
rtbuf_var_unbind(rtb, i);
}
-void rtbuf_delete (s_rtbuf *rtb)
-{
- rtbuf_unbind(rtb);
- free(rtb->data);
- free(rtb->var);
- bzero(rtb, sizeof(s_rtbuf));
- g_rtbuf_n--;
- g_rtbuf_sort = 1;
-}
-
typedef struct rtbuf_var_ptr {
unsigned int rtb;
unsigned int var;
@@ -179,7 +193,7 @@ void rtbuf_sort_push_child (s_rtbuf_var_stack *rvs,
unsigned int i = 0;
int found = 0;
//printf("rtbuf_sort_push_child { %u, %u }\n", ptr->rtb, ptr->var);
- rtb = g_rtbuf[ptr->rtb].var[ptr->var];
+ rtb = g_rtbuf[ptr->rtb].var[ptr->var].rtb;
ptr->var++;
if (rtb >= 0) {
while (i < g_rtbuf_sorted_n && !found) {
@@ -290,3 +304,23 @@ int rtbuf_find (const char *x)
return i;
return -1;
}
+
+int rtbuf_out_find (s_rtbuf *rtb, const char *x)
+{
+ const char *sym;
+ if ('0' <= x[0] && x[0] <= '9') {
+ int i = atoi(x);
+ if (0 <= i && (unsigned int) i < rtb->fun->out_n)
+ return i;
+ }
+ if ((sym = symbol_find(x))) {
+ s_rtbuf_fun_out *out = rtb->fun->out;
+ int i = 0;
+ while (i < RTBUF_FUN_OUT_MAX) {
+ if (sym == out->name)
+ return i;
+ i++;
+ }
+ }
+ return -1;
+}
diff --git a/rtbuf.h b/rtbuf.h
index 9680e80..0f2bca5 100644
--- a/rtbuf.h
+++ b/rtbuf.h
@@ -1,47 +1,28 @@
#ifndef RTBUF_H
#define RTBUF_H
-typedef struct rtbuf s_rtbuf;
-
-typedef int f_rtbuf_fun (s_rtbuf *rtbuf);
-
-typedef struct rtbuf_fun
-{
- const char *name; /* symbol */
- f_rtbuf_fun *f;
- f_rtbuf_fun *start;
- f_rtbuf_fun *stop;
- unsigned int nmemb; /* number of members in buffer data */
- unsigned int size; /* size of members in bytes in buffer data */
- const char **var;
- unsigned int var_n; /* number of rtbuf variables */
- struct rtbuf_lib *lib;
- unsigned int lib_fun;
-} s_rtbuf_fun;
-
-#define RTBUF_FUN_MAX 32768
-s_rtbuf_fun g_rtbuf_fun[RTBUF_FUN_MAX];
-unsigned int g_rtbuf_fun_n;
-
-typedef struct rtbuf_lib_fun s_rtbuf_lib_fun;
-
-s_rtbuf_fun * find_rtbuf_fun (const char *x);
-s_rtbuf_fun * new_rtbuf_fun (s_rtbuf_lib_fun *x);
-void delete_rtbuf_fun (s_rtbuf_fun *fun);
+#include "rtbuf_defs.h"
+#include "rtbuf_type.h"
+#include "rtbuf_fun.h"
#define RTBUF_SORT 0x0001
#define RTBUF_DELETE 0x0002
-struct rtbuf
+struct rtbuf_binding
{
- void *data;
- unsigned int flags;
- s_rtbuf_fun *fun;
- unsigned int refc;
- int *var;
+ int rtb;
+ unsigned int out;
};
-typedef int f_rtbuf_lib_init ();
+struct rtbuf
+{
+ void *data;
+ unsigned int flags;
+ s_rtbuf_fun *fun;
+ unsigned int refc;
+ s_rtbuf_binding var[RTBUF_FUN_VAR_MAX];
+ unsigned int var_n;
+};
#define RTBUF_MAX 1000
@@ -57,6 +38,7 @@ int rtbuf_init ();
void rtbuf_delete (s_rtbuf *rtb);
int rtbuf_err (const char *msg);
int rtbuf_find (const char *x);
+int rtbuf_out_find (s_rtbuf *rtb, const char *x);
int rtbuf_new (s_rtbuf_fun *rf);
void rtbuf_run ();
void rtbuf_sort ();
@@ -64,7 +46,8 @@ void rtbuf_start();
void rtbuf_stop();
void rtbuf_unbind (s_rtbuf *rtb);
void rtbuf_var_unbind (s_rtbuf *rtb, unsigned int var);
-void rtbuf_var_bind (s_rtbuf *rtb, unsigned int var, int target);
+void rtbuf_var_bind (s_rtbuf *rtb, unsigned int var,
+ unsigned int target, unsigned int target_out);
static inline double min (double a, double b)
{
diff --git a/rtbuf_cli.c b/rtbuf_cli.c
index 3b2c708..aebccac 100644
--- a/rtbuf_cli.c
+++ b/rtbuf_cli.c
@@ -5,6 +5,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
+#include "rtbuf.h"
#include "rtbuf_lib.h"
#include "symbol.h"
@@ -18,12 +19,27 @@ void print_lib (unsigned int i)
void print_rtbuf_fun (s_rtbuf_fun *fun)
{
- printf("#<fun %i %s nmemb=%u size=%u var_n=%u>",
- fun->lib_fun,
- fun->name,
- fun->nmemb,
- fun->size,
- fun->var_n);
+ unsigned int i = 0;
+ printf("#<fun %i %s (", fun->lib_fun, fun->name);
+ while (i < fun->var_n) {
+ if (i > 0)
+ fputs(" ", stdout);
+ fputs(fun->var[i].name, stdout);
+ fputs(":", stdout);
+ fputs(fun->var[i].type->name, stdout);
+ i++;
+ }
+ printf(") -> (");
+ i = 0;
+ while (i < fun->out_n) {
+ if (i > 0)
+ fputs(" ", stdout);
+ fputs(fun->out[i].name, stdout);
+ fputs(":", stdout);
+ fputs(fun->out[i].type->name, stdout);
+ i++;
+ }
+ fputs(")>", stdout);
}
void print_lib_long (unsigned int i)
@@ -62,9 +78,13 @@ void print_rtbuf_long (unsigned int i)
printf(" %d", rtb->refc);
}
while (j < rtb->fun->var_n) {
- if (rtb->var[j] >= 0) {
- printf("\n %i %s = ", j, rtb->fun->var[j]);
- print_rtbuf(rtb->var[j]);
+ if (rtb->var[j].rtb >= 0) {
+ printf("\n %i %s:%s = ", j, rtb->fun->var[j].name,
+ rtb->fun->var[j].type->name);
+ print_rtbuf(rtb->var[j].rtb);
+ printf(" %u %s:%s", rtb->var[j].out,
+ rtb->fun->out[j].name,
+ rtb->fun->out[j].type->name);
}
j++;
}
@@ -183,8 +203,9 @@ int rtbuf_cli_bind (int argc, const char *argv[])
int rtb;
int var;
int target;
- if (argc != 3)
- return rtbuf_err("usage: bind BUFFER VARIABLE TARGET");
+ int target_out;
+ if (argc != 4)
+ return rtbuf_err("usage: bind BUFFER VARIABLE TARGET OUTPUT");
if ((rtb = rtbuf_find(argv[1])) < 0)
return rtbuf_err("buffer not found");
var = atoi(argv[2]);
@@ -192,7 +213,9 @@ int rtbuf_cli_bind (int argc, const char *argv[])
return rtbuf_err("variable not found");
if ((target = rtbuf_find(argv[3])) < 0)
return rtbuf_err("target not found");
- rtbuf_var_bind(&g_rtbuf[rtb], var, target);
+ if ((target_out = rtbuf_out_find(&g_rtbuf[rtb], argv[4])) < 0)
+ return rtbuf_err("target output not found");
+ rtbuf_var_bind(&g_rtbuf[rtb], var, target, target_out);
print_rtbuf_long(rtb);
return 0;
}
@@ -340,7 +363,9 @@ int main (int argc, char *argv[])
{
(void) argc;
(void) argv;
- init_symbols();
+ symbols_init();
+ rtbuf_type_init();
+ rtbuf_fun_init();
rtbuf_lib_init();
return repl();
}
diff --git a/rtbuf_defs.h b/rtbuf_defs.h
new file mode 100644
index 0000000..89cb695
--- /dev/null
+++ b/rtbuf_defs.h
@@ -0,0 +1,17 @@
+#ifndef RTBUF_DEFS_H
+#define RTBUF_DEFS_H
+
+typedef struct rtbuf s_rtbuf;
+typedef struct rtbuf_binding s_rtbuf_binding;
+typedef struct rtbuf_fun s_rtbuf_fun;
+typedef struct rtbuf_fun_out s_rtbuf_fun_out;
+typedef struct rtbuf_fun_var s_rtbuf_fun_var;
+typedef struct rtbuf_lib s_rtbuf_lib;
+typedef struct rtbuf_lib_fun s_rtbuf_lib_fun;
+typedef struct rtbuf_lib_fun_out s_rtbuf_lib_fun_out;
+typedef struct rtbuf_lib_fun_var s_rtbuf_lib_fun_var;
+typedef struct rtbuf_type s_rtbuf_type;
+
+typedef int f_rtbuf_fun (s_rtbuf *rtbuf);
+
+#endif
diff --git a/rtbuf_fun.c b/rtbuf_fun.c
index fcf2bc0..f613caf 100644
--- a/rtbuf_fun.c
+++ b/rtbuf_fun.c
@@ -9,51 +9,49 @@
s_rtbuf_fun g_rtbuf_fun[RTBUF_FUN_MAX];
unsigned int g_rtbuf_fun_n = 0;
+void rtbuf_fun_init ()
+{
+ bzero(g_rtbuf_fun, sizeof(g_rtbuf_fun));
+}
+
int rtbuf_fun_p (s_rtbuf_fun *fun)
{
return fun && fun->name;
}
-s_rtbuf_fun * find_rtbuf_fun (const char *x)
+void rtbuf_fun_new_var (s_rtbuf_fun *fun, s_rtbuf_lib_fun_var *var)
{
- const char *sym = find_symbol(x);
- if (sym) {
- unsigned int i = 0;
- unsigned int n = g_rtbuf_fun_n;
- while (i < RTBUF_FUN_MAX && n > 0) {
- if (rtbuf_fun_p(&g_rtbuf_fun[i]) &&
- sym == g_rtbuf_fun[i].name)
- return &g_rtbuf_fun[i];
+ unsigned int i = 0;
+ bzero(fun->var, sizeof(fun->var));
+ if (var)
+ while (var->name) {
+ s_rtbuf_fun_var *v = &fun->var[i];
+ v->name = symbol_intern(var->name);
+ v->type = rtbuf_type(var->type);
i++;
}
- }
- return 0;
+ fun->var_n = i;
}
-void init_rtbuf_fun (s_rtbuf_fun *fun, s_rtbuf_lib_fun *x)
+void rtbuf_fun_new_out (s_rtbuf_fun *fun, s_rtbuf_lib_fun_out *out)
{
- const char **var = x->var;
- unsigned int j = 0;
- fun->name = intern(x->name);
- fun->f = x->f;
- fun->start = x->start;
- fun->stop = x->stop;
- fun->nmemb = x->nmemb;
- fun->size = x->size;
- fun->var_n = 0;
- if (var)
- while (*var) {
- fun->var_n++;
- var++;
+ unsigned int i = 0;
+ bzero(fun->out, sizeof(fun->out));
+ if (out) {
+ unsigned int offset = 0;
+ while (out->name) {
+ s_rtbuf_fun_out *o = &fun->out[i];
+ o->name = symbol_intern(out->name);
+ o->type = rtbuf_type(out->type);
+ o->offset = offset;
+ offset += o->type->size;
+ i++;
}
- fun->var = malloc(sizeof(const char *) * (fun->var_n + 1));
- if ((var = x->var))
- while (*var)
- fun->var[j++] = intern(*var++);
- fun->var[j] = 0;
+ }
+ fun->out_n = i;
}
-s_rtbuf_fun * new_rtbuf_fun (s_rtbuf_lib_fun *x)
+s_rtbuf_fun * rtbuf_fun_new (s_rtbuf_lib_fun *x)
{
unsigned int i = 0;
if (g_rtbuf_fun_n == RTBUF_FUN_MAX) {
@@ -61,8 +59,14 @@ s_rtbuf_fun * new_rtbuf_fun (s_rtbuf_lib_fun *x)
return 0;
}
while (i < RTBUF_FUN_MAX) {
- if (!rtbuf_fun_p(&g_rtbuf_fun[i])) {
- init_rtbuf_fun(&g_rtbuf_fun[i], x);
+ s_rtbuf_fun *fun = &g_rtbuf_fun[i];
+ if (!rtbuf_fun_p(fun)) {
+ fun->name = symbol_intern(x->name);
+ fun->f = x->f;
+ fun->start = x->start;
+ fun->stop = x->stop;
+ rtbuf_fun_new_var(&g_rtbuf_fun[i], x->var);
+ rtbuf_fun_new_out(&g_rtbuf_fun[i], x->out);
g_rtbuf_fun_n++;
return &g_rtbuf_fun[i];
}
@@ -71,12 +75,26 @@ s_rtbuf_fun * new_rtbuf_fun (s_rtbuf_lib_fun *x)
return 0;
}
-void delete_rtbuf_fun (s_rtbuf_fun *fun)
+void rtbuf_fun_delete (s_rtbuf_fun *fun)
{
- if (fun && fun->var) {
- free(fun->var);
+ if (fun && fun->name) {
bzero(fun, sizeof(s_rtbuf_fun));
g_rtbuf_fun_n--;
}
- fun->name = 0;
+}
+
+s_rtbuf_fun * rtbuf_fun_find (const char *x)
+{
+ const char *sym = symbol_find(x);
+ if (sym) {
+ unsigned int i = 0;
+ unsigned int n = g_rtbuf_fun_n;
+ while (i < RTBUF_FUN_MAX && n > 0) {
+ if (rtbuf_fun_p(&g_rtbuf_fun[i]) &&
+ sym == g_rtbuf_fun[i].name)
+ return &g_rtbuf_fun[i];
+ i++;
+ }
+ }
+ return 0;
}
diff --git a/rtbuf_fun.h b/rtbuf_fun.h
new file mode 100644
index 0000000..19254b8
--- /dev/null
+++ b/rtbuf_fun.h
@@ -0,0 +1,44 @@
+#ifndef RTBUF_FUN_H
+#define RTBUF_FUN_H
+
+#include "rtbuf_defs.h"
+
+struct rtbuf_fun_var {
+ const char *name; /* symbol */
+ s_rtbuf_type *type;
+};
+
+struct rtbuf_fun_out {
+ const char *name; /* symbol */
+ s_rtbuf_type *type;
+ unsigned int offset;
+};
+
+#define RTBUF_FUN_VAR_MAX 32
+#define RTBUF_FUN_OUT_MAX 32
+
+struct rtbuf_fun {
+ const char *name; /* symbol */
+ f_rtbuf_fun *f;
+ f_rtbuf_fun *start;
+ f_rtbuf_fun *stop;
+ s_rtbuf_fun_var var[RTBUF_FUN_VAR_MAX]; /* variables */
+ unsigned int var_n; /* number of variables */
+ s_rtbuf_fun_out out[RTBUF_FUN_OUT_MAX]; /* outputs */
+ unsigned int out_n; /* number of outputs */
+ unsigned int out_bytes; /* size of output data in bytes */
+ s_rtbuf_lib *lib; /* the library this function comes from */
+ unsigned int lib_fun; /* the function index in lib functions */
+};
+
+#define RTBUF_FUN_MAX 1024
+extern s_rtbuf_fun g_rtbuf_fun[RTBUF_FUN_MAX];
+extern unsigned int g_rtbuf_fun_n;
+
+extern void rtbuf_fun_init ();
+extern int rtbuf_fun_p (s_rtbuf_fun *fun);
+extern s_rtbuf_fun * rtbuf_fun_new (s_rtbuf_lib_fun *x);
+extern void rtbuf_fun_delete (s_rtbuf_fun *fun);
+extern s_rtbuf_fun * rtbuf_fun_find (const char *x);
+
+#endif
diff --git a/rtbuf_glfw3.c b/rtbuf_glfw3.c
index 4174999..19d597c 100644
--- a/rtbuf_glfw3.c
+++ b/rtbuf_glfw3.c
@@ -8,15 +8,16 @@
#include "rtbuf_music.h"
#include "rtbuf_glfw3.h"
+s_rtbuf_lib_fun_out g_rtbuf_glfw3_keyboard_out[] = {
+ { "notes", RTBUF_MUSIC_NOTES_TYPE },
+ { 0, 0 } };
+
const char *rtbuf_lib_name = "glfw3";
unsigned long rtbuf_lib_ver = RTBUF_LIB_VER;
s_rtbuf_lib_fun rtbuf_lib_fun[] = {
{ "keyboard", rtbuf_glfw3_keyboard, rtbuf_glfw3_keyboard_start, 0,
- sizeof(s_rtbuf_glfw3_keyboard_data) / sizeof(double) + 1,
- sizeof(double),
- (const char*[]) { 0 } },
- { 0, 0, 0, 0, 0, 0, 0 }
-};
+ 0, g_rtbuf_glfw3_keyboard_out },
+ { 0, 0, 0, 0, 0, 0 } };
s_rtbuf_music_notes g_rtbuf_glfw3_keyboard;
diff --git a/rtbuf_glfw3.h b/rtbuf_glfw3.h
index 19c8635..25cffc1 100644
--- a/rtbuf_glfw3.h
+++ b/rtbuf_glfw3.h
@@ -2,6 +2,7 @@
#define RTBUF_GLFW3_H
#include <GLFW/glfw3.h>
+#include "rtbuf_defs.h"
#include "rtbuf_music.h"
typedef struct rtbuf_glfw3_keyboard_data {
diff --git a/rtbuf_lib.c b/rtbuf_lib.c
index aea3de2..a8ac041 100644
--- a/rtbuf_lib.c
+++ b/rtbuf_lib.c
@@ -5,6 +5,7 @@
#include <stdlib.h>
#include <string.h>
#include <strings.h>
+#include "rtbuf.h"
#include "rtbuf_lib.h"
#include "symbol.h"
@@ -46,7 +47,7 @@ int rtbuf_lib_find (const char *str)
if (0 <= i && i < RTBUF_LIB_MAX && rtbuf_lib_p(&g_rtbuf_lib[i]))
return i;
}
- if ((sym = find_symbol(str))) {
+ if ((sym = symbol_find(str))) {
unsigned int i = 0;
unsigned int n = g_rtbuf_lib_n;
while (i < RTBUF_LIB_MAX && n > 0) {
@@ -69,7 +70,7 @@ int rtbuf_lib_find_fun (s_rtbuf_lib *rl, const char *str)
if (0 <= i && (unsigned) i < rl->fun_n)
return i;
}
- if ((sym = find_symbol(str))) {
+ if ((sym = symbol_find(str))) {
unsigned int i = 0;
while (i < rl->fun_n) {
if (sym == rl->fun[i]->name)
@@ -144,7 +145,7 @@ s_rtbuf_lib * rtbuf_lib_load (const char *name)
ver = dlsym(lib->lib, "rtbuf_lib_ver");
//printf("lib_load ver %lu\n", *ver);
assert(*ver == RTBUF_LIB_VER);
- lib->name = intern(name);
+ lib->name = symbol_intern(name);
//printf("lib_load name %s\n", lib->name);
fun = dlsym(lib->lib, "rtbuf_lib_fun");
lib->fun_n = 0;
@@ -153,13 +154,13 @@ s_rtbuf_lib * rtbuf_lib_load (const char *name)
if (fun[lib->fun_n].name == 0) {
Dl_info info;
dladdr(fun[lib->fun_n].f, &info);
- fun[lib->fun_n].name = intern(info.dli_sname);
+ fun[lib->fun_n].name = symbol_intern(info.dli_sname);
}
lib->fun_n++;
}
lib->fun = malloc(sizeof(s_rtbuf_fun*) * (lib->fun_n + 1));
while (i < lib->fun_n) {
- lib->fun[i] = new_rtbuf_fun(&fun[i]);
+ lib->fun[i] = rtbuf_fun_new(&fun[i]);
lib->fun[i]->lib = lib;
lib->fun[i]->lib_fun = i;
i++;
diff --git a/rtbuf_lib.h b/rtbuf_lib.h
index 8f89382..23e8d23 100644
--- a/rtbuf_lib.h
+++ b/rtbuf_lib.h
@@ -1,28 +1,37 @@
#ifndef RTBUF_LIB_H
#define RTBUF_LIB_H
-#include "rtbuf.h"
+#include "rtbuf_defs.h"
#define RTBUF_LIB_MAX 1000
#define RTBUF_LIB_VER 0x00010001
-typedef struct rtbuf_lib_fun {
+struct rtbuf_lib_fun_var {
+ const char *name;
+ const char *type;
+};
+
+struct rtbuf_lib_fun_out {
+ const char *name;
+ const char *type;
+};
+
+struct rtbuf_lib_fun {
const char *name;
f_rtbuf_fun *f;
f_rtbuf_fun *start;
f_rtbuf_fun *stop;
- unsigned int nmemb; /* number of members in buffer data */
- unsigned int size; /* size of members in bytes in buffer data */
- const char **var; /* names of variables, end with NULL */
-} s_rtbuf_lib_fun;
+ s_rtbuf_lib_fun_var *var; /* variables, end with NULL */
+ s_rtbuf_lib_fun_out *out; /* outputs, end with NULL */
+};
-typedef struct rtbuf_lib {
+struct rtbuf_lib {
const char *name;
s_rtbuf_fun **fun;
unsigned int fun_n;
void *lib;
const char *path;
-} s_rtbuf_lib;
+};
extern s_rtbuf_lib g_rtbuf_lib[];
extern unsigned int g_rtbuf_lib_n;
diff --git a/rtbuf_music.h b/rtbuf_music.h
index b43c20e..45b611e 100644
--- a/rtbuf_music.h
+++ b/rtbuf_music.h
@@ -15,6 +15,8 @@ typedef struct rtbuf_music_notes {
unsigned int note_n;
} s_rtbuf_music_notes;
+#define RTBUF_MUSIC_NOTES_TYPE "music_notes"
+
void rtbuf_music_notes_init (s_rtbuf_music_notes *notes);
int rtbuf_music_notes_new (s_rtbuf_music_notes *notes);
void rtbuf_music_notes_delete (s_rtbuf_music_notes *notes, unsigned int i);
diff --git a/rtbuf_signal.c b/rtbuf_signal.c
index 10cdc34..05be336 100644
--- a/rtbuf_signal.c
+++ b/rtbuf_signal.c
@@ -3,18 +3,63 @@
#include <stdio.h>
#include "rtbuf.h"
#include "rtbuf_lib.h"
+#include "rtbuf_music.h"
#include "rtbuf_signal.h"
+s_rtbuf_lib_fun_var g_rtbuf_signal_sinus_var[] = {
+ { "frequency", RTBUF_SIGNAL_TYPE },
+ { "amplitude", RTBUF_SIGNAL_TYPE },
+ { 0, 0 } };
+
+s_rtbuf_lib_fun_out g_rtbuf_signal_sinus_out[] = {
+ { "signal", RTBUF_SIGNAL_TYPE },
+ { "phase", "double" },
+ { 0, 0 } };
+
+s_rtbuf_lib_fun_var g_rtbuf_signal_square_var[] = {
+ { "frequency", RTBUF_SIGNAL_TYPE },
+ { "amplitude", RTBUF_SIGNAL_TYPE },
+ { "pulse", RTBUF_SIGNAL_TYPE },
+ { 0, 0 } };
+
+s_rtbuf_lib_fun_out g_rtbuf_signal_square_out[] = {
+ { "signal", RTBUF_SIGNAL_TYPE },
+ { "phase", "double" },
+ { 0, 0 } };
+
+s_rtbuf_lib_fun_var g_rtbuf_signal_synth_var[] = {
+ { "keyboard", RTBUF_MUSIC_NOTES_TYPE },
+ { "envelope", RTBUF_SIGNAL_TYPE },
+ { "oscillator", RTBUF_SIGNAL_TYPE },
+ { 0, 0 } };
+
+s_rtbuf_lib_fun_out g_rtbuf_signal_synth_out[] = {
+ { "signal", RTBUF_SIGNAL_TYPE },
+ { "notes", RTBUF_SIGNAL_SYNTH_NOTES_TYPE },
+ { 0, 0 } };
+
const char *rtbuf_lib_name = "signal";
unsigned long rtbuf_lib_ver = RTBUF_LIB_VER;
s_rtbuf_lib_fun rtbuf_lib_fun[] = {
{ "sinus", rtbuf_signal_sinus, rtbuf_signal_sinus_start, 0,
- sizeof(s_rtbuf_signal_sinus_data) / sizeof(double) + 1,
- sizeof(double),
- (const char*[]) { "frequency", "amplitude", 0 } },
+ g_rtbuf_signal_sinus_var, g_rtbuf_signal_sinus_out },
{ "square", rtbuf_signal_square, rtbuf_signal_square_start, 0,
- sizeof(s_rtbuf_signal_square_data) / sizeof(double) + 1,
- sizeof(double),
- (const char*[]) { "frequency", "amplitude", "pulse", 0 } },
- { 0, 0, 0, 0, 0, 0, 0 }
-};
+ g_rtbuf_signal_square_var, g_rtbuf_signal_square_out },
+ { "synth", rtbuf_signal_synth, rtbuf_signal_synth_start, 0,
+ g_rtbuf_signal_synth_var, g_rtbuf_signal_synth_out },
+ { 0, 0, 0, 0, 0, 0 } };
+
+double rtbuf_signal_sample (s_rtbuf *rtb, unsigned int var,
+ unsigned int i, double default_value)
+{
+ s_rtbuf_binding *v = &rtb->var[var];
+ s_rtbuf *target;
+ double *signal;
+ unsigned int offset;
+ if (v->rtb < 0)
+ return default_value;
+ target = &g_rtbuf[v->rtb];
+ offset = target->fun->out[v->out].offset;
+ signal = (double*) ((char*) target->data + offset);
+ return signal[i];
+}
diff --git a/rtbuf_signal.h b/rtbuf_signal.h
index 2931ae2..db08937 100644
--- a/rtbuf_signal.h
+++ b/rtbuf_signal.h
@@ -1,22 +1,32 @@
#ifndef RTBUF_SIGNAL_H
#define RTBUF_SIGNAL_H
+#include "rtbuf_type.h"
+#include "rtbuf_music.h"
+
#define RTBUF_SIGNAL_SAMPLES 256
#define RTBUF_SIGNAL_SAMPLERATE 44100
+#define RTBUF_SIGNAL_TYPE \
+ RTBUF_TYPE_DOUBLE_ARRAY(RTBUF_SIGNAL_SAMPLES)
+
+typedef double t_rtbuf_signal[RTBUF_SIGNAL_SAMPLES];
+
+double rtbuf_signal_sample (s_rtbuf *rtb, unsigned int var,
+ unsigned int i, double default_value);
/* sinus */
+typedef struct rtbuf_signal_sinus_data {
+ t_rtbuf_signal signal;
+ double phase;
+} s_rtbuf_signal_sinus_data;
+
enum {
RTBUF_SIGNAL_SINUS_VAR_FREQUENCY = 0,
RTBUF_SIGNAL_SINUS_VAR_AMPLITUDE,
RTBUF_SIGNAL_SINUS_VAR_N
};
-typedef struct rtbuf_signal_sinus_data {
- double samples[RTBUF_SIGNAL_SAMPLES];
- double phase;
-} s_rtbuf_signal_sinus_data;
-
int rtbuf_signal_sinus (s_rtbuf *rtb);
int rtbuf_signal_sinus_start (s_rtbuf *rtb);
@@ -30,11 +40,45 @@ enum {
};
typedef struct rtbuf_signal_square_data {
- double samples[RTBUF_SIGNAL_SAMPLES];
+ t_rtbuf_signal signal;
double phase;
} s_rtbuf_signal_square_data;
int rtbuf_signal_square (s_rtbuf *rtb);
int rtbuf_signal_square_start (s_rtbuf *rtb);
+/* synth */
+
+typedef struct rtbuf_signal_synth_note {
+ s_rtbuf *envelope;
+ s_rtbuf *oscillator;
+} s_rtbuf_signal_synth_note;
+
+#define RTBUF_SIGNAL_SYNTH_NOTE_SIZE sizeof(s_rtbuf_signal_synth_note)
+#define RTBUF_SIGNAL_SYNTH_NOTE_TYPE "signal_synth_note"
+
+enum {
+ RTBUF_SIGNAL_SYNTH_VAR_KEYBOARD = 0,
+ RTBUF_SIGNAL_SYNTH_VAR_ENVELOPE,
+ RTBUF_SIGNAL_SYNTH_VAR_OSCILLATOR,
+ RTBUF_SIGNAL_SYNTH_VAR_N,
+};
+
+typedef struct rtbuf_signal_synth_notes {
+ s_rtbuf_signal_synth_note note[RTBUF_MUSIC_NOTE_MAX];
+ unsigned int note_n;
+} s_rtbuf_signal_synth_notes;
+
+#define RTBUF_SIGNAL_SYNTH_NOTES_SIZE sizeof(s_rtbuf_signal_synth_notes)
+#define RTBUF_SIGNAL_SYNTH_NOTES_TYPE "signal_synth_notes"
+
+typedef struct rtbuf_signal_synth_data
+{
+ t_rtbuf_signal signal;
+ s_rtbuf_signal_synth_notes notes;
+} s_rtbuf_signal_synth_data;
+
+int rtbuf_signal_synth (s_rtbuf *rtb);
+int rtbuf_signal_synth_start (s_rtbuf *rtb);
+
#endif /* RTBUF_SIGNAL_H */
diff --git a/rtbuf_signal_adsr.c b/rtbuf_signal_adsr.c
new file mode 100644
index 0000000..252e50b
--- /dev/null
+++ b/rtbuf_signal_adsr.c
@@ -0,0 +1,56 @@
+#include "rtbuf.h"
+#include "rtbuf_signal.h"
+#include "rtbuf_music.h"
+
+static inline
+double adsr (double attack, double decay, double sustain,
+ double release, double start, double stop)
+{
+ double x;
+ if (start < attack)
+ x = start / attack;
+ else if (start < attack + decay)
+ x = 1.0 + (sustain - 1.0) * (start - attack);
+ else
+ x = sustain;
+ if (stop < 0.0)
+ return x;
+ if (stop < release)
+ return x * (1.0 - stop / release);
+ return 0.0;
+}
+
+enum {
+ RTBUF_SIGNAL_ADSR_VAR_NOTE = 0,
+ RTBUF_SIGNAL_ADSR_VAR_ATTACK,
+ RTBUF_SIGNAL_ADSR_VAR_DECAY,
+ RTBUF_SIGNAL_ADSR_VAR_SUSTAIN,
+ RTBUF_SIGNAL_ADSR_VAR_RELEASE,
+ RTBUF_SIGNAL_ADSR_VAR_N,
+};
+
+typedef struct rtbuf_signal_adsr_data {
+ double samples[RTBUF_SIGNAL_SAMPLES];
+} s_rtbuf_signal_adsr_data;
+
+int rtbuf_signal_adsr (s_rtbuf *rtb)
+{
+ s_rtbuf_signal_adsr_data *data;
+ int attack = rtb->var[RTBUF_SIGNAL_ADSR_VAR_ATTACK];
+ int decay = rtb->var[RTBUF_SIGNAL_ADSR_VAR_DECAY];
+ int sustain = rtb->var[RTBUF_SIGNAL_ADSR_VAR_SUSTAIN];
+ int release = rtb->var[RTBUF_SIGNAL_ADSR_VAR_RELEASE];
+ double *attack_samples = attack < 0 ? 0 : g_rtbuf[attack].data;
+ double *decay_samples = decay < 0 ? 0 : g_rtbuf[decay].data;
+ double *sustain_samples = sustain < 0 ? 0 : g_rtbuf[sustain].data;
+ double *release_samples = release < 0 ? 0 : g_rtbuf[release].data;
+ double *sample;
+ unsigned int i = 0;
+ data = (s_rtbuf_signal_adsr_data*) rtb->data;
+ sample = data->samples;
+ while (i < RTBUF_SIGNAL_SAMPLES) {
+ *sample = adsr(
+ sample++;
+ i++;
+ }
+}
diff --git a/rtbuf_signal_sinus.c b/rtbuf_signal_sinus.c
index 72bb485..6eca06d 100644
--- a/rtbuf_signal_sinus.c
+++ b/rtbuf_signal_sinus.c
@@ -6,25 +6,25 @@
int rtbuf_signal_sinus (s_rtbuf *rtb)
{
- double phase;
unsigned int i = 0;
s_rtbuf_signal_sinus_data *data;
- int freq = rtb->var[RTBUF_SIGNAL_SINUS_VAR_FREQUENCY];
- int amp = rtb->var[RTBUF_SIGNAL_SINUS_VAR_AMPLITUDE];
- double *freq_samples = freq < 0 ? 0 : (double*) g_rtbuf[freq].data;
- double *amp_samples = amp < 0 ? 0 : (double*) g_rtbuf[amp].data;
+ double phase;
data = (s_rtbuf_signal_sinus_data*) rtb->data;
phase = data->phase;
while (i < RTBUF_SIGNAL_SAMPLES) {
- double f = freq_samples ? freq_samples[i] : 220.0;
- double a = amp_samples ? amp_samples[i] : 1.0;
+ double f = rtbuf_signal_sample(rtb,
+ RTBUF_SIGNAL_SINUS_VAR_FREQUENCY,
+ i, 220.0);
+ double a = rtbuf_signal_sample(rtb,
+ RTBUF_SIGNAL_SINUS_VAR_AMPLITUDE,
+ i, 1.0);
f = max(0.0, f);
a = max(0.0, a);
f /= (double) RTBUF_SIGNAL_SAMPLERATE;
phase = phase + 2.0 * M_PI * f;
while (phase >= 2.0 * M_PI)
phase -= 2.0 * M_PI;
- data->samples[i] = a * sin(phase);
+ data->signal[i] = a * sin(phase);
//printf(" i=%u f=%f a=%f %f", i, f, a, data->samples[i]);
i++;
}
diff --git a/rtbuf_signal_square.c b/rtbuf_signal_square.c
index 9eaf7b9..64fc5d1 100644
--- a/rtbuf_signal_square.c
+++ b/rtbuf_signal_square.c
@@ -15,26 +15,26 @@ int rtbuf_signal_square (s_rtbuf *rtb)
double phase;
unsigned int i = 0;
s_rtbuf_signal_square_data *data;
- int freq = rtb->var[RTBUF_SIGNAL_SQUARE_VAR_FREQUENCY];
- int amp = rtb->var[RTBUF_SIGNAL_SQUARE_VAR_AMPLITUDE];
- int pulse = rtb->var[RTBUF_SIGNAL_SQUARE_VAR_PULSE];
- double *freq_samples = freq < 0 ? 0 : (double*) g_rtbuf[freq].data;
- double *amp_samples = amp < 0 ? 0 : (double*) g_rtbuf[amp].data;
- double *pulse_samples = pulse < 0 ? 0 : (double*) g_rtbuf[pulse].data;
data = (s_rtbuf_signal_square_data*) rtb->data;
phase = data->phase;
while (i < RTBUF_SIGNAL_SAMPLES) {
- double f = freq_samples ? freq_samples[i] : 220.0;
- double a = amp_samples ? amp_samples[i] : 1.0;
- double p = pulse_samples ? pulse_samples[i] : 0.5;
+ double f = rtbuf_signal_sample(rtb,
+ RTBUF_SIGNAL_SQUARE_VAR_FREQUENCY,
+ i, 220.0);
+ double a = rtbuf_signal_sample(rtb,
+ RTBUF_SIGNAL_SQUARE_VAR_AMPLITUDE,
+ i, 1.0);
+ double p = rtbuf_signal_sample(rtb,
+ RTBUF_SIGNAL_SQUARE_VAR_PULSE,
+ i, 0.5);
f = max(0.0, f);
a = max(0.0, a);
p = clamp(0.0, p, 1.0);
//printf(" i=%u freq=%f amp=%f pulse=%f", i, f, a, p);
f /= (double) RTBUF_SIGNAL_SAMPLERATE;
- phase = phase + f;
- phase = phase - floor(phase);
- data->samples[i] = square(a, phase, p);
+ phase += f;
+ phase -= floor(phase);
+ data->signal[i] = square(a, phase, p);
//printf(" f=%f a=%f p=%f square=%f", f, a, p, data->samples[i]);
i++;
}
diff --git a/rtbuf_sndio.c b/rtbuf_sndio.c
index dd8f5b5..1e6b214 100644
--- a/rtbuf_sndio.c
+++ b/rtbuf_sndio.c
@@ -7,20 +7,31 @@
#include "rtbuf_signal.h"
#include "rtbuf_sndio.h"
+s_rtbuf_lib_fun_out g_rtbuf_sndio_input_out[] = {
+ { "left", RTBUF_SIGNAL_TYPE },
+ { "right", RTBUF_SIGNAL_TYPE },
+ { "samples", RTBUF_SNDIO_SAMPLES_TYPE },
+ { 0, 0 } };
+
+s_rtbuf_lib_fun_var g_rtbuf_sndio_output_var[] = {
+ { "left", RTBUF_SIGNAL_TYPE },
+ { "right", RTBUF_SIGNAL_TYPE },
+ { 0, 0 } };
+
+s_rtbuf_lib_fun_out g_rtbuf_sndio_output_out[] = {
+ { "samples", RTBUF_SNDIO_SAMPLES_TYPE },
+ { "reserved", RTBUF_SNDIO_OUTPUT_RESERVED_TYPE },
+ { 0, 0 } };
+
const char *rtbuf_lib_name = "sndio";
unsigned long rtbuf_lib_ver = RTBUF_LIB_VER;
s_rtbuf_lib_fun rtbuf_lib_fun[] = {
{ "input", rtbuf_sndio_input, rtbuf_sndio_input_start,
- rtbuf_sndio_input_stop,
- sizeof(s_rtbuf_sndio_input_data) / sizeof(double) + 1,
- sizeof(double), 0 },
+ rtbuf_sndio_input_stop, 0, g_rtbuf_sndio_input_out },
{ "output", rtbuf_sndio_output, rtbuf_sndio_output_start,
- rtbuf_sndio_output_stop,
- sizeof(s_rtbuf_sndio_output_data) / sizeof(short) + 1,
- sizeof(short),
- (const char*[]) { "left", "right", 0 } },
- { 0, 0, 0, 0, 0, 0, 0 }
-};
+ rtbuf_sndio_output_stop, g_rtbuf_sndio_output_var,
+ g_rtbuf_sndio_output_out },
+ { 0, 0, 0, 0, 0, 0 } };
void print_sio_par (struct sio_par *par)
{
diff --git a/rtbuf_sndio.h b/rtbuf_sndio.h
index 314b8bb..17cbfb7 100644
--- a/rtbuf_sndio.h
+++ b/rtbuf_sndio.h
@@ -1,6 +1,9 @@
#ifndef RTBUF_SNDIO_H
#define RTBUF_SNDIO_H
+#include <sndio.h>
+#include "rtbuf_signal.h"
+
void print_sio_par (struct sio_par *par);
enum {
@@ -9,9 +12,18 @@ enum {
RTBUF_SNDIO_CHANNELS
};
+#define RTBUF_SNDIO_SAMPLE_TYPE "short"
+#define RTBUF_SNDIO_SAMPLES \
+ (RTBUF_SNDIO_CHANNELS * RTBUF_SIGNAL_SAMPLES)
+#define RTBUF_SNDIO_SAMPLES_TYPE \
+ RTBUF_TYPE_SHORT_ARRAY(RTBUF_SNDIO_SAMPLES)
+
+typedef short t_rtbuf_sndio_sample;
+typedef t_rtbuf_sndio_sample t_rtbuf_sndio_samples[RTBUF_SNDIO_SAMPLES];
+
typedef struct rtbuf_sndio_input_data {
- double samples[RTBUF_SNDIO_CHANNELS][RTBUF_SIGNAL_SAMPLES];
- short short_samples[RTBUF_SNDIO_CHANNELS * RTBUF_SIGNAL_SAMPLES];
+ t_rtbuf_signal signal[RTBUF_SNDIO_CHANNELS];
+ t_rtbuf_sndio_samples samples;
} s_rtbuf_sndio_input_data;
int rtbuf_sndio_input (s_rtbuf *rtb);
@@ -19,12 +31,17 @@ int rtbuf_sndio_input_start (s_rtbuf *rtb);
int rtbuf_sndio_input_stop (s_rtbuf *rtb);
typedef struct rtbuf_sndio_output_data {
- short samples[RTBUF_SNDIO_CHANNELS * RTBUF_SIGNAL_SAMPLES];
+ t_rtbuf_sndio_samples samples;
struct sio_hdl *sio_hdl;
struct sio_par want;
struct sio_par have;
} s_rtbuf_sndio_output_data;
+#define RTBUF_SNDIO_OUTPUT_RESERVED_SIZE \
+ (sizeof(s_rtbuf_sndio_output_data) - sizeof(t_rtbuf_sndio_samples))
+#define RTBUF_SNDIO_OUTPUT_RESERVED_TYPE \
+ RTBUF_TYPE_CHAR_ARRAY(RTBUF_SNDIO_OUTPUT_RESERVED_SIZE)
+
int rtbuf_sndio_output (s_rtbuf *rtb);
int rtbuf_sndio_output_start (s_rtbuf *rtb);
int rtbuf_sndio_output_stop (s_rtbuf *rtb);
diff --git a/rtbuf_sndio_midi.c b/rtbuf_sndio_midi.c
new file mode 100644
index 0000000..1dbcbc0
--- /dev/null
+++ b/rtbuf_sndio_midi.c
@@ -0,0 +1,7 @@
+int rtbuf_sndio_midi (s_rtbuf *rtb)
+{
+}
+
+int rtbuf_sndio_midi_start (s_rtbuf *rtb)
+{
+}
diff --git a/rtbuf_sndio_output.c b/rtbuf_sndio_output.c
index 3a434d7..bc905ac 100644
--- a/rtbuf_sndio_output.c
+++ b/rtbuf_sndio_output.c
@@ -1,9 +1,9 @@
+#include <limits.h>
#include <sndio.h>
#include <stdio.h>
#include <strings.h>
#include "rtbuf.h"
-#include "rtbuf_signal.h"
#include "rtbuf_sndio.h"
void rtbuf_sndio_output_parameters (struct sio_par *want)
@@ -69,35 +69,25 @@ int rtbuf_sndio_output_stop (s_rtbuf *rtb)
int rtbuf_sndio_output (s_rtbuf *rtb)
{
s_rtbuf_sndio_output_data *data;
- double *in[RTBUF_SNDIO_CHANNELS];
short *sample;
unsigned int i = 0;
unsigned int j = 0;
data = (s_rtbuf_sndio_output_data*) rtb->data;
sample = data->samples;
//printf("sndio_output");
- while (j < RTBUF_SNDIO_CHANNELS) {
- in[j] = rtb->var[j] < 0 ? 0 : (double*) g_rtbuf[rtb->var[j]].data;
- j++;
- }
while (i < RTBUF_SIGNAL_SAMPLES) {
j = 0;
while (j < RTBUF_SNDIO_CHANNELS) {
- if (in[j]) {
- double limit = max(-1.0, min(*in[j], 1.0));
- in[j]++;
- *sample = (short) (((1 << 15) - 1) * limit);
- //printf(" %i", *sample);
- }
- else
- *sample = 0;
+ double in = rtbuf_signal_sample(rtb, j, i, 0.0);
+ in = clamp(-1.0, in, 1.0);
+ *sample = (short) (in < 0 ? in * -SHRT_MIN : in * SHRT_MAX);
+ //printf(" %i", *sample);
sample++;
j++;
}
i++;
}
- sio_write(data->sio_hdl, data->samples,
- sizeof(data->samples));
+ sio_write(data->sio_hdl, data->samples, sizeof(data->samples));
//printf("\n");
return 0;
}
diff --git a/rtbuf_type.c b/rtbuf_type.c
new file mode 100644
index 0000000..69e9f73
--- /dev/null
+++ b/rtbuf_type.c
@@ -0,0 +1,99 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include "rtbuf_type.h"
+#include "symbol.h"
+
+s_rtbuf_type g_rtbuf_type[RTBUF_TYPE_MAX];
+unsigned int g_rtbuf_type_n = 0;
+
+void rtbuf_type_init ()
+{
+ bzero(g_rtbuf_type, sizeof(g_rtbuf_type));
+ rtbuf_type_new("char", sizeof(char));
+ rtbuf_type_new("short", sizeof(short));
+ rtbuf_type_new("int", sizeof(int));
+ rtbuf_type_new("long", sizeof(long));
+ rtbuf_type_new("double", sizeof(double));
+}
+
+s_rtbuf_type * rtbuf_type_new (const char *name, unsigned int size)
+{
+ unsigned int i = 0;
+ while (i < RTBUF_TYPE_MAX) {
+ if (g_rtbuf_type[i].name == 0) {
+ g_rtbuf_type[i].name = symbol_intern(name);
+ g_rtbuf_type[i].size = size;
+ g_rtbuf_type_n++;
+ return &g_rtbuf_type[i];
+ }
+ i++;
+ }
+ return 0;
+}
+
+void rtbuf_type_delete (s_rtbuf_type *rt)
+{
+ if (rt->name) {
+ rt->name = 0;
+ rt->size = 0;
+ g_rtbuf_type_n--;
+ }
+}
+
+s_rtbuf_type * rtbuf_type_find (const char *name)
+{
+ unsigned int i = 0;
+ unsigned int n = g_rtbuf_type_n;
+ while (i < RTBUF_TYPE_MAX && n > 0) {
+ if (g_rtbuf_type[i].name) {
+ if (name == g_rtbuf_type[i].name)
+ return &g_rtbuf_type[i];
+ n--;
+ }
+ i++;
+ }
+ return 0;
+}
+
+s_rtbuf_type * rtbuf_type_parse_array (const char *name)
+{
+ char *bracket = strchr(name, '[');
+ if (bracket) {
+ char buf[1024];
+ s_rtbuf_type *before;
+ int len = bracket - name;
+ char *a = &buf[len + 1];
+ char *right_bracket;
+ unsigned int size;
+ strlcpy(buf, name, sizeof(buf));
+ buf[len] = 0;
+ if ((before = rtbuf_type(buf)) == 0)
+ return 0;
+ right_bracket = strchr(a, ']');
+ *right_bracket = 0;
+ size = atoi(a);
+ return rtbuf_type_new(buf, size);
+ }
+ return 0;
+}
+
+s_rtbuf_type * rtbuf_type_parse_pointer (const char *name)
+{
+ char *star = strchr(name, '*');
+ if (star && star[1] == 0)
+ return rtbuf_type_new(name, sizeof(void*));
+ return 0;
+}
+
+s_rtbuf_type * rtbuf_type (const char *name)
+{
+ const char *sym = symbol_find(name);
+ s_rtbuf_type *rt = sym ? rtbuf_type_find(sym) : 0;
+ if (!rt || !(rt = rtbuf_type_parse_array(name)) ||
+ !(rt = rtbuf_type_parse_pointer(name)))
+ printf("type not found: %s\n", name);
+ return rt;
+}
diff --git a/rtbuf_type.h b/rtbuf_type.h
new file mode 100644
index 0000000..6a5ea78
--- /dev/null
+++ b/rtbuf_type.h
@@ -0,0 +1,29 @@
+#ifndef RTBUF_TYPE_H
+#define RTBUF_TYPE_H
+
+#include "rtbuf_defs.h"
+
+struct rtbuf_type {
+ const char *name; /* symbol */
+ unsigned int size;
+};
+
+#define RTBUF_TYPE_MAX 1024
+
+s_rtbuf_type g_rtbuf_type[RTBUF_TYPE_MAX];
+unsigned int g_rtbuf_type_n;
+
+void rtbuf_type_init ();
+s_rtbuf_type * rtbuf_type_new (const char *name, unsigned int size);
+void rtbuf_type_delete (s_rtbuf_type *rt);
+s_rtbuf_type * rtbuf_type_find (const char *name);
+s_rtbuf_type * rtbuf_type (const char *name);
+
+#define RTBUF_TYPE_CHAR_ARRAY(size) "char[" #size "]"
+#define RTBUF_TYPE_SHORT_ARRAY(size) "short[" #size "]"
+#define RTBUF_TYPE_INT_ARRAY(size) "int[" #size "]"
+#define RTBUF_TYPE_LONG_ARRAY(size) "long[" #size "]"
+#define RTBUF_TYPE_FLOAT_ARRAY(size) "float[" #size "]"
+#define RTBUF_TYPE_DOUBLE_ARRAY(size) "double[" #size "]"
+
+#endif
diff --git a/symbol.c b/symbol.c
index d50b6fb..432f427 100644
--- a/symbol.c
+++ b/symbol.c
@@ -10,28 +10,12 @@ unsigned int g_string_n = 0;
const char *g_symbols[SYMBOL_MAX];
unsigned int g_symbols_n = 0;
-void init_symbols () {
+void symbols_init () {
bzero(g_string, sizeof(g_string));
bzero(g_symbols, sizeof(g_symbols));
}
-symbol find_symbol (const char *name)
-{
- unsigned int i = 0;
- unsigned int n = g_symbols_n;
- while (i < SYMBOL_MAX && n > 0) {
- if (g_symbols[i]) {
- if (name == g_symbols[i] ||
- strcmp(name, g_symbols[i]) == 0)
- return g_symbols[i];
- n--;
- }
- i++;
- }
- return 0;
-}
-
-symbol make_symbol (const char *name)
+symbol symbol_new (const char *name)
{
unsigned int i = 0;
if (g_symbols_n == SYMBOL_MAX) {
@@ -57,10 +41,26 @@ symbol make_symbol (const char *name)
return 0;
}
-const char * intern (const char *name)
+symbol symbol_find (const char *name)
+{
+ unsigned int i = 0;
+ unsigned int n = g_symbols_n;
+ while (i < SYMBOL_MAX && n > 0) {
+ if (g_symbols[i]) {
+ if (name == g_symbols[i] ||
+ strcmp(name, g_symbols[i]) == 0)
+ return g_symbols[i];
+ n--;
+ }
+ i++;
+ }
+ return 0;
+}
+
+symbol symbol_intern (const char *name)
{
- const char *sym = find_symbol(name);
+ symbol sym = symbol_find(name);
if (sym == 0)
- sym = make_symbol(name);
+ sym = symbol_new(name);
return sym;
}
diff --git a/symbol.h b/symbol.h
index f2bf1ae..cb5c133 100644
--- a/symbol.h
+++ b/symbol.h
@@ -11,9 +11,10 @@ extern unsigned int g_string_n;
extern symbol g_symbols[SYMBOL_MAX];
extern unsigned int g_symbols_n;
-void init_symbols ();
-symbol find_symbol (symbol name);
-symbol make_symbol (symbol name);
-symbol intern (symbol name);
+void symbols_init ();
+symbol symbol_new (symbol name);
+void symbol_delete (symbol sym);
+symbol symbol_find (symbol name);
+symbol symbol_intern (const char *name);
#endif