Skip to content

Commit

Permalink
optimize conv for detection
Browse files Browse the repository at this point in the history
  • Loading branch information
marenz2569 committed Jan 24, 2024
1 parent 31946c5 commit feba058
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 53 deletions.
24 changes: 14 additions & 10 deletions include/fixed_queue.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,34 @@
#include <iostream>
#include <queue>

template <typename T, int MaxLen, typename Container = std::deque<T>>
class FixedQueue : public std::queue<T, Container> {
template <typename T, int MaxLen, typename Container = std::deque<T>> class FixedQueue {
private:
Container queue{};

public:
FixedQueue() {
for (auto i = 0; i < MaxLen; i++) {
T default_value{};
std::queue<T, Container>::push(default_value);
queue.push_back(default_value);
}
}

void push(const T& value) {
if (this->size() == MaxLen) {
this->c.pop_front();
if (queue.size() == MaxLen) {
queue.pop_front();
}
std::queue<T, Container>::push(value);
queue.push_back(value);
}

void pop(const T& value) { std::logic_error("Function not implemented"); }

typename Container::const_iterator cbegin() { return this->c.cbegin(); }
typename Container::const_iterator cbegin() { return queue.cbegin(); }

typename Container::const_reverse_iterator crbegin() { return queue.crbegin(); }

typename Container::const_reverse_iterator crbegin() { return this->c.crbegin(); }
typename Container::const_iterator cend() { return queue.cend(); }

typename Container::const_iterator cend() { return this->c.cend(); }
typename Container::const_reverse_iterator crend() { return queue.crend(); }

typename Container::const_reverse_iterator crend() { return this->c.crend(); }
typename Container::const_reference operator[](typename Container::size_type pos) const { return queue[pos]; }
};
10 changes: 6 additions & 4 deletions include/iq_stream_decoder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,19 +33,21 @@ class IQStreamDecoder {
void process_complex(std::complex<float> symbol) noexcept;

private:
using QueueT = FixedQueue<std::complex<float>, 300>;

void upperMacWorker();

std::complex<float> hard_decision(std::complex<float> symbol);
std::vector<uint8_t> symbols_to_bitstream(std::vector<std::complex<float>> const& stream);

std::vector<std::complex<float>> convolve_valid(std::vector<std::complex<float>> const& a,
std::vector<std::complex<float>> const& b);
void abs_convolve_same_length(const QueueT& queueA, const std::size_t offsetA, const std::complex<float>* itb,
const std::size_t len, float* res);

std::vector<std::complex<float>> channel_estimation(std::vector<std::complex<float>> const& stream,
std::vector<std::complex<float>> const& pilots);

FixedQueue<std::complex<float>, 300> symbol_buffer_;
FixedQueue<std::complex<float>, 300> symbol_buffer_hard_decision_;
QueueT symbol_buffer_;
QueueT symbol_buffer_hard_decision_;

// 9.4.4.3.2 Normal training sequence
const std::vector<std::complex<float>> training_seq_n_ = {{-1, -1}, {-1, 1}, {1, 1}, {1, 1}, {-1, -1}, {1, -1},
Expand Down
61 changes: 22 additions & 39 deletions src/iq_stream_decoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ IQStreamDecoder::IQStreamDecoder(std::shared_ptr<LowerMac> lower_mac,
}

IQStreamDecoder::~IQStreamDecoder() {
// TODO: replace this crude hack that keeps the StreamingOrderedOutputThreadPoolExecutor<...> get function from blocking on programm stop
// TODO: replace this crude hack that keeps the StreamingOrderedOutputThreadPoolExecutor<...> get function from
// blocking on programm stop
threadPool_->queueWork([]() { return std::vector<std::function<void()>>(); });
upperMacWorkerThread_.join();
}
Expand Down Expand Up @@ -100,27 +101,14 @@ std::vector<uint8_t> IQStreamDecoder::symbols_to_bitstream(std::vector<std::comp
return bits;
}

std::vector<std::complex<float>> IQStreamDecoder::convolve_valid(std::vector<std::complex<float>> const& a,
std::vector<std::complex<float>> const& b) {
std::vector<std::complex<float>> res;

// make shure a is longer equal than b
if (b.size() > a.size()) {
return convolve_valid(b, a);
}

for (int i = 0; i < a.size() - b.size() + 1; i++) {
std::complex<float> v{};
auto ita = a.begin();
std::advance(ita, i);
auto itb = b.rbegin();
for (; itb != b.rend(); ita++, itb++) {
v += *ita * *itb;
}
res.push_back(v);
void IQStreamDecoder::abs_convolve_same_length(const QueueT& queueA, const std::size_t offsetA,
const std::complex<float>* const itb, const std::size_t len,
float* res) {
std::complex<float> acc = {0.0, 0.0};
for (std::size_t i = 0; i < len; ++i) {
acc += queueA[offsetA + i] * itb[i];
}

return res;
*res = std::abs(acc);
}

std::vector<std::complex<float>> IQStreamDecoder::channel_estimation(std::vector<std::complex<float>> const& stream,
Expand All @@ -131,6 +119,10 @@ std::vector<std::complex<float>> IQStreamDecoder::channel_estimation(std::vector

void IQStreamDecoder::process_complex(std::complex<float> symbol) noexcept {
if (is_uplink_) {
float detectedN;
float detectedP;
float detectedX;

// Control Uplink Burst or Normal Uplink Burst
symbol_buffer_.push(symbol);
symbol_buffer_hard_decision_.push(hard_decision(symbol));
Expand All @@ -140,30 +132,21 @@ void IQStreamDecoder::process_complex(std::complex<float> symbol) noexcept {
//
// find NUB
// 2 tail + 108 coded symbols + middle of 11 training sequence (6) = 116
auto start_n = symbol_buffer_hard_decision_.cbegin();
std::advance(start_n, 109);
auto end_n = start_n;
std::advance(end_n, 11);
auto find_n = convolve_valid({start_n, end_n}, training_seq_n_reversed_conj_)[0];
abs_convolve_same_length(symbol_buffer_hard_decision_, 109, training_seq_n_reversed_conj_.data(),
training_seq_n_reversed_conj_.size(), &detectedN);
// find NUB_Split
// 2 tail + 108 coded symbols + middle of 11 training sequence (6) = 116
auto start_p = symbol_buffer_hard_decision_.cbegin();
std::advance(start_p, 109);
auto end_p = start_p;
std::advance(end_p, 11);
auto find_p = convolve_valid({start_p, end_p}, training_seq_p_reversed_conj_)[0];
abs_convolve_same_length(symbol_buffer_hard_decision_, 109, training_seq_p_reversed_conj_.data(),
training_seq_p_reversed_conj_.size(), &detectedP);
// find CUB
// 2 tail + 42 coded symbols + middle of 15 training sequence (8) = 52
auto start_x = symbol_buffer_hard_decision_.cbegin();
std::advance(start_x, 44);
auto end_x = start_x;
std::advance(end_x, 15);
auto find_x = convolve_valid({start_x, end_x}, training_seq_x_reversed_conj_)[0];
abs_convolve_same_length(symbol_buffer_hard_decision_, 44, training_seq_x_reversed_conj_.data(),
training_seq_x_reversed_conj_.size(), &detectedX);

// use actual signal for further processing
auto start = symbol_buffer_.cbegin();

if (std::abs(find_x) >= SEQUENCE_DETECTION_THRESHOLD) {
if (detectedX >= SEQUENCE_DETECTION_THRESHOLD) {
// std::cout << "Potential CUB found" << std::endl;

auto end = start;
Expand All @@ -174,7 +157,7 @@ void IQStreamDecoder::process_complex(std::complex<float> symbol) noexcept {
threadPool_->queueWork(std::bind(&LowerMac::process, lower_mac_, bitstream, BurstType::ControlUplinkBurst));
}

if (std::abs(find_p) >= SEQUENCE_DETECTION_THRESHOLD) {
if (detectedP >= SEQUENCE_DETECTION_THRESHOLD) {
// std::cout << "Potential NUB_Split found" << std::endl;

auto end = start;
Expand All @@ -185,7 +168,7 @@ void IQStreamDecoder::process_complex(std::complex<float> symbol) noexcept {
BurstType::NormalUplinkBurstSplit));
}

if (std::abs(find_n) >= SEQUENCE_DETECTION_THRESHOLD) {
if (detectedN >= SEQUENCE_DETECTION_THRESHOLD) {
// std::cout << "Potential NUB found" << std::endl;

auto end = start;
Expand Down

0 comments on commit feba058

Please sign in to comment.