BladeRF2 output: fixed SO mode

This commit is contained in:
f4exb 2018-09-29 21:40:22 +02:00
parent 5566dc6a7e
commit 53ff8f32bf
9 changed files with 94 additions and 69 deletions

View File

@ -18,6 +18,10 @@
MESSAGE_CLASS_DEFINITION(DeviceBladeRF2Shared::MsgReportBuddyChange, Message)
const float DeviceBladeRF2Shared::m_sampleFifoLengthInSeconds = 0.25;
const int DeviceBladeRF2Shared::m_sampleFifoMinSize = 75000; // 300 kS/s knee
const int DeviceBladeRF2Shared::m_sampleFifoMinSize32 = 150000; // Fixed for interpolation by 32
DeviceBladeRF2Shared::DeviceBladeRF2Shared() :
m_dev(0),
m_channel(-1),

View File

@ -79,6 +79,10 @@ public:
int m_channel; //!< allocated channel (-1 if none)
BladeRF2Input *m_source;
BladeRF2Output *m_sink;
static const float m_sampleFifoLengthInSeconds;
static const int m_sampleFifoMinSize;
static const int m_sampleFifoMinSize32;
};

View File

@ -645,6 +645,37 @@ bool BladeRF2Output::applySettings(const BladeRF2OutputSettings& settings, bool
struct bladerf *dev = m_deviceShared.m_dev->getDev();
int requestedChannel = m_deviceAPI->getItemIndex();
if ((m_settings.m_devSampleRate != settings.m_devSampleRate) || (m_settings.m_log2Interp != settings.m_log2Interp) || force)
{
BladeRF2OutputThread *bladeRF2OutputThread = findThread();
SampleSourceFifo *fifo = 0;
if (bladeRF2OutputThread)
{
fifo = bladeRF2OutputThread->getFifo(requestedChannel);
bladeRF2OutputThread->setFifo(requestedChannel, 0);
}
int fifoSize;
if (settings.m_log2Interp >= 5)
{
fifoSize = DeviceBladeRF2Shared::m_sampleFifoMinSize32;
}
else
{
fifoSize = std::max(
(int) ((settings.m_devSampleRate/(1<<settings.m_log2Interp)) * DeviceBladeRF2Shared::m_sampleFifoLengthInSeconds),
DeviceBladeRF2Shared::m_sampleFifoMinSize);
}
m_sampleSourceFifo.resize(fifoSize);
if (fifo) {
bladeRF2OutputThread->setFifo(requestedChannel, &m_sampleSourceFifo);
}
}
if ((m_settings.m_devSampleRate != settings.m_devSampleRate) || force)
{
forwardChangeOwnDSP = true;
@ -663,7 +694,7 @@ bool BladeRF2Output::applySettings(const BladeRF2OutputSettings& settings, bool
}
else
{
qDebug() << "BladeRF2Output::applySettings: bladerf_set_sample_rate(BLADERF_MODULE_RX) actual sample rate is " << actualSamplerate;
qDebug() << "BladeRF2Output::applySettings: bladerf_set_sample_rate: actual sample rate is " << actualSamplerate;
}
}
}
@ -684,7 +715,7 @@ bool BladeRF2Output::applySettings(const BladeRF2OutputSettings& settings, bool
}
else
{
qDebug() << "BladeRF2Output::applySettings: bladerf_set_bandwidth(BLADERF_MODULE_RX) actual bandwidth is " << actualBandwidth;
qDebug() << "BladeRF2Output::applySettings: bladerf_set_bandwidth: actual bandwidth is " << actualBandwidth;
}
}
}
@ -736,25 +767,7 @@ bool BladeRF2Output::applySettings(const BladeRF2OutputSettings& settings, bool
m_deviceShared.m_dev->setBiasTeeTx(settings.m_biasTee);
}
if ((m_settings.m_gainMode != settings.m_gainMode) || force)
{
forwardChangeTxBuddies = true;
if (dev)
{
int status = bladerf_set_gain_mode(dev, BLADERF_CHANNEL_TX(requestedChannel), (bladerf_gain_mode) settings.m_gainMode);
if (status < 0) {
qWarning("BladeRF2Output::applySettings: bladerf_set_gain_mode(%d) failed: %s",
settings.m_gainMode, bladerf_strerror(status));
} else {
qDebug("BladeRF2Output::applySettings: bladerf_set_gain_mode(%d)", settings.m_gainMode);
}
}
}
if ((m_settings.m_globalGain != settings.m_globalGain)
|| ((m_settings.m_gainMode != settings.m_gainMode) && (settings.m_gainMode == BLADERF_GAIN_MANUAL)) || force)
if ((m_settings.m_globalGain != settings.m_globalGain) || force)
{
forwardChangeTxBuddies = true;
@ -821,7 +834,6 @@ bool BladeRF2Output::applySettings(const BladeRF2OutputSettings& settings, bool
<< " m_log2Interp: " << m_settings.m_log2Interp
<< " m_devSampleRate: " << m_settings.m_devSampleRate
<< " m_globalGain: " << m_settings.m_globalGain
<< " m_gainMode: " << m_settings.m_gainMode
<< " m_biasTee: " << m_settings.m_biasTee;
return true;
@ -860,9 +872,6 @@ int BladeRF2Output::webapiSettingsPutPatch(
if (deviceSettingsKeys.contains("biasTee")) {
settings.m_biasTee = response.getBladeRf2OutputSettings()->getBiasTee() != 0;
}
if (deviceSettingsKeys.contains("gainMode")) {
settings.m_gainMode = response.getBladeRf2OutputSettings()->getGainMode();
}
if (deviceSettingsKeys.contains("globalGain")) {
settings.m_globalGain = response.getBladeRf2OutputSettings()->getGlobalGain();
}
@ -895,7 +904,6 @@ void BladeRF2Output::webapiFormatDeviceSettings(SWGSDRangel::SWGDeviceSettings&
response.getBladeRf2OutputSettings()->setBandwidth(settings.m_bandwidth);
response.getBladeRf2OutputSettings()->setLog2Interp(settings.m_log2Interp);
response.getBladeRf2OutputSettings()->setBiasTee(settings.m_biasTee ? 1 : 0);
response.getBladeRf2OutputSettings()->setGainMode(settings.m_gainMode);
response.getBladeRf2OutputSettings()->setGlobalGain(settings.m_globalGain);
}

View File

@ -30,8 +30,7 @@ void BladeRF2OutputSettings::resetToDefaults()
m_centerFrequency = 435000*1000;
m_devSampleRate = 3072000;
m_bandwidth = 1500000;
m_gainMode = 0;
m_globalGain = -20;
m_globalGain = -3;
m_biasTee = false;
m_log2Interp = 0;
}
@ -42,7 +41,6 @@ QByteArray BladeRF2OutputSettings::serialize() const
s.writeS32(1, m_devSampleRate);
s.writeS32(2, m_bandwidth);
s.writeS32(3, m_gainMode);
s.writeS32(4, m_globalGain);
s.writeBool(5, m_biasTee);
s.writeU32(6, m_log2Interp);
@ -64,7 +62,6 @@ bool BladeRF2OutputSettings::deserialize(const QByteArray& data)
{
d.readS32(1, &m_devSampleRate);
d.readS32(2, &m_bandwidth);
d.readS32(3, &m_gainMode);
d.readS32(4, &m_globalGain);
d.readBool(5, &m_biasTee);
d.readU32(6, &m_log2Interp);

View File

@ -24,7 +24,6 @@ struct BladeRF2OutputSettings {
quint64 m_centerFrequency;
qint32 m_devSampleRate;
qint32 m_bandwidth;
int m_gainMode;
int m_globalGain;
bool m_biasTee;
quint32 m_log2Interp;

View File

@ -92,10 +92,10 @@ void BladeRF2OutputThread::run()
if (m_nbChannels > 1) {
callbackMO(m_buf, DeviceBladeRF2::blockSize);
} else {
callbackSO(m_buf, 2*DeviceBladeRF2::blockSize);
callbackSO(m_buf, DeviceBladeRF2::blockSize);
}
res = bladerf_sync_tx(m_dev, m_buf, DeviceBladeRF2::blockSize, NULL, 10000);
res = bladerf_sync_tx(m_dev, m_buf, DeviceBladeRF2::blockSize, 0, 10000);
if (res < 0)
{
@ -166,7 +166,7 @@ void BladeRF2OutputThread::callbackMO(qint16* buf, qint32 samplesPerChannel)
for (unsigned int channel = 0; channel < m_nbChannels; channel++)
{
if (m_channels[channel].m_sampleFifo) {
callbackSO(&buf[2*samplesPerChannel*channel], 2*samplesPerChannel, channel);
callbackSO(&buf[2*samplesPerChannel*channel], samplesPerChannel, channel);
} else {
std::fill(&buf[2*samplesPerChannel*channel], &buf[2*samplesPerChannel*channel]+2*samplesPerChannel, 0); // fill with zero samples
}
@ -182,42 +182,57 @@ void BladeRF2OutputThread::callbackMO(qint16* buf, qint32 samplesPerChannel)
}
}
// Interpolate according to specified log2 (ex: log2=4 => decim=16)
// Interpolate according to specified log2 (ex: log2=4 => decim=16). len is a number of samples (not a number of I or Q)
void BladeRF2OutputThread::callbackSO(qint16* buf, qint32 len, unsigned int channel)
{
SampleVector::iterator beginRead;
m_channels[channel].m_sampleFifo->readAdvance(beginRead, len/(1<<m_channels[channel].m_log2Interp));
beginRead -= len;
if (m_channels[channel].m_log2Interp == 0)
if (m_channels[channel].m_sampleFifo)
{
m_channels[channel].m_interpolators.interpolate1(&beginRead, buf, len*2);
float bal = m_channels[channel].m_sampleFifo->getRWBalance();
if (bal < -0.25) {
qDebug("BladeRF2OutputThread::callbackSO: read lags: %f", bal);
} else if (bal > 0.25) {
qDebug("BladeRF2OutputThread::callbackSO: read leads: %f", bal);
}
SampleVector::iterator beginRead;
m_channels[channel].m_sampleFifo->readAdvance(beginRead, len/(1<<m_channels[channel].m_log2Interp));
beginRead -= len;
if (m_channels[channel].m_log2Interp == 0)
{
m_channels[channel].m_interpolators.interpolate1(&beginRead, buf, len*2);
}
else
{
switch (m_channels[channel].m_log2Interp)
{
case 1:
m_channels[channel].m_interpolators.interpolate2_cen(&beginRead, buf, len*2);
break;
case 2:
m_channels[channel].m_interpolators.interpolate4_cen(&beginRead, buf, len*2);
break;
case 3:
m_channels[channel].m_interpolators.interpolate8_cen(&beginRead, buf, len*2);
break;
case 4:
m_channels[channel].m_interpolators.interpolate16_cen(&beginRead, buf, len*2);
break;
case 5:
m_channels[channel].m_interpolators.interpolate32_cen(&beginRead, buf, len*2);
break;
case 6:
m_channels[channel].m_interpolators.interpolate64_cen(&beginRead, buf, len*2);
break;
default:
break;
}
}
}
else
{
switch (m_channels[channel].m_log2Interp)
{
case 1:
m_channels[channel].m_interpolators.interpolate2_cen(&beginRead, buf, len*2);
break;
case 2:
m_channels[channel].m_interpolators.interpolate4_cen(&beginRead, buf, len*2);
break;
case 3:
m_channels[channel].m_interpolators.interpolate8_cen(&beginRead, buf, len*2);
break;
case 4:
m_channels[channel].m_interpolators.interpolate16_cen(&beginRead, buf, len*2);
break;
case 5:
m_channels[channel].m_interpolators.interpolate32_cen(&beginRead, buf, len*2);
break;
case 6:
m_channels[channel].m_interpolators.interpolate64_cen(&beginRead, buf, len*2);
break;
default:
break;
}
std::fill(buf, buf+2*len, 0);
}
}

View File

@ -735,7 +735,7 @@ bool BladeRF2Input::applySettings(const BladeRF2InputSettings& settings, bool fo
}
else
{
qDebug() << "BladeRF2Input::applySettings: bladerf_set_sample_rate(BLADERF_MODULE_RX) actual sample rate is " << actualSamplerate;
qDebug() << "BladeRF2Input::applySettings: bladerf_set_sample_rate: actual sample rate is " << actualSamplerate;
}
}
}
@ -756,7 +756,7 @@ bool BladeRF2Input::applySettings(const BladeRF2InputSettings& settings, bool fo
}
else
{
qDebug() << "BladeRF2Input::applySettings: bladerf_set_bandwidth(BLADERF_MODULE_RX) actual bandwidth is " << actualBandwidth;
qDebug() << "BladeRF2Input::applySettings: bladerf_set_bandwidth: actual bandwidth is " << actualBandwidth;
}
}
}

View File

@ -43,7 +43,7 @@ public:
void write(const Sample& sample); //!< write directly - phase 1 + phase 2
/** returns ratio of off center over buffer size with sign: negative real lags and positive read leads */
/** returns ratio of off center over buffer size with sign: negative read lags and positive read leads */
float getRWBalance() const
{
int delta;

View File

@ -51,8 +51,6 @@ BladeRF2OutputSettings:
type: integer
bandwidth:
type: integer
gainMode:
type: integer
globalGain:
type: integer
biasTee: