Skip to content

Commit

Permalink
Add experimental ring buffer based RAW recording
Browse files Browse the repository at this point in the history
  • Loading branch information
AlbrechtL committed Nov 13, 2018
1 parent e8e487e commit 10a6bdd
Show file tree
Hide file tree
Showing 9 changed files with 123 additions and 4 deletions.
1 change: 1 addition & 0 deletions src/input/raw_file.cpp
Expand Up @@ -283,6 +283,7 @@ void CRAWFile::run(void)
}
SampleBuffer.putDataIntoBuffer(bi.data(), t);
SpectrumSampleBuffer.putDataIntoBuffer(bi.data(), t);
putIntoRecordBuffer(*bi.data(), t);
int64_t t_to_wait = nextStop - getMyTime();
if (throttle and t_to_wait > 0)
std::this_thread::sleep_for(std::chrono::microseconds(t_to_wait));
Expand Down
1 change: 1 addition & 0 deletions src/input/rtl_sdr.cpp
Expand Up @@ -343,6 +343,7 @@ void CRTL_SDR::RTLSDRCallBack(uint8_t* buf, uint32_t len, void* ctx)
rtlsdr->sampleCounter += len - tmp;

rtlsdr->spectrumSampleBuffer.putDataIntoBuffer(buf, len);
rtlsdr->putIntoRecordBuffer(*buf, len);

// Check if device is overloaded
rtlsdr->minAmplitude = 255;
Expand Down
52 changes: 49 additions & 3 deletions src/input/virtual_input.h
Expand Up @@ -30,16 +30,62 @@
#ifndef __VIRTUAL_INPUT
#define __VIRTUAL_INPUT

#include <memory>
#include <fstream>
#include <iostream>

#include "dab-constants.h"
#include "radio-controller.h"
#include "ringbuffer.h"

enum class CDeviceID {
UNKNOWN, NULLDEVICE, AIRSPY, RAWFILE, RTL_SDR, RTL_TCP, SOAPYSDR};

class CVirtualInput : public InputInterface {
public:
virtual ~CVirtualInput() {}
virtual CDeviceID getID(void) = 0;
public:
virtual ~CVirtualInput() {}
virtual CDeviceID getID(void) = 0;

void writeRecordBufferToFile(std::string &fileanme) {
if(!recordBuffer)
return;

std::ofstream rawStream(fileanme, std::ios::binary);
int test = recordBuffer->GetRingBufferReadAvailable();

while(recordBuffer->GetRingBufferReadAvailable() > 0) {
size_t data_tmpSize = 0;
if(recordBuffer->GetRingBufferReadAvailable() > 1024)
data_tmpSize = 1024;
else
data_tmpSize = static_cast<size_t>(recordBuffer->GetRingBufferReadAvailable());

uint8_t data_tmp[data_tmpSize];

This comment has been minimized.

Copy link
@gvanem

gvanem Nov 28, 2018

Contributor

I get a stack-overflow here when pressing the Save ring buffer button. Can we be certain that the elementType is uint8_t for all uses of the IQRingBuffer?

This comment has been minimized.

Copy link
@gvanem

gvanem Nov 28, 2018

Contributor

Update: Doing this patch:

--- a/src/input/virtual_input.h 2018-11-28 16:14:12
+++ b/src/input/virtual_input.h 2018-11-28 18:49:23
@@ -59,7 +59,7 @@
             else
                 data_tmpSize = static_cast<size_t>(recordBuffer->GetRingBufferReadAvailable());

-            uint8_t data_tmp[data_tmpSize];
+            uint8_t data_tmp[1024*sizeof(float)];
             recordBuffer->getDataFromBuffer(data_tmp, data_tmpSize);
             rawStream.write((char *) data_tmp, data_tmpSize);
         }

fixed the stack-overflow.

This comment has been minimized.

Copy link
@mpbraendli

mpbraendli Nov 29, 2018

Collaborator

This comment has been minimized.

Copy link
@gvanem

gvanem Nov 29, 2018

Contributor

Talking to me? I fully agree, but a 1024*sizeof(float) is a constant according to the C/C++-standards AFAICS.

This comment has been minimized.

Copy link
@mpbraendli

mpbraendli Nov 29, 2018

Collaborator

Talking to me?

No :-)

1024*sizeof(float) is indeed a compile-time constant.

This comment has been minimized.

Copy link
@AlbrechtL

AlbrechtL Nov 29, 2018

Author Owner

I added this preliminary feature to analyze #247. I agree that variable-length array isn't a great idea but it was working for me. Please keep in mind that my focus was not to write perfect code. My focus was to analyze the synchronization issue. ;-)
This was also the reason why I marked it as experimental and I only tested with a rtl-sdr which is using uint8.

@gvanem You are welcome to make the recorder stable and send a pull request.
Honestly, you give a lot of feedback and you are able to fix issues inside the code. I would prefer that you fix issues or improve features and send pull requests. To comment our commits makes us more work but it doesn't improve the code.

recordBuffer->getDataFromBuffer(data_tmp, data_tmpSize);
rawStream.write((char *) data_tmp, data_tmpSize);
}
rawStream.close();
}

void initRecordBuffer(uint32_t size) {
// The ring buffer size has to be power of 2
uint32_t bitCount = ceil(log2(size));
uint32_t bufferSize = pow(2, bitCount);

recordBuffer.reset(new RingBuffer<uint8_t>(bufferSize));
}

protected:
void putIntoRecordBuffer(uint8_t &data, uint32_t size) {
if(!recordBuffer)
return;

recordBuffer->putDataIntoBuffer(&data, static_cast<int>(size));
std::clog << "CVirtualInput: GetRingBufferReadAvailable() " << recordBuffer->GetRingBufferReadAvailable() << std::endl;
}

private:
std::unique_ptr<RingBuffer<uint8_t>> recordBuffer;
};

#endif
6 changes: 6 additions & 0 deletions src/welle-gui/QML/MainView.qml
Expand Up @@ -417,6 +417,12 @@ ApplicationWindow {
font.pixelSize: TextStyle.textStandartSize
onTriggered: generalView.addComponent("qrc:/QML/expertviews/TextOutputView.qml")
}

MenuItem {
text: qsTr("RAW Recorder")
font.pixelSize: TextStyle.textStandartSize
onTriggered: generalView.addComponent("qrc:/QML/expertviews/RawRecorder.qml")
}
}
}

Expand Down
47 changes: 47 additions & 0 deletions src/welle-gui/QML/expertviews/RawRecorder.qml
@@ -0,0 +1,47 @@
import QtQuick 2.0
import QtQuick.Controls 2.3
import QtQuick.Layouts 1.1


// Import custom styles
import "../texts"
import "../components"

ViewBaseFrame {
labelText: qsTr("I/Q RAW Recorder (experimental)")

property bool isStart: false
property int ringeBufferSize: 0

content: ColumnLayout {
RowLayout {
TextStandart {
text: qsTr("Ring buffer length [s]")
}

WTumbler {
id: ringeBufferSetting
model: [5, 10, 60, 120, 240]
}

WButton {
text: isStart ? qsTr("Save ringe buffer") : qsTr("Init")

onPressed: {
ringeBufferSize = parseInt(ringeBufferSetting.currentItem.text) * 2048 * 1024

if(!isStart)
radioController.initRecorder(ringeBufferSize)
else
radioController.triggerRecorder("")

isStart = !isStart
}
}
}

TextStandart {
text: "Ringe buffer size [MB]: " + (ringeBufferSize / 1000000)
}
}
}
16 changes: 15 additions & 1 deletion src/welle-gui/radio_controller.cpp
Expand Up @@ -32,6 +32,7 @@

#include <QDebug>
#include <QSettings>
#include <QStandardPaths>
#include <stdexcept>

#include "radio_controller.h"
Expand Down Expand Up @@ -395,7 +396,20 @@ void CRadioController::setGain(int Gain)
gainCount = gainCount_tmp;
emit gainCountChanged(gainCount);
}
}
}
}

void CRadioController::initRecorder(int size)
{
device->initRecordBuffer(size);
}

void CRadioController::triggerRecorder(QString filename)
{
// TODO just for testing
filename = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation) + "/welle-io-record.iq";
std::string filename_tmp = filename.toStdString();
device->writeRecordBufferToFile(filename_tmp);
}

DABParams& CRadioController::getDABParams()
Expand Down
2 changes: 2 additions & 0 deletions src/welle-gui/radio_controller.h
Expand Up @@ -122,6 +122,8 @@ class CRadioController :
Q_INVOKABLE void enableOldFFTWindowPlacement(bool old);
Q_INVOKABLE void setFreqSyncMethod(int fsm_ix);
Q_INVOKABLE void setGain(int gain);
Q_INVOKABLE void initRecorder(int size);
Q_INVOKABLE void triggerRecorder(QString filename);
DABParams& getDABParams(void);
int getCurrentFrequency();

Expand Down
1 change: 1 addition & 0 deletions src/welle-gui/resources.qrc
Expand Up @@ -92,6 +92,7 @@
<file>QML/expertviews/NullSymbolGraph.qml</file>
<file>QML/expertviews/SpectrumGraph.qml</file>
<file>QML/expertviews/TextOutputView.qml</file>
<file>QML/expertviews/RawRecorder.qml</file>
<file>QML/components/ViewBaseFrame.qml</file>
<file>QML/MotView.qml</file>
<file>QML/GeneralView.qml</file>
Expand Down
1 change: 1 addition & 0 deletions src/welle-gui/welle-gui.pro
Expand Up @@ -46,6 +46,7 @@ DISTFILES += \
QML/expertviews/NullSymbolGraph.qml \
QML/expertviews/SpectrumGraph.qml \
QML/expertviews/TextOutputView.qml \
QML/expertviews/RawRecorder.qml \
QML/components/StationListModel.qml \
QML/MotView.qml \
QML/components/ViewBaseFrame.qml \
Expand Down

0 comments on commit 10a6bdd

Please sign in to comment.