kopia lustrzana https://github.com/windytan/slowrx
more fft display stuff; fft struct; etc
rodzic
d5cb9604eb
commit
f406f35cbb
3
common.c
3
common.c
|
@ -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);
|
||||
|
|
7
common.h
7
common.h
|
@ -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
2
fsk.c
|
@ -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
66
gui.c
|
@ -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);
|
||||
}*/
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
4
slowrx.c
4
slowrx.c
|
@ -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
25
video.c
|
@ -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
6
vis.c
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue