mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-12-23 01:55:48 -05:00
WDSP: FIR: calculate on double precision as much as possible
This commit is contained in:
parent
6d3516482e
commit
3f800dd0a9
@ -24,6 +24,8 @@ The author can be reached by email at
|
|||||||
warren@wpratt.com
|
warren@wpratt.com
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
#include "comm.hpp"
|
#include "comm.hpp"
|
||||||
#include "calculus.hpp"
|
#include "calculus.hpp"
|
||||||
#include "emnr.hpp"
|
#include "emnr.hpp"
|
||||||
@ -273,7 +275,7 @@ void EMNR::calc_emnr(EMNR *a)
|
|||||||
float tau = -128.0 / 8000.0 / log(0.98);
|
float tau = -128.0 / 8000.0 / log(0.98);
|
||||||
a->g.alpha = exp(-a->incr / a->rate / tau);
|
a->g.alpha = exp(-a->incr / a->rate / tau);
|
||||||
}
|
}
|
||||||
a->g.eps_floor = 1.0e-300;
|
a->g.eps_floor = std::numeric_limits<double>::min();
|
||||||
a->g.gamma_max = 1000.0;
|
a->g.gamma_max = 1000.0;
|
||||||
a->g.q = 0.2;
|
a->g.q = 0.2;
|
||||||
for (i = 0; i < a->g.msize; i++)
|
for (i = 0; i < a->g.msize; i++)
|
||||||
|
51
wdsp/fir.cpp
51
wdsp/fir.cpp
@ -25,6 +25,9 @@ warren@pratt.one
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#define _CRT_SECURE_NO_WARNINGS
|
#define _CRT_SECURE_NO_WARNINGS
|
||||||
|
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
#include "fftw3.h"
|
#include "fftw3.h"
|
||||||
#include "comm.hpp"
|
#include "comm.hpp"
|
||||||
#include "fir.hpp"
|
#include "fir.hpp"
|
||||||
@ -54,15 +57,15 @@ float* FIR::fftcv_mults (int NM, float* c_impulse)
|
|||||||
float* FIR::get_fsamp_window(int N, int wintype)
|
float* FIR::get_fsamp_window(int N, int wintype)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
float arg0, arg1;
|
double arg0, arg1;
|
||||||
float* window = new float[N]; // (float *) malloc0 (N * sizeof(float));
|
float* window = new float[N]; // (float *) malloc0 (N * sizeof(float));
|
||||||
switch (wintype)
|
switch (wintype)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
arg0 = 2.0 * PI / ((float)N - 1.0);
|
arg0 = 2.0 * PI / ((double)N - 1.0);
|
||||||
for (i = 0; i < N; i++)
|
for (i = 0; i < N; i++)
|
||||||
{
|
{
|
||||||
arg1 = cos(arg0 * (float)i);
|
arg1 = cos(arg0 * (double)i);
|
||||||
window[i] = +0.21747
|
window[i] = +0.21747
|
||||||
+ arg1 * (-0.45325
|
+ arg1 * (-0.45325
|
||||||
+ arg1 * (+0.28256
|
+ arg1 * (+0.28256
|
||||||
@ -70,10 +73,10 @@ float* FIR::get_fsamp_window(int N, int wintype)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
arg0 = 2.0 * PI / ((float)N - 1.0);
|
arg0 = 2.0 * PI / ((double)N - 1.0);
|
||||||
for (i = 0; i < N; ++i)
|
for (i = 0; i < N; ++i)
|
||||||
{
|
{
|
||||||
arg1 = cos(arg0 * (float)i);
|
arg1 = cos(arg0 * (double)i);
|
||||||
window[i] = +6.3964424114390378e-02
|
window[i] = +6.3964424114390378e-02
|
||||||
+ arg1 * (-2.3993864599352804e-01
|
+ arg1 * (-2.3993864599352804e-01
|
||||||
+ arg1 * (+3.5015956323820469e-01
|
+ arg1 * (+3.5015956323820469e-01
|
||||||
@ -90,11 +93,11 @@ float* FIR::get_fsamp_window(int N, int wintype)
|
|||||||
return window;
|
return window;
|
||||||
}
|
}
|
||||||
|
|
||||||
float* FIR::fir_fsamp_odd (int N, float* A, int rtype, float scale, int wintype)
|
float* FIR::fir_fsamp_odd (int N, float* A, int rtype, double scale, int wintype)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
int mid = (N - 1) / 2;
|
int mid = (N - 1) / 2;
|
||||||
float mag, phs;
|
double mag, phs;
|
||||||
float* window;
|
float* window;
|
||||||
float *fcoef = new float[N * 2];
|
float *fcoef = new float[N * 2];
|
||||||
float *c_impulse = new float[N * 2];
|
float *c_impulse = new float[N * 2];
|
||||||
@ -105,11 +108,11 @@ float* FIR::fir_fsamp_odd (int N, float* A, int rtype, float scale, int wintype)
|
|||||||
FFTW_BACKWARD,
|
FFTW_BACKWARD,
|
||||||
FFTW_PATIENT
|
FFTW_PATIENT
|
||||||
);
|
);
|
||||||
float local_scale = 1.0 / (float)N;
|
double local_scale = 1.0 / (double) N;
|
||||||
for (i = 0; i <= mid; i++)
|
for (i = 0; i <= mid; i++)
|
||||||
{
|
{
|
||||||
mag = A[i] * local_scale;
|
mag = A[i] * local_scale;
|
||||||
phs = - (float)mid * TWOPI * (float)i / (float)N;
|
phs = - (double)mid * TWOPI * (double)i / (double)N;
|
||||||
fcoef[2 * i + 0] = mag * cos (phs);
|
fcoef[2 * i + 0] = mag * cos (phs);
|
||||||
fcoef[2 * i + 1] = mag * sin (phs);
|
fcoef[2 * i + 1] = mag * sin (phs);
|
||||||
}
|
}
|
||||||
@ -140,10 +143,10 @@ float* FIR::fir_fsamp_odd (int N, float* A, int rtype, float scale, int wintype)
|
|||||||
return c_impulse;
|
return c_impulse;
|
||||||
}
|
}
|
||||||
|
|
||||||
float* FIR::fir_fsamp (int N, float* A, int rtype, float scale, int wintype)
|
float* FIR::fir_fsamp (int N, float* A, int rtype, double scale, int wintype)
|
||||||
{
|
{
|
||||||
int n, i, j, k;
|
int n, i, j, k;
|
||||||
float sum;
|
double sum;
|
||||||
float* window;
|
float* window;
|
||||||
float *c_impulse = new float[N * 2]; // (float *) malloc0 (N * sizeof (complex));
|
float *c_impulse = new float[N * 2]; // (float *) malloc0 (N * sizeof (complex));
|
||||||
|
|
||||||
@ -166,7 +169,7 @@ float* FIR::fir_fsamp (int N, float* A, int rtype, float scale, int wintype)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
float M = (float)(N - 1) / 2.0;
|
double M = (double)(N - 1) / 2.0;
|
||||||
for (n = 0; n < N / 2; n++)
|
for (n = 0; n < N / 2; n++)
|
||||||
{
|
{
|
||||||
sum = 0.0;
|
sum = 0.0;
|
||||||
@ -200,18 +203,18 @@ float* FIR::fir_fsamp (int N, float* A, int rtype, float scale, int wintype)
|
|||||||
return c_impulse;
|
return c_impulse;
|
||||||
}
|
}
|
||||||
|
|
||||||
float* FIR::fir_bandpass (int N, float f_low, float f_high, float samplerate, int wintype, int rtype, float scale)
|
float* FIR::fir_bandpass (int N, double f_low, double f_high, double samplerate, int wintype, int rtype, double scale)
|
||||||
{
|
{
|
||||||
float *c_impulse = new float[N * 2]; // (float *) malloc0 (N * sizeof (complex));
|
float *c_impulse = new float[N * 2]; // (float *) malloc0 (N * sizeof (complex));
|
||||||
float ft = (f_high - f_low) / (2.0 * samplerate);
|
double ft = (f_high - f_low) / (2.0 * samplerate);
|
||||||
float ft_rad = TWOPI * ft;
|
double ft_rad = TWOPI * ft;
|
||||||
float w_osc = PI * (f_high + f_low) / samplerate;
|
double w_osc = PI * (f_high + f_low) / samplerate;
|
||||||
int i, j;
|
int i, j;
|
||||||
float m = 0.5 * (float)(N - 1);
|
double m = 0.5 * (double)(N - 1);
|
||||||
float delta = PI / m;
|
double delta = PI / m;
|
||||||
float cosphi;
|
double cosphi;
|
||||||
float posi, posj;
|
double posi, posj;
|
||||||
float sinc, window, coef;
|
double sinc, window, coef;
|
||||||
|
|
||||||
if (N & 1)
|
if (N & 1)
|
||||||
{
|
{
|
||||||
@ -228,8 +231,8 @@ float* FIR::fir_bandpass (int N, float f_low, float f_high, float samplerate, in
|
|||||||
}
|
}
|
||||||
for (i = (N + 1) / 2, j = N / 2 - 1; i < N; i++, j--)
|
for (i = (N + 1) / 2, j = N / 2 - 1; i < N; i++, j--)
|
||||||
{
|
{
|
||||||
posi = (float)i - m;
|
posi = (double)i - m;
|
||||||
posj = (float)j - m;
|
posj = (double)j - m;
|
||||||
sinc = sin (ft_rad * posi) / (PI * posi);
|
sinc = sin (ft_rad * posi) / (PI * posi);
|
||||||
switch (wintype)
|
switch (wintype)
|
||||||
{
|
{
|
||||||
@ -384,7 +387,7 @@ void FIR::mp_imp (int N, float* fir, float* mpfir, int pfactor, int polarity)
|
|||||||
if (mag[i] > 0.0)
|
if (mag[i] > 0.0)
|
||||||
ana[2 * i + 0] = log (mag[i]);
|
ana[2 * i + 0] = log (mag[i]);
|
||||||
else
|
else
|
||||||
ana[2 * i + 0] = log (1.0e-300);
|
ana[2 * i + 0] = log (std::numeric_limits<float>::min());
|
||||||
}
|
}
|
||||||
analytic (size, ana, ana);
|
analytic (size, ana, ana);
|
||||||
for (i = 0; i < size; i++)
|
for (i = 0; i < size; i++)
|
||||||
|
@ -35,9 +35,9 @@ class WDSP_API FIR
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static float* fftcv_mults (int NM, float* c_impulse);
|
static float* fftcv_mults (int NM, float* c_impulse);
|
||||||
static float* fir_fsamp_odd (int N, float* A, int rtype, float scale, int wintype);
|
static float* fir_fsamp_odd (int N, float* A, int rtype, double scale, int wintype);
|
||||||
static float* fir_fsamp (int N, float* A, int rtype, float scale, int wintype);
|
static float* fir_fsamp (int N, float* A, int rtype, double scale, int wintype);
|
||||||
static float* fir_bandpass (int N, float f_low, float f_high, float samplerate, int wintype, int rtype, float scale);
|
static float* fir_bandpass (int N, double f_low, double f_high, double samplerate, int wintype, int rtype, double scale);
|
||||||
static void mp_imp (int N, float* fir, float* mpfir, int pfactor, int polarity);
|
static void mp_imp (int N, float* fir, float* mpfir, int pfactor, int polarity);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -75,7 +75,13 @@ void FIRCORE::plan_fircore (FIRCORE *a)
|
|||||||
FFTW_FORWARD,
|
FFTW_FORWARD,
|
||||||
FFTW_PATIENT
|
FFTW_PATIENT
|
||||||
);
|
);
|
||||||
a->maskplan[1][i] = fftwf_plan_dft_1d(2 * a->size, (fftwf_complex *)a->maskgen, (fftwf_complex *)a->fmask[1][i], FFTW_FORWARD, FFTW_PATIENT);
|
a->maskplan[1][i] = fftwf_plan_dft_1d(
|
||||||
|
2 * a->size,
|
||||||
|
(fftwf_complex *)a->maskgen,
|
||||||
|
(fftwf_complex *)a->fmask[1][i],
|
||||||
|
FFTW_FORWARD,
|
||||||
|
FFTW_PATIENT
|
||||||
|
);
|
||||||
}
|
}
|
||||||
a->accum = new float[2 * a->size * 2]; // (float *) malloc0 (2 * a->size * sizeof (complex));
|
a->accum = new float[2 * a->size * 2]; // (float *) malloc0 (2 * a->size * sizeof (complex));
|
||||||
a->crev = fftwf_plan_dft_1d(
|
a->crev = fftwf_plan_dft_1d(
|
||||||
|
Loading…
Reference in New Issue
Block a user