From 6628102647d3cffcf431527844cb038479663099 Mon Sep 17 00:00:00 2001 From: Krzysztof Foltman Date: Sun, 24 Nov 2013 00:41:10 +0000 Subject: [PATCH] First version of the disable_mixer_controls option in the sampler. --- sampler.c | 66 +-------------------------------------- sampler.h | 3 ++ sampler_channel.c | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- sampler_voice.c | 4 +-- 4 files changed, 97 insertions(+), 69 deletions(-) diff --git a/sampler.c b/sampler.c index 0f5e476..c502a27 100644 --- a/sampler.c +++ b/sampler.c @@ -120,71 +120,6 @@ void sampler_process_block(struct cbox_module *module, cbox_sample_t **inputs, c m->current_time += CBOX_BLOCK_SIZE; } -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 && m->voices_free) - { - struct sampler_rll *rll = c->program->rll; - if (!(rll->cc_trigger_bitmask[cc >> 5] & (1 << (cc & 31)))) - return; - int old_value = c->cc[cc]; - for (GSList *p = rll->layers_oncc; p; p = p->next) - { - struct sampler_layer *layer = p->data; - assert(layer->runtime); - // Only trigger on transition between 'out of range' and 'in range' values. - // XXXKF I'm not sure if it's what is expected here, but don't have - // the reference implementation handy. - if (layer->runtime->on_cc_number == cc && - (val >= layer->runtime->on_locc && val <= layer->runtime->on_hicc) && - !(old_value >= layer->runtime->on_locc && old_value <= layer->runtime->on_hicc)) - { - struct sampler_voice *v = m->voices_free; - int exgroups[MAX_RELEASED_GROUPS], exgroupcount = 0; - sampler_voice_start(v, c, layer->runtime, layer->runtime->pitch_keycenter, 127, exgroups, &exgroupcount); - sampler_channel_release_groups(c, -1, exgroups, exgroupcount); - } - } - } - int was_enabled = c->cc[cc] >= 64; - int enabled = val >= 64; - switch(cc) - { - 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); - c->cc[11] = 127; - c->cc[1] = 0; - c->pitchwheel = 0; - c->cc[smsrc_chanaft] = 0; - // XXXKF reset polyphonic pressure values when supported - return; - } - if (cc < 120) - c->cc[cc] = val; -} - void sampler_process_event(struct cbox_module *module, const uint8_t *data, uint32_t len) { struct sampler_module *m = (struct sampler_module *)module; @@ -588,6 +523,7 @@ MODULE_CREATE_FUNCTION(sampler) // XXXKF read defaults from some better place, like config // XXXKF allow dynamic change of the number of the pipes m->pipe_stack = cbox_prefetch_stack_new(MAX_SAMPLER_VOICES, cbox_config_get_int("streaming", "streambuf_size", 65536)); + m->disable_mixer_controls = cbox_config_get_int("sampler", "disable_mixer_controls", 0); float srate = m->module.srate; for (i = 0; i < 12800; i++) diff --git a/sampler.h b/sampler.h index 56d9866..09c3093 100644 --- a/sampler.h +++ b/sampler.h @@ -59,6 +59,7 @@ struct sampler_channel int active_voices; uint8_t prev_note_velocity[128]; uint32_t prev_note_start_time[128]; + int channel_volume_cc, channel_pan_cc; }; struct sampler_lfo @@ -142,6 +143,7 @@ struct sampler_module int output_pairs, aux_pairs; uint32_t current_time; gboolean deleting; + int disable_mixer_controls; struct cbox_prefetch_stack *pipe_stack; struct cbox_sincos sincos[12800]; }; @@ -167,6 +169,7 @@ extern void sampler_channel_stop_sostenuto(struct sampler_channel *c); extern void sampler_channel_capture_sostenuto(struct sampler_channel *c); extern void sampler_channel_release_groups(struct sampler_channel *c, int note, int exgroups[MAX_RELEASED_GROUPS], int exgroupcount); extern void sampler_channel_stop_all(struct sampler_channel *c); +extern void sampler_channel_process_cc(struct sampler_channel *c, int cc, int val); extern void sampler_voice_start(struct sampler_voice *v, struct sampler_channel *c, struct sampler_layer_data *l, int note, int vel, int *exgroups, int *pexgroupcount); extern void sampler_voice_release(struct sampler_voice *v, gboolean is_polyaft); diff --git a/sampler_channel.c b/sampler_channel.c index 6531db9..8379618 100644 --- a/sampler_channel.c +++ b/sampler_channel.c @@ -42,8 +42,20 @@ void sampler_channel_init(struct sampler_channel *c, struct sampler_module *m) c->active_voices = 0; c->pitchwheel = 0; memset(c->cc, 0, sizeof(c->cc)); - c->cc[7] = 100; - c->cc[10] = 64; + + // 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); + } c->cc[11] = 127; c->cc[71] = 64; c->cc[74] = 64; @@ -55,6 +67,83 @@ void sampler_channel_init(struct sampler_channel *c, struct sampler_module *m) 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 && m->voices_free) + { + struct sampler_rll *rll = c->program->rll; + if (!(rll->cc_trigger_bitmask[cc >> 5] & (1 << (cc & 31)))) + return; + int old_value = c->cc[cc]; + for (GSList *p = rll->layers_oncc; p; p = p->next) + { + struct sampler_layer *layer = p->data; + assert(layer->runtime); + // Only trigger on transition between 'out of range' and 'in range' values. + // XXXKF I'm not sure if it's what is expected here, but don't have + // the reference implementation handy. + if (layer->runtime->on_cc_number == cc && + (val >= layer->runtime->on_locc && val <= layer->runtime->on_hicc) && + !(old_value >= layer->runtime->on_locc && old_value <= layer->runtime->on_hicc)) + { + struct sampler_voice *v = m->voices_free; + int exgroups[MAX_RELEASED_GROUPS], exgroupcount = 0; + sampler_voice_start(v, c, layer->runtime, layer->runtime->pitch_keycenter, 127, exgroups, &exgroupcount); + sampler_channel_release_groups(c, -1, exgroups, exgroupcount); + } + } + } + int was_enabled = c->cc[cc] >= 64; + int enabled = val >= 64; + switch(cc) + { + case 10: + case 10 + 32: + c->cc[cc] = val; + if (!c->module->disable_mixer_controls) + c->channel_pan_cc = sampler_channel_addcc(c, 10); + break; + case 7: + case 7 + 32: + c->cc[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); + c->cc[11] = 127; + c->cc[1] = 0; + c->pitchwheel = 0; + c->cc[smsrc_chanaft] = 0; + // XXXKF reset polyphonic pressure values when supported + return; + } + if (cc < 120) + c->cc[cc] = val; +} + void sampler_channel_release_groups(struct sampler_channel *c, int note, int exgroups[MAX_RELEASED_GROUPS], int exgroupcount) { if (exgroupcount) diff --git a/sampler_voice.c b/sampler_voice.c index 40e6181..a3aeb36 100644 --- a/sampler_voice.c +++ b/sampler_voice.c @@ -603,13 +603,13 @@ void sampler_voice_process(struct sampler_voice *v, struct sampler_module *m, cb v->gen.bigdelta = freq64; - float gain = modsrcs[smsrc_ampenv - smsrc_pernote_offset] * l->volume_linearized * v->gain_fromvel * sampler_channel_addcc(c, 7) * sampler_channel_addcc(c, 11) / (maxv * maxv); + float gain = modsrcs[smsrc_ampenv - smsrc_pernote_offset] * l->volume_linearized * v->gain_fromvel * c->channel_volume_cc * sampler_channel_addcc(c, 11) / (maxv * maxv); if (moddests[smdest_gain] != 0.f) gain *= dB2gain(moddests[smdest_gain]); // http://drealm.info/sfz/plj-sfz.xhtml#amp "The overall gain must remain in the range -144 to 6 decibels." if (gain > 2.f) gain = 2.f; - float pan = (l->pan + 100.f) * (1.f / 200.f) + (sampler_channel_addcc(c, 10) * 1.f / maxv - 0.5f) * 2.f; + float pan = (l->pan + 100.f) * (1.f / 200.f) + (c->channel_pan_cc * 1.f / maxv - 0.5f) * 2.f; if (pan < 0.f) pan = 0.f; if (pan > 1.f) -- 2.11.4.GIT