/** * * \section COPYRIGHT * * Copyright 2013-2021 Software Radio Systems Limited * * By using this file, you agree to the terms and conditions set * forth in the LICENSE file which can be found at the top level of * the distribution. * */ #ifndef SRSRAN_RF_BUFFER_H #define SRSRAN_RF_BUFFER_H #include "srsran/interfaces/radio_interfaces.h" namespace srsran { /** * Implemenation of the rf_buffer_interface for the current radio implementation which uses flat arrays. * @see rf_buffer_interface * @see radio * */ class rf_buffer_t : public rf_buffer_interface { public: /** * Creates an object and allocates memory for nof_subframes_ assuming the * largest system bandwidth * @param nof_subframes_ Number of subframes to allocate */ explicit rf_buffer_t(uint32_t nof_subframes_) { if (nof_subframes_ > 0) { // Allocate buffers for an integer number of subframes for (uint32_t i = 0; i < SRSRAN_MAX_CHANNELS; i++) { sample_buffer[i] = srsran_vec_cf_malloc(nof_subframes_ * SRSRAN_SF_LEN_MAX); srsran_vec_cf_zero(sample_buffer[i], SRSRAN_SF_LEN_MAX); } allocated = true; nof_subframes = nof_subframes_; } } /** * Creates an object and sets the buffers to the flat array pointed by data. Note that data must * contain up to SRSRAN_MAX_CHANNELS pointers * @param data Flat array to use as initializer for the internal buffer pointers */ explicit rf_buffer_t(cf_t* data[SRSRAN_MAX_CHANNELS], uint32_t nof_samples_) { for (uint32_t i = 0; i < SRSRAN_MAX_CHANNELS; i++) { sample_buffer[i] = data[i]; } nof_samples = nof_samples_; } /** * Creates an object from a single array pointer. The rest of the channel pointers will be left to NULL * @param data Flat array to use as initializer for the internal buffer pointers */ explicit rf_buffer_t(cf_t* data, uint32_t nof_samples_) { sample_buffer[0] = data; nof_samples = nof_samples_; } /** * Default constructor leaves the internal pointers to NULL */ rf_buffer_t() = default; /** * The destructor will deallocate memory only if it was allocated passing nof_subframes > 0 */ ~rf_buffer_t() { if (allocated) { free_all(); } } /** * Overrides the = operator such that the lvalue internal buffers point to the pointers inside rvalue. * If memory has already been allocated in the lvalue object, it will free it before pointing the * buffers to the lvalue. * After this operator, when the lvalue is destroyed no memory will be freed. * @param other rvalue * @return lvalue */ rf_buffer_t& operator=(const rf_buffer_t& other) { if (this == &other) { return *this; } if (this->allocated) { free_all(); this->allocated = false; } for (int i = 0; i < SRSRAN_MAX_CHANNELS; i++) { this->sample_buffer[i] = other.sample_buffer[i]; } return *this; } rf_buffer_t(const rf_buffer_t& other) = delete; cf_t* get(const uint32_t& channel_idx) const override { return sample_buffer.at(channel_idx); } void set(const uint32_t& channel_idx, cf_t* ptr) override { sample_buffer.at(channel_idx) = ptr; } cf_t* get(const uint32_t& logical_ch, const uint32_t& port_idx, const uint32_t& nof_antennas) const override { return sample_buffer.at(logical_ch * nof_antennas + port_idx); } void set(const uint32_t& logical_ch, const uint32_t& port_idx, const uint32_t& nof_antennas, cf_t* ptr) override { sample_buffer.at(logical_ch * nof_antennas + port_idx) = ptr; } void set_combine(const uint32_t& channel_idx, cf_t* ptr) { if (sample_buffer.at(channel_idx) == nullptr) { sample_buffer.at(channel_idx) = ptr; } else if (ptr != nullptr) { srsran_vec_sum_ccc(ptr, sample_buffer.at(channel_idx), sample_buffer.at(channel_idx), nof_samples); } } void set_combine(const uint32_t& logical_ch, const uint32_t& port_idx, const uint32_t& nof_antennas, cf_t* ptr) { set_combine(logical_ch * nof_antennas + port_idx, ptr); } void set_combine(const rf_buffer_interface& other) { // Take the other number of samples always set_nof_samples(other.get_nof_samples()); for (uint32_t ch = 0; ch < SRSRAN_MAX_CHANNELS; ch++) { set_combine(ch, other.get(ch)); } } void** to_void() override { return (void**)sample_buffer.data(); } cf_t** to_cf_t() override { return sample_buffer.data(); } uint32_t size() override { return nof_subframes * SRSRAN_SF_LEN_MAX; } void set_nof_samples(uint32_t n) override { nof_samples = n; } uint32_t get_nof_samples() const override { return nof_samples; } private: std::array sample_buffer = {}; bool allocated = false; uint32_t nof_subframes = 0; uint32_t nof_samples = 0; void free_all() { for (uint32_t i = 0; i < SRSRAN_MAX_CHANNELS; i++) { if (sample_buffer[i]) { free(sample_buffer[i]); } } } }; } // namespace srsran #endif // SRSRAN_RF_BUFFER_H