9. tlseq
The tlseq
node provides a sample sequencer node similar to
tseq
that takes in ftlist directly. This example is
designed to showcase the sample accurate choosing
capabilities.
9.1. Struct
<<tlseq_struct>>=
typedef struct {
gf_cable *trig;
gf_cable *out;
sp_ftlist *ftl;
GFFLT last;
int pos;
} tlseq;
9.2. Node
<<tlseq_funcdefs>>=
int node_tlseq(gf_node *node, sp_ftlist *ftl);
<<tlseq_funcs>>=
int node_tlseq(gf_node *node, sp_ftlist *ftl)
{
tlseq *seq;
void *mem;
gf_patch *patch;
int rc;
rc = gf_node_get_patch(node, &patch);
if (rc != GF_OK) return rc;
rc = gf_memory_alloc(patch, sizeof(tlseq), &mem);
if (rc != GF_OK) return rc;
seq = mem;
seq->ftl = ftl;
seq->pos = -1;
seq->last = 0;
gf_node_cables_alloc(node, 2);
gf_node_set_block(node, 1);
gf_node_get_cable(node, 0, &seq->trig);
gf_node_get_cable(node, 1, &seq->out);
gf_node_set_data(node, seq);
gf_node_set_compute(node, compute);
gf_node_set_destroy(node, destroy);
return GF_OK;
}
The computation is reasonably straight forward. Read the
trigger and position cables. Any time the trigger is
non-zero, run sp_ftlist_choose
.
<<tlseq_static_funcdefs>>=
static void compute(gf_node *node);
<<tlseq_funcs>>=
static void compute(gf_node *node)
{
int blksize;
tlseq *seq;
int n;
blksize = gf_node_blksize(node);
seq = gf_node_get_data(node);
for (n = 0; n < blksize; n++) {
GFFLT t;
t = gf_cable_get(seq->trig, n);
if (t != 0) {
sp_ftbl *ft;
ft = sp_ftlist_target_sa(seq->ftl, n);
seq->pos++;
while (seq->pos >= ft->size) {
seq->pos -= ft->size;
}
seq->last = ft->tbl[seq->pos];
}
gf_cable_set(seq->out, n, seq->last);
}
}
<<tlseq_static_funcdefs>>=
static void destroy(gf_node *node);
<<tlseq_funcs>>=
static void destroy(gf_node *node)
{
int rc;
gf_patch *patch;
void *mem;
gf_node_cables_free(node);
rc = gf_node_get_patch(node, &patch);
if (rc != GF_OK) return;
mem = gf_node_get_data(node);
gf_memory_free(patch, &mem);
}
9.3. Runt Loader
tlseq is loaded as a runt word using the function
load_tlseq
.
<<tlseq_funcdefs>>=
int load_tlseq(runt_vm *vm, runt_ptr pw);
<<tlseq_funcs>>=
int load_tlseq(runt_vm *vm, runt_ptr pw)
{
runt_cell *c;
runt_keyword_define(vm, "tlseq", 5, rproc_tlseq, &c);
runt_cell_data(vm, c, pw);
return runt_is_alive(vm);
}
9.4. Runt Word
<<tlseq_static_funcdefs>>=
static runt_int rproc_tlseq(runt_vm *vm, runt_ptr p);
<<tlseq_funcdefs>>=
static runt_int rproc_tlseq(runt_vm *vm, runt_ptr p)
{
runt_int rc;
gf_patch *patch;
rgf_param trig;
sp_ftlist *ftlst;
gf_node *node;
runt_stacklet *out;
rc = rgf_get_ftlist(vm, &ftlst);
RUNT_ERROR_CHECK(rc);
rc = rgf_get_param(vm, &trig);
RUNT_ERROR_CHECK(rc);
rc = runt_ppush(vm, &out);
RUNT_ERROR_CHECK(rc);
patch = rgf_get_patch(p);
rc = gf_patch_new_node(patch, &node);
GF_RUNT_ERROR_CHECK(rc);
node_tlseq(node, ftlst);
rgf_set_param(vm, node, &trig, 0);
rgf_push_output(vm, node, out, 1);
return RUNT_OK;
}
prev | home | next