1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2024-11-16 05:11:49 -05:00

Demod plugins with configurable audio: fixed audio sample rate handling

This commit is contained in:
f4exb 2020-08-01 10:09:39 +02:00
parent 720d69311e
commit c41cf68d60
40 changed files with 149 additions and 66 deletions

View File

@ -165,14 +165,15 @@ void AMDemodBaseband::applySettings(const AMDemodSettings& settings, bool force)
AudioDeviceManager *audioDeviceManager = DSPEngine::instance()->getAudioDeviceManager(); AudioDeviceManager *audioDeviceManager = DSPEngine::instance()->getAudioDeviceManager();
int audioDeviceIndex = audioDeviceManager->getOutputDeviceIndex(settings.m_audioDeviceName); int audioDeviceIndex = audioDeviceManager->getOutputDeviceIndex(settings.m_audioDeviceName);
//qDebug("AMDemod::applySettings: audioDeviceName: %s audioDeviceIndex: %d", qPrintable(settings.m_audioDeviceName), audioDeviceIndex); //qDebug("AMDemod::applySettings: audioDeviceName: %s audioDeviceIndex: %d", qPrintable(settings.m_audioDeviceName), audioDeviceIndex);
audioDeviceManager->removeAudioSink(m_sink.getAudioFifo());
audioDeviceManager->addAudioSink(m_sink.getAudioFifo(), getInputMessageQueue(), audioDeviceIndex); audioDeviceManager->addAudioSink(m_sink.getAudioFifo(), getInputMessageQueue(), audioDeviceIndex);
uint32_t audioSampleRate = audioDeviceManager->getOutputSampleRate(audioDeviceIndex); int audioSampleRate = audioDeviceManager->getOutputSampleRate(audioDeviceIndex);
if (m_sink.getAudioSampleRate() != audioSampleRate) if (m_sink.getAudioSampleRate() != audioSampleRate)
{ {
m_sink.applyAudioSampleRate(audioSampleRate);
m_channelizer->setChannelization(audioSampleRate, settings.m_inputFrequencyOffset); m_channelizer->setChannelization(audioSampleRate, settings.m_inputFrequencyOffset);
m_sink.applyChannelSettings(m_channelizer->getChannelSampleRate(), m_channelizer->getChannelFrequencyOffset()); m_sink.applyChannelSettings(m_channelizer->getChannelSampleRate(), m_channelizer->getChannelFrequencyOffset());
m_sink.applyAudioSampleRate(audioSampleRate);
} }
} }

View File

@ -66,7 +66,7 @@ public:
int getChannelSampleRate() const; int getChannelSampleRate() const;
void getMagSqLevels(double& avg, double& peak, int& nbSamples) { m_sink.getMagSqLevels(avg, peak, nbSamples); } void getMagSqLevels(double& avg, double& peak, int& nbSamples) { m_sink.getMagSqLevels(avg, peak, nbSamples); }
bool getSquelchOpen() const { return m_sink.getSquelchOpen(); } bool getSquelchOpen() const { return m_sink.getSquelchOpen(); }
unsigned int getAudioSampleRate() const { return m_sink.getAudioSampleRate(); } int getAudioSampleRate() const { return m_sink.getAudioSampleRate(); }
void setBasebandSampleRate(int sampleRate); void setBasebandSampleRate(int sampleRate);
double getMagSq() const { return m_sink.getMagSq(); } double getMagSq() const { return m_sink.getMagSq(); }
bool getPllLocked() const { return m_sink.getPllLocked(); } bool getPllLocked() const { return m_sink.getPllLocked(); }

View File

@ -255,6 +255,7 @@ AMDemodGUI::AMDemodGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandS
m_channelMarker(this), m_channelMarker(this),
m_doApplySettings(true), m_doApplySettings(true),
m_squelchOpen(false), m_squelchOpen(false),
m_audioSampleRate(-1),
m_samUSB(true), m_samUSB(true),
m_tickCount(0) m_tickCount(0)
{ {
@ -461,18 +462,22 @@ void AMDemodGUI::tick()
ui->channelPower->setText(QString::number(powDbAvg, 'f', 1)); ui->channelPower->setText(QString::number(powDbAvg, 'f', 1));
} }
int audioSampleRate = m_amDemod->getAudioSampleRate();
bool squelchOpen = m_amDemod->getSquelchOpen(); bool squelchOpen = m_amDemod->getSquelchOpen();
if (squelchOpen != m_squelchOpen) if ((audioSampleRate != m_audioSampleRate) || (squelchOpen != m_squelchOpen))
{ {
m_squelchOpen = squelchOpen; if (audioSampleRate < 0) {
ui->audioMute->setStyleSheet("QToolButton { background-color : red; }");
} else if (squelchOpen) {
ui->audioMute->setStyleSheet("QToolButton { background-color : green; }");
} else {
ui->audioMute->setStyleSheet("QToolButton { background:rgb(79,79,79); }");
}
if (m_squelchOpen) { m_audioSampleRate = audioSampleRate;
ui->audioMute->setStyleSheet("QToolButton { background-color : green; }"); m_squelchOpen = squelchOpen;
} else { }
ui->audioMute->setStyleSheet("QToolButton { background:rgb(79,79,79); }");
}
}
if (m_settings.m_pll) if (m_settings.m_pll)
{ {
@ -482,7 +487,7 @@ void AMDemodGUI::tick()
ui->pll->setStyleSheet("QToolButton { background:rgb(79,79,79); }"); ui->pll->setStyleSheet("QToolButton { background:rgb(79,79,79); }");
} }
int freq = (m_amDemod->getPllFrequency() * m_amDemod->getAudioSampleRate()) / (2.0*M_PI); int freq = (m_amDemod->getPllFrequency() * audioSampleRate) / (2.0*M_PI);
ui->pll->setToolTip(tr("PLL for synchronous AM. Freq = %1 Hz").arg(freq)); ui->pll->setToolTip(tr("PLL for synchronous AM. Freq = %1 Hz").arg(freq));
} }

View File

@ -52,6 +52,7 @@ private:
AMDemod* m_amDemod; AMDemod* m_amDemod;
bool m_squelchOpen; bool m_squelchOpen;
int m_audioSampleRate; //!< for display purposes
bool m_samUSB; bool m_samUSB;
uint32_t m_tickCount; uint32_t m_tickCount;
MessageQueue m_inputMessageQueue; MessageQueue m_inputMessageQueue;

View File

@ -297,6 +297,12 @@ void AMDemodSink::applySettings(const AMDemodSettings& settings, bool force)
void AMDemodSink::applyAudioSampleRate(int sampleRate) void AMDemodSink::applyAudioSampleRate(int sampleRate)
{ {
if (sampleRate < 0)
{
qWarning("AMDemodSink::applyAudioSampleRate: invalid sample rate: %d", sampleRate);
return;
}
qDebug("AMDemodSink::applyAudioSampleRate: sampleRate: %d m_channelSampleRate: %d", sampleRate, m_channelSampleRate); qDebug("AMDemodSink::applyAudioSampleRate: sampleRate: %d m_channelSampleRate: %d", sampleRate, m_channelSampleRate);
m_interpolator.create(16, m_channelSampleRate, m_settings.m_rfBandwidth / 2.2f); m_interpolator.create(16, m_channelSampleRate, m_settings.m_rfBandwidth / 2.2f);

View File

@ -44,7 +44,7 @@ public:
void applySettings(const AMDemodSettings& settings, bool force = false); void applySettings(const AMDemodSettings& settings, bool force = false);
void applyAudioSampleRate(int sampleRate); void applyAudioSampleRate(int sampleRate);
uint32_t getAudioSampleRate() const { return m_audioSampleRate; } int getAudioSampleRate() const { return m_audioSampleRate; }
double getMagSq() const { return m_magsq; } double getMagSq() const { return m_magsq; }
bool getSquelchOpen() const { return m_squelchOpen; } bool getSquelchOpen() const { return m_squelchOpen; }
bool getPllLocked() const { return m_settings.m_pll && m_pll.locked(); } bool getPllLocked() const { return m_settings.m_pll && m_pll.locked(); }
@ -88,7 +88,7 @@ private:
int m_channelSampleRate; int m_channelSampleRate;
int m_channelFrequencyOffset; int m_channelFrequencyOffset;
AMDemodSettings m_settings; AMDemodSettings m_settings;
uint32_t m_audioSampleRate; int m_audioSampleRate;
NCO m_nco; NCO m_nco;
Interpolator m_interpolator; Interpolator m_interpolator;

View File

@ -105,6 +105,7 @@ public:
Real getDemodAcc() const { return m_basebandSink->getDemodAcc(); } Real getDemodAcc() const { return m_basebandSink->getDemodAcc(); }
Real getDemodQua() const { return m_basebandSink->getDemodQua(); } Real getDemodQua() const { return m_basebandSink->getDemodQua(); }
Real getDemodFclk() const { return m_basebandSink->getDemodFclk(); } Real getDemodFclk() const { return m_basebandSink->getDemodFclk(); }
int getAudioSampleRate() const { return m_basebandSink->getAudioSampleRate(); }
void getMagSqLevels(double& avg, double& peak, int& nbSamples) { m_basebandSink->getMagSqLevels(avg, peak, nbSamples); } void getMagSqLevels(double& avg, double& peak, int& nbSamples) { m_basebandSink->getMagSqLevels(avg, peak, nbSamples); }

View File

@ -159,8 +159,9 @@ void BFMDemodBaseband::applySettings(const BFMDemodSettings& settings, bool forc
AudioDeviceManager *audioDeviceManager = DSPEngine::instance()->getAudioDeviceManager(); AudioDeviceManager *audioDeviceManager = DSPEngine::instance()->getAudioDeviceManager();
int audioDeviceIndex = audioDeviceManager->getOutputDeviceIndex(settings.m_audioDeviceName); int audioDeviceIndex = audioDeviceManager->getOutputDeviceIndex(settings.m_audioDeviceName);
//qDebug("AMDemod::applySettings: audioDeviceName: %s audioDeviceIndex: %d", qPrintable(settings.m_audioDeviceName), audioDeviceIndex); //qDebug("AMDemod::applySettings: audioDeviceName: %s audioDeviceIndex: %d", qPrintable(settings.m_audioDeviceName), audioDeviceIndex);
audioDeviceManager->removeAudioSink(m_sink.getAudioFifo());
audioDeviceManager->addAudioSink(m_sink.getAudioFifo(), getInputMessageQueue(), audioDeviceIndex); audioDeviceManager->addAudioSink(m_sink.getAudioFifo(), getInputMessageQueue(), audioDeviceIndex);
uint32_t audioSampleRate = audioDeviceManager->getOutputSampleRate(audioDeviceIndex); int audioSampleRate = audioDeviceManager->getOutputSampleRate(audioDeviceIndex);
if (m_sink.getAudioSampleRate() != audioSampleRate) { if (m_sink.getAudioSampleRate() != audioSampleRate) {
m_sink.applyAudioSampleRate(audioSampleRate); m_sink.applyAudioSampleRate(audioSampleRate);

View File

@ -66,7 +66,7 @@ public:
void setSpectrumSink(BasebandSampleSink* spectrumSink) { m_sink.setSpectrumSink(spectrumSink); } void setSpectrumSink(BasebandSampleSink* spectrumSink) { m_sink.setSpectrumSink(spectrumSink); }
void setMessageQueueToGUI(MessageQueue *messageQueue) { m_messageQueueToGUI = messageQueue; } void setMessageQueueToGUI(MessageQueue *messageQueue) { m_messageQueueToGUI = messageQueue; }
unsigned int getAudioSampleRate() const { return m_sink.getAudioSampleRate(); } int getAudioSampleRate() const { return m_sink.getAudioSampleRate(); }
int getSquelchState() const { return m_sink.getSquelchState(); } int getSquelchState() const { return m_sink.getSquelchState(); }
double getMagSq() const { return m_sink.getMagSq(); } double getMagSq() const { return m_sink.getMagSq(); }
bool getPilotLock() const { return m_sink.getPilotLock(); } bool getPilotLock() const { return m_sink.getPilotLock(); }

View File

@ -551,20 +551,25 @@ void BFMDemodGUI::tick()
pilotPowDbStr.sprintf("%+02.1f", pilotPowDb); pilotPowDbStr.sprintf("%+02.1f", pilotPowDb);
ui->pilotPower->setText(pilotPowDbStr); ui->pilotPower->setText(pilotPowDbStr);
if (m_bfmDemod->getPilotLock()) if (m_bfmDemod->getAudioSampleRate() < 0)
{ {
if (ui->audioStereo->isChecked()) ui->audioStereo->setStyleSheet("QToolButton { background-color : red; }");
{ }
ui->audioStereo->setStyleSheet("QToolButton { background-color : green; }"); else
} {
} if (m_bfmDemod->getPilotLock())
else {
{ if (ui->audioStereo->isChecked()) {
if (ui->audioStereo->isChecked()) ui->audioStereo->setStyleSheet("QToolButton { background-color : green; }");
{ }
ui->audioStereo->setStyleSheet("QToolButton { background:rgb(79,79,79); }"); }
} else
} {
if (ui->audioStereo->isChecked()) {
ui->audioStereo->setStyleSheet("QToolButton { background:rgb(79,79,79); }");
}
}
}
if (ui->rds->isChecked() && (m_rdsTimerCount == 0)) if (ui->rds->isChecked() && (m_rdsTimerCount == 0))
{ {

View File

@ -247,8 +247,14 @@ void BFMDemodSink::feed(const SampleVector::const_iterator& begin, const SampleV
m_sampleBuffer.clear(); m_sampleBuffer.clear();
} }
void BFMDemodSink::applyAudioSampleRate(unsigned int sampleRate) void BFMDemodSink::applyAudioSampleRate(int sampleRate)
{ {
if (sampleRate < 0)
{
qWarning("BFMDemodSink::applyAudioSampleRate: invalid sample rate: %d", sampleRate);
return;
}
qDebug("BFMDemodSink::applyAudioSampleRate: %u", sampleRate); qDebug("BFMDemodSink::applyAudioSampleRate: %u", sampleRate);
m_interpolator.create(16, m_channelSampleRate, m_settings.m_afBandwidth); m_interpolator.create(16, m_channelSampleRate, m_settings.m_afBandwidth);

View File

@ -83,8 +83,8 @@ public:
void applySettings(const BFMDemodSettings& settings, bool force = false); void applySettings(const BFMDemodSettings& settings, bool force = false);
AudioFifo *getAudioFifo() { return &m_audioFifo; } AudioFifo *getAudioFifo() { return &m_audioFifo; }
void applyAudioSampleRate(unsigned int sampleRate); void applyAudioSampleRate(int sampleRate);
unsigned int getAudioSampleRate() const { return m_audioSampleRate; } int getAudioSampleRate() const { return m_audioSampleRate; }
private: private:
struct MagSqLevelsStore struct MagSqLevelsStore
@ -106,7 +106,7 @@ private:
int m_channelFrequencyOffset; int m_channelFrequencyOffset;
BFMDemodSettings m_settings; BFMDemodSettings m_settings;
quint32 m_audioSampleRate; int m_audioSampleRate;
AudioVector m_audioBuffer; AudioVector m_audioBuffer;
uint m_audioBufferFill; uint m_audioBufferFill;
AudioFifo m_audioFifo; AudioFifo m_audioFifo;

View File

@ -119,6 +119,7 @@ public:
const DSDDecoder& getDecoder() const { return m_basebandSink->getDecoder(); } const DSDDecoder& getDecoder() const { return m_basebandSink->getDecoder(); }
void getMagSqLevels(double& avg, double& peak, int& nbSamples) { m_basebandSink->getMagSqLevels(avg, peak, nbSamples); } void getMagSqLevels(double& avg, double& peak, int& nbSamples) { m_basebandSink->getMagSqLevels(avg, peak, nbSamples); }
const char *updateAndGetStatusText() { return m_basebandSink->updateAndGetStatusText(); } const char *updateAndGetStatusText() { return m_basebandSink->updateAndGetStatusText(); }
int getAudioSampleRate() const { return m_basebandSink->getAudioSampleRate(); }
static const QString m_channelIdURI; static const QString m_channelIdURI;
static const QString m_channelId; static const QString m_channelId;

View File

@ -147,15 +147,17 @@ void DSDDemodBaseband::applySettings(const DSDDemodSettings& settings, bool forc
AudioDeviceManager *audioDeviceManager = DSPEngine::instance()->getAudioDeviceManager(); AudioDeviceManager *audioDeviceManager = DSPEngine::instance()->getAudioDeviceManager();
int audioDeviceIndex = audioDeviceManager->getOutputDeviceIndex(settings.m_audioDeviceName); int audioDeviceIndex = audioDeviceManager->getOutputDeviceIndex(settings.m_audioDeviceName);
//qDebug("AMDemod::applySettings: audioDeviceName: %s audioDeviceIndex: %d", qPrintable(settings.m_audioDeviceName), audioDeviceIndex); //qDebug("AMDemod::applySettings: audioDeviceName: %s audioDeviceIndex: %d", qPrintable(settings.m_audioDeviceName), audioDeviceIndex);
audioDeviceManager->removeAudioSink(m_sink.getAudioFifo1());
audioDeviceManager->removeAudioSink(m_sink.getAudioFifo2());
audioDeviceManager->addAudioSink(m_sink.getAudioFifo1(), getInputMessageQueue(), audioDeviceIndex); audioDeviceManager->addAudioSink(m_sink.getAudioFifo1(), getInputMessageQueue(), audioDeviceIndex);
audioDeviceManager->addAudioSink(m_sink.getAudioFifo2(), getInputMessageQueue(), audioDeviceIndex); audioDeviceManager->addAudioSink(m_sink.getAudioFifo2(), getInputMessageQueue(), audioDeviceIndex);
uint32_t audioSampleRate = audioDeviceManager->getOutputSampleRate(audioDeviceIndex); int audioSampleRate = audioDeviceManager->getOutputSampleRate(audioDeviceIndex);
if (m_sink.getAudioSampleRate() != audioSampleRate) if (m_sink.getAudioSampleRate() != audioSampleRate)
{ {
m_sink.applyAudioSampleRate(audioSampleRate);
m_channelizer->setChannelization(audioSampleRate, settings.m_inputFrequencyOffset); m_channelizer->setChannelization(audioSampleRate, settings.m_inputFrequencyOffset);
m_sink.applyChannelSettings(m_channelizer->getChannelSampleRate(), m_channelizer->getChannelFrequencyOffset()); m_sink.applyChannelSettings(m_channelizer->getChannelSampleRate(), m_channelizer->getChannelFrequencyOffset());
m_sink.applyAudioSampleRate(audioSampleRate);
} }
} }

View File

@ -62,7 +62,7 @@ public:
void feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end); void feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end);
MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; } //!< Get the queue for asynchronous inbound communication MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; } //!< Get the queue for asynchronous inbound communication
int getChannelSampleRate() const; int getChannelSampleRate() const;
unsigned int getAudioSampleRate() const { return m_sink.getAudioSampleRate(); } int getAudioSampleRate() const { return m_sink.getAudioSampleRate(); }
double getMagSq() { return m_sink.getMagSq(); } double getMagSq() { return m_sink.getMagSq(); }
void getMagSqLevels(double& avg, double& peak, int& nbSamples) { m_sink.getMagSqLevels(avg, peak, nbSamples); } void getMagSqLevels(double& avg, double& peak, int& nbSamples) { m_sink.getMagSqLevels(avg, peak, nbSamples); }
bool getSquelchOpen() const { return m_sink.getSquelchOpen(); } bool getSquelchOpen() const { return m_sink.getSquelchOpen(); }

View File

@ -334,6 +334,7 @@ DSDDemodGUI::DSDDemodGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, Baseban
m_slot2On(false), m_slot2On(false),
m_tdmaStereo(false), m_tdmaStereo(false),
m_squelchOpen(false), m_squelchOpen(false),
m_audioSampleRate(-1),
m_tickCount(0), m_tickCount(0),
m_dsdStatusTextDialog(0) m_dsdStatusTextDialog(0)
{ {
@ -560,16 +561,20 @@ void DSDDemodGUI::tick()
ui->channelPower->setText(tr("%1 dB").arg(powDbAvg, 0, 'f', 1)); ui->channelPower->setText(tr("%1 dB").arg(powDbAvg, 0, 'f', 1));
} }
int audioSampleRate = m_dsdDemod->getAudioSampleRate();
bool squelchOpen = m_dsdDemod->getSquelchOpen(); bool squelchOpen = m_dsdDemod->getSquelchOpen();
if (squelchOpen != m_squelchOpen) if ((audioSampleRate != m_audioSampleRate) || (squelchOpen != m_squelchOpen))
{ {
if (squelchOpen) { if (audioSampleRate < 0) {
ui->audioMute->setStyleSheet("QToolButton { background-color : red; }");
} else if (squelchOpen) {
ui->audioMute->setStyleSheet("QToolButton { background-color : green; }"); ui->audioMute->setStyleSheet("QToolButton { background-color : green; }");
} else { } else {
ui->audioMute->setStyleSheet("QToolButton { background:rgb(79,79,79); }"); ui->audioMute->setStyleSheet("QToolButton { background:rgb(79,79,79); }");
} }
m_audioSampleRate = audioSampleRate;
m_squelchOpen = squelchOpen; m_squelchOpen = squelchOpen;
} }

View File

@ -91,6 +91,7 @@ private:
bool m_tdmaStereo; bool m_tdmaStereo;
bool m_audioMute; bool m_audioMute;
bool m_squelchOpen; bool m_squelchOpen;
int m_audioSampleRate;
uint32_t m_tickCount; uint32_t m_tickCount;
float m_myLatitude; float m_myLatitude;

View File

@ -281,6 +281,12 @@ void DSDDemodSink::feed(const SampleVector::const_iterator& begin, const SampleV
void DSDDemodSink::applyAudioSampleRate(int sampleRate) void DSDDemodSink::applyAudioSampleRate(int sampleRate)
{ {
if (sampleRate < 0)
{
qWarning("DSDDemodSink::applyAudioSampleRate: invalid sample rate: %d", sampleRate);
return;
}
int upsampling = sampleRate / 8000; int upsampling = sampleRate / 8000;
qDebug("DSDDemodSink::applyAudioSampleRate: audio rate: %d upsample by %d", sampleRate, upsampling); qDebug("DSDDemodSink::applyAudioSampleRate: audio rate: %d upsample by %d", sampleRate, upsampling);

View File

@ -47,7 +47,7 @@ public:
void applySettings(const DSDDemodSettings& settings, bool force = false); void applySettings(const DSDDemodSettings& settings, bool force = false);
AudioFifo *getAudioFifo1() { return &m_audioFifo1; } AudioFifo *getAudioFifo1() { return &m_audioFifo1; }
AudioFifo *getAudioFifo2() { return &m_audioFifo2; } AudioFifo *getAudioFifo2() { return &m_audioFifo2; }
unsigned int getAudioSampleRate() const { return m_audioSampleRate; } int getAudioSampleRate() const { return m_audioSampleRate; }
void setScopeXYSink(BasebandSampleSink* scopeSink) { m_scopeXY = scopeSink; } void setScopeXYSink(BasebandSampleSink* scopeSink) { m_scopeXY = scopeSink; }
void configureMyPosition(float myLatitude, float myLongitude); void configureMyPosition(float myLatitude, float myLongitude);
@ -106,7 +106,7 @@ private:
int m_channelSampleRate; int m_channelSampleRate;
int m_channelFrequencyOffset; int m_channelFrequencyOffset;
DSDDemodSettings m_settings; DSDDemodSettings m_settings;
quint32 m_audioSampleRate; int m_audioSampleRate;
NCO m_nco; NCO m_nco;
Interpolator m_interpolator; Interpolator m_interpolator;

View File

@ -101,7 +101,7 @@ public:
return m_settings.m_inputFrequencyOffset; return m_settings.m_inputFrequencyOffset;
} }
uint32_t getAudioSampleRate() const { return m_basebandSink->getAudioSampleRate(); } int getAudioSampleRate() const { return m_basebandSink->getAudioSampleRate(); }
uint32_t getModemSampleRate() const { return m_basebandSink->getModemSampleRate(); } uint32_t getModemSampleRate() const { return m_basebandSink->getModemSampleRate(); }
double getMagSq() const { return m_basebandSink->getMagSq(); } double getMagSq() const { return m_basebandSink->getMagSq(); }
bool getAudioActive() const { return m_basebandSink->getAudioActive(); } bool getAudioActive() const { return m_basebandSink->getAudioActive(); }

View File

@ -159,8 +159,9 @@ void FreeDVDemodBaseband::applySettings(const FreeDVDemodSettings& settings, boo
AudioDeviceManager *audioDeviceManager = DSPEngine::instance()->getAudioDeviceManager(); AudioDeviceManager *audioDeviceManager = DSPEngine::instance()->getAudioDeviceManager();
int audioDeviceIndex = audioDeviceManager->getOutputDeviceIndex(settings.m_audioDeviceName); int audioDeviceIndex = audioDeviceManager->getOutputDeviceIndex(settings.m_audioDeviceName);
//qDebug("AMDemod::applySettings: audioDeviceName: %s audioDeviceIndex: %d", qPrintable(settings.m_audioDeviceName), audioDeviceIndex); //qDebug("AMDemod::applySettings: audioDeviceName: %s audioDeviceIndex: %d", qPrintable(settings.m_audioDeviceName), audioDeviceIndex);
audioDeviceManager->removeAudioSink(m_sink.getAudioFifo());
audioDeviceManager->addAudioSink(m_sink.getAudioFifo(), getInputMessageQueue(), audioDeviceIndex); audioDeviceManager->addAudioSink(m_sink.getAudioFifo(), getInputMessageQueue(), audioDeviceIndex);
uint32_t audioSampleRate = audioDeviceManager->getOutputSampleRate(audioDeviceIndex); int audioSampleRate = audioDeviceManager->getOutputSampleRate(audioDeviceIndex);
if (m_sink.getAudioSampleRate() != audioSampleRate) { if (m_sink.getAudioSampleRate() != audioSampleRate) {
m_sink.applyAudioSampleRate(audioSampleRate); m_sink.applyAudioSampleRate(audioSampleRate);

View File

@ -75,7 +75,7 @@ public:
void feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end); void feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end);
MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; } //!< Get the queue for asynchronous inbound communication MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; } //!< Get the queue for asynchronous inbound communication
int getChannelSampleRate() const; int getChannelSampleRate() const;
unsigned int getAudioSampleRate() const { return m_sink.getAudioSampleRate(); } int getAudioSampleRate() const { return m_sink.getAudioSampleRate(); }
double getMagSq() { return m_sink.getMagSq(); } double getMagSq() { return m_sink.getMagSq(); }
void getMagSqLevels(double& avg, double& peak, int& nbSamples) { m_sink.getMagSqLevels(avg, peak, nbSamples); } void getMagSqLevels(double& avg, double& peak, int& nbSamples) { m_sink.getMagSqLevels(avg, peak, nbSamples); }
void setBasebandSampleRate(int sampleRate); void setBasebandSampleRate(int sampleRate);

View File

@ -268,7 +268,8 @@ FreeDVDemodGUI::FreeDVDemodGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, B
m_audioBinaural(false), m_audioBinaural(false),
m_audioFlipChannels(false), m_audioFlipChannels(false),
m_audioMute(false), m_audioMute(false),
m_squelchOpen(false) m_squelchOpen(false),
m_audioSampleRate(-1)
{ {
ui->setupUi(this); ui->setupUi(this);
setAttribute(Qt::WA_DeleteOnClose, true); setAttribute(Qt::WA_DeleteOnClose, true);
@ -486,16 +487,20 @@ void FreeDVDemodGUI::tick()
ui->snrText->setText(tr("%1 dB").arg(snrAvg < -90 ? -90 : snrAvg > 90 ? 90 : snrAvg, 0, 'f', 1)); ui->snrText->setText(tr("%1 dB").arg(snrAvg < -90 ? -90 : snrAvg > 90 ? 90 : snrAvg, 0, 'f', 1));
} }
int audioSampleRate = m_freeDVDemod->getAudioSampleRate();
bool squelchOpen = m_freeDVDemod->getAudioActive(); bool squelchOpen = m_freeDVDemod->getAudioActive();
if (squelchOpen != m_squelchOpen) if ((audioSampleRate != m_audioSampleRate) || (squelchOpen != m_squelchOpen))
{ {
if (squelchOpen) { if (audioSampleRate < 0) {
ui->audioMute->setStyleSheet("QToolButton { background-color : red; }");
} else if (squelchOpen) {
ui->audioMute->setStyleSheet("QToolButton { background-color : green; }"); ui->audioMute->setStyleSheet("QToolButton { background-color : green; }");
} else { } else {
ui->audioMute->setStyleSheet("QToolButton { background:rgb(79,79,79); }"); ui->audioMute->setStyleSheet("QToolButton { background:rgb(79,79,79); }");
} }
m_audioSampleRate = audioSampleRate;
m_squelchOpen = squelchOpen; m_squelchOpen = squelchOpen;
} }

View File

@ -73,6 +73,7 @@ private:
bool m_audioFlipChannels; bool m_audioFlipChannels;
bool m_audioMute; bool m_audioMute;
bool m_squelchOpen; bool m_squelchOpen;
int m_audioSampleRate;
uint32_t m_tickCount; uint32_t m_tickCount;
FreeDVDemod* m_freeDVDemod; FreeDVDemod* m_freeDVDemod;

View File

@ -379,6 +379,12 @@ void FreeDVDemodSink::applyChannelSettings(int channelSampleRate, int channnelFr
void FreeDVDemodSink::applyAudioSampleRate(int sampleRate) void FreeDVDemodSink::applyAudioSampleRate(int sampleRate)
{ {
if (sampleRate < 0)
{
qWarning("FreeDVDemodSink::applyAudioSampleRate: invalid sample rate: %d", sampleRate);
return;
}
qDebug("FreeDVDemodSink::applyAudioSampleRate: %d", sampleRate); qDebug("FreeDVDemodSink::applyAudioSampleRate: %d", sampleRate);
m_audioFifo.setSize(sampleRate); m_audioFifo.setSize(sampleRate);

View File

@ -51,7 +51,7 @@ public:
void resyncFreeDV(); void resyncFreeDV();
void setSpectrumSink(BasebandSampleSink* spectrumSink) { m_spectrumSink = spectrumSink; } void setSpectrumSink(BasebandSampleSink* spectrumSink) { m_spectrumSink = spectrumSink; }
uint32_t getAudioSampleRate() const { return m_audioSampleRate; } int getAudioSampleRate() const { return m_audioSampleRate; }
uint32_t getModemSampleRate() const { return m_modemSampleRate; } uint32_t getModemSampleRate() const { return m_modemSampleRate; }
double getMagSq() const { return m_magsq; } double getMagSq() const { return m_magsq; }
bool getAudioActive() const { return m_audioActive; } bool getAudioActive() const { return m_audioActive; }
@ -155,7 +155,7 @@ private:
int m_channelSampleRate; int m_channelSampleRate;
uint32_t m_modemSampleRate; uint32_t m_modemSampleRate;
uint32_t m_speechSampleRate; uint32_t m_speechSampleRate;
uint32_t m_audioSampleRate; int m_audioSampleRate;
int m_channelFrequencyOffset; int m_channelFrequencyOffset;
bool m_audioMute; bool m_audioMute;
double m_magsq; double m_magsq;

View File

@ -115,6 +115,7 @@ public:
bool getSquelchOpen() const { return m_basebandSink->getSquelchOpen(); } bool getSquelchOpen() const { return m_basebandSink->getSquelchOpen(); }
void getMagSqLevels(double& avg, double& peak, int& nbSamples) { m_basebandSink->getMagSqLevels(avg, peak, nbSamples); } void getMagSqLevels(double& avg, double& peak, int& nbSamples) { m_basebandSink->getMagSqLevels(avg, peak, nbSamples); }
void propagateMessageQueueToGUI() { m_basebandSink->setMessageQueueToGUI(getMessageQueueToGUI()); } void propagateMessageQueueToGUI() { m_basebandSink->setMessageQueueToGUI(getMessageQueueToGUI()); }
int getAudioSampleRate() const { return m_basebandSink->getAudioSampleRate(); }
uint32_t getNumberOfDeviceStreams() const; uint32_t getNumberOfDeviceStreams() const;

View File

@ -144,14 +144,15 @@ void NFMDemodBaseband::applySettings(const NFMDemodSettings& settings, bool forc
AudioDeviceManager *audioDeviceManager = DSPEngine::instance()->getAudioDeviceManager(); AudioDeviceManager *audioDeviceManager = DSPEngine::instance()->getAudioDeviceManager();
int audioDeviceIndex = audioDeviceManager->getOutputDeviceIndex(settings.m_audioDeviceName); int audioDeviceIndex = audioDeviceManager->getOutputDeviceIndex(settings.m_audioDeviceName);
//qDebug("AMDemod::applySettings: audioDeviceName: %s audioDeviceIndex: %d", qPrintable(settings.m_audioDeviceName), audioDeviceIndex); //qDebug("AMDemod::applySettings: audioDeviceName: %s audioDeviceIndex: %d", qPrintable(settings.m_audioDeviceName), audioDeviceIndex);
audioDeviceManager->removeAudioSink(m_sink.getAudioFifo());
audioDeviceManager->addAudioSink(m_sink.getAudioFifo(), getInputMessageQueue(), audioDeviceIndex); audioDeviceManager->addAudioSink(m_sink.getAudioFifo(), getInputMessageQueue(), audioDeviceIndex);
uint32_t audioSampleRate = audioDeviceManager->getOutputSampleRate(audioDeviceIndex); int audioSampleRate = audioDeviceManager->getOutputSampleRate(audioDeviceIndex);
if (m_sink.getAudioSampleRate() != audioSampleRate) if (m_sink.getAudioSampleRate() != audioSampleRate)
{ {
m_sink.applyAudioSampleRate(audioSampleRate);
m_channelizer->setChannelization(audioSampleRate, settings.m_inputFrequencyOffset); m_channelizer->setChannelization(audioSampleRate, settings.m_inputFrequencyOffset);
m_sink.applyChannelSettings(m_channelizer->getChannelSampleRate(), m_channelizer->getChannelFrequencyOffset()); m_sink.applyChannelSettings(m_channelizer->getChannelSampleRate(), m_channelizer->getChannelFrequencyOffset());
m_sink.applyAudioSampleRate(audioSampleRate);
} }
} }

View File

@ -67,7 +67,7 @@ public:
bool getSquelchOpen() const { return m_sink.getSquelchOpen(); } bool getSquelchOpen() const { return m_sink.getSquelchOpen(); }
const Real *getCtcssToneSet(int& nbTones) const { return m_sink.getCtcssToneSet(nbTones); } const Real *getCtcssToneSet(int& nbTones) const { return m_sink.getCtcssToneSet(nbTones); }
void setMessageQueueToGUI(MessageQueue *messageQueue) { m_sink.setMessageQueueToGUI(messageQueue); } void setMessageQueueToGUI(MessageQueue *messageQueue) { m_sink.setMessageQueueToGUI(messageQueue); }
unsigned int getAudioSampleRate() const { return m_sink.getAudioSampleRate(); } int getAudioSampleRate() const { return m_sink.getAudioSampleRate(); }
void setBasebandSampleRate(int sampleRate); void setBasebandSampleRate(int sampleRate);
private: private:

View File

@ -283,6 +283,7 @@ NFMDemodGUI::NFMDemodGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, Baseban
m_basicSettingsShown(false), m_basicSettingsShown(false),
m_doApplySettings(true), m_doApplySettings(true),
m_squelchOpen(false), m_squelchOpen(false),
m_audioSampleRate(-1),
m_tickCount(0) m_tickCount(0)
{ {
ui->setupUi(this); ui->setupUi(this);
@ -490,16 +491,20 @@ void NFMDemodGUI::tick()
ui->channelPower->setText(tr("%1 dB").arg(powDbAvg, 0, 'f', 1)); ui->channelPower->setText(tr("%1 dB").arg(powDbAvg, 0, 'f', 1));
} }
int audioSampleRate = m_nfmDemod->getAudioSampleRate();
bool squelchOpen = m_nfmDemod->getSquelchOpen(); bool squelchOpen = m_nfmDemod->getSquelchOpen();
if (squelchOpen != m_squelchOpen) if ((audioSampleRate != m_audioSampleRate) || (squelchOpen != m_squelchOpen))
{ {
if (squelchOpen) { if (audioSampleRate < 0) {
ui->audioMute->setStyleSheet("QToolButton { background-color : red; }");
} else if (squelchOpen) {
ui->audioMute->setStyleSheet("QToolButton { background-color : green; }"); ui->audioMute->setStyleSheet("QToolButton { background-color : green; }");
} else { } else {
ui->audioMute->setStyleSheet("QToolButton { background:rgb(79,79,79); }"); ui->audioMute->setStyleSheet("QToolButton { background:rgb(79,79,79); }");
} }
m_audioSampleRate = audioSampleRate;
m_squelchOpen = squelchOpen; m_squelchOpen = squelchOpen;
} }

View File

@ -53,6 +53,7 @@ private:
NFMDemod* m_nfmDemod; NFMDemod* m_nfmDemod;
bool m_squelchOpen; bool m_squelchOpen;
int m_audioSampleRate;
uint32_t m_tickCount; uint32_t m_tickCount;
MessageQueue m_inputMessageQueue; MessageQueue m_inputMessageQueue;

View File

@ -358,6 +358,12 @@ void NFMDemodSink::applySettings(const NFMDemodSettings& settings, bool force)
void NFMDemodSink::applyAudioSampleRate(unsigned int sampleRate) void NFMDemodSink::applyAudioSampleRate(unsigned int sampleRate)
{ {
if (sampleRate < 0)
{
qWarning("NFMDemodSink::applyAudioSampleRate: invalid sample rate: %d", sampleRate);
return;
}
qDebug("NFMDemodSink::applyAudioSampleRate: %u m_channelSampleRate: %d", sampleRate, m_channelSampleRate); qDebug("NFMDemodSink::applyAudioSampleRate: %u m_channelSampleRate: %d", sampleRate, m_channelSampleRate);
m_ctcssLowpass.create(301, sampleRate, 250.0); m_ctcssLowpass.create(301, sampleRate, 250.0);

View File

@ -77,7 +77,7 @@ public:
AudioFifo *getAudioFifo() { return &m_audioFifo; } AudioFifo *getAudioFifo() { return &m_audioFifo; }
void applyAudioSampleRate(unsigned int sampleRate); void applyAudioSampleRate(unsigned int sampleRate);
unsigned int getAudioSampleRate() const { return m_audioSampleRate; } int getAudioSampleRate() const { return m_audioSampleRate; }
private: private:
struct MagSqLevelsStore struct MagSqLevelsStore
@ -99,7 +99,7 @@ private:
int m_channelFrequencyOffset; int m_channelFrequencyOffset;
NFMDemodSettings m_settings; NFMDemodSettings m_settings;
quint32 m_audioSampleRate; int m_audioSampleRate;
AudioVector m_audioBuffer; AudioVector m_audioBuffer;
uint m_audioBufferFill; uint m_audioBufferFill;
AudioFifo m_audioFifo; AudioFifo m_audioFifo;

View File

@ -88,6 +88,7 @@ public:
double getMagSq() const { return m_basebandSink->getMagSq(); } double getMagSq() const { return m_basebandSink->getMagSq(); }
bool getSquelchOpen() const { return m_basebandSink->getSquelchOpen(); } bool getSquelchOpen() const { return m_basebandSink->getSquelchOpen(); }
int getAudioSampleRate() const { return m_basebandSink->getAudioSampleRate(); }
void getMagSqLevels(double& avg, double& peak, int& nbSamples) { m_basebandSink->getMagSqLevels(avg, peak, nbSamples); } void getMagSqLevels(double& avg, double& peak, int& nbSamples) { m_basebandSink->getMagSqLevels(avg, peak, nbSamples); }

View File

@ -145,8 +145,9 @@ void WFMDemodBaseband::applySettings(const WFMDemodSettings& settings, bool forc
AudioDeviceManager *audioDeviceManager = DSPEngine::instance()->getAudioDeviceManager(); AudioDeviceManager *audioDeviceManager = DSPEngine::instance()->getAudioDeviceManager();
int audioDeviceIndex = audioDeviceManager->getOutputDeviceIndex(settings.m_audioDeviceName); int audioDeviceIndex = audioDeviceManager->getOutputDeviceIndex(settings.m_audioDeviceName);
//qDebug("AMDemod::applySettings: audioDeviceName: %s audioDeviceIndex: %d", qPrintable(settings.m_audioDeviceName), audioDeviceIndex); //qDebug("AMDemod::applySettings: audioDeviceName: %s audioDeviceIndex: %d", qPrintable(settings.m_audioDeviceName), audioDeviceIndex);
audioDeviceManager->removeAudioSink(m_sink.getAudioFifo());
audioDeviceManager->addAudioSink(m_sink.getAudioFifo(), getInputMessageQueue(), audioDeviceIndex); audioDeviceManager->addAudioSink(m_sink.getAudioFifo(), getInputMessageQueue(), audioDeviceIndex);
uint32_t audioSampleRate = audioDeviceManager->getOutputSampleRate(audioDeviceIndex); int audioSampleRate = audioDeviceManager->getOutputSampleRate(audioDeviceIndex);
if (m_sink.getAudioSampleRate() != audioSampleRate) { if (m_sink.getAudioSampleRate() != audioSampleRate) {
m_sink.applyAudioSampleRate(audioSampleRate); m_sink.applyAudioSampleRate(audioSampleRate);

View File

@ -64,7 +64,7 @@ public:
int getChannelSampleRate() const; int getChannelSampleRate() const;
void setBasebandSampleRate(int sampleRate); void setBasebandSampleRate(int sampleRate);
unsigned int getAudioSampleRate() const { return m_sink.getAudioSampleRate(); } int getAudioSampleRate() const { return m_sink.getAudioSampleRate(); }
double getMagSq() const { return m_sink.getMagSq(); } double getMagSq() const { return m_sink.getMagSq(); }
bool getSquelchOpen() const { return m_sink.getSquelchOpen(); } bool getSquelchOpen() const { return m_sink.getSquelchOpen(); }
int getSquelchState() const { return m_sink.getSquelchState(); } int getSquelchState() const { return m_sink.getSquelchState(); }

View File

@ -218,7 +218,9 @@ WFMDemodGUI::WFMDemodGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, Baseban
m_pluginAPI(pluginAPI), m_pluginAPI(pluginAPI),
m_deviceUISet(deviceUISet), m_deviceUISet(deviceUISet),
m_channelMarker(this), m_channelMarker(this),
m_basicSettingsShown(false) m_basicSettingsShown(false),
m_squelchOpen(false),
m_audioSampleRate(-1)
{ {
ui->setupUi(this); ui->setupUi(this);
setAttribute(Qt::WA_DeleteOnClose, true); setAttribute(Qt::WA_DeleteOnClose, true);
@ -361,16 +363,20 @@ void WFMDemodGUI::tick()
(100.0f + powDbPeak) / 100.0f, (100.0f + powDbPeak) / 100.0f,
nbMagsqSamples); nbMagsqSamples);
int audioSampleRate = m_wfmDemod->getAudioSampleRate();
bool squelchOpen = m_wfmDemod->getSquelchOpen(); bool squelchOpen = m_wfmDemod->getSquelchOpen();
if (squelchOpen != m_squelchOpen) if ((audioSampleRate != m_audioSampleRate) || (squelchOpen != m_squelchOpen))
{ {
if (squelchOpen) { if (audioSampleRate < 0) {
ui->audioMute->setStyleSheet("QToolButton { background-color : red; }");
} else if (squelchOpen) {
ui->audioMute->setStyleSheet("QToolButton { background-color : green; }"); ui->audioMute->setStyleSheet("QToolButton { background-color : green; }");
} else { } else {
ui->audioMute->setStyleSheet("QToolButton { background:rgb(79,79,79); }"); ui->audioMute->setStyleSheet("QToolButton { background:rgb(79,79,79); }");
} }
m_audioSampleRate = audioSampleRate;
m_squelchOpen = squelchOpen; m_squelchOpen = squelchOpen;
} }
} }

View File

@ -49,6 +49,7 @@ private:
bool m_doApplySettings; bool m_doApplySettings;
bool m_audioMute; bool m_audioMute;
bool m_squelchOpen; bool m_squelchOpen;
int m_audioSampleRate;
WFMDemod* m_wfmDemod; WFMDemod* m_wfmDemod;
MessageQueue m_inputMessageQueue; MessageQueue m_inputMessageQueue;

View File

@ -148,8 +148,14 @@ void WFMDemodSink::feed(const SampleVector::const_iterator& begin, const SampleV
m_sampleBuffer.clear(); m_sampleBuffer.clear();
} }
void WFMDemodSink::applyAudioSampleRate(unsigned int sampleRate) void WFMDemodSink::applyAudioSampleRate(int sampleRate)
{ {
if (sampleRate < 0)
{
qWarning("WFMDemodSink::applyAudioSampleRate: invalid sample rate: %d", sampleRate);
return;
}
qDebug("WFMDemodSink::applyAudioSampleRate: %u", sampleRate); qDebug("WFMDemodSink::applyAudioSampleRate: %u", sampleRate);
m_interpolator.create(16, m_channelSampleRate, m_settings.m_afBandwidth); m_interpolator.create(16, m_channelSampleRate, m_settings.m_afBandwidth);

View File

@ -65,8 +65,8 @@ public:
void applySettings(const WFMDemodSettings& settings, bool force = false); void applySettings(const WFMDemodSettings& settings, bool force = false);
AudioFifo *getAudioFifo() { return &m_audioFifo; } AudioFifo *getAudioFifo() { return &m_audioFifo; }
void applyAudioSampleRate(unsigned int sampleRate); void applyAudioSampleRate(int sampleRate);
unsigned int getAudioSampleRate() const { return m_audioSampleRate; } int getAudioSampleRate() const { return m_audioSampleRate; }
private: private:
struct MagSqLevelsStore struct MagSqLevelsStore
@ -88,7 +88,7 @@ private:
int m_channelFrequencyOffset; int m_channelFrequencyOffset;
WFMDemodSettings m_settings; WFMDemodSettings m_settings;
quint32 m_audioSampleRate; int m_audioSampleRate;
NCO m_nco; NCO m_nco;
Interpolator m_interpolator; //!< Interpolator between sample rate sent from DSP engine and requested RF bandwidth (rational) Interpolator m_interpolator; //!< Interpolator between sample rate sent from DSP engine and requested RF bandwidth (rational)