2020-09-18 00:23:03 +02:00
|
|
|
#pragma once
|
2020-11-02 03:57:44 +01:00
|
|
|
#include <stdio.h>
|
2020-09-18 00:23:03 +02:00
|
|
|
#include <dsp/stream.h>
|
2020-11-02 03:57:44 +01:00
|
|
|
#include <dsp/types.h>
|
|
|
|
#include <thread>
|
|
|
|
#include <vector>
|
|
|
|
#include <algorithm>
|
|
|
|
|
2020-12-25 16:58:07 +01:00
|
|
|
#include <spdlog/spdlog.h>
|
|
|
|
|
2020-09-18 00:23:03 +02:00
|
|
|
namespace dsp {
|
2021-03-29 21:53:43 +02:00
|
|
|
|
|
|
|
class generic_unnamed_block {
|
|
|
|
public:
|
|
|
|
virtual void start() {}
|
|
|
|
virtual void stop() {}
|
|
|
|
virtual int calcOutSize(int inSize) { return inSize; }
|
|
|
|
virtual int run() { return -1; }
|
|
|
|
};
|
2021-12-19 22:11:44 +01:00
|
|
|
|
2020-11-02 03:57:44 +01:00
|
|
|
template <class BLOCK>
|
2021-03-29 21:53:43 +02:00
|
|
|
class generic_block : public generic_unnamed_block {
|
2020-09-18 00:23:03 +02:00
|
|
|
public:
|
2020-11-02 03:57:44 +01:00
|
|
|
virtual void init() {}
|
2020-09-18 00:23:03 +02:00
|
|
|
|
2020-12-08 04:36:37 +01:00
|
|
|
virtual ~generic_block() {
|
2021-07-12 05:03:51 +02:00
|
|
|
if (!_block_init) { return; }
|
2020-12-08 04:36:37 +01:00
|
|
|
stop();
|
2021-07-12 05:03:51 +02:00
|
|
|
_block_init = false;
|
2020-12-08 04:36:37 +01:00
|
|
|
}
|
|
|
|
|
2020-11-02 03:57:44 +01:00
|
|
|
virtual void start() {
|
2021-07-12 05:03:51 +02:00
|
|
|
assert(_block_init);
|
2020-11-02 03:57:44 +01:00
|
|
|
std::lock_guard<std::mutex> lck(ctrlMtx);
|
2020-09-18 00:23:03 +02:00
|
|
|
if (running) {
|
|
|
|
return;
|
|
|
|
}
|
2020-11-02 17:48:17 +01:00
|
|
|
running = true;
|
2020-11-02 03:57:44 +01:00
|
|
|
doStart();
|
2020-09-18 00:23:03 +02:00
|
|
|
}
|
|
|
|
|
2020-11-02 03:57:44 +01:00
|
|
|
virtual void stop() {
|
2021-07-12 05:03:51 +02:00
|
|
|
assert(_block_init);
|
2020-11-02 03:57:44 +01:00
|
|
|
std::lock_guard<std::mutex> lck(ctrlMtx);
|
2020-11-02 17:48:17 +01:00
|
|
|
if (!running) {
|
2020-09-18 00:23:03 +02:00
|
|
|
return;
|
|
|
|
}
|
2020-11-02 03:57:44 +01:00
|
|
|
doStop();
|
2020-11-02 17:48:17 +01:00
|
|
|
running = false;
|
2020-09-18 00:23:03 +02:00
|
|
|
}
|
|
|
|
|
2021-04-18 19:12:07 +02:00
|
|
|
void tempStart() {
|
2021-07-12 05:03:51 +02:00
|
|
|
assert(_block_init);
|
2021-04-18 19:12:07 +02:00
|
|
|
if (tempStopped) {
|
|
|
|
doStart();
|
|
|
|
tempStopped = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void tempStop() {
|
2021-07-12 05:03:51 +02:00
|
|
|
assert(_block_init);
|
2021-04-18 19:12:07 +02:00
|
|
|
if (running && !tempStopped) {
|
|
|
|
doStop();
|
|
|
|
tempStopped = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-12 05:03:51 +02:00
|
|
|
virtual int calcOutSize(int inSize) {
|
|
|
|
assert(_block_init);
|
|
|
|
return inSize;
|
|
|
|
}
|
2020-09-18 00:23:03 +02:00
|
|
|
|
2020-11-02 03:57:44 +01:00
|
|
|
virtual int run() = 0;
|
2021-12-19 22:11:44 +01:00
|
|
|
|
2020-11-02 03:57:44 +01:00
|
|
|
friend BLOCK;
|
2020-09-18 00:23:03 +02:00
|
|
|
|
|
|
|
private:
|
2021-12-19 22:11:44 +01:00
|
|
|
void workerLoop() {
|
|
|
|
while (run() >= 0) {}
|
2020-09-18 00:23:03 +02:00
|
|
|
}
|
|
|
|
|
2021-07-09 14:24:07 -04:00
|
|
|
void acquire() {
|
2020-11-02 03:57:44 +01:00
|
|
|
ctrlMtx.lock();
|
2020-09-18 00:23:03 +02:00
|
|
|
}
|
|
|
|
|
2020-11-02 03:57:44 +01:00
|
|
|
void release() {
|
|
|
|
ctrlMtx.unlock();
|
2020-10-20 00:32:17 +02:00
|
|
|
}
|
|
|
|
|
2021-07-12 17:49:06 -04:00
|
|
|
void registerInput(untyped_stream* inStream) {
|
2020-11-02 03:57:44 +01:00
|
|
|
inputs.push_back(inStream);
|
2020-10-20 00:32:17 +02:00
|
|
|
}
|
|
|
|
|
2021-07-12 17:49:06 -04:00
|
|
|
void unregisterInput(untyped_stream* inStream) {
|
2020-11-02 03:57:44 +01:00
|
|
|
inputs.erase(std::remove(inputs.begin(), inputs.end(), inStream), inputs.end());
|
|
|
|
}
|
2020-10-24 14:51:55 +02:00
|
|
|
|
2021-07-12 17:49:06 -04:00
|
|
|
void registerOutput(untyped_stream* outStream) {
|
2020-11-02 03:57:44 +01:00
|
|
|
outputs.push_back(outStream);
|
2020-10-24 14:51:55 +02:00
|
|
|
}
|
|
|
|
|
2021-07-12 17:49:06 -04:00
|
|
|
void unregisterOutput(untyped_stream* outStream) {
|
2020-11-02 03:57:44 +01:00
|
|
|
outputs.erase(std::remove(outputs.begin(), outputs.end(), outStream), outputs.end());
|
2020-10-24 14:51:55 +02:00
|
|
|
}
|
|
|
|
|
2020-11-02 03:57:44 +01:00
|
|
|
virtual void doStart() {
|
2020-11-03 19:22:53 +01:00
|
|
|
workerThread = std::thread(&generic_block<BLOCK>::workerLoop, this);
|
2020-10-24 14:51:55 +02:00
|
|
|
}
|
|
|
|
|
2020-11-02 03:57:44 +01:00
|
|
|
virtual void doStop() {
|
2020-12-25 16:58:07 +01:00
|
|
|
for (auto& in : inputs) {
|
2020-11-02 03:57:44 +01:00
|
|
|
in->stopReader();
|
|
|
|
}
|
2020-12-25 16:58:07 +01:00
|
|
|
for (auto& out : outputs) {
|
2020-11-02 03:57:44 +01:00
|
|
|
out->stopWriter();
|
2020-10-24 14:51:55 +02:00
|
|
|
}
|
|
|
|
|
2020-11-02 03:57:44 +01:00
|
|
|
// TODO: Make sure this isn't needed, I don't know why it stops
|
|
|
|
if (workerThread.joinable()) {
|
|
|
|
workerThread.join();
|
|
|
|
}
|
2020-12-25 16:58:07 +01:00
|
|
|
|
|
|
|
for (auto& in : inputs) {
|
2020-11-02 03:57:44 +01:00
|
|
|
in->clearReadStop();
|
|
|
|
}
|
2020-12-25 16:58:07 +01:00
|
|
|
for (auto& out : outputs) {
|
2020-11-02 03:57:44 +01:00
|
|
|
out->clearWriteStop();
|
2020-10-24 14:51:55 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-12 05:03:51 +02:00
|
|
|
protected:
|
|
|
|
bool _block_init = false;
|
|
|
|
|
|
|
|
std::mutex ctrlMtx;
|
|
|
|
|
2021-07-12 17:49:06 -04:00
|
|
|
std::vector<untyped_stream*> inputs;
|
|
|
|
std::vector<untyped_stream*> outputs;
|
2020-11-02 03:57:44 +01:00
|
|
|
|
2020-10-24 14:51:55 +02:00
|
|
|
bool running = false;
|
2020-11-02 03:57:44 +01:00
|
|
|
bool tempStopped = false;
|
2020-10-24 14:51:55 +02:00
|
|
|
std::thread workerThread;
|
|
|
|
};
|
2021-03-29 21:53:43 +02:00
|
|
|
|
|
|
|
template <class BLOCK>
|
|
|
|
class generic_hier_block {
|
|
|
|
public:
|
|
|
|
virtual void init() {}
|
|
|
|
|
|
|
|
virtual ~generic_hier_block() {
|
2021-07-12 05:03:51 +02:00
|
|
|
if (!_block_init) { return; }
|
2021-03-29 21:53:43 +02:00
|
|
|
stop();
|
2021-07-12 05:03:51 +02:00
|
|
|
_block_init = false;
|
2021-03-29 21:53:43 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
virtual void start() {
|
2021-07-12 05:03:51 +02:00
|
|
|
assert(_block_init);
|
2021-03-29 21:53:43 +02:00
|
|
|
std::lock_guard<std::mutex> lck(ctrlMtx);
|
|
|
|
if (running) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
running = true;
|
|
|
|
doStart();
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual void stop() {
|
2021-07-12 05:03:51 +02:00
|
|
|
assert(_block_init);
|
2021-03-29 21:53:43 +02:00
|
|
|
std::lock_guard<std::mutex> lck(ctrlMtx);
|
|
|
|
if (!running) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
doStop();
|
|
|
|
running = false;
|
|
|
|
}
|
|
|
|
|
2021-04-18 19:12:07 +02:00
|
|
|
void tempStart() {
|
2021-07-12 05:03:51 +02:00
|
|
|
assert(_block_init);
|
2021-04-18 19:12:07 +02:00
|
|
|
if (tempStopped) {
|
|
|
|
doStart();
|
|
|
|
tempStopped = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void tempStop() {
|
2021-07-12 05:03:51 +02:00
|
|
|
assert(_block_init);
|
2021-04-18 19:12:07 +02:00
|
|
|
if (running && !tempStopped) {
|
|
|
|
doStop();
|
|
|
|
tempStopped = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-12 05:03:51 +02:00
|
|
|
virtual int calcOutSize(int inSize) {
|
|
|
|
assert(_block_init);
|
|
|
|
return inSize;
|
|
|
|
}
|
2021-03-29 21:53:43 +02:00
|
|
|
|
|
|
|
friend BLOCK;
|
|
|
|
|
|
|
|
private:
|
|
|
|
void registerBlock(generic_unnamed_block* block) {
|
|
|
|
blocks.push_back(block);
|
|
|
|
}
|
|
|
|
|
|
|
|
void unregisterBlock(generic_unnamed_block* block) {
|
|
|
|
blocks.erase(std::remove(blocks.begin(), blocks.end(), block), blocks.end());
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual void doStart() {
|
|
|
|
for (auto& block : blocks) {
|
|
|
|
block->start();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual void doStop() {
|
|
|
|
for (auto& block : blocks) {
|
|
|
|
block->stop();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<generic_unnamed_block*> blocks;
|
|
|
|
bool tempStopped = false;
|
|
|
|
bool running = false;
|
|
|
|
|
|
|
|
protected:
|
2021-07-12 05:03:51 +02:00
|
|
|
bool _block_init = false;
|
2021-03-29 21:53:43 +02:00
|
|
|
std::mutex ctrlMtx;
|
|
|
|
};
|
2020-11-02 03:57:44 +01:00
|
|
|
}
|