rate Fs tx and rx filtering working, a preliminary frame sync (coarse timing) and...
authordrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Wed, 18 Mar 2015 21:32:56 +0000 (21:32 +0000)
committerdrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Wed, 18 Mar 2015 21:32:56 +0000 (21:32 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@2082 01035d8c-6547-0410-b346-abe4f91aad63

codec2-dev/octave/fdmdv.m
codec2-dev/octave/gmsk.m
codec2-dev/octave/tcohpsk.m

index c0ad4540f8a9834be2def3d62d9afe1c56ec775e..4fcdc153e40a63e6fc6dfe1abfe6e5ddb0900596 100644 (file)
@@ -247,54 +247,35 @@ endfunction
 
 % Frequency shift each modem carrier down to Nc+1 baseband signals
 
-function rx_baseband = fdm_downconvert(rx_fdm, nin)
-  global Fs;
-  global M;
-  global Nc;
-  global Fsep;
-  global phase_rx;
-  global freq;
-
-  rx_baseband = zeros(1,nin);
+function [rx_baseband fdmdv] = fdm_downconvert(fdmdv, rx_fdm, nin)
+  Fs = fdmdv.Fs;
+  M = fdmdv.M;
+  Nc = fdmdv.Nc;
+  phase_rx = fdmdv.phase_rx;
+  freq = fdmdv.freq;
 
-  % Nc/2 tones below centre freq
+  rx_baseband = zeros(Nc+1,nin);
   
-  for c=1:Nc/2
-      for i=1:nin
-        phase_rx(c) = phase_rx(c) * freq(c);
-       rx_baseband(c,i) = rx_fdm(i)*phase_rx(c)';
-      end
-  end
-
-  % Nc/2 tones above centre freq  
-
-  for c=Nc/2+1:Nc
+  for c=1:Nc+1
       for i=1:nin
         phase_rx(c) = phase_rx(c) * freq(c);
        rx_baseband(c,i) = rx_fdm(i)*phase_rx(c)';
       end
   end
 
-  % Pilot
-
-  c = Nc+1;
-  for i=1:nin
-    phase_rx(c) = phase_rx(c) * freq(c);
-    rx_baseband(c,i) = rx_fdm(i)*phase_rx(c)';
-  end
-
+  fdmdv.phase_rx = phase_rx;
 endfunction
 
 
 % Receive filter each baseband signal at oversample rate P
 
-function rx_filt = rx_filter(rx_baseband, nin)
-  global Nc;
-  global M;
-  global P;
-  global rx_filter_memory;
-  global Nfilter;
-  global gt_alpha5_root;
+function [rx_filt fdmdv] = rx_filter(fdmdv, rx_baseband, nin)
+  Nc = fdmdv.Nc;
+  M = fdmdv.M;
+  P = fdmdv.P;
+  rx_filter_memory = fdmdv.rx_filter_memory;
+  Nfilter = fdmdv.Nfilter;
+  gt_alpha5_root = fdmdv.gt_alpha5_root;
 
   rx_filt = zeros(Nc+1,nin*P/M);
 
@@ -309,16 +290,18 @@ function rx_filt = rx_filter(rx_baseband, nin)
     rx_filter_memory(:,1:Nfilter-N) = rx_filter_memory(:,1+N:Nfilter);
     j+=1;
   end
+
+  fdmdv.rx_filter_memory = rx_filter_memory;
 endfunction
 
 
 % LP filter +/- 1000 Hz, allows us to perfrom rx filtering at a lower rate saving CPU
 
-function rx_fdm_filter = rxdec_filter(rx_fdm, nin)
-  global M;
-  global Nrxdec;
-  global rxdec_coeff;
-  global rxdec_lpf_mem;
+function [rx_fdm_filter fdmdv] = rxdec_filter(fdmdv, rx_fdm, nin)
+  M = fdmdv.M;
+  Nrxdec = fdmdv.Nrxdec;
+  rxdec_coeff = fdmdv.rxdec_coeff;
+  rxdec_lpf_mem = fdmdv.rxdec_lpf_mem;
  
   rxdec_lpf_mem(1:Nrxdec-1+M-nin) = rxdec_lpf_mem(nin+1:Nrxdec-1+M);
   rxdec_lpf_mem(Nrxdec-1+M-nin+1:Nrxdec-1+M) = rx_fdm(1:nin);
@@ -327,6 +310,8 @@ function rx_fdm_filter = rxdec_filter(rx_fdm, nin)
   for i=1:nin
     rx_fdm_filter(i) = rxdec_lpf_mem(i:Nrxdec-1+i) * rxdec_coeff;
   end
+
+  fdmdv.rxdec_lpf_mem = rxdec_lpf_mem;
 end
 
 
@@ -334,17 +319,17 @@ end
 % TODO: Decimate mem update and downconversion, this will save some more CPU and memory
 %       note phase would have to advance 4 times as fast
 
-function rx_filt = down_convert_and_rx_filter(rx_fdm, nin, dec_rate)
-  global Nc;
-  global M;
-  global P;
-  global rx_fdm_mem;
-  global phase_rx;
-  global freq;
-  global freq_pol;
-  global Nfilter;
-  global gt_alpha5_root;
-  global Q;
+function [rx_filt fdmdv] = down_convert_and_rx_filter(fdmdv, rx_fdm, nin, dec_rate)
+  Nc = fdmdv.Nc;
+  M = fdmdv.M;
+  P = fdmdv.P;
+  rx_fdm_mem = fdmdv.rx_fdm_mem;
+  phase_rx = fdmdv.phase_rx;
+  freq = fdmdv.freq;
+  freq_pol = fdmdv.freq_pol;
+  Nfilter = fdmdv.Nfilter;
+  gt_alpha5_root = fdmdv.gt_alpha5_root;
+  Q = fdmdv.Q;
 
   % update memory of rx_fdm
 
@@ -389,6 +374,9 @@ function rx_filt = down_convert_and_rx_filter(rx_fdm, nin, dec_rate)
        k+=1;
      end
   end
+
+  fdmdv.phase_rx   = phase_rx;
+  fdmdv.rx_fdm_mem = rx_fdm_mem;
 endfunction
 
 
@@ -479,15 +467,14 @@ endfunction
 
 % Estimate optimum timing offset, re-filter receive symbols
 
-function [rx_symbols rx_timing_M env] = rx_est_timing(rx_filt, nin)
-  global M;
-  global Nt;
-  global Nc;
-  global rx_filter_mem_timing;
-  global P;
-  global Nfilter;
-  global Nfiltertiming;
-  global gt_alpha5_root;
+function [rx_symbols rx_timing_M env fdmdv] = rx_est_timing(fdmdv, rx_filt, nin)
+  M = fdmdv.M;
+  Nt = fdmdv.Nt;
+  Nc = fdmdv.Nc;
+  rx_filter_mem_timing = fdmdv.rx_filter_mem_timing;
+  P = fdmdv.P;
+  Nfilter = fdmdv.Nfilter;
+  Nfiltertiming = fdmdv.Nfiltertiming;
 
   % nin  adjust 
   % --------------------------------
@@ -537,6 +524,8 @@ function [rx_symbols rx_timing_M env] = rx_est_timing(rx_filt, nin)
   % rx_symbols = rx_filter_mem_timing(:,high_sample+1);
 
   rx_timing_M = norm_rx_timing*M;
+
+  fdmdv.rx_filter_mem_timing = rx_filter_mem_timing;
 endfunction
 
 
index 2092a59358dc02bc8e10bda6bc04475fbbace05e..0549c338992c87301ff5cd33576afc3f2e3314cf 100644 (file)
@@ -837,7 +837,7 @@ function gmsk_rx(rx_file_name, err_file_name)
   Rs = 1200;
   framesize = 480;
   npreamble = 480;
-  fc        = 1900;
+  fc        = 1500;
 
   gmsk_states.npreamble = npreamble;
   gmsk_states.verbose = 1;
@@ -1013,5 +1013,6 @@ endfunction
 %gmsk_rx("ssb-ber5.wav")
 %gmsk_rx("ssb25db.wav")
 %gmsk_rx("~/Desktop/ssb_fm_gmsk_high.wav")
-gmsk_rx("~/Desktop/test_gmsk_28BER.raw")
+%gmsk_rx("~/Desktop/test_gmsk_28BER.raw")
+gmsk_rx("~/Desktop/gmsk_rec1.wav")
 
index b5e6e0607513686c9c82de66fbe23a3891421790..57906e4ff3645ec54b778bcecaf07208eaba07f3 100644 (file)
@@ -71,18 +71,54 @@ Nerrs = Tbits = 0;
 
 fdmdv.Fs = 8000;
 fdmdv.Nc = Nc-1;
-fdmdv.M = Fs/Rs;
+M = fdmdv.M = Fs/Rs;
 fdmdv.tx_filter_memory = zeros(fdmdv.Nc+1, Nfilter);
 fdmdv.Nfilter =  Nfilter;
 fdmdv.gt_alpha5_root = gt_alpha5_root;
 fdmdv.Fsep = 75;
-fdmdv.phase_tx = exp(j*2*pi*(0:Nc)/(Nc+1));
+fdmdv.phase_tx = ones(fdmdv.Nc+1,1);
 freq_hz = Fsep*( -Nc/2 - 0.5 + (1:Nc) );
-fdmdv.freq = exp(j*2*pi*freq_hz/Fs);
+fdmdv.freq_pol = 2*pi*freq_hz/Fs;
+fdmdv.freq = exp(j*fdmdv.freq_pol);
 Fcentre = 1500;
 fdmdv.fbb_rect = exp(j*2*pi*Fcentre/Fs);
 fdmdv.fbb_phase_tx = 1;
 
+fdmdv.Nrxdec = 31;
+fdmdv.rxdec_coeff = fir1(fdmdv.Nrxdec-1, 0.25)';
+fdmdv.rxdec_lpf_mem = zeros(1,fdmdv.Nrxdec-1+M);
+
+P = fdmdv.P = 4;
+fdmdv.phase_rx = ones(fdmdv.Nc+1,1);
+fdmdv.Nsym = 6;
+fdmdv.Nfilter = fdmdv.Nsym*fdmdv.M;
+fdmdv.rx_fdm_mem = zeros(1,fdmdv.Nfilter + fdmdv.M);
+Q = fdmdv.Q = fdmdv.M/4;
+
+fdmdv.Nt = 5;
+fdmdv.rx_filter_mem_timing = zeros(fdmdv.Nc+1, fdmdv.Nt*fdmdv.P);
+fdmdv.Nfiltertiming = fdmdv.M + fdmdv.Nfilter + fdmdv.M;
+
+fdmdv.rx_filter_memory = zeros(fdmdv.Nc+1, fdmdv.Nfilter);
+
+rx_filt_log = [];
+rx_fdm_filter_log = [];
+rx_baseband_log = [];
+
+fbb_phase_rx = 1;
+
+% frame of just pilots ofr coarse sync
+
+tx_bits = zeros(1,framesize);
+[tx_symb_pilot tx_bits prev_tx_sym] = bits_to_qpsk_symbols(sim_in, tx_bits, [], []);
+for r=1:(sim_in.Ns+1):sim_in.Nsymbrowpilot
+  tx_symb_pilot(r+1:r+sim_in.Ns,:) = zeros(sim_in.Ns, sim_in.Nc);
+end
+
+ct_symb_buf = zeros(2*sim_in.Nsymbrowpilot, sim_in.Nc);
+
+% main loop --------------------------------------------------------------------
+
 for i=1:frames
   tx_bits = tx_bits_coh(ptx_bits_coh:ptx_bits_coh+framesize-1);
   ptx_bits_coh += framesize;
@@ -93,15 +129,48 @@ for i=1:frames
   tx_bits_log = [tx_bits_log tx_bits];
 
   [tx_symb tx_bits prev_tx_sym] = bits_to_qpsk_symbols(sim_in, tx_bits, [], []);
+  %tx_symb = tx_symb_pilot;
   tx_symb_log = [tx_symb_log; tx_symb];
 
+  tx_fdm_frame = [];
   for r=1:sim_in.Nsymbrowpilot
-    [tx_baseband fdmdv] = tx_filter(fdmdv, rot90(tx_symb(r,:),1));
+    tx_onesymb = tx_symb(r,:);
+    [tx_baseband fdmdv] = tx_filter(fdmdv, tx_onesymb);
     tx_baseband_log = [tx_baseband_log tx_baseband];
     [tx_fdm fdmdv] = fdm_upconvert(fdmdv, tx_baseband);
-    tx_fdm_log = [tx_fdm_log tx_fdm];
+    tx_fdm_frame = [tx_fdm_frame tx_fdm];
   end
+  tx_fdm_log = [tx_fdm_log tx_fdm_frame];
 
+  nin = M;
+
+  % shift frame down to complex baseband
+
+  rx_fdm_frame_bb = zeros(1, sim_in.Nsymbrowpilot*M);
+  for r=1:sim_in.Nsymbrowpilot*M
+    fbb_phase_rx = fbb_phase_rx*fdmdv.fbb_rect';
+    rx_fdm_frame_bb(r) = tx_fdm_frame(r)*fbb_phase_rx;
+  end
+  mag = abs(fbb_phase_rx);
+  fbb_phase_rx /= mag;
+
+  ch_symb = zeros(sim_in.Nsymbrowpilot, Nc);
+  for r=1:sim_in.Nsymbrowpilot
+    %[rx_fdm_filter fdmdv] = rxdec_filter(fdmdv, rx_fdm_frame_bb(1+(r-1)*M:r*M), nin);
+    %rx_fdm_filter_log = [rx_fdm_filter_log rx_fdm_filter];
+    %[rx_filt fdmdv] = down_convert_and_rx_filter(fdmdv, rx_fdm_filter, nin, M/Q);
+
+    [rx_baseband fdmdv] = fdm_downconvert(fdmdv, rx_fdm_frame_bb(1+(r-1)*M:r*M), nin);
+    rx_baseband_log = [rx_baseband_log rx_baseband];
+    [rx_filt fdmdv] = rx_filter(fdmdv, rx_baseband, nin);
+
+    rx_filt_log = [rx_filt_log rx_filt];
+
+    [rx_onesym rx_timing env fdmdv] = rx_est_timing(fdmdv, rx_filt, nin);     
+    ch_symb(r,:) = rx_onesym;
+  end
+
+if 0
   noise = sqrt(variance*0.5)*(randn(sim_in.Nsymbrowpilot,sim_in.Nc) + j*randn(sim_in.Nsymbrowpilot,sim_in.Nc));
   noise_log = [noise_log; noise];
 
@@ -110,9 +179,25 @@ for i=1:frames
     ch_symb(r,:) = tx_symb(r,:)*phase + noise(r,:);  
   end
   phase = phase/abs(phase);
+end
   ch_symb_log = [ch_symb_log; ch_symb];
 
-  [rx_symb rx_bits rx_symb_linear amp_linear amp_ phi_ EsNo_ prev_sym_rx sim_in] = qpsk_symbols_to_bits(sim_in, ch_symb, []);
+  % coarse timing 
+
+  ct_symb_buf(1:sim_in.Nsymbrowpilot,:) = ct_symb_buf(sim_in.Nsymbrowpilot+1:2*sim_in.Nsymbrowpilot,:);
+  ct_symb_buf(sim_in.Nsymbrowpilot+1:2*sim_in.Nsymbrowpilot,:) = ch_symb;
+
+  max_corr = 0;
+  for t=0:sim_in.Nsymbrowpilot-1
+    corr =  sum(sum(rot90(ct_symb_buf(t+1:t+sim_in.Nsymbrowpilot,:),1) * tx_symb_pilot));
+    if corr > max_corr
+      max_corr = corr;
+      ct = t;
+    end
+  end
+  %printf("max_corr: %f ct: %d\n", max_corr, ct);
+
+  [rx_symb rx_bits rx_symb_linear amp_linear amp_ phi_ EsNo_ prev_sym_rx sim_in] = qpsk_symbols_to_bits(sim_in, ct_symb_buf(ct+1:ct+sim_in.Nsymbrowpilot,:), []);
   rx_symb_log = [rx_symb_log; rx_symb];
   rx_amp_log = [rx_amp_log; amp_];
   rx_phi_log = [rx_phi_log; phi_];
@@ -120,12 +205,13 @@ for i=1:frames
 
   % BER stats
 
-  if i > 2
-    error_positions = xor(prev_tx_bits, rx_bits);
+  if i > 3
+    error_positions = xor(prev_tx_bits2, rx_bits);
     Nerrs  += sum(error_positions);
     nerr_log = [nerr_log sum(error_positions)];
     Tbits += length(error_positions);
   end
+  prev_tx_bits2 = prev_tx_bits;
   prev_tx_bits = tx_bits;
 end