8. Seq16 Graforge Nodes
8.1. Clock Node
Clocks the sequence. Should only be called once, and before trying to get values.
8.1.1. Clock Node Function
static int node_seq16clk(gf_node *node, page_seq16_d *seq16);
<<seq16_node_functions>>
static int node_seq16clk(gf_node *node, page_seq16_d *seq16)
{
gf_node_cables_alloc(node, 1);
gf_node_set_data(node, seq16);
gf_node_set_compute(node, clk_compute);
return GF_OK;
}
8.1.2. Clock Compute
static void clk_compute(gf_node *n)
{
int blksize;
int s;
gf_cable *in;
page_seq16_d *seq;
blksize = gf_node_blksize(n);
seq = gf_node_get_data(n);
gf_node_get_cable(n, 0, &in);
seq->nevt = 0;
seq->lastpos = seq->pos;
for(s = 0; s < blksize; s++) {
if (gf_cable_get(in, s) != 0) {
if (seq->reset) {
seq->reset = 0;
seq->nevt = 0;
seq16_draw_col(seq, seq->pos);
seq->lastpos = -1;
seq->pos = -1;
}
if (seq->nevt >= 4) continue;
seq->evt[seq->nevt] = s;
seq->nevt++;
seq16_draw_col(seq, seq->pos);
seq->pos = (seq->pos + 1) % seq->size;
if (seq->playhead) seq16_draw_playhead(seq, seq->pos);
}
}
}
8.2. Seq16 value
8.2.1. Value Node Function
static int node_seq16val(gf_node *node, page_seq16_d *seq16);
<<seq16val_node_functions>>
static int node_seq16val(gf_node *node, page_seq16_d *seq16)
{
gf_node_cables_alloc(node, 1);
gf_node_set_block(node, 0);
gf_node_set_data(node, seq16);
gf_node_set_compute(node, val_compute);
return GF_OK;
}
8.2.2. Value Node Compute
The value function will locally step through the event stack and "replay" the sequences.
static void val_compute(gf_node *n)
{
int blksize;
int s;
gf_cable *out;
page_seq16_d *seq;
int *evt;
int nevt;
int val;
int pos;
int evtpos;
blksize = gf_node_blksize(n);
seq = gf_node_get_data(n);
gf_node_get_cable(n, 0, &out);
pos = seq->lastpos;
nevt = seq->nevt;
evt = seq->evt;
evtpos = 0;
if (pos < 0) val = 0;
else val = seq->seq[pos];
for(s = 0; s < blksize; s++) {
if (evtpos < nevt) {
if (evt[evtpos] == s) {
pos = (pos + 1) % seq->size;
val = seq->seq[pos];
evtpos++;
}
}
gf_cable_set(out, s, val);
}
}
8.3. Seq16 gate
8.3.1. Gate Function
static int node_seq16gt(gf_node *node, page_seq16_d *seq16);
<<seq16gt_node_functions>>
static int node_seq16gt(gf_node *node, page_seq16_d *seq16)
{
gf_node_cables_alloc(node, 1);
gf_node_set_block(node, 0);
gf_node_set_data(node, seq16);
gf_node_set_compute(node, gt_compute);
return GF_OK;
}
8.3.2. Gate Compute
Gate is identical in behavior to val, except for the last bit. The value is checked for 0 values. A zero value is a 0, anything else is a 1.
static void gt_compute(gf_node *n)
{
int blksize;
int s;
gf_cable *out;
page_seq16_d *seq;
int *evt;
int nevt;
int val;
int pos;
int evtpos;
blksize = gf_node_blksize(n);
seq = gf_node_get_data(n);
gf_node_get_cable(n, 0, &out);
pos = seq->lastpos;
nevt = seq->nevt;
evt = seq->evt;
evtpos = 0;
if (pos < 0) val = 0;
else val = seq->seq[pos];
for(s = 0; s < blksize; s++) {
if (evtpos < nevt) {
if (evt[evtpos] == s) {
pos = (pos + 1) % seq->size;
val = seq->seq[pos];
evtpos++;
}
}
gf_cable_set(out, s, val != 0);
}
}
8.4. Clock Getter
Once a clock has been set, this signal can be dynamically reconstructed. This sort of thing is useful for times when the clock signal gets processed somehow before being sent into seq16 (with a probability filter, or a clock divider).
8.4.1. Clock Getter Node
static int node_seq16clkget(gf_node *node, page_seq16_d *seq16);
<<seq16clkget_node_functions>>
static int node_seq16clkget(gf_node *node, page_seq16_d *seq16)
{
gf_node_cables_alloc(node, 1);
gf_node_set_block(node, 0);
gf_node_set_data(node, seq16);
gf_node_set_compute(node, clkget_compute);
return GF_OK;
}
8.4.2. Clock Getter Compute
This works very similary to the gate compute function. It reads values from the event stack. When it reaches an event, it turns on a trigger.
static void clkget_compute(gf_node *n)
{
int blksize;
int s;
gf_cable *out;
page_seq16_d *seq;
int *evt;
int nevt;
int evtpos;
blksize = gf_node_blksize(n);
seq = gf_node_get_data(n);
gf_node_get_cable(n, 0, &out);
nevt = seq->nevt;
evt = seq->evt;
evtpos = 0;
for(s = 0; s < blksize; s++) {
GFFLT o;
o = 0;
if (evtpos < nevt) {
if (evt[evtpos] == s) {
o = 1;
evtpos++;
}
}
gf_cable_set(out, s, o);
}
}
8.5. TODO Column Getter
Gets a value from a specific column. Intended to be used if you want to use seq16 as a set of 16 8-item choosers.
8.5.1. Column Getter Node
static int node_seq16col(gf_node *node, page_seq16_d *seq16);
<<seq16col_node_functions>>
static int node_seq16col(gf_node *node, page_seq16_d *seq16)
{
gf_node_cables_alloc(node, 2);
gf_node_set_block(node, 1);
gf_node_set_data(node, seq16);
gf_node_set_compute(node, col_compute);
return GF_OK;
}
8.5.2. Column Getter Compute
static void col_compute(gf_node *n)
{
int blksize;
int s;
gf_cable *out;
gf_cable *col;
page_seq16_d *seq;
blksize = gf_node_blksize(n);
seq = gf_node_get_data(n);
gf_node_get_cable(n, 0, &col);
gf_node_get_cable(n, 1, &out);
for(s = 0; s < blksize; s++) {
GFFLT o;
int c;
o = 0;
c = floor(gf_cable_get(col, s));
o = seq16_colget(seq, c);
gf_cable_set(out, s, o);
}
}
prev | home | next