4. Components

4.1. Conductor Analysis Components

<<gest_d>>=
SKFLT last;
SKFLT last_inc;
<<init>>=
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

<<gest_d>>=
SKFLT phs;
<<init>>=
g->phs = -1;

4.3. Top/Selected Target and Cached Values

This is called curtarget.

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_d>>=
gest_target *curtarget;
gest_target *toptarget;
gest_target *nxttarget;
int targetondeck;
<<init>>=
g->curtarget = NULL;
g->toptarget = NULL;
g->nxttarget = NULL;
g->targetondeck = 0;

Value for the current and next targets are cached for faster accessibility.

<<gest_d>>=
SKFLT curval;
SKFLT nxtval;
<<init>>=
g->curval = 0;
g->nxtval = 0;

Update the current target with set_curtarget.

<<static_funcdefs>>=
static void set_curtarget(gest_d *g, gest_target *target, int pos);
<<funcs>>=
static void set_curtarget(gest_d *g, gest_target *target, int pos)
{
    g->curtarget = target;
    g->curval = target->value;
    do_actions(g, target, pos);
}


<<funcdefs>>=
gest_target * gest_curtarget(gest_d *g);
<<funcs>>=
gest_target * gest_curtarget(gest_d *g)
{
    return g->curtarget;
}
<<funcdefs>>=
gest_target * gest_nxttarget(gest_d *g);
<<funcs>>=
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.

<<gest_d>>=
int num;
int den;
<<init>>=
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_d>>=
gest_phrase *phrase_top;
gest_phrase *phrase_selected;
<<init>>=
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_d>>=
gest_collection col;
<<init>>=
collection_init(&g->col);
<<cleanup>>=
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_d>>=
gest_node *curnode;
<<init>>=
g->curnode = NULL;

select it with set_curnode.

<<static_funcdefs>>=
static void set_curnode(gest_d *g, gest_node *node);
<<funcs>>=
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_d>>=
gest_node *nxtnode;
<<init>>=
g->nxtnode = NULL;

4.9. Node Position

Needed for debugging.

<<gest_d>>=
int nodepos;
<<init>>=
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.

<<gest_d>>=
SKFLT inertia;
SKFLT mass;

By default, the mass is set to be regular (0) with instantaneous inertia (0).

<<init>>=
g->inertia = 0;
g->mass = 0;

Getters are gest_mass_get and gest_inertia_get.

<<funcdefs>>=
SKFLT gest_mass_get(gest_d *g);
SKFLT gest_inertia_get(gest_d *g);
<<funcs>>=
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.

<<gest_d>>=
int beat;
SKFLT t;
<<init>>=
g->beat = 0;
g->t = 0;

4.12. Please Wait Flag

<<gest_d>>=
int please_wait;
<<init>>=
g->please_wait = 0;

4.13. Correction

<<gest_d>>=
SKFLT correction;
<<init>>=
g->correction = 1.0;

4.14. User Data

<<gest_d>>=
void *ud;
<<init>>=
g->ud = NULL;
<<funcdefs>>=
void gest_data_set(gest_d *g, void *ud);
void * gest_data_get(gest_d *g);
<<funcs>>=
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.

<<gest_d>>=
SKFLT prevout;
<<init>>=
g->prevout = 0;

4.16. next target state

The variable nxtstate stores the state information needed for the next node.

<<gest_d>>=
gest_state nxtstate;
<<init>>=
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.

<<typedefs>>=
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.

<<gest_state>>=
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_funcdefs>>=
static void init_state(gest_state *s);
<<funcs>>=
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_d>>=
gest_phrase *saved;
<<init>>=
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.

<<gest_d>>=
SKFLT (*mix)(gest_d *, SKFLT, SKFLT, SKFLT);
<<init>>=
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.

<<gest_d>>=
int squawk;
<<init>>=
gest_squawk(g, 0);


<<funcdefs>>=
void gest_squawk(gest_d *g, int squawk);
<<funcs>>=
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.

<<gest_d>>=
int spillover;
SKFLT tolerance;
<<init>>=
g->spillover = 0;
gest_tolerance(g, 0);


<<funcdefs>>=
void gest_tolerance(gest_d *g, SKFLT tolerance);
<<funcs>>=
void gest_tolerance(gest_d *g, SKFLT tolerance)
{
    g->tolerance = tolerance;
}



prev | home | next