more fft display stuff; fft struct; etc

pull/5/head
Oona 2013-01-28 08:57:05 +02:00
rodzic d5cb9604eb
commit f406f35cbb
7 zmienionych plików z 60 dodań i 53 usunięć

Wyświetl plik

@ -35,9 +35,6 @@ GtkListStore *savedstore = NULL;
GKeyFile *config = NULL;
fftw_plan Plan1024 = NULL;
fftw_plan Plan2048 = NULL;
// Return the FFT bin index matching the given frequency
guint GetBin (double Freq, guint FFTLen) {
return (Freq / 44100 * FFTLen);

Wyświetl plik

@ -19,6 +19,8 @@ typedef struct _FFTStuff FFTStuff;
struct _FFTStuff {
double *in;
fftw_complex *out;
fftw_plan Plan1024;
fftw_plan Plan2048;
};
extern FFTStuff fft;
@ -77,9 +79,6 @@ extern GtkListStore *savedstore;
extern GKeyFile *config;
extern fftw_plan Plan1024;
extern fftw_plan Plan2048;
typedef struct _PicMeta PicMeta;
struct _PicMeta {
gshort HedrShift;
@ -137,7 +136,7 @@ void *Listen ();
void populateDeviceList ();
void readPcm (gint numsamples);
void saveCurrentPic();
void setVU (double *Power, int FFTLen, int WinIdx);
void setVU (double *Power, int FFTLen, int WinIdx, gboolean ShowWin);
void evt_AbortRx ();
void evt_changeDevices ();

2
fsk.c
Wyświetl plik

@ -51,7 +51,7 @@ void GetFSK (char *dest) {
pcm.WindowPtr += (InSync ? 970 : 485);
// FFT of last 22 ms
fftw_execute(Plan2048);
fftw_execute(fft.Plan2048);
LoBin = GetBin(1900+CurrentPic.HedrShift, FFTLen)-1;
MidBin = GetBin(2000+CurrentPic.HedrShift, FFTLen);

66
gui.c
Wyświetl plik

@ -13,7 +13,7 @@ void createGUI() {
builder = gtk_builder_new();
gtk_builder_add_from_file(builder, "slowrx.ui", NULL);
gtk_builder_add_from_file(builder, "window_about.ui", NULL);
gtk_builder_add_from_file(builder, "aboutdialog.ui", NULL);
gui.button_abort = GTK_WIDGET(gtk_builder_get_object(builder,"button_abort"));
gui.button_browse = GTK_WIDGET(gtk_builder_get_object(builder,"button_browse"));
@ -65,8 +65,8 @@ void createGUI() {
pixbuf_disp = gdk_pixbuf_scale_simple (pixbuf_rx, 500, 400, GDK_INTERP_BILINEAR);
gtk_image_set_from_pixbuf(GTK_IMAGE(gui.image_rx), pixbuf_disp);
pixbuf_PWR = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, 100, 20);
pixbuf_SNR = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, 100, 20);
pixbuf_PWR = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, 100, 30);
pixbuf_SNR = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, 100, 30);
gtk_combo_box_set_active(GTK_COMBO_BOX(gui.combo_mode), 0);
@ -84,11 +84,11 @@ void createGUI() {
}
// Draw signal level meters according to given values
void setVU (double *Power, int FFTLen, int WinIdx) {
int x,y;
void setVU (double *Power, int FFTLen, int WinIdx, gboolean ShowWin) {
int x,y, W=100, H=30;
guchar *pixelsPWR, *pixelsSNR, *pPWR, *pSNR;
unsigned int rowstridePWR,rowstrideSNR;
double logpow;
unsigned int rowstridePWR,rowstrideSNR, LoBin, HiBin, i;
double logpow,p;
rowstridePWR = gdk_pixbuf_get_rowstride (pixbuf_PWR);
pixelsPWR = gdk_pixbuf_get_pixels (pixbuf_PWR);
@ -96,37 +96,53 @@ void setVU (double *Power, int FFTLen, int WinIdx) {
rowstrideSNR = gdk_pixbuf_get_rowstride (pixbuf_SNR);
pixelsSNR = gdk_pixbuf_get_pixels (pixbuf_SNR);
for (y=0; y<20; y++) {
for (x=0; x<100; x++) {
for (y=0; y<H; y++) {
for (x=0; x<W; x++) {
pPWR = pixelsPWR + y * rowstridePWR + (99-x) * 3;
pSNR = pixelsSNR + y * rowstrideSNR + (99-x) * 3;
pPWR = pixelsPWR + y * rowstridePWR + (W-1-x) * 3;
pSNR = pixelsSNR + y * rowstrideSNR + (W-1-x) * 3;
if (y > 3 && y < 16 && (99-x) % 16 >3 && x % 2 == 0) {
if ((5-WinIdx) >= (99-x)/16) {
if ((5-WinIdx) >= (W-1-x)/16) {
if (y > 3 && y < H-3 && (W-1-x) % 16 >3 && x % 2 == 0) {
pSNR[0] = 0x34;
pSNR[1] = 0xe4;
pSNR[2] = 0x84;
} else {
pSNR[0] = pSNR[2] = 0x60;
pSNR[1] = 0x60;
pSNR[0] = 0x00;
pSNR[1] = 0x50;
pSNR[2] = 0x30;
}
} else {
pSNR[0] = pSNR[1] = pSNR[2] = 0x40;
if (y > 3 && y < H-3 && (W-1-x) % 16 >3 && x % 2 == 0) {
pSNR[0] = pSNR[1] = pSNR[2] = 0x40;
} else {
pSNR[0] = pSNR[1] = pSNR[2] = 0x20;
}
}
logpow = log(4*Power[(int)((99-x)*60/44100.0 * FFTLen)]);
LoBin = (int)((W-1-x)*(6000/W)/44100.0 * FFTLen);
HiBin = (int)((W -x)*(6000/W)/44100.0 * FFTLen);
if (logpow > (19-y)/2.0) {
pPWR[1] = 0xaa;
pPWR[2] = 0xff;
pPWR[0] = 0x33;
} else {
pPWR[0] = pPWR[1] = pPWR[2] = 0;
logpow = 0;
for (i=LoBin; i<HiBin; i++) logpow += log(850*Power[i]) / 2;
p = (H-1-y)/(H/23.0);
pPWR[0] = pPWR[1] = pPWR[2] = 0;
if (logpow > p) {
pPWR[0] = clip(pPWR[0] + 0x22 * (logpow-p) / (HiBin-LoBin+1));
pPWR[1] = clip(pPWR[1] + 0x66 * (logpow-p) / (HiBin-LoBin+1));
pPWR[2] = clip(pPWR[2] + 0x22 * (logpow-p) / (HiBin-LoBin+1));
}
/*if (ShowWin && LoBin >= GetBin(1200+CurrentPic.HedrShift, FFTLen) &&
HiBin <= GetBin(2300+CurrentPic.HedrShift, FFTLen)) {
pPWR[0] = clip(pPWR[0] + 0x66);
pPWR[1] = clip(pPWR[1] + 0x11);
pPWR[2] = clip(pPWR[2] + 0x11);
}*/
}
}

Wyświetl plik

@ -228,8 +228,8 @@ int main(int argc, char *argv[]) {
}
memset(fft.in, 0, sizeof(double) * 2048);
Plan1024 = fftw_plan_dft_r2c_1d(1024, fft.in, fft.out, FFTW_ESTIMATE);
Plan2048 = fftw_plan_dft_r2c_1d(2048, fft.in, fft.out, FFTW_ESTIMATE);
fft.Plan1024 = fftw_plan_dft_r2c_1d(1024, fft.in, fft.out, FFTW_ESTIMATE);
fft.Plan2048 = fftw_plan_dft_r2c_1d(2048, fft.in, fft.out, FFTW_ESTIMATE);
createGUI();
populateDeviceList();

25
video.c
Wyświetl plik

@ -24,7 +24,7 @@ gboolean GetVideo(guchar Mode, double Rate, int Skip, gboolean Redraw) {
guint SyncSampleNum;
guint i=0, j=0;
guint FFTLen=1024, WinLength=0;
guint LopassBin,SyncTargetBin;
guint SyncTargetBin;
int SampleNum, Length, NumChans;
int x = 0, y = 0, tx=0, k=0;
double Hann[7][1024] = {{0}};
@ -175,7 +175,6 @@ gboolean GetVideo(guchar Mode, double Rate, int Skip, gboolean Redraw) {
Length = ModeSpec[Mode].LineLen * ModeSpec[Mode].ImgHeight * 44100;
SyncTargetBin = GetBin(1200+CurrentPic.HedrShift, FFTLen);
LopassBin = GetBin(5000, FFTLen);
Abort = FALSE;
SyncSampleNum = 0;
@ -200,23 +199,20 @@ gboolean GetVideo(guchar Mode, double Rate, int Skip, gboolean Redraw) {
// Hann window
for (i = 0; i < 64; i++) fft.in[i] = pcm.Buffer[pcm.WindowPtr+i-32] / 32768.0 * Hann[1][i];
fftw_execute(Plan1024);
fftw_execute(fft.Plan1024);
for (i=0;i<LopassBin;i++) {
if (i >= GetBin(1500+CurrentPic.HedrShift, FFTLen) && i <= GetBin(2300+CurrentPic.HedrShift, FFTLen))
Praw += power(fft.out[i]);
for (i=GetBin(1500+CurrentPic.HedrShift,FFTLen); i<=GetBin(2300+CurrentPic.HedrShift, FFTLen); i++)
Praw += power(fft.out[i]);
if (i >= SyncTargetBin-1 && i <= SyncTargetBin+1)
Psync += power(fft.out[i]) * (1- .5*abs(SyncTargetBin-i));
}
for (i=SyncTargetBin-1; i<=SyncTargetBin+1; i++)
Psync += power(fft.out[i]) * (1- .5*abs(SyncTargetBin-i));
Praw /= (GetBin(2300+CurrentPic.HedrShift, FFTLen) - GetBin(1500+CurrentPic.HedrShift, FFTLen));
Psync /= 2.0;
// If there is more than twice the amount of power per Hz in the
// sync band than in the video band, we have a sync signal here
if (Psync > 2*Praw) HasSync[SyncSampleNum] = TRUE;
else HasSync[SyncSampleNum] = FALSE;
HasSync[SyncSampleNum] = (Psync > 2*Praw);
NextSyncTime += 13;
SyncSampleNum ++;
@ -230,12 +226,11 @@ gboolean GetVideo(guchar Mode, double Rate, int Skip, gboolean Redraw) {
if (SampleNum == NextSNRtime) {
memset(fft.in, 0, sizeof(double)*FFTLen);
memset(fft.out, 0, sizeof(double)*FFTLen);
// Apply Hann window
for (i = 0; i < FFTLen; i++) fft.in[i] = pcm.Buffer[pcm.WindowPtr + i - FFTLen/2] / 32768.0 * Hann[6][i];
fftw_execute(Plan1024);
fftw_execute(fft.Plan1024);
// Calculate video-plus-noise power (1500-2300 Hz)
@ -301,7 +296,7 @@ gboolean GetVideo(guchar Mode, double Rate, int Skip, gboolean Redraw) {
WinLength = HannLens[WinIdx];
for (i = 0; i < WinLength; i++) fft.in[i] = pcm.Buffer[pcm.WindowPtr + i - WinLength/2] / 32768.0 * Hann[WinIdx][i];
fftw_execute(Plan1024);
fftw_execute(fft.Plan1024);
MaxBin = 0;
@ -400,7 +395,7 @@ gboolean GetVideo(guchar Mode, double Rate, int Skip, gboolean Redraw) {
} /* endif (SampleNum == PixelGrid[PixelIdx].Time) */
if (!Redraw && SampleNum % 8820 == 0) {
setVU(Power, FFTLen, WinIdx);
setVU(Power, FFTLen, WinIdx, TRUE);
}
if (Abort) return FALSE;

6
vis.c
Wyświetl plik

@ -48,7 +48,7 @@ guchar GetVIS () {
for (i = 0; i < 882; i++) fft.in[i] = pcm.Buffer[pcm.WindowPtr + i - 441] / 32768.0 * Hann[i];
// FFT of last 20 ms
fftw_execute(Plan2048);
fftw_execute(fft.Plan2048);
// Find the bin with most power
MaxBin = 0;
@ -157,8 +157,8 @@ guchar GetVIS () {
break;
}
if (++ptr == 25) {
setVU(Power, 2048, 6);
if (++ptr == 10) {
setVU(Power, 2048, 6, FALSE);
ptr = 0;
}