From ceb2934dc90727ba5a8376ac1566b3b1301cb2a8 Mon Sep 17 00:00:00 2001 From: ismagom Date: Mon, 18 Apr 2016 23:49:15 +0200 Subject: [PATCH] Added static library for srslte for linkage with MEX files. Calibrated SNR estimation --- matlab/tests/equalizer_test.m | 113 +++++------------- srslte/lib/CMakeLists.txt | 23 ++++ srslte/lib/ch_estimation/chest_dl.c | 20 ++-- srslte/lib/ch_estimation/test/CMakeLists.txt | 6 +- .../ch_estimation/test/chest_test_dl_mex.c | 12 +- srslte/lib/fec/test/CMakeLists.txt | 6 +- srslte/lib/mimo/test/CMakeLists.txt | 2 +- srslte/lib/phch/test/CMakeLists.txt | 18 +-- srslte/lib/sync/test/CMakeLists.txt | 6 +- 9 files changed, 92 insertions(+), 114 deletions(-) diff --git a/matlab/tests/equalizer_test.m b/matlab/tests/equalizer_test.m index 45bde11a8..8cbf99373 100644 --- a/matlab/tests/equalizer_test.m +++ b/matlab/tests/equalizer_test.m @@ -6,12 +6,13 @@ clear plot_noise_estimation_only=false; -SNR_values_db=30;%linspace(0,30,8); -Nrealizations=1; +SNR_values_db=linspace(0,30,5); +Nrealizations=4; -Lp=5; -N=512; -enb.NDLRB = 25; % Number of resource blocks +w1=0.1; +w2=0.2; + +enb.NDLRB = 50; % Number of resource blocks enb.CellRefP = 1; % One transmit antenna port enb.NCellID = 0; % Cell ID @@ -19,17 +20,13 @@ enb.CyclicPrefix = 'Normal'; % Normal cyclic prefix enb.DuplexMode = 'FDD'; % FDD K=enb.NDLRB*12; -rstart=(N-K)/2; P=K/6; -Rhphp=zeros(P,P); -Rhhp=zeros(K,P); -Rhh=zeros(K,K); %% Channel Model Configuration cfg.Seed = 0; % Random channel seed cfg.InitTime = 0; cfg.NRxAnts = 1; % 1 receive antenna -cfg.DelayProfile = 'EPA'; +cfg.DelayProfile = 'EVA'; % doppler 5, 70 300 @@ -67,7 +64,7 @@ hls=zeros(4,4*P*10); MSE=zeros(Ntests,Nrealizations,length(SNR_values_db)); noiseEst=zeros(Ntests,Nrealizations,length(SNR_values_db)); -legends={'matlab','ls.linear','mmse','r.smooth'}; +legends={'matlab','ls',num2str(w1),num2str(w2)}; colors={'bo-','rx-','m*-','k+-','c+-'}; colors2={'b-','r-','m-','k-','c-'}; @@ -190,67 +187,17 @@ noiseEst(1,nreal,snr_idx)=mean(tmpnoise)*sqrt(2)*enb.CellRefP; [tmp, ~, ~, noiseEst(2,nreal,snr_idx)] = srslte_chest(enb.NCellID,enb.CellRefP,rxGrid); hest{2}=reshape(tmp, size(hest{1})); -tmp_noise=zeros(2,1); -for sf=[0 5] - enb.NSubframe=sf; - pssSym = ltePSS(enb); - pssInd = ltePSSIndices(enb); - x=reshape(rxGrid(pssInd),[],1); - hh=reshape(hest{2}(pssInd),[],1); - y=hh.*pssSym; - tmp_noise(sf/5+1)=mean(abs(x-y).^2); -end -% noiseEst(2,nreal,snr_idx)=mean(tmp_noise); - -%% MMSE estimation with srsLTE - -% Compute Correlation matrices -M=40; -a=0.1; -hidx=zeros(M,1); -for i=1:M - if (mod(i,2)==1) - hx=floor((i-1)/2)*7+1; - else - hx=floor((i-1)/2)*7+5; - end - hidx(i)=hx; - hp=hest{1}(hls(1,(1:P)+P*(i-1)),hx); - Rhphp = (1-a)*Rhphp+a*(hp*hp'); - Rhhp = (1-a)*Rhhp+a*(hest{1}(:,hx)*hp'); - Rhh = (1-a)*Rhh+a*h(:,hx)*h(:,hx)'; -end -snr_lin=10^(SNR_values_db(snr_idx)/10); -Wi=((Rhphp+(1/snr_lin)*eye(P)))^-1; -W = Rhhp*Wi; - -w=reshape(transpose(W),1,[]); -[tmp, ~, ~, noiseEst(3,nreal,snr_idx)] = srslte_chest(enb.NCellID,enb.CellRefP,rxGrid,w); +%% LS-Linear + averaging with srsLTE +[tmp, ~, ~, noiseEst(3,nreal,snr_idx)] = srslte_chest(enb.NCellID,enb.CellRefP,rxGrid,w1); hest{3}=reshape(tmp, size(hest{1})); - -%% Low-pass filter smoother - -prows=rstart+(1:6:K); -t=0:Lp-1; -alfa=log(2*Lp)/Lp; -c_l=exp(-t*alfa); -c_l2=[c_l zeros(1,N-Lp)]; -C_l=diag(c_l2); -F=dftmtx(N); -R_hh=F*C_l*F'; -R_hh=R_hh(prows,prows); -W3=R_hh*(R_hh+0.05*eye(P))^-1; - -w3=reshape(transpose(W3),1,[]); -[tmp, pilot_avg, ~, noiseEst(4,nreal,snr_idx)] = srslte_chest(enb.NCellID,enb.CellRefP,rxGrid,w3); +%% LS-Linear + more averaging with srsLTE +[tmp, ~, ~, noiseEst(4,nreal,snr_idx)] = srslte_chest(enb.NCellID,enb.CellRefP,rxGrid,w2); hest{4}=reshape(tmp, size(hest{1})); - - %% Compute MSE for i=1:Ntests - MSE(i,nreal,snr_idx)=mean(mean(abs(h(:,hidx)-hest{i}(:,hidx)).^2)); + MSE(i,nreal,snr_idx)=mean(mean(abs(h-hest{i}).^2)); fprintf('MSE test %d: %f\n',i, 10*log10(MSE(i,nreal,snr_idx))); end @@ -297,7 +244,7 @@ mean_snr=10*log10(1./mean(noiseEst,2)); %% Plot average over all SNR values if (length(SNR_values_db) > 1) - subplot(1,1,1) + subplot(1,2,1) for i=1:Ntests plot(SNR_values_db, 10*log10(mean_mse(i,:)),colors{i}) hold on; @@ -308,21 +255,21 @@ if (length(SNR_values_db) > 1) xlabel('SNR (dB)') ylabel('MSE (dB)') -% subplot(1,2,2) -% plot(SNR_values_db, SNR_values_db,'k:') -% hold on; -% for i=1:Ntests -% plot(SNR_values_db, mean_snr(i,:), colors{i}) -% end -% hold off -% tmp=cell(Ntests+1,1); -% tmp{1}='Theory'; -% for i=2:Ntests+1 -% tmp{i}=legends{i-1}; -% end -% legend(tmp) -% grid on -% xlabel('SNR (dB)') -% ylabel('Estimated SNR (dB)') + subplot(1,2,2) + plot(SNR_values_db, SNR_values_db,'k:') + hold on; + for i=1:Ntests + plot(SNR_values_db, mean_snr(i,:), colors{i}) + end + hold off + tmp=cell(Ntests+1,1); + tmp{1}='Theory'; + for i=2:Ntests+1 + tmp{i}=legends{i-1}; + end + legend(tmp) + grid on + xlabel('SNR (dB)') + ylabel('Estimated SNR (dB)') end diff --git a/srslte/lib/CMakeLists.txt b/srslte/lib/CMakeLists.txt index fddbd45ba..5f2fac04b 100644 --- a/srslte/lib/CMakeLists.txt +++ b/srslte/lib/CMakeLists.txt @@ -53,6 +53,29 @@ add_library(srslte SHARED version.c $ $ ) + + +if(NOT DisableMEX) + add_library(srslte_static STATIC version.c + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + ) +endif(NOT DisableMEX) + target_link_libraries(srslte pthread m ${FFTW3F_LIBRARIES}) set_target_properties(srslte PROPERTIES VERSION ${SRSLTE_VERSION_MAJOR}.${SRSLTE_VERSION_MINOR}) diff --git a/srslte/lib/ch_estimation/chest_dl.c b/srslte/lib/ch_estimation/chest_dl.c index c2ec616a6..d34df6219 100644 --- a/srslte/lib/ch_estimation/chest_dl.c +++ b/srslte/lib/ch_estimation/chest_dl.c @@ -163,13 +163,11 @@ void srslte_chest_dl_free(srslte_chest_dl_t *q) } /* Uses the difference between the averaged and non-averaged pilot estimates */ -static float estimate_noise_pilots(srslte_chest_dl_t *q, cf_t *ce, uint32_t port_id) +static float estimate_noise_pilots(srslte_chest_dl_t *q, uint32_t port_id) { int nref=SRSLTE_REFSIGNAL_NUM_SF(q->cell.nof_prb, port_id); - /* Get averaged pilots from channel estimates */ - srslte_refsignal_cs_get_sf(q->cell, port_id, ce, q->tmp_noise); /* Substract noisy pilot estimates */ - srslte_vec_sub_ccc(q->tmp_noise, q->pilot_estimates, q->tmp_noise, nref); + srslte_vec_sub_ccc(q->pilot_estimates_average, q->pilot_estimates, q->tmp_noise, nref); #ifdef FREQ_SEL_SNR /* Compute frequency-selective SNR */ @@ -181,7 +179,7 @@ static float estimate_noise_pilots(srslte_chest_dl_t *q, cf_t *ce, uint32_t port #endif /* Compute average power */ - float power = 2*q->cell.nof_ports*srslte_vec_avg_power_cf(q->tmp_noise, nref); + float power = (1/q->smooth_filter[0])*q->cell.nof_ports*srslte_vec_avg_power_cf(q->tmp_noise, nref); return power; } @@ -201,7 +199,7 @@ static float estimate_noise_pss(srslte_chest_dl_t *q, cf_t *input, cf_t *ce) srslte_vec_sub_ccc(q->tmp_pss_noisy, q->tmp_pss, q->tmp_pss_noisy, SRSLTE_PSS_LEN); /* Compute average power */ - float power = sqrt(2)*q->cell.nof_ports*srslte_vec_avg_power_cf(q->tmp_pss_noisy, SRSLTE_PSS_LEN); + float power = q->cell.nof_ports*srslte_vec_avg_power_cf(q->tmp_pss_noisy, SRSLTE_PSS_LEN); return power; } @@ -267,8 +265,12 @@ static void interpolate_pilots(srslte_chest_dl_t *q, cf_t *pilot_estimates, cf_t void srslte_chest_dl_set_smooth_filter(srslte_chest_dl_t *q, float *filter, uint32_t filter_len) { if (filter_len < SRSLTE_CHEST_DL_MAX_SMOOTH_FIL_LEN) { - memcpy(q->smooth_filter, filter, filter_len*sizeof(float)); - q->smooth_filter_len = filter_len; + if (filter) { + memcpy(q->smooth_filter, filter, filter_len*sizeof(float)); + q->smooth_filter_len = filter_len; + } else { + q->smooth_filter_len = 0; + } } else { fprintf(stderr, "Error setting smoothing filter: filter len exceeds maximum (%d>%d)\n", filter_len, SRSLTE_CHEST_DL_MAX_SMOOTH_FIL_LEN); @@ -320,7 +322,7 @@ int srslte_chest_dl_estimate_port(srslte_chest_dl_t *q, cf_t *input, cf_t *ce, u /* If averaging, compute noise from difference between received and averaged estimates */ if (sf_idx == 0 || sf_idx == 5) { - q->noise_estimate[port_id] = estimate_noise_pilots(q, ce, port_id); + q->noise_estimate[port_id] = estimate_noise_pilots(q, port_id); } } else { interpolate_pilots(q, q->pilot_estimates, ce, port_id); diff --git a/srslte/lib/ch_estimation/test/CMakeLists.txt b/srslte/lib/ch_estimation/test/CMakeLists.txt index ecd0a25db..5866a118d 100644 --- a/srslte/lib/ch_estimation/test/CMakeLists.txt +++ b/srslte/lib/ch_estimation/test/CMakeLists.txt @@ -37,7 +37,7 @@ add_test(chest_test_dl_cellid2 chest_test_dl -c 2 -r 50) # Downlink MEX libs ######################################################################## -BuildMex(MEXNAME chest SOURCES chest_test_dl_mex.c LIBRARIES srslte srslte_mex) +BuildMex(MEXNAME chest SOURCES chest_test_dl_mex.c LIBRARIES srslte_static srslte_mex) ######################################################################## @@ -47,9 +47,9 @@ BuildMex(MEXNAME chest SOURCES chest_test_dl_mex.c LIBRARIES srslte srslte_mex) add_executable(refsignal_ul_test_all refsignal_ul_test.c) target_link_libraries(refsignal_ul_test_all srslte) -BuildMex(MEXNAME refsignal_pusch SOURCES refsignal_pusch_mex.c LIBRARIES srslte srslte_mex) +BuildMex(MEXNAME refsignal_pusch SOURCES refsignal_pusch_mex.c LIBRARIES srslte_static srslte_mex) -BuildMex(MEXNAME refsignal_srs SOURCES refsignal_srs_mex.c LIBRARIES srslte srslte_mex) +BuildMex(MEXNAME refsignal_srs SOURCES refsignal_srs_mex.c LIBRARIES srslte_static srslte_mex) diff --git a/srslte/lib/ch_estimation/test/chest_test_dl_mex.c b/srslte/lib/ch_estimation/test/chest_test_dl_mex.c index 789f4aa6d..579397019 100644 --- a/srslte/lib/ch_estimation/test/chest_test_dl_mex.c +++ b/srslte/lib/ch_estimation/test/chest_test_dl_mex.c @@ -40,8 +40,7 @@ void help() { mexErrMsgTxt - ("[estChannel, avg_refs, output] = srslte_chest(cell_id, nof_ports, inputSignal,[sf_idx|freq_filter]," - "[time_filter])\n\n" + ("[estChannel, avg_refs, output] = srslte_chest(cell_id, nof_ports, inputSignal)\n\n" " Returns a matrix of size equal to the inputSignal matrix with the channel estimates\n " "for each resource element in inputSignal. The inputSignal matrix is the received Grid\n" "of size nof_resource_elements x nof_ofdm_symbols.\n" @@ -146,6 +145,13 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) if (nsubframes != 1) { sf_idx = sf%10; } + + if (nrhs > NOF_INPUTS) { + float w = (float) mxGetScalar(prhs[NOF_INPUTS]); + srslte_chest_dl_set_smooth_filter3_coeff(&chest, w); + } else { + srslte_chest_dl_set_smooth_filter(&chest, NULL, 0); + } if (srslte_chest_dl_estimate(&chest, input_signal, ce, sf_idx)) { mexErrMsgTxt("Error running channel estimator\n"); @@ -194,7 +200,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) } } } - + if (nlhs >= 4) { plhs[3] = mxCreateDoubleScalar(noise_power); } diff --git a/srslte/lib/fec/test/CMakeLists.txt b/srslte/lib/fec/test/CMakeLists.txt index 2a240d591..27dd144de 100644 --- a/srslte/lib/fec/test/CMakeLists.txt +++ b/srslte/lib/fec/test/CMakeLists.txt @@ -35,7 +35,7 @@ add_test(rm_conv_test_2 rm_conv_test -t 1920 -r 480) add_test(rm_turbo_test_1 rm_turbo_test -e 1920) add_test(rm_turbo_test_2 rm_turbo_test -e 8192) -BuildMex(MEXNAME rm_turbo_rx SOURCES rm_turbo_rx_mex.c LIBRARIES srslte srslte_mex) +BuildMex(MEXNAME rm_turbo_rx SOURCES rm_turbo_rx_mex.c LIBRARIES srslte_static srslte_mex) ######################################################################## # Turbo Coder TEST @@ -48,7 +48,7 @@ add_test(turbodecoder_test_504_2 turbodecoder_test -n 100 -s 1 -l 504 -e 2.0 -t) add_test(turbodecoder_test_6114_1_5 turbodecoder_test -n 100 -s 1 -l 6144 -e 1.5 -t) add_test(turbodecoder_test_known turbodecoder_test -n 1 -s 1 -k -e 0.5) -BuildMex(MEXNAME turbodecoder SOURCES turbodecoder_test_mex.c LIBRARIES srslte srslte_mex) +BuildMex(MEXNAME turbodecoder SOURCES turbodecoder_test_mex.c LIBRARIES srslte_static srslte_mex) add_executable(turbocoder_test turbocoder_test.c) target_link_libraries(turbocoder_test srslte) @@ -71,7 +71,7 @@ add_test(viterbi_1000_2 viterbi_test -n 100 -s 1 -l 1000 -t -e 2.0) add_test(viterbi_1000_3 viterbi_test -n 100 -s 1 -l 1000 -t -e 3.0) add_test(viterbi_1000_4 viterbi_test -n 100 -s 1 -l 1000 -t -e 4.5) -BuildMex(MEXNAME viterbi SOURCES viterbi_test_mex.c LIBRARIES srslte srslte_mex) +BuildMex(MEXNAME viterbi SOURCES viterbi_test_mex.c LIBRARIES srslte_static srslte_mex) ######################################################################## # CRC TEST diff --git a/srslte/lib/mimo/test/CMakeLists.txt b/srslte/lib/mimo/test/CMakeLists.txt index 8a633c9b1..b0fc0a78d 100644 --- a/srslte/lib/mimo/test/CMakeLists.txt +++ b/srslte/lib/mimo/test/CMakeLists.txt @@ -62,7 +62,7 @@ add_test(precoding_diversity4 precoding_test -n 1024 -m diversity -l 4 -p 4) # MEX file for predecoding and layer demapping test -BuildMex(MEXNAME diversitydecode SOURCES diversitydecode_mex.c LIBRARIES srslte srslte_mex) +BuildMex(MEXNAME diversitydecode SOURCES diversitydecode_mex.c LIBRARIES srslte_static srslte_mex) diff --git a/srslte/lib/phch/test/CMakeLists.txt b/srslte/lib/phch/test/CMakeLists.txt index 052373291..ea1d14aca 100644 --- a/srslte/lib/phch/test/CMakeLists.txt +++ b/srslte/lib/phch/test/CMakeLists.txt @@ -32,7 +32,7 @@ add_test(pbch_test_50 pbch_test -p 1 -n 50 -c 50) add_test(pbch_test_502 pbch_test -p 2 -n 50 -c 50) add_test(pbch_test_504 pbch_test -p 4 -n 50 -c 50) -BuildMex(MEXNAME pbch SOURCES pbch_test_mex.c LIBRARIES srslte srslte_mex) +BuildMex(MEXNAME pbch SOURCES pbch_test_mex.c LIBRARIES srslte_static srslte_mex) ######################################################################## @@ -49,7 +49,7 @@ add_test(pcfich_test_10 pcfich_test -p 1 -n 10) add_test(pcfich_test_102 pcfich_test -p 2 -n 10) add_test(pcfich_test_104 pcfich_test -p 4 -n 10) -BuildMex(MEXNAME pcfich SOURCES pcfich_test_mex.c LIBRARIES srslte srslte_mex) +BuildMex(MEXNAME pcfich SOURCES pcfich_test_mex.c LIBRARIES srslte_static srslte_mex) ######################################################################## # PHICH TEST @@ -83,7 +83,7 @@ add_test(pdcch_test pdcch_test) add_executable(dci_unpacking dci_unpacking.c) target_link_libraries(dci_unpacking srslte) -BuildMex(MEXNAME pdcch SOURCES pdcch_test_mex.c LIBRARIES srslte srslte_mex) +BuildMex(MEXNAME pdcch SOURCES pdcch_test_mex.c LIBRARIES srslte_static srslte_mex) ######################################################################## # PDSCH TEST @@ -96,8 +96,8 @@ add_test(pdsch_test_qpsk pdsch_test -m 10 -n 50 -r 1) add_test(pdsch_test_qam16 pdsch_test -m 20 -n 100) add_test(pdsch_test_qam64 pdsch_test -m 28 -n 100 -r 0) -BuildMex(MEXNAME pdsch SOURCES pdsch_test_mex.c LIBRARIES srslte srslte_mex) -BuildMex(MEXNAME dlsch_encode SOURCES dlsch_encode_test_mex.c LIBRARIES srslte srslte_mex) +BuildMex(MEXNAME pdsch SOURCES pdsch_test_mex.c LIBRARIES srslte_static srslte_mex) +BuildMex(MEXNAME dlsch_encode SOURCES dlsch_encode_test_mex.c LIBRARIES srslte_static srslte_mex) ######################################################################## # FILE TEST @@ -131,8 +131,8 @@ add_test(pdsch_pdcch_file_test pdsch_pdcch_file_test -c 1 -f 3 -n 6 -p 1 -i ${CM add_executable(pusch_test pusch_test.c) target_link_libraries(pusch_test srslte) -BuildMex(MEXNAME ulsch_encode SOURCES ulsch_encode_test_mex.c LIBRARIES srslte srslte_mex) -BuildMex(MEXNAME pusch_encode SOURCES pusch_encode_test_mex.c LIBRARIES srslte srslte_mex) +BuildMex(MEXNAME ulsch_encode SOURCES ulsch_encode_test_mex.c LIBRARIES srslte_static srslte_mex) +BuildMex(MEXNAME pusch_encode SOURCES pusch_encode_test_mex.c LIBRARIES srslte_static srslte_mex) add_test(pusch_test pusch_test) @@ -145,7 +145,7 @@ target_link_libraries(pucch_test srslte) add_test(pucch_test pucch_test) -BuildMex(MEXNAME pucch_encode SOURCES pucch_encode_test_mex.c LIBRARIES srslte srslte_mex) +BuildMex(MEXNAME pucch_encode SOURCES pucch_encode_test_mex.c LIBRARIES srslte_static srslte_mex) @@ -190,7 +190,7 @@ add_test(prach_test_multi_n8 prach_test_multi -n 8) add_test(prach_test_multi_n4 prach_test_multi -n 4) -BuildMex(MEXNAME prach SOURCES prach_test_mex.c LIBRARIES srslte srslte_mex) +BuildMex(MEXNAME prach SOURCES prach_test_mex.c LIBRARIES srslte_static srslte_mex) if(UHD_FOUND) diff --git a/srslte/lib/sync/test/CMakeLists.txt b/srslte/lib/sync/test/CMakeLists.txt index c80cd8b84..b6239124f 100644 --- a/srslte/lib/sync/test/CMakeLists.txt +++ b/srslte/lib/sync/test/CMakeLists.txt @@ -41,11 +41,11 @@ if(UHD_FOUND) endif(SRSGUI_FOUND) endif(UHD_FOUND) -BuildMex(MEXNAME pss SOURCES pss_mex.c LIBRARIES srslte srslte_mex) -BuildMex(MEXNAME sss SOURCES sss_mex.c LIBRARIES srslte srslte_mex) +BuildMex(MEXNAME pss SOURCES pss_mex.c LIBRARIES srslte_static srslte_mex) +BuildMex(MEXNAME sss SOURCES sss_mex.c LIBRARIES srslte_static srslte_mex) # Build MEX for cp-based synchronization -BuildMex(MEXNAME cp_synch SOURCES cp_mex.c LIBRARIES srslte srslte_mex) +BuildMex(MEXNAME cp_synch SOURCES cp_mex.c LIBRARIES srslte_static srslte_mex) ######################################################################## # SYNC TEST