From: drowe67 Date: Tue, 12 Jun 2012 05:07:40 +0000 (+0000) Subject: first pass at fdmdv_get_rx_spectrum(), wrote octave tfft_log.m to test it X-Git-Url: http://git.whiteaudio.com/gitweb/?a=commitdiff_plain;h=4993ad74c0aa6dd281c4509c168dfe491e005ae0;p=freetel-svn-tracking.git first pass at fdmdv_get_rx_spectrum(), wrote octave tfft_log.m to test it git-svn-id: https://svn.code.sf.net/p/freetel/code@543 01035d8c-6547-0410-b346-abe4f91aad63 --- diff --git a/codec2-dev/octave/tfft_log.m b/codec2-dev/octave/tfft_log.m new file mode 100644 index 00000000..89364968 --- /dev/null +++ b/codec2-dev/octave/tfft_log.m @@ -0,0 +1,49 @@ +% tfft_log.m +% +% Used in conjunction swith src/fdmdv_demod to test the +% fdmdv_get_rx_spectrum() function. +% +% codec2-dev/src$ ./fdmdv_demod fdmdv_mod.raw tmp.c2 dump.txt +% octave:3> tfft_log("../src/dump.txt") +% +% Copyright David Rowe 2012 +% This program is distributed under the terms of the GNU General Public License +% Version 2 +% + +function tfft_log(dumpfilename) + + load(dumpfilename); + + [rows cols] = size(rx_spec_log_c); + Fs = 8000; low_freq = 0; high_freq = 2500; + res = (Fs/2)/cols; + st_bin = low_freq/res + 1; + en_bin = high_freq/res; + xaxis = (st_bin:en_bin)*res; + + f_start = 2; f_end = 100; + beta = 0.1; + + av = zeros(f_end, en_bin-st_bin+1); + for r=f_start:f_end + x = (1-beta)*av(r-1,:) + beta*rx_spec_log_c(r,st_bin:en_bin); + av(r,:) = x; + end + + % spectrogram (waterfall) + + figure(1) + clf; + imagesc(av,[-40 0]); + + % animated spectrum display + + figure(2) + clf; + for r=f_start:f_end + plot(xaxis, av(r,:)) + axis([ low_freq high_freq -40 0]) + sleep(0.1) + end +endfunction diff --git a/codec2-dev/src/fdmdv.c b/codec2-dev/src/fdmdv.c index c626e9d4..2e88d1d4 100644 --- a/codec2-dev/src/fdmdv.c +++ b/codec2-dev/src/fdmdv.c @@ -224,9 +224,9 @@ struct FDMDV * CODEC2_WIN32SUPPORT fdmdv_create(void) f->noise_est[c] = 0.0; } - for(i=0; i<2*FDMDV_NFFT; i++) + for(i=0; i<2*FDMDV_NSPEC; i++) f->fft_buf[i] = 0.0; - f->fft_cfg = kiss_fft_alloc (2*FDMDV_NFFT, 0, NULL, NULL); + f->fft_cfg = kiss_fft_alloc (2*FDMDV_NSPEC, 0, NULL, NULL); assert(f->fft_cfg != NULL); @@ -1362,55 +1362,63 @@ void CODEC2_WIN32SUPPORT fdmdv_48_to_8(float out8k[], float in48k[], int n) /*---------------------------------------------------------------------------*\ - FUNCTION....: fdmdv_get_fft() + FUNCTION....: fdmdv_get_rx_spectrum() AUTHOR......: David Rowe DATE CREATED: 9 June 2012 - Performs a FFT on the received modem signal at the input of the - demod, returns the FDMDV_NFFT point magnitiude spectrum in dB. 0dB - is a signal with amplitude +/- 2^15. + Returns the FDMDV_NSPEC point magnitude spectrum of the rx signal in + dB. The spectral samples are scaled so that 0dB is the peak, a good + range for plotting is 0 to -40dB. - The output can be used to plot a spectrum of the demod input. - Sucessive calls can be used to build up a waterfall or spectrogram + Successive calls can be used to build up a waterfall or spectrogram plot, by mapping the received levels to colours. - The time-frequency resolution of the FFT can be adjusted by varying - FDMDV_NFFT. Note that a 2*FDMDV_NFFT size FFT is reqd to get - FDMDV_NFFT output points. + The time-frequency resolution of the spectrum can be adjusted by varying + FDMDV_NSPEC. Note that a 2*FDMDV_NSPEC size FFT is reqd to get + FDMDV_NSPEC output points. FDMDV_NSPEC must be a power of 2. + + See octave/tfft_log.m for a demo real time spectral display using + Octave. This demo averages the output over time to get a smoother + display: + + av = 0.9*av + 0.1*mag_dB \*---------------------------------------------------------------------------*/ -void CODEC2_WIN32SUPPORT fdmdv_get_fft(struct FDMDV *f, float mag_dB[], float rx_fdm[], int nin) +void CODEC2_WIN32SUPPORT fdmdv_get_rx_spectrum(struct FDMDV *f, float mag_spec_dB[], + float rx_fdm[], int nin) { int i,j; - COMP fft_in[2*FDMDV_NFFT]; - COMP fft_out[2*FDMDV_NFFT]; - float fullscale_dB; + COMP fft_in[2*FDMDV_NSPEC]; + COMP fft_out[2*FDMDV_NSPEC]; + float full_scale_dB; /* update buffer of input samples */ - for(i=0; i<2*FDMDV_NFFT-nin; i++) + for(i=0; i<2*FDMDV_NSPEC-nin; i++) f->fft_buf[i] = f->fft_buf[i+nin]; for(j=0; jfft_buf[i] = rx_fdm[j]; - assert(i == 2*FDMDV_NFFT); + assert(i == 2*FDMDV_NSPEC); /* window and FFT */ - for(i=0; i<2*FDMDV_NFFT; i++) { - fft_in[i].real = f->fft_buf[i] * (0.5 - 0.5*cos((float)i*2.0*PI/(2*FDMDV_NFFT))); + for(i=0; i<2*FDMDV_NSPEC; i++) { + fft_in[i].real = f->fft_buf[i] * (0.5 - 0.5*cos((float)i*2.0*PI/(2*FDMDV_NSPEC))); fft_in[i].imag = 0.0; } kiss_fft(f->fft_cfg, (kiss_fft_cpx *)fft_in, (kiss_fft_cpx *)fft_out); - /* scale and convert to dB */ + /* FFT scales up a signal of level 1 FDMDV_NSPEC */ - fullscale_dB = 20.0*log10(FDMDV_NFFT*32767.0); + full_scale_dB = 20*log10(FDMDV_NSPEC); + + /* scale and convert to dB */ - for(i=0; i