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.
545 lines
18 KiB
545 lines
18 KiB
/*
|
|
Calf Box, an open source musical instrument.
|
|
Copyright (C) 2010-2013 Krzysztof Foltman
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "config-api.h"
|
|
#include "dspmath.h"
|
|
#include "engine.h"
|
|
#include "errors.h"
|
|
#include "midi.h"
|
|
#include "module.h"
|
|
#include "rt.h"
|
|
#include "sampler.h"
|
|
#include "sampler_impl.h"
|
|
#include "sfzloader.h"
|
|
#include "stm.h"
|
|
#include <assert.h>
|
|
#include <errno.h>
|
|
#include <glib.h>
|
|
#include <math.h>
|
|
#include <memory.h>
|
|
#include <sndfile.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
static inline void set_cc_int(struct sampler_channel *c, uint32_t cc, uint8_t value)
|
|
{
|
|
c->intcc[cc] = value;
|
|
c->floatcc[cc] = value * (1.0f / 127.f);
|
|
}
|
|
|
|
static inline void set_cc_float(struct sampler_channel *c, uint32_t cc, float value)
|
|
{
|
|
c->intcc[cc] = (uint8_t)(value * 127) & 127;
|
|
c->floatcc[cc] = value;
|
|
}
|
|
|
|
void sampler_channel_reset_keyswitches(struct sampler_channel *c)
|
|
{
|
|
if (c->program && c->program->rll)
|
|
{
|
|
memset(c->keyswitch_state, 255, sizeof(c->keyswitch_state));
|
|
memset(c->keyswitch_lastkey, 255, sizeof(c->keyswitch_lastkey));
|
|
for (uint32_t i = 0; i < c->program->rll->keyswitch_group_count; ++i)
|
|
{
|
|
const struct sampler_keyswitch_group *ksg = c->program->rll->keyswitch_groups[i];
|
|
if (ksg->def_value == 255)
|
|
{
|
|
c->keyswitch_state[i] = ksg->key_offsets[0];
|
|
c->keyswitch_lastkey[i] = ksg->lo;
|
|
}
|
|
else
|
|
{
|
|
c->keyswitch_state[i] = ksg->key_offsets[ksg->def_value];
|
|
c->keyswitch_lastkey[i] = ksg->def_value + ksg->lo;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void sampler_channel_init(struct sampler_channel *c, struct sampler_module *m)
|
|
{
|
|
c->module = m;
|
|
c->voices_running = NULL;
|
|
c->active_voices = 0;
|
|
c->active_prevoices = 0;
|
|
c->pitchwheel = 0;
|
|
c->output_shift = 0;
|
|
for (int i = 0; i < smsrc_perchan_count; ++i)
|
|
{
|
|
c->intcc[i] = 0;
|
|
c->floatcc[i] = 0;
|
|
}
|
|
c->poly_pressure_mask = 0;
|
|
|
|
// default to maximum and pan=centre if MIDI mixing disabled
|
|
if (m->disable_mixer_controls)
|
|
{
|
|
c->channel_volume_cc = 16383;
|
|
c->channel_pan_cc = 8192;
|
|
}
|
|
else
|
|
{
|
|
sampler_channel_process_cc(c, 7, 100);
|
|
sampler_channel_process_cc(c, 7 + 32, 0);
|
|
sampler_channel_process_cc(c, 10, 64);
|
|
sampler_channel_process_cc(c, 10 + 32, 0);
|
|
}
|
|
set_cc_int(c, 11, 127);
|
|
set_cc_int(c, 71, 64);
|
|
set_cc_int(c, 74, 64);
|
|
set_cc_float(c, smsrc_alternate, 0);
|
|
c->previous_note = -1;
|
|
c->last_polyaft = 0;
|
|
c->first_note_vel = 100;
|
|
c->program = NULL;
|
|
sampler_channel_set_program_RT(c, m->program_count ? m->programs[0] : NULL);
|
|
memset(c->switchmask, 0, sizeof(c->switchmask));
|
|
memset(c->sustainmask, 0, sizeof(c->sustainmask));
|
|
memset(c->sostenutomask, 0, sizeof(c->sostenutomask));
|
|
}
|
|
|
|
void sampler_channel_process_cc(struct sampler_channel *c, int cc, int val)
|
|
{
|
|
struct sampler_module *m = c->module;
|
|
// Handle CC triggering.
|
|
if (c->program && c->program->rll && c->program->rll->layers_oncc)
|
|
{
|
|
struct sampler_rll *rll = c->program->rll;
|
|
if ((rll->cc_trigger_bitmask[cc >> 5] & (1 << (cc & 31))))
|
|
{
|
|
int old_value = c->intcc[cc];
|
|
for (GSList *p = rll->layers_oncc; p; p = p->next)
|
|
{
|
|
struct sampler_layer *layer = p->data;
|
|
assert(layer->runtime);
|
|
// Default (compatible) behaviour means the region will trigger
|
|
// on every CC that has value within the specified range.
|
|
// XXXKF add a switch for only triggering the region on
|
|
// transition between in-range and out-of-range.
|
|
gboolean compatible_oncc_behaviour = TRUE;
|
|
|
|
struct sampler_cc_range *on_cc = layer->runtime->on_cc;
|
|
gboolean trigger = FALSE;
|
|
while(on_cc)
|
|
{
|
|
if (on_cc->key.cc_number == cc &&
|
|
(val >= on_cc->value.locc && val <= on_cc->value.hicc) &&
|
|
(compatible_oncc_behaviour || !(old_value >= on_cc->value.locc && old_value <= on_cc->value.hicc)))
|
|
{
|
|
trigger = TRUE;
|
|
break;
|
|
}
|
|
on_cc = on_cc->next;
|
|
}
|
|
if(trigger)
|
|
{
|
|
struct sampler_voice *v = m->voices_free;
|
|
if (!v)
|
|
break;
|
|
struct sampler_released_groups exgroups;
|
|
sampler_released_groups_init(&exgroups);
|
|
sampler_voice_start(v, c, layer->runtime, layer->runtime->pitch_keycenter, 127, &exgroups);
|
|
sampler_channel_release_groups(c, -1, &exgroups);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
int was_enabled = c->intcc[cc] >= 64;
|
|
int enabled = val >= 64;
|
|
switch(cc)
|
|
{
|
|
case 10:
|
|
case 10 + 32:
|
|
set_cc_int(c, cc, val);
|
|
if (!c->module->disable_mixer_controls)
|
|
c->channel_pan_cc = sampler_channel_addcc(c, 10);
|
|
break;
|
|
case 7:
|
|
case 7 + 32:
|
|
set_cc_int(c, cc, val);
|
|
if (!c->module->disable_mixer_controls)
|
|
c->channel_volume_cc = sampler_channel_addcc(c, 7);
|
|
break;
|
|
case 64:
|
|
if (was_enabled && !enabled)
|
|
{
|
|
sampler_channel_stop_sustained(c);
|
|
}
|
|
break;
|
|
case 66:
|
|
if (was_enabled && !enabled)
|
|
sampler_channel_stop_sostenuto(c);
|
|
else if (!was_enabled && enabled)
|
|
sampler_channel_capture_sostenuto(c);
|
|
break;
|
|
|
|
case 120:
|
|
case 123:
|
|
sampler_channel_stop_all(c);
|
|
break;
|
|
case 121:
|
|
// Recommended Practice (RP-015) Response to Reset All Controllers
|
|
// http://www.midi.org/techspecs/rp15.php
|
|
sampler_channel_process_cc(c, 64, 0);
|
|
sampler_channel_process_cc(c, 66, 0);
|
|
set_cc_int(c, 11, 127);
|
|
set_cc_int(c, 1, 0);
|
|
set_cc_float(c, smsrc_alternate, 0);
|
|
c->pitchwheel = 0;
|
|
c->last_chanaft = 0;
|
|
c->poly_pressure_mask = 0;
|
|
c->last_polyaft = 0;
|
|
sampler_channel_reset_keyswitches(c);
|
|
return;
|
|
}
|
|
if (cc < smsrc_perchan_count)
|
|
set_cc_int(c, cc, val);
|
|
}
|
|
|
|
void sampler_channel_release_groups(struct sampler_channel *c, int note, struct sampler_released_groups *exgroups)
|
|
{
|
|
if (exgroups->group_count || exgroups->low_groups)
|
|
{
|
|
FOREACH_VOICE(c->voices_running, v)
|
|
{
|
|
if (v->off_by && v->note != note)
|
|
{
|
|
if (sampler_released_groups_check(exgroups, v->off_by))
|
|
{
|
|
v->released = 1;
|
|
if (v->layer->off_mode == som_fast)
|
|
cbox_envelope_go_to(&v->amp_env, 15);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void sampler_channel_start_note(struct sampler_channel *c, int note, int vel, gboolean is_release_trigger)
|
|
{
|
|
struct sampler_module *m = c->module;
|
|
float random = rand() * 1.0 / (RAND_MAX + 1.0);
|
|
|
|
set_cc_float(c, smsrc_alternate, c->intcc[smsrc_alternate] ? 0.f : 1.f);
|
|
set_cc_float(c, smsrc_random_unipolar, random); // is that a per-voice or per-channel value? is it generated per region or per note?
|
|
|
|
gboolean is_first = FALSE;
|
|
if (!is_release_trigger)
|
|
{
|
|
c->switchmask[note >> 5] |= 1 << (note & 31);
|
|
c->prev_note_velocity[note] = vel;
|
|
c->prev_note_start_time[note] = m->current_time;
|
|
is_first = TRUE;
|
|
FOREACH_VOICE(c->voices_running, v)
|
|
{
|
|
if (!v->released && v->layer->trigger != stm_release)
|
|
{
|
|
is_first = FALSE;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
struct sampler_program *prg = c->program;
|
|
if (!prg || !prg->rll || prg->deleting)
|
|
return;
|
|
|
|
if (!is_release_trigger)
|
|
{
|
|
for (uint32_t i = 0; i < prg->rll->keyswitch_group_count; ++i)
|
|
{
|
|
const struct sampler_keyswitch_group *ks = prg->rll->keyswitch_groups[i];
|
|
if (note >= ks->lo && note <= ks->hi)
|
|
{
|
|
c->keyswitch_lastkey[i] = note;
|
|
c->keyswitch_state[i] = ks->key_offsets[note - ks->lo];
|
|
}
|
|
}
|
|
}
|
|
|
|
struct sampler_rll_iterator iter;
|
|
sampler_rll_iterator_init(&iter, prg->rll, c, note, vel, random, is_first, is_release_trigger);
|
|
|
|
struct sampler_layer *layer = sampler_rll_iterator_next(&iter);
|
|
if (!layer)
|
|
{
|
|
if (!is_release_trigger)
|
|
c->previous_note = note;
|
|
return;
|
|
}
|
|
struct sampler_layer_data *layers[MAX_SAMPLER_VOICES];
|
|
struct sampler_layer_data *delayed_layers[MAX_SAMPLER_PREVOICES];
|
|
int lcount = 0, dlcount = 0, slcount = 0;
|
|
struct sampler_voice *free_voice = m->voices_free;
|
|
struct sampler_prevoice *free_prevoice = m->prevoices_free;
|
|
int fvcount = 0, fpcount = 0;
|
|
|
|
while(layer && lcount < MAX_SAMPLER_VOICES + MAX_SAMPLER_PREVOICES)
|
|
{
|
|
if (free_voice)
|
|
{
|
|
free_voice = free_voice->next;
|
|
fvcount++;
|
|
}
|
|
if (free_prevoice)
|
|
{
|
|
free_prevoice = free_prevoice->next;
|
|
fpcount++;
|
|
}
|
|
assert(layer->runtime);
|
|
if (layer->runtime->computed.eff_use_prevoice)
|
|
delayed_layers[dlcount++] = layer->runtime;
|
|
else
|
|
{
|
|
layers[lcount++] = layer->runtime;
|
|
if (layer->runtime->computed.eff_is_silent)
|
|
slcount++;
|
|
}
|
|
layer = sampler_rll_iterator_next(&iter);
|
|
}
|
|
|
|
struct sampler_released_groups exgroups;
|
|
sampler_released_groups_init(&exgroups);
|
|
// If running out of polyphony, do not start the note if all the regions cannot be played
|
|
// (silent notes don't count into polyphony)
|
|
if (lcount <= slcount + fvcount && dlcount <= fpcount)
|
|
{
|
|
// this might perhaps be optimized by mapping the group identifiers to flat-array indexes
|
|
// but I'm not going to do that until someone gives me an SFZ worth doing that work ;)
|
|
|
|
for (int i = 0; i < lcount; ++i)
|
|
{
|
|
struct sampler_layer_data *l = layers[i];
|
|
if (l->computed.eff_is_silent)
|
|
sampler_voice_start_silent(l, &exgroups);
|
|
else
|
|
{
|
|
int velc = (!is_first && l->vel_mode == svm_previous) ? c->first_note_vel : vel;
|
|
sampler_voice_start(m->voices_free, c, l, note, velc, &exgroups);
|
|
}
|
|
}
|
|
for (int i = 0; i < dlcount; ++i)
|
|
{
|
|
struct sampler_layer_data *l = delayed_layers[i];
|
|
int velc = (!is_first && l->vel_mode == svm_previous) ? c->first_note_vel : vel;
|
|
sampler_prevoice_start(m->prevoices_free, c, l, note, velc);
|
|
}
|
|
}
|
|
if (!is_release_trigger)
|
|
c->previous_note = note;
|
|
if (is_first)
|
|
c->first_note_vel = vel;
|
|
sampler_channel_release_groups(c, note, &exgroups);
|
|
}
|
|
|
|
void sampler_channel_start_release_triggered_voices(struct sampler_channel *c, int note)
|
|
{
|
|
if (c->program && c->program->rll && c->program->rll->has_release_layers)
|
|
{
|
|
if (c->prev_note_velocity[note])
|
|
{
|
|
sampler_channel_start_note(c, note, c->prev_note_velocity[note], TRUE);
|
|
c->prev_note_velocity[note] = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
void sampler_channel_stop_note(struct sampler_channel *c, int note, int vel, gboolean is_polyaft)
|
|
{
|
|
c->switchmask[note >> 5] &= ~(1 << (note & 31));
|
|
FOREACH_PREVOICE(c->module->prevoices_running, pv)
|
|
{
|
|
if (pv->note == note)
|
|
sampler_prevoice_unlink(&c->module->prevoices_running, pv);
|
|
}
|
|
FOREACH_VOICE(c->voices_running, v)
|
|
{
|
|
if (v->note == note && v->layer->trigger != stm_release)
|
|
{
|
|
v->off_vel = vel;
|
|
if (v->captured_sostenuto)
|
|
v->released_with_sostenuto = 1;
|
|
else if (c->intcc[64] >= 64)
|
|
v->released_with_sustain = 1;
|
|
else
|
|
sampler_voice_release(v, is_polyaft);
|
|
|
|
}
|
|
}
|
|
if (c->intcc[64] < 64)
|
|
sampler_channel_start_release_triggered_voices(c, note);
|
|
else
|
|
c->sustainmask[note >> 5] |= (1 << (note & 31));
|
|
}
|
|
|
|
void sampler_channel_stop_sustained(struct sampler_channel *c)
|
|
{
|
|
FOREACH_VOICE(c->voices_running, v)
|
|
{
|
|
if (v->channel == c && v->released_with_sustain && v->layer->trigger != stm_release)
|
|
{
|
|
sampler_voice_release(v, FALSE);
|
|
v->released_with_sustain = 0;
|
|
}
|
|
}
|
|
// Start release layers for the newly released keys
|
|
if (c->program && c->program->rll && c->program->rll->has_release_layers)
|
|
{
|
|
for (int i = 0; i < 128; i++)
|
|
{
|
|
if (c->sustainmask[i >> 5] & (1 << (i & 31)))
|
|
sampler_channel_start_release_triggered_voices(c, i);
|
|
}
|
|
}
|
|
memset(c->sustainmask, 0, sizeof(c->sustainmask));
|
|
}
|
|
|
|
void sampler_channel_stop_sostenuto(struct sampler_channel *c)
|
|
{
|
|
FOREACH_VOICE(c->voices_running, v)
|
|
{
|
|
if (v->released_with_sostenuto && v->layer->trigger != stm_release)
|
|
{
|
|
sampler_channel_start_release_triggered_voices(c, v->note);
|
|
sampler_voice_release(v, FALSE);
|
|
v->released_with_sostenuto = 0;
|
|
// XXXKF unsure what to do with sustain
|
|
}
|
|
}
|
|
// Start release layers for the newly released keys
|
|
if (c->program && c->program->rll && c->program->rll->has_release_layers)
|
|
{
|
|
for (int i = 0; i < 128; i++)
|
|
{
|
|
if (c->sostenutomask[i >> 5] & (1 << (i & 31)))
|
|
sampler_channel_start_release_triggered_voices(c, i);
|
|
}
|
|
}
|
|
memset(c->sostenutomask, 0, sizeof(c->sostenutomask));
|
|
}
|
|
|
|
void sampler_channel_capture_sostenuto(struct sampler_channel *c)
|
|
{
|
|
FOREACH_VOICE(c->voices_running, v)
|
|
{
|
|
if (!v->released && v->loop_mode != slm_one_shot && v->loop_mode != slm_one_shot_chokeable && !v->layer->count)
|
|
{
|
|
// XXXKF unsure what to do with sustain
|
|
v->captured_sostenuto = 1;
|
|
c->sostenutomask[v->note >> 5] |= (1 << (v->note & 31));
|
|
}
|
|
}
|
|
}
|
|
|
|
void sampler_channel_stop_all(struct sampler_channel *c)
|
|
{
|
|
FOREACH_VOICE(c->voices_running, v)
|
|
{
|
|
sampler_voice_release(v, v->loop_mode == slm_one_shot_chokeable);
|
|
v->released_with_sustain = 0;
|
|
v->released_with_sostenuto = 0;
|
|
v->captured_sostenuto = 0;
|
|
}
|
|
}
|
|
|
|
void sampler_channel_set_program_RT(struct sampler_channel *c, struct sampler_program *prg)
|
|
{
|
|
FOREACH_PREVOICE(c->module->prevoices_running, pv)
|
|
{
|
|
if (pv->channel == c)
|
|
{
|
|
sampler_prevoice_unlink(&c->module->prevoices_running, pv);
|
|
sampler_prevoice_link(&c->module->prevoices_free, pv);
|
|
}
|
|
}
|
|
if (c->program)
|
|
c->program->in_use--;
|
|
c->program = prg;
|
|
if (prg)
|
|
{
|
|
assert(prg->rll);
|
|
sampler_channel_reset_keyswitches(c);
|
|
for(GSList *p = prg->ctrl_init_list; p; p = p->next)
|
|
{
|
|
union sampler_ctrlinit_union u;
|
|
u.ptr = p->data;
|
|
// printf("Setting controller %d -> %d\n", u.cinit.controller, u.cinit.value);
|
|
set_cc_int(c, u.cinit.controller, u.cinit.value);
|
|
}
|
|
c->program->in_use++;
|
|
}
|
|
}
|
|
|
|
#define sampler_channel_set_program_args(ARG) ARG(struct sampler_program *, prg)
|
|
|
|
DEFINE_RT_VOID_FUNC(sampler_channel, c, sampler_channel_set_program)
|
|
{
|
|
sampler_channel_set_program_RT(c, prg);
|
|
}
|
|
|
|
void sampler_channel_program_change(struct sampler_channel *c, int program)
|
|
{
|
|
struct sampler_module *m = c->module;
|
|
// XXXKF replace with something more efficient
|
|
for (uint32_t i = 0; i < m->program_count; i++)
|
|
{
|
|
// XXXKF support banks
|
|
if (m->programs[i]->prog_no == program)
|
|
{
|
|
sampler_channel_set_program_RT(c, m->programs[i]);
|
|
return;
|
|
}
|
|
}
|
|
g_warning("Unknown program %d", program);
|
|
if (m->program_count)
|
|
sampler_channel_set_program_RT(c, m->programs[0]);
|
|
}
|
|
|
|
float sampler_channel_get_expensive_cc(struct sampler_channel *c, struct sampler_voice *v, struct sampler_prevoice *pv, int cc_no)
|
|
{
|
|
switch(cc_no)
|
|
{
|
|
case smsrc_pitchbend:
|
|
return c->pitchwheel / 8191.f;
|
|
case smsrc_lastpolyaft: // how this is defined? is it last or is it current voice's?
|
|
return sampler_channel_get_poly_pressure(c, v ? v->note : (pv ? pv->note : 0));
|
|
case smsrc_noteonvel:
|
|
return v ? v->vel / 127.0 : (pv ? pv->vel / 127.0 : 0);
|
|
case smsrc_noteoffvel:
|
|
return v ? v->off_vel / 127.0 : 0;
|
|
case smsrc_keynotenum:
|
|
return v ? v->note / 127.0 : (pv ? pv->note / 127.0 : 0);
|
|
case smsrc_keynotegate:
|
|
return c->switchmask[0] || c->switchmask[1] || c->switchmask[2] || c->switchmask[3]; // XXXKF test interactions with sustain/sostenuto
|
|
case smsrc_chanaft_sfz2:
|
|
return c->last_chanaft / 127.0;
|
|
case smsrc_random_unipolar:
|
|
case smsrc_alternate:
|
|
return c->floatcc[cc_no];
|
|
case smsrc_random_bipolar:
|
|
return -1 + 2 * c->floatcc[smsrc_random_unipolar];
|
|
case smsrc_keydelta: // not supported yet
|
|
return 0;
|
|
case smsrc_keydelta_abs:
|
|
return 0;
|
|
case smsrc_tempo:
|
|
return c->module->module.engine->master->tempo; // XXXKF what scale???
|
|
default:
|
|
assert(0);
|
|
return 0.f;
|
|
}
|
|
}
|
|
|