SDRPlusPlus/core/src/dsp/stream.h

142 wiersze
3.6 KiB
C
Czysty Zwykły widok Historia

2020-06-10 02:13:56 +00:00
#pragma once
2022-06-15 14:08:28 +00:00
#include <string.h>
2020-11-02 02:57:44 +00:00
#include <mutex>
2020-06-10 02:13:56 +00:00
#include <condition_variable>
2020-11-02 02:57:44 +00:00
#include <volk/volk.h>
2022-06-15 14:08:28 +00:00
#include "buffer/buffer.h"
2020-06-10 02:13:56 +00:00
2022-06-15 14:08:28 +00:00
// 1MSample buffer
#define STREAM_BUFFER_SIZE 1000000
2020-06-22 14:45:57 +00:00
namespace dsp {
class untyped_stream {
2020-11-02 02:57:44 +00:00
public:
virtual ~untyped_stream() {}
virtual bool swap(int size) { return false; }
2020-11-02 02:57:44 +00:00
virtual int read() { return -1; }
virtual void flush() {}
virtual void stopWriter() {}
virtual void clearWriteStop() {}
virtual void stopReader() {}
virtual void clearReadStop() {}
2020-11-02 02:57:44 +00:00
};
2020-06-10 02:13:56 +00:00
template <class T>
class stream : public untyped_stream {
2020-06-10 02:13:56 +00:00
public:
2020-06-10 16:52:07 +00:00
stream() {
2022-06-15 14:08:28 +00:00
writeBuf = buffer::alloc<T>(STREAM_BUFFER_SIZE);
readBuf = buffer::alloc<T>(STREAM_BUFFER_SIZE);
2020-06-10 16:52:07 +00:00
}
2022-06-15 14:08:28 +00:00
virtual ~stream() {
2022-06-20 16:15:35 +00:00
free();
2020-06-10 02:13:56 +00:00
}
2022-06-15 14:08:28 +00:00
virtual void setBufferSize(int samples) {
buffer::free(writeBuf);
buffer::free(readBuf);
writeBuf = buffer::alloc<T>(samples);
readBuf = buffer::alloc<T>(samples);
2022-01-26 12:23:55 +00:00
}
2022-06-15 14:08:28 +00:00
virtual inline bool swap(int size) {
{
// Wait to either swap or stop
std::unique_lock<std::mutex> lck(swapMtx);
swapCV.wait(lck, [this] { return (canSwap || writerStop); });
// If writer was stopped, abandon operation
2020-12-25 17:17:43 +00:00
if (writerStop) { return false; }
// Swap buffers
dataSize = size;
T* temp = writeBuf;
writeBuf = readBuf;
readBuf = temp;
canSwap = false;
}
// Notify reader that some data is ready
2020-11-02 15:16:21 +00:00
{
std::lock_guard<std::mutex> lck(rdyMtx);
2020-11-02 15:16:21 +00:00
dataReady = true;
}
rdyCV.notify_all();
return true;
2020-06-10 02:13:56 +00:00
}
2022-06-15 14:08:28 +00:00
virtual inline int read() {
// Wait for data to be ready or to be stopped
std::unique_lock<std::mutex> lck(rdyMtx);
rdyCV.wait(lck, [this] { return (dataReady || readerStop); });
2020-12-25 17:17:43 +00:00
return (readerStop ? -1 : dataSize);
2020-06-10 02:13:56 +00:00
}
2022-06-15 14:08:28 +00:00
virtual inline void flush() {
2020-12-25 17:17:43 +00:00
// Clear data ready
{
std::lock_guard<std::mutex> lck(rdyMtx);
dataReady = false;
}
// Notify writer that buffers can be swapped
2020-11-02 15:16:21 +00:00
{
std::lock_guard<std::mutex> lck(swapMtx);
canSwap = true;
2020-11-02 15:16:21 +00:00
}
2020-12-25 17:17:43 +00:00
swapCV.notify_all();
2020-06-10 02:13:56 +00:00
}
2022-06-15 14:08:28 +00:00
virtual void stopWriter() {
2020-11-02 15:16:21 +00:00
{
std::lock_guard<std::mutex> lck(swapMtx);
writerStop = true;
2020-11-02 15:16:21 +00:00
}
swapCV.notify_all();
2020-06-10 02:13:56 +00:00
}
2022-06-15 14:08:28 +00:00
virtual void clearWriteStop() {
writerStop = false;
2020-06-15 13:53:45 +00:00
}
2022-06-15 14:08:28 +00:00
virtual void stopReader() {
2020-11-02 15:16:21 +00:00
{
std::lock_guard<std::mutex> lck(rdyMtx);
readerStop = true;
2020-11-02 15:16:21 +00:00
}
rdyCV.notify_all();
2020-06-15 13:53:45 +00:00
}
2022-06-15 14:08:28 +00:00
virtual void clearReadStop() {
readerStop = false;
2020-06-15 13:53:45 +00:00
}
2022-06-20 16:15:35 +00:00
void free() {
if (writeBuf) { buffer::free(writeBuf); }
if (readBuf) { buffer::free(readBuf); }
writeBuf = NULL;
readBuf = NULL;
}
T* writeBuf;
T* readBuf;
2020-06-15 13:53:45 +00:00
2020-11-02 02:57:44 +00:00
private:
std::mutex swapMtx;
std::condition_variable swapCV;
bool canSwap = true;
2020-06-15 13:53:45 +00:00
std::mutex rdyMtx;
std::condition_variable rdyCV;
2020-11-02 02:57:44 +00:00
bool dataReady = false;
2020-06-22 14:45:57 +00:00
2020-11-02 02:57:44 +00:00
bool readerStop = false;
bool writerStop = false;
int dataSize = 0;
2020-06-10 02:13:56 +00:00
};
2020-11-02 02:57:44 +00:00
}