2727function vq_compare(action = " run_curves" , vq_fn , dec= 1 , EbNodB= 3 , in_fn , out_fn )
2828 more off ;
2929 randn(' state' ,1 );
30-
30+ graphics_toolkit(" gnuplot" );
31+
3132 if strcmp(action , " run_curves" )
3233 run_curves(30 * 100 );
3334 end
@@ -123,7 +124,7 @@ function vq_compare(action="run_curves", vq_fn, dec=1, EbNodB=3, in_fn, out_fn)
123124 target_ = vq(rx_indexes + 1 ,: );
124125 diff = target - target_ ;
125126 mse = mean(diff(: ).^2 );
126- printf(" Eb/No: %3.2f dB nframes: %2d nerrors: %3d BER: %4.3f PER: %3.2f mse: %3.2f %3.2f\n" ,
127+ printf(" Eb/No: %3.2f dB nframes: %3d nerrors: %4d BER: %4.3f PER: %3.2f mse: %3.2f %3.2f\n" ,
127128 EbNodB , nframes , nerrors , nerrors / tbits , nper / nframes , mse_noerrors , mse );
128129 results.ber = nerrors / tbits ;
129130 results.per = nper / nframes ;
@@ -133,10 +134,113 @@ function vq_compare(action="run_curves", vq_fn, dec=1, EbNodB=3, in_fn, out_fn)
133134 results.rx_indexes = rx_indexes ;
134135endfunction
135136
137+ % VQ a target sequence of frames then run a test using a LDPC code
138+ function results = run_test_ldpc(target , vq , EbNo , verbose )
139+ [frames tmp ] = size(target );
140+ [vq_length tmp ] = size(vq );
141+ nbits = log2(vq_length );
142+ nerrors = 0 ;
143+ tbits = 0 ;
144+ nframes = 0 ;
145+ nper = 0 ;
146+
147+ % init LDPC code
148+ mod_order = 4 ; bps = 2 ;
149+ modulation = ' QPSK' ;
150+ mapping = ' gray' ;
151+ max_iterations = 100 ; demod_type = 0 ; decoder_type = 0 ;
152+ ldpc ; init_cml(' ~/cml/' );
153+ tempStruct = load(" HRA_56_56.txt" );
154+ b = fieldnames(tempStruct );
155+ ldpcArrayName = b{1 ,1 };
156+ % extract the array from the struct
157+ HRA = tempStruct.(ldpcArrayName );
158+ [code_param framesize rate ] = ldpc_init_user(HRA , modulation , mod_order , mapping );
159+
160+ % set up noise
161+ EbNodB = 10 * log10(EbNo );
162+ EsNodB = EbNodB + 10 * log10(rate ) + 10 * log10(bps );
163+ EsNo = 10 ^(EsNodB / 10 );
164+ variance = 1 / EsNo ;
165+
166+ % Vector Quantise target vectors sequence
167+ [tx_indexes target_ ] = vector_quantiser_fast(vq , target , verbose );
168+ % use convention of indexes starting from 0
169+ tx_indexes -= 1 ;
170+ % mean SD of VQ with no errors
171+ diff = target - target_ ;
172+ mse_noerrors = mean(diff(: ).^2 );
173+
174+ % construct tx frames x nbit matrix using VQ indexes
175+ tx_bits = zeros(frames , nbits );
176+ for f= 1 : frames
177+ tx_bits(f ,: ) = dec2sd(tx_indexes(f ), nbits ) > 0 ;
178+ end
179+
180+ % find a superframe size, that has an integer number of nbits and data_bits_per_frame frames
181+ bits_per_superframe = nbits ;
182+ while mod(bits_per_superframe ,nbits ) || mod(bits_per_superframe ,code_param .data_bits_per_frame )
183+ bits_per_superframe += nbits ;
184+ end
185+
186+ Nsuperframes = floor(frames * nbits / bits_per_superframe );
187+ Nldpc_codewords = Nsuperframes * bits_per_superframe / code_param .data_bits_per_frame ;
188+ frames = Nsuperframes * bits_per_superframe / nbits ;
189+ % printf("bits_per_superframe: %d Nldpc_codewords: %d frames: %d\n", bits_per_superframe, Nldpc_codewords, frames);
190+
191+ % reshape tx_bits matrix into Nldpc_codewords x data_bits_per_frame
192+ tx_bits = tx_bits(1 : frames ,: );
193+ tx_bits_ldpc = reshape(tx_bits ' ,code_param .data_bits_per_frame , Nldpc_codewords )' ;
194+
195+ % modulate tx symbols
196+ tx_symbols = [];
197+ for nn= 1 : Nldpc_codewords
198+ [tx_codeword atx_symbols ] = ldpc_enc(tx_bits_ldpc(nn ,: ), code_param );
199+ tx_symbols = [tx_symbols atx_symbols ];
200+ end
201+
202+ noise = sqrt(variance * 0.5 )*(randn(1 ,length(tx_symbols )) + j * randn(1 ,length(tx_symbols )));
203+ rx_symbols = tx_symbols + noise ;
204+
205+ % LDPC decode
206+ for nn = 1 : Nldpc_codewords
207+ st = (nn - 1 )*code_param .coded_syms_per_frame + 1 ;
208+ en = (nn )*code_param .coded_syms_per_frame ;
209+
210+ arx_codeword = ldpc_dec(code_param , max_iterations , demod_type , decoder_type , rx_symbols(st : en ), EsNo , ones(1 ,code_param .coded_syms_per_frame ));
211+ rx_bits_ldpc(nn ,: ) = arx_codeword(1 : code_param .data_bits_per_frame );
212+ end
213+
214+ % reshape rx_bits_ldpc matrix into frames x nbits
215+ rx_bits = reshape(rx_bits_ldpc ' ,nbits ,frames )' ;
216+
217+ rx_indexes = tx_indexes ;
218+ for f= 1 : frames
219+ rx_indexes(f ) = sum(rx_bits(f ,: ) .* 2 .^(nbits - 1 : -1 : 0 ));
220+ errors = sum(xor(tx_bits(f ,: ), rx_bits(f ,: )));
221+ nerrors += errors ;
222+ if errors nper ++;, end
223+ tbits += nbits ;
224+ nframes ++;
225+ end
226+
227+ EbNodB = 10 * log10(EbNo );
228+ target_ = vq(rx_indexes + 1 ,: );
229+ diff = target - target_ ;
230+ mse = mean(diff(: ).^2 );
231+ printf(" Eb/No: %3.2f dB nframes: %4d nerrors: %4d BER: %4.3f PER: %3.2f mse: %3.2f %3.2f\n" ,
232+ EbNodB , nframes , nerrors , nerrors / tbits , nper / nframes , mse_noerrors , mse );
233+ results.ber = nerrors / tbits ;
234+ results.per = nper / nframes ;
235+ results.mse = mse ;
236+ results.tx_indexes = tx_indexes ;
237+ results.rx_indexes = rx_indexes ;
238+ endfunction
239+
136240% Simulations ---------------------------------------------------------------------
137241
138242% top level function to set up and run a test with a specific vq
139- function [results target_ ] = run_test_vq(vq_fn , target_fn , nframes= 100 , dec= 1 , EbNodB= 3 , verbose= 0 )
243+ function [results target_ ] = run_test_vq(vq_fn , target_fn , nframes= 100 , dec= 1 , EbNodB= 3 , ldpc_en = 0 , verbose= 0 )
140244 K = 20 ; K_st= 2 + 1 ; K_en= 16 + 1 ;
141245
142246 % load VQ
@@ -157,7 +261,11 @@ function vq_compare(action="run_curves", vq_fn, dec=1, EbNodB=3, in_fn, out_fn)
157261
158262 % run a test
159263 EbNo= 10 ^(EbNodB / 10 );
160- results = run_test(target , vqsub , EbNo , verbose );
264+ if ldpc_en
265+ results = run_test_ldpc(target , vqsub , EbNo , verbose );
266+ else
267+ results = run_test(target , vqsub , EbNo , verbose );
268+ end
161269 if verbose
162270 for f= 2 : nframes - 1
163271 printf(" f: %03d tx_index: %04d rx_index: %04d\n" , f , results .tx_indexes(f ), results .rx_indexes(f ));
@@ -182,43 +290,53 @@ function vq_compare(action="run_curves", vq_fn, dec=1, EbNodB=3, in_fn, out_fn)
182290% generate sets of curves
183291function run_curves(frames = 100 , dec= 1 )
184292 target_fn = " ../build_linux/all_speech_8k_lim.f32" ;
185- results1_log = [];
186293 EbNodB = 0 : 5 ;
294+
295+ results1_ldpc_log = [];
187296 for i= 1 : length(EbNodB )
188- results = run_test_vq(" ../build_linux/vq_stage1.f32" , target_fn , frames , dec , EbNodB(i ), verbose= 0 );
189- results1_log = [results1_log results ];
297+ results = run_test_vq(" ../build_linux/vq_stage1.f32" , target_fn , frames , dec , EbNodB(i ), ldpc_en = 1 , verbose= 0 );
298+ results1_ldpc_log = [results1_ldpc_log results ];
190299 end
191- results2_log = [];
300+ results4_ldpc_log = [];
192301 for i= 1 : length(EbNodB )
193- results = run_test_vq(" ../build_linux/vq_stage1_bs001.f32" , target_fn , frames , dec , EbNodB(i ), verbose= 0 );
194- results2_log = [results2_log results ];
302+ results = run_test_vq(" ../build_linux/vq_stage1_bs004.f32" , target_fn , frames , dec , EbNodB(i ), ldpc_en= 1 , verbose= 0 );
303+ results4_ldpc_log = [results4_ldpc_log results ];
304+ end
305+
306+ results1_log = [];
307+ for i= 1 : length(EbNodB )
308+ results = run_test_vq(" ../build_linux/vq_stage1.f32" , target_fn , frames , dec , EbNodB(i ), ldpc_en= 0 , verbose= 0 );
309+ results1_log = [results1_log results ];
195310 end
196311 results4_log = [];
197312 for i= 1 : length(EbNodB )
198- results = run_test_vq(" ../build_linux/vq_stage1_bs004.f32" , target_fn , frames , dec , EbNodB(i ), verbose= 0 );
313+ results = run_test_vq(" ../build_linux/vq_stage1_bs004.f32" , target_fn , frames , dec , EbNodB(i ), ldpc_en = 0 , verbose= 0 );
199314 results4_log = [results4_log results ];
200315 end
201316 for i= 1 : length(results1_log )
202317 ber(i ) = results1_log(i ).ber;
203318 per(i ) = results1_log(i ).per;
204319 mse_noerrors(i ) = sqrt(results1_log(i ).mse_noerrors);
205320 mse_vq1(i ) = sqrt(results1_log(i ).mse);
206- mse_vq2(i ) = sqrt(results2_log(i ).mse);
207321 mse_vq4(i ) = sqrt(results4_log(i ).mse);
322+ mse_vq1_ldpc(i ) = sqrt(results1_ldpc_log(i ).mse);
323+ mse_vq4_ldpc(i ) = sqrt(results4_ldpc_log(i ).mse);
208324 end
209325
210326 figure(1 ); clf ;
211327 semilogy(EbNodB , ber , ' g+-;ber;' ,' linewidth' , 2 ); hold on ;
212328 semilogy(EbNodB , per , ' b+-;per;' ,' linewidth' , 2 );
213329 grid(' minor' ); xlabel(' Eb/No(dB)' );
214-
215- hold off ;
330+ hold off ;
216331
217332 figure(2 ); clf ;
218333 plot(EbNodB , mse_noerrors , " b+-;no errors;" ); hold on ;
219- plot(EbNodB , mse_vq1 , " g+-;vanilla;" );
220- plot(EbNodB , mse_vq2 , " r+-;binary switch;" );
221- plot(EbNodB , mse_vq4 , " b+-;binary switch with prob;" );
334+ plot(EbNodB , mse_vq1 , " g+-;vanilla AWGN;" );
335+ plot(EbNodB , mse_vq4 , " b+-;binary switch;" );
336+ plot(EbNodB , mse_vq1_ldpc , " r+-;ldpc (112,56);" );
337+ plot(EbNodB , mse_vq4_ldpc , " k+-;binary switch ldpc (112,56);" );
338+ load trellis_dec3_nstage3.txt
339+ plot(EbNodB , rms_sd , " c+-;binary switch trellis dec3;" );
222340 hold off ; grid ; title(" RMS SD (dB)" ); xlabel(' Eb/No(dB)' );
223341endfunction
224342
0 commit comments