Sampled Instrument Player with static and monolithic design. All instruments are built-in.
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

#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;
}