states.f1 = f1;
states.f2 = f2;
- %printf("ESTF - f1 = %d, f2 = %d, twist = %f \n",f1,f2,twist);
if bitand(verbose,0x1)
printf("centre: %4.0f shift: %4.0f twist: %3.1f dB\n", (f2+f1)/2, f2-f1, twist);
end
% symbols so we have extra samples for the fine timing re-sampler at either
% end of the array.
-
- length(f1_dc);
rx_bits = zeros(1, (nsym+1)*P);
for i=1:(nsym+1)*P
st = 1 + (i-1)*Ts/P;
end
states.f1_int = f1_int;
states.f2_int = f2_int;
- length(f1_dc);
+
% fine timing estimation -----------------------------------------------
% Non linearity has a spectral line at Rs, with a phase
Np = length(f1_int);
w = 2*pi*(Rs)/(P*Rs);
-
- %%# same as sum of ((abs(f1_int)-abs(f2_int)).^2) .* exp(-j*w*(0:Np-1))
x = ((abs(f1_int)-abs(f2_int)).^2) * exp(-j*w*(0:Np-1))';
-
norm_rx_timing = angle(x)/(2*pi);
rx_timing = norm_rx_timing*P;
%f1_int_resample(i) = f1_int(st+1);
%f2_int_resample(i) = f2_int(st+1);
rx_bits(i) = abs(f2_int_resample(i)) > abs(f1_int_resample(i));
-
-
rx_bits_sd(i) = abs(f2_int_resample(i)) - abs(f1_int_resample(i));
end
x = abs(abs(f1_int_resample) - abs(f2_int_resample));
states.EbNodB = 20*log10(1E-6+mean(x)/(1E-6+std(x)));
- % printf("EbNodB %f\n",states.EbNodB);
endfunction
% UW found Sometimes there may be several matches, returns the
% position of the best match to UW.
-function [uw_start best_corr] = find_uw(states, start_bit, rx_bits)
+function uw_start = find_uw(states, start_bit, rx_bits)
uw = states.uw;
mapped_rx_bits = 2*rx_bits - 1;
if crc_ok == 0
[str_flipped crc_flipped_ok rx_bits_log] = sd_bit_flipping(states.rtty, rx_bits_log, rx_bits_sd_log, uw_loc, uw_loc+states.rtty.max_packet_len);
+ if crc_flipped_ok
+ str = sprintf("%s fixed", str_flipped);
+ end
end
% update memory of previous packet, we use this to guess where errors may be
if crc_ok || crc_flipped_ok
states.prev_pkt = rx_bits_log(uw_loc+length(states.rtty.uw):uw_loc+states.rtty.max_packet_len);
end
-
if crc_ok
str = sprintf("%s CRC OK", str);
else
- if crc_flipped_ok
- str = sprintf("%s fixed", str_flipped);
- else
- str = sprintf("%s CRC BAD", str);
- end
+ str = sprintf("%s CRC BAD", str);
end
printf("%s\n", str);
end
endfunction
-% Extract as many binary packets as we can from a great big buffer of bits,
+% Extract as many ASCII packets as we can from a great big buffer of bits,
% and send them to the C decoder for FEC decoding.
% horus_l2 can be compiled a bunch of different ways. You need to
% compile with:
states.f1_tx = 1200;
states.f2_tx = 1600;
states.tx_bits_file = "horus_tx_bits_rtty.txt"; % Octave file of bits we FSK modulate
-
end
if test_frame_mode == 5
states = fsk_horus_init(8000, 100);
states.f1_tx = 1200;
states.f2_tx = 1600;
- %%%states.tx_bits_file = "horus_tx_bits_binary.txt"; % Octave file of bits we FSK modulate
- states.tx_bits_file = "horus_payload_rtty.txt"
+ states.tx_bits_file = "horus_tx_bits_binary.txt"; % Octave file of bits we FSK modulate
end
% ----------------------------------------------------------------------
uwstates = fsk_horus_init_binary_uw;
end
- states.verbose = 0x1;
+ states.verbose = 0x1 + 0x8;
N = states.N;
P = states.P;
f2_int_resample_log = [];
EbNodB_log = [];
ppm_log = [];
- f1_log = [];
- f2_log = [];
rx_bits_buf = zeros(1,2*nsym);
% First extract raw bits from samples ------------------------------------------------------
f2_int_resample_log = [f2_int_resample_log abs(states.f2_int_resample)];
EbNodB_log = [EbNodB_log states.EbNodB];
ppm_log = [ppm_log states.ppm];
- f1_log = [f1_log states.f1];
- f2_log = [f2_log states.f2];
if test_frame_mode == 1
states = ber_counter(states, test_frame, rx_bits_buf);
printf("plotting...\n");
figure(1);
- plot(f1_log);
- hold on;
- plot(f2_log,'g');
- hold off;
-
- figure(2);
plot(f1_int_resample_log,'+')
hold on;
plot(f2_int_resample_log,'g+')
hold off;
- figure(3)
+ figure(2)
clf
subplot(211)
plot(norm_rx_timing_log)
plot(states.nerr_log)
title('num bit errors each frame')
- figure(4)
+ figure(3)
clf
plot(EbNodB_log);
title('Eb/No estimate')
- figure(5)
+ figure(4)
clf
- rx_nowave = rx(1000:length(rx));
subplot(211)
- plot(rx_nowave(1:states.Fs));
+ plot(rx(1:states.Fs));
title('input signal to demod (1 sec)')
xlabel('Time (samples)');
axis([1 states.Fs -35000 35000])
- % normalise spectrum to 0dB full scale with a 32767 sine wave input
+ % normalise spectrum to 0dB full scale witha 32767 sine wave input
subplot(212)
- RxdBFS = 20*log10(abs(fft(rx_nowave(1:states.Fs)))) - 20*log10((states.Fs/2)*32767);
+ RxdBFS = 20*log10(abs(fft(rx(1:states.Fs)))) - 20*log10((states.Fs/2)*32767);
plot(RxdBFS)
axis([1 states.Fs/2 -80 0])
xlabel('Frequency (Hz)');
- figure(6);
+ figure(5);
clf
plot(ppm_log)
title('Sample clock (baud rate) offset in PPM');
% run test functions from here during development
if exist("fsk_horus_as_a_lib") == 0
- run_sim(5);
+ %run_sim(5);
%rx_bits = demod_file("horus.raw",4);
%rx_bits = demod_file("fsk_horus_100bd_binary.raw",5);
- %rx_bits = demod_file("~/Desktop/phorus_binary_ascii.wav",4);
- %rx_bits = demod_file("~/Desktop/binary/horus_160102_binary_rtty_2.wav",4);
-
-
- %rx_bits = demod_file("~/Desktop/horus_160102_vk5ei_capture2.wav",4);
+ rx_bits = demod_file("~/Desktop/phorus_binary_ascii.wav",4);
%rx_bits = demod_file("~/Desktop/horus_rtty_binary.wav",4);
%rx_bits = demod_file("t.raw",5);
%rx_bits = demod_file("~/Desktop/fsk_horus_10dB_1000ppm.wav",4);
% tfsk.m
-% Brady O'Brien 8 January 2016
+% Author: Brady O'Brien 8 January 2016
+
+
+
+% Copyright 2016 David Rowe
+%
+% All rights reserved.
+%
+% This program is free software; you can redistribute it and/or modify
+% it under the terms of the GNU Lesser General Public License version 2, as
+% published by the Free Software Foundation. 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 Lesser General Public License
+% along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+
% Octave script to check c port of fsk_horus against the fsk_horus.m
%
% [X] - Functions to wrap around fsk_mod and fsk_demod executables
% same dataset, compare outputs, and give clear go/no-go
% [X] - fsk_mod_test
% [X] - fsk_demod_test
-% [.] - Port of run_sim and EbNodB curve test battery
-% [ ] - Extract and compare more parameters from demod
-% [ ] - Run some tests in parallel
+% [X] - Port of run_sim and EbNodB curve test battery
+% [X] - Extract and compare more parameters from demod
+% [X] - Run some tests in parallel
+
+%
+% FSK Modem test instructions --
+% 1 - Compile tfsk.c and fm_mod.c
+% - tfsk.c is in unittest/, so build must not be configured for release
+% 2 - Change tfsk_location and fsk_mod_location to point to tfsk and fsk_mod
+% 3 - Ensure octave packages signal and parallel are installed
+% 4 - run tfsk.m. It will take care of the rest.
+%
+
+
+global tfsk_location = '../build/unittest/tfsk';
+global fsk_mod_location = '../build/src/fsk_mod';
+
fsk_horus_as_a_lib = 1; % make sure calls to test functions at bottom are disabled
fsk_horus_2fsk;
pkg load signal;
-
+pkg load parallel;
graphics_toolkit('gnuplot');
global mod_pass_fail_maxdiff = 1e-3/50000;
-global demod_pass_fail_maxdiff = .01;
function mod = fsk_mod_c(Fs,Rs,f1,f2,bits)
%Name of executable containing the modulator
endfunction
-function bits = fsk_demod_c(Fs,Rs,f1,f2,mod)
- %Name of executable containing the modulator
- fsk_demod_ex_file = '../build/unittest/tfsk';
- modvecfilename = sprintf('fsk_demod_ut_modvec_%d',getpid());
- bitvecfilename = sprintf('fsk_demod_ut_bitvec_%d',getpid());
- tvecfilename = sprintf('fsk_demod_ut_tracevec_%d.txt',getpid());
-
- %command to be run by system to launch the demod
- command = sprintf('%s %d %d %d %d %s %s %s',fsk_demod_ex_file,Fs,Rs,f1,f2,modvecfilename,bitvecfilename,tvecfilename);
-
- %save modulated input into a file
- modvecfile = fopen(modvecfilename,'wb+');
- fwrite(modvecfile,mod,'single');
- fclose(modvecfile);
-
- %run the modulator
- system(command);
-
- bitvecfile = fopen(bitvecfilename,'rb');
- bits = fread(bitvecfile,'uint8');
- fclose(bitvecfile);
- bits = bits!=0;
-
- %Clean up files
- delete(bitvecfilename);
- delete(modvecfilename);
- %delete(tvecfilename);
-endfunction
%Compare 2 vectors, fail if they are not close enough
function pass = vcompare(va,vb,vname,tname,tol)
delete(modvecfilename);
delete(tvecfilename);
-
o_f1_dc = [];
o_f2_dc = [];
o_f1_int = [];
o_f2_int = [];
o_EbNodB = [];
+ o_ppm = [];
o_rx_timing = [];
%Run octave demod, dump some test vectors
states = fsk_horus_init(Fs,Rs);
o_f1_int = [o_f1_int states.f1_int];
o_f2_int = [o_f2_int states.f2_int];
o_EbNodB = [o_EbNodB states.EbNodB];
+ o_ppm = [o_ppm states.ppm];
o_rx_timing = [o_rx_timing states.rx_timing];
end
pass = vcompare(o_rx_timing, t_rx_timing,'rx_timing',tname,.011);
pass = pass && vcompare(o_EbNodB, t_EbNodB, 'EbNodB', tname,.15);
+ pass = pass && vcompare(o_ppm , t_ppm, 'ppm', tname,.011);
pass = pass && vcompare(o_f1_int, t_f1_int, 'f1_int', tname,.011);
pass = pass && vcompare(o_f2_int, t_f2_int, 'f2_int', tname,.011);
- pass = pass && vcompare(o_f1_dc(1:length(t_f1_dc)), t_f1_dc, 'f1_dc', tname,.001);
- pass = pass && vcompare(o_f2_dc(1:length(t_f1_dc)), t_f2_dc, 'f2_dc', tname,.001);
+ pass = pass && vcompare(o_f1_dc, t_f1_dc, 'f1_dc', tname,.001);
+ pass = pass && vcompare(o_f2_dc, t_f2_dc, 'f2_dc', tname,.001);
diffpass = sum(xor(obits,bits'))<3
end
endfunction
-function [cbits,obits,pass] = fsk_demod_test(Fs,Rs,f1,f2,mod,tname)
- global pass_fail_maxdiff;
- %Run the C demodulator
- cbits = fsk_demod_c(Fs,Rs,f1,f2,mod)';
- %Set up and run the octave demodulator
- states = fsk_horus_init(Fs,Rs);
- states.f1_tx = f1;
- states.f2_tx = f2;
- states.dA = 1;
- states.dF = 0;
-
- modin = mod;
- obits = [];
- while length(modin)>=states.nin
- ninold = states.nin;
- [bitbuf,states] = fsk_horus_demod(states, modin(1:states.nin));
- modin=modin(ninold+1:length(modin));
- obits = [obits bitbuf];
- end
-
- diff = sum(xor(obits,cbits))
-
- %Allow 2 bit difference between model and C
- pass = diff < 3
- if !pass
- printf('Demod failed test %s!\n',tname);
- figure(10);
- plot((1:length(obits)),obits,(1:length(cbits)),cbits);
- figure(11);
- plot(xor(obits,cbits));
- end
-endfunction
-
% Random bit modulator test
% Pass random bits through the modulators and compare
function pass = test_mod_horuscfg_randbits
printf("***** All tests passed! *****\n");
end
endfunction
+
+test_fsk_battery
fsk->nin = fsk->N;
/* Set up rx state */
- fsk->phi1_d = 0;
- fsk->phi2_d = 0;
fsk->phi1_c.real = 1;
fsk->phi1_c.imag = 0;
fsk->phi2_c.real = 1;
fsk->norm_rx_timing = 0;
/* Set up tx state */
- fsk->tx_phase = 0;
fsk->tx_phase_c.imag = 0;
fsk->tx_phase_c.real = 1;
*f1_est = (float)m1*(float)Fs/(float)Ndft;
*f2_est = (float)m2*(float)Fs/(float)Ndft;
*twist = 20*log10f(m1v/m2v);
- //printf("ESTF - f1 = %f, f2 = %f, twist = %f \n",*f1_est,*f2_est,*twist);
}
COMP t1,t2;
COMP phi1_c = fsk->phi1_c;
COMP phi2_c = fsk->phi2_c;
- COMP phi_ft; /* Phase of fine timing estimator */
+ COMP phi_ft;
int nold = Nmem-nin;
COMP dphi1,dphi2;
COMP dphift;
float f1,f2;
- float rx_timing,norm_rx_timing;//,old_norm_rx_timing;//,d_norm_rx_timing;
+ float rx_timing,norm_rx_timing,old_norm_rx_timing,d_norm_rx_timing,appm;
int using_old_samps;
float *sample_src;
COMP *f1_intbuf,*f2_intbuf;
if(cbuf_i>=Ts) cbuf_i = 0;
/* Integrate over the integration buffers, save samples */
- /* This uses Kahan summation to reduce floating point funnyness */
t1 = t2 = comp0();
- f1_strc = f1_stic = 0;
- f2_strc = f2_stic = 0;
- f1_strs = f1_stis = 0;
- f2_strs = f2_stis = 0;
for(j=0; j<Ts; j++){
t1 = cadd(t1,f1_intbuf[j]);
t2 = cadd(t2,f2_intbuf[j]);
/* Apply magic nonlinearity to f1_int and f2_int, shift down to 0,
* exract angle */
- float ft_rc,ft_rs,ft_ic,ft_is;
- ft_rc = ft_rs = 0;
- ft_ic = ft_is = 0;
/* Figure out how much to spin the oscillator to extract magic spectral line */
dphift = comp_exp_j(-2*M_PI*((float)(Rs)/(float)(P*Rs)));
phi_ft.real = 1;
/* Add and square 'em */
ft1 = ft1-ft2;
ft1 = ft1*ft1;
- /* Spin the oscillator for the magic line shift */
/* Down shift and accumulate magic line */
t1 = cadd(t1,fcmult(ft1,phi_ft));
+ /* Spin the oscillator for the magic line shift */
phi_ft = cmult(phi_ft,dphift);
}
/* Get the magic angle */
norm_rx_timing = -atan2f(t1.imag,t1.real)/(2*M_PI);
rx_timing = norm_rx_timing*(float)P;
- //old_norm_rx_timing = fsk->norm_rx_timing;
+ old_norm_rx_timing = fsk->norm_rx_timing;
fsk->norm_rx_timing = norm_rx_timing;
/* Estimate sample clock offset */
- //d_norm_rx_timing = norm_rx_timing - old_norm_rx_timing;
+ d_norm_rx_timing = norm_rx_timing - old_norm_rx_timing;
/* Filter out big jumps in due to nin change */
- //if(fabsf(d_norm_rx_timing) < .2){
+ if(fabsf(d_norm_rx_timing) < .2){
+ appm = 1e6*d_norm_rx_timing/(float)nsym;
+ fsk->ppm = .9*fsk->ppm + .1*appm;
+ }
/* Figure out how many samples are needed the next modem cycle */
if(norm_rx_timing > 0.25)
#ifdef EST_EBNO
meanebno = 0;
+ stdebno = 0;
#endif
/* FINALLY, THE BITS */
t2 = cadd(t2,fcmult( fract,f2_int[st+high_sample]));
/* Accumulate resampled int magnitude for EbNodB estimation */
+ /* Standard deviation is calculated by algorithm devised by crafty soviets */
#ifdef EST_EBNO
+
ft1 = sqrtf(t1.real*t1.real + t1.imag*t1.imag);
ft2 = sqrtf(t2.real*t2.real + t2.imag*t2.imag);
ft1 = fabsf(ft1-ft2);
meanebno += ft1;
+
#endif
/* THE BIT! */
/* Dump some internal samples */
modem_probe_samp_f("t_EbNodB",&(fsk->EbNodB),1);
+ modem_probe_samp_f("t_ppm",&(fsk->ppm),1);
modem_probe_samp_f("t_f1",&f1,1);
modem_probe_samp_f("t_f2",&f2,1);
modem_probe_samp_c("t_f1_int",f1_int,(nsym+1)*P);
modem_probe_samp_f("t_rx_timing",&(rx_timing),1);;
}
-
-void fsk_mod_realphase(struct FSK *fsk,float fsk_out[],uint8_t tx_bits[]){
- float tx_phase = fsk->tx_phase; /* current TX phase */
- int f1_tx = fsk->f1_tx; /* '0' frequency */
- int f2_tx = fsk->f2_tx; /* '1' frequency */
- int Ts = fsk->Ts; /* samples-per-symbol */
- int Fs = fsk->Fs; /* sample freq */
- int i,j;
- uint8_t bit;
-
- /* delta-phase per cycle for both symbol freqs */
- float dph_f1 = 2*M_PI*((float)(f1_tx)/(float)(Fs));
- float dph_f2 = 2*M_PI*((float)(f2_tx)/(float)(Fs));
-
- /* Note: Right now, this mirrors fm.c and fsk_horus.m, but it
- * ought to be possible to make it more efficent (one complex mul per
- * cycle) by using a complex number for the phase. */
-
- /* Outer loop through bits */
- for(i=0; i<fsk->Nsym; i++){
- bit = tx_bits[i];
- for(j=0; j<Ts; j++){
- /* Nudge phase forward a bit */
- tx_phase += (bit==0)?dph_f1:dph_f2;
- /* Make sure phase stays on [0,2pi] */
- if(tx_phase>2*M_PI)
- tx_phase -= 2*M_PI;
- fsk_out[i*Ts+j] = 2*cosf(tx_phase);
- }
- }
-
- /* save TX phase */
- fsk->tx_phase = tx_phase;
-
-}
-
void fsk_mod(struct FSK *fsk,float fsk_out[],uint8_t tx_bits[]){
COMP tx_phase_c = fsk->tx_phase_c; /* Current complex TX phase */
int f1_tx = fsk->f1_tx; /* '0' frequency */
int f2_tx; /* f2 for modulator */
/* Parameters used by demod */
- float phi1_d; /* f1 oscillator for demod */
- float phi2_d; /* f2 oscillator for demod */
COMP phi1_c;
COMP phi2_c;
kiss_fftr_cfg fft_cfg; /* Config for KISS FFT, used in freq est */
float norm_rx_timing; /* Normalized RX timing */
- float *samp_old; /* Ass end of last batch of samples */
+ float *samp_old; /* Tail end of last batch of samples */
int nstash; /* How many elements are in there */
/* Memory used by demod but not important between demod frames */
/* Parameters used by mod */
- float tx_phase; /* phase of modulator */
COMP tx_phase_c; /* TX phase, but complex */
/* Statistics generated by demod */
float f1_est; /* Estimated f1 freq. */
float f2_est; /* Estimated f2 freq. */
float twist_est; /* Estimaged 'twist' from freq est */
+ float ppm; /* Estimated PPM clock offset */
/* Parameters used by mod/demod and driving code */
int nin; /* Number of samples to feed the next demod cycle */
};
+/*
+ * Create an FSK config/state struct from a set of config parameters
+ *
+ * int Fs - Sample frequency
+ * int Rs - Symbol rate
+ * int tx_f1 - '0' frequency
+ * int tx_f2 - '1' frequency
+ */
struct FSK * fsk_create(int Fs, int Rs, int tx_f1, int tx_f2);
+
+/*
+ * Destroy an FSK state struct and free it's memory
+ *
+ * struct FSK *fsk - FSK config/state struct to be destroyed
+ */
void fsk_destroy(struct FSK *fsk);
-void fsk_mod(struct FSK *fsk,
- float fsk_out[], /* N float output modulated FSK samples */
- uint8_t tx_bits[] /* Nsym unpacked input bits in LSB */
- );
+/*
+ * Modulates Nsym bits into N samples
+ *
+ * struct FSK *fsk - FSK config/state struct, set up by fsk_create
+ * float fsk_out[] - Buffer for N samples of modulated FSK
+ * uint8_t tx_bits[] - Buffer containing Nsym unpacked bits
+ */
+void fsk_mod(struct FSK *fsk, float fsk_out[], uint8_t tx_bits[]);
-/* number of input samples required for next call to fsk_demod() */
+/*
+ * Returns the number of samples needed for the next fsk_demod() cycle
+ *
+ * struct FSK *fsk - FSK config/state struct, set up by fsk_create
+ * returns - number of samples to be fed into fsk_demod next cycle
+ */
uint32_t fsk_nin(struct FSK *fsk);
-void fsk_demod(struct FSK *fsk,
- uint8_t rx_bits[], /* Nsym unpacked output demodulated rx bits in each LSB */
- float fsk_in[] /* N input float modulated FSK samples */
- );
+
+/*
+ * Demodulate some number of FSK samples. The number of samples to be
+ * demodulated can be found by calling fsk_nin().
+ *
+ * struct FSK *fsk - FSK config/state struct, set up by fsk_create
+ * uint8_t rx_bits[] - Buffer for Nsym unpacked bits to be written
+ * float fsk_in[] - nin samples of modualted FSK
+ */
+void fsk_demod(struct FSK *fsk, uint8_t rx_bits[],float fsk_in[]);
AUTHOR......: Brady O'Brien
DATE CREATED: 9 January 2016
- Library to easily extract debug traces from modems during development
+ Library to easily extract debug traces from modems during development and
+ verification
\*---------------------------------------------------------------------------*/
switch(cur->type){
case TRACE_I:
octave_save_int(dumpfile,cur->name,(int32_t*)dbuf,1,len/sizeof(int32_t));
- break;
+ break;
case TRACE_F:
octave_save_float(dumpfile,cur->name,(float*)dbuf,1,len/sizeof(float),10);
break;
#ifdef MODEMPROBE_ENABLE
+/* Internal functions */
void modem_probe_init_int(char *modname, char *runname);
void modem_probe_close_int();
void modem_probe_samp_f_int(char * tracename,float samp[],size_t cnt);
void modem_probe_samp_c_int(char * tracename,COMP samp[],size_t cnt);
-
+/*
+ * Init the probe library.
+ * char *modname - Name of the modem under test
+ * char *runname - Name/path of the file data is dumped to
+ */
static inline void modem_probe_init(char *modname,char *runname){
- modem_probe_init_int(modname,runname);
+ modem_probe_init_int(modname,runname);
}
+/*
+ * Dump traces to a file and clean up
+ */
static inline void modem_probe_close(){
- modem_probe_close_int();
+ modem_probe_close_int();
}
+/*
+ * Save some number of int samples to a named trace
+ * char *tracename - name of trace being saved to
+ * int samp[] - int samples
+ * size_t cnt - how many samples to save
+ */
static inline void modem_probe_samp_i(char *tracename,int samp[],size_t cnt){
- modem_probe_samp_i_int(tracename,samp,cnt);
+ modem_probe_samp_i_int(tracename,samp,cnt);
}
-
+/*
+ * Save some number of float samples to a named trace
+ * char *tracename - name of trace being saved to
+ * float samp[] - int samples
+ * size_t cnt - how many samples to save
+ */
static inline void modem_probe_samp_f(char *tracename,float samp[],size_t cnt){
- modem_probe_samp_f_int(tracename,samp,cnt);
-}
+ modem_probe_samp_f_int(tracename,samp,cnt);
+}
+/*
+ * Save some number of complex samples to a named trace
+ * char *tracename - name of trace being saved to
+ * COMP samp[] - int samples
+ * size_t cnt - how many samples to save
+ */
static inline void modem_probe_samp_c(char *tracename,COMP samp[],size_t cnt){
- modem_probe_samp_c_int(tracename,samp,cnt);
+ modem_probe_samp_c_int(tracename,samp,cnt);
}
#else
static inline void modem_probe_init(char *modname,char *runname){
- return;
+ return;
}
static inline void modem_probe_close(){
- return;
+ return;
}
static inline void modem_probe_samp_i(char *name,int samp[],size_t sampcnt){
- return;
+ return;
}
static inline void modem_probe_samp_f(char *name,float samp[],size_t cnt){
- return;
+ return;
}
static inline void modem_probe_samp_c(char *name,COMP samp[],size_t cnt){
- return;
+ return;
}
#endif
C test driver for fsk_mod and fsk_demod in fsk.c. Reads a file with input
bits/rf and spits out modulated/demoduladed samples and a dump of internal
- state
+ state. To run unit test, see octave/tfsk.m
\*---------------------------------------------------------------------------*/