mirror of
https://github.com/AlexandreRouma/SDRPlusPlus.git
synced 2025-03-27 01:45:28 +01:00
new buffer thingy
This commit is contained in:
parent
192e86064c
commit
dff9ec2d37
@ -214,4 +214,112 @@ namespace dsp {
|
|||||||
std::condition_variable canReadVar;
|
std::condition_variable canReadVar;
|
||||||
std::condition_variable canWriteVar;
|
std::condition_variable canWriteVar;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define TEST_BUFFER_SIZE 32
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
class SampleFrameBuffer : public generic_block<SampleFrameBuffer<T>> {
|
||||||
|
public:
|
||||||
|
SampleFrameBuffer() {}
|
||||||
|
|
||||||
|
SampleFrameBuffer(stream<T>* in) { init(in); }
|
||||||
|
|
||||||
|
~SampleFrameBuffer() {
|
||||||
|
stop();
|
||||||
|
out.stopWriter();
|
||||||
|
stopWorker = true;
|
||||||
|
cnd.notify_all();
|
||||||
|
if (readWorkerThread.joinable()) { readWorkerThread.join(); }
|
||||||
|
}
|
||||||
|
|
||||||
|
void init(stream<T>* in) {
|
||||||
|
_in = in;
|
||||||
|
|
||||||
|
for (int i = 0; i < TEST_BUFFER_SIZE; i++) {
|
||||||
|
buffers[i] = new T[STREAM_BUFFER_SIZE];
|
||||||
|
}
|
||||||
|
|
||||||
|
generic_block<SampleFrameBuffer<T>>::registerInput(in);
|
||||||
|
generic_block<SampleFrameBuffer<T>>::registerOutput(&out);
|
||||||
|
|
||||||
|
readWorkerThread = std::thread(&SampleFrameBuffer::worker, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setInput(stream<T>* in) {
|
||||||
|
std::lock_guard<std::mutex> lck(generic_block<SampleFrameBuffer<T>>::ctrlMtx);
|
||||||
|
generic_block<SampleFrameBuffer<T>>::tempStop();
|
||||||
|
generic_block<SampleFrameBuffer<T>>::unregisterInput(_in);
|
||||||
|
_in = in;
|
||||||
|
generic_block<SampleFrameBuffer<T>>::registerInput(_in);
|
||||||
|
generic_block<SampleFrameBuffer<T>>::tempStart();
|
||||||
|
}
|
||||||
|
|
||||||
|
int run() {
|
||||||
|
// Wait for data
|
||||||
|
int count = _in->read();
|
||||||
|
if (count < 0) { return -1; }
|
||||||
|
|
||||||
|
if (bypass) {
|
||||||
|
memcpy(out.writeBuf, _in->readBuf, count * sizeof(T));
|
||||||
|
_in->flush();
|
||||||
|
if (!out.swap(count)) { return -1; }
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Push it on the ring buffer
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lck(bufMtx);
|
||||||
|
memcpy(buffers[writeCur], _in->readBuf, count * sizeof(T));
|
||||||
|
uintptr_t ptr = (uintptr_t)buffers[writeCur];
|
||||||
|
sizes[writeCur] = count;
|
||||||
|
writeCur++;
|
||||||
|
writeCur = ((writeCur) % TEST_BUFFER_SIZE);
|
||||||
|
|
||||||
|
if (((writeCur - readCur + TEST_BUFFER_SIZE) % TEST_BUFFER_SIZE) >= (TEST_BUFFER_SIZE-2)) {
|
||||||
|
spdlog::warn("Overflow");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cnd.notify_all();
|
||||||
|
_in->flush();
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
void worker() {
|
||||||
|
while (true) {
|
||||||
|
// Wait for data
|
||||||
|
std::unique_lock lck(bufMtx);
|
||||||
|
cnd.wait(lck, [this](){ return (((writeCur - readCur + TEST_BUFFER_SIZE) % TEST_BUFFER_SIZE) > 0) || stopWorker; });
|
||||||
|
if (stopWorker) { break; }
|
||||||
|
|
||||||
|
// Write one to output buffer and unlock in preparation to swap buffers
|
||||||
|
int count = sizes[readCur];
|
||||||
|
memcpy(out.writeBuf, buffers[readCur], count * sizeof(T));
|
||||||
|
readCur++;
|
||||||
|
readCur = ((readCur) % TEST_BUFFER_SIZE);
|
||||||
|
lck.unlock();
|
||||||
|
|
||||||
|
// Swap
|
||||||
|
if (!out.swap(count)) { break; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stream<T> out;
|
||||||
|
|
||||||
|
int writeCur = 0;
|
||||||
|
int readCur = 0;
|
||||||
|
|
||||||
|
bool bypass = false;
|
||||||
|
|
||||||
|
private:
|
||||||
|
stream<T>* _in;
|
||||||
|
|
||||||
|
std::thread readWorkerThread;
|
||||||
|
std::mutex bufMtx;
|
||||||
|
std::condition_variable cnd;
|
||||||
|
T* buffers[TEST_BUFFER_SIZE];
|
||||||
|
int sizes[TEST_BUFFER_SIZE];
|
||||||
|
|
||||||
|
bool stopWorker = false;
|
||||||
|
|
||||||
|
};
|
||||||
};
|
};
|
@ -459,6 +459,10 @@ void MainWindow::draw() {
|
|||||||
ImGui::Checkbox("Show demo window", &demoWindow);
|
ImGui::Checkbox("Show demo window", &demoWindow);
|
||||||
ImGui::Text("ImGui version: %s", ImGui::GetVersion());
|
ImGui::Text("ImGui version: %s", ImGui::GetVersion());
|
||||||
|
|
||||||
|
ImGui::Checkbox("Bypass buffering", &sigpath::signalPath.inputBuffer.bypass);
|
||||||
|
|
||||||
|
ImGui::Text("Buffering: %d", (sigpath::signalPath.inputBuffer.writeCur - sigpath::signalPath.inputBuffer.readCur + 20) % 20);
|
||||||
|
|
||||||
if (ImGui::Button("Test Bug")) {
|
if (ImGui::Button("Test Bug")) {
|
||||||
spdlog::error("Will this make the software crash?");
|
spdlog::error("Will this make the software crash?");
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,9 @@ void SignalPath::init(uint64_t sampleRate, int fftRate, int fftSize, dsp::stream
|
|||||||
this->fftSize = fftSize;
|
this->fftSize = fftSize;
|
||||||
inputBlockSize = sampleRate / 200.0f;
|
inputBlockSize = sampleRate / 200.0f;
|
||||||
|
|
||||||
split.init(input);
|
// split.init(input);
|
||||||
|
inputBuffer.init(input);
|
||||||
|
split.init(&inputBuffer.out);
|
||||||
|
|
||||||
reshape.init(&fftStream, fftSize, (sampleRate / fftRate) - fftSize);
|
reshape.init(&fftStream, fftSize, (sampleRate / fftRate) - fftSize);
|
||||||
split.bindStream(&fftStream);
|
split.bindStream(&fftStream);
|
||||||
@ -45,12 +47,14 @@ double SignalPath::getSampleRate() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SignalPath::start() {
|
void SignalPath::start() {
|
||||||
|
inputBuffer.start();
|
||||||
split.start();
|
split.start();
|
||||||
reshape.start();
|
reshape.start();
|
||||||
fftHandlerSink.start();
|
fftHandlerSink.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SignalPath::stop() {
|
void SignalPath::stop() {
|
||||||
|
inputBuffer.stop();
|
||||||
split.stop();
|
split.stop();
|
||||||
reshape.stop();
|
reshape.stop();
|
||||||
fftHandlerSink.stop();
|
fftHandlerSink.stop();
|
||||||
@ -83,7 +87,8 @@ void SignalPath::removeVFO(std::string name) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SignalPath::setInput(dsp::stream<dsp::complex_t>* input) {
|
void SignalPath::setInput(dsp::stream<dsp::complex_t>* input) {
|
||||||
split.setInput(input);
|
// split.setInput(input);
|
||||||
|
inputBuffer.setInput(input);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SignalPath::bindIQStream(dsp::stream<dsp::complex_t>* stream) {
|
void SignalPath::bindIQStream(dsp::stream<dsp::complex_t>* stream) {
|
||||||
|
@ -21,6 +21,8 @@ public:
|
|||||||
void startFFT();
|
void startFFT();
|
||||||
void stopFFT();
|
void stopFFT();
|
||||||
|
|
||||||
|
dsp::SampleFrameBuffer<dsp::complex_t> inputBuffer;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct VFO_t {
|
struct VFO_t {
|
||||||
dsp::stream<dsp::complex_t>* inputStream;
|
dsp::stream<dsp::complex_t>* inputStream;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user