global mod_pass_fail_maxdiff = 1e-3/50000;
-global demod_pass_fail_maxdiff = .1;
+global demod_pass_fail_maxdiff = .01;
function mod = fsk_mod_c(Fs,Rs,f1,f2,bits)
%Name of executable containing the modulator
endfunction
%Compare 2 vectors, fail if they are not close enough
-function pass = vcompare(va,vb,vname,tname)
- global demod_pass_fail_maxdiff;
+function pass = vcompare(va,vb,vname,tname,tol)
%Get delta of vectors
- dvec = abs(va)-abs(vb);
+ dvec = abs(abs(va)-abs(vb));
%Normalize difference
- dvec = dvec ./ max(va);
+ dvec = dvec ./ abs(max(abs(va)));
- titlestr = sprintf('Diff between C and Octave of %s for %s',vname,tname);
- pass = max(dvec)<(demod_pass_fail_maxdiff)
- maxdvec = max(dvec)
- %figure(12)
- %title(titlestr)
- %plot(abs(dvec))
+ maxdvec = abs(max(dvec))
+ pass = maxdvec<tol
- %figure(13)
- %plot(abs(va))
+ printf('Comparing vectors %s in test %s. Diff is %f\n',vname,tname,maxdvec);
- %figure(14)
- %plot(abs(vb))
+ if pass == 0
+ printf('\n*** vcompaire failed %s in test %s. Diff: %f Tol: %f\n\n',vname,tname,maxdvec,tol);
+
+ titlestr = sprintf('Diff between C and Octave of %s for %s',vname,tname)
+ figure(12)
+ plot(abs(dvec))
+ title(titlestr)
+
+ figure(13)
+ plot(abs(va))
- printf('Comparing vectors %s in test %s\n',vname,tname);
+ figure(14)
+ plot(abs(vb))
+ end
assert(pass);
endfunction
o_rx_timing = [];
%Run octave demod, dump some test vectors
states = fsk_horus_init(Fs,Rs);
+ Ts = states.Ts;
+ P = states.P;
states.f1_tx = f1;
states.f2_tx = f2;
states.dA = 1;
obits = [obits bitbuf];
%Save other parameters
- o_f1_dc = [o_f1_dc states.f1_dc];
- o_f2_dc = [o_f2_dc states.f2_dc];
+ o_f1_dc = [o_f1_dc states.f1_dc(1:states.Nmem-Ts/P)];
+ o_f2_dc = [o_f2_dc states.f2_dc(1:states.Nmem-Ts/P)];
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_rx_timing = [o_rx_timing states.rx_timing];
end
- pass = 1;
- pass = and(pass,vcompare(o_rx_timing,t_rx_timing,'rx_timing',tname));
- pass = and(pass,vcompare(o_f1_int,t_f1_int,'f1_int',tname));
- pass = and(pass,vcompare(o_f2_int,t_f2_int,'f2_int',tname));
-
- diff = sum(xor(obits,bits'))
+ 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_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);
+
+ diffpass = sum(xor(obits,bits'))<3
+
+ if diffpass==0
+ printf('\n***bitcompare test failed test %s diff %d\n\n',tname,sum(xor(obits,bits')))
+ figure(15)
+ plot(xor(obits,bits'))
+ title(sprintf('Bitcompare failure test %s',tname))
+ end
+
+ pass = pass && diffpass;
+
- pass = pass && diff<2;
test_stats.pass = pass;
- assert(pass)
- test_stats.diff = diff;
+ test_stats.diff = sum(xor(obits,bits'));
+
endfunction
function [dmod,cmod,omod,pass] = fsk_mod_test(Fs,Rs,f1,f2,bits,tname)
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_payload_rtty.txt";
end
% ----------------------------------------------------------------------
endfunction
-function pass = ebno_battery_test(fading,df,dA)
- pass = 1
- ebnodbrange = (2:13)
- timing_offset=0;
-
- npass=zeros(1,length(ebnodbrange));
- for i=(1:length(npass))
- npass(i) = tfsk_run_sim(5,ebnodbrange(i),0,0,df,dA)
- assert(npass(i))
- pass = npass(i) && pass
- end
-endfunction
function pass = ebno_battery_test(timing_offset,fading,df,dA)
%Range of EbNodB over which to test
ebnodbrange = fliplr(3:13);
ebnodbs = length(ebnodbrange);
- mode = 2;
+ mode = 5;
%Replication of other parameters for parcellfun
modev = repmat(mode,1,ebnodbs);
timingv = repmat(timing_offset,1,ebnodbs);
dfv = repmat(df,1,ebnodbs);
dav = repmat(dA,1,ebnodbs);
- passv = pararrayfun(floor(.7*nproc()),@tfsk_run_sim,modev,ebnodbrange,timingv,fadingv,dfv,dav);
+
+ passv = pararrayfun(floor(1.25*nproc()),@tfsk_run_sim,modev,ebnodbrange,timingv,fadingv,dfv,dav);
%passv = arrayfun(@tfsk_run_sim,modev,ebnodbrange,timingv,fadingv,dfv,dav);
- pass = sum(passv)>=length(passv)
+ %All pass flags are '1'
+ pass = sum(passv)>=length(passv);
+ %and no tests died
+ pass = pass && length(passv)==ebnodbs;
passv
assert(pass)
endfunction
f1_intbuf[dc_i]=fcmult(sample_src[dc_i],phi1_c);
f2_intbuf[dc_i]=fcmult(sample_src[dc_i],phi2_c);
+ modem_probe_samp_c("t_f1_dc",&f1_intbuf[dc_i],1);
+ modem_probe_samp_c("t_f2_dc",&f2_intbuf[dc_i],1);
/* Spin downconversion phases */
phi1_c = cmult(phi1_c,dphi1);
phi2_c = cmult(phi2_c,dphi2);
}
- modem_probe_samp_c("t_f1_dc",&f1_intbuf[0],Ts-(Ts/P));
- modem_probe_samp_c("t_f2_dc",&f2_intbuf[0],Ts-(Ts/P));
cbuf_i = dc_i;
float f1_strs,f1_stis,f2_strs,f2_stis;
f1_intbuf[cbuf_i+j]=fcmult(sample_src[dc_i],phi1_c);
f2_intbuf[cbuf_i+j]=fcmult(sample_src[dc_i],phi2_c);
+
+ modem_probe_samp_c("t_f1_dc",&f1_intbuf[cbuf_i+j],1);
+ modem_probe_samp_c("t_f2_dc",&f2_intbuf[cbuf_i+j],1);
+
/* Spin downconversion phases */
phi1_c = cmult(phi1_c,dphi1);
phi2_c = cmult(phi2_c,dphi2);
+
}
/* Dump internal samples */
- modem_probe_samp_c("t_f1_dc",&f1_intbuf[cbuf_i],Ts/P);
- modem_probe_samp_c("t_f2_dc",&f2_intbuf[cbuf_i],Ts/P);
cbuf_i += Ts/P;
if(cbuf_i>=Ts) cbuf_i = 0;
f1_strs = f1_stis = 0;
f2_strs = f2_stis = 0;
for(j=0; j<Ts; j++){
- y = f1_intbuf[j].real - f1_strc;
+ /* y = f1_intbuf[j].real - f1_strc;
t = f1_strs + y;
f1_strc = (t - f1_strs) - y;
f1_strs = t;
t = f2_stis + y;
f2_stic = (t - f2_stis) - y;
f2_stis = t;
+ t1.real = f1_strs;
+ t1.imag = f1_stis;
+ t2.real = f2_strs;
+ t2.real = f2_stis;
+ */
- //t1 = cadd(t1,f1_intbuf[j]);
- //t2 = cadd(t2,f2_intbuf[j]);
+ t1 = cadd(t1,f1_intbuf[j]);
+ t2 = cadd(t2,f2_intbuf[j]);
}
- f1_int[i].real = f1_strs;
- f1_int[i].imag = f1_stis;
- f2_int[i].real = f2_strs;
- f2_int[i].imag = f2_stis;
+ f1_int[i] = t1;
+ f2_int[i] = t2;
}
/* 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;
t1=comp0();
for(i=0; i<(nsym+1)*P; i++){
/* Get abs of f1_int[i] and f2_int[i] */
- //ft1 = sqrtf( (f1_int[i].real*f1_int[i].real) + (f1_int[i].imag*f1_int[i].imag) );
- //ft2 = sqrtf( (f2_int[i].real*f2_int[i].real) + (f2_int[i].imag*f2_int[i].imag) );
- ft1 = cabsolute(f1_int[i]);
- ft2 = cabsolute(f2_int[i]);
+ ft1 = sqrtf( (f1_int[i].real*f1_int[i].real) + (f1_int[i].imag*f1_int[i].imag) );
+ ft2 = sqrtf( (f2_int[i].real*f2_int[i].real) + (f2_int[i].imag*f2_int[i].imag) );
+ //ft1 = cabsolute(f1_int[i]);
+ //ft2 = cabsolute(f2_int[i]);
/* 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));
+ //t1 = fcmult(ft1,phi_ft);
+
+ y = t1.real - ft_rc;
+ t = ft_rs + y;
+ ft_rc = (t - ft_rs) - y;
+ ft_rs = t;
+
+ y = t1.imag - ft_ic;
+ t = ft_is + y;
+ ft_ic = (t - ft_is) - y;
+ ft_is = t;
+
phi_ft = cmult(phi_ft,dphift);
}
+ // t1.real = ft_rs;
+ // t1.imag = ft_is;
/* Get the magic angle */
norm_rx_timing = -atan2f(t1.imag,t1.real)/(2*M_PI);
rx_timing = norm_rx_timing*(float)P;