mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-11-25 17:28:50 -05: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…
Reference in New Issue
Block a user