/* gpsk31 - PSK31 for Linux with a GTK+ Interface * Copyright (C) 2000 Luc Langehegermann, LX2GT * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program; if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, * USA. */ /* * Functions for the spectrum analizer */ #include #include #include #include #include #include #include #include #include #include #include "main_screen.h" #include "spectrum.h" #include "globals.h" #include "server.h" float luc; /* Position of the red line in the spectrum */ int ffts; /* Number of filters */ float centrefreq; /* Centre freq of the spectrum */ float fc; /* Currently RX freq */ float deltaf; /* Hz per fft sample */ int delta; /* Offset into ffts */ double max; /* Max value in values? */ int maxi; /* Index to max */ int row; /* First row in circular buffer */ int samples; /* Number of samles */ int cnt; float pwr[201]; /* Array where we put fft data */ GdkGC *gc_tune_line; /* GC's of the spectrum */ GdkGC *gc_spectrum; /* * setup for spectrum GC's */ void spectrum_setup () { GdkColor color; GdkColormap * cmap; cmap = gdk_colormap_get_system (); gdk_color_parse (ini_settings.spectrum_color, &color); if (!gdk_color_alloc (cmap, &color)) g_error ("Couldn't allocate color"); gc_spectrum = gdk_gc_new (main_screen.spectrum); gdk_gc_set_foreground (gc_spectrum, &color); gdk_color_parse (ini_settings.spectrum_tune_line_color, &color); if (!gdk_color_alloc (cmap, &color)) g_error ("Couldn't allocate color"); gc_tune_line = gdk_gc_new (main_screen.spectrum); gdk_gc_set_foreground (gc_tune_line, &color); //fft_setup (SAMPS , SPEED); /* HARD CODED FOR NOW? */ } /* * fft_setup - set fft values for sample sizes */ void fft_setup (int samps, int speed) { if (samps > 3000) gdk_gc_set_line_attributes (gc_tune_line, 2, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND); else gdk_gc_set_line_attributes (gc_tune_line, 1, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND); static int fftspeed=0; if(samps>0) { samples = samps; } float expo = 8+(100-speed)/99.0*3; // 8..11 fftspeed = (int)pow(2.0, expo); ffts = samples/2; deltaf = (float)8000 / samples; delta = (int)(fc / deltaf - 100); cnt = 0; commControl(COMM_FFTCH, COMM_FFTN, samples); commControl(COMM_FFTCH, COMM_FFTOVERLAP, fftspeed); } /* * new_fc - set new center frequency */ float spectrum_new_fc (int x) { fc = centrefreq + deltaf * (x - 100); return (fc); } void spectrum_updateFFT(float *val, int len) { if(len!=samples) { g_warning ("FFT length mismatch"); } spectrum_calc_power(val); spectrum_draw_display(); } /* * calc power - pwr array * just calculate power for the 200 we need. */ void spectrum_calc_power (float *buffer) { int i, j; for(i=delta,j=0; isamples/2) pwr[j]=0; else pwr[j] = buffer[i]; } } /* * draw_display method - draws display as spectrum or waterfall */ void spectrum_draw_display () { PSK31info rxinfo; int x; float my_value; gdk_draw_rectangle (main_screen.spectrum, main_screen.spectrum_drawing->style->black_gc, TRUE, 0, 0, main_screen.spectrum_drawing->allocation.width, main_screen.spectrum_drawing->allocation.height); for (x = 0; x < 200 ; x = x + 1) { my_value = (42.0 * (log10 (pwr[x] + 1))); gdk_draw_line (main_screen.spectrum, gc_spectrum, x, 100, x, 100 - (int) my_value); commGetInfo (COMM_RXCH, &rxinfo, sizeof(rxinfo)); luc = 100 + ((rxinfo.freq/100) - centrefreq) / deltaf + 0.5; gdk_draw_line (main_screen.spectrum, gc_tune_line, (int) luc, 100, (int) luc, 0); } gdk_draw_pixmap (main_screen.spectrum_drawing->window, main_screen.spectrum_drawing-> style->fg_gc[GTK_WIDGET_STATE (main_screen.spectrum_drawing)], main_screen.spectrum, 0, 0, 0, 0, 200, 100); } /* * offset method - sets delta to starting index value of values array */ void spectrum_offset (float freq) { fc = freq; centrefreq = freq; delta = (int) (fc / deltaf - 100); } /* * Returns the number of samles */ int getsamplecnt() { return samples; }