You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
81 lines
2.7 KiB
81 lines
2.7 KiB
#include "config.h"
|
|
#include "config-api.h"
|
|
#include "dspmath.h"
|
|
#include "errors.h"
|
|
#include "midi.h"
|
|
#include "module.h"
|
|
#include "rt.h"
|
|
#include "sampler.h"
|
|
#include "sampler_impl.h"
|
|
|
|
void sampler_prevoice_start(struct sampler_prevoice *pv, struct sampler_channel *channel, struct sampler_layer_data *l, int note, int vel)
|
|
{
|
|
pv->channel = channel;
|
|
pv->layer_data = l;
|
|
pv->note = note;
|
|
pv->vel = vel;
|
|
pv->age = 0;
|
|
pv->delay_computed = 0.f;
|
|
pv->sync_beats = -1;
|
|
pv->sync_initial_time = -1;
|
|
pv->sync_trigger_time = -1;
|
|
|
|
for(struct sampler_noteinitfunc *nif = pv->layer_data->prevoice_nifs; nif; nif = nif->next)
|
|
nif->key.notefunc_prevoice(nif, pv);
|
|
sampler_prevoice_unlink(&channel->module->prevoices_free, pv);
|
|
sampler_prevoice_link(&channel->module->prevoices_running, pv);
|
|
}
|
|
|
|
void sampler_prevoice_link(struct sampler_prevoice **pv, struct sampler_prevoice *v)
|
|
{
|
|
v->prev = NULL;
|
|
v->next = *pv;
|
|
if (*pv)
|
|
(*pv)->prev = v;
|
|
*pv = v;
|
|
}
|
|
|
|
void sampler_prevoice_unlink(struct sampler_prevoice **pv, struct sampler_prevoice *v)
|
|
{
|
|
if (*pv == v)
|
|
*pv = v->next;
|
|
if (v->prev)
|
|
v->prev->next = v->next;
|
|
if (v->next)
|
|
v->next->prev = v->prev;
|
|
v->prev = NULL;
|
|
v->next = NULL;
|
|
}
|
|
|
|
int sampler_prevoice_process(struct sampler_prevoice *pv, struct sampler_module *m)
|
|
{
|
|
struct sampler_layer_data *layer_data = pv->layer_data;
|
|
if (pv->sync_beats != -1)
|
|
{
|
|
double cur_beat = sampler_get_current_beat(m);
|
|
|
|
if (cur_beat < pv->sync_initial_time - 0.001 || cur_beat >= pv->sync_trigger_time + 1)
|
|
{
|
|
gboolean backward_jump = cur_beat < pv->sync_initial_time;
|
|
// printf("Recalc: time %f, initial %f, delta %f, trigger %f\n", cur_beat, pv->sync_initial_time, cur_beat - pv->sync_initial_time, pv->sync_trigger_time);
|
|
// Recalculate after seek/looping etc
|
|
pv->sync_initial_time = cur_beat;
|
|
double cur_rel_beat = fmod(cur_beat, pv->sync_beats);
|
|
double bar_start = cur_beat - cur_rel_beat;
|
|
if (pv->layer_data->sync_offset <= cur_rel_beat && !backward_jump) // trigger in next bar
|
|
pv->sync_trigger_time = bar_start + pv->sync_beats + pv->layer_data->sync_offset;
|
|
else // trigger in the same bar
|
|
pv->sync_trigger_time = bar_start + pv->layer_data->sync_offset;
|
|
}
|
|
if (cur_beat < pv->sync_trigger_time)
|
|
return 0;
|
|
// Let the other logic (note delay etc.) take over
|
|
pv->sync_beats = -1;
|
|
}
|
|
pv->age += CBOX_BLOCK_SIZE;
|
|
if (pv->age >= (layer_data->delay + pv->delay_computed) * m->module.srate)
|
|
return 1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
|