4. Components
4.1. Conductor Analysis Components
SKFLT last;
SKFLT last_inc;
g->last = 0;
g->last_inc = 0;
When the previous sample is larger than the current sample, it is registered as a reset, and the reset flag is set.
4.2. Phase
SKFLT phs;
g->phs = -1;
4.3. Top/Selected Target and Cached Values
The top target from the first phrase is stored
in a variable called toptarget
. This is used
so the last target of the last phrase can smoothly
loop back to the top.
gest_target *curtarget;
gest_target *toptarget;
gest_target *nxttarget;
int targetondeck;
g->curtarget = NULL;
g->toptarget = NULL;
g->nxttarget = NULL;
g->targetondeck = 0;
Value for the current and next targets are cached for faster accessibility.
SKFLT curval;
SKFLT nxtval;
g->curval = 0;
g->nxtval = 0;
Update the current target with set_curtarget
.
static void set_curtarget(gest_d *g, gest_target *target, int pos);
static void set_curtarget(gest_d *g, gest_target *target, int pos)
{
g->curtarget = target;
g->curval = target->value;
do_actions(g, target, pos);
}
gest_target * gest_curtarget(gest_d *g);
gest_target * gest_curtarget(gest_d *g)
{
return g->curtarget;
}
gest_target * gest_nxttarget(gest_d *g);
gest_target * gest_nxttarget(gest_d *g)
{
return g->nxttarget;
}
4.4. Stack
Tree nodes create a new layer every time it descends into children nodes. This is managed with a stack containing the parent node and current state. When a node begins, it pushes itself onto the stack, and pops itself off when it ends.
4.5. Modifier
The modifier is a value which mainpulates the increment value calculated from the analyzing the conductor signal.
It is represented as a rational value with a numerator and denominator, represented as integers.
int num;
int den;
g->num = 1;
g->den = 1;
Monoramps manipulate the numerator, increasing the increment value by a factor and slowing it down. Polyramps manpulate the denominator, decreasing the increment amount and speeding it up.
4.6. Top/Selected Phrases
Gestures are created in units of phrases, so a few variable references are stored here.
For starters, the starting phrase is stored in a variable
called phrase_top
. It is expected that the gesture will
iterate in a (mostly) linear fashion as a linked list.
When populating and computing gest, the currently
selected phrase is stored in a variable called
phrase_selected
.
gest_phrase *phrase_top;
gest_phrase *phrase_selected;
g->phrase_top = NULL;
g->phrase_selected = NULL;
4.7. Collection
A local instance of a gest_collection
, used to allocate
components needed to make gestures.
gest_collection col;
collection_init(&g->col);
collection_cleanup(&g->col);
4.8. Selected Ramp Tree Node
A copy of the currently selected ramp tree node
is stored in a variable called curnode
.
gest_node *curnode;
g->curnode = NULL;
select it with set_curnode
.
static void set_curnode(gest_d *g, gest_node *node);
static void set_curnode(gest_d *g, gest_node *node)
{
g->curnode = node;
}
The next node is also stored as well. Will be needed moving forward, in order for things like metatargets to work.
gest_node *nxtnode;
g->nxtnode = NULL;
4.9. Node Position
int nodepos;
g->nodepos = 0;
4.10. Global Temporal Inertia and Mass
The global inertia and mass amounts used for temporal weight.
Targets in Gest can manipulate the external conductor signal, causing temporal fluctuations. Tempo can be slowed down or sped up by changing the mass. The rate at which the changes happen is measured with inertia.
SKFLT inertia;
SKFLT mass;
By default, the mass is set to be regular (0) with instantaneous inertia (0).
g->inertia = 0;
g->mass = 0;
Getters are gest_mass_get
and gest_inertia_get
.
SKFLT gest_mass_get(gest_d *g);
SKFLT gest_inertia_get(gest_d *g);
SKFLT gest_mass_get(gest_d *g)
{
return g->mass;
}
SKFLT gest_inertia_get(gest_d *g)
{
return g->inertia;
}
4.11. Position In Time
Used for clock drift compensation. Measured in beats, and with an accumulator.
int beat;
SKFLT t;
g->beat = 0;
g->t = 0;
4.12. Please Wait Flag
int please_wait;
g->please_wait = 0;
4.13. Correction
SKFLT correction;
g->correction = 1.0;
4.14. User Data
void *ud;
g->ud = NULL;
void gest_data_set(gest_d *g, void *ud);
void * gest_data_get(gest_d *g);
void gest_data_set(gest_d *g, void *ud)
{
g->ud = ud;
}
void * gest_data_get(gest_d *g)
{
return g->ud;
}
4.15. Previous Output Value
The prevout
variable caches the output of the
previously computed sample. This is useful for
situations when gest gets paused mid-gesture.
SKFLT prevout;
g->prevout = 0;
4.16. next target state
The variable nxtstate
stores the state information
needed for the next node.
gest_state nxtstate;
init_state(&g->nxtstate);
Metatargets change things up. Before metatargets, it used to be that targets were things that wouldn't change, and this made logic and flow very simpler. Metatargets can change their targets. Because of this, there is a need to introduce cached states.
Basically, when the next target is acquired, it takes a snapshot of that state, which can then be applied without any traversal or searching.
State is represetned by the struct gest_state
.
typedef struct gest_state gest_state;
State includes the target, the node belonging to that target, the modifier (representation as rational value with numerator/denominator integers), and the phrase.
struct gest_state {
gest_target *target;
gest_node *node;
gest_phrase *phrase;
gest_behavior *behavior;
int num;
int den;
int please_wait;
};
Initialize state with init_state
.
static void init_state(gest_state *s);
static void init_state(gest_state *s)
{
s->num = 1;
s->den = 1;
s->phrase = NULL;
s->target = NULL;
s->node = NULL;
s->behavior = NULL;
s->please_wait = 0;
}
4.17. Saved Phrase
Used by gest_mark
and gest_return
. This might
eventually turn into a stack.
gest_phrase *saved;
g->saved = NULL;
4.18. Main Mix Callback
The main mix callback used to interpolate two targets given an alpha value (computed via the ramp tree). The default is to use linear interpolation.
SKFLT (*mix)(gest_d *, SKFLT, SKFLT, SKFLT);
g->mix = default_mix;
4.19. Squawk Level
The squawk
is a value that determines how
much verbosity is printed on screen. It can be
set with gest_squawk
. The higher the number,
the more squawk. By default, it is set to be 0,
or no squawking.
int squawk;
gest_squawk(g, 0);
void gest_squawk(gest_d *g, int squawk);
void gest_squawk(gest_d *g, int squawk)
{
g->squawk = squawk;
}
4.20. Spillover Flag and Tolerance
When spillover
flag is engaged, it will enable phrases
that did not fully complete (undershoot) to finish up
by "spilling over" into the next phrase. This will cause
the next phrase to start a bit later (and with any luck,
this new phrase will be automatically adjusted to
compensate using the course correction that happens
during the beat check-in.)
The tolerance
is the amount which is allowed to spillover.
This should be between 0 and 1, and ideally should be a very
very small or zero value. The greater this value is, the
more things that are allowed to spillover. Less
ramp undershoot can be achieved this way, but at the risk
of more clock sync issues.
By default tolerance is at 0 (no spillover at all).
Tolerance can be set with gest_tolerance
.
int spillover;
SKFLT tolerance;
g->spillover = 0;
gest_tolerance(g, 0);
void gest_tolerance(gest_d *g, SKFLT tolerance);
void gest_tolerance(gest_d *g, SKFLT tolerance)
{
g->tolerance = tolerance;
}
prev | home | next