mirror of
https://github.com/f4exb/sdrangel.git
synced 2026-07-26 03:54:30 -04:00
WDSP: more double precision calculation
This commit is contained in:
+115
-21
@@ -43,6 +43,7 @@ void NOB::init_nob (NOB *a)
|
||||
{
|
||||
int i;
|
||||
double coef;
|
||||
|
||||
a->adv_slew_count = (int)(a->advslewtime * a->samplerate);
|
||||
a->adv_count = (int)(a->advtime * a->samplerate);
|
||||
a->hang_count = (int)(a->hangtime * a->samplerate);
|
||||
@@ -50,15 +51,19 @@ void NOB::init_nob (NOB *a)
|
||||
a->max_imp_seq = (int)(a->max_imp_seq_time * a->samplerate);
|
||||
a->backmult = exp (-1.0 / (a->samplerate * a->backtau));
|
||||
a->ombackmult = 1.0 - a->backmult;
|
||||
|
||||
if (a->adv_slew_count > 0)
|
||||
{
|
||||
coef = PI / (a->adv_slew_count + 1);
|
||||
|
||||
for (i = 0; i < a->adv_slew_count; i++)
|
||||
a->awave[i] = 0.5 * cos ((i + 1) * coef);
|
||||
}
|
||||
|
||||
if (a->hang_slew_count > 0)
|
||||
{
|
||||
coef = PI / a->hang_slew_count;
|
||||
|
||||
for (i = 0; i < a->hang_slew_count; i++)
|
||||
a->hwave[i] = 0.5 * cos (i * coef);
|
||||
}
|
||||
@@ -179,14 +184,20 @@ void NOB::xnob (NOB *a)
|
||||
a->dline[2 * a->in_idx + 1] = a->in[2 * i + 1];
|
||||
mag = sqrt(a->dline[2 * a->in_idx + 0] * a->dline[2 * a->in_idx + 0] + a->dline[2 * a->in_idx + 1] * a->dline[2 * a->in_idx + 1]);
|
||||
a->avg = a->backmult * a->avg + a->ombackmult * mag;
|
||||
|
||||
if (mag > (a->avg * a->threshold))
|
||||
a->imp[a->in_idx] = 1;
|
||||
else
|
||||
a->imp[a->in_idx] = 0;
|
||||
if ((bf_idx = a->out_idx + a->adv_slew_count) >= a->dline_size) bf_idx -= a->dline_size;
|
||||
|
||||
if ((bf_idx = a->out_idx + a->adv_slew_count) >= a->dline_size)
|
||||
bf_idx -= a->dline_size;
|
||||
|
||||
if (a->imp[bf_idx] == 0)
|
||||
{
|
||||
if (++a->bfb_in_idx == a->filterlen) a->bfb_in_idx -= a->filterlen;
|
||||
if (++a->bfb_in_idx == a->filterlen)
|
||||
a->bfb_in_idx -= a->filterlen;
|
||||
|
||||
a->bfbuff[2 * a->bfb_in_idx + 0] = a->dline[2 * bf_idx + 0];
|
||||
a->bfbuff[2 * a->bfb_in_idx + 1] = a->dline[2 * bf_idx + 1];
|
||||
}
|
||||
@@ -199,31 +210,41 @@ void NOB::xnob (NOB *a)
|
||||
a->out[2 * i + 1] = a->dline[2 * a->out_idx + 1];
|
||||
a->Ilast = a->dline[2 * a->out_idx + 0];
|
||||
a->Qlast = a->dline[2 * a->out_idx + 1];
|
||||
|
||||
if (a->imp[a->scan_idx] > 0)
|
||||
{
|
||||
a->time = 0;
|
||||
|
||||
if (a->adv_slew_count > 0)
|
||||
a->state = 1;
|
||||
else if (a->adv_count > 0)
|
||||
a->state = 2;
|
||||
else
|
||||
a->state = 3;
|
||||
|
||||
tidx = a->scan_idx;
|
||||
a->blank_count = 0;
|
||||
|
||||
do
|
||||
{
|
||||
len = 0;
|
||||
hcount = 0;
|
||||
|
||||
while ((a->imp[tidx] > 0 || hcount > 0) && a->blank_count < a->max_imp_seq)
|
||||
{
|
||||
a->blank_count++;
|
||||
if (hcount > 0) hcount--;
|
||||
if (a->imp[tidx] > 0) hcount = a->hang_count + a->hang_slew_count;
|
||||
if (++tidx >= a->dline_size) tidx -= a->dline_size;
|
||||
if (hcount > 0)
|
||||
hcount--;
|
||||
if (a->imp[tidx] > 0)
|
||||
hcount = a->hang_count + a->hang_slew_count;
|
||||
if (++tidx >= a->dline_size)
|
||||
tidx -= a->dline_size;
|
||||
}
|
||||
|
||||
j = 1;
|
||||
len = 0;
|
||||
lidx = tidx;
|
||||
|
||||
while (j <= a->adv_slew_count + a->adv_count && len == 0)
|
||||
{
|
||||
if (a->imp[lidx] == 1)
|
||||
@@ -231,16 +252,22 @@ void NOB::xnob (NOB *a)
|
||||
len = j;
|
||||
tidx = lidx;
|
||||
}
|
||||
if (++lidx >= a->dline_size) lidx -= a->dline_size;
|
||||
|
||||
if (++lidx >= a->dline_size)
|
||||
lidx -= a->dline_size;
|
||||
|
||||
j++;
|
||||
}
|
||||
|
||||
if((a->blank_count += len) > a->max_imp_seq)
|
||||
{
|
||||
a->blank_count = a->max_imp_seq;
|
||||
a->overflow = 1;
|
||||
break;
|
||||
}
|
||||
} while (len != 0);
|
||||
}
|
||||
while (len != 0);
|
||||
|
||||
if (a->overflow == 0)
|
||||
{
|
||||
a->blank_count -= a->hang_slew_count;
|
||||
@@ -252,37 +279,53 @@ void NOB::xnob (NOB *a)
|
||||
bfboutidx = a->bfb_in_idx;
|
||||
a->I1 = 0.0;
|
||||
a->Q1 = 0.0;
|
||||
|
||||
for (k = 0; k < a->filterlen; k++)
|
||||
{
|
||||
a->I1 += a->fcoefs[k] * a->bfbuff[2 * bfboutidx + 0];
|
||||
a->Q1 += a->fcoefs[k] * a->bfbuff[2 * bfboutidx + 1];
|
||||
if (--bfboutidx < 0) bfboutidx += a->filterlen;
|
||||
|
||||
if (--bfboutidx < 0)
|
||||
bfboutidx += a->filterlen;
|
||||
}
|
||||
}
|
||||
|
||||
if (a->mode == 2 || a->mode == 3 || a->mode == 4)
|
||||
{
|
||||
if ((ff_idx = a->scan_idx + a->blank_count) >= a->dline_size) ff_idx -= a->dline_size;
|
||||
if ((ff_idx = a->scan_idx + a->blank_count) >= a->dline_size)
|
||||
ff_idx -= a->dline_size;
|
||||
|
||||
ffcount = 0;
|
||||
|
||||
while (ffcount < a->filterlen)
|
||||
{
|
||||
if (a->imp[ff_idx] == 0)
|
||||
{
|
||||
if (++a->ffb_in_idx == a->filterlen) a->ffb_in_idx -= a->filterlen;
|
||||
if (++a->ffb_in_idx == a->filterlen)
|
||||
a->ffb_in_idx -= a->filterlen;
|
||||
|
||||
a->ffbuff[2 * a->ffb_in_idx + 0] = a->dline[2 * ff_idx + 0];
|
||||
a->ffbuff[2 * a->ffb_in_idx + 1] = a->dline[2 * ff_idx + 1];
|
||||
++ffcount;
|
||||
}
|
||||
if (++ff_idx >= a->dline_size) ff_idx -= a->dline_size;
|
||||
|
||||
if (++ff_idx >= a->dline_size)
|
||||
ff_idx -= a->dline_size;
|
||||
}
|
||||
if ((ffboutidx = a->ffb_in_idx + 1) >= a->filterlen) ffboutidx -= a->filterlen;
|
||||
|
||||
if ((ffboutidx = a->ffb_in_idx + 1) >= a->filterlen)
|
||||
ffboutidx -= a->filterlen;
|
||||
|
||||
a->I2 = 0.0;
|
||||
a->Q2 = 0.0;
|
||||
|
||||
for (k = 0; k < a->filterlen; k++)
|
||||
{
|
||||
a->I2 += a->fcoefs[k] * a->ffbuff[2 * ffboutidx + 0];
|
||||
a->Q2 += a->fcoefs[k] * a->ffbuff[2 * ffboutidx + 1];
|
||||
if (++ffboutidx >= a->filterlen) ffboutidx -= a->filterlen;
|
||||
|
||||
if (++ffboutidx >= a->filterlen)
|
||||
ffboutidx -= a->filterlen;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -323,7 +366,9 @@ void NOB::xnob (NOB *a)
|
||||
else
|
||||
{
|
||||
if (a->adv_slew_count > 0)
|
||||
{
|
||||
a->state = 5;
|
||||
}
|
||||
else
|
||||
{
|
||||
a->state = 6;
|
||||
@@ -332,23 +377,29 @@ void NOB::xnob (NOB *a)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 1: // slew output in advance of blanking period
|
||||
{
|
||||
scale = 0.5 + a->awave[a->time];
|
||||
a->out[2 * i + 0] = a->Ilast * scale + (1.0 - scale) * a->I;
|
||||
a->out[2 * i + 1] = a->Qlast * scale + (1.0 - scale) * a->Q;
|
||||
|
||||
if (++a->time == a->adv_slew_count)
|
||||
{
|
||||
a->time = 0;
|
||||
|
||||
if (a->adv_count > 0)
|
||||
a->state = 2;
|
||||
else
|
||||
a->state = 3;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 2: // initial advance period
|
||||
{
|
||||
a->out[2 * i + 0] = a->I;
|
||||
@@ -361,8 +412,10 @@ void NOB::xnob (NOB *a)
|
||||
a->state = 3;
|
||||
a->time = 0;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 3: // impulse & hang period
|
||||
{
|
||||
a->out[2 * i + 0] = a->I;
|
||||
@@ -378,52 +431,69 @@ void NOB::xnob (NOB *a)
|
||||
a->time = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
a->state = 0;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 4: // slew output after blanking period
|
||||
{
|
||||
scale = 0.5 - a->hwave[a->time];
|
||||
a->out[2 * i + 0] = a->Inext * scale + (1.0 - scale) * a->I;
|
||||
a->out[2 * i + 1] = a->Qnext * scale + (1.0 - scale) * a->Q;
|
||||
|
||||
if (++a->time == a->hang_slew_count)
|
||||
a->state = 0;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 5:
|
||||
{
|
||||
scale = 0.5 + a->awave[a->time];
|
||||
a->out[2 * i + 0] = a->Ilast * scale;
|
||||
a->out[2 * i + 1] = a->Qlast * scale;
|
||||
|
||||
if (++a->time == a->adv_slew_count)
|
||||
{
|
||||
a->state = 6;
|
||||
a->time = 0;
|
||||
a->blank_count += a->adv_count + a->filterlen;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 6:
|
||||
{
|
||||
a->out[2 * i + 0] = 0.0;
|
||||
a->out[2 * i + 1] = 0.0;
|
||||
|
||||
if (++a->time == a->blank_count)
|
||||
a->state = 7;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 7:
|
||||
{
|
||||
a->out[2 * i + 0] = 0.0;
|
||||
a->out[2 * i + 1] = 0.0;
|
||||
staydown = 0;
|
||||
a->time = 0;
|
||||
if ((tidx = a->scan_idx + a->hang_slew_count + a->hang_count) >= a->dline_size) tidx -= a->dline_size;
|
||||
|
||||
if ((tidx = a->scan_idx + a->hang_slew_count + a->hang_count) >= a->dline_size)
|
||||
tidx -= a->dline_size;
|
||||
|
||||
while (a->time++ <= a->adv_count + a->adv_slew_count + a->hang_slew_count + a->hang_count) // CHECK EXACT COUNTS!!!!!!!!!!!!!!!!!!!!!!!
|
||||
{
|
||||
if (a->imp[tidx] == 1) staydown = 1;
|
||||
if (--tidx < 0) tidx += a->dline_size;
|
||||
}
|
||||
|
||||
if (staydown == 0)
|
||||
{
|
||||
if (a->hang_count > 0)
|
||||
@@ -435,8 +505,13 @@ void NOB::xnob (NOB *a)
|
||||
{
|
||||
a->state = 9;
|
||||
a->time = 0;
|
||||
if ((tidx = a->scan_idx + a->hang_slew_count + a->hang_count - a->adv_count - a->adv_slew_count) >= a->dline_size) tidx -= a->dline_size;
|
||||
if (tidx < 0) tidx += a->dline_size;
|
||||
|
||||
if ((tidx = a->scan_idx + a->hang_slew_count + a->hang_count - a->adv_count - a->adv_slew_count) >= a->dline_size)
|
||||
tidx -= a->dline_size;
|
||||
|
||||
if (tidx < 0)
|
||||
tidx += a->dline_size;
|
||||
|
||||
a->Inext = a->dline[2 * tidx + 0];
|
||||
a->Qnext = a->dline[2 * tidx + 1];
|
||||
}
|
||||
@@ -446,20 +521,28 @@ void NOB::xnob (NOB *a)
|
||||
a->overflow = 0;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 8:
|
||||
{
|
||||
a->out[2 * i + 0] = 0.0;
|
||||
a->out[2 * i + 1] = 0.0;
|
||||
|
||||
if (++a->time == a->hang_count)
|
||||
{
|
||||
if (a->hang_slew_count > 0)
|
||||
{
|
||||
a->state = 9;
|
||||
a->time = 0;
|
||||
if ((tidx = a->scan_idx + a->hang_slew_count - a->adv_count - a->adv_slew_count) >= a->dline_size) tidx -= a->dline_size;
|
||||
if (tidx < 0) tidx += a->dline_size;
|
||||
|
||||
if ((tidx = a->scan_idx + a->hang_slew_count - a->adv_count - a->adv_slew_count) >= a->dline_size)
|
||||
tidx -= a->dline_size;
|
||||
|
||||
if (tidx < 0)
|
||||
tidx += a->dline_size;
|
||||
|
||||
a->Inext = a->dline[2 * tidx + 0];
|
||||
a->Qnext = a->dline[2 * tidx + 1];
|
||||
}
|
||||
@@ -469,8 +552,10 @@ void NOB::xnob (NOB *a)
|
||||
a->overflow = 0;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 9:
|
||||
{
|
||||
scale = 0.5 - a->hwave[a->time];
|
||||
@@ -482,16 +567,25 @@ void NOB::xnob (NOB *a)
|
||||
a->state = 0;
|
||||
a->overflow = 0;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (++a->in_idx == a->dline_size) a->in_idx = 0;
|
||||
if (++a->scan_idx == a->dline_size) a->scan_idx = 0;
|
||||
if (++a->out_idx == a->dline_size) a->out_idx = 0;
|
||||
|
||||
if (++a->in_idx == a->dline_size)
|
||||
a->in_idx = 0;
|
||||
|
||||
if (++a->scan_idx == a->dline_size)
|
||||
a->scan_idx = 0;
|
||||
|
||||
if (++a->out_idx == a->dline_size)
|
||||
a->out_idx = 0;
|
||||
}
|
||||
}
|
||||
else if (a->in != a->out)
|
||||
{
|
||||
std::copy(a->in, a->in + a->buffsize * 2, a->out);
|
||||
}
|
||||
}
|
||||
|
||||
void NOB::setBuffers_nob (NOB *a, float* in, float* out)
|
||||
|
||||
Reference in New Issue
Block a user