4. Line16 Core Functions
4.1. Draw Point Bank
Given a point and position, will draw the slot on the grid.
In progress. Right now, we just mark if things are active or not.
static void line16_draw_point(line16_point *pt,
int pos,
monolith_page_mstate *m);
static void line16_draw_point(line16_point *pt,
int pos,
monolith_page_mstate *ms)
{
if(pt->active) {
monolith_page_mstate_led_set(ms, pos, 1, 1);
} else {
monolith_page_mstate_led_set(ms, pos, 1, 0);
}
line16_draw_point_type(pt, pos, ms);
}
4.2. Draw Point Type
static void line16_draw_point_type(line16_point *pt,
int pos,
monolith_page_mstate *m);
Because the type flag has a special bit reserved for trigger mode, the type needs to be bitmasked in order to work.
static void line16_draw_point_type(line16_point *pt,
int pos,
monolith_page_mstate *m)
{
int y;
int type;
type = pt->type & 3;
for(y = 0; y < 4; y++) {
if(type == y) {
monolith_page_mstate_led_set(m, pos, y + 2, 1);
} else {
monolith_page_mstate_led_set(m, pos, y + 2, 0);
}
}
}
4.3. Draw Point Togmode
static void line16_draw_point_togmode(line16_point *pt,
monolith_page_mstate *m);
static void line16_draw_point_togmode(line16_point *pt,
monolith_page_mstate *m)
{
int t;
t = pt->type & 1<<2;
monolith_page_mstate_led_set(m, 0, 7, t);
}
4.4. Draw Selected Line
Draws the select line on the control panel, located in the bottom right corner.
static void line16_draw_selected_line(int selected,
monolith_page_mstate *m);
static void line16_draw_selected_line(int selected,
monolith_page_mstate *m)
{
int t;
int s;
for (t = 0; t < 4; t++) {
s = (selected & (1 << t)) != 0;
monolith_page_mstate_led_set(m,
12 + t, 7,
s);
}
}
4.5. Redraw all points
Will redraw all points on the grid. At the very least, this will be called at creation.
static void line16_redraw_points(page_line16_d *l);
static void line16_redraw_points(page_line16_d *l)
{
int pt;
line16_point *points;
points = l->lines[l->selected_line].points;
for(pt = 0; pt < 16; pt++) {
line16_draw_point(&points[pt],
pt,
l->mstate);
}
}
4.6. Display Point Values
Given a point, this will display the point values on the arc.
static void line16_display_vals(line16_point *pt,
monolith_page_arcstate *as);
static void line16_display_vals(line16_point *pt,
monolith_page_arcstate *as)
{
monolith_arcstate_mapval(as, 0, pt->val);
monolith_arcstate_mapval(as, 1, pt->dur);
monolith_arcstate_mapval(as, 2, pt->aux[0]);
monolith_arcstate_mapval(as, 3, pt->aux[1]);
}
4.7. Select a point
This will select a point, and update the UI.
static void line16_select_point(page_line16_d *l, int pt);
static void line16_select_point(page_line16_d *l, int pt)
{
line16_line *line;
if(pt < 0 || pt >= 16) return;
line = &l->lines[l->selected_line];
l->selected_point = pt;
line16_display_vals(&line->points[pt], l->arcstate);
line16_draw_point_togmode(&line->points[pt], l->mstate);
monolith_page_mstate_led_row16(l->mstate, 0, 1<<pt);
}
Point can be retrieved using line16_select_point_get
.
static int line16_select_point_get(page_line16_d *l);
static int line16_select_point_get(page_line16_d *l)
{
return l->selected_point;
}
4.8. Compute a Line
This computes a line segment, which is then written to the internal block.
4.8.1. Main Callback
static void line16_compute_line(page_line16_d *l,
gf_patch *p,
gf_cable *in);
A line is a connection between to points. At the time of writing, this connection is limited to linear interpolation. Exponential mapping could be in the future, but to get things started, linear.
A line has three main components. A point A, a point B, and a duration between the two. A counter keeps tracker of the current line position, which is then used to derive position.
When the position has reached the length of the duration, a new line segment begins! The points, duration, and counter are updated.
static void update_counters(page_line16_d *l)
{
l->timer += l->onedsr * l->rate;
/* to prevent overflow, circle between values */
if(l->timer > 10) {
l->timer = 1; /* low but still slow */
}
/* do it again for aux timer */
l->aux_timer += l->onedsr * l->rate;
if(l->aux_timer > 10) {
l->aux_timer = 1;
}
}
static void line16_compute_line(page_line16_d *l,
gf_patch *p,
gf_cable *in)
{
int blksize;
int s;
gf_cable *out;
GFFLT dur;
GFFLT o;
line16_point *pt_a;
line16_point *pt_b;
blksize = gf_patch_blksize(p);
line16_state_apply(l);
out = &l->out;
if (l->pointpos < 0) {
line16_start_line(l);
line16_aux_cache_udpate(l);
line16_update_pointpos(l);
if(l->pointpos < 0) {
for(s = 0; s < blksize; s++) {
gf_cable_set(out, s, 0);
update_counters(l);
}
return;
}
}
pt_a = line16_get_point(l, l->pointpos);
pt_b = line16_get_point(l, l->nextpoint);
if (pt_a == NULL && pt_b == NULL) return;
for (s = 0; s < blksize; s++) {
if (gf_cable_get(in, s) != 0) {
l->trig = 1;
}
if (l->pointpos < 0) {
o = 0;
} else {
if (l->pointpos < 0) {
o = 0;
} else {
pt_a = line16_get_point(l, l->pointpos);
pt_b = line16_get_point(l, l->nextpoint);
dur = line16_durscale(l, pt_a->dur);
if (l->counter >= dur) {
line16_begin_segment(l);
pt_a = line16_get_point(l, l->pointpos);
pt_b = line16_get_point(l, l->nextpoint);
line16_aux_cache_udpate(l);
line16_update_pointpos(l);
}
if (l->pointpos >= 0) {
/* calculate the line */
if ((pt_a->type & 4) && l->trig == 0) {
o = pt_a->val;
} else {
switch (pt_a->type & 3) {
case SLOPE_LINEAR:
o = line_linear(l,
pt_a, pt_b,
l->counter);
break;
case SLOPE_EXP_POSITIVE:
o = line_exp_pos(l,
pt_a, pt_b,
l->counter,
l->aux_cache[0]);
break;
case SLOPE_EXP_NEGATIVE:
o = line_exp_neg(l,
pt_a, pt_b,
l->counter,
l->aux_cache[0]);
break;
case SLOPE_BEZIER:
o = line_bezier(l,
pt_a, pt_b,
l->counter,
l->aux_cache[0],
l->aux_cache[1]);
break;
default:
o = line_linear(l,
pt_a, pt_b,
l->counter);
break;
}
l->counter += l->onedsr *
l->rate *
pt_a->rate;
}
} else {
o = 0;
}
}
}
gf_cable_set(out, s, o);
update_counters(l);
}
}
4.8.2. Line Slope Functions
4.8.2.1. Linear
static GFFLT line_linear(page_line16_d *l,
line16_point *pt_a,
line16_point *pt_b,
GFFLT counter);
static GFFLT line_linear(page_line16_d *l,
line16_point *pt_a,
line16_point *pt_b,
GFFLT counter)
{
GFFLT a, b;
GFFLT o;
GFFLT dur;
a = pt_a->val;
b = pt_b->val;
dur = line16_durscale(l, pt_a->dur);
o = a + (b - a) * (counter / dur);
return o;
}
4.8.2.2. Exponential Positive
static GFFLT line_exp_pos(page_line16_d *l,
line16_point *pt_a,
line16_point *pt_b,
GFFLT counter,
GFFLT aux);
static GFFLT line_exp_pos(page_line16_d *l,
line16_point *pt_a,
line16_point *pt_b,
GFFLT counter,
GFFLT aux)
{
GFFLT a, b;
GFFLT o;
GFFLT slp;
GFFLT dur;
a = pt_a->val;
b = pt_b->val;
dur = line16_durscale(l, pt_a->dur);
slp = 1 + (15 * aux);
o = a + (b - a) *
(1 - exp(counter * slp / dur)) /
(1 - exp(slp));
return o;
}
4.8.2.3. Exponential Negative
static GFFLT line_exp_neg(page_line16_d *l,
line16_point *pt_a,
line16_point *pt_b,
GFFLT counter,
GFFLT aux);
static GFFLT line_exp_neg(page_line16_d *l,
line16_point *pt_a,
line16_point *pt_b,
GFFLT counter,
GFFLT aux)
{
GFFLT a, b;
GFFLT o;
GFFLT slp;
GFFLT dur;
a = pt_a->val;
b = pt_b->val;
dur = line16_durscale(l, pt_a->dur);
slp = -1 - (15 * aux);
o = a + (b - a) *
(1 - exp(counter * slp / dur)) /
(1 - exp(slp));
return o;
}
4.8.2.4. Bezier
The reference equation:
B(t) = (1 - t)^2P0 + 2(1 - t)P1 + t^2P2
static GFFLT line_bezier(page_line16_d *l,
line16_point *pt_a,
line16_point *pt_b,
GFFLT counter,
GFFLT aux1,
GFFLT aux2);
static GFFLT line_bezier(page_line16_d *l,
line16_point *pt_a,
line16_point *pt_b,
GFFLT counter,
GFFLT aux1,
GFFLT aux2)
{
GFFLT a, b;
GFFLT o;
GFFLT x[3];
GFFLT y[3];
GFFLT dur;
GFFLT val;
GFFLT t;
a = pt_a->val;
b = pt_b->val;
dur = line16_durscale(l, pt_a->dur);
/* some light clamping... in case of weirdness */
val = aux1;
if(val < 0.001) val = 0.001;
if(val > 0.999) val = 0.99;
x[0] = 0;
y[0] = a;
x[1] = (dur * val);
y[1]= aux2;
x[2] = dur;
y[2] = b;
t = find_t(x[0], x[1], x[2], counter);
o = (1.0 - t) * (1.0 - t) * y[0] +
2.0 * (1.0 - t) * t * y[1] +
t * t * y[2];
return o;
}
static GFFLT find_t(GFFLT x0, GFFLT x1, GFFLT x2, GFFLT x);
static GFFLT find_t(GFFLT x0, GFFLT x1, GFFLT x2, GFFLT x)
{
GFFLT a;
GFFLT b;
GFFLT c;
GFFLT out;
GFFLT det;
a = (x0 - 2.0 * x1 + x2);
b = 2.0 * (-x0 + x1);
c = x0 - x;
out = 0;
if(a) {
det = b * b - 4 * a * c;
if(det > 0)
out = ((-b + sqrt(det))/(2.0 * a));
else
out = 0;
} else {
if(b != 0) out = (x - x0)/b;
}
return out;
}
4.9. DONE Compute a Local Line
CLOSED: [2020-01-03 Fri 14:16] This function is used to compute a single line instance. It will compute once per block.
void line16_compute_localline(line16_localline *localline,
gf_patch *patch,
gf_cable *in,
gf_cable *out);
void line16_compute_localline(line16_localline *ll,
gf_patch *patch,
gf_cable *in,
gf_cable *out)
{
int blksize;
int s;
/* gf_cable *out; */
GFFLT dur;
GFFLT o;
line16_point *pt_a;
line16_point *pt_b;
line16_line *line;
page_line16_d *pg;
blksize = gf_patch_blksize(patch);
/* line16_state_apply(l); */
/* out = &l->out; */
line = ll->l;
pg = ll->pg;
if (ll->pointpos < 0) {
line16_start_line_local(ll);
/* line16_update_pointpos(l); */
pt_a = line16_line_point(line, ll->pointpos);
if (pt_a != NULL) {
ll->aux[0] = pt_a->aux[0];
ll->aux[1] = pt_a->aux[1];
}
if(ll->pointpos < 0) {
for(s = 0; s < blksize; s++) {
gf_cable_set(out, s, 0);
/* update_counters(l); */
}
return;
}
}
pt_a = line16_line_point(line, ll->pointpos);
pt_b = line16_line_point(line, ll->nextpoint);
if (pt_a == NULL && pt_b == NULL) return;
for (s = 0; s < blksize; s++) {
if (gf_cable_get(in, s) != 0) ll->trig = 1;
if (ll->pointpos < 0) {
o = 0;
} else {
if (ll->pointpos < 0) {
o = 0;
} else {
pt_a = line16_line_point(line, ll->pointpos);
pt_b = line16_line_point(line, ll->nextpoint);
dur = line16_durscale(pg, pt_a->dur);
if (ll->counter >= dur) {
line16_begin_local(ll);
pt_a = line16_line_point(line, ll->pointpos);
pt_b = line16_line_point(line, ll->nextpoint);
/* line16_aux_cache_udpate(l); */
/* line16_update_pointpos(l); */
ll->aux[0] = pt_a->aux[0];
ll->aux[1] = pt_a->aux[1];
}
if (ll->pointpos >= 0) {
/* calculate the line */
if ((pt_a->type & 4) && ll->trig == 0) {
o = pt_a->val;
} else {
switch (pt_a->type & 3) {
case SLOPE_LINEAR:
o = line_linear(pg,
pt_a, pt_b,
ll->counter);
break;
case SLOPE_EXP_POSITIVE:
o = line_exp_pos(pg,
pt_a, pt_b,
ll->counter,
ll->aux[0]);
break;
case SLOPE_EXP_NEGATIVE:
o = line_exp_neg(pg,
pt_a, pt_b,
ll->counter,
ll->aux[0]);
break;
case SLOPE_BEZIER:
o = line_bezier(pg,
pt_a, pt_b,
ll->counter,
ll->aux[0],
ll->aux[1]);
break;
default:
o = line_linear(pg,
pt_a, pt_b,
ll->counter);
break;
}
ll->counter += pg->onedsr *
pg->rate *
pt_a->rate;
}
} else {
o = 0;
}
}
}
gf_cable_set(out, s, o);
/* update_counters(l); */
}
}
This line is self contained and ancillary to the main line sequence. For this reason it is known as "local".
The biggest difference between the local line and the main line is that the local line can only loop between itself.
The local line callback expects an input and output cable. The input cable contains a trigger signal for points that wait. The output cable is where the line will write the signal to.
As the name would suggest, the local line utilizes local variables. Local variables are stored in a struct and are passed to the line callback.
Some Local variables I see here include:
- counter - pointpos - nextpoint - trig - local aux cache
typedef struct line16_localline line16_localline;
struct line16_localline {
page_line16_d *pg;
line16_line *l;
GFFLT counter;
int pointpos;
int nextpoint;
int trig;
GFFLT aux[2];
};
This struct is initialized with line16_localline_init
.
void line16_localline_init(line16_localline *l,
line16_line *line,
page_line16_d *pg);
void line16_localline_init(line16_localline *l,
line16_line *line,
page_line16_d *pg)
{
l->counter = 0;
l->pointpos = -1;
l->nextpoint = -1;
l->trig = 0;
l->l = line;
l->pg = pg;
l->aux[0] = 0;
l->aux[1] = 0;
}
4.10. Find Next Point (Main and Local)
This will return the next available point. This will start at the current point, and iterate through the points in ascending order until a point has been found. This can include wrapping back to the beginning, if need be.
If there are no active points to be found, this function will return a negative value. If there is only one active point, it means that the current point will be returned.
4.10.1. Main
static int line16_find_next(page_line16_d *l, int after);
In the for loop, n starts on 1 in order to skip the current point position.
static int line16_find_next(page_line16_d *l, int after)
{
line16_line *line;
line = &l->lines[l->playing_line];
return line16_line_find_next(line, after);
}
4.10.2. Local
static int line16_line_find_next(line16_line *l, int after);
In the for loop, n starts on 1 in order to skip the current point position.
static int line16_line_find_next(line16_line *l, int after)
{
int pp;
int n;
int pos;
line16_point *pt;
pp = after;
if(l->nactive == 0) {
return -1;
} else if(l->nactive == 1 && pp >= 0) {
return pp;
}
for(n = 0; n < 16; n++) {
pos = (pp + n + 1) % 16;
pt = &l->points[pos];
if(pt->active) return pos;
}
return -1;
}
4.11. Increment Value
Increments a value up or down and returns it. This includes clamping value to be in range 0-1.
static GFFLT line16_increment(GFFLT val, int delta);
static GFFLT line16_increment(GFFLT val, int delta)
{
val += 0.001 * delta;
if(val < 0) val = 0;
else if(val > 1) val = 1;
return val;
}
4.12. Get Point (Main and Local)
Given an index value, retrieve the point. If point is out of range, return NULL.
4.12.1. Main Point Getter
line16_point * line16_get_point(page_line16_d *l, int pt);
line16_point * line16_get_point(page_line16_d *l, int pt)
{
line16_line *line;
line = &l->lines[l->playing_line];
return line16_line_point(line, pt);
}
4.12.2. Get Local Point
Get a point from a particular line.
line16_point * line16_line_point(line16_line *l, int pt);
line16_point * line16_line_point(line16_line *l, int pt)
{
if(pt < 0 || pt >= 16) return NULL;
return &l->points[pt];
}
4.13. Point Setters/Getters
Where l
is the page data, line
is the line number
(in case we implement multiple lines), pos
is the
point position on the line, and val
is the value to be
set.
4.13.1. line16_point_val_set
static void line16_point_val_set(page_line16_d *l,
int linepos,
int pos,
GFFLT val);
static void line16_point_val_set(page_line16_d *l,
int linepos,
int pos,
GFFLT val)
{
line16_line *line;
int lite;
if (val < 0) val = 0;
if (val > 1) val = 1;
if (pos < 0) pos = 0;
if (pos > 15) pos = 15;
if (linepos < 0) linepos = 0;
if (linepos > 15) linepos = 15;
line = &l->lines[linepos];
line->points[pos].val = val;
lite =
linepos == l->selected_line &&
pos == l->selected_point;
if (lite) {
monolith_arcstate_mapval(l->arcstate, 0, val);
}
}
4.13.2. line16_point_val_get
static GFFLT line16_point_val_get(page_line16_d *l,
int linepos,
int pos);
static GFFLT line16_point_val_get(page_line16_d *l,
int linepos,
int pos)
{
line16_line *line;
if(pos < 0) pos = 0;
if(pos > 15) pos = 15;
if (linepos < 0) linepos = 0;
if (linepos > 15) linepos = 15;
line = &l->lines[linepos];
return line->points[pos].val;
}
4.13.3. line16_point_dur_set
static void line16_point_dur_set(page_line16_d *l,
int linepos,
int pos,
GFFLT dur);
static void line16_point_dur_set(page_line16_d *l,
int linepos,
int pos,
GFFLT dur)
{
line16_line *line;
int lite;
if(dur < 0) dur = 0;
if(dur > 1) dur = 1;
if(pos < 0) pos = 0;
if(pos > 15) pos = 15;
if(linepos < 0) linepos = 0;
if(linepos > 15) linepos = 15;
line = &l->lines[linepos];
line->points[pos].dur = dur;
lite =
linepos == l->selected_line &&
pos == l->selected_point;
if(lite) {
monolith_arcstate_mapval(l->arcstate, 1, dur);
}
}
4.13.4. line16_point_dur_get
static GFFLT line16_point_dur_get(page_line16_d *l,
int line,
int pos);
static GFFLT line16_point_dur_get(page_line16_d *l,
int linepos,
int pos)
{
line16_line *line;
if(pos < 0) pos = 0;
if(pos > 15) pos = 15;
if(linepos < 0) linepos = 0;
if(linepos > 15) linepos = 15;
line = &l->lines[linepos];
return line->points[pos].dur;
}
4.13.5. line16_point_aux_set
static void line16_point_aux_set(page_line16_d *l,
int linepos,
int pos,
int aux,
GFFLT val);
Because this can set the monome, this function is rate limited. This is especially important for cases when the aux value is being set by a graforge node.
static void line16_point_aux_set(page_line16_d *l,
int linepos,
int pos,
int aux,
GFFLT val)
{
line16_line *line;
int lite;
if(val < 0) val = 0;
if(val > 1) val = 1;
if(pos < 0) pos = 0;
if(pos > 15) pos = 15;
if(aux < 0) aux = 0;
if(aux > 1) aux = 1;
if(linepos < 0) linepos = 0;
if(linepos > 15) linepos = 15;
line = &l->lines[linepos];
line->points[pos].aux[aux] = val;
lite =
linepos == l->selected_line &&
pos == l->selected_point;
if (lite) {
if(l->aux_timer < AUX_MIN_DUR) return;
monolith_arcstate_mapval(l->arcstate,
2 + aux,
val);
l->aux_timer = 0;
}
}
4.13.6. line16_point_aux_get
static GFFLT line16_point_aux_get(page_line16_d *l,
int linepos,
int pos,
int aux);
static GFFLT line16_point_aux_get(page_line16_d *l,
int linepos,
int pos,
int aux)
{
line16_line *line;
if (pos < 0) pos = 0;
if (pos > 15) pos = 15;
if (linepos < 0) linepos = 0;
if (linepos > 15) linepos = 15;
line = &l->lines[linepos];
return line->points[pos].aux[aux];
}
4.13.7. line16_point_status_set
static void line16_point_status_set(page_line16_d *l,
int line,
int pos,
int status);
static void line16_point_status_set(page_line16_d *l,
int line,
int pos,
int status)
{
if (pos < 0) pos = 0;
if (pos > 15) pos = 15;
if (line == l->selected_line) {
monolith_page_mstate_led_set(l->mstate,
pos, 1, (status != 0));
/* TODO state_set should know which line, no? */
line16_state_set(l, pos, status);
}
}
4.13.8. line16_point_status_get
static int line16_point_status_get(page_line16_d *l,
int linepos,
int pos);
static int line16_point_status_get(page_line16_d *l,
int linepos,
int pos)
{
line16_line *line;
if (pos < 0) pos = 0;
if (pos > 15) pos = 15;
if (linepos < 0) linepos = 0;
if (linepos > 15) linepos = 15;
line = &l->lines[linepos];
return line->points[pos].active;
}
4.13.9. line16_point_type_set
static void line16_point_type_set(page_line16_d *l,
int linepos,
int pos,
int type);
Because the type flag stores extra data in the upper bits (like the trigger flag), setting must be done to only change the lower two bits.
static void line16_point_type_set(page_line16_d *l,
int linepos,
int pos,
int type)
{
int tmp;
line16_line *line;
if(pos < 0) pos = 0;
if(pos > 15) pos = 15;
if (linepos < 0) linepos = 0;
if (linepos > 15) linepos = 15;
line = &l->lines[linepos];
tmp = line->points[pos].type;
tmp &= ~3; /* clear last two bits */
tmp |= type & 3; /* mask + set */
line->points[pos].type = tmp;
}
4.13.10. line16_point_type_get
static int line16_point_type_get(page_line16_d *l,
int linepos,
int pos);
The value is AND'd, because other data is stored in the upper bits.
static int line16_point_type_get(page_line16_d *l,
int linepos,
int pos)
{
line16_line *line;
if (linepos < 0) linepos = 0;
if (linepos > 15) linepos = 15;
line = &l->lines[linepos];
if(pos < 0) pos = 0;
if(pos > 15) pos = 15;
return line->points[pos].type & 3;
}
4.13.11. line16_point_rate_set
static void line16_point_rate_set(page_line16_d *l,
int linepos,
int pos,
GFFLT rate);
static void line16_point_rate_set(page_line16_d *l,
int linepos,
int pos,
GFFLT rate)
{
line16_line *line;
if(pos < 0) pos = 0;
if(pos > 15) pos = 15;
if (linepos < 0) linepos = 0;
if (linepos > 15) linepos = 15;
line = &l->lines[linepos];
line->points[pos].rate = rate;
}
4.13.12. line16_point_rate_get
static GFFLT line16_point_rate_get(page_line16_d *l,
int linepos,
int pos);
static GFFLT line16_point_rate_get(page_line16_d *l,
int linepos,
int pos)
{
line16_line *line;
if(pos < 0) pos = 0;
if(pos > 15) pos = 15;
if (linepos < 0) linepos = 0;
if (linepos > 15) linepos = 15;
line = &l->lines[linepos];
return line->points[pos].rate;
}
4.13.13. line16_point_trigmode_set
/* static void line16_point_trigmode_set(page_line16_d *l, */
/* int line, */
/* int pos, */
/* int tog); */
Trigmode is embedded inside of the type variable, so some bit twiddling is needed.
/* static void line16_point_trigger_set(page_line16_d *l, */
/* int line, */
/* int pos, */
/* int tog) */
/* { */
/* int tmp; */
/* if(pos < 0) pos = 0; */
/* if(pos > 15) pos = 15; */
/* tmp = l->points[pos].type; */
/* tmp &= ~(1<<2); /\* clear bit 3 *\/ */
/* tmp |= tog & ~(1<<2); /\* mask + set *\/ */
/* l->points[pos].type = tmp; */
/* } */
4.13.14. line16_point_trigmode_get
/* static int line16_point_trigmode_get(page_line16_d *l, */
/* int line, */
/* int pos); */
/* static int line16_point_trigmode_get(page_line16_d *l, */
/* int line, */
/* int pos) */
/* { */
/* if(pos < 0) pos = 0; */
/* if(pos > 15) pos = 15; */
/* return l->points[pos].type & (1 << 2); */
/* } */
4.14. Begin New Segment (Main and Local)
4.14.1. Main
static void line16_begin_segment(page_line16_d *l);
When a new segment starts:
Find the next point.
Counter reset to be zero.
static void line16_begin_segment(page_line16_d *l)
{
int nextpoint;
l->counter = 0;
l->trig = 0;
nextpoint = line16_find_next(l, l->nextpoint);
if(nextpoint < 0) return;
l->pointpos = l->nextpoint;
l->nextpoint = nextpoint;
}
4.14.2. DONE Local
CLOSED: [2020-01-03 Fri 12:27]
static void line16_begin_local(line16_localline *ll);
static void line16_begin_local(line16_localline *ll)
{
int nextpoint;
ll->counter = 0;
ll->trig = 0;
nextpoint = line16_line_find_next(ll->l, ll->nextpoint);
if(nextpoint < 0) return;
ll->pointpos = ll->nextpoint;
ll->nextpoint = nextpoint;
}
4.15. Scale to duration
static GFFLT line16_durscale(page_line16_d *l, GFFLT val);
static GFFLT line16_durscale(page_line16_d *l, GFFLT val)
{
GFFLT mn, mx;
mn = line16_dur_min_get(l);
mx = line16_dur_max_get(l);
return val * (mx - mn) + mn;
}
4.16. Start a line (Main + Local)
Called when line is first initialized. This will start the line. It will find first two line segments.
4.16.1. Main
static void line16_start_line(page_line16_d *line);
A value of -1 is passed into find_next
because this
function looks for the next value AFTER the input
value. Passing -1 allows the function to start looking
AT 0.
static void line16_start_line(page_line16_d *line)
{
line->counter = 0;
line->pointpos = line16_find_next(line, -1);
line->nextpoint = line16_find_next(line,
line->pointpos);
}
4.16.2. Local
static void line16_start_line_local(line16_localline *line);
A value of -1 is passed into find_next
because this
function looks for the next value AFTER the input
value. Passing -1 allows the function to start looking
AT 0.
static void line16_start_line_local(line16_localline *line)
{
line->counter = 0;
line->pointpos = line16_line_find_next(line->l, -1);
line->nextpoint = line16_line_find_next(line->l,
line->pointpos);
}
4.17. Update Point Position
This will update the point position on the monome.
static void line16_update_pointpos(page_line16_d *l);
static void line16_update_pointpos(page_line16_d *l)
{
unsigned short val;
if (l->selected_line != l->playing_line) {
return;
}
if (l->timer >= 0 && l->timer < MIN_DUR) return;
if (l->pointpos < 0) val = 0;
else val = 1 << l->pointpos;
if (l->pointpos != l->lpointpos) {
monolith_page_mstate_led_row16(l->mstate, 6, val);
l->timer = 0;
l->lpointpos = l->pointpos;
}
}
prev | home | next