mirror of
				https://github.com/f4exb/sdrangel.git
				synced 2025-10-30 20:40:20 -04:00 
			
		
		
		
	LimeSDR output: regulate Tx output
This commit is contained in:
		
							parent
							
								
									e0b7027756
								
							
						
					
					
						commit
						d1e16b6ab0
					
				| @ -52,6 +52,7 @@ public: | |||||||
|     public: |     public: | ||||||
|         virtual void startWork() = 0; |         virtual void startWork() = 0; | ||||||
|         virtual void stopWork() = 0; |         virtual void stopWork() = 0; | ||||||
|  |         virtual void setDeviceSampleRate(int sampleRate) = 0; | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     DeviceLimeSDRParams *m_deviceParams; //!< unique hardware device parameters
 |     DeviceLimeSDRParams *m_deviceParams; //!< unique hardware device parameters
 | ||||||
|  | |||||||
| @ -164,8 +164,8 @@ bool LimeSDROutput::openDevice() | |||||||
|     // set up the stream
 |     // set up the stream
 | ||||||
| 
 | 
 | ||||||
|     m_streamId.channel =  m_deviceShared.m_channel; // channel number
 |     m_streamId.channel =  m_deviceShared.m_channel; // channel number
 | ||||||
|     m_streamId.fifoSize = 1024 * 128;               // fifo size in samples
 |     m_streamId.fifoSize = 5000000;                  // fifo size in samples
 | ||||||
|     m_streamId.throughputVsLatency = 1.0;           // optimize for max throughput
 |     m_streamId.throughputVsLatency = 0.0;           // optimize for max throughput
 | ||||||
|     m_streamId.isTx = true;                         // TX channel
 |     m_streamId.isTx = true;                         // TX channel
 | ||||||
|     m_streamId.dataFmt = lms_stream_t::LMS_FMT_I12; // 12-bit integers
 |     m_streamId.dataFmt = lms_stream_t::LMS_FMT_I12; // 12-bit integers
 | ||||||
| 
 | 
 | ||||||
| @ -576,6 +576,23 @@ bool LimeSDROutput::applySettings(const LimeSDROutputSettings& settings, bool fo | |||||||
|                         m_settings.m_devSampleRate, |                         m_settings.m_devSampleRate, | ||||||
|                         1<<m_settings.m_log2HardInterp); |                         1<<m_settings.m_log2HardInterp); | ||||||
|             } |             } | ||||||
|  | 
 | ||||||
|  |             if (m_limeSDROutputThread != 0) | ||||||
|  |             { | ||||||
|  |                 m_limeSDROutputThread->setDeviceSampleRate(m_settings.m_devSampleRate); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             const std::vector<DeviceSinkAPI*>& sinkBuddies = m_deviceAPI->getSinkBuddies(); | ||||||
|  |             std::vector<DeviceSinkAPI*>::const_iterator itSink = sinkBuddies.begin(); | ||||||
|  | 
 | ||||||
|  |             for (; itSink != sinkBuddies.end(); ++itSink) | ||||||
|  |             { | ||||||
|  |                 DeviceLimeSDRShared *buddySharedPtr = (DeviceLimeSDRShared *) (*itSink)->getBuddySharedPtr(); | ||||||
|  | 
 | ||||||
|  |                 if (buddySharedPtr->m_thread) { | ||||||
|  |                     buddySharedPtr->m_thread->setDeviceSampleRate(m_settings.m_devSampleRate); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -703,11 +720,11 @@ bool LimeSDROutput::applySettings(const LimeSDROutputSettings& settings, bool fo | |||||||
|                 m_settings.m_lpfBW, |                 m_settings.m_lpfBW, | ||||||
|                 0) < 0) |                 0) < 0) | ||||||
|         { |         { | ||||||
|             qCritical("LimeSDROutput::applySettings: calibration failed on Rx channel %lu", m_deviceShared.m_channel); |             qCritical("LimeSDROutput::applySettings: calibration failed on Tx channel %lu", m_deviceShared.m_channel); | ||||||
|         } |         } | ||||||
|         else |         else | ||||||
|         { |         { | ||||||
|             qDebug("LimeSDROutput::applySettings: calibration successful on Rx channel %lu", m_deviceShared.m_channel); |             qDebug("LimeSDROutput::applySettings: calibration successful on Tx channel %lu", m_deviceShared.m_channel); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -225,7 +225,7 @@ void LimeSDROutputGUI::handleMessagesToGUI() | |||||||
| 
 | 
 | ||||||
|                 ui->fifoBar->setMaximum(report->getFifoSize()); |                 ui->fifoBar->setMaximum(report->getFifoSize()); | ||||||
|                 ui->fifoBar->setValue(report->getFifoFilledCount()); |                 ui->fifoBar->setValue(report->getFifoFilledCount()); | ||||||
|                 ui->fifoBar->setToolTip(tr("FIFO fill %1/%2 bytes").arg(QString::number(report->getFifoFilledCount())).arg(QString::number(report->getFifoSize()))); |                 ui->fifoBar->setToolTip(tr("FIFO fill %1/%2 samples").arg(QString::number(report->getFifoFilledCount())).arg(QString::number(report->getFifoSize()))); | ||||||
|             } |             } | ||||||
|             else |             else | ||||||
|             { |             { | ||||||
| @ -382,7 +382,7 @@ void LimeSDROutputGUI::on_sampleRate_changed(quint64 value) | |||||||
|     setNCODisplay(); |     setNCODisplay(); | ||||||
|     sendSettings();} |     sendSettings();} | ||||||
| 
 | 
 | ||||||
| void LimeSDROutputGUI::on_hwDecim_currentIndexChanged(int index) | void LimeSDROutputGUI::on_hwInterp_currentIndexChanged(int index) | ||||||
| { | { | ||||||
|     if ((index <0) || (index > 5)) |     if ((index <0) || (index > 5)) | ||||||
|         return; |         return; | ||||||
| @ -391,7 +391,7 @@ void LimeSDROutputGUI::on_hwDecim_currentIndexChanged(int index) | |||||||
|     sendSettings(); |     sendSettings(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void LimeSDROutputGUI::on_swDecim_currentIndexChanged(int index) | void LimeSDROutputGUI::on_swInterp_currentIndexChanged(int index) | ||||||
| { | { | ||||||
|     if ((index <0) || (index > 5)) |     if ((index <0) || (index > 5)) | ||||||
|         return; |         return; | ||||||
|  | |||||||
| @ -79,8 +79,8 @@ private slots: | |||||||
|     void on_ncoEnable_toggled(bool checked); |     void on_ncoEnable_toggled(bool checked); | ||||||
|     void on_ncoReset_clicked(bool checked); |     void on_ncoReset_clicked(bool checked); | ||||||
|     void on_sampleRate_changed(quint64 value); |     void on_sampleRate_changed(quint64 value); | ||||||
|     void on_hwDecim_currentIndexChanged(int index); |     void on_hwInterp_currentIndexChanged(int index); | ||||||
|     void on_swDecim_currentIndexChanged(int index); |     void on_swInterp_currentIndexChanged(int index); | ||||||
|     void on_lpf_changed(quint64 value); |     void on_lpf_changed(quint64 value); | ||||||
|     void on_lpFIREnable_toggled(bool checked); |     void on_lpFIREnable_toggled(bool checked); | ||||||
|     void on_lpFIR_changed(quint64 value); |     void on_lpFIR_changed(quint64 value); | ||||||
|  | |||||||
| @ -24,6 +24,7 @@ LimeSDROutputThread::LimeSDROutputThread(lms_stream_t* stream, SampleSourceFifo* | |||||||
|     m_running(false), |     m_running(false), | ||||||
|     m_stream(stream), |     m_stream(stream), | ||||||
|     m_sampleFifo(sampleFifo), |     m_sampleFifo(sampleFifo), | ||||||
|  |     m_sampleRate(5000000), | ||||||
|     m_log2Interp(0), |     m_log2Interp(0), | ||||||
|     m_fcPos(LimeSDROutputSettings::FC_POS_CENTER) |     m_fcPos(LimeSDROutputSettings::FC_POS_CENTER) | ||||||
| { | { | ||||||
| @ -66,7 +67,8 @@ void LimeSDROutputThread::setFcPos(int fcPos) | |||||||
| 
 | 
 | ||||||
| void LimeSDROutputThread::run() | void LimeSDROutputThread::run() | ||||||
| { | { | ||||||
|     int res; |     int res, count, msleep, mdelta; | ||||||
|  |     lms_stream_status_t streamStatus; | ||||||
| 
 | 
 | ||||||
|     lms_stream_meta_t metadata;          //Use metadata for additional control over sample receive function behaviour
 |     lms_stream_meta_t metadata;          //Use metadata for additional control over sample receive function behaviour
 | ||||||
|     metadata.flushPartialPacket = false; //Do not discard data remainder when read size differs from packet size
 |     metadata.flushPartialPacket = false; //Do not discard data remainder when read size differs from packet size
 | ||||||
| @ -81,15 +83,46 @@ void LimeSDROutputThread::run() | |||||||
|         qDebug("LimeSDROutputThread::run: stream started"); |         qDebug("LimeSDROutputThread::run: stream started"); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     count = 0; | ||||||
|  |     msleep = LIMESDROUTPUT_BLOCKSIZE/(m_sampleRate/1e6f); | ||||||
|  |     mdelta = msleep/100; | ||||||
|  |     msleep = (3*msleep)/4; // to start faster
 | ||||||
|  | 
 | ||||||
|     while (m_running) |     while (m_running) | ||||||
|     { |     { | ||||||
|         callback(m_buf, LIMESDROUTPUT_BLOCKSIZE); |         callback(m_buf, LIMESDROUTPUT_BLOCKSIZE); | ||||||
| 
 | 
 | ||||||
|         if ((res = LMS_SendStream(m_stream, (void *) m_buf, LIMESDROUTPUT_BLOCKSIZE, &metadata, 1000)) < 0) |         res = LMS_SendStream(m_stream, (void *) m_buf, LIMESDROUTPUT_BLOCKSIZE, &metadata, 1000); | ||||||
|  | 
 | ||||||
|  |         if (res < 0) | ||||||
|         { |         { | ||||||
|             qCritical("LimeSDROutputThread::run write error: %s", strerror(errno)); |             qCritical("LimeSDROutputThread::run write error: %s", strerror(errno)); | ||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
|  |         else if (res != LIMESDROUTPUT_BLOCKSIZE) | ||||||
|  |         { | ||||||
|  |             qDebug("LimeSDROutputThread::run written %d/%d samples", res, LIMESDROUTPUT_BLOCKSIZE); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         usleep(msleep); | ||||||
|  | 
 | ||||||
|  |         if (count < 10) | ||||||
|  |         { | ||||||
|  |             count++; | ||||||
|  |         } | ||||||
|  |         else | ||||||
|  |         { | ||||||
|  |             if (LMS_GetStreamStatus(m_stream, &streamStatus) == 0) | ||||||
|  |             { | ||||||
|  |                 if (streamStatus.fifoFilledCount < (4*streamStatus.fifoSize)/5) { // FIFO at 80%
 | ||||||
|  |                     msleep -= mdelta; | ||||||
|  |                 } else { | ||||||
|  |                     msleep += mdelta; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             count = 0; | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (LMS_StopStream(m_stream) < 0) { |     if (LMS_StopStream(m_stream) < 0) { | ||||||
|  | |||||||
| @ -27,7 +27,7 @@ | |||||||
| #include "dsp/interpolators.h" | #include "dsp/interpolators.h" | ||||||
| #include "limesdr/devicelimesdrshared.h" | #include "limesdr/devicelimesdrshared.h" | ||||||
| 
 | 
 | ||||||
| #define LIMESDROUTPUT_BLOCKSIZE (1<<14) //complex samples per buffer ~10k (16k)
 | #define LIMESDROUTPUT_BLOCKSIZE (1<<15) //complex samples per buffer ~10k (16k)
 | ||||||
| 
 | 
 | ||||||
| class LimeSDROutputThread : public QThread, public DeviceLimeSDRShared::ThreadInterface | class LimeSDROutputThread : public QThread, public DeviceLimeSDRShared::ThreadInterface | ||||||
| { | { | ||||||
| @ -39,6 +39,7 @@ public: | |||||||
| 
 | 
 | ||||||
|     virtual void startWork(); |     virtual void startWork(); | ||||||
|     virtual void stopWork(); |     virtual void stopWork(); | ||||||
|  |     virtual void setDeviceSampleRate(int sampleRate) { m_sampleRate = sampleRate; } | ||||||
|     void setLog2Interpolation(unsigned int log2_ioterp); |     void setLog2Interpolation(unsigned int log2_ioterp); | ||||||
|     void setFcPos(int fcPos); |     void setFcPos(int fcPos); | ||||||
| 
 | 
 | ||||||
| @ -51,6 +52,7 @@ private: | |||||||
|     qint16 m_buf[2*LIMESDROUTPUT_BLOCKSIZE]; //must hold I+Q values of each sample hence 2xcomplex size
 |     qint16 m_buf[2*LIMESDROUTPUT_BLOCKSIZE]; //must hold I+Q values of each sample hence 2xcomplex size
 | ||||||
|     SampleSourceFifo* m_sampleFifo; |     SampleSourceFifo* m_sampleFifo; | ||||||
| 
 | 
 | ||||||
|  |     int m_sampleRate; | ||||||
|     unsigned int m_log2Interp; // soft decimation
 |     unsigned int m_log2Interp; // soft decimation
 | ||||||
|     int m_fcPos; |     int m_fcPos; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -228,7 +228,7 @@ void LimeSDRInputGUI::handleMessagesToGUI() | |||||||
| 
 | 
 | ||||||
|                 ui->fifoBar->setMaximum(report->getFifoSize()); |                 ui->fifoBar->setMaximum(report->getFifoSize()); | ||||||
|                 ui->fifoBar->setValue(report->getFifoFilledCount()); |                 ui->fifoBar->setValue(report->getFifoFilledCount()); | ||||||
|                 ui->fifoBar->setToolTip(tr("FIFO fill %1/%2 bytes").arg(QString::number(report->getFifoFilledCount())).arg(QString::number(report->getFifoSize()))); |                 ui->fifoBar->setToolTip(tr("FIFO fill %1/%2 samples").arg(QString::number(report->getFifoFilledCount())).arg(QString::number(report->getFifoSize()))); | ||||||
|             } |             } | ||||||
|             else |             else | ||||||
|             { |             { | ||||||
|  | |||||||
| @ -39,6 +39,7 @@ public: | |||||||
| 
 | 
 | ||||||
|     virtual void startWork(); |     virtual void startWork(); | ||||||
|     virtual void stopWork(); |     virtual void stopWork(); | ||||||
|  |     virtual void setDeviceSampleRate(int sampleRate) {} | ||||||
|     void setLog2Decimation(unsigned int log2_decim); |     void setLog2Decimation(unsigned int log2_decim); | ||||||
|     void setFcPos(int fcPos); |     void setFcPos(int fcPos); | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user