1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2025-09-04 22:27:53 -04:00

Remote input buffer size rework: member name changes. Adjust sample sink fifo size from sample rate

This commit is contained in:
f4exb 2020-06-28 06:56:21 +02:00
parent b7284b6b5c
commit 16364d604a
6 changed files with 76 additions and 28 deletions

View File

@ -48,13 +48,16 @@ MESSAGE_CLASS_DEFINITION(RemoteInput::MsgStartStop, Message)
RemoteInput::RemoteInput(DeviceAPI *deviceAPI) : RemoteInput::RemoteInput(DeviceAPI *deviceAPI) :
m_deviceAPI(deviceAPI), m_deviceAPI(deviceAPI),
m_sampleRate(48000),
m_fileSink(nullptr),
m_settings(), m_settings(),
m_remoteInputUDPHandler(0), m_remoteInputUDPHandler(0),
m_deviceDescription(), m_deviceDescription(),
m_startingTimeStamp(0) m_startingTimeStamp(0)
{ {
m_sampleFifo.setSize(96000 * 4); m_sampleFifo.setSize(m_sampleRate * 8);
m_remoteInputUDPHandler = new RemoteInputUDPHandler(&m_sampleFifo, m_deviceAPI); m_remoteInputUDPHandler = new RemoteInputUDPHandler(&m_sampleFifo, m_deviceAPI);
m_remoteInputUDPHandler->setMessageQueueToInput(&m_inputMessageQueue);
m_fileSink = new FileRecord(QString("test_%1.sdriq").arg(m_deviceAPI->getDeviceUID())); m_fileSink = new FileRecord(QString("test_%1.sdriq").arg(m_deviceAPI->getDeviceUID()));
m_deviceAPI->setNbSourceStreams(1); m_deviceAPI->setNbSourceStreams(1);
@ -167,6 +170,21 @@ bool RemoteInput::handleMessage(const Message& message)
DSPSignalNotification& notif = (DSPSignalNotification&) message; DSPSignalNotification& notif = (DSPSignalNotification&) message;
return m_fileSink->handleMessage(notif); // forward to file sink return m_fileSink->handleMessage(notif); // forward to file sink
} }
else if (RemoteInputUDPHandler::MsgReportSampleRateChange::match(message))
{
RemoteInputUDPHandler::MsgReportSampleRateChange& notif = (RemoteInputUDPHandler::MsgReportSampleRateChange&) message;
int sampleRate = notif.getSampleRate();
if (sampleRate != m_sampleRate)
{
qDebug("RemoteInput::handleMessage: RemoteInputUDPHandler::MsgReportSampleRateChange: %d", sampleRate);
QMutexLocker mutexLocker(&m_mutex);
m_sampleFifo.setSize(sampleRate * 8);
m_sampleRate = sampleRate;
}
return true;
}
else if (MsgFileRecord::match(message)) else if (MsgFileRecord::match(message))
{ {
MsgFileRecord& conf = (MsgFileRecord&) message; MsgFileRecord& conf = (MsgFileRecord&) message;

View File

@ -329,6 +329,7 @@ public:
private: private:
DeviceAPI *m_deviceAPI; DeviceAPI *m_deviceAPI;
int m_sampleRate;
QMutex m_mutex; QMutex m_mutex;
RemoteInputSettings m_settings; RemoteInputSettings m_settings;
RemoteInputUDPHandler* m_remoteInputUDPHandler; RemoteInputUDPHandler* m_remoteInputUDPHandler;

View File

@ -27,7 +27,7 @@
RemoteInputBuffer::RemoteInputBuffer() : RemoteInputBuffer::RemoteInputBuffer() :
m_decoderIndexHead(nbDecoderSlots/2), m_decoderIndexHead(m_nbDecoderSlots/2),
m_frameHead(0), m_frameHead(0),
m_curNbBlocks(0), m_curNbBlocks(0),
m_minNbBlocks(256), m_minNbBlocks(256),
@ -46,7 +46,7 @@ RemoteInputBuffer::RemoteInputBuffer() :
m_balCorrLimit(0) m_balCorrLimit(0)
{ {
m_currentMeta.init(); m_currentMeta.init();
m_framesNbBytes = nbDecoderSlots * sizeof(BufferFrame); m_framesNbBytes = m_nbDecoderSlots * sizeof(BufferFrame);
m_wrDeltaEstimate = m_framesNbBytes / 2; m_wrDeltaEstimate = m_framesNbBytes / 2;
m_tvOut_sec = 0; m_tvOut_sec = 0;
m_tvOut_usec = 0; m_tvOut_usec = 0;
@ -61,8 +61,8 @@ RemoteInputBuffer::RemoteInputBuffer() :
m_cm256_OK = true; m_cm256_OK = true;
} }
std::fill(m_decoderSlots, m_decoderSlots + nbDecoderSlots, DecoderSlot()); std::fill(m_decoderSlots, m_decoderSlots + m_nbDecoderSlots, DecoderSlot());
std::fill(m_frames, m_frames + nbDecoderSlots, BufferFrame()); std::fill(m_frames, m_frames + m_nbDecoderSlots, BufferFrame());
} }
RemoteInputBuffer::~RemoteInputBuffer() RemoteInputBuffer::~RemoteInputBuffer()
@ -74,7 +74,7 @@ RemoteInputBuffer::~RemoteInputBuffer()
void RemoteInputBuffer::initDecodeAllSlots() void RemoteInputBuffer::initDecodeAllSlots()
{ {
for (int i = 0; i < nbDecoderSlots; i++) for (int i = 0; i < m_nbDecoderSlots; i++)
{ {
m_decoderSlots[i].m_blockCount = 0; m_decoderSlots[i].m_blockCount = 0;
m_decoderSlots[i].m_originalCount = 0; m_decoderSlots[i].m_originalCount = 0;
@ -124,7 +124,7 @@ void RemoteInputBuffer::initDecodeSlot(int slotIndex)
void RemoteInputBuffer::initReadIndex() void RemoteInputBuffer::initReadIndex()
{ {
m_readIndex = ((m_decoderIndexHead + (nbDecoderSlots/2)) % nbDecoderSlots) * sizeof(BufferFrame); m_readIndex = ((m_decoderIndexHead + (m_nbDecoderSlots/2)) % m_nbDecoderSlots) * sizeof(BufferFrame);
m_wrDeltaEstimate = m_framesNbBytes / 2; m_wrDeltaEstimate = m_framesNbBytes / 2;
m_nbReads = 0; m_nbReads = 0;
m_nbWrites = 0; m_nbWrites = 0;
@ -134,20 +134,20 @@ void RemoteInputBuffer::rwCorrectionEstimate(int slotIndex)
{ {
if (m_nbReads >= 40) // check every ~1s as tick is ~50ms if (m_nbReads >= 40) // check every ~1s as tick is ~50ms
{ {
int targetPivotSlot = (slotIndex + (nbDecoderSlots/2)) % nbDecoderSlots; // slot at half buffer opposite of current write slot int targetPivotSlot = (slotIndex + (m_nbDecoderSlots/2)) % m_nbDecoderSlots; // slot at half buffer opposite of current write slot
int targetPivotIndex = targetPivotSlot * sizeof(BufferFrame); // buffer index corresponding to start of above slot int targetPivotIndex = targetPivotSlot * sizeof(BufferFrame); // buffer index corresponding to start of above slot
int normalizedReadIndex = (m_readIndex < targetPivotIndex ? m_readIndex + nbDecoderSlots * sizeof(BufferFrame) : m_readIndex) int normalizedReadIndex = (m_readIndex < targetPivotIndex ? m_readIndex + m_nbDecoderSlots * sizeof(BufferFrame) : m_readIndex)
- (targetPivotSlot * sizeof(BufferFrame)); // normalize read index so it is positive and zero at start of pivot slot - (targetPivotSlot * sizeof(BufferFrame)); // normalize read index so it is positive and zero at start of pivot slot
int dBytes; int dBytes;
int rwDelta = (m_nbReads * m_readNbBytes) - (m_nbWrites * sizeof(BufferFrame)); int rwDelta = (m_nbReads * m_readNbBytes) - (m_nbWrites * sizeof(BufferFrame));
if (normalizedReadIndex < (nbDecoderSlots/ 2) * (int) sizeof(BufferFrame)) // read leads if (normalizedReadIndex < (m_nbDecoderSlots/ 2) * (int) sizeof(BufferFrame)) // read leads
{ {
dBytes = - normalizedReadIndex - rwDelta; dBytes = - normalizedReadIndex - rwDelta;
} }
else // read lags else // read lags
{ {
int bufSize = (nbDecoderSlots * sizeof(BufferFrame)); int bufSize = (m_nbDecoderSlots * sizeof(BufferFrame));
dBytes = bufSize - normalizedReadIndex - rwDelta; dBytes = bufSize - normalizedReadIndex - rwDelta;
} }
@ -171,7 +171,7 @@ void RemoteInputBuffer::checkSlotData(int slotIndex)
{ {
int pseudoWriteIndex = slotIndex * sizeof(BufferFrame); int pseudoWriteIndex = slotIndex * sizeof(BufferFrame);
m_wrDeltaEstimate = pseudoWriteIndex - m_readIndex; m_wrDeltaEstimate = pseudoWriteIndex - m_readIndex;
int rwDelayBytes = (m_wrDeltaEstimate > 0 ? m_wrDeltaEstimate : sizeof(BufferFrame) * nbDecoderSlots + m_wrDeltaEstimate); int rwDelayBytes = (m_wrDeltaEstimate > 0 ? m_wrDeltaEstimate : sizeof(BufferFrame) * m_nbDecoderSlots + m_wrDeltaEstimate);
int sampleRate = m_currentMeta.m_sampleRate; int sampleRate = m_currentMeta.m_sampleRate;
if (sampleRate > 0) if (sampleRate > 0)
@ -195,7 +195,7 @@ void RemoteInputBuffer::writeData(char *array)
{ {
RemoteSuperBlock *superBlock = (RemoteSuperBlock *) array; RemoteSuperBlock *superBlock = (RemoteSuperBlock *) array;
int frameIndex = superBlock->m_header.m_frameIndex; int frameIndex = superBlock->m_header.m_frameIndex;
int decoderIndex = frameIndex % nbDecoderSlots; int decoderIndex = frameIndex % m_nbDecoderSlots;
// frame break // frame break
@ -338,8 +338,8 @@ uint8_t *RemoteInputBuffer::readData(int32_t length)
m_nbReads++; m_nbReads++;
// SEGFAULT FIX: arbitratily truncate so that it does not exceed buffer length // SEGFAULT FIX: arbitratily truncate so that it does not exceed buffer length
if (length > framesSize) { if (length > m_framesSize) {
length = framesSize; length = m_framesSize;
} }
if (m_readIndex + length < m_framesNbBytes) // ends before buffer bound if (m_readIndex + length < m_framesNbBytes) // ends before buffer bound

View File

@ -106,10 +106,9 @@ public:
} }
} }
static const int framesSize = REMOTEINPUT_NBDECODERSLOTS * (RemoteNbOrginalBlocks - 1) * RemoteNbBytesPerBlock;
private: private:
static const int nbDecoderSlots = REMOTEINPUT_NBDECODERSLOTS; static const int m_framesSize = REMOTEINPUT_NBDECODERSLOTS * (RemoteNbOrginalBlocks - 1) * RemoteNbBytesPerBlock;
static const int m_nbDecoderSlots = REMOTEINPUT_NBDECODERSLOTS;
#pragma pack(push, 1) #pragma pack(push, 1)
struct BufferFrame struct BufferFrame
@ -133,8 +132,8 @@ private:
RemoteMetaDataFEC m_currentMeta; //!< Stored current meta data RemoteMetaDataFEC m_currentMeta; //!< Stored current meta data
CM256::cm256_encoder_params m_paramsCM256; //!< CM256 decoder parameters block CM256::cm256_encoder_params m_paramsCM256; //!< CM256 decoder parameters block
DecoderSlot m_decoderSlots[nbDecoderSlots]; //!< CM256 decoding control/buffer slots DecoderSlot m_decoderSlots[m_nbDecoderSlots]; //!< CM256 decoding control/buffer slots
BufferFrame m_frames[nbDecoderSlots]; //!< Samples buffer BufferFrame m_frames[m_nbDecoderSlots]; //!< Samples buffer
int m_framesNbBytes; //!< Number of bytes in samples buffer int m_framesNbBytes; //!< Number of bytes in samples buffer
int m_decoderIndexHead; //!< index of the current head frame slot in decoding slots int m_decoderIndexHead; //!< index of the current head frame slot in decoding slots
int m_frameHead; //!< index of the current head frame sent int m_frameHead; //!< index of the current head frame sent

View File

@ -26,6 +26,8 @@
#include "remoteinputudphandler.h" #include "remoteinputudphandler.h"
#include "remoteinput.h" #include "remoteinput.h"
MESSAGE_CLASS_DEFINITION(RemoteInputUDPHandler::MsgReportSampleRateChange, Message)
RemoteInputUDPHandler::RemoteInputUDPHandler(SampleSinkFifo *sampleFifo, DeviceAPI *deviceAPI) : RemoteInputUDPHandler::RemoteInputUDPHandler(SampleSinkFifo *sampleFifo, DeviceAPI *deviceAPI) :
m_deviceAPI(deviceAPI), m_deviceAPI(deviceAPI),
m_masterTimer(deviceAPI->getMasterTimer()), m_masterTimer(deviceAPI->getMasterTimer()),
@ -43,7 +45,7 @@ RemoteInputUDPHandler::RemoteInputUDPHandler(SampleSinkFifo *sampleFifo, DeviceA
m_samplerate(0), m_samplerate(0),
m_centerFrequency(0), m_centerFrequency(0),
m_tv_msec(0), m_tv_msec(0),
m_outputMessageQueueToGUI(0), m_messageQueueToGUI(0),
m_tickCount(0), m_tickCount(0),
m_samplesCount(0), m_samplesCount(0),
m_timer(0), m_timer(0),
@ -189,6 +191,12 @@ void RemoteInputUDPHandler::processData()
if (m_samplerate != metaData.m_sampleRate) if (m_samplerate != metaData.m_sampleRate)
{ {
if (m_messageQueueToInput)
{
MsgReportSampleRateChange *msg = MsgReportSampleRateChange::create(metaData.m_sampleRate);
m_messageQueueToInput->push(msg);
}
m_samplerate = metaData.m_sampleRate; m_samplerate = metaData.m_sampleRate;
change = true; change = true;
} }
@ -200,14 +208,14 @@ void RemoteInputUDPHandler::processData()
DSPSignalNotification *notif = new DSPSignalNotification(m_samplerate, m_centerFrequency); // Frequency in Hz for the DSP engine DSPSignalNotification *notif = new DSPSignalNotification(m_samplerate, m_centerFrequency); // Frequency in Hz for the DSP engine
m_deviceAPI->getDeviceEngineInputMessageQueue()->push(notif); m_deviceAPI->getDeviceEngineInputMessageQueue()->push(notif);
if (m_outputMessageQueueToGUI) if (m_messageQueueToGUI)
{ {
RemoteInput::MsgReportRemoteInputStreamData *report = RemoteInput::MsgReportRemoteInputStreamData::create( RemoteInput::MsgReportRemoteInputStreamData *report = RemoteInput::MsgReportRemoteInputStreamData::create(
m_samplerate, m_samplerate,
m_centerFrequency, // Frequency in Hz for the GUI m_centerFrequency, // Frequency in Hz for the GUI
m_tv_msec); m_tv_msec);
m_outputMessageQueueToGUI->push(report); m_messageQueueToGUI->push(report);
} }
connectTimer(); connectTimer();
@ -326,7 +334,7 @@ void RemoteInputUDPHandler::tick()
{ {
m_tickCount = 0; m_tickCount = 0;
if (m_outputMessageQueueToGUI) if (m_messageQueueToGUI)
{ {
int framesDecodingStatus; int framesDecodingStatus;
int minNbBlocks = m_remoteInputBuffer.getMinNbBlocks(); int minNbBlocks = m_remoteInputBuffer.getMinNbBlocks();
@ -362,7 +370,7 @@ void RemoteInputUDPHandler::tick()
sampleBits, sampleBits,
sampleBytes); sampleBytes);
m_outputMessageQueueToGUI->push(report); m_messageQueueToGUI->push(report);
} }
} }
} }

View File

@ -37,10 +37,31 @@ class RemoteInputUDPHandler : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
class MsgReportSampleRateChange : public Message {
MESSAGE_CLASS_DECLARATION
public:
int getSampleRate() const { return m_sampleRate; }
static MsgReportSampleRateChange* create(int sampleRate)
{
return new MsgReportSampleRateChange(sampleRate);
}
protected:
int m_sampleRate;
MsgReportSampleRateChange(int sampleRate) :
Message(),
m_sampleRate(sampleRate)
{ }
};
RemoteInputUDPHandler(SampleSinkFifo* sampleFifo, DeviceAPI *deviceAPI); RemoteInputUDPHandler(SampleSinkFifo* sampleFifo, DeviceAPI *deviceAPI);
~RemoteInputUDPHandler(); ~RemoteInputUDPHandler();
void setMessageQueueToGUI(MessageQueue *queue) { m_outputMessageQueueToGUI = queue; } void setMessageQueueToInput(MessageQueue *queue) { m_messageQueueToInput = queue; }
void start(); void setMessageQueueToGUI(MessageQueue *queue) { m_messageQueueToGUI = queue; }
void start();
void stop(); void stop();
void configureUDPLink(const QString& address, quint16 port); void configureUDPLink(const QString& address, quint16 port);
void getRemoteAddress(QString& s) const { s = m_remoteAddress.toString(); } void getRemoteAddress(QString& s) const { s = m_remoteAddress.toString(); }
@ -73,7 +94,8 @@ private:
uint32_t m_samplerate; uint32_t m_samplerate;
uint64_t m_centerFrequency; uint64_t m_centerFrequency;
uint64_t m_tv_msec; uint64_t m_tv_msec;
MessageQueue *m_outputMessageQueueToGUI; MessageQueue *m_messageQueueToInput;
MessageQueue *m_messageQueueToGUI;
uint32_t m_tickCount; uint32_t m_tickCount;
std::size_t m_samplesCount; std::size_t m_samplesCount;
QTimer *m_timer; QTimer *m_timer;