13
0

Improve a-delay to follow tempo-ramps & BPM changes

This is a bit of a hotfix, not a proper solution
This commit is contained in:
Robin Gareus 2017-03-11 23:10:44 +01:00
parent 69bcc38e99
commit 0b6e2d1e46

View File

@ -327,9 +327,10 @@ static float runfilter(LV2_Handle instance, const float in)
return out;
}
static void
static bool
update_bpm(ADelay* self, const LV2_Atom_Object* obj)
{
bool changed = false;
const DelayURIs* uris = &self->uris;
// Received new transport bpm/beatunit
@ -340,25 +341,22 @@ update_bpm(ADelay* self, const LV2_Atom_Object* obj)
NULL);
// Tempo changed, update BPM
if (bpm && bpm->type == uris->atom_Float) {
self->bpm = ((LV2_Atom_Float*)bpm)->body;
float b = ((LV2_Atom_Float*)bpm)->body;
if (self->bpm != b) {
changed = true;
}
self->bpm = b;
}
// Time signature changed, update beatunit
if (beatunit && beatunit->type == uris->atom_Int) {
int b = ((LV2_Atom_Int*)beatunit)->body;
self->beatunit = (float)b;
}
if (beatunit && beatunit->type == uris->atom_Double) {
double b = ((LV2_Atom_Double*)beatunit)->body;
self->beatunit = (float)b;
}
if (beatunit && beatunit->type == uris->atom_Float) {
self->beatunit = ((LV2_Atom_Float*)beatunit)->body;
}
if (beatunit && beatunit->type == uris->atom_Long) {
long int b = ((LV2_Atom_Long*)beatunit)->body;
self->beatunit = (float)b;
if (self->beatunit != b) {
changed = true;
}
self->beatunit = b;
}
self->bpmvalid = 1;
return changed;
}
static void
@ -388,7 +386,7 @@ run(LV2_Handle instance, uint32_t n_samples)
unsigned int tmp;
float inv;
float xfade;
int recalc;
bool recalc = false;
// TODO LPF
if (*(adelay->inv) < 0.5) {
@ -397,28 +395,43 @@ run(LV2_Handle instance, uint32_t n_samples)
inv = 1.f;
}
recalc = 0;
if (adelay->atombpm) {
LV2_Atom_Event* ev = lv2_atom_sequence_begin(&(adelay->atombpm)->body);
while(!lv2_atom_sequence_is_end(&(adelay->atombpm)->body, (adelay->atombpm)->atom.size, ev)) {
if (ev->body.type == adelay->uris.atom_Blank || ev->body.type == adelay->uris.atom_Object) {
const LV2_Atom_Object* obj = (LV2_Atom_Object*)&ev->body;
if (obj->body.otype == adelay->uris.time_Position) {
recalc = update_bpm(adelay, obj);
// TODO: split process on BPM change. (independent of buffer-size)
}
}
ev = lv2_atom_sequence_next(ev);
}
}
if (*(adelay->inv) != adelay->invertold) {
recalc = 1;
recalc = true;
}
if (*(adelay->sync) != adelay->syncold) {
recalc = 1;
recalc = true;
}
if (*(adelay->time) != adelay->timeold) {
recalc = 1;
recalc = true;
}
if (*(adelay->feedback) != adelay->feedbackold) {
recalc = 1;
recalc = true;
}
if (*(adelay->divisor) != adelay->divisorold) {
recalc = 1;
recalc = true;
}
if (!is_eq(adelay->lpfold, *adelay->lpf, 0.1)) {
float tc = (1.0 - exp (-2.f * M_PI * n_samples * 25.f / adelay->srate));
adelay->lpfold += tc * (*adelay->lpf - adelay->lpfold);
recalc = 1;
recalc = true;
}
// rg says: in case the delay-time changes, oversampling/interpolate + LPF
// would me more appropriate.
if (recalc) {
lpfRbj(adelay, adelay->lpfold, srate);
if (*(adelay->sync) > 0.5f && adelay->bpmvalid) {
@ -479,18 +492,6 @@ run(LV2_Handle instance, uint32_t n_samples)
adelay->next = tmp;
}
if (adelay->atombpm) {
LV2_Atom_Event* ev = lv2_atom_sequence_begin(&(adelay->atombpm)->body);
while(!lv2_atom_sequence_is_end(&(adelay->atombpm)->body, (adelay->atombpm)->atom.size, ev)) {
if (ev->body.type == adelay->uris.atom_Blank || ev->body.type == adelay->uris.atom_Object) {
const LV2_Atom_Object* obj = (LV2_Atom_Object*)&ev->body;
if (obj->body.otype == adelay->uris.time_Position) {
update_bpm(adelay, obj);
}
}
ev = lv2_atom_sequence_next(ev);
}
}
}
static void