From 3f8a23b9b20eaaa5b8458e2e1b66e316e67be5ca Mon Sep 17 00:00:00 2001 From: drowe67 Date: Thu, 28 Nov 2024 15:09:07 +1030 Subject: [PATCH] initial attempt at passing in tx EOO bits via function call (Python) --- CMakeLists.txt | 6 ++---- radae/radae.py | 32 ++++++++++++++++---------------- radae_rxe.py | 6 ++++-- radae_txe.py | 14 +++++++++++++- 4 files changed, 35 insertions(+), 23 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 13e8a64..0c57a6c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -556,10 +556,8 @@ add_test(NAME c_decoder_aux_mpp add_test(NAME radae_eoo_data_py COMMAND sh -c "cd ${CMAKE_SOURCE_DIR}; \ - ./inference.sh model19_check3/checkpoints/checkpoint_epoch_100.pth wav/brian_g8sez.wav /dev/null \ - --EbNodB 10 --freq_offset 13 \ - --rate_Fs --pilots --pilot_eq --eq_ls --cp 0.004 --bottleneck 3 --time_offset -16 --write_rx rx.f32 \ - --prepend_noise 1 --append_noise 1 --end_of_over --auxdata --correct_freq_offset; \ + ${CMAKE_CURRENT_BINARY_DIR}/src/lpcnet_demo -features wav/brian_g8sez.wav features_in.f32; \ + cat features_in.f32 | python3 radae_txe.py --eoo_data_test > rx.f32; \ cat rx.f32 | python3 radae_rxe.py -v 2 --eoo_data_test > /dev/null") set_tests_properties(radae_eoo_data_py PROPERTIES PASS_REGULAR_EXPRESSION "PASS") diff --git a/radae/radae.py b/radae/radae.py index 569356f..00dec6e 100644 --- a/radae/radae.py +++ b/radae/radae.py @@ -220,22 +220,6 @@ def __init__(self, # experimental EOO data symbols (quick and dirty supplimentary txt channel) self.Nseoo = (Ns-1)*Nc # number of EOO data symbols - # use a customer RNG to avoid upsetting some other rather delicate ctests (TODO fix this sensitvity later) - g = torch.Generator().manual_seed(1) - eoo_bits = torch.sign(torch.rand(self.Nseoo*bps,generator=g)-0.5) - self.eoo_bits = eoo_bits - eoo_syms = eoo_bits[::2] + 1j*eoo_bits[1::2] - eoo_syms = torch.reshape(eoo_syms,(1,Ns-1,Nc)) - - eoo_tx = torch.matmul(eoo_syms,self.Winv) - if self.Ncp: - eoo_tx_cp = torch.zeros((1,Ns-1,self.M+Ncp),dtype=torch.complex64) - eoo_tx_cp[:,:,Ncp:] = eoo_tx - eoo_tx_cp[:,:,:Ncp] = eoo_tx_cp[:,:,-Ncp:] - eoo_tx = torch.reshape(eoo_tx_cp,(1,(Ns-1)*(self.M+Ncp)))*self.pilot_gain - if self.bottleneck == 3: - eoo_tx = torch.tanh(torch.abs(eoo_tx)) * torch.exp(1j*torch.angle(eoo_tx)) - self.eoo[0,2*(M+Ncp):Nmf] = eoo_tx print(f"Rs: {Rs:5.2f} Rs': {Rs_dash:5.2f} Ts': {Ts_dash:5.3f} Nsmf: {Nsmf:3d} Ns: {Ns:3d} Nc: {Nc:3d} M: {self.M:d} Ncp: {self.Ncp:d}", file=sys.stderr) @@ -454,6 +438,22 @@ def est_snr(self, r, time_offset=0): SNR_est = Ct/(torch.dot(torch.conj(p),p) - Ct) return SNR_est.real + def set_eoo_bits(self, eoo_bits): + Ns = self.Ns; Ncp = self.Ncp; M = self.M; Nc = self.Nc; Nmf = int((Ns+1)*(M+Ncp)) + + eoo_syms = eoo_bits[::2] + 1j*eoo_bits[1::2] + eoo_syms = torch.reshape(eoo_syms,(1,Ns-1,Nc)) + + eoo_tx = torch.matmul(eoo_syms,self.Winv) + if self.Ncp: + eoo_tx_cp = torch.zeros((1,Ns-1,self.M+Ncp),dtype=torch.complex64) + eoo_tx_cp[:,:,Ncp:] = eoo_tx + eoo_tx_cp[:,:,:Ncp] = eoo_tx_cp[:,:,-Ncp:] + eoo_tx = torch.reshape(eoo_tx_cp,(1,(Ns-1)*(self.M+Ncp)))*self.pilot_gain + if self.bottleneck == 3: + eoo_tx = torch.tanh(torch.abs(eoo_tx)) * torch.exp(1j*torch.angle(eoo_tx)) + self.eoo[0,2*(M+Ncp):Nmf] = eoo_tx + def forward(self, features, H, G=None): (num_batches, num_ten_ms_timesteps, num_features) = features.shape diff --git a/radae_rxe.py b/radae_rxe.py index 127d8e0..8a2f0b6 100644 --- a/radae_rxe.py +++ b/radae_rxe.py @@ -347,8 +347,10 @@ def do_radae_rx(self, buffer_complex, floats_out): if (ret & 1) and args.use_stdout: sys.stdout.buffer.write(floats_out) if (ret & 2) and args.eoo_data_test: - n_bits = rx.model.Nseoo*rx.model.bps - tx_bits = rx.model.eoo_bits.cpu().detach().numpy().flatten() + # same RNG as tx + g = torch.Generator().manual_seed(1) + tx_bits = torch.sign(torch.rand(rx.model.Nseoo*rx.model.bps,generator=g)-0.5).detach().numpy() + n_bits = len(tx_bits) n_errors = sum(floats_out[:n_bits]*tx_bits < 0) ber = n_errors/n_bits print(f"EOO data n_bits: {n_bits} n_errors: {n_errors} BER: {ber:5.2f}", file=sys.stderr) diff --git a/radae_txe.py b/radae_txe.py index 4e09eb8..7a8ad9f 100644 --- a/radae_txe.py +++ b/radae_txe.py @@ -143,10 +143,17 @@ def do_eoo(self,tx_out): parser.add_argument('--noauxdata', dest="auxdata", action='store_false', help='disable injection of auxillary data symbols') parser.add_argument('--txbpf', action='store_true', help='enable Tx BPF') parser.add_argument('--bypass_enc', action='store_true', help='Bypass core encoder, read z from stdin') + parser.add_argument('--eoo_data_test', action='store_true', help='experimental EOO data test - tx test frame') parser.set_defaults(auxdata=True) args = parser.parse_args() tx = radae_tx(model_name=args.model_name, auxdata=args.auxdata, txbpf_en=args.txbpf, bypass_enc=args.bypass_enc) - + + if args.eoo_data_test: + # use a custom RNG to avoid upsetting some other rather delicate ctests (TODO fix this sensitvity later) + g = torch.Generator().manual_seed(1) + tx_bits = torch.sign(torch.rand(tx.model.Nseoo*tx.model.bps,generator=g)-0.5) + tx.model.set_eoo_bits(tx_bits) + tx_out = np.zeros(tx.Nmf,dtype=np.csingle) while True: buffer = sys.stdin.buffer.read(tx.n_floats_in*struct.calcsize("f")) @@ -159,3 +166,8 @@ def do_eoo(self,tx_out): eoo_out = np.zeros(tx.Neoo,dtype=np.csingle) tx.do_eoo(eoo_out) sys.stdout.buffer.write(eoo_out) + if args.eoo_data_test: + # trailing silence so Rx has enough sample to process EOO frame + eoo_out = np.zeros(tx.Neoo,dtype=np.csingle) + sys.stdout.buffer.write(eoo_out) +