/* Compute f(i,el) for the current i. */ int osc_get(osc_t *osc, int el) { if (!osc) return 0; switch (osc->type) { case otyp_Constant: return osc->u.oconstant.val; case otyp_Bounce: return osc->u.obounce.val; case otyp_Wrap: return osc->u.owrap.val; case otyp_VeloWrap: return osc->u.ovelowrap.val; case otyp_Linear: return osc_get(osc->u.olinear.base, el) + el * osc_get(osc->u.olinear.diff, el); case otyp_Multiplex: { struct omultiplex_struct *ox = &(osc->u.omultiplex); int sel = osc_get(ox->sel, el); return osc_get(ox->val[sel % NUM_PHASES], el); } case otyp_Phaser: { struct ophaser_struct *ox = &(osc->u.ophaser); return ox->curphase; } case otyp_RandPhaser: { struct orandphaser_struct *ox = &(osc->u.orandphaser); return ox->curphase; } case otyp_Buffer: { struct obuffer_struct *ox = &(osc->u.obuffer); return ox->el[(ox->firstel + el) % NUM_ELS]; } default: return 0; } }
osc_t *new_osc_buffer(osc_t *val) { int ix; osc_t *osc = create_osc(otyp_Buffer); if (!osc) return NULL; osc->u.obuffer.val = val; osc->u.obuffer.firstel = NUM_ELS-1; /* The last N values are stored in a ring buffer, which we must initialize here. */ for (ix=0; ix<NUM_ELS; ix++) { osc->u.obuffer.el[ix] = osc_get(val, 0); } return osc; }
osc_t *new_osc_buffer(stonerview_state *st, osc_t *val) { int ix; osc_t *osc = create_osc(st, otyp_Buffer); if (!osc) return NULL; osc->u.obuffer.val = val; osc->u.obuffer.firstel = st->num_els-1; /* The last N values are stored in a ring buffer, which we must initialize here. */ for (ix=0; ix<st->num_els; ix++) { osc->u.obuffer.el[ix] = osc_get(st, val, 0); } return osc; }
/* Increment i. This affects all osc_t objects; we go down the linked list to get them all. */ void osc_increment() { osc_t *osc; for (osc = oscroot; osc; osc = osc->next) { switch (osc->type) { case otyp_Bounce: { struct obounce_struct *ox = &(osc->u.obounce); ox->val += ox->step; if (ox->val < ox->min && ox->step < 0) { ox->step = -(ox->step); ox->val = ox->min + (ox->min - ox->val); } if (ox->val > ox->max && ox->step > 0) { ox->step = -(ox->step); ox->val = ox->max + (ox->max - ox->val); } break; } case otyp_Wrap: { struct owrap_struct *ox = &(osc->u.owrap); ox->val += ox->step; if (ox->val < ox->min && ox->step < 0) { ox->val += (ox->max - ox->min); } if (ox->val > ox->max && ox->step > 0) { ox->val -= (ox->max - ox->min); } break; } case otyp_VeloWrap: { struct ovelowrap_struct *ox = &(osc->u.ovelowrap); int diff = (ox->max - ox->min); ox->val += osc_get(ox->step, 0); while (ox->val < ox->min) ox->val += diff; while (ox->val > ox->max) ox->val -= diff; break; } case otyp_Phaser: { struct ophaser_struct *ox = &(osc->u.ophaser); ox->count++; if (ox->count >= ox->phaselen) { ox->count = 0; ox->curphase++; if (ox->curphase >= NUM_PHASES) ox->curphase = 0; } break; } case otyp_RandPhaser: { struct orandphaser_struct *ox = &(osc->u.orandphaser); ox->count++; if (ox->count >= ox->curphaselen) { ox->count = 0; ox->curphaselen = rand_range(ox->minphaselen, ox->maxphaselen); ox->curphase++; if (ox->curphase >= NUM_PHASES) ox->curphase = 0; } break; } case otyp_Buffer: { struct obuffer_struct *ox = &(osc->u.obuffer); ox->firstel--; if (ox->firstel < 0) ox->firstel += NUM_ELS; ox->el[ox->firstel] = osc_get(ox->val, 0); /* We can assume that ox->val has already been incremented, since it was created first. This is why new objects are put on the end of the linked list... yeah, it's gross. */ break; } default: break; } } }