3. Line16 Data
3.1. Line16 Point
A point is a explicit point in a line.
3.1.1. Typedef
Data for this point
is contained in a struct called line16_point
.
typedef struct line16_point line16_point;
struct line16_point {
<<line16_point_contents>>
};
3.1.2. Init Function
A line16_point
is initialized using the function
line16_point_init
.
static void line16_point_init(line16_point *pt);
static void line16_point_init(line16_point *pt)
{
<<line16_point_init>>
}
3.1.3. Contents
3.1.3.1. Active
This is a boolean value. When not active, the point will be skipped. The last active value will determine the length of the line segment.
int active;
pt->active = 0;
3.1.3.2. Value
The value of a point is a normalized GFFLT
floating point
value between 0 and 1.
GFFLT val;
pt->val = 0;
3.1.3.3. Duration
The duration tells how long the segment is, and by definition also illustrates how long the interpolation time to the next value will be.
GFFLT dur;
pt->dur = 0;
3.1.3.4. Aux Values
These are two aux values. These will be controllable via the arc. These will map to any special point functionalities that may arise in the future.
GFFLT aux[2];
pt->aux[0] = 0;
pt->aux[1] = 0;
3.1.3.5. Playback Rate
Every point has their own playback rate amount. The idea is that this can be modified inside of graforge. By default, this is set to be 1 (normal speed).
GFFLT rate;
pt->rate = 1;
3.1.3.6. Type
This refers to the point slope type. By default, it is set to be 0, or linear.
3.1.3.6.1. Struct Declaration
enum {
SLOPE_LINEAR,
SLOPE_EXP_POSITIVE,
SLOPE_EXP_NEGATIVE,
SLOPE_BEZIER
};
int type;
pt->type = SLOPE_LINEAR;
3.2. DONE Line16 Line
CLOSED: [2020-01-02 Thu 13:58] This is a struct which encapsulates a line.
3.2.1. Typedef
typedef struct line16_line line16_line;
struct line16_line {
<<line16_line_contents>>
};
3.2.2. Init
static void line16_line_init(line16_line *line);
static void line16_line_init(line16_line *line)
{
<<line16_line_init>>
}
3.2.3. Contents
3.2.3.1. Point Bank
line16_point points[16];
{
int i;
for (i = 0; i < 16; i++) {
line16_point_init(&line->points[i]);
}
}
3.2.3.2. Number Of Active Points
Keeps track of how many active points there are. If there are none, the line does not get saved.
int nactive;
line->nactive = 0;
3.3. Line16 Main Data Contents
3.3.1. Monome State Data
monolith_page_mstate *mstate;
monolith_page_mstate_new(pg, &line16->mstate);
monolith_page_mstate_free(&line16->mstate);
3.3.2. Arc State Data
monolith_page_arcstate *arcstate;
monolith_page_arcstate_new(pg, &line16->arcstate);
monolith_page_arcstate_free(&line16->arcstate);
3.3.3. Line Point Bank (soon to be line bank).
This is being refactored. Instead of having a point bank, a newly introduced line struct with a point bank inside of it. This will be a line bank with up to 16 lines available for programming.
line16_line lines[16];
for (i = 0; i < 16; i++) {
line16_line_init(&line16->lines[i]);
}
3.3.4. Global Playback Rate
GFFLT rate;
line16_rate_set(line16, 1);
This can be accessed with line16_rate_set
and
line16_rate_get
.
static void line16_rate_set(page_line16_d *l, GFFLT x);
static GFFLT line16_rate_get(page_line16_d *l);
static void line16_rate_set(page_line16_d *l, GFFLT x)
{
l->rate = x;
}
static GFFLT line16_rate_get(page_line16_d *l)
{
return l->rate;
}
3.3.5. Selected Point
The currently selected point in the main line sequencer.
int selected_point;
line16->selected_point = 0;
3.3.6. Selected Line
int selected_line;
line16->selected_line = 0;
3.3.7. Currently Playing Line
This is the line that is being played in the main sequencer. This can be different from the currently selected line.
int playing_line;
line16->playing_line = 0;
3.3.8. Point Position
An integer value. This shows holds the current point value.
int pointpos;
line16->pointpos = -1;
3.3.9. Last Point Position
Every time the point position is updated on the monome grid, it stores the previous value. This is done to prevent the main function from overloading the grid and causing libmonome to bugout.
Initially set this to any arbitrary postive value larger than 15, or any value less than -1 (-1 being the initial unset point position).
int lpointpos;
line16->lpointpos = -100;
3.3.10. Timers
3.3.10.1. Update Timer
This is a special timer used rate limit the updates to the monome grid. The timer measures the duration between time segments. If the distance it too short, it will simply not update the monome.
Set to be a negative value by default, so the program knows it is only initialized and not time has passed.
double timer;
line16->timer = -1;
#define MIN_DUR 0.05
3.3.10.2. Aux Timer
This is used to rate limit updated values coming from graforge nodes. To prevent weird interruptions and glitches, a separate timer is used. This only needs to be set to 0.
double aux_timer;
line16->aux_timer = 0;
#define AUX_MIN_DUR 0.03
3.3.11. Next Point
Holds the integer value for the next point.
int nextpoint;
line16->nextpoint = 0;
3.3.12. 1 / SR
This is a constant that is the inverse of the sampling rate.
GFFLT onedsr;
line16->onedsr = 1.0 / gf_patch_srate_get(patch);
3.3.13. Counter
This is the counter, stored as a floating point value, in seconds. Stores the current duration of the line segment.
GFFLT counter;
line16->counter = 0;
3.3.14. Graforge Cable
This holds a pre-allocated graforge cable with an internal block. At every render block, the line gets computed exactly once, and it is written to this cable.. Other nodes then retrieve the block and copy it over to their internal block.
gf_cable out;
GFFLT *blk;
Still need to initialize with graforge block. Also need to allocate and bind a block.
gf_cable_init(NULL, &line16->out);
line16->blk = calloc(1,
gf_patch_blksize(patch) *
sizeof(GFFLT));
gf_cable_set_block(&line16->out,
line16->blk,
gf_patch_blksize(patch));
Said block needs to be freed here.
free(line16->blk);
3.3.15. Number of active points (migrated!)
3.3.16. Event Stack
When a point is told to be turned on or off via the grid or programatically, it pushes the command onto an event stack, which is then processed by the internal node. This is done as a measure to prevent weird bugs from happening related to finding the next available point. The event stack right now is only concerned with whether or not things get activated. Other events, such as setting a value, will be directly written to the point. I do not see any potential weirdness here.
3.3.16.1. [2019-08-09 Fri 15:22] Dispute
Okay. So I just realized the downfall of this event stack. It makes it so you have to include the main node in the audio graph in order to use. If you don't, the thing appears to be broken. Also, if the sound is paused, the thing will appear to be broken. Overall not a great design.
My interest I think is going to be maybe capturing the states of all the lines, and then copying over the states whenever a change is made.
3.3.16.1.1. [2019-12-19 Thu 17:13] believe this is resolved
3.3.16.2. Data
The intermediate state of a page is stored in an array of char values as booleans.
The actions
variable is used to keep track of if any
actions happened.
unsigned char state[16];
int actions;
line16_state_init(line16);
3.3.16.3. Initializing the event stack
This just zeros out the stack.
static void line16_state_init(page_line16_d *l);
static void line16_state_init(page_line16_d *l)
{
int i;
for(i = 0; i < 16; i++) {
l->state[i] = 0;
}
l->actions = 0;
}
3.3.16.4. Set the state
static void line16_state_set(page_line16_d *l, int pt, int s);
static void line16_state_set(page_line16_d *l, int pt, int s)
{
if(pt < 0 || pt >= 16) {
return;
}
l->state[pt] = s;
l->actions++;
}
3.3.16.5. Applying the state
Will take the intermeidate state and apply it to the point bank.
static void line16_state_apply(page_line16_d *l);
static void line16_state_apply(page_line16_d *l)
{
int n;
unsigned char *state;
line16_point *pt;
int nactive;
line16_point *points;
line16_line *line;
line = &l->lines[l->selected_line];
points = line->points;
if (!l->actions) return;
state = l->state;
nactive = 0;
for (n = 0; n < 16; n++) {
pt = &points[n];
pt->active = state[n];
if(state[n]) nactive++;
}
line->nactive = nactive;
l->actions = 0;
}
3.3.16.6. Copying Page to Event Stack
Does the reverse of line16_state_apply
. Call it...
line16_state_copy
.
static void line16_state_copy(page_line16_d *l);
static void line16_state_copy(page_line16_d *l)
{
int n;
line16_point *pt;
unsigned char *state;
int nactive;
line16_point *points;
line16_line *line;
state = l->state;
line = &l->lines[l->selected_line];
points = line->points;
nactive = 0;
for (n = 0; n < 16; n++) {
pt = &points[n];
state[n] = pt->active;
if (state[n]) nactive++;
}
line->nactive = nactive;
}
3.3.17. min/max durations
This will set the range of possible durations for the line segments.
GFFLT min;
GFFLT max;
line16_dur_min_set(line16, 0.1);
line16_dur_max_set(line16, 10);
These are accessible through setters and getters, defined below.
static void line16_dur_min_set(page_line16_d *l, GFFLT val);
static void line16_dur_max_set(page_line16_d *l, GFFLT val);
static void line16_dur_min_set(page_line16_d *l, GFFLT val)
{
l->min = val;
}
static void line16_dur_max_set(page_line16_d *l, GFFLT val)
{
l->max = val;
}
static GFFLT line16_dur_min_get(page_line16_d *l);
static GFFLT line16_dur_max_get(page_line16_d *l);
static GFFLT line16_dur_min_get(page_line16_d *l)
{
return l->min;
}
static GFFLT line16_dur_max_get(page_line16_d *l)
{
return l->max;
}
3.3.18. Aux Cache
3.3.18.1. Struct Contents
Any time a point changes, the point A's aux values at that point in time are saved. As a result, the nodes setting naturally go through a kind of sample and hold. Holding onto values for the duration of the line is more musical than if it were constantly changing because it allows more contrast to happen.
GFFLT aux_cache[2];
line16->aux_cache[0] = 0;
line16->aux_cache[1] = 0;
3.3.18.2. Updating The Aux Cache
Any time the line is updated, the cache, too needs
to be updated. This is done with line16_aux_cache_update
.
static void line16_aux_cache_udpate(page_line16_d *l);
static void line16_aux_cache_udpate(page_line16_d *l)
{
line16_point *pt_a;
pt_a = line16_get_point(l, l->pointpos);
if(pt_a == NULL) return;
l->aux_cache[0] = pt_a->aux[0];
l->aux_cache[1] = pt_a->aux[1];
}
CLOSED: [2019-08-24 Sat 13:58]
3.3.19. Trigger Flag
This gets set every time there is a trigger, and is used to start a line up that waits for a trigger. When a trigger occurs, the sample position is stored.
int trig;
line16->trig = -1;
3.4. Line16 Typedef Declaration
All line16 page data is contained in a struct called page_line16_d
.
typedef struct page_line16_d page_line16_d;
struct page_line16_d {
<<page_line16_contents>>
};
3.5. Line16 Data Allocation/Initialization
Line16 data is initiatlized with the function
page_line16_init
.
static void page_line16_init(monolith_page *pg, page_line16_d *line16);
static void page_line16_init(monolith_page *pg, page_line16_d *line16)
{
int i;
gf_patch *patch;
patch = monolith_page_graforge(pg);
<<line16_init>>
line16_redraw_points(line16);
line16_select_point(line16, line16->selected_point);
}
3.6. Line16 Data Cleanup
Line16 data is freed with the funciton page_line16_free
.
static void page_line16_cleanup(page_line16_d *line16);
static void page_line16_cleanup(page_line16_d *line16)
{
<<line16_cleanup>>
}
prev | home | next