2011-07-07 14:09:57 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
2011-08-20 11:49:29 +00:00
|
|
|
#include <stdbool.h>
|
2011-07-07 14:09:57 +00:00
|
|
|
#include <math.h>
|
|
|
|
|
2011-07-29 20:09:42 +00:00
|
|
|
#include <gtk/gtk.h>
|
|
|
|
#include <alsa/asoundlib.h>
|
2012-12-25 20:43:26 +00:00
|
|
|
|
2011-08-16 21:29:38 +00:00
|
|
|
#include <fftw3.h>
|
2011-07-29 20:09:42 +00:00
|
|
|
|
2011-07-07 14:09:57 +00:00
|
|
|
#include "common.h"
|
|
|
|
|
2011-08-16 21:29:38 +00:00
|
|
|
gint16 *PcmBuffer = NULL;
|
2011-08-08 21:36:47 +00:00
|
|
|
int PcmPointer = 0;
|
2011-08-20 05:51:27 +00:00
|
|
|
int MaxPcm = 0;
|
2011-08-18 00:04:28 +00:00
|
|
|
guchar *StoredLum = NULL;
|
2011-08-20 11:49:29 +00:00
|
|
|
bool *HasSync = NULL;
|
2011-08-16 21:29:38 +00:00
|
|
|
double *in = NULL;
|
|
|
|
double *out = NULL;
|
2011-08-11 11:48:35 +00:00
|
|
|
gshort HedrShift = 0;
|
2011-08-20 11:49:29 +00:00
|
|
|
bool Adaptive = true;
|
|
|
|
bool ManualActivated = false;
|
|
|
|
bool Abort = false;
|
2013-01-13 09:40:56 +00:00
|
|
|
bool BufferDrop = false;
|
2011-08-08 21:36:47 +00:00
|
|
|
|
2013-01-09 19:02:41 +00:00
|
|
|
pthread_t thread1;
|
|
|
|
|
2013-01-09 19:46:39 +00:00
|
|
|
GuiObjs gui;
|
|
|
|
|
2013-01-13 19:52:31 +00:00
|
|
|
GdkPixbuf *pixbuf_rx = NULL;
|
|
|
|
GdkPixbuf *pixbuf_disp = NULL;
|
|
|
|
GdkPixbuf *pixbuf_PWR = NULL;
|
|
|
|
GdkPixbuf *pixbuf_SNR = NULL;
|
2011-08-13 12:26:49 +00:00
|
|
|
|
|
|
|
GtkListStore *savedstore = NULL;
|
|
|
|
|
2013-01-09 19:02:41 +00:00
|
|
|
GKeyFile *keyfile = 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-16 21:29:38 +00:00
|
|
|
fftw_plan Plan1024 = NULL;
|
|
|
|
fftw_plan Plan2048 = NULL;
|
|
|
|
|
2011-08-20 05:51:27 +00:00
|
|
|
// Return the FFT bin index matching the given frequency
|
|
|
|
guint GetBin (double Freq, guint FFTLen) {
|
2011-08-16 21:29:38 +00:00
|
|
|
return (Freq / 44100 * 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;
|
2011-08-20 05:51:27 +00:00
|
|
|
return (guchar)round(a);
|
2011-07-07 14:09:57 +00:00
|
|
|
}
|
|
|
|
|
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
|
|
|
|
2013-01-13 19:18:10 +00:00
|
|
|
|
|
|
|
/*** Gtk+ event handlers ***/
|
|
|
|
|
|
|
|
|
2011-08-12 09:33:49 +00:00
|
|
|
// Quit
|
2013-01-13 19:48:20 +00:00
|
|
|
void evt_deletewindow() {
|
2011-08-02 23:42:56 +00:00
|
|
|
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
|
2013-01-13 19:48:20 +00:00
|
|
|
void evt_GetAdaptive() {
|
2013-01-13 19:18:10 +00:00
|
|
|
Adaptive = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(gui.tog_adapt));
|
2011-08-10 20:43:17 +00:00
|
|
|
}
|
|
|
|
|
2011-08-12 09:33:49 +00:00
|
|
|
// Manual Start clicked
|
2013-01-13 19:48:20 +00:00
|
|
|
void evt_ManualStart() {
|
2011-08-20 11:49:29 +00:00
|
|
|
ManualActivated = true;
|
2011-08-11 11:48:35 +00:00
|
|
|
}
|
|
|
|
|
2013-01-09 19:02:41 +00:00
|
|
|
// Abort clicked during rx
|
2013-01-13 19:48:20 +00:00
|
|
|
void evt_AbortRx() {
|
2011-08-20 11:49:29 +00:00
|
|
|
Abort = true;
|
2011-08-10 20:43:17 +00:00
|
|
|
}
|
2013-01-09 19:02:41 +00:00
|
|
|
|
|
|
|
// Another device selected from list
|
2013-01-13 19:48:20 +00:00
|
|
|
void evt_changeDevices() {
|
2013-01-09 19:02:41 +00:00
|
|
|
|
|
|
|
int status;
|
|
|
|
|
2013-01-13 09:40:56 +00:00
|
|
|
BufferDrop = false;
|
2013-01-09 19:02:41 +00:00
|
|
|
Abort = true;
|
|
|
|
|
|
|
|
pthread_join(thread1, NULL);
|
|
|
|
|
|
|
|
if (pcm_handle != NULL) snd_pcm_close(pcm_handle);
|
|
|
|
|
2013-01-13 19:18:10 +00:00
|
|
|
status = initPcmDevice(gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(gui.combo_card)));
|
2013-01-09 19:02:41 +00:00
|
|
|
|
|
|
|
|
|
|
|
switch(status) {
|
|
|
|
case 0:
|
2013-01-13 19:18:10 +00:00
|
|
|
gtk_image_set_from_stock(GTK_IMAGE(gui.image_devstatus),GTK_STOCK_YES,GTK_ICON_SIZE_SMALL_TOOLBAR);
|
|
|
|
gtk_widget_set_tooltip_text(gui.image_devstatus, "Device successfully opened");
|
2013-01-09 19:02:41 +00:00
|
|
|
break;
|
|
|
|
case -1:
|
2013-01-13 19:18:10 +00:00
|
|
|
gtk_image_set_from_stock(GTK_IMAGE(gui.image_devstatus),GTK_STOCK_DIALOG_WARNING,GTK_ICON_SIZE_SMALL_TOOLBAR);
|
|
|
|
gtk_widget_set_tooltip_text(gui.image_devstatus, "Device was opened, but doesn't support 44100 Hz");
|
2013-01-09 19:02:41 +00:00
|
|
|
break;
|
|
|
|
case -2:
|
2013-01-13 19:18:10 +00:00
|
|
|
gtk_image_set_from_stock(GTK_IMAGE(gui.image_devstatus),GTK_STOCK_DIALOG_ERROR,GTK_ICON_SIZE_SMALL_TOOLBAR);
|
|
|
|
gtk_widget_set_tooltip_text(gui.image_devstatus, "Failed to open device");
|
2013-01-09 19:02:41 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2013-01-13 19:18:10 +00:00
|
|
|
g_key_file_set_string(keyfile,"slowrx","device",gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(gui.combo_card)));
|
2013-01-09 19:02:41 +00:00
|
|
|
|
|
|
|
pthread_create (&thread1, NULL, Listen, NULL);
|
|
|
|
|
|
|
|
}
|
2013-01-13 18:49:42 +00:00
|
|
|
|
|
|
|
// Clear received picture & metadata
|
2013-01-13 19:48:20 +00:00
|
|
|
void evt_clearPix() {
|
2013-01-13 19:52:31 +00:00
|
|
|
gdk_pixbuf_fill (pixbuf_disp, 0);
|
|
|
|
gtk_image_set_from_pixbuf(GTK_IMAGE(gui.image_rx), pixbuf_disp);
|
2013-01-13 19:18:10 +00:00
|
|
|
gtk_label_set_markup (GTK_LABEL(gui.label_fskid), "");
|
|
|
|
gtk_label_set_markup (GTK_LABEL(gui.label_utc), "");
|
|
|
|
gtk_label_set_markup (GTK_LABEL(gui.label_lastmode), "");
|
2013-01-13 18:49:42 +00:00
|
|
|
}
|