2020-06-22 16:45:57 +02:00
|
|
|
#pragma once
|
2020-11-02 03:57:44 +01:00
|
|
|
#include <dsp/block.h>
|
2020-10-23 10:39:20 +08:00
|
|
|
#include <volk/volk.h>
|
2020-06-22 16:45:57 +02:00
|
|
|
|
|
|
|
namespace dsp {
|
2020-11-02 03:57:44 +01:00
|
|
|
template <class T>
|
|
|
|
class Add : public generic_block<Add<T>> {
|
2020-06-22 16:45:57 +02:00
|
|
|
public:
|
2020-11-02 03:57:44 +01:00
|
|
|
Add() {}
|
|
|
|
|
|
|
|
Add(stream<T>* a, stream<T>* b) { init(a, b); }
|
|
|
|
|
|
|
|
void init(stream<T>* a, stream<T>* b) {
|
2020-06-22 16:45:57 +02:00
|
|
|
_a = a;
|
|
|
|
_b = b;
|
2021-02-20 15:27:43 +01:00
|
|
|
generic_block<Add<T>>::registerInput(a);
|
|
|
|
generic_block<Add<T>>::registerInput(b);
|
|
|
|
generic_block<Add<T>>::registerOutput(&out);
|
2021-07-12 05:03:51 +02:00
|
|
|
generic_block<Add<T>>::_block_init = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void setInputs(stream<T>* a, stream<T>* b) {
|
|
|
|
assert(generic_block<Add<T>>::_block_init);
|
|
|
|
std::lock_guard<std::mutex> lck(generic_block<Add<T>>::ctrlMtx);
|
|
|
|
generic_block<Add<T>>::tempStop();
|
|
|
|
generic_block<Add<T>>::unregisterInput(_a);
|
|
|
|
generic_block<Add<T>>::unregisterInput(_b);
|
|
|
|
_a = a;
|
|
|
|
_b = b;
|
|
|
|
generic_block<Add<T>>::registerInput(_a);
|
|
|
|
generic_block<Add<T>>::registerInput(_b);
|
|
|
|
generic_block<Add<T>>::tempStart();
|
|
|
|
}
|
|
|
|
|
|
|
|
void setInputA(stream<T>* a) {
|
|
|
|
assert(generic_block<Add<T>>::_block_init);
|
|
|
|
std::lock_guard<std::mutex> lck(generic_block<Add<T>>::ctrlMtx);
|
|
|
|
generic_block<Add<T>>::tempStop();
|
|
|
|
generic_block<Add<T>>::unregisterInput(_a);
|
|
|
|
_a = a;
|
|
|
|
generic_block<Add<T>>::registerInput(_a);
|
|
|
|
generic_block<Add<T>>::tempStart();
|
|
|
|
}
|
|
|
|
|
|
|
|
void setInputB(stream<T>* b) {
|
|
|
|
assert(generic_block<Add<T>>::_block_init);
|
|
|
|
std::lock_guard<std::mutex> lck(generic_block<Add<T>>::ctrlMtx);
|
|
|
|
generic_block<Add<T>>::tempStop();
|
|
|
|
generic_block<Add<T>>::unregisterInput(_b);
|
|
|
|
_b = b;
|
|
|
|
generic_block<Add<T>>::registerInput(_b);
|
|
|
|
generic_block<Add<T>>::tempStart();
|
2020-06-22 16:45:57 +02:00
|
|
|
}
|
|
|
|
|
2020-11-02 03:57:44 +01:00
|
|
|
int run() {
|
2021-03-29 21:53:43 +02:00
|
|
|
int a_count = _a->read();
|
2020-11-02 03:57:44 +01:00
|
|
|
if (a_count < 0) { return -1; }
|
2021-03-29 21:53:43 +02:00
|
|
|
int b_count = _b->read();
|
2020-11-02 03:57:44 +01:00
|
|
|
if (b_count < 0) { return -1; }
|
|
|
|
if (a_count != b_count) {
|
|
|
|
_a->flush();
|
|
|
|
_b->flush();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if constexpr (std::is_same_v<T, complex_t> || std::is_same_v<T, stereo_t>) {
|
2021-02-20 15:27:43 +01:00
|
|
|
volk_32fc_x2_add_32fc((lv_32fc_t*)out.writeBuf, (lv_32fc_t*)_a->readBuf, (lv_32fc_t*)_b->readBuf, a_count);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
volk_32f_x2_add_32f(out.writeBuf, _a->readBuf, _b->readBuf, a_count);
|
|
|
|
}
|
|
|
|
|
|
|
|
_a->flush();
|
|
|
|
_b->flush();
|
|
|
|
if (!out.swap(a_count)) { return -1; }
|
|
|
|
return a_count;
|
|
|
|
}
|
|
|
|
|
|
|
|
stream<T> out;
|
|
|
|
|
|
|
|
private:
|
|
|
|
stream<T>* _a;
|
|
|
|
stream<T>* _b;
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
template <class T>
|
2021-07-12 05:03:51 +02:00
|
|
|
class Subtract : public generic_block<Subtract<T>> {
|
2021-02-20 15:27:43 +01:00
|
|
|
public:
|
2021-07-12 05:03:51 +02:00
|
|
|
Subtract() {}
|
2021-02-20 15:27:43 +01:00
|
|
|
|
2021-07-12 05:03:51 +02:00
|
|
|
Subtract(stream<T>* a, stream<T>* b) { init(a, b); }
|
2021-02-20 15:27:43 +01:00
|
|
|
|
|
|
|
void init(stream<T>* a, stream<T>* b) {
|
|
|
|
_a = a;
|
|
|
|
_b = b;
|
2021-07-12 05:03:51 +02:00
|
|
|
generic_block<Subtract<T>>::registerInput(a);
|
|
|
|
generic_block<Subtract<T>>::registerInput(b);
|
|
|
|
generic_block<Subtract<T>>::registerOutput(&out);
|
|
|
|
generic_block<Subtract<T>>::_block_init = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void setInputs(stream<T>* a, stream<T>* b) {
|
|
|
|
assert(generic_block<Subtract<T>>::_block_init);
|
|
|
|
std::lock_guard<std::mutex> lck(generic_block<Subtract<T>>::ctrlMtx);
|
|
|
|
generic_block<Subtract<T>>::tempStop();
|
|
|
|
generic_block<Subtract<T>>::unregisterInput(_a);
|
|
|
|
generic_block<Subtract<T>>::unregisterInput(_b);
|
|
|
|
_a = a;
|
|
|
|
_b = b;
|
|
|
|
generic_block<Subtract<T>>::registerInput(_a);
|
|
|
|
generic_block<Subtract<T>>::registerInput(_b);
|
|
|
|
generic_block<Subtract<T>>::tempStart();
|
|
|
|
}
|
|
|
|
|
|
|
|
void setInputA(stream<T>* a) {
|
|
|
|
assert(generic_block<Subtract<T>>::_block_init);
|
|
|
|
std::lock_guard<std::mutex> lck(generic_block<Subtract<T>>::ctrlMtx);
|
|
|
|
generic_block<Subtract<T>>::tempStop();
|
|
|
|
generic_block<Subtract<T>>::unregisterInput(_a);
|
|
|
|
_a = a;
|
|
|
|
generic_block<Subtract<T>>::registerInput(_a);
|
|
|
|
generic_block<Subtract<T>>::tempStart();
|
|
|
|
}
|
|
|
|
|
|
|
|
void setInputB(stream<T>* b) {
|
|
|
|
assert(generic_block<Subtract<T>>::_block_init);
|
|
|
|
std::lock_guard<std::mutex> lck(generic_block<Subtract<T>>::ctrlMtx);
|
|
|
|
generic_block<Subtract<T>>::tempStop();
|
|
|
|
generic_block<Subtract<T>>::unregisterInput(_b);
|
|
|
|
_b = b;
|
|
|
|
generic_block<Subtract<T>>::registerInput(_b);
|
|
|
|
generic_block<Subtract<T>>::tempStart();
|
2021-02-20 15:27:43 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
int run() {
|
2021-03-29 21:53:43 +02:00
|
|
|
int a_count = _a->read();
|
2021-02-20 15:27:43 +01:00
|
|
|
if (a_count < 0) { return -1; }
|
2021-03-29 21:53:43 +02:00
|
|
|
int b_count = _b->read();
|
2021-02-20 15:27:43 +01:00
|
|
|
if (b_count < 0) { return -1; }
|
|
|
|
if (a_count != b_count) {
|
|
|
|
_a->flush();
|
|
|
|
_b->flush();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if constexpr (std::is_same_v<T, complex_t> || std::is_same_v<T, stereo_t>) {
|
|
|
|
volk_32f_x2_subtract_32f((float*)out.writeBuf, (float*)_a->readBuf, (float*)_b->readBuf, a_count * 2);
|
2020-11-02 03:57:44 +01:00
|
|
|
}
|
|
|
|
else {
|
2021-03-29 21:53:43 +02:00
|
|
|
volk_32f_x2_subtract_32f(out.writeBuf, _a->readBuf, _b->readBuf, a_count);
|
2020-11-02 03:57:44 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
_a->flush();
|
|
|
|
_b->flush();
|
2020-12-25 16:58:07 +01:00
|
|
|
if (!out.swap(a_count)) { return -1; }
|
2020-11-02 03:57:44 +01:00
|
|
|
return a_count;
|
|
|
|
}
|
|
|
|
|
|
|
|
stream<T> out;
|
|
|
|
|
|
|
|
private:
|
|
|
|
stream<T>* _a;
|
|
|
|
stream<T>* _b;
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
template <class T>
|
|
|
|
class Multiply : public generic_block<Multiply<T>> {
|
|
|
|
public:
|
|
|
|
Multiply() {}
|
|
|
|
|
|
|
|
Multiply(stream<T>* a, stream<T>* b) { init(a, b); }
|
|
|
|
|
|
|
|
void init(stream<T>* a, stream<T>* b) {
|
2020-06-22 16:45:57 +02:00
|
|
|
_a = a;
|
|
|
|
_b = b;
|
2020-11-02 03:57:44 +01:00
|
|
|
generic_block<Multiply>::registerInput(a);
|
|
|
|
generic_block<Multiply>::registerInput(b);
|
|
|
|
generic_block<Multiply>::registerOutput(&out);
|
2021-07-12 05:03:51 +02:00
|
|
|
generic_block<Multiply>::_block_init = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void setInputs(stream<T>* a, stream<T>* b) {
|
|
|
|
assert(generic_block<Multiply<T>>::_block_init);
|
|
|
|
std::lock_guard<std::mutex> lck(generic_block<Multiply<T>>::ctrlMtx);
|
|
|
|
generic_block<Multiply<T>>::tempStop();
|
|
|
|
generic_block<Multiply<T>>::unregisterInput(_a);
|
|
|
|
generic_block<Multiply<T>>::unregisterInput(_b);
|
|
|
|
_a = a;
|
|
|
|
_b = b;
|
|
|
|
generic_block<Multiply<T>>::registerInput(_a);
|
|
|
|
generic_block<Multiply<T>>::registerInput(_b);
|
|
|
|
generic_block<Multiply<T>>::tempStart();
|
|
|
|
}
|
|
|
|
|
|
|
|
void setInputA(stream<T>* a) {
|
|
|
|
assert(generic_block<Multiply<T>>::_block_init);
|
|
|
|
std::lock_guard<std::mutex> lck(generic_block<Multiply<T>>::ctrlMtx);
|
|
|
|
generic_block<Multiply<T>>::tempStop();
|
|
|
|
generic_block<Multiply<T>>::unregisterInput(_a);
|
|
|
|
_a = a;
|
|
|
|
generic_block<Multiply<T>>::registerInput(_a);
|
|
|
|
generic_block<Multiply<T>>::tempStart();
|
|
|
|
}
|
|
|
|
|
|
|
|
void setInputB(stream<T>* b) {
|
|
|
|
assert(generic_block<Multiply<T>>::_block_init);
|
|
|
|
std::lock_guard<std::mutex> lck(generic_block<Multiply<T>>::ctrlMtx);
|
|
|
|
generic_block<Multiply<T>>::tempStop();
|
|
|
|
generic_block<Multiply<T>>::unregisterInput(_b);
|
|
|
|
_b = b;
|
|
|
|
generic_block<Multiply<T>>::registerInput(_b);
|
|
|
|
generic_block<Multiply<T>>::tempStart();
|
2020-06-22 16:45:57 +02:00
|
|
|
}
|
|
|
|
|
2020-11-02 03:57:44 +01:00
|
|
|
int run() {
|
2021-03-29 21:53:43 +02:00
|
|
|
int a_count = _a->read();
|
2020-11-02 03:57:44 +01:00
|
|
|
if (a_count < 0) { return -1; }
|
2021-03-29 21:53:43 +02:00
|
|
|
int b_count = _b->read();
|
2020-11-02 03:57:44 +01:00
|
|
|
if (b_count < 0) { return -1; }
|
|
|
|
if (a_count != b_count) {
|
|
|
|
_a->flush();
|
|
|
|
_b->flush();
|
|
|
|
return 0;
|
2020-06-22 16:45:57 +02:00
|
|
|
}
|
|
|
|
|
2020-11-02 03:57:44 +01:00
|
|
|
if constexpr (std::is_same_v<T, complex_t>) {
|
2021-03-29 22:28:26 +02:00
|
|
|
volk_32fc_x2_multiply_32fc((lv_32fc_t*)out.writeBuf, (lv_32fc_t*)_a->readBuf, (lv_32fc_t*)_b->readBuf, a_count);
|
2020-06-22 16:45:57 +02:00
|
|
|
}
|
2020-11-02 03:57:44 +01:00
|
|
|
else {
|
2020-12-25 16:58:07 +01:00
|
|
|
volk_32f_x2_multiply_32f(out.writeBuf, _a->readBuf, _b->readBuf, a_count);
|
2020-06-22 16:45:57 +02:00
|
|
|
}
|
2020-11-02 03:57:44 +01:00
|
|
|
|
|
|
|
_a->flush();
|
|
|
|
_b->flush();
|
2020-12-25 16:58:07 +01:00
|
|
|
if (!out.swap(a_count)) { return -1; }
|
2020-11-02 03:57:44 +01:00
|
|
|
return a_count;
|
2020-06-22 16:45:57 +02:00
|
|
|
}
|
|
|
|
|
2020-11-02 03:57:44 +01:00
|
|
|
stream<T> out;
|
2020-06-22 16:45:57 +02:00
|
|
|
|
|
|
|
private:
|
2020-11-02 03:57:44 +01:00
|
|
|
stream<T>* _a;
|
|
|
|
stream<T>* _b;
|
2020-06-22 16:45:57 +02:00
|
|
|
|
|
|
|
};
|
2020-11-02 03:57:44 +01:00
|
|
|
}
|