slowrx/common.c

163 wiersze
4.3 KiB
C
Czysty Zwykły widok Historia

2011-07-07 14:09:57 +00:00
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
2011-07-29 20:09:42 +00:00
#include <gtk/gtk.h>
#include <alsa/asoundlib.h>
2011-07-07 14:09:57 +00:00
#include "common.h"
2011-08-11 11:48:35 +00:00
guchar VISmap[128];
gint16 PcmBuffer[2048] = {0};
2011-08-08 21:36:47 +00:00
double *PCM = NULL;
int PcmPointer = 0;
int Sample = 0;
unsigned int SRate = 44100;
double *StoredFreq = NULL;
2011-08-11 11:48:35 +00:00
guint StoredFreqRate = 0;
gshort HedrShift = 0;
2011-08-10 20:43:17 +00:00
int PWRdBthresh[10] = {0, -3, -5, -10, -15, -20, -25, -30, -40, -50};
2011-08-08 21:36:47 +00:00
int SNRdBthresh[10] = {30, 15, 10, 5, 3, 0, -3, -5, -10, -15};
2011-08-11 11:48:35 +00:00
gboolean Adaptive = TRUE;
gboolean ManualActivated = FALSE;
gboolean Abort = FALSE;
2011-08-12 20:06:23 +00:00
gboolean *HasSync = NULL;
2011-08-08 21:36:47 +00:00
GtkWidget *mainwindow = NULL;
GtkWidget *notebook = NULL;
GdkPixbuf *RxPixbuf = NULL;
GdkPixbuf *DispPixbuf = NULL;
GtkWidget *RxImage = NULL;
GtkWidget *statusbar = NULL;
GtkWidget *snrbar = NULL;
GtkWidget *pwrbar = NULL;
GtkWidget *vugrid = NULL;
2011-08-10 20:43:17 +00:00
GdkPixbuf *pixbufPWR = NULL;
GdkPixbuf *pixbufSNR = NULL;
2011-08-08 21:36:47 +00:00
GtkWidget *infolabel = NULL;
GtkWidget *aboutdialog = NULL;
2011-08-10 20:43:17 +00:00
GtkWidget *prefdialog = NULL;
2011-08-08 21:36:47 +00:00
GtkWidget *sdialog = NULL;
GtkWidget *cardcombo = NULL;
2011-08-10 20:43:17 +00:00
GtkWidget *modecombo = NULL;
GtkWidget *togslant = NULL;
GtkWidget *togsave = NULL;
GtkWidget *togadapt = NULL;
GtkWidget *togrx = NULL;
2011-08-12 20:06:23 +00:00
GtkWidget *togfsk = NULL;
2011-08-10 20:43:17 +00:00
GtkWidget *btnabort = NULL;
GtkWidget *btnstart = NULL;
GtkWidget *manualframe = NULL;
GtkWidget *shiftspin = NULL;
GtkWidget *pwrimage = NULL;
GtkWidget *snrimage = NULL;
2011-08-12 20:06:23 +00:00
GtkWidget *idlabel = NULL;
2011-08-08 21:36:47 +00:00
snd_pcm_t *pcm_handle = NULL;
2011-07-29 20:09:42 +00:00
2011-08-12 09:33:49 +00:00
// Draw a fancy gradient
2011-08-11 11:48:35 +00:00
void ClearPixbuf(GdkPixbuf *pb, gushort width, gushort height) {
2011-07-07 14:09:57 +00:00
2011-08-11 11:48:35 +00:00
guint x,y,rowstride;
2011-07-07 14:09:57 +00:00
guchar *pixels, *p;
rowstride = gdk_pixbuf_get_rowstride (pb);
pixels = gdk_pixbuf_get_pixels(pb);
for (y = 0; y < height; y++) {
for (x = 0; x < width; x++) {
p = pixels + y * rowstride + x * 3;
2011-08-10 20:43:17 +00:00
p[0] = p[2] = p[1] = 96 + (1.0*y/height) * 32;
2011-07-07 14:09:57 +00:00
}
}
}
// Return the bin index matching the given frequency
2011-08-11 11:48:35 +00:00
guint GetBin (double Freq, int FFTLen) {
2011-07-29 20:09:42 +00:00
return (Freq / SRATE * FFTLen);
2011-07-07 14:09:57 +00:00
}
// Clip to [0..255]
2011-08-11 11:48:35 +00:00
guchar clip (double a) {
2011-07-07 14:09:57 +00:00
if (a < 0) return 0;
else if (a > 255) return 255;
return (unsigned char)round(a);
}
2011-08-12 09:33:49 +00:00
// Draw signal level meters according to given values
2011-08-10 20:43:17 +00:00
void setVU (short int PcmValue, double SNRdB) {
int x,y;
2011-08-08 21:36:47 +00:00
int PWRdB = (int)round(10 * log10(pow(PcmValue/32767.0,2)));
2011-08-12 09:33:49 +00:00
guchar *pixelsPWR, *pixelsSNR, *pPWR, *pSNR;
2011-08-10 20:43:17 +00:00
unsigned int rowstridePWR,rowstrideSNR;
rowstridePWR = gdk_pixbuf_get_rowstride (pixbufPWR);
pixelsPWR = gdk_pixbuf_get_pixels (pixbufPWR);
rowstrideSNR = gdk_pixbuf_get_rowstride (pixbufSNR);
pixelsSNR = gdk_pixbuf_get_pixels (pixbufSNR);
for (y=0; y<20; y++) {
for (x=0; x<100; x++) {
2011-08-12 09:33:49 +00:00
pPWR = pixelsPWR + y * rowstridePWR + (99-x) * 3;
pSNR = pixelsSNR + y * rowstrideSNR + (99-x) * 3;
2011-08-10 20:43:17 +00:00
2011-08-12 09:33:49 +00:00
if (y > 1 && y < 18 && x % 10 > 1 && x % 10 < 8 && x % 2 == 0 && y % 2 == 0) {
2011-08-10 20:43:17 +00:00
2011-08-12 09:33:49 +00:00
if (PWRdB >= PWRdBthresh[x/10]) {
pPWR[0] = 0x39;
pPWR[1] = 0xde;
pPWR[2] = 0xd4;
} else {
pPWR[0] = pPWR[1] = pPWR[2] = 0x80;
}
if (SNRdB >= SNRdBthresh[x/10]) {
pSNR[0] = 0xef;
pSNR[1] = 0xe4;
pSNR[2] = 0x34;
} else {
pSNR[0] = pSNR[1] = pSNR[2] = 0x80;
}
2011-08-10 20:43:17 +00:00
} else {
2011-08-12 09:33:49 +00:00
pPWR[0] = pPWR[1] = pPWR[2] = 0x40;
pSNR[0] = pSNR[1] = pSNR[2] = 0x40;
2011-08-10 20:43:17 +00:00
}
2011-08-12 09:33:49 +00:00
2011-08-10 20:43:17 +00:00
}
}
2011-07-07 14:09:57 +00:00
gdk_threads_enter();
2011-08-10 20:43:17 +00:00
gtk_image_set_from_pixbuf(GTK_IMAGE(pwrimage), pixbufPWR);
gtk_image_set_from_pixbuf(GTK_IMAGE(snrimage), pixbufSNR);
2011-07-07 14:09:57 +00:00
gdk_threads_leave();
}
2011-08-12 09:33:49 +00:00
// Convert degrees -> radians
2011-07-07 14:09:57 +00:00
double deg2rad (double Deg) {
2011-08-10 20:43:17 +00:00
return (Deg / 180) * M_PI;
2011-07-07 14:09:57 +00:00
}
2011-08-02 23:42:56 +00:00
2011-08-12 09:33:49 +00:00
// Quit
2011-08-02 23:42:56 +00:00
void delete_event() {
gtk_main_quit ();
}
2011-08-10 20:43:17 +00:00
2011-08-12 09:33:49 +00:00
// Transform the NoiseAdapt toggle state into a variable
2011-08-10 20:43:17 +00:00
void GetAdaptive() {
Adaptive = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(togadapt));
}
2011-08-12 09:33:49 +00:00
// Manual Start clicked
2011-08-10 20:43:17 +00:00
void ManualStart() {
ManualActivated = TRUE;
2011-08-11 11:48:35 +00:00
}
2011-08-12 09:33:49 +00:00
// Abort clicked
2011-08-11 11:48:35 +00:00
void AbortRx() {
Abort = TRUE;
2011-08-10 20:43:17 +00:00
}