SDRPlusPlus/core/src/dsp/block.h

132 wiersze
3.2 KiB
C
Czysty Zwykły widok Historia

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