mirror of
https://github.com/f4exb/sdrangel.git
synced 2025-05-23 18:52:28 -04:00
Multiple audio support: WFM modulator
This commit is contained in:
parent
d2a658d8a1
commit
75201ad303
@ -1,5 +1,7 @@
|
||||
project(modwfm)
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
|
||||
|
||||
set(modwfm_SOURCES
|
||||
wfmmod.cpp
|
||||
wfmmodgui.cpp
|
||||
|
@ -60,9 +60,11 @@ Switches to the Morse keyer input. You must switch it off to make other inputs a
|
||||
|
||||
Adjusts the tone frequency from 0.1 to 2.5 kHz in 0.01 kHz steps
|
||||
|
||||
<h4>10.4: Audio input select</h4>
|
||||
<h4>10.4: Audio input select and select audio input device</h4>
|
||||
|
||||
Switches to the audio input. You must switch it off to make other inputs available.
|
||||
Left click to switch to the audio input. You must switch it off to make other inputs available.
|
||||
|
||||
Right click to select audio input device.
|
||||
|
||||
<h3>11: CW (Morse) text</h3>
|
||||
|
||||
|
@ -73,9 +73,10 @@ WFMMod::WFMMod(DeviceSinkAPI *deviceAPI) :
|
||||
|
||||
m_magsq = 0.0;
|
||||
|
||||
m_toneNco.setFreq(1000.0, m_settings.m_audioSampleRate);
|
||||
m_toneNcoRF.setFreq(1000.0, m_outputSampleRate);
|
||||
DSPEngine::instance()->getAudioDeviceManager()->addAudioSource(&m_audioFifo, getInputMessageQueue());
|
||||
m_audioSampleRate = DSPEngine::instance()->getAudioDeviceManager()->getInputSampleRate();
|
||||
|
||||
m_toneNcoRF.setFreq(1000.0, m_outputSampleRate);
|
||||
|
||||
// CW keyer
|
||||
m_cwKeyer.setSampleRate(m_outputSampleRate);
|
||||
@ -164,7 +165,7 @@ void WFMMod::pull(Sample& sample)
|
||||
|
||||
void WFMMod::pullAudio(int nbSamples)
|
||||
{
|
||||
unsigned int nbSamplesAudio = nbSamples * ((Real) m_settings.m_audioSampleRate / (Real) m_basebandSampleRate);
|
||||
unsigned int nbSamplesAudio = nbSamples * ((Real) m_audioSampleRate / (Real) m_basebandSampleRate);
|
||||
|
||||
if (nbSamplesAudio > m_audioBuffer.size())
|
||||
{
|
||||
@ -359,6 +360,20 @@ bool WFMMod::handleMessage(const Message& cmd)
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (DSPConfigureAudio::match(cmd))
|
||||
{
|
||||
DSPConfigureAudio& cfg = (DSPConfigureAudio&) cmd;
|
||||
uint32_t sampleRate = cfg.getSampleRate();
|
||||
|
||||
qDebug() << "WFMMod::handleMessage: DSPConfigureAudio:"
|
||||
<< " sampleRate: " << sampleRate;
|
||||
|
||||
if (sampleRate != m_audioSampleRate) {
|
||||
applyAudioSampleRate(sampleRate);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (DSPSignalNotification::match(cmd))
|
||||
{
|
||||
return true;
|
||||
@ -404,6 +419,20 @@ void WFMMod::seekFileStream(int seekPercentage)
|
||||
}
|
||||
}
|
||||
|
||||
void WFMMod::applyAudioSampleRate(int sampleRate)
|
||||
{
|
||||
qDebug("WFMMod::applyAudioSampleRate: %d", sampleRate);
|
||||
|
||||
m_settingsMutex.lock();
|
||||
m_interpolatorDistanceRemain = 0;
|
||||
m_interpolatorConsumed = false;
|
||||
m_interpolatorDistance = (Real) sampleRate / (Real) m_outputSampleRate;
|
||||
m_interpolator.create(48, sampleRate, m_settings.m_rfBandwidth / 2.2, 3.0);
|
||||
m_settingsMutex.unlock();
|
||||
|
||||
m_audioSampleRate = sampleRate;
|
||||
}
|
||||
|
||||
void WFMMod::applyChannelSettings(int basebandSampleRate, int outputSampleRate, int inputFrequencyOffset, bool force)
|
||||
{
|
||||
qDebug() << "WFMMod::applyChannelSettings:"
|
||||
@ -424,8 +453,8 @@ void WFMMod::applyChannelSettings(int basebandSampleRate, int outputSampleRate,
|
||||
m_settingsMutex.lock();
|
||||
m_interpolatorDistanceRemain = 0;
|
||||
m_interpolatorConsumed = false;
|
||||
m_interpolatorDistance = (Real) m_settings.m_audioSampleRate / (Real) outputSampleRate;
|
||||
m_interpolator.create(48, m_settings.m_audioSampleRate, m_settings.m_rfBandwidth / 2.2, 3.0);
|
||||
m_interpolatorDistance = (Real) m_audioSampleRate / (Real) outputSampleRate;
|
||||
m_interpolator.create(48, m_audioSampleRate, m_settings.m_rfBandwidth / 2.2, 3.0);
|
||||
Real lowCut = -(m_settings.m_rfBandwidth / 2.0) / outputSampleRate;
|
||||
Real hiCut = (m_settings.m_rfBandwidth / 2.0) / outputSampleRate;
|
||||
m_rfFilter->create_filter(lowCut, hiCut);
|
||||
@ -451,16 +480,16 @@ void WFMMod::applySettings(const WFMModSettings& settings, bool force)
|
||||
<< " m_toneFrequency: " << settings.m_toneFrequency
|
||||
<< " m_channelMute: " << settings.m_channelMute
|
||||
<< " m_playLoop: " << settings.m_playLoop
|
||||
<< " m_audioDeviceName: " << settings.m_audioDeviceName
|
||||
<< " force: " << force;
|
||||
|
||||
if((settings.m_audioSampleRate != m_settings.m_audioSampleRate) ||
|
||||
(settings.m_afBandwidth != m_settings.m_afBandwidth) || force)
|
||||
if((settings.m_afBandwidth != m_settings.m_afBandwidth) || force)
|
||||
{
|
||||
m_settingsMutex.lock();
|
||||
m_interpolatorDistanceRemain = 0;
|
||||
m_interpolatorConsumed = false;
|
||||
m_interpolatorDistance = (Real) settings.m_audioSampleRate / (Real) m_outputSampleRate;
|
||||
m_interpolator.create(48, settings.m_audioSampleRate, settings.m_rfBandwidth / 2.2, 3.0);
|
||||
m_interpolatorDistance = (Real) m_audioSampleRate / (Real) m_outputSampleRate;
|
||||
m_interpolator.create(48, m_audioSampleRate, settings.m_rfBandwidth / 2.2, 3.0);
|
||||
m_settingsMutex.unlock();
|
||||
}
|
||||
|
||||
@ -480,6 +509,18 @@ void WFMMod::applySettings(const WFMModSettings& settings, bool force)
|
||||
m_settingsMutex.unlock();
|
||||
}
|
||||
|
||||
if ((settings.m_audioDeviceName != m_settings.m_audioDeviceName) || force)
|
||||
{
|
||||
AudioDeviceManager *audioDeviceManager = DSPEngine::instance()->getAudioDeviceManager();
|
||||
int audioDeviceIndex = audioDeviceManager->getInputDeviceIndex(settings.m_audioDeviceName);
|
||||
audioDeviceManager->addAudioSource(&m_audioFifo, getInputMessageQueue(), audioDeviceIndex);
|
||||
uint32_t audioSampleRate = audioDeviceManager->getInputSampleRate(audioDeviceIndex);
|
||||
|
||||
if (m_audioSampleRate != audioSampleRate) {
|
||||
applyAudioSampleRate(audioSampleRate);
|
||||
}
|
||||
}
|
||||
|
||||
m_settings = settings;
|
||||
}
|
||||
|
||||
|
@ -277,9 +277,9 @@ private:
|
||||
int m_outputSampleRate;
|
||||
int m_inputFrequencyOffset;
|
||||
WFMModSettings m_settings;
|
||||
quint32 m_audioSampleRate;
|
||||
|
||||
NCO m_carrierNco;
|
||||
NCOF m_toneNco;
|
||||
NCOF m_toneNcoRF;
|
||||
float m_modPhasor; //!< baseband modulator phasor
|
||||
Complex m_modSample;
|
||||
@ -316,6 +316,7 @@ private:
|
||||
CWKeyer m_cwKeyer;
|
||||
static const int m_levelNbSamples;
|
||||
|
||||
void applyAudioSampleRate(int sampleRate);
|
||||
void applyChannelSettings(int basebandSampleRate, int outputSampleRate, int inputFrequencyOffset, bool force = false);
|
||||
void applySettings(const WFMModSettings& settings, bool force = false);
|
||||
void pullAF(Complex& sample);
|
||||
|
@ -28,6 +28,8 @@
|
||||
#include "util/simpleserializer.h"
|
||||
#include "util/db.h"
|
||||
#include "dsp/dspengine.h"
|
||||
#include "gui/crightclickenabler.h"
|
||||
#include "gui/audioselectdialog.h"
|
||||
#include "mainwindow.h"
|
||||
|
||||
#include "ui_wfmmodgui.h"
|
||||
@ -299,6 +301,9 @@ WFMModGUI::WFMModGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSam
|
||||
|
||||
connect(&MainWindow::getInstance()->getMasterTimer(), SIGNAL(timeout()), this, SLOT(tick()));
|
||||
|
||||
CRightClickEnabler *audioMuteRightClickEnabler = new CRightClickEnabler(ui->mic);
|
||||
connect(audioMuteRightClickEnabler, SIGNAL(rightClick()), this, SLOT(audioSelect()));
|
||||
|
||||
ui->deltaFrequencyLabel->setText(QString("%1f").arg(QChar(0x94, 0x03)));
|
||||
ui->deltaFrequency->setColorMapper(ColorMapper(ColorMapper::GrayGold));
|
||||
ui->deltaFrequency->setValueRange(false, 7, -9999999, 9999999);
|
||||
@ -411,6 +416,19 @@ void WFMModGUI::enterEvent(QEvent*)
|
||||
m_channelMarker.setHighlighted(true);
|
||||
}
|
||||
|
||||
void WFMModGUI::audioSelect()
|
||||
{
|
||||
qDebug("WFMModGUI::audioSelect");
|
||||
AudioSelectDialog audioSelect(DSPEngine::instance()->getAudioDeviceManager(), m_settings.m_audioDeviceName, true); // true for input
|
||||
audioSelect.exec();
|
||||
|
||||
if (audioSelect.m_selected)
|
||||
{
|
||||
m_settings.m_audioDeviceName = audioSelect.m_audioDeviceName;
|
||||
applySettings();
|
||||
}
|
||||
}
|
||||
|
||||
void WFMModGUI::tick()
|
||||
{
|
||||
double powDb = CalcDb::dbPower(m_wfmMod->getMagSq());
|
||||
|
@ -122,6 +122,7 @@ private slots:
|
||||
void onWidgetRolled(QWidget* widget, bool rollDown);
|
||||
|
||||
void configureFileName();
|
||||
void audioSelect();
|
||||
void tick();
|
||||
};
|
||||
|
||||
|
@ -42,12 +42,12 @@ void WFMModSettings::resetToDefaults()
|
||||
m_afBandwidth = 15000.0f;
|
||||
m_fmDeviation = 50000.0f;
|
||||
m_toneFrequency = 1000.0f;
|
||||
m_audioSampleRate = DSPEngine::instance()->getDefaultAudioSampleRate();
|
||||
m_volumeFactor = 1.0f;
|
||||
m_channelMute = false;
|
||||
m_playLoop = false;
|
||||
m_rgbColor = QColor(0, 0, 255).rgb();
|
||||
m_title = "WFM Modulator";
|
||||
m_audioDeviceName = AudioDeviceManager::m_defaultDeviceName;
|
||||
}
|
||||
|
||||
QByteArray WFMModSettings::serialize() const
|
||||
@ -71,6 +71,7 @@ QByteArray WFMModSettings::serialize() const
|
||||
}
|
||||
|
||||
s.writeString(10, m_title);
|
||||
s.writeString(11, m_audioDeviceName);
|
||||
|
||||
return s.final();
|
||||
}
|
||||
@ -110,6 +111,7 @@ bool WFMModSettings::deserialize(const QByteArray& data)
|
||||
}
|
||||
|
||||
d.readString(10, &m_title, "WFM Modulator");
|
||||
d.readString(11, &m_audioDeviceName, AudioDeviceManager::m_defaultDeviceName);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -32,11 +32,11 @@ struct WFMModSettings
|
||||
float m_fmDeviation;
|
||||
float m_toneFrequency;
|
||||
float m_volumeFactor;
|
||||
quint32 m_audioSampleRate;
|
||||
bool m_channelMute;
|
||||
bool m_playLoop;
|
||||
quint32 m_rgbColor;
|
||||
QString m_title;
|
||||
QString m_audioDeviceName;
|
||||
|
||||
Serializable *m_channelMarker;
|
||||
Serializable *m_cwKeyerGUI;
|
||||
|
Loading…
x
Reference in New Issue
Block a user