|
|
|
#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"
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
// Note initialisation functions
|
|
|
|
|
|
|
|
void sampler_nif_cc2delay(struct sampler_noteinitfunc *nif, struct sampler_prevoice *pv)
|
|
|
|
{
|
|
|
|
float cc = sampler_channel_getcc_prevoice(pv->channel, pv, nif->key.variant, nif->value.curve_id, nif->value.step);
|
|
|
|
pv->delay_computed += nif->value.value * cc;
|
|
|
|
}
|
|
|
|
|
|
|
|
void sampler_nif_addrandomdelay(struct sampler_noteinitfunc *nif, struct sampler_prevoice *pv)
|
|
|
|
{
|
|
|
|
pv->delay_computed += nif->value.value * rand() * (1.0 / RAND_MAX);
|
|
|
|
}
|
|
|
|
|
|
|
|
void sampler_nif_syncbeats(struct sampler_noteinitfunc *nif, struct sampler_prevoice *pv)
|
|
|
|
{
|
|
|
|
if (nif->value.value > 0)
|
|
|
|
{
|
|
|
|
pv->sync_beats = nif->value.value;
|
|
|
|
double cur_beat = sampler_get_current_beat(pv->channel->module);
|
|
|
|
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) // 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;
|
|
|
|
// printf("cur_beat %f trigger %f offset %f\n", cur_beat, pv->sync_trigger_time, pv->layer_data->sync_offset);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void sampler_nif_vel2pitch(struct sampler_noteinitfunc *nif, struct sampler_voice *v)
|
|
|
|
{
|
|
|
|
v->pitch_shift += nif->value.value * v->vel * (1.0 / 127.0);
|
|
|
|
}
|
|
|
|
|
|
|
|
void sampler_nif_vel2offset(struct sampler_noteinitfunc *nif, struct sampler_voice *v)
|
|
|
|
{
|
|
|
|
v->offset += nif->value.value * v->vel * (1.0 / 127.0);
|
|
|
|
}
|
|
|
|
|
|
|
|
void sampler_nif_cc2offset(struct sampler_noteinitfunc *nif, struct sampler_voice *v)
|
|
|
|
{
|
|
|
|
v->offset += nif->value.value * sampler_channel_getcc_mod(v->channel, v, nif->key.variant, nif->value.curve_id, nif->value.step);
|
|
|
|
}
|
|
|
|
|
|
|
|
void sampler_nif_vel2reloffset(struct sampler_noteinitfunc *nif, struct sampler_voice *v)
|
|
|
|
{
|
|
|
|
v->reloffset += nif->value.value * v->vel * (1.0 / 127.0);
|
|
|
|
}
|
|
|
|
|
|
|
|
void sampler_nif_cc2reloffset(struct sampler_noteinitfunc *nif, struct sampler_voice *v)
|
|
|
|
{
|
|
|
|
v->reloffset += nif->value.value * sampler_channel_getcc_mod(v->channel, v, nif->key.variant, nif->value.curve_id, nif->value.step);
|
|
|
|
}
|
|
|
|
|
|
|
|
void sampler_nif_addrandom(struct sampler_noteinitfunc *nif, struct sampler_voice *v)
|
|
|
|
{
|
|
|
|
float rnd = rand() * 1.0 / RAND_MAX;
|
|
|
|
switch(nif->key.variant)
|
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
v->gain_shift += rnd * nif->value.value;
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
v->cutoff_shift += rnd * nif->value.value;
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
v->pitch_shift += rnd * nif->value.value; // this is in cents
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void modify_env_stage_by_nif(struct sampler_noteinitfunc *nif, struct sampler_voice *v, uint32_t variant, float value)
|
|
|
|
{
|
|
|
|
int env_type = variant >> 4;
|
|
|
|
struct cbox_envelope *env = NULL;
|
|
|
|
switch(env_type)
|
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
env = &v->amp_env;
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
env = &v->filter_env;
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
env = &v->pitch_env;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
assert(0);
|
|
|
|
}
|
|
|
|
if (env->shape != &v->vel_envs[env_type])
|
|
|
|
{
|
|
|
|
memcpy(&v->vel_envs[env_type], env->shape, sizeof(struct cbox_envelope_shape));
|
|
|
|
env->shape = &v->vel_envs[env_type];
|
|
|
|
}
|
|
|
|
float param = nif->value.value * value;
|
|
|
|
if ((variant & 15) == snif_env_sustain || (variant & 15) == snif_env_start)
|
|
|
|
param *= 0.01;
|
|
|
|
cbox_envelope_modify_dahdsr(env->shape, variant & 15, param, v->channel->module->module.srate * (1.0 / CBOX_BLOCK_SIZE));
|
|
|
|
}
|
|
|
|
|
|
|
|
void sampler_nif_vel2env(struct sampler_noteinitfunc *nif, struct sampler_voice *v)
|
|
|
|
{
|
|
|
|
modify_env_stage_by_nif(nif, v, nif->key.variant, v->vel * (1.0 / 127.0));
|
|
|
|
}
|