mirror of https://github.com/pvnis/srsRAN_4G.git
Added MEX lib. Added PDCCH test
parent
f32ac7b1ab
commit
48da6746cd
@ -0,0 +1,163 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Ismael Gomez-Miguelez <ismael.gomez@tsc.upc.edu>.
|
||||
* This file is part of ALOE++ (http://flexnets.upc.edu/)
|
||||
*
|
||||
* ALOE++ is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* ALOE++ is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with ALOE++. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "liblte/phy/phy.h"
|
||||
#include "liblte/mex/mexutils.h"
|
||||
|
||||
/** MEX function to be called from MATLAB to test the channel estimator
|
||||
*/
|
||||
|
||||
#define ENBCFG prhs[0]
|
||||
#define RNTI prhs[1]
|
||||
#define INPUT prhs[2]
|
||||
#define NOF_INPUTS 3
|
||||
|
||||
#define MAX_CANDIDATES 64
|
||||
|
||||
|
||||
dci_format_t ue_formats[] = {Format1A,Format1}; // Format1B should go here also
|
||||
const uint32_t nof_ue_formats = 2;
|
||||
|
||||
dci_format_t common_formats[] = {Format1A,Format1C};
|
||||
const uint32_t nof_common_formats = 2;
|
||||
|
||||
|
||||
void help()
|
||||
{
|
||||
mexErrMsgTxt
|
||||
("[decoded_ok, llr, rm, bits] = liblte_pdcch(enbConfig, RNTI, inputSignal)\n\n");
|
||||
}
|
||||
|
||||
/* the gateway function */
|
||||
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
|
||||
{
|
||||
|
||||
int i;
|
||||
lte_cell_t cell;
|
||||
pdcch_t pdcch;
|
||||
regs_t regs;
|
||||
dci_location_t locations[MAX_CANDIDATES];
|
||||
uint32_t cfi, sf_idx;
|
||||
uint16_t rnti;
|
||||
cf_t *input_symbols;
|
||||
int nof_re;
|
||||
uint32_t nof_formats;
|
||||
dci_format_t *formats = NULL;
|
||||
|
||||
if (nrhs != NOF_INPUTS) {
|
||||
help();
|
||||
return;
|
||||
}
|
||||
|
||||
if (mexutils_read_cell(ENBCFG, &cell)) {
|
||||
help();
|
||||
return;
|
||||
}
|
||||
|
||||
if (mexutils_read_uint32_struct(ENBCFG, "CFI", &cfi)) {
|
||||
help();
|
||||
return;
|
||||
}
|
||||
if (mexutils_read_uint32_struct(ENBCFG, "NSubframe", &sf_idx)) {
|
||||
help();
|
||||
return;
|
||||
}
|
||||
|
||||
rnti = (uint16_t) mxGetScalar(RNTI);
|
||||
|
||||
if (regs_init(®s, cell)) {
|
||||
mexErrMsgTxt("Error initiating regs\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (regs_set_cfi(®s, cfi)) {
|
||||
fprintf(stderr, "Error setting CFI\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if (pdcch_init(&pdcch, ®s, cell)) {
|
||||
mexErrMsgTxt("Error initiating channel estimator\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/** Allocate input buffers */
|
||||
nof_re = mexutils_read_cf(INPUT, &input_symbols);
|
||||
if (nof_re < 0) {
|
||||
mexErrMsgTxt("Error reading input symbols\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// Set Channel estimates to 1.0 (ignore fading)
|
||||
cf_t *ce[MAX_PORTS];
|
||||
for (i=0;i<cell.nof_ports;i++) {
|
||||
ce[i] = vec_malloc(nof_re * sizeof(cf_t));
|
||||
for (int j=0;j<nof_re;j++) {
|
||||
ce[i][j] = 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
pdcch_extract_llr(&pdcch, input_symbols, ce, 0, sf_idx, cfi);
|
||||
|
||||
|
||||
uint32_t nof_locations;
|
||||
if (rnti == SIRNTI) {
|
||||
nof_locations = pdcch_common_locations(&pdcch, locations, MAX_CANDIDATES, cfi);
|
||||
formats = common_formats;
|
||||
nof_formats = nof_common_formats;
|
||||
} else {
|
||||
nof_locations = pdcch_ue_locations(&pdcch, locations, MAX_CANDIDATES, sf_idx, cfi, rnti);
|
||||
formats = ue_formats;
|
||||
nof_formats = nof_ue_formats;
|
||||
}
|
||||
uint16_t crc_rem;
|
||||
dci_msg_t dci_msg;
|
||||
|
||||
for (int f=0;f<nof_formats;f++) {
|
||||
for (i=0;i<nof_locations && crc_rem != rnti;i++) {
|
||||
if (pdcch_decode_msg(&pdcch, &dci_msg, &locations[i], formats[f], &crc_rem)) {
|
||||
fprintf(stderr, "Error decoding DCI msg\n");
|
||||
return;
|
||||
}
|
||||
/* mexPrintf("Trying location (%d,%d), %s, CRC: 0x%x\n",
|
||||
locations[i].ncce, locations[i].L, dci_format_string(formats[f]), crc_rem);
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
if (nlhs >= 1) {
|
||||
plhs[0] = mxCreateLogicalScalar(crc_rem == rnti);
|
||||
}
|
||||
int nof_bits = (regs_pdcch_nregs(®s, cfi) / 9) * 72;
|
||||
if (nlhs >= 2) {
|
||||
mexutils_write_f(pdcch.pdcch_llr, &plhs[1], nof_bits, 1);
|
||||
}
|
||||
if (nlhs >= 3) {
|
||||
mexutils_write_f(pdcch.pdcch_rm_f, &plhs[2], 3*(dci_msg.nof_bits+16), 1);
|
||||
}
|
||||
|
||||
pdcch_free(&pdcch);
|
||||
regs_free(®s);
|
||||
for (i=0;i<cell.nof_ports;i++) {
|
||||
free(ce[i]);
|
||||
}
|
||||
free(input_symbols);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -0,0 +1,105 @@
|
||||
%% PDCCH Blind Search and DCI Decoding
|
||||
|
||||
%% Cell-Wide Settings
|
||||
% A structure |enbConfig| is used to configure the eNodeB.
|
||||
|
||||
Npackets = 50;
|
||||
SNR_values =linspace(-5,3,8);
|
||||
|
||||
enbConfig.NDLRB = 15; % No of Downlink RBs in total BW
|
||||
enbConfig.CyclicPrefix = 'Normal'; % CP length
|
||||
enbConfig.CFI = 3; ; % 4 PDCCH symbols as NDLRB <= 10
|
||||
enbConfig.Ng = 'Sixth'; % HICH groups
|
||||
enbConfig.CellRefP = 2; % 1-antenna ports
|
||||
enbConfig.NCellID = 10; % Physical layer cell identity
|
||||
enbConfig.NSubframe = 0; % Subframe number 0
|
||||
enbConfig.DuplexMode = 'FDD'; % Frame structure
|
||||
enbConfig.PHICHDuration = 'Normal';
|
||||
|
||||
%% DCI Message Generation
|
||||
% Generate a DCI message to be mapped to the PDCCH.
|
||||
|
||||
dciConfig.DCIFormat = 'Format1A'; % DCI message format
|
||||
dciConfig.Allocation.RIV = 26; % Resource indication value
|
||||
|
||||
% Create DCI message for given configuration
|
||||
[dciMessage, dciMessageBits] = lteDCI(enbConfig, dciConfig);
|
||||
|
||||
%% DCI Channel Coding
|
||||
|
||||
C_RNTI = 65535; % 16-bit UE-specific mask
|
||||
pdcchConfig.RNTI = C_RNTI; % Radio network temporary identifier
|
||||
pdcchConfig.PDCCHFormat = 3; % PDCCH format
|
||||
|
||||
% DCI message bits coding to form coded DCI bits
|
||||
codedDciBits = lteDCIEncode(pdcchConfig, dciMessageBits);
|
||||
|
||||
%% PDCCH Bits Generation
|
||||
|
||||
pdcchDims = ltePDCCHInfo(enbConfig);
|
||||
|
||||
% Initialize elements with -1 to indicate that all the bits are unused
|
||||
pdcchBits = -1*ones(pdcchDims.MTot, 1);
|
||||
|
||||
% Perform search space for UE-specific control channel candidates.
|
||||
candidates = ltePDCCHSpace(enbConfig, pdcchConfig, {'bits', '1based'});
|
||||
|
||||
Ncad=randi(length(candidates),1,1);
|
||||
|
||||
% Map PDCCH payload on available UE-specific candidate. In this example the
|
||||
% first available candidate is used to map the coded DCI bits.
|
||||
pdcchBits ( candidates(Ncad, 1) : candidates(Ncad, 2) ) = codedDciBits;
|
||||
|
||||
%% PDCCH Complex-Valued Modulated Symbol Generation
|
||||
|
||||
pdcchSymbols = ltePDCCH(enbConfig, pdcchBits);
|
||||
|
||||
pdcchIndices = ltePDCCHIndices(enbConfig,{'1based'});
|
||||
|
||||
decoded = zeros(size(SNR_values));
|
||||
decoded_liblte = zeros(size(SNR_values));
|
||||
|
||||
Nports = enbConfig.CellRefP;
|
||||
ueConfig.RNTI = C_RNTI;
|
||||
|
||||
subframe_tx = lteDLResourceGrid(enbConfig);
|
||||
subframe_tx(pdcchIndices) = pdcchSymbols;
|
||||
|
||||
addpath('../../debug/lte/phy/lib/phch/test')
|
||||
|
||||
parfor snr_idx=1:length(SNR_values)
|
||||
SNRdB = SNR_values(snr_idx);
|
||||
for i=1:Npackets
|
||||
|
||||
%% Noise Addition
|
||||
SNR = 10^(SNRdB/10); % Linear SNR
|
||||
|
||||
N0 = 1/(sqrt(2.0*Nports)*SNR);
|
||||
noise = N0*complex(randn(size(subframe_tx)), randn(size(subframe_tx))); % Generate noise
|
||||
|
||||
subframe_rx = sum(subframe_tx + noise,3); % Add noise to PDCCH symbols
|
||||
|
||||
pdcchSymbolsNoisy = subframe_rx(pdcchIndices(:,1));
|
||||
|
||||
%% PDCCH Decoding
|
||||
recPdcchBits = ltePDCCHDecode(enbConfig, pdcchSymbolsNoisy);
|
||||
|
||||
%% Blind Decoding using DCI Search
|
||||
[rxDCI, rxDCIBits] = ltePDCCHSearch(enbConfig, ueConfig, recPdcchBits);
|
||||
decoded(snr_idx) = decoded(snr_idx) + length(rxDCI);
|
||||
|
||||
[found_liblte, llr, viterbi_in] = liblte_pdcch(enbConfig, ueConfig.RNTI, subframe_rx);
|
||||
|
||||
decoded_liblte(snr_idx) = decoded_liblte(snr_idx)+found_liblte;
|
||||
end
|
||||
fprintf('SNR: %.1f\n',SNRdB)
|
||||
end
|
||||
|
||||
if (Npackets>1)
|
||||
plot(SNR_values,1-decoded/Npackets,SNR_values,1-decoded_liblte/Npackets)
|
||||
grid on
|
||||
legend('Matlab','libLTE')
|
||||
else
|
||||
disp(decoded_liblte)
|
||||
end
|
||||
|
@ -0,0 +1,32 @@
|
||||
enb = lteTestModel('1.1','5MHz');
|
||||
Ntrials = 1;
|
||||
SNR_values =-10;%linspace(-18,-10,8);
|
||||
|
||||
tx_offset = randi(50,Ntrials,1);
|
||||
tx_offset = 50;
|
||||
diff=zeros(size(SNR_values));
|
||||
|
||||
tx_signal = lteTestModelTool(enb);
|
||||
tx_power = mean(tx_signal.*conj(tx_signal));
|
||||
|
||||
for snr_idx=1:length(SNR_values)
|
||||
SNRdB = SNR_values(snr_idx);
|
||||
rx_offset = zeros(size(tx_offset));
|
||||
for i=1:Ntrials
|
||||
SNR = 10^(SNRdB/10); % Linear SNR
|
||||
tx = [zeros(tx_offset(i),1); tx_signal];
|
||||
N0 = tx_power/(sqrt(2.0)*SNR);
|
||||
noise = N0*complex(randn(size(tx)), randn(size(tx))); % Generate noise
|
||||
rx=noise+tx;
|
||||
[rx_offset(i),corr] = lteDLFrameOffset(enb,rx);
|
||||
end
|
||||
diff(snr_idx)=sum(abs(rx_offset-tx_offset));
|
||||
disp(SNRdB)
|
||||
end
|
||||
|
||||
if (Ntrials == 1)
|
||||
plot(corr)
|
||||
else
|
||||
plot(SNR_values,diff);
|
||||
end
|
||||
|
@ -0,0 +1,49 @@
|
||||
#
|
||||
# Copyright 2012-2013 The libLTE Developers. See the
|
||||
# COPYRIGHT file at the top-level directory of this distribution.
|
||||
#
|
||||
# This file is part of the libLTE library.
|
||||
#
|
||||
# libLTE is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# libLTE is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# A copy of the GNU Lesser General Public License can be found in
|
||||
# the LICENSE file in the top-level directory of this distribution
|
||||
# and at http://www.gnu.org/licenses/.
|
||||
#
|
||||
|
||||
########################################################################
|
||||
# Install headers
|
||||
########################################################################
|
||||
INSTALL(DIRECTORY include/
|
||||
DESTINATION "${INCLUDE_DIR}"
|
||||
FILES_MATCHING PATTERN "*.h"
|
||||
PATTERN ".svn" EXCLUDE
|
||||
)
|
||||
|
||||
########################################################################
|
||||
# Add headers to cmake project (useful for IDEs)
|
||||
########################################################################
|
||||
SET(HEADERS_ALL "")
|
||||
FILE(GLOB headers *)
|
||||
FOREACH (_header ${headers})
|
||||
IF(IS_DIRECTORY ${_header})
|
||||
FILE(GLOB_RECURSE tmp "${_header}/*.h")
|
||||
LIST(APPEND HEADERS_ALL ${tmp})
|
||||
ENDIF(IS_DIRECTORY ${_header})
|
||||
ENDFOREACH()
|
||||
|
||||
ADD_CUSTOM_TARGET (add_mex_headers SOURCES ${HEADERS_ALL})
|
||||
|
||||
########################################################################
|
||||
# Add the subdirectories
|
||||
########################################################################
|
||||
ADD_SUBDIRECTORY(lib)
|
||||
|
@ -0,0 +1,70 @@
|
||||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2014 The libLTE Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution.
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the libLTE library.
|
||||
*
|
||||
* libLTE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* libLTE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Lesser General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef MEXUTILS_
|
||||
#define MEXUTILS_
|
||||
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef UNDEF_BOOL
|
||||
#undef bool
|
||||
#endif
|
||||
|
||||
#include "mex.h"
|
||||
|
||||
#include "liblte/config.h"
|
||||
|
||||
typedef _Complex float cf_t;
|
||||
|
||||
LIBLTE_API bool mexutils_isScalar(const mxArray *ptr);
|
||||
|
||||
LIBLTE_API int mexutils_read_cell(const mxArray *ptr,
|
||||
lte_cell_t *cell);
|
||||
|
||||
LIBLTE_API int mexutils_read_uint32_struct(const mxArray *ptr,
|
||||
const char *field_name,
|
||||
uint32_t *value);
|
||||
|
||||
LIBLTE_API int mexutils_write_f(float *buffer,
|
||||
mxArray **ptr,
|
||||
uint32_t nr,
|
||||
uint32_t nc);
|
||||
|
||||
LIBLTE_API int mexutils_write_cf(cf_t *buffer,
|
||||
mxArray **ptr,
|
||||
uint32_t nr,
|
||||
uint32_t nc);
|
||||
|
||||
LIBLTE_API int mexutils_read_f(const mxArray *ptr,
|
||||
float **buffer);
|
||||
|
||||
LIBLTE_API int mexutils_read_cf(const mxArray *ptr,
|
||||
cf_t **buffer);
|
||||
|
||||
#endif
|
@ -0,0 +1,63 @@
|
||||
#
|
||||
# Copyright 2012-2013 The libLTE Developers. See the
|
||||
# COPYRIGHT file at the top-level directory of this distribution.
|
||||
#
|
||||
# This file is part of the libLTE library.
|
||||
#
|
||||
# libLTE is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# libLTE is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# A copy of the GNU Lesser General Public License can be found in
|
||||
# the LICENSE file in the top-level directory of this distribution
|
||||
# and at http://www.gnu.org/licenses/.
|
||||
#
|
||||
|
||||
if(NOT MATLAB_FOUND)
|
||||
find_package(MATLAB)
|
||||
endif()
|
||||
|
||||
if(NOT OCTAVE_FOUND)
|
||||
find_package(OCTAVE)
|
||||
endif()
|
||||
|
||||
# CMake 2.8.12 & earlier apparently don't define the
|
||||
# Mex script path, so find it.
|
||||
if(NOT MATLAB_MEX_PATH)
|
||||
find_program( MATLAB_MEX_PATH mex
|
||||
HINTS ${MATLAB_ROOT}/bin
|
||||
PATHS ${MATLAB_ROOT}/bin
|
||||
DOC "The mex program path"
|
||||
)
|
||||
endif()
|
||||
|
||||
IF (MATLAB_FOUND)
|
||||
message(STATUS "Found MATLAB in ${MATLAB_ROOT}")
|
||||
ENDIF(MATLAB_FOUND)
|
||||
IF (OCTAVE_FOUND)
|
||||
message(STATUS "Found OCTAVE in ${OCTAVE_INCLUDE_PATHS}")
|
||||
ENDIF(OCTAVE_FOUND)
|
||||
|
||||
|
||||
IF (MATLAB_FOUND OR OCTAVE_FOUND)
|
||||
ADD_LIBRARY(liblte_mex SHARED mexutils.c)
|
||||
INSTALL(TARGETS liblte_mex DESTINATION ${LIBRARY_DIR})
|
||||
LIBLTE_SET_PIC(liblte_mex)
|
||||
if (MATLAB_FOUND)
|
||||
target_include_directories(liblte_mex PUBLIC ${MATLAB_INCLUDE_DIR})
|
||||
endif(MATLAB_FOUND)
|
||||
if (OCTAVE_FOUND)
|
||||
target_include_directories(liblte_mex PUBLIC ${OCTAVE_INCLUDE_DIR})
|
||||
endif (OCTAVE_FOUND)
|
||||
|
||||
ELSEIF (MATLAB_FOUND OR OCTAVE_FOUND)
|
||||
message(STATUS "Could NOT find OCTAVE or MATLAB. MEX files won't be compiled")
|
||||
ENDIF(MATLAB_FOUND OR OCTAVE_FOUND)
|
||||
|
||||
|
@ -0,0 +1,128 @@
|
||||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2014 The libLTE Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution.
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the libLTE library.
|
||||
*
|
||||
* libLTE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* libLTE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Lesser General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <complex.h>
|
||||
#include "liblte/phy/common/phy_common.h"
|
||||
#include "liblte/mex/mexutils.h"
|
||||
#include "liblte/phy/utils/vector.h"
|
||||
|
||||
|
||||
bool mexutils_isScalar(const mxArray *ptr) {
|
||||
return mxGetM(ptr) == 1 && mxGetN(ptr) == 1;
|
||||
}
|
||||
|
||||
int mexutils_read_uint32_struct(const mxArray *ptr, const char *field_name, uint32_t *value)
|
||||
{
|
||||
mxArray *p;
|
||||
p = mxGetField(ptr, 0, field_name);
|
||||
if (!p) {
|
||||
mexPrintf("Error field %s not found\n", field_name);
|
||||
return -1;
|
||||
}
|
||||
*value = (uint32_t) mxGetScalar(p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mexutils_read_cell(const mxArray *ptr, lte_cell_t *cell) {
|
||||
if (mexutils_read_uint32_struct(ptr, "NCellID", &cell->id)) {
|
||||
return -1;
|
||||
}
|
||||
if (mexutils_read_uint32_struct(ptr, "CellRefP", &cell->nof_ports)) {
|
||||
return -1;
|
||||
}
|
||||
if (mexutils_read_uint32_struct(ptr, "NDLRB", &cell->nof_prb)) {
|
||||
return -1;
|
||||
}
|
||||
// TODO
|
||||
cell->cp = CPNORM;
|
||||
cell->phich_length = PHICH_NORM;
|
||||
cell->phich_resources = R_1_6;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mexutils_read_cf(const mxArray *ptr, cf_t **buffer) {
|
||||
int numelems = mxGetNumberOfElements(ptr);
|
||||
cf_t *tmp = vec_malloc(numelems * sizeof(cf_t));
|
||||
if (tmp) {
|
||||
double *inr=mxGetPr(ptr);
|
||||
double *ini=mxGetPi(ptr);
|
||||
for (int i=0;i<numelems;i++) {
|
||||
__real__ tmp[i] = (float) inr[i];
|
||||
if (ini) {
|
||||
__imag__ tmp[i] = (float) ini[i];
|
||||
}
|
||||
}
|
||||
*buffer = tmp;
|
||||
return numelems;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int mexutils_read_f(const mxArray *ptr, float **buffer) {
|
||||
int numelems = mxGetNumberOfElements(ptr);
|
||||
float *tmp = vec_malloc(numelems * sizeof(float));
|
||||
if (tmp) {
|
||||
double *inr=mxGetPr(ptr);
|
||||
for (int i=0;i<numelems;i++) {
|
||||
tmp[i] = (float) inr[i];
|
||||
}
|
||||
*buffer = tmp;
|
||||
return numelems;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int mexutils_write_cf(cf_t *buffer, mxArray **ptr, uint32_t nr, uint32_t nc) {
|
||||
*ptr = mxCreateDoubleMatrix(nr, nc, mxCOMPLEX);
|
||||
if (*ptr) {
|
||||
double *outr = mxGetPr(*ptr);
|
||||
double *outi = mxGetPi(*ptr);
|
||||
for (int i=0;i<nr*nc;i++) {
|
||||
outr[i] = (double) crealf(buffer[i]);
|
||||
outi[i] = (double) cimagf(buffer[i]);
|
||||
}
|
||||
return nc*nr;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int mexutils_write_f(float *buffer, mxArray **ptr, uint32_t nr, uint32_t nc) {
|
||||
*ptr = mxCreateDoubleMatrix(nr, nc, mxREAL);
|
||||
if (*ptr) {
|
||||
double *outr = mxGetPr(*ptr);
|
||||
for (int i=0;i<nr*nc;i++) {
|
||||
outr[i] = (double) buffer[i];
|
||||
}
|
||||
return nc*nr;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue