kopia lustrzana https://github.com/windytan/slowrx
rodzic
657fd58940
commit
cf34bf5f45
|
@ -1,20 +1,3 @@
|
||||||
slowrx
|
slowrx
|
||||||
rx
|
rx
|
||||||
rx-lum
|
rx-lum
|
||||||
Makefile.in
|
|
||||||
/autom4te.cache
|
|
||||||
/aclocal.m4
|
|
||||||
/compile
|
|
||||||
/configure
|
|
||||||
/depcomp
|
|
||||||
/install-sh
|
|
||||||
/missing
|
|
||||||
/stamp-h1
|
|
||||||
Makefile
|
|
||||||
autoscan.log
|
|
||||||
config.h
|
|
||||||
config.h.in
|
|
||||||
config.log
|
|
||||||
config.status
|
|
||||||
configure.scan
|
|
||||||
.deps
|
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
AC_INIT([slowrx], [0.1], [oona@kapsi.fi])
|
AC_INIT([slowrx], [0.1], [oona@kapsi.fi])
|
||||||
AM_INIT_AUTOMAKE([-Wall -Werror foreign])
|
AM_INIT_AUTOMAKE([-Wall -Werror foreign])
|
||||||
AX_CXX_COMPILE_STDCXX_11()
|
|
||||||
AC_PROG_CXX
|
AC_PROG_CXX
|
||||||
AC_CONFIG_HEADERS([config.h])
|
AC_CONFIG_HEADERS([config.h])
|
||||||
AC_CONFIG_FILES([
|
AC_CONFIG_FILES([
|
||||||
Makefile
|
Makefile
|
||||||
src/uus/Makefile
|
src/Makefile
|
||||||
])
|
])
|
||||||
PKG_CHECK_MODULES([GTKMM], [gtkmm-3.0 >= 3.8.0])
|
PKG_CHECK_MODULES([GTKMM], [gtkmm-3.0 >= 3.8.0])
|
||||||
AC_OUTPUT
|
AC_OUTPUT
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
bin_PROGRAMS = slowrx
|
bin_PROGRAMS = slowrx
|
||||||
slowrx_CPPFLAGS = $(GTKMM_CFLAGS)
|
slowrx_CPPFLAGS = $(GTKMM_CFLAGS)
|
||||||
slowrx_LDADD = $(GTKMM_LIBS)
|
slowrx_LDADD = $(GTKMM_LIBS)
|
||||||
slowrx_SOURCES = slowrx.cc modespec.cc
|
slowrx_SOURCES = slowrx.cc common.cc gui.cc fsk.cc modespec.cc pcm.cc sync.cc video.cc vis.cc
|
||||||
|
|
113
src/common.h
113
src/common.h
|
@ -6,6 +6,15 @@
|
||||||
#define BUFLEN 4096
|
#define BUFLEN 4096
|
||||||
#define SYNCPIXLEN 1.5e-3
|
#define SYNCPIXLEN 1.5e-3
|
||||||
|
|
||||||
|
extern gboolean Abort;
|
||||||
|
extern gboolean Adaptive;
|
||||||
|
extern gboolean *HasSync;
|
||||||
|
extern gboolean ManualActivated;
|
||||||
|
extern gboolean ManualResync;
|
||||||
|
extern guchar *StoredLum;
|
||||||
|
extern pthread_t thread1;
|
||||||
|
extern guchar VISmap[];
|
||||||
|
|
||||||
typedef struct _FFTStuff FFTStuff;
|
typedef struct _FFTStuff FFTStuff;
|
||||||
struct _FFTStuff {
|
struct _FFTStuff {
|
||||||
double *in;
|
double *in;
|
||||||
|
@ -17,51 +26,49 @@ extern FFTStuff fft;
|
||||||
|
|
||||||
typedef struct _PcmData PcmData;
|
typedef struct _PcmData PcmData;
|
||||||
struct _PcmData {
|
struct _PcmData {
|
||||||
// snd_pcm_t *handle;
|
snd_pcm_t *handle;
|
||||||
void *handle;
|
|
||||||
gint16 *Buffer;
|
gint16 *Buffer;
|
||||||
int WindowPtr;
|
int WindowPtr;
|
||||||
gboolean BufferDrop;
|
gboolean BufferDrop;
|
||||||
};
|
};
|
||||||
//extern PcmData pcm;
|
extern PcmData pcm;
|
||||||
|
|
||||||
typedef struct _GuiObjs GuiObjs;
|
typedef struct _GuiObjs GuiObjs;
|
||||||
struct _GuiObjs {
|
struct _GuiObjs {
|
||||||
Gtk::Button *button_abort;
|
GtkWidget *button_abort;
|
||||||
Gtk::Button *button_browse;
|
GtkWidget *button_browse;
|
||||||
Gtk::Button *button_clear;
|
GtkWidget *button_clear;
|
||||||
Gtk::Button *button_start;
|
GtkWidget *button_start;
|
||||||
Gtk::ComboBox *combo_card;
|
GtkWidget *combo_card;
|
||||||
Gtk::ComboBox *combo_mode;
|
GtkWidget *combo_mode;
|
||||||
Gtk::Widget *entry_picdir;
|
GtkWidget *entry_picdir;
|
||||||
Gtk::Widget *eventbox_img;
|
GtkWidget *eventbox_img;
|
||||||
Gtk::Widget *frame_manual;
|
GtkWidget *frame_manual;
|
||||||
Gtk::Widget *frame_slant;
|
GtkWidget *frame_slant;
|
||||||
Gtk::Widget *grid_vu;
|
GtkWidget *grid_vu;
|
||||||
Gtk::Widget *iconview;
|
GtkWidget *iconview;
|
||||||
Gtk::Widget *image_devstatus;
|
GtkWidget *image_devstatus;
|
||||||
Gtk::Widget *image_pwr;
|
GtkWidget *image_pwr;
|
||||||
Gtk::Widget *image_rx;
|
GtkWidget *image_rx;
|
||||||
Gtk::Widget *image_snr;
|
GtkWidget *image_snr;
|
||||||
Gtk::Label *label_fskid;
|
GtkWidget *label_fskid;
|
||||||
Gtk::Label *label_lastmode;
|
GtkWidget *label_lastmode;
|
||||||
Gtk::Label *label_utc;
|
GtkWidget *label_utc;
|
||||||
Gtk::MenuItem *menuitem_about;
|
GtkWidget *menuitem_about;
|
||||||
Gtk::MenuItem *menuitem_quit;
|
GtkWidget *menuitem_quit;
|
||||||
Gtk::SpinButton *spin_shift;
|
GtkWidget *spin_shift;
|
||||||
Gtk::Widget *statusbar;
|
GtkWidget *statusbar;
|
||||||
Gtk::ToggleButton *tog_adapt;
|
GtkWidget *tog_adapt;
|
||||||
Gtk::ToggleButton *tog_fsk;
|
GtkWidget *tog_fsk;
|
||||||
Gtk::ToggleButton *tog_rx;
|
GtkWidget *tog_rx;
|
||||||
Gtk::ToggleButton *tog_save;
|
GtkWidget *tog_save;
|
||||||
Gtk::ToggleButton *tog_setedge;
|
GtkWidget *tog_setedge;
|
||||||
Gtk::ToggleButton *tog_slant;
|
GtkWidget *tog_slant;
|
||||||
Gtk::Window *window_about;
|
GtkWidget *window_about;
|
||||||
Gtk::Window *window_main;
|
GtkWidget *window_main;
|
||||||
};
|
};
|
||||||
extern GuiObjs gui;
|
extern GuiObjs gui;
|
||||||
|
|
||||||
/*
|
|
||||||
extern GdkPixbuf *pixbuf_PWR;
|
extern GdkPixbuf *pixbuf_PWR;
|
||||||
extern GdkPixbuf *pixbuf_SNR;
|
extern GdkPixbuf *pixbuf_SNR;
|
||||||
extern GdkPixbuf *pixbuf_rx;
|
extern GdkPixbuf *pixbuf_rx;
|
||||||
|
@ -69,13 +76,13 @@ extern GdkPixbuf *pixbuf_disp;
|
||||||
|
|
||||||
extern GtkListStore *savedstore;
|
extern GtkListStore *savedstore;
|
||||||
|
|
||||||
extern GKeyFile *config;*/
|
extern GKeyFile *config;
|
||||||
|
|
||||||
|
|
||||||
typedef struct _PicMeta PicMeta;
|
typedef struct _PicMeta PicMeta;
|
||||||
struct _PicMeta {
|
struct _PicMeta {
|
||||||
int HedrShift;
|
gshort HedrShift;
|
||||||
int Mode;
|
guchar Mode;
|
||||||
double Rate;
|
double Rate;
|
||||||
int Skip;
|
int Skip;
|
||||||
GdkPixbuf *thumbbuf;
|
GdkPixbuf *thumbbuf;
|
||||||
|
@ -100,36 +107,36 @@ enum {
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct ModeSpec {
|
typedef struct ModeSpec {
|
||||||
std::string Name;
|
char *Name;
|
||||||
std::string ShortName;
|
char *ShortName;
|
||||||
double SyncTime;
|
double SyncTime;
|
||||||
double PorchTime;
|
double PorchTime;
|
||||||
double SeptrTime;
|
double SeptrTime;
|
||||||
double PixelTime;
|
double PixelTime;
|
||||||
double LineTime;
|
double LineTime;
|
||||||
int ImgWidth;
|
gushort ImgWidth;
|
||||||
int NumLines;
|
gushort NumLines;
|
||||||
int LineHeight;
|
guchar LineHeight;
|
||||||
int ColorEnc;
|
guchar ColorEnc;
|
||||||
} _ModeSpec;
|
} _ModeSpec;
|
||||||
|
|
||||||
extern _ModeSpec ModeSpec[];
|
extern _ModeSpec ModeSpec[];
|
||||||
|
|
||||||
double power (fftw_complex coeff);
|
double power (fftw_complex coeff);
|
||||||
int clip (double a);
|
guchar clip (double a);
|
||||||
void createGUI ();
|
void createGUI ();
|
||||||
double deg2rad (double Deg);
|
double deg2rad (double Deg);
|
||||||
double FindSync (int Mode, double Rate, int *Skip);
|
double FindSync (guchar Mode, double Rate, int *Skip);
|
||||||
void GetFSK (char *dest);
|
void GetFSK (char *dest);
|
||||||
bool GetVideo (int Mode, double Rate, int Skip, bool Redraw);
|
gboolean GetVideo (guchar Mode, double Rate, int Skip, gboolean Redraw);
|
||||||
int GetVIS ();
|
guchar GetVIS ();
|
||||||
int GetBin (double Freq, int FFTLen);
|
guint GetBin (double Freq, guint FFTLen);
|
||||||
int initPcmDevice (char *);
|
int initPcmDevice ();
|
||||||
void *Listen ();
|
void *Listen ();
|
||||||
void populateDeviceList ();
|
void populateDeviceList ();
|
||||||
void readPcm (int numsamples);
|
void readPcm (gint numsamples);
|
||||||
void saveCurrentPic();
|
void saveCurrentPic();
|
||||||
void setVU (double *Power, int FFTLen, int WinIdx, bool ShowWin);
|
void setVU (double *Power, int FFTLen, int WinIdx, gboolean ShowWin);
|
||||||
|
|
||||||
void evt_AbortRx ();
|
void evt_AbortRx ();
|
||||||
void evt_changeDevices ();
|
void evt_changeDevices ();
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
#include <gtkmm.h>
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
#include <alsa/asoundlib.h>
|
||||||
|
|
||||||
#include <fftw3.h>
|
#include <fftw3.h>
|
||||||
|
|
||||||
|
|
265
src/slowrx.cc
265
src/slowrx.cc
|
@ -1,21 +1,256 @@
|
||||||
#include <gtkmm.h>
|
/*
|
||||||
|
* slowrx - an SSTV decoder
|
||||||
|
* * * * * * * * * * * * * *
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#include <alsa/asoundlib.h>
|
||||||
|
|
||||||
#include <fftw3.h>
|
#include <fftw3.h>
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
int startGui (int, char**);
|
// The thread that listens to VIS headers and calls decoders etc
|
||||||
|
void *Listen() {
|
||||||
|
|
||||||
|
char rctime[8];
|
||||||
|
|
||||||
|
guchar Mode=0;
|
||||||
|
struct tm *timeptr = NULL;
|
||||||
|
time_t timet;
|
||||||
|
gboolean Finished;
|
||||||
|
char id[20];
|
||||||
|
GtkTreeIter iter;
|
||||||
|
|
||||||
|
while (TRUE) {
|
||||||
|
|
||||||
|
gdk_threads_enter ();
|
||||||
|
gtk_widget_set_sensitive (gui.grid_vu, TRUE);
|
||||||
|
gtk_widget_set_sensitive (gui.button_abort, FALSE);
|
||||||
|
gtk_widget_set_sensitive (gui.button_clear, TRUE);
|
||||||
|
gdk_threads_leave ();
|
||||||
|
|
||||||
|
pcm.WindowPtr = 0;
|
||||||
|
snd_pcm_prepare(pcm.handle);
|
||||||
|
snd_pcm_start (pcm.handle);
|
||||||
|
Abort = FALSE;
|
||||||
|
|
||||||
|
do {
|
||||||
|
|
||||||
|
// Wait for VIS
|
||||||
|
Mode = GetVIS();
|
||||||
|
|
||||||
|
// Stop listening on ALSA error
|
||||||
|
if (Abort) pthread_exit(NULL);
|
||||||
|
|
||||||
|
// If manual resync was requested, redraw image
|
||||||
|
if (ManualResync) {
|
||||||
|
ManualResync = FALSE;
|
||||||
|
snd_pcm_drop(pcm.handle);
|
||||||
|
printf("getvideo at %.2f skip %d\n",CurrentPic.Rate,CurrentPic.Skip);
|
||||||
|
GetVideo(CurrentPic.Mode, CurrentPic.Rate, CurrentPic.Skip, TRUE);
|
||||||
|
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(gui.tog_save)))
|
||||||
|
saveCurrentPic();
|
||||||
|
pcm.WindowPtr = 0;
|
||||||
|
snd_pcm_prepare(pcm.handle);
|
||||||
|
snd_pcm_start (pcm.handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
} while (Mode == 0);
|
||||||
|
|
||||||
|
// Start reception
|
||||||
|
|
||||||
|
CurrentPic.Rate = 44100;
|
||||||
|
CurrentPic.Mode = Mode;
|
||||||
|
|
||||||
|
printf(" ==== %s ====\n", ModeSpec[CurrentPic.Mode].Name);
|
||||||
|
|
||||||
|
// Store time of reception
|
||||||
|
timet = time(NULL);
|
||||||
|
timeptr = gmtime(&timet);
|
||||||
|
strftime(CurrentPic.timestr, sizeof(CurrentPic.timestr)-1,"%Y%m%d-%H%M%Sz", timeptr);
|
||||||
|
|
||||||
|
|
||||||
|
// Allocate space for cached Lum
|
||||||
|
free(StoredLum);
|
||||||
|
StoredLum = calloc( (int)((ModeSpec[CurrentPic.Mode].LineTime * ModeSpec[CurrentPic.Mode].NumLines + 1) * 44100), sizeof(guchar));
|
||||||
|
if (StoredLum == NULL) {
|
||||||
|
perror("Listen: Unable to allocate memory for Lum");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allocate space for sync signal
|
||||||
|
HasSync = calloc((int)(ModeSpec[CurrentPic.Mode].LineTime * ModeSpec[CurrentPic.Mode].NumLines / (13.0/44100) +1), sizeof(gboolean));
|
||||||
|
if (HasSync == NULL) {
|
||||||
|
perror("Listen: Unable to allocate memory for sync signal");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get video
|
||||||
|
strftime(rctime, sizeof(rctime)-1, "%H:%Mz", timeptr);
|
||||||
|
gdk_threads_enter ();
|
||||||
|
gtk_label_set_text (GTK_LABEL(gui.label_fskid), "");
|
||||||
|
gtk_widget_set_sensitive (gui.frame_manual, FALSE);
|
||||||
|
gtk_widget_set_sensitive (gui.frame_slant, FALSE);
|
||||||
|
gtk_widget_set_sensitive (gui.combo_card, FALSE);
|
||||||
|
gtk_widget_set_sensitive (gui.button_abort, TRUE);
|
||||||
|
gtk_widget_set_sensitive (gui.button_clear, FALSE);
|
||||||
|
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(gui.tog_setedge), FALSE);
|
||||||
|
gtk_statusbar_push (GTK_STATUSBAR(gui.statusbar), 0, "Receiving video..." );
|
||||||
|
gtk_label_set_markup (GTK_LABEL(gui.label_lastmode), ModeSpec[CurrentPic.Mode].Name);
|
||||||
|
gtk_label_set_markup (GTK_LABEL(gui.label_utc), rctime);
|
||||||
|
gdk_threads_leave ();
|
||||||
|
printf(" getvideo @ %.1f Hz, Skip %d, HedrShift %+d Hz\n", 44100.0, 0, CurrentPic.HedrShift);
|
||||||
|
|
||||||
|
Finished = GetVideo(CurrentPic.Mode, 44100, 0, FALSE);
|
||||||
|
|
||||||
|
gdk_threads_enter ();
|
||||||
|
gtk_widget_set_sensitive (gui.button_abort, FALSE);
|
||||||
|
gdk_threads_leave ();
|
||||||
|
|
||||||
|
id[0] = '\0';
|
||||||
|
|
||||||
|
if (Finished && gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gui.tog_fsk))) {
|
||||||
|
gdk_threads_enter ();
|
||||||
|
gtk_statusbar_push (GTK_STATUSBAR(gui.statusbar), 0, "Receiving FSK ID..." );
|
||||||
|
gdk_threads_leave ();
|
||||||
|
GetFSK(id);
|
||||||
|
printf(" FSKID \"%s\"\n",id);
|
||||||
|
gdk_threads_enter ();
|
||||||
|
gtk_label_set_text (GTK_LABEL(gui.label_fskid), id);
|
||||||
|
gdk_threads_leave ();
|
||||||
|
}
|
||||||
|
|
||||||
|
snd_pcm_drop(pcm.handle);
|
||||||
|
|
||||||
|
if (Finished && gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gui.tog_slant))) {
|
||||||
|
|
||||||
|
// Fix slant
|
||||||
|
//setVU(0,6);
|
||||||
|
gdk_threads_enter ();
|
||||||
|
gtk_statusbar_push (GTK_STATUSBAR(gui.statusbar), 0, "Calculating slant..." );
|
||||||
|
gtk_widget_set_sensitive (gui.grid_vu, FALSE);
|
||||||
|
gdk_threads_leave ();
|
||||||
|
printf(" FindSync @ %.1f Hz\n",CurrentPic.Rate);
|
||||||
|
CurrentPic.Rate = FindSync(CurrentPic.Mode, CurrentPic.Rate, &CurrentPic.Skip);
|
||||||
|
|
||||||
|
// Final image
|
||||||
|
printf(" getvideo @ %.1f Hz, Skip %d, HedrShift %+d Hz\n", CurrentPic.Rate, CurrentPic.Skip, CurrentPic.HedrShift);
|
||||||
|
GetVideo(CurrentPic.Mode, CurrentPic.Rate, CurrentPic.Skip, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
free (HasSync);
|
||||||
|
HasSync = NULL;
|
||||||
|
|
||||||
|
// Add thumbnail to iconview
|
||||||
|
CurrentPic.thumbbuf = gdk_pixbuf_scale_simple (pixbuf_rx, 100,
|
||||||
|
100.0/ModeSpec[CurrentPic.Mode].ImgWidth * ModeSpec[CurrentPic.Mode].NumLines * ModeSpec[CurrentPic.Mode].LineHeight, GDK_INTERP_HYPER);
|
||||||
|
gdk_threads_enter ();
|
||||||
|
gtk_list_store_prepend (savedstore, &iter);
|
||||||
|
gtk_list_store_set (savedstore, &iter, 0, CurrentPic.thumbbuf, 1, id, -1);
|
||||||
|
gdk_threads_leave ();
|
||||||
|
|
||||||
|
// Save PNG
|
||||||
|
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(gui.tog_save))) {
|
||||||
|
|
||||||
|
//setVU(0,6);
|
||||||
|
|
||||||
|
/*ensure_dir_exists("rx-lum");
|
||||||
|
LumFile = fopen(lumfilename,"w");
|
||||||
|
if (LumFile == NULL)
|
||||||
|
perror("Unable to open luma file for writing");
|
||||||
|
fwrite(StoredLum,1,(ModeSpec[Mode].LineTime * ModeSpec[Mode].NumLines) * 44100,LumFile);
|
||||||
|
fclose(LumFile);*/
|
||||||
|
|
||||||
|
saveCurrentPic();
|
||||||
|
}
|
||||||
|
|
||||||
|
gdk_threads_enter ();
|
||||||
|
gtk_widget_set_sensitive (gui.frame_slant, TRUE);
|
||||||
|
gtk_widget_set_sensitive (gui.frame_manual, TRUE);
|
||||||
|
gtk_widget_set_sensitive (gui.combo_card, TRUE);
|
||||||
|
gdk_threads_leave ();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* main
|
||||||
|
*/
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
return startGui(argc, argv);
|
|
||||||
}
|
FILE *ConfFile;
|
||||||
|
const gchar *confdir;
|
||||||
int startGui(int argc, char *argv[]) {
|
GString *confpath;
|
||||||
Glib::RefPtr<Gtk::Application> app =
|
gchar *confdata;
|
||||||
Gtk::Application::create(argc, argv,
|
gsize *keylen=NULL;
|
||||||
"com.windytan.slowrx");
|
|
||||||
|
gtk_init (&argc, &argv);
|
||||||
Glib::RefPtr<Gtk::Builder> builder = Gtk::Builder::create_from_file("ui/slowrx.ui");
|
|
||||||
Gtk::Window *pWindow;
|
gdk_threads_init ();
|
||||||
builder->get_widget("window_main", pWindow);
|
|
||||||
|
// Load config
|
||||||
return app->run(*pWindow);
|
confdir = g_get_user_config_dir();
|
||||||
|
confpath = g_string_new(confdir);
|
||||||
|
g_string_append(confpath, "/slowrx.ini");
|
||||||
|
|
||||||
|
config = g_key_file_new();
|
||||||
|
if (g_key_file_load_from_file(config, confpath->str, G_KEY_FILE_KEEP_COMMENTS, NULL)) {
|
||||||
|
|
||||||
|
} else {
|
||||||
|
printf("No valid config file found\n");
|
||||||
|
g_key_file_load_from_data(config, "[slowrx]\ndevice=default", -1, G_KEY_FILE_NONE, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare FFT
|
||||||
|
fft.in = fftw_alloc_real(2048);
|
||||||
|
if (fft.in == NULL) {
|
||||||
|
perror("GetVideo: Unable to allocate memory for FFT");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
fft.out = fftw_alloc_complex(2048);
|
||||||
|
if (fft.out == NULL) {
|
||||||
|
perror("GetVideo: Unable to allocate memory for FFT");
|
||||||
|
fftw_free(fft.in);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
memset(fft.in, 0, sizeof(double) * 2048);
|
||||||
|
|
||||||
|
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();
|
||||||
|
|
||||||
|
gtk_main();
|
||||||
|
|
||||||
|
// Save config on exit
|
||||||
|
ConfFile = fopen(confpath->str,"w");
|
||||||
|
if (ConfFile == NULL) {
|
||||||
|
perror("Unable to open config file for writing");
|
||||||
|
} else {
|
||||||
|
confdata = g_key_file_to_data(config,keylen,NULL);
|
||||||
|
fprintf(ConfFile,"%s",confdata);
|
||||||
|
fwrite(confdata,1,(size_t)keylen,ConfFile);
|
||||||
|
fclose(ConfFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_object_unref(pixbuf_rx);
|
||||||
|
free(StoredLum);
|
||||||
|
fftw_free(fft.in);
|
||||||
|
fftw_free(fft.out);
|
||||||
|
|
||||||
|
return (EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
Ładowanie…
Reference in New Issue