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