diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 90929d563b..95250297a5 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -119,6 +119,7 @@ endmacro(add_list_string_option) #################################################### # compilation flags ############################################# +set (CMAKE_BUILD_TYPE "Debug") if (CMAKE_BUILD_TYPE STREQUAL "") set(CMAKE_BUILD_TYPE "RelWithDebInfo") endif() diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index dc4db92e2b..cad71e4a8f 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -872,7 +872,8 @@ int generate_eNB_dlsch_params_from_dci(int frame, uint16_t si_rnti, uint16_t ra_rnti, uint16_t p_rnti, - uint16_t DL_pmi_single) + uint16_t DL_pmi_single + ) { uint8_t harq_pid = UINT8_MAX; @@ -1538,14 +1539,14 @@ int generate_eNB_dlsch_params_from_dci(int frame, case 0: dlsch0_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODING1; dlsch1_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODING1; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0); - dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,1); + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0,1); + dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,0,1); break; case 1: dlsch0_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODINGj; dlsch1_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODINGj; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,2); - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,3); + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,1,1); + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,1,1); break; case 2: // PUSCH precoding dlsch0_harq->mimo_mode = DUALSTREAM_PUSCH_PRECODING; @@ -1566,19 +1567,19 @@ int generate_eNB_dlsch_params_from_dci(int frame, break; case 1: dlsch0_harq->mimo_mode = UNIFORM_PRECODING11; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0); + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0, 0); break; case 2: dlsch0_harq->mimo_mode = UNIFORM_PRECODING1m1; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,1); + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,1, 0); break; case 3: dlsch0_harq->mimo_mode = UNIFORM_PRECODING1j; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,2); + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,2, 0); break; case 4: dlsch0_harq->mimo_mode = UNIFORM_PRECODING1mj; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,3); + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,3, 0); break; case 5: dlsch0_harq->mimo_mode = PUSCH_PRECODING0; @@ -2108,12 +2109,13 @@ int generate_eNB_dlsch_params_from_dci(int frame, rballoc, frame_parms->N_RB_DL, dlsch0_harq->rb_alloc); - dlsch1_harq->rb_alloc[0] = dlsch0_harq->rb_alloc[0]; + + dlsch1_harq->rb_alloc[0] = dlsch0_harq->rb_alloc[0]; - dlsch0_harq->nb_rb = conv_nprb(rah, - rballoc, - frame_parms->N_RB_DL); - dlsch1_harq->nb_rb = dlsch0_harq->nb_rb; + dlsch0_harq->nb_rb = conv_nprb(rah, + rballoc, + frame_parms->N_RB_DL); + dlsch1_harq->nb_rb = dlsch0_harq->nb_rb; dlsch0_harq->mcs = mcs1; dlsch1_harq->mcs = mcs2; @@ -2557,27 +2559,27 @@ int generate_eNB_dlsch_params_from_dci(int frame, case 1: dlsch0_harq->mimo_mode = UNIFORM_PRECODING11; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0); + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0, 0); break; case 2: dlsch0_harq->mimo_mode = UNIFORM_PRECODING1m1; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,1); + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,1, 0); break; case 3: dlsch0_harq->mimo_mode = UNIFORM_PRECODING1j; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,2); + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,2, 0); break; case 4: dlsch0_harq->mimo_mode = UNIFORM_PRECODING1mj; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,3); + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,3, 0); break; case 5: dlsch0_harq->mimo_mode = PUSCH_PRECODING0; - dlsch0_harq->pmi_alloc = DL_pmi_single; + dlsch0_harq->pmi_alloc = DL_pmi_single; break; case 6: @@ -4795,14 +4797,14 @@ int generate_ue_dlsch_params_from_dci(int frame, case 0: dlsch0_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODING1; dlsch1_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODING1; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0); - dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,1); + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0, 1); + dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,0, 1); break; case 1: dlsch0_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODINGj; dlsch1_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODINGj; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,2); - dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,3); + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,1,1); + dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,1, 1); break; case 2: // PUSCH precoding dlsch0_harq->mimo_mode = DUALSTREAM_PUSCH_PRECODING; @@ -4822,19 +4824,19 @@ int generate_ue_dlsch_params_from_dci(int frame, break; case 1: dlsch0_harq->mimo_mode = UNIFORM_PRECODING11; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0); + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0, 0); break; case 2: dlsch0_harq->mimo_mode = UNIFORM_PRECODING1m1; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,1); + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,1, 0); break; case 3: dlsch0_harq->mimo_mode = UNIFORM_PRECODING1j; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,2); + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,2, 0); break; case 4: dlsch0_harq->mimo_mode = UNIFORM_PRECODING1mj; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,3); + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,3, 0); break; case 5: dlsch0_harq->mimo_mode = PUSCH_PRECODING0; @@ -5523,28 +5525,28 @@ int generate_ue_dlsch_params_from_dci(int frame, case 1: dlsch0_harq->mimo_mode = UNIFORM_PRECODING11; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0); + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0,0); break; case 2: dlsch0_harq->mimo_mode = UNIFORM_PRECODING1m1; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,1); + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,1, 0); break; case 3: dlsch0_harq->mimo_mode = UNIFORM_PRECODING1j; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,2); + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,2, 0); break; case 4: dlsch0_harq->mimo_mode = UNIFORM_PRECODING1mj; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,3); + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,3, 0); break; case 5: dlsch0_harq->mimo_mode = PUSCH_PRECODING0; // pmi stored from ulsch allocation routine - dlsch0_harq->pmi_alloc = dlsch0->pmi_alloc; + dlsch0_harq->pmi_alloc = dlsch0->pmi_alloc; //LOG_I(PHY,"XXX using PMI %x\n",pmi2hex_2Ar1(dlsch0_harq->pmi_alloc)); break; @@ -5779,7 +5781,7 @@ uint16_t quantize_subband_pmi(PHY_MEASUREMENTS *meas,uint8_t eNB_id,int nb_rb) int i, aarx; uint16_t pmiq=0; - uint16_t pmivect = 0; + uint32_t pmivect = 0; // work with tyoe uint8_t rank = meas->rank[eNB_id]; int pmi_re,pmi_im; int nb_subbands=0; @@ -5827,18 +5829,20 @@ uint16_t quantize_subband_pmi(PHY_MEASUREMENTS *meas,uint8_t eNB_id,int nb_rb) // printf("subband %d, pmi%d \n",i,pmiq); pmivect |= (pmiq<<(2*i)); - } + } + else if (rank==1) { for (aarx=0; aarxnb_antennas_rx; aarx++) { pmi_re += meas->subband_pmi_re[eNB_id][i][aarx]; pmi_im += meas->subband_pmi_im[eNB_id][i][aarx]; } if (pmi_re > pmi_im) - pmiq = PMI_2A_11; + pmiq = PMI_2A_R1_11; else if (pmi_re < pmi_im) - pmiq = PMI_2A_1m1; + pmiq = PMI_2A_R1_1j; printf("subband %d, pmi%d \n",i,pmiq); - pmivect |= (pmiq<<(2*i)); + //According to Section 7.2.4 of 36.213 + pmivect |= ((pmiq-1)<<(i)); //shift 1 since only one bit printf("subband %d pmivect %d \n",i, pmivect); } else { @@ -6282,14 +6286,31 @@ void reset_cba_uci(void *o) ((HLC_subband_cqi_mcs_CBA_5MHz *)o)->crnti = 0x0; } -uint32_t pmi_extend(LTE_DL_FRAME_PARMS *frame_parms,uint8_t wideband_pmi) +uint32_t pmi_extend(LTE_DL_FRAME_PARMS *frame_parms,uint8_t wideband_pmi, uint8_t rank) { - uint8_t i,wideband_pmi2=wideband_pmi&3; + uint8_t i,wideband_pmi2; uint32_t pmi_ex = 0; - for (i=0; i<14; i+=2) - pmi_ex|=(wideband_pmi2<N_RB_DL!=25) { + LOG_E(PHY,"pmi_extend not yet implemented for anything else than 25PRB\n"); + return(-1); + } + + if (rank==0) { + wideband_pmi2=wideband_pmi&3; + for (i=0; i<14; i+=2) + pmi_ex|=(wideband_pmi2<lte_ue_pdsch_vars_SI[eNB_id]; @@ -167,10 +172,13 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, else rballoc = dlsch0_harq->rb_alloc_even; - if (dlsch0_harq->mimo_mode>DUALSTREAM_UNIFORM_PRECODINGj) { + if (dlsch0_harq->mimo_mode>DUALSTREAM_PUSCH_PRECODING) { LOG_E(PHY,"This transmission mode is not yet supported!\n"); return(-1); } + + + if ((dlsch0_harq->mimo_mode==LARGE_CDD) || ((dlsch0_harq->mimo_mode>=DUALSTREAM_UNIFORM_PRECODING1) && (dlsch0_harq->mimo_mode<=DUALSTREAM_PUSCH_PRECODING))) { DevAssert(dlsch1_harq); if (eNB_id!=eNB_id_i) { @@ -182,9 +190,9 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, //printf("rx_pdsch: harq_pid=%d, round=%d\n",harq_pid,round); if (frame_parms->nb_antennas_tx_eNB>1) { -#ifdef DEBUG_DLSCH_MOD - LOG_I(PHY,"dlsch: using pmi %x (%p), rb_alloc %x\n",pmi2hex_2Ar1(dlsch0_harq->pmi_alloc),dlsch_ue[0],dlsch0_harq->rb_alloc_even[0]); -#endif +//#ifdef DEBUG_DLSCH_MOD + //printf("dlsch: using pmi %x (%p), rb_alloc %x\n",pmi2hex_2Ar1(dlsch0_harq->pmi_alloc),dlsch_ue[0],dlsch0_harq->rb_alloc_even[0]); +//#endif nb_rb = dlsch_extract_rbs_dual(lte_ue_common_vars->rxdataF, lte_ue_common_vars->dl_ch_estimates[eNB_id], lte_ue_pdsch_vars[eNB_id]->rxdataF_ext, @@ -195,7 +203,8 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, symbol, subframe, phy_vars_ue->high_speed_flag, - frame_parms); + frame_parms, + dlsch0_harq->mimo_mode); if (rx_type==rx_IC_single_stream) { if (eNB_id_in_connected_eNB) // we are in TM5 @@ -209,7 +218,8 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, symbol, subframe, phy_vars_ue->high_speed_flag, - frame_parms); + frame_parms, + dlsch0_harq->mimo_mode); else nb_rb = dlsch_extract_rbs_dual(lte_ue_common_vars->rxdataF, lte_ue_common_vars->dl_ch_estimates[eNB_id], @@ -221,7 +231,8 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, symbol, subframe, phy_vars_ue->high_speed_flag, - frame_parms); + frame_parms, + dlsch0_harq->mimo_mode); } } // if n_tx>1 else { @@ -406,7 +417,8 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, if (first_symbol_flag==1) { // effective channel of desired user is always stronger than interfering eff. channel dlsch_channel_level_TM34(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, - frame_parms, + frame_parms, + lte_ue_pdsch_vars[eNB_id]->pmi_ext, avg, symbol, nb_rb, @@ -418,8 +430,6 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, lte_ue_pdsch_vars[eNB_id]->log2_maxh = log2_approx(avg[0]) - 13 + offset_mumimo_llr_drange[dlsch0_harq->mcs][(get_Qm(dlsch1_harq->mcs)>>1)-1]; } else - - lte_ue_pdsch_vars[eNB_id]->log2_maxh = log2_approx(avg[0])/2; } @@ -488,7 +498,12 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, if (first_symbol_flag==1) { // effective channel of desired user is always stronger than interfering eff. channel - dlsch_channel_level_TM56(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, frame_parms, lte_ue_pdsch_vars[eNB_id]->pmi_ext, avg, symbol, nb_rb); + dlsch_channel_level_TM56(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, + frame_parms, + lte_ue_pdsch_vars[eNB_id]->pmi_ext, + avg, + symbol, + nb_rb); // LOG_D(PHY,"llr_offset = %d\n",offset_mumimo_llr_drange[dlsch0_harq->mcs][(i_mod>>1)-1]); avg[0] = log2_approx(avg[0]) - 13 + offset_mumimo_llr_drange[dlsch0_harq->mcs][(i_mod>>1)-1]; @@ -949,7 +964,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, LOG_W(PHY,"rx_dlsch.c : Unknown mod_order!!!!\n"); return(-1); break; - } + } return(0); } @@ -1388,7 +1403,8 @@ void prec2A_TM4_128(int pmi,__m128i *ch0,__m128i *ch1) { ch0[0] = _mm_srai_epi16(ch0[0],1); //divide by 2 ch1[0] = _mm_srai_epi16(ch1[0],1); //divide by 2 - + _mm_empty(); + _m_empty(); // print_shorts("prec2A_TM4 ch0 (end):",ch0); //print_shorts("prec2A_TM4 ch1 (end):",ch1); } @@ -1814,6 +1830,7 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, int **dl_ch_magb1 = lte_ue_pdsch_vars->dl_ch_magb1; int **rxdataF_comp0 = lte_ue_pdsch_vars->rxdataF_comp0; int **rxdataF_comp1 = lte_ue_pdsch_vars->rxdataF_comp1[harq_pid][round]; + unsigned char **pmi_ext = lte_ue_pdsch_vars->pmi_ext; __m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3,QAM_amp0_128,QAM_amp0_128b,QAM_amp1_128,QAM_amp1_128b; symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; @@ -1884,6 +1901,17 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, prec2A_TM4_128(1,&dl_ch0_128[2],&dl_ch1_128[2]); } } + + else if (mimo_mode==DUALSTREAM_PUSCH_PRECODING) { + prec2A_TM4_128(pmi_ext[rb],&dl_ch0_128[0],&dl_ch1_128[0]); + prec2A_TM4_128(pmi_ext[rb],&dl_ch0_128[1],&dl_ch1_128[1]); + + if (pilots==0) { + prec2A_TM4_128(pmi_ext[rb],&dl_ch0_128[2],&dl_ch1_128[2]); + } + } + + else { LOG_E(PHY,"Unknown MIMO mode\n"); return; @@ -2984,8 +3012,119 @@ void dlsch_channel_level(int **dl_ch_estimates_ext, #endif } +//compute average channel_level of effective (precoded) channel + //compute average channel_level of effective (precoded) channel void dlsch_channel_level_TM34(int **dl_ch_estimates_ext, + LTE_DL_FRAME_PARMS *frame_parms, + unsigned char *pmi_ext, + int *avg, + uint8_t symbol, + unsigned short nb_rb, + MIMO_mode_t mimo_mode){ + +#if defined(__x86_64__)||defined(__i386__) + + + short rb; + unsigned char aarx,nre=12,symbol_mod; + __m128i *dl_ch0_128,*dl_ch1_128, dl_ch0_128_tmp, dl_ch1_128_tmp,avg128D; + + symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; + + //clear average level + avg128D = _mm_setzero_si128(); + avg[0] = 0; + avg[1] = 0; + // 5 is always a symbol with no pilots for both normal and extended prefix + + if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->mode1_flag==0)) + nre=8; + else if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->mode1_flag==1)) + nre=10; + else + nre=12; + + for (aarx=0; aarxnb_antennas_rx; aarx++) { + dl_ch0_128 = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12]; + dl_ch1_128 = (__m128i *)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12]; + + for (rb=0; rbNcp-1)))&&(frame_parms->mode1_flag==0)) { + dl_ch0_128+=2; + dl_ch1_128+=2; + } + else { + dl_ch0_128_tmp = _mm_load_si128(&dl_ch0_128[2]); + dl_ch1_128_tmp = _mm_load_si128(&dl_ch1_128[2]); + + if (mimo_mode==LARGE_CDD) + prec2A_TM3_128(&dl_ch0_128_tmp,&dl_ch1_128_tmp); + else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODING1) + prec2A_TM4_128(0,&dl_ch0_128_tmp,&dl_ch1_128_tmp); + else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODINGj) + prec2A_TM4_128(1,&dl_ch0_128_tmp,&dl_ch1_128_tmp); + else if (mimo_mode==DUALSTREAM_PUSCH_PRECODING) + prec2A_TM4_128(pmi_ext[rb],&dl_ch0_128_tmp,&dl_ch1_128_tmp); + // mmtmpD2 = _mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp); + avg128D = _mm_add_epi32(avg128D,_mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp)); + + dl_ch0_128+=3; + dl_ch1_128+=3; + } + } + + avg[aarx] = (((int*)&avg128D)[0])/(nb_rb*nre) + + (((int*)&avg128D)[1])/(nb_rb*nre) + + (((int*)&avg128D)[2])/(nb_rb*nre) + + (((int*)&avg128D)[3])/(nb_rb*nre); + } + + // choose maximum of the 2 effective channels + avg[0] = cmax(avg[0],avg[1]); + + _mm_empty(); + _m_empty(); + +#elif defined(__arm__) + +#endif +} + + + +/*void dlsch_channel_level_TM34(int **dl_ch_estimates_ext, LTE_DL_FRAME_PARMS *frame_parms, int *avg, uint8_t symbol, @@ -3084,7 +3223,7 @@ void dlsch_channel_level_TM34(int **dl_ch_estimates_ext, #elif defined(__arm__) #endif -} +}*/ //compute average channel_level of effective (precoded) channel void dlsch_channel_level_TM56(int **dl_ch_estimates_ext, @@ -3874,10 +4013,17 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF, unsigned char symbol, unsigned char subframe, uint32_t high_speed_flag, - LTE_DL_FRAME_PARMS *frame_parms) { + LTE_DL_FRAME_PARMS *frame_parms, + MIMO_mode_t mimo_mode) { +/*uint8_t get_pmi(uint8_t N_RB_DL,LTE_DL_eNB_HARQ_t *dlsch_harq,uint16_t rb) +{ + MIMO_mode_t mode = dlsch_harq->mimo_mode;*/ + +//PHY_VARS_UE *phy_vars_ue, + int prb,nb_rb=0; int prb_off,prb_off2; int rb_alloc_ind,skip_half=0,sss_symb,pss_symb=0,nsymb,l; @@ -3885,7 +4031,7 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF, int32_t *dl_ch0,*dl_ch0p,*dl_ch0_ext,*dl_ch1,*dl_ch1p,*dl_ch1_ext,*rxF,*rxF_ext; int symbol_mod,pilots=0,j=0; unsigned char *pmi_loc; - + symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; // printf("extract_rbs: symbol_mod %d\n",symbol_mod); @@ -3999,7 +4145,12 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF, rxF = &rxdataF[aarx][prb_off2+ (symbol*(frame_parms->ofdm_symbol_size))]; } + + if (mimo_mode <= PUSCH_PRECODING1) *pmi_loc = (pmi>>((prb>>2)<<1))&3; + else + *pmi_loc=(pmi>>prb)&1; + pmi_loc++; @@ -4136,8 +4287,11 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF, #ifdef DEBUG_DLSCH_DEMOD printf("symbol %d / rb %d: alloc %d skip_half %d (rxF %p, rxF_ext %p) prb_off (%d,%d)\n",symbol,prb,rb_alloc_ind,skip_half,rxF,rxF_ext,prb_off,prb_off2); #endif - *pmi_loc = (pmi>>((prb>>2)<<1))&3; - // printf("symbol_mod %d (pilots %d) rb %d, sb %d, pmi %d (pmi_loc %p,rxF %p, ch00 %p, ch01 %p, rxF_ext %p dl_ch0_ext %p dl_ch1_ext %p)\n",symbol_mod,pilots,rb,rb>>2,*pmi_loc,pmi_loc,rxF,dl_ch0, dl_ch1, rxF_ext,dl_ch0_ext,dl_ch1_ext); + if (mimo_mode <= PUSCH_PRECODING1) + *pmi_loc = (pmi>>((prb>>2)<<1))&3; + else + *pmi_loc=(pmi>>prb)&1; + // printf("symbol_mod %d (pilots %d) rb %d, sb %d, pmi %d (pmi_loc %p,rxF %p, ch00 %p, ch01 %p, rxF_ext %p dl_ch0_ext %p dl_ch1_ext %p)\n",symbol_mod,pilots,prb,prb>>2,*pmi_loc,pmi_loc,rxF,dl_ch0, dl_ch1, rxF_ext,dl_ch0_ext,dl_ch1_ext); pmi_loc++; diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c index 111f507fea..c4e706b5a7 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c @@ -786,7 +786,7 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms, precoder_index1 = 3; //[1 -j] } else { - LOG_E(PHY,"problem with precoder in TM4\n"); + printf("problem with precoder in TM4\n"); return(-1); } @@ -1254,7 +1254,7 @@ uint8_t get_pmi(uint8_t N_RB_DL,LTE_DL_eNB_HARQ_t *dlsch_harq,uint16_t rb) MIMO_mode_t mode = dlsch_harq->mimo_mode; uint32_t pmi_alloc = dlsch_harq->pmi_alloc; - // printf("Getting pmi for RB %d => %d\n",rb,(pmi_alloc>>((rb>>2)<<1))&3); + printf("Getting pmi for RB %d => %d\n",rb,((pmi_alloc>>rb)&1)); switch (N_RB_DL) { case 6: // 1 PRB per subband if (mode <= PUSCH_PRECODING1) @@ -1369,10 +1369,10 @@ int dlsch_modulation(mod_sym_t **txdataF, for (l=num_pdcch_symbols; lmimo_mode, - pmi2hex_2Ar1(dlsch0_harq->pmi_alloc), + pmi2hex_2Ar2(dlsch0_harq->pmi_alloc), mod_order0, mod_order1, rb_alloc[0], diff --git a/openair1/PHY/LTE_TRANSPORT/proto.h b/openair1/PHY/LTE_TRANSPORT/proto.h index a12a6f6743..79d68ab066 100644 --- a/openair1/PHY/LTE_TRANSPORT/proto.h +++ b/openair1/PHY/LTE_TRANSPORT/proto.h @@ -909,7 +909,8 @@ uint16_t dlsch_extract_rbs_dual(int32_t **rxdataF, uint8_t symbol, uint8_t subframe, uint32_t high_speed_flag, - LTE_DL_FRAME_PARMS *frame_parms); + LTE_DL_FRAME_PARMS *frame_parms, + MIMO_mode_t mimo_mode); /** \brief This function performs channel compensation (matched filtering) on the received RBs for this allocation. In addition, it computes the squared-magnitude of the channel with weightings for 16QAM/64QAM detection as well as dual-stream detection (cross-correlation) @param rxdataF_ext Frequency-domain received signal in RBs to be demodulated @@ -994,6 +995,7 @@ void dlsch_channel_level(int32_t **dl_ch_estimates_ext, void dlsch_channel_level_TM34(int **dl_ch_estimates_ext, LTE_DL_FRAME_PARMS *frame_parms, + unsigned char *pmi_ext, int *avg, uint8_t symbol, unsigned short nb_rb, @@ -1587,7 +1589,7 @@ uint64_t cqi2hex(uint32_t cqi); uint16_t computeRIV(uint16_t N_RB_DL,uint16_t RBstart,uint16_t Lcrbs); -uint32_t pmi_extend(LTE_DL_FRAME_PARMS *frame_parms,uint8_t wideband_pmi); +uint32_t pmi_extend(LTE_DL_FRAME_PARMS *frame_parms,uint8_t wideband_pmi, uint8_t rank); uint16_t get_nCCE(uint8_t num_pdcch_symbols,LTE_DL_FRAME_PARMS *frame_parms,uint8_t mi); diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 3a392c01be..a72ab6a01e 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -450,7 +450,7 @@ int main(int argc, char **argv) case 'w': snr_int = atof(optarg); break; - + case 'f': input_snr_step= atof(optarg); break; @@ -1529,7 +1529,7 @@ n(tikz_fname,"w"); ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 1; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; break; case 50: dci_length = sizeof_DCI1A_10MHz_TDD_1_6_t; @@ -1662,7 +1662,7 @@ n(tikz_fname,"w"); ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 0; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 2; break; case 25: dci_length = sizeof_DCI2_5MHz_2A_TDD_t; @@ -1679,7 +1679,7 @@ n(tikz_fname,"w"); ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 0; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 2; break; case 50: @@ -1697,7 +1697,7 @@ n(tikz_fname,"w"); ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 0; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 2; break; case 100: @@ -1713,7 +1713,7 @@ n(tikz_fname,"w"); ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 0; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 2; dci_length = sizeof_DCI2_20MHz_2A_TDD_t; dci_length_bytes = sizeof(DCI2_20MHz_2A_TDD_t); break; @@ -1791,6 +1791,12 @@ n(tikz_fname,"w"); else if (PHY_vars_eNB->lte_frame_parms.nb_antennas_tx == 4) { } + + if (((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 2) { // not a nice way to do it, fix later + + PHY_vars_eNB->eNB_UE_stats[0].DL_pmi_single = (unsigned short)(taus()&0xffff); + + } memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes); dci_alloc[num_dci].dci_length = dci_length; @@ -2765,6 +2771,14 @@ n(tikz_fname,"w"); } */ } + + + if (transmission_mode==4 && (((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 2)){ + PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->pmi_alloc = quantize_subband_pmi(&PHY_vars_UE->PHY_measurements,0,PHY_vars_eNB->lte_frame_parms.N_RB_DL); + PHY_vars_UE->dlsch_ue[0][0]->pmi_alloc = quantize_subband_pmi(&PHY_vars_UE->PHY_measurements,0,PHY_vars_UE->lte_frame_parms.N_RB_DL); + } + + start_meas(&PHY_vars_eNB->dlsch_encoding_stats); @@ -2929,10 +2943,6 @@ n(tikz_fname,"w"); // r_re[1][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][1]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)]); // r_im[1][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][1]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)+1]); -// printf("r_re0 = %d\n",r_re[0][i]); -// printf("r_im0 = %d\n",r_im[0][i]); -// printf("r_re1 = %d\n",r_re[1][i]); -// printf("r_im1 = %d\n",r_im[1][i]); } else { @@ -3165,7 +3175,7 @@ n(tikz_fname,"w"); PHY_vars_UE->PHY_measurements.wideband_cqi_avg[0]); */ - if (transmission_mode==5 || transmission_mode==6) { + if (transmission_mode == 4 || transmission_mode == 5 || transmission_mode == 6) { if (pmi_feedback == 1) { pmi_feedback = 0; hold_channel = 1; diff --git a/openair1/SIMULATION/TOOLS/random_channel.c b/openair1/SIMULATION/TOOLS/random_channel.c index 027dc84cf5..a378a56c76 100644 --- a/openair1/SIMULATION/TOOLS/random_channel.c +++ b/openair1/SIMULATION/TOOLS/random_channel.c @@ -1,5 +1,5 @@ /******************************************************************************* - OpenAirInterface + OpenAirInterface Copyright(c) 1999 - 2014 Eurecom OpenAirInterface is free software: you can redistribute it and/or modify @@ -14,15 +14,15 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, + along with OpenAirInterface.The full GNU General Public License is + included in this distribution in the file called "COPYING". If not, see . Contact Information OpenAirInterface Admin: openair_admin@eurecom.fr OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr - + OpenAirInterface Dev : openair4g-devel@eurecom.fr + Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE *******************************************************************************/ @@ -42,29 +42,28 @@ extern void print_shorts(char *s,__m128i *x); void fill_channel_desc(channel_desc_t *chan_desc, - uint8_t nb_tx, - uint8_t nb_rx, - uint8_t nb_taps, - uint8_t channel_length, - double *amps, - double *delays, - struct complex** R_sqrt, - double Td, - double BW, - double ricean_factor, - double aoa, - double forgetting_factor, - double max_Doppler, - int32_t channel_offset, - double path_loss_dB, - uint8_t random_aoa) -{ - + uint8_t nb_tx, + uint8_t nb_rx, + uint8_t nb_taps, + uint8_t channel_length, + double *amps, + double *delays, + struct complex** R_sqrt, + double Td, + double BW, + double ricean_factor, + double aoa, + double forgetting_factor, + double max_Doppler, + int32_t channel_offset, + double path_loss_dB, + uint8_t random_aoa) { + uint16_t i,j; double delta_tau; LOG_I(OCM,"[CHANNEL] Getting new channel descriptor, nb_tx %d, nb_rx %d, nb_taps %d, channel_length %d\n", - nb_tx,nb_rx,nb_taps,channel_length); + nb_tx,nb_rx,nb_taps,channel_length); chan_desc->nb_tx = nb_tx; chan_desc->nb_rx = nb_rx; @@ -72,14 +71,13 @@ void fill_channel_desc(channel_desc_t *chan_desc, chan_desc->channel_length = channel_length; chan_desc->amps = amps; LOG_D(OCM,"[CHANNEL] Doing delays ...\n"); - if (delays==NULL) { chan_desc->delays = (double*) malloc(nb_taps*sizeof(double)); delta_tau = Td/nb_taps; - for (i=0; idelays[i] = ((double)i)*delta_tau; - } else + } + else chan_desc->delays = delays; chan_desc->Td = Td; @@ -99,30 +97,26 @@ void fill_channel_desc(channel_desc_t *chan_desc, LOG_D(OCM,"[CHANNEL] Filling ch \n"); - for (i = 0; ich[i] = (struct complex*) malloc(channel_length * sizeof(struct complex)); + for (i = 0; ich[i] = (struct complex*) malloc(channel_length * sizeof(struct complex)); - for (i = 0; ichF[i] = (struct complex*) malloc(1200 * sizeof(struct complex)); // allocate for up to 100 RBs, 12 samples per RB LOG_D(OCM,"[CHANNEL] Filling a (nb_taps %d)\n",nb_taps); - for (i = 0; ia[i],nb_tx*nb_rx * sizeof(struct complex)); chan_desc->a[i] = (struct complex*) malloc(nb_tx*nb_rx * sizeof(struct complex)); } LOG_D(OCM,"[CHANNEL] Doing R_sqrt ...\n"); - if (R_sqrt == NULL) { - chan_desc->R_sqrt = (struct complex**) calloc(nb_taps,sizeof(struct complex*)); - + chan_desc->R_sqrt = (struct complex**) calloc(nb_taps,sizeof(struct complex*)); for (i = 0; iR_sqrt[i] = (struct complex*) calloc(nb_tx*nb_rx*nb_tx*nb_rx,sizeof(struct complex)); - + chan_desc->R_sqrt[i] = (struct complex*) calloc(nb_tx*nb_rx*nb_tx*nb_rx,sizeof(struct complex)); for (j = 0; jR_sqrt[i][j].x = 1.0; - chan_desc->R_sqrt[i][j].y = 0.0; + chan_desc->R_sqrt[i][j].x = 1.0; + chan_desc->R_sqrt[i][j].y = 0.0; } } } @@ -142,8 +136,7 @@ void fill_channel_desc(channel_desc_t *chan_desc, } LOG_D(OCM,"[CHANNEL] RF %f\n",chan_desc->ricean_factor); - - for (i=0; inb_taps; i++) + for (i=0;inb_taps;i++) LOG_D(OCM,"[CHANNEL] tap %d: amp %f, delay %f\n",i,chan_desc->amps[i],chan_desc->delays[i]); chan_desc->nb_paths=10; @@ -181,23 +174,21 @@ struct complex R_sqrt_22_corr_tap[16] = {{0.70711,0}, {0.0, 0.0}, {0.70711,0}, { {0.0, 0.0}, {0.70711,0}, {0.0, 0.0}, {0.70711,0}, {0.70711,0}, {0.0, 0.0}, {0.70711,0}, {0.0, 0.0}, {0.0, 0.0}, {0.70711,0}, {0.0, 0.0}, {0.70711,0}}; - struct complex *R_sqrt_22_corr[1] = {R_sqrt_22_corr_tap}; //correlation matrix for a fully correlated 2x1 channel (h1==h2) -struct complex R_sqrt_21_corr_tap[4] = {{0.70711,0}, {0.70711,0}, {0.70711,0}, {0.70711,0}}; +struct complex R_sqrt_21_corr_tap[4] = {{0.70711,0}, {0.70711,0}, {0.70711,0}, {0.70711,0}}; struct complex *R_sqrt_21_corr[1] = {R_sqrt_21_corr_tap}; -//correlation matrix for a 2x2 channel with full Tx anti-correlation -struct complex R_sqrt_22_anticorr_tap[16] = {{0.70711,0}, {0.0, 0.0}, {-0.70711,0}, {0.0, 0.0}, - {0.0, 0.0}, {0.70711,0}, {0.0, 0.0}, {-0.70711,0}, - {-0.70711,0}, {0.0, 0.0}, {0.70711,0}, {0.0, 0.0}, - {0.0, 0.0}, {-0.70711,0}, {0.0, 0.0}, {0.70711,0} -}; +//correlation matrix for a 2x2 channel with full Tx anti-correlation +struct complex R_sqrt_22_anticorr_tap[16] = {{0.70711,0}, {0.0, 0.0}, {-0.70711,0}, {0.0, 0.0}, + {0.0, 0.0}, {0.70711,0}, {0.0, 0.0}, {-0.70711,0}, + {-0.70711,0}, {0.0, 0.0}, {0.70711,0}, {0.0, 0.0}, + {0.0, 0.0}, {-0.70711,0}, {0.0, 0.0}, {0.70711,0}}; struct complex *R_sqrt_22_anticorr[1] = {R_sqrt_22_anticorr_tap}; //correlation matrix for a fully anti-correlated 2x1 channel (h1==-h2) -struct complex R_sqrt_21_anticorr_tap[4] = {{0.70711,0}, {-0.70711,0}, {-0.70711,0}, {0.70711,0}}; +struct complex R_sqrt_21_anticorr_tap[4] = {{0.70711,0}, {-0.70711,0}, {-0.70711,0}, {0.70711,0}}; struct complex *R_sqrt_21_anticorr[1] = {R_sqrt_21_anticorr_tap}; struct complex **R_sqrt_ptr2; @@ -233,14 +224,13 @@ struct complex *R_sqrt_22_orth_eff_ch_TM4_prec_imag[1] = {R_sqrt_22_orth_eff //Rayleigh1_orth_eff_ch_TM4 -channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, - uint8_t nb_rx, - SCM_t channel_model, - double BW, - double forgetting_factor, - int32_t channel_offset, - double path_loss_dB) -{ +channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, + uint8_t nb_rx, + SCM_t channel_model, + double BW, + double forgetting_factor, + int32_t channel_offset, + double path_loss_dB) { channel_desc_t *chan_desc = (channel_desc_t *)malloc(sizeof(channel_desc_t)); uint16_t i,j; @@ -264,27 +254,22 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, LOG_W(OCM,"channel model not yet supported\n"); free(chan_desc); return(NULL); - case SCM_B: LOG_W(OCM,"channel model not yet supported\n"); free(chan_desc); return(NULL); - case SCM_C: chan_desc->nb_taps = 18; chan_desc->Td = 4.625; chan_desc->channel_length = (int) (2*chan_desc->BW*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->BW*chan_desc->Td)); sum_amps = 0; chan_desc->amps = (double*) malloc(chan_desc->nb_taps*sizeof(double)); - for (i = 0; inb_taps; i++) { - chan_desc->amps[i] = pow(10,.1*scm_c_amps_dB[i]); + chan_desc->amps[i] = pow(10,.1*scm_c_amps_dB[i]); sum_amps += chan_desc->amps[i]; } - for (i = 0; inb_taps; i++) chan_desc->amps[i] /= sum_amps; - chan_desc->delays = scm_c_delays; chan_desc->ricean_factor = 1; chan_desc->aoa = 0; @@ -292,42 +277,37 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, chan_desc->ch = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*)); chan_desc->chF = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*)); chan_desc->a = (struct complex**) malloc(chan_desc->nb_taps*sizeof(struct complex*)); - - for (i = 0; ich[i] = (struct complex*) malloc(chan_desc->channel_length * sizeof(struct complex)); - - for (i = 0; ichF[i] = (struct complex*) malloc(1200 * sizeof(struct complex)); - - for (i = 0; inb_taps; i++) + for (i = 0; ich[i] = (struct complex*) malloc(chan_desc->channel_length * sizeof(struct complex)); + for (i = 0; ichF[i] = (struct complex*) malloc(1200 * sizeof(struct complex)); + for (i = 0; inb_taps; i++) chan_desc->a[i] = (struct complex*) malloc(nb_tx*nb_rx * sizeof(struct complex)); chan_desc->R_sqrt = (struct complex**) malloc(6*sizeof(struct complex**)); - if (nb_tx==2 && nb_rx==2) { - for (i = 0; i<6; i++) - chan_desc->R_sqrt[i] = (struct complex*) &R22_sqrt[i][0]; - } else if (nb_tx==2 && nb_rx==1) { - for (i = 0; i<6; i++) - chan_desc->R_sqrt[i] = (struct complex*) &R21_sqrt[i][0]; - } else if (nb_tx==1 && nb_rx==2) { - for (i = 0; i<6; i++) - chan_desc->R_sqrt[i] = (struct complex*) &R12_sqrt[i][0]; - } else { + for (i = 0; i<6; i++) + chan_desc->R_sqrt[i] = (struct complex*) &R22_sqrt[i][0]; + } + else if (nb_tx==2 && nb_rx==1) { + for (i = 0; i<6; i++) + chan_desc->R_sqrt[i] = (struct complex*) &R21_sqrt[i][0]; + } + else if (nb_tx==1 && nb_rx==2) { + for (i = 0; i<6; i++) + chan_desc->R_sqrt[i] = (struct complex*) &R12_sqrt[i][0]; + } + else { for (i = 0; i<6; i++) { - chan_desc->R_sqrt[i] = (struct complex*) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); - - for (j = 0; jR_sqrt[i][j].x = 1.0; - chan_desc->R_sqrt[i][j].y = 0.0; - } - - LOG_W(OCM,"correlation matrix not implemented for nb_tx==%d and nb_rx==%d, using identity\n", nb_tx, nb_rx); + chan_desc->R_sqrt[i] = (struct complex*) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); + for (j = 0; jR_sqrt[i][j].x = 1.0; + chan_desc->R_sqrt[i][j].y = 0.0; + } + LOG_W(OCM,"correlation matrix not implemented for nb_tx==%d and nb_rx==%d, using identity\n", nb_tx, nb_rx); } } - break; - case SCM_D: LOG_W(OCM,"This is not the real SCM-D model! It is just SCM-C with an additional Rice factor!\n"); chan_desc->nb_taps = 18; @@ -335,15 +315,12 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, chan_desc->channel_length = (int) (2*chan_desc->BW*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->BW*chan_desc->Td)); sum_amps = 0; chan_desc->amps = (double*) malloc(chan_desc->nb_taps*sizeof(double)); - for (i = 0; inb_taps; i++) { - chan_desc->amps[i] = pow(10,.1*scm_c_amps_dB[i]); + chan_desc->amps[i] = pow(10,.1*scm_c_amps_dB[i]); sum_amps += chan_desc->amps[i]; } - for (i = 0; inb_taps; i++) chan_desc->amps[i] /= sum_amps; - chan_desc->delays = scm_c_delays; chan_desc->ricean_factor = 0.1; chan_desc->aoa = 0; @@ -351,57 +328,49 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, chan_desc->ch = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*)); chan_desc->chF = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*)); chan_desc->a = (struct complex**) malloc(chan_desc->nb_taps*sizeof(struct complex*)); - - for (i = 0; ich[i] = (struct complex*) malloc(chan_desc->channel_length * sizeof(struct complex)); - - for (i = 0; ichF[i] = (struct complex*) malloc(1200 * sizeof(struct complex)); - - for (i = 0; inb_taps; i++) + for (i = 0; ich[i] = (struct complex*) malloc(chan_desc->channel_length * sizeof(struct complex)); + for (i = 0; ichF[i] = (struct complex*) malloc(1200 * sizeof(struct complex)); + for (i = 0; inb_taps; i++) chan_desc->a[i] = (struct complex*) malloc(nb_tx*nb_rx * sizeof(struct complex)); chan_desc->R_sqrt = (struct complex**) malloc(6*sizeof(struct complex**)); - if (nb_tx==2 && nb_rx==2) { - for (i = 0; i<6; i++) - chan_desc->R_sqrt[i] = (struct complex*) &R22_sqrt[i][0]; - } else if (nb_tx==2 && nb_rx==1) { - for (i = 0; i<6; i++) - chan_desc->R_sqrt[i] = (struct complex*) &R21_sqrt[i][0]; - } else if (nb_tx==1 && nb_rx==2) { - for (i = 0; i<6; i++) - chan_desc->R_sqrt[i] = (struct complex*) &R12_sqrt[i][0]; - } else { + for (i = 0; i<6; i++) + chan_desc->R_sqrt[i] = (struct complex*) &R22_sqrt[i][0]; + } + else if (nb_tx==2 && nb_rx==1) { + for (i = 0; i<6; i++) + chan_desc->R_sqrt[i] = (struct complex*) &R21_sqrt[i][0]; + } + else if (nb_tx==1 && nb_rx==2) { + for (i = 0; i<6; i++) + chan_desc->R_sqrt[i] = (struct complex*) &R12_sqrt[i][0]; + } + else { for (i = 0; i<6; i++) { - chan_desc->R_sqrt[i] = (struct complex*) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); - - for (j = 0; jR_sqrt[i][j].x = 1.0; - chan_desc->R_sqrt[i][j].y = 0.0; - } - - LOG_W(OCM,"correlation matrix not implemented for nb_tx==%d and nb_rx==%d, using identity\n", nb_tx, nb_rx); + chan_desc->R_sqrt[i] = (struct complex*) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); + for (j = 0; jR_sqrt[i][j].x = 1.0; + chan_desc->R_sqrt[i][j].y = 0.0; + } + LOG_W(OCM,"correlation matrix not implemented for nb_tx==%d and nb_rx==%d, using identity\n", nb_tx, nb_rx); } } - break; - case EPA: chan_desc->nb_taps = 7; chan_desc->Td = .410; chan_desc->channel_length = (int) (2*chan_desc->BW*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->BW*chan_desc->Td)); sum_amps = 0; chan_desc->amps = (double*) malloc(chan_desc->nb_taps*sizeof(double)); - for (i = 0; inb_taps; i++) { - chan_desc->amps[i] = pow(10,.1*epa_amps_dB[i]); + chan_desc->amps[i] = pow(10,.1*epa_amps_dB[i]); sum_amps += chan_desc->amps[i]; } - for (i = 0; inb_taps; i++) chan_desc->amps[i] /= sum_amps; - chan_desc->delays = epa_delays; chan_desc->ricean_factor = 1; chan_desc->aoa = 0; @@ -409,53 +378,41 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, chan_desc->ch = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*)); chan_desc->chF = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*)); chan_desc->a = (struct complex**) malloc(chan_desc->nb_taps*sizeof(struct complex*)); - - for (i = 0; ich[i] = (struct complex*) malloc(chan_desc->channel_length * sizeof(struct complex)); - - for (i = 0; ichF[i] = (struct complex*) malloc(1200 * sizeof(struct complex)); - - for (i = 0; inb_taps; i++) + for (i = 0; ich[i] = (struct complex*) malloc(chan_desc->channel_length * sizeof(struct complex)); + for (i = 0; ichF[i] = (struct complex*) malloc(1200 * sizeof(struct complex)); + for (i = 0; inb_taps; i++) chan_desc->a[i] = (struct complex*) malloc(nb_tx*nb_rx * sizeof(struct complex)); - if (nb_tx==2 && nb_rx==2) { chan_desc->R_sqrt = (struct complex**) malloc(6*sizeof(struct complex**)); - - for (i = 0; i<6; i++) - chan_desc->R_sqrt[i] = (struct complex*) &R22_sqrt[i][0]; - } else { + for (i = 0; i<6; i++) + chan_desc->R_sqrt[i] = (struct complex*) &R22_sqrt[i][0]; + } + else { chan_desc->R_sqrt = (struct complex**) malloc(6*sizeof(struct complex**)); - for (i = 0; i<6; i++) { - chan_desc->R_sqrt[i] = (struct complex*) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); - - for (j = 0; jR_sqrt[i][j].x = 1.0; - chan_desc->R_sqrt[i][j].y = 0.0; - } - - LOG_W(OCM,"correlation matrix only implemented for nb_tx==2 and nb_rx==2, using identity\n"); + chan_desc->R_sqrt[i] = (struct complex*) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); + for (j = 0; jR_sqrt[i][j].x = 1.0; + chan_desc->R_sqrt[i][j].y = 0.0; + } + LOG_W(OCM,"correlation matrix only implemented for nb_tx==2 and nb_rx==2, using identity\n"); } } - break; - case EVA: chan_desc->nb_taps = 9; chan_desc->Td = 2.51; chan_desc->channel_length = (int) (2*chan_desc->BW*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->BW*chan_desc->Td)); sum_amps = 0; chan_desc->amps = (double*) malloc(chan_desc->nb_taps*sizeof(double)); - for (i = 0; inb_taps; i++) { - chan_desc->amps[i] = pow(10,.1*eva_amps_dB[i]); + chan_desc->amps[i] = pow(10,.1*eva_amps_dB[i]); sum_amps += chan_desc->amps[i]; } - for (i = 0; inb_taps; i++) chan_desc->amps[i] /= sum_amps; - chan_desc->delays = eva_delays; chan_desc->ricean_factor = 1; chan_desc->aoa = 0; @@ -463,53 +420,41 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, chan_desc->ch = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*)); chan_desc->chF = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*)); chan_desc->a = (struct complex**) malloc(chan_desc->nb_taps*sizeof(struct complex*)); - - for (i = 0; ich[i] = (struct complex*) malloc(chan_desc->channel_length * sizeof(struct complex)); - - for (i = 0; ichF[i] = (struct complex*) malloc(1200 * sizeof(struct complex)); - - for (i = 0; inb_taps; i++) + for (i = 0; ich[i] = (struct complex*) malloc(chan_desc->channel_length * sizeof(struct complex)); + for (i = 0; ichF[i] = (struct complex*) malloc(1200 * sizeof(struct complex)); + for (i = 0; inb_taps; i++) chan_desc->a[i] = (struct complex*) malloc(nb_tx*nb_rx * sizeof(struct complex)); - if (nb_tx==2 && nb_rx==2) { chan_desc->R_sqrt = (struct complex**) malloc(6*sizeof(struct complex**)); - - for (i = 0; i<6; i++) - chan_desc->R_sqrt[i] = (struct complex*) &R22_sqrt[i][0]; - } else { + for (i = 0; i<6; i++) + chan_desc->R_sqrt[i] = (struct complex*) &R22_sqrt[i][0]; + } + else { chan_desc->R_sqrt = (struct complex**) malloc(6*sizeof(struct complex**)); - for (i = 0; i<6; i++) { - chan_desc->R_sqrt[i] = (struct complex*) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); - - for (j = 0; jR_sqrt[i][j].x = 1.0; - chan_desc->R_sqrt[i][j].y = 0.0; - } - - LOG_W(OCM,"correlation matrix only implemented for nb_tx==2 and nb_rx==2, using identity\n"); + chan_desc->R_sqrt[i] = (struct complex*) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); + for (j = 0; jR_sqrt[i][j].x = 1.0; + chan_desc->R_sqrt[i][j].y = 0.0; + } + LOG_W(OCM,"correlation matrix only implemented for nb_tx==2 and nb_rx==2, using identity\n"); } } - break; - case ETU: chan_desc->nb_taps = 9; chan_desc->Td = 5.0; chan_desc->channel_length = (int) (2*chan_desc->BW*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->BW*chan_desc->Td)); sum_amps = 0; chan_desc->amps = (double*) malloc(chan_desc->nb_taps*sizeof(double)); - for (i = 0; inb_taps; i++) { - chan_desc->amps[i] = pow(10,.1*etu_amps_dB[i]); + chan_desc->amps[i] = pow(10,.1*etu_amps_dB[i]); sum_amps += chan_desc->amps[i]; } - for (i = 0; inb_taps; i++) chan_desc->amps[i] /= sum_amps; - chan_desc->delays = etu_delays; chan_desc->ricean_factor = 1; chan_desc->aoa = 0; @@ -517,53 +462,41 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, chan_desc->ch = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*)); chan_desc->chF = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*)); chan_desc->a = (struct complex**) malloc(chan_desc->nb_taps*sizeof(struct complex*)); - - for (i = 0; ich[i] = (struct complex*) malloc(chan_desc->channel_length * sizeof(struct complex)); - - for (i = 0; ichF[i] = (struct complex*) malloc(1200 * sizeof(struct complex)); - - for (i = 0; inb_taps; i++) + for (i = 0; ich[i] = (struct complex*) malloc(chan_desc->channel_length * sizeof(struct complex)); + for (i = 0; ichF[i] = (struct complex*) malloc(1200 * sizeof(struct complex)); + for (i = 0; inb_taps; i++) chan_desc->a[i] = (struct complex*) malloc(nb_tx*nb_rx * sizeof(struct complex)); - if (nb_tx==2 && nb_rx==2) { chan_desc->R_sqrt = (struct complex**) malloc(6*sizeof(struct complex**)); - - for (i = 0; i<6; i++) - chan_desc->R_sqrt[i] = (struct complex*) &R22_sqrt[i][0]; - } else { + for (i = 0; i<6; i++) + chan_desc->R_sqrt[i] = (struct complex*) &R22_sqrt[i][0]; + } + else { chan_desc->R_sqrt = (struct complex**) malloc(6*sizeof(struct complex**)); - for (i = 0; i<6; i++) { - chan_desc->R_sqrt[i] = (struct complex*) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); - - for (j = 0; jR_sqrt[i][j].x = 1.0; - chan_desc->R_sqrt[i][j].y = 0.0; - } - - LOG_W(OCM,"correlation matrix only implemented for nb_tx==2 and nb_rx==2, using identity\n"); + chan_desc->R_sqrt[i] = (struct complex*) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); + for (j = 0; jR_sqrt[i][j].x = 1.0; + chan_desc->R_sqrt[i][j].y = 0.0; + } + LOG_W(OCM,"correlation matrix only implemented for nb_tx==2 and nb_rx==2, using identity\n"); } } - break; - case MBSFN: chan_desc->nb_taps = 18; chan_desc->Td = 28.58; chan_desc->channel_length = (int) (2*chan_desc->BW*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->BW*chan_desc->Td)); sum_amps = 0; chan_desc->amps = (double*) malloc(chan_desc->nb_taps*sizeof(double)); - for (i = 0; inb_taps; i++) { - chan_desc->amps[i] = pow(10,.1*mbsfn_amps_dB[i]); + chan_desc->amps[i] = pow(10,.1*mbsfn_amps_dB[i]); sum_amps += chan_desc->amps[i]; } - for (i = 0; inb_taps; i++) chan_desc->amps[i] /= sum_amps; - chan_desc->delays = mbsfn_delays; chan_desc->ricean_factor = 1; chan_desc->aoa = 0; @@ -571,168 +504,162 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, chan_desc->ch = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*)); chan_desc->chF = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*)); chan_desc->a = (struct complex**) malloc(chan_desc->nb_taps*sizeof(struct complex*)); - - for (i = 0; ich[i] = (struct complex*) malloc(chan_desc->channel_length * sizeof(struct complex)); - - for (i = 0; ichF[i] = (struct complex*) malloc(1200 * sizeof(struct complex)); - - for (i = 0; inb_taps; i++) + for (i = 0; ich[i] = (struct complex*) malloc(chan_desc->channel_length * sizeof(struct complex)); + for (i = 0; ichF[i] = (struct complex*) malloc(1200 * sizeof(struct complex)); + for (i = 0; inb_taps; i++) chan_desc->a[i] = (struct complex*) malloc(nb_tx*nb_rx * sizeof(struct complex)); chan_desc->R_sqrt = (struct complex**) malloc(6*sizeof(struct complex*)); - for (i = 0; i<6; i++) { chan_desc->R_sqrt[i] = (struct complex*) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); - for (j = 0; jR_sqrt[i][j].x = 1.0; - chan_desc->R_sqrt[i][j].y = 0.0; + chan_desc->R_sqrt[i][j].x = 1.0; + chan_desc->R_sqrt[i][j].y = 0.0; } - LOG_W(OCM,"correlation matrix only implemented for nb_tx==2 and nb_rx==2, using identity\n"); } - break; - case Rayleigh8: - nb_taps = 8; - Td = 0.8; - channel_length = (int)11+2*BW*Td; - ricean_factor = 1; - aoa = .03; - maxDoppler = 0; + nb_taps = 8; + Td = 0.8; + channel_length = (int)11+2*BW*Td; + ricean_factor = 1; + aoa = .03; + maxDoppler = 0; - fill_channel_desc(chan_desc, - nb_tx, - nb_rx, - nb_taps, - channel_length, - default_amps_lin, - NULL, - NULL, - Td, - BW, - ricean_factor, - aoa, - forgetting_factor, - maxDoppler, - channel_offset, - path_loss_dB, - 0); - break; + fill_channel_desc(chan_desc, + nb_tx, + nb_rx, + nb_taps, + channel_length, + default_amps_lin, + NULL, + NULL, + Td, + BW, + ricean_factor, + aoa, + forgetting_factor, + maxDoppler, + channel_offset, + path_loss_dB, + 0); + break; case Rice8: - nb_taps = 8; - Td = 0.8; - channel_length = (int)11+2*BW*Td; - ricean_factor = 0.1; - aoa = .03; - maxDoppler = 0; + nb_taps = 8; + Td = 0.8; + channel_length = (int)11+2*BW*Td; + ricean_factor = 0.1; + aoa = .03; + maxDoppler = 0; - fill_channel_desc(chan_desc,nb_tx, - nb_rx, - nb_taps, - channel_length, - default_amps_lin, - NULL, - NULL, - Td, - BW, - ricean_factor, - aoa, - forgetting_factor, - maxDoppler, - channel_offset, - path_loss_dB, - 1); - break; + fill_channel_desc(chan_desc,nb_tx, + nb_rx, + nb_taps, + channel_length, + default_amps_lin, + NULL, + NULL, + Td, + BW, + ricean_factor, + aoa, + forgetting_factor, + maxDoppler, + channel_offset, + path_loss_dB, + 1); + break; case Rayleigh1: - nb_taps = 1; - Td = 0; - channel_length = 1; - ricean_factor = 1; - aoa = .03; - maxDoppler = 0; + nb_taps = 1; + Td = 0; + channel_length = 1; + ricean_factor = 1; + aoa = .03; + maxDoppler = 0; - fill_channel_desc(chan_desc,nb_tx, - nb_rx, - nb_taps, - channel_length, - default_amp_lin, - NULL, - NULL, - Td, - BW, - ricean_factor, - aoa, - forgetting_factor, - maxDoppler, - channel_offset, - path_loss_dB, - 0); - break; + fill_channel_desc(chan_desc,nb_tx, + nb_rx, + nb_taps, + channel_length, + default_amp_lin, + NULL, + NULL, + Td, + BW, + ricean_factor, + aoa, + forgetting_factor, + maxDoppler, + channel_offset, + path_loss_dB, + 0); + break; case Rayleigh1_800: - nb_taps = 1; - Td = 0; - channel_length = 1; - ricean_factor = 1; - aoa = .03; - maxDoppler = 800; + nb_taps = 1; + Td = 0; + channel_length = 1; + ricean_factor = 1; + aoa = .03; + maxDoppler = 800; - fill_channel_desc(chan_desc,nb_tx, - nb_rx, - nb_taps, - channel_length, - default_amp_lin, - NULL, - NULL, - Td, - BW, - ricean_factor, - aoa, - forgetting_factor, - maxDoppler, - channel_offset, - path_loss_dB, - 0); - break; + fill_channel_desc(chan_desc,nb_tx, + nb_rx, + nb_taps, + channel_length, + default_amp_lin, + NULL, + NULL, + Td, + BW, + ricean_factor, + aoa, + forgetting_factor, + maxDoppler, + channel_offset, + path_loss_dB, + 0); + break; case Rayleigh1_corr: - nb_taps = 1; - Td = 0; - channel_length = 1; - ricean_factor = 1; - aoa = .03; - maxDoppler = 0; + nb_taps = 1; + Td = 0; + channel_length = 1; + ricean_factor = 1; + aoa = .03; + maxDoppler = 0; - if ((nb_tx==2) && (nb_rx==1)) { - R_sqrt_ptr2 = R_sqrt_21_corr; - } else if ((nb_tx==2) && (nb_rx==2)) { - R_sqrt_ptr2 = R_sqrt_22_corr; - } else - R_sqrt_ptr2 = NULL; + if ((nb_tx==2) && (nb_rx==1)) { + R_sqrt_ptr2 = R_sqrt_21_corr; + } + else if ((nb_tx==2) && (nb_rx==2)) { + R_sqrt_ptr2 = R_sqrt_22_corr; + } + else + R_sqrt_ptr2 = NULL; - fill_channel_desc(chan_desc,nb_tx, - nb_rx, - nb_taps, - channel_length, - default_amp_lin, - NULL, - R_sqrt_ptr2, - Td, - BW, - ricean_factor, - aoa, - forgetting_factor, - maxDoppler, - channel_offset, - path_loss_dB, - 0); - break; + fill_channel_desc(chan_desc,nb_tx, + nb_rx, + nb_taps, + channel_length, + default_amp_lin, + NULL, + R_sqrt_ptr2, + Td, + BW, + ricean_factor, + aoa, + forgetting_factor, + maxDoppler, + channel_offset, + path_loss_dB, + 0); + break; case Rayleigh1_anticorr: nb_taps = 1; @@ -770,58 +697,58 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, break; case Rice1: - nb_taps = 1; - Td = 0; - channel_length = 1; - ricean_factor = 0.1; - aoa = .03; - maxDoppler = 0; + nb_taps = 1; + Td = 0; + channel_length = 1; + ricean_factor = 0.1; + aoa = .03; + maxDoppler = 0; - fill_channel_desc(chan_desc,nb_tx, - nb_rx, - nb_taps, - channel_length, - default_amp_lin, - NULL, - NULL, - Td, - BW, - ricean_factor, - aoa, - forgetting_factor, - maxDoppler, - channel_offset, - path_loss_dB, - 0); - break; + fill_channel_desc(chan_desc,nb_tx, + nb_rx, + nb_taps, + channel_length, + default_amp_lin, + NULL, + NULL, + Td, + BW, + ricean_factor, + aoa, + forgetting_factor, + maxDoppler, + channel_offset, + path_loss_dB, + 0); + break; case AWGN: - nb_taps = 1; - Td = 0; - channel_length = 1; - ricean_factor = 0.0; - aoa = 0.0; - maxDoppler = 0; + nb_taps = 1; + Td = 0; + channel_length = 1; + ricean_factor = 0.0; + aoa = 0.0; + maxDoppler = 0; - fill_channel_desc(chan_desc,nb_tx, - nb_rx, - nb_taps, - channel_length, - default_amp_lin, - NULL, - NULL, - Td, - BW, - ricean_factor, - aoa, - forgetting_factor, - maxDoppler, - channel_offset, - path_loss_dB, - 0); - printf("AWGN: ricean_factor %f\n",chan_desc->ricean_factor); + fill_channel_desc(chan_desc,nb_tx, + nb_rx, + nb_taps, + channel_length, + default_amp_lin, + NULL, + NULL, + Td, + BW, + ricean_factor, + aoa, + forgetting_factor, + maxDoppler, + channel_offset, + path_loss_dB, + 0); + printf("AWGN: ricean_factor %f\n",chan_desc->ricean_factor); - break; + break; case TS_SHIFT: nb_taps = 2; @@ -852,40 +779,41 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, break; case Rice1_corr: - nb_taps = 1; - Td = 0; - channel_length = 1; - ricean_factor = 0.1; - aoa = .03; - maxDoppler = 0; + nb_taps = 1; + Td = 0; + channel_length = 1; + ricean_factor = 0.1; + aoa = .03; + maxDoppler = 0; - if ((nb_tx==2) && (nb_rx==1)) { - R_sqrt_ptr2 = R_sqrt_21_corr; - } else if ((nb_tx==2) && (nb_rx==2)) { - R_sqrt_ptr2 = R_sqrt_22_corr; - } else - R_sqrt_ptr2 = NULL; + if ((nb_tx==2) && (nb_rx==1)) { + R_sqrt_ptr2 = R_sqrt_21_corr; + } + else if ((nb_tx==2) && (nb_rx==2)) { + R_sqrt_ptr2 = R_sqrt_22_corr; + } + else + R_sqrt_ptr2 = NULL; - fill_channel_desc(chan_desc,nb_tx, - nb_rx, - nb_taps, - channel_length, - default_amp_lin, - NULL, - R_sqrt_ptr2, - Td, - BW, - ricean_factor, - aoa, - forgetting_factor, - maxDoppler, - channel_offset, - path_loss_dB, - 1); - break; + fill_channel_desc(chan_desc,nb_tx, + nb_rx, + nb_taps, + channel_length, + default_amp_lin, + NULL, + R_sqrt_ptr2, + Td, + BW, + ricean_factor, + aoa, + forgetting_factor, + maxDoppler, + channel_offset, + path_loss_dB, + 1); + break; case Rice1_anticorr: - nb_taps = 1; Td = 0; channel_length = 1; @@ -1094,10 +1022,8 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, free(chan_desc); return(NULL); } - LOG_D(OCM,"[CHANNEL] RF %f\n",chan_desc->ricean_factor); - - for (i=0; inb_taps; i++) + for (i=0;inb_taps;i++) LOG_D(OCM,"[CHANNEL] tap %d: amp %f, delay %f\n",i,chan_desc->amps[i],chan_desc->delays[i]); chan_desc->nb_paths = 10; @@ -1106,46 +1032,43 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, } -int random_channel(channel_desc_t *desc, uint8_t abstraction_flag) -{ - +int random_channel(channel_desc_t *desc, uint8_t abstraction_flag) { + double s; int i,k,l,aarx,aatx; struct complex anew[NB_ANTENNAS_TX*NB_ANTENNAS_RX],acorr[NB_ANTENNAS_TX*NB_ANTENNAS_RX]; struct complex phase, alpha, beta; - + if ((desc->nb_tx>NB_ANTENNAS_TX) || (desc->nb_rx > NB_ANTENNAS_RX)) { msg("random_channel.c: Error: temporary buffer for channel not big enough (%d,%d)\n",desc->nb_tx,desc->nb_rx); return(-1); } start_meas(&desc->random_channel); + for (i=0;i<(int)desc->nb_taps;i++) { + for (aarx=0;aarxnb_rx;aarx++) { + for (aatx=0;aatxnb_tx;aatx++) { - for (i=0; i<(int)desc->nb_taps; i++) { - for (aarx=0; aarxnb_rx; aarx++) { - for (aatx=0; aatxnb_tx; aatx++) { + anew[aarx+(aatx*desc->nb_rx)].x = sqrt(desc->ricean_factor*desc->amps[i]/2) * gaussdouble(0.0,1.0); + anew[aarx+(aatx*desc->nb_rx)].y = sqrt(desc->ricean_factor*desc->amps[i]/2) * gaussdouble(0.0,1.0); - anew[aarx+(aatx*desc->nb_rx)].x = sqrt(desc->ricean_factor*desc->amps[i]/2) * gaussdouble(0.0,1.0); - anew[aarx+(aatx*desc->nb_rx)].y = sqrt(desc->ricean_factor*desc->amps[i]/2) * gaussdouble(0.0,1.0); - - if ((i==0) && (desc->ricean_factor != 1.0)) { - if (desc->random_aoa==1) { - desc->aoa = uniformrandom()*2*M_PI; - } - - // this assumes that both RX and TX have linear antenna arrays with lambda/2 antenna spacing. - // Furhter it is assumed that the arrays are parallel to each other and that they are far enough apart so - // that we can safely assume plane wave propagation. - phase.x = cos(M_PI*((aarx-aatx)*sin(desc->aoa))); - phase.y = sin(M_PI*((aarx-aatx)*sin(desc->aoa))); - - anew[aarx+(aatx*desc->nb_rx)].x += phase.x * sqrt(1.0-desc->ricean_factor); - anew[aarx+(aatx*desc->nb_rx)].y += phase.y * sqrt(1.0-desc->ricean_factor); - } + if ((i==0) && (desc->ricean_factor != 1.0)) { + if (desc->random_aoa==1) { + desc->aoa = uniformrandom()*2*M_PI; + } + // this assumes that both RX and TX have linear antenna arrays with lambda/2 antenna spacing. + // Furhter it is assumed that the arrays are parallel to each other and that they are far enough apart so + // that we can safely assume plane wave propagation. + phase.x = cos(M_PI*((aarx-aatx)*sin(desc->aoa))); + phase.y = sin(M_PI*((aarx-aatx)*sin(desc->aoa))); + + anew[aarx+(aatx*desc->nb_rx)].x += phase.x * sqrt(1.0-desc->ricean_factor); + anew[aarx+(aatx*desc->nb_rx)].y += phase.y * sqrt(1.0-desc->ricean_factor); + } #ifdef DEBUG_CH - printf("(%d,%d,%d) %f->(%f,%f) (%f,%f) phase (%f,%f)\n",aarx,aatx,i,desc->amps[i],anew[aarx+(aatx*desc->nb_rx)].x,anew[aarx+(aatx*desc->nb_rx)].y,desc->aoa,desc->ricean_factor,phase.x,phase.y); -#endif + printf("(%d,%d,%d) %f->(%f,%f) (%f,%f) phase (%f,%f)\n",aarx,aatx,i,desc->amps[i],anew[aarx+(aatx*desc->nb_rx)].x,anew[aarx+(aatx*desc->nb_rx)].y,desc->aoa,desc->ricean_factor,phase.x,phase.y); +#endif } //aatx } //aarx @@ -1153,9 +1076,9 @@ int random_channel(channel_desc_t *desc, uint8_t abstraction_flag) // for debugging set a=anew; for (aarx=0;aarxnb_rx;aarx++) { for (aatx=0;aatxnb_tx;aatx++) { - desc->a[i][aarx+(aatx*desc->nb_rx)].x = anew[aarx+(aatx*desc->nb_rx)].x; - desc->a[i][aarx+(aatx*desc->nb_rx)].y = anew[aarx+(aatx*desc->nb_rx)].y; - printf("anew(%d,%d) = %f+1j*%f\n",aatx,aarx,anew[aarx+(aatx*desc->nb_rx)].x, anew[aarx+(aatx*desc->nb_rx)].y); + desc->a[i][aarx+(aatx*desc->nb_rx)].x = anew[aarx+(aatx*desc->nb_rx)].x; + desc->a[i][aarx+(aatx*desc->nb_rx)].y = anew[aarx+(aatx*desc->nb_rx)].y; + printf("anew(%d,%d) = %f+1j*%f\n",aatx,aarx,anew[aarx+(aatx*desc->nb_rx)].x, anew[aarx+(aatx*desc->nb_rx)].y); } } */ @@ -1166,23 +1089,24 @@ int random_channel(channel_desc_t *desc, uint8_t abstraction_flag) beta.x = 0.0; beta.y = 0.0; - cblas_zgemv(CblasRowMajor, CblasNoTrans, desc->nb_tx*desc->nb_rx, desc->nb_tx*desc->nb_rx, - (void*) &alpha, (void*) desc->R_sqrt[i/3], desc->nb_rx*desc->nb_tx, - (void*) anew, 1, (void*) &beta, (void*) acorr, 1); + cblas_zgemv(CblasRowMajor, CblasNoTrans, desc->nb_tx*desc->nb_rx, desc->nb_tx*desc->nb_rx, + (void*) &alpha, (void*) desc->R_sqrt[i/3], desc->nb_rx*desc->nb_tx, + (void*) anew, 1, (void*) &beta, (void*) acorr, 1); /* for (aarx=0;aarxnb_rx;aarx++) { for (aatx=0;aatxnb_tx;aatx++) { - desc->a[i][aarx+(aatx*desc->nb_rx)].x = acorr[aarx+(aatx*desc->nb_rx)].x; - desc->a[i][aarx+(aatx*desc->nb_rx)].y = acorr[aarx+(aatx*desc->nb_rx)].y; - printf("tap %d, acorr1(%d,%d) = %f+1j*%f\n",i,aatx,aarx,acorr[aarx+(aatx*desc->nb_rx)].x, acorr[aarx+(aatx*desc->nb_rx)].y); + desc->a[i][aarx+(aatx*desc->nb_rx)].x = acorr[aarx+(aatx*desc->nb_rx)].x; + desc->a[i][aarx+(aatx*desc->nb_rx)].y = acorr[aarx+(aatx*desc->nb_rx)].y; + printf("tap %d, acorr1(%d,%d) = %f+1j*%f\n",i,aatx,aarx,acorr[aarx+(aatx*desc->nb_rx)].x, acorr[aarx+(aatx*desc->nb_rx)].y); } } */ - if (desc->first_run==1) { + if (desc->first_run==1){ cblas_zcopy(desc->nb_tx*desc->nb_rx, (void*) acorr, 1, (void*) desc->a[i], 1); - } else { + } + else { // a = alpha*acorr+beta*a // a = beta*a // a = a+alpha*acorr @@ -1200,19 +1124,18 @@ int random_channel(channel_desc_t *desc, uint8_t abstraction_flag) /* for (aarx=0;aarxnb_rx;aarx++) { for (aatx=0;aatxnb_tx;aatx++) { - //desc->a[i][aarx+(aatx*desc->nb_rx)].x = acorr[aarx+(aatx*desc->nb_rx)].x; - //desc->a[i][aarx+(aatx*desc->nb_rx)].y = acorr[aarx+(aatx*desc->nb_rx)].y; - printf("tap %d, a(%d,%d) = %f+1j*%f\n",i,aatx,aarx,desc->a[i][aarx+(aatx*desc->nb_rx)].x, desc->a[i][aarx+(aatx*desc->nb_rx)].y); + //desc->a[i][aarx+(aatx*desc->nb_rx)].x = acorr[aarx+(aatx*desc->nb_rx)].x; + //desc->a[i][aarx+(aatx*desc->nb_rx)].y = acorr[aarx+(aatx*desc->nb_rx)].y; + printf("tap %d, a(%d,%d) = %f+1j*%f\n",i,aatx,aarx,desc->a[i][aarx+(aatx*desc->nb_rx)].x, desc->a[i][aarx+(aatx*desc->nb_rx)].y); } } */ - } //nb_taps - + } //nb_taps stop_meas(&desc->random_channel); //memset((void *)desc->ch[aarx+(aatx*desc->nb_rx)],0,(int)(desc->channel_length)*sizeof(struct complex)); - + if (abstraction_flag==0) { start_meas(&desc->interp_time); for (aarx=0;aarxnb_rx;aarx++) { @@ -1243,16 +1166,14 @@ int random_channel(channel_desc_t *desc, uint8_t abstraction_flag) // printf("l %d : desc->ch.x %f\n",l,desc->a[l][aarx+(aatx*desc->nb_rx)].x); } //nb_taps - #ifdef DEBUG_CH - printf("(%d,%d,%d)->(%f,%f)\n",k,aarx,aatx,desc->ch[aarx+(aatx*desc->nb_rx)][k].x,desc->ch[aarx+(aatx*desc->nb_rx)][k].y); + printf("(%d,%d,%d)->(%f,%f)\n",k,aarx,aatx,desc->ch[aarx+(aatx*desc->nb_rx)][k].x,desc->ch[aarx+(aatx*desc->nb_rx)][k].y); #endif - } - } //channel_length - } //aatx - } //aarx - - stop_meas(&desc->interp_time); + } + } //channel_length + } //aatx + } //aarx + stop_meas(&desc->interp_time); } if (desc->first_run==1) @@ -1264,13 +1185,12 @@ int random_channel(channel_desc_t *desc, uint8_t abstraction_flag) #ifdef RANDOM_CHANNEL_MAIN #define BW 5.0 #define Td 2.0 -main(int argc,char **argv) -{ +main(int argc,char **argv) { double amps[8] = {.8,.2,.1,.04,.02,.01,.005}; struct complex ch[(int)(1+2*BW*Td)],phase; int i; - + randominit(); phase.x = 1.0; phase.y = 0; @@ -1282,4 +1202,4 @@ main(int argc,char **argv) */ } -#endif +#endif \ No newline at end of file