* Changed Waterfall fft from Cfft to g_fft
pull/1/head
David Freese 2013-10-19 07:43:31 -05:00
rodzic b8f424213b
commit da36c7bd91
5 zmienionych plików z 60 dodań i 76 usunięć

Wyświetl plik

@ -3,8 +3,8 @@
#include "filters.h"
class cDTMF {
public:
#define N 240 // 30 msec interval at 8000 sps
private:
//#define N 240 // 30 msec interval at 8000 sps
#define RANGE 0.5 /* any thing higher than RANGE*peak is "on" */
#define THRESH 1000 /* 6 dB s/n for detection */
@ -43,7 +43,7 @@ public:
cDTMF() {
for (int i = 0; i < 4; i++) filt[i] = new goertzel(240, row[i], 8000);
for (int i = 0; i < 4; i++) filt[i+4] = new goertzel(240, col[i], 8000);
for (int i = 0; i < N; i++) data[i] = 0;
for (int i = 0; i < 240; i++) data[i] = 0;
dtmfchars.clear();
framesize = 240; // 8000 sr default
silence_time = 0;

Wyświetl plik

@ -75,7 +75,7 @@ private:
short *BRLow;
void fftInit();
int ConvertFFTSize(int N);
int ConvertFFTSize(int);
// base fft methods
void riffts1(FFT_TYPE *ioptr, int M, FFT_TYPE *Utbl, short *BRLow);

Wyświetl plik

@ -30,7 +30,7 @@
#include <FL/Fl_Counter.H>
#include <FL/Fl_Box.H>
#include "fft.h"
#include "gfft.h"
#include "fldigi-config.h"
#include "digiscope.h"
#include "flslider2.h"
@ -40,22 +40,9 @@ enum {
WF_FFT_HANNING, WF_FFT_TRIANGULAR
};
/*
#ifdef HAVE_DFFTW_H
# include <dfftw.h>
#endif
#ifdef HAVE_FFTW_H
# include <fftw.h>
#endif
*/
#define FFT_LEN 4096
//8192
//2048
//4096
#define FFT_LEN 8192
#define SC_SMPLRATE 8000
#define WFBLOCKSIZE 512
#define WFBLOCKSIZE 512
struct RGB {
uchar R;
@ -70,7 +57,13 @@ struct RGBI {
uchar I;
};
extern RGBI mag2RGBI[256];
// you can change the basic fft processing type by a simple change in the
// following typedef. change to float if you need to skimp on cpu cycles.
typedef double wf_fft_type;
typedef std::complex<wf_fft_type> wf_cpx_type;
extern RGBI mag2RGBI[256];
extern RGB palette[9];
enum WFmode {
@ -149,7 +142,6 @@ public:
void initmaps();
void draw();
// void resize (int, int, int, int);
int handle(int event);
void update_sigmap();
void update_waterfall();
@ -161,7 +153,7 @@ public:
inline void makeNotch_(int notch_frequency);
inline void makeMarker_(int width, const RGB* color, int freq, const RGB* clrMin, RGB* clrM, const RGB* clrMax);
void makeMarker();
void process_analog(double *sig, int len);
void process_analog(wf_fft_type *sig, int len);
void processFFT();
void sig_data( double *sig, int len, int sr );
void rfcarrier(long long f) {
@ -173,8 +165,6 @@ public:
bool USB() {return usb;};
long long rfcarrier() { return rfc;};
// void useBands(bool b) { usebands = b;};
void updateMarker() {
drawMarker();};
int peakFreq(int f0, int delta);
@ -202,7 +192,6 @@ private:
bool overload;
bool usb;
long long rfc;
// bool usebands;
int offset;
int sigoffset;
int step;
@ -220,24 +209,24 @@ private:
WFspeed wfspeed;
int srate;
RGBI *fft_img;
// RGBI mag2RGBI[256];
RGB *markerimage;
RGB RGBmarker;
RGB RGBcursor;
RGBI RGBInotch;
double *fftout;
double *fftwindow;
uchar *scaleimage;
uchar *fft_sig_img;
uchar *sig_img;
uchar *scline;
wf_cpx_type *wfbuf;
short int *fft_db;
int ptrFFTbuff;
double *circbuff;
wf_fft_type *circbuff;
int ptrCB;
double *pwr;
Cfft *wfft;
wf_fft_type *pwr;
g_fft<wf_fft_type> *wfft;
int prefilter;
@ -271,7 +260,6 @@ public:
class waterfall: public Fl_Group {
friend void x1_cb(Fl_Widget *w, void* v);
// friend void slew_cb(Fl_Widget *w, void * v);
friend void slew_left(Fl_Widget *w, void * v);
friend void slew_right(Fl_Widget *w, void * v);
friend void center_cb(Fl_Widget *w, void *v);
@ -351,10 +339,6 @@ public:
qsy->activate();
else
qsy->deactivate();
// wfdisp->useBands(!on);
}
void setXMLRPC(bool on) {
// wfdisp->useBands(!on);
}
double Pwr(int i) { return wfdisp->Pwr(i); }

Wyświetl plik

@ -787,11 +787,12 @@ void configuration::initInterface()
}
#endif
} else if (chkUSEXMLRPCis) {
wf->setXMLRPC(1);
rigCAT_init(false);
wf->USB(true);
wf->setQSY(0);
riginitOK = true;
if (rigCAT_init(false)) {
LOG_VERBOSE("%s", "using XMLRPC");
wf->USB(true);
wf->setQSY(0);
riginitOK = true;
}
}
if (riginitOK == false) {

Wyświetl plik

@ -129,17 +129,16 @@ WFdisp::WFdisp (int x0, int y0, int w0, int h0, char *lbl) :
scline = new uchar[scale_width];
fft_sig_img = new uchar[image_area];
sig_img = new uchar[sig_image_area];
pwr = new double[IMAGE_WIDTH];
pwr = new wf_fft_type[IMAGE_WIDTH];
fft_db = new short int[image_area];
tmp_fft_db = new short int[image_area];
circbuff = new double[FFT_LEN * 2];
fftout = new double[FFT_LEN * 2];
wfft = new Cfft(FFT_LEN);
fftwindow = new double[FFT_LEN * 2];
circbuff = new wf_fft_type[FFT_LEN];
wfbuf = new wf_cpx_type[FFT_LEN];
wfft = new g_fft<wf_fft_type>(FFT_LEN);
fftwindow = new double[FFT_LEN];
setPrefilter(progdefaults.wfPreFilter);
for (int i = 0; i < FFT_LEN*2; i++)
circbuff[i] = fftout[i] = 0.0;
memset(circbuff, 0, FFT_LEN * sizeof(*circbuff));
mag = 1;
step = 4;
@ -481,11 +480,11 @@ double WFdisp::powerDensityMaximum(int bw_nb, const int (*bw)[2]) const
void WFdisp::setPrefilter(int v)
{
switch (v) {
case WF_FFT_RECTANGULAR: RectWindow(fftwindow, FFT_LEN*2); break;
case WF_FFT_BLACKMAN: BlackmanWindow(fftwindow, FFT_LEN*2); break;
case WF_FFT_HAMMING: HammingWindow(fftwindow, FFT_LEN*2); break;
case WF_FFT_HANNING: HanningWindow(fftwindow, FFT_LEN*2); break;
case WF_FFT_TRIANGULAR: TriangularWindow(fftwindow, FFT_LEN*2); break;
case WF_FFT_RECTANGULAR: RectWindow(fftwindow, FFT_LEN); break;
case WF_FFT_BLACKMAN: BlackmanWindow(fftwindow, FFT_LEN); break;
case WF_FFT_HAMMING: HammingWindow(fftwindow, FFT_LEN); break;
case WF_FFT_HANNING: HanningWindow(fftwindow, FFT_LEN); break;
case WF_FFT_TRIANGULAR: TriangularWindow(fftwindow, FFT_LEN); break;
}
prefilter = v;
}
@ -502,30 +501,31 @@ void WFdisp::processFFT() {
if (prefilter != progdefaults.wfPreFilter)
setPrefilter(progdefaults.wfPreFilter);
const double scale = ( (double)SC_SMPLRATE / srate ) * ( FFT_LEN / 2000.0 );
wf_fft_type scale = ( 1.0 * SC_SMPLRATE / srate ) * ( FFT_LEN / 8000.0);
if (dispcnt == 0) {
int step = 8 / progdefaults.latency;
int last_i = FFT_LEN * 2 / step;
memset(wfbuf, 0, FFT_LEN * sizeof(*wfbuf));
int last_i = FFT_LEN / step;
for (int i = 0; i < last_i; i++)
fftout[i] = fftwindow[i * step] * circbuff[i] * step;
/// Zeroes only the last elements.
memset (fftout + last_i , 0, ( FFT_LEN*2 - last_i ) *sizeof(double));
wfbuf[i] = wf_cpx_type(fftwindow[i * step] * circbuff[i] * step, 0);
wfft->ComplexFFT(wfbuf);
wfft->rdft(fftout);
FL_LOCK_D();
const int log2disp100 = log2disp(-100);
for (int i = 0; i <= progdefaults.LowFreqCutoff; i++) {
pwr[i] = 0.0;
fft_db[ptrFFTbuff * IMAGE_WIDTH + i] = log2disp100;
}
static const int log2disp100 = log2disp(-100);
static const double pscale = 4.0 / (FFT_LEN * FFT_LEN);
memset(pwr, 0, progdefaults.LowFreqCutoff * sizeof(wf_fft_type));
memset(&fft_db[ptrFFTbuff * IMAGE_WIDTH],
log2disp100,
progdefaults.LowFreqCutoff * sizeof(*fft_db));
int n = 0;
for (int i = progdefaults.LowFreqCutoff + 1; i < IMAGE_WIDTH; i++) {
int n = (int)(scale * i) & ~1 ; // Even number.
double pw = fftout[n]*fftout[n] + fftout[n+1]*fftout[n+1];
pwr[i] = pw;
int ffth = (int)(10.0 * log10(pw + 1e-10) );
n = round(scale * i);
pwr[i] = norm(wfbuf[n]) * pscale;;
int ffth = round(10.0 * log10(pwr[i] + 1e-10) );
fft_db[ptrFFTbuff * IMAGE_WIDTH + i] = log2disp(ffth);
}
@ -559,7 +559,7 @@ FL_UNLOCK_D();
}
--dispcnt;
}
void WFdisp::process_analog (double *sig, int len) {
void WFdisp::process_analog (wf_fft_type *sig, int len) {
int h1, h2, h3;
int sigy, sigpixel, ynext, graylevel;
h1 = h()/8 - 1;
@ -580,7 +580,7 @@ FL_LOCK_D();
ynext = (int)(h2 * sig[cbc]);
if (ynext < -h2) ynext = -h2;
if (ynext > h2) ynext = h2;
cbc = (cbc + 1) % (FFT_LEN *2);
cbc = (cbc + 1) % (FFT_LEN);
for (; sigy < ynext; sigy++) sig_img[sigpixel -= IMAGE_WIDTH] = graylevel;
for (; sigy > ynext; sigy--) sig_img[sigpixel += IMAGE_WIDTH] = graylevel;
sig_img[sigpixel++] = graylevel;
@ -604,7 +604,7 @@ void WFdisp::sig_data( double *sig, int len, int sr )
// if sound card sampling rate changed reset the waterfall buffer
if (srate != sr) {
srate = sr;
memset (circbuff, 0, FFT_LEN * 2 * sizeof(double));
memset(circbuff, 0, FFT_LEN * sizeof(*circbuff));
ptrCB = 0;
}
@ -613,18 +613,17 @@ void WFdisp::sig_data( double *sig, int len, int sr )
double overval, peak = 0.0;
memmove((void*)circbuff,
(void*)(circbuff + len),
(size_t)((FFT_LEN *2 - len)*sizeof(double)));
memmove((void*)(circbuff + (FFT_LEN*2-len)),
(void*)sig,
(size_t)(len*sizeof(double)));
(size_t)((FFT_LEN - len)*sizeof(wf_fft_type)));
for (int i = 0; i < len; i++) {
circbuff[FFT_LEN - len + i] = sig[i];
overval = fabs(sig[i]);
if (overval > peak) peak = overval;
}
peakaudio = 0.1 * peak + 0.9 * peakaudio;
}
if (mode == SCOPE)
process_analog(circbuff, FFT_LEN * 2);
process_analog(circbuff, FFT_LEN);
else
processFFT();