diff --git a/plugins/samplesource/remoteinput/remoteinput.cpp b/plugins/samplesource/remoteinput/remoteinput.cpp index 8f6c26a61..b41ea132e 100644 --- a/plugins/samplesource/remoteinput/remoteinput.cpp +++ b/plugins/samplesource/remoteinput/remoteinput.cpp @@ -48,14 +48,16 @@ MESSAGE_CLASS_DEFINITION(RemoteInput::MsgStartStop, Message) RemoteInput::RemoteInput(DeviceAPI *deviceAPI) : m_deviceAPI(deviceAPI), + m_sampleRate(48000), m_fileSink(nullptr), m_settings(), m_remoteInputUDPHandler(0), m_deviceDescription(), m_startingTimeStamp(0) { - m_sampleFifo.setSize(96000 * 4); + m_sampleFifo.setSize(m_sampleRate * 8); m_remoteInputUDPHandler = new RemoteInputUDPHandler(&m_sampleFifo, m_deviceAPI); + m_remoteInputUDPHandler->setMessageQueueToInput(&m_inputMessageQueue); m_deviceAPI->setNbSourceStreams(1); @@ -176,6 +178,21 @@ bool RemoteInput::handleMessage(const Message& message) return false; } } + 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)) { MsgFileRecord& conf = (MsgFileRecord&) message; diff --git a/plugins/samplesource/remoteinput/remoteinput.h b/plugins/samplesource/remoteinput/remoteinput.h index 17860349a..88fe748e1 100644 --- a/plugins/samplesource/remoteinput/remoteinput.h +++ b/plugins/samplesource/remoteinput/remoteinput.h @@ -329,6 +329,7 @@ public: private: DeviceAPI *m_deviceAPI; + int m_sampleRate; QMutex m_mutex; RemoteInputSettings m_settings; RemoteInputUDPHandler* m_remoteInputUDPHandler; diff --git a/plugins/samplesource/remoteinput/remoteinputbuffer.cpp b/plugins/samplesource/remoteinput/remoteinputbuffer.cpp index fb9a15a77..d5b3b2e58 100644 --- a/plugins/samplesource/remoteinput/remoteinputbuffer.cpp +++ b/plugins/samplesource/remoteinput/remoteinputbuffer.cpp @@ -27,7 +27,7 @@ RemoteInputBuffer::RemoteInputBuffer() : - m_decoderIndexHead(nbDecoderSlots/2), + m_decoderIndexHead(m_nbDecoderSlots/2), m_frameHead(0), m_curNbBlocks(0), m_minNbBlocks(256), @@ -46,7 +46,7 @@ RemoteInputBuffer::RemoteInputBuffer() : m_balCorrLimit(0) { m_currentMeta.init(); - m_framesNbBytes = nbDecoderSlots * sizeof(BufferFrame); + m_framesNbBytes = m_nbDecoderSlots * sizeof(BufferFrame); m_wrDeltaEstimate = m_framesNbBytes / 2; m_tvOut_sec = 0; m_tvOut_usec = 0; @@ -61,8 +61,8 @@ RemoteInputBuffer::RemoteInputBuffer() : m_cm256_OK = true; } - std::fill(m_decoderSlots, m_decoderSlots + nbDecoderSlots, DecoderSlot()); - std::fill(m_frames, m_frames + nbDecoderSlots, BufferFrame()); + std::fill(m_decoderSlots, m_decoderSlots + m_nbDecoderSlots, DecoderSlot()); + std::fill(m_frames, m_frames + m_nbDecoderSlots, BufferFrame()); } RemoteInputBuffer::~RemoteInputBuffer() @@ -74,7 +74,7 @@ RemoteInputBuffer::~RemoteInputBuffer() 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_originalCount = 0; @@ -124,7 +124,7 @@ void RemoteInputBuffer::initDecodeSlot(int slotIndex) 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_nbReads = 0; m_nbWrites = 0; @@ -134,20 +134,20 @@ void RemoteInputBuffer::rwCorrectionEstimate(int slotIndex) { 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 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 int dBytes; 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; } else // read lags { - int bufSize = (nbDecoderSlots * sizeof(BufferFrame)); + int bufSize = (m_nbDecoderSlots * sizeof(BufferFrame)); dBytes = bufSize - normalizedReadIndex - rwDelta; } @@ -171,7 +171,7 @@ void RemoteInputBuffer::checkSlotData(int slotIndex) { int pseudoWriteIndex = slotIndex * sizeof(BufferFrame); 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; if (sampleRate > 0) @@ -195,7 +195,7 @@ void RemoteInputBuffer::writeData(char *array) { RemoteSuperBlock *superBlock = (RemoteSuperBlock *) array; int frameIndex = superBlock->m_header.m_frameIndex; - int decoderIndex = frameIndex % nbDecoderSlots; + int decoderIndex = frameIndex % m_nbDecoderSlots; // frame break @@ -338,8 +338,8 @@ uint8_t *RemoteInputBuffer::readData(int32_t length) m_nbReads++; // SEGFAULT FIX: arbitratily truncate so that it does not exceed buffer length - if (length > framesSize) { - length = framesSize; + if (length > m_framesSize) { + length = m_framesSize; } if (m_readIndex + length < m_framesNbBytes) // ends before buffer bound diff --git a/plugins/samplesource/remoteinput/remoteinputbuffer.h b/plugins/samplesource/remoteinput/remoteinputbuffer.h index e4bb9c1d2..7fb150769 100644 --- a/plugins/samplesource/remoteinput/remoteinputbuffer.h +++ b/plugins/samplesource/remoteinput/remoteinputbuffer.h @@ -106,10 +106,9 @@ public: } } - static const int framesSize = REMOTEINPUT_NBDECODERSLOTS * (RemoteNbOrginalBlocks - 1) * RemoteNbBytesPerBlock; - 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) struct BufferFrame @@ -133,8 +132,8 @@ private: RemoteMetaDataFEC m_currentMeta; //!< Stored current meta data CM256::cm256_encoder_params m_paramsCM256; //!< CM256 decoder parameters block - DecoderSlot m_decoderSlots[nbDecoderSlots]; //!< CM256 decoding control/buffer slots - BufferFrame m_frames[nbDecoderSlots]; //!< Samples buffer + DecoderSlot m_decoderSlots[m_nbDecoderSlots]; //!< CM256 decoding control/buffer slots + BufferFrame m_frames[m_nbDecoderSlots]; //!< 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_frameHead; //!< index of the current head frame sent diff --git a/plugins/samplesource/remoteinput/remoteinputudphandler.cpp b/plugins/samplesource/remoteinput/remoteinputudphandler.cpp index 2d827c668..f62fe2c29 100644 --- a/plugins/samplesource/remoteinput/remoteinputudphandler.cpp +++ b/plugins/samplesource/remoteinput/remoteinputudphandler.cpp @@ -26,6 +26,8 @@ #include "remoteinputudphandler.h" #include "remoteinput.h" +MESSAGE_CLASS_DEFINITION(RemoteInputUDPHandler::MsgReportSampleRateChange, Message) + RemoteInputUDPHandler::RemoteInputUDPHandler(SampleSinkFifo *sampleFifo, DeviceAPI *deviceAPI) : m_deviceAPI(deviceAPI), m_masterTimer(deviceAPI->getMasterTimer()), @@ -43,7 +45,7 @@ RemoteInputUDPHandler::RemoteInputUDPHandler(SampleSinkFifo *sampleFifo, DeviceA m_samplerate(0), m_centerFrequency(0), m_tv_msec(0), - m_outputMessageQueueToGUI(0), + m_messageQueueToGUI(0), m_tickCount(0), m_samplesCount(0), m_timer(0), @@ -189,6 +191,12 @@ void RemoteInputUDPHandler::processData() 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; change = true; } @@ -200,14 +208,14 @@ void RemoteInputUDPHandler::processData() DSPSignalNotification *notif = new DSPSignalNotification(m_samplerate, m_centerFrequency); // Frequency in Hz for the DSP engine m_deviceAPI->getDeviceEngineInputMessageQueue()->push(notif); - if (m_outputMessageQueueToGUI) + if (m_messageQueueToGUI) { RemoteInput::MsgReportRemoteInputStreamData *report = RemoteInput::MsgReportRemoteInputStreamData::create( m_samplerate, m_centerFrequency, // Frequency in Hz for the GUI m_tv_msec); - m_outputMessageQueueToGUI->push(report); + m_messageQueueToGUI->push(report); } connectTimer(); @@ -326,7 +334,7 @@ void RemoteInputUDPHandler::tick() { m_tickCount = 0; - if (m_outputMessageQueueToGUI) + if (m_messageQueueToGUI) { int framesDecodingStatus; int minNbBlocks = m_remoteInputBuffer.getMinNbBlocks(); @@ -362,7 +370,7 @@ void RemoteInputUDPHandler::tick() sampleBits, sampleBytes); - m_outputMessageQueueToGUI->push(report); + m_messageQueueToGUI->push(report); } } } diff --git a/plugins/samplesource/remoteinput/remoteinputudphandler.h b/plugins/samplesource/remoteinput/remoteinputudphandler.h index a8c757daa..dafbcbc6c 100644 --- a/plugins/samplesource/remoteinput/remoteinputudphandler.h +++ b/plugins/samplesource/remoteinput/remoteinputudphandler.h @@ -37,10 +37,31 @@ class RemoteInputUDPHandler : public QObject { Q_OBJECT 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(); - void setMessageQueueToGUI(MessageQueue *queue) { m_outputMessageQueueToGUI = queue; } - void start(); + void setMessageQueueToInput(MessageQueue *queue) { m_messageQueueToInput = queue; } + void setMessageQueueToGUI(MessageQueue *queue) { m_messageQueueToGUI = queue; } + void start(); void stop(); void configureUDPLink(const QString& address, quint16 port); void getRemoteAddress(QString& s) const { s = m_remoteAddress.toString(); } @@ -73,7 +94,8 @@ private: uint32_t m_samplerate; uint64_t m_centerFrequency; uint64_t m_tv_msec; - MessageQueue *m_outputMessageQueueToGUI; + MessageQueue *m_messageQueueToInput; + MessageQueue *m_messageQueueToGUI; uint32_t m_tickCount; std::size_t m_samplesCount; QTimer *m_timer;