1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2024-11-26 09:48:45 -05:00

Multiple audio support: AM modulator

This commit is contained in:
f4exb 2018-03-29 15:20:38 +02:00
parent e0db2adc6b
commit 2380211533
9 changed files with 92 additions and 30 deletions

View File

@ -1,5 +1,7 @@
project(modam)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(modam_SOURCES
ammod.cpp
ammodgui.cpp

View File

@ -65,11 +65,12 @@ AMMod::AMMod(DeviceSinkAPI *deviceAPI) :
m_magsq = 0.0;
m_toneNco.setFreq(1000.0, m_settings.m_audioSampleRate);
DSPEngine::instance()->getAudioDeviceManager()->addAudioSource(&m_audioFifo, getInputMessageQueue());
m_audioSampleRate = DSPEngine::instance()->getAudioDeviceManager()->getInputSampleRate();
m_toneNco.setFreq(1000.0, m_audioSampleRate);
// CW keyer
m_cwKeyer.setSampleRate(m_settings.m_audioSampleRate);
m_cwKeyer.setSampleRate(m_audioSampleRate);
m_cwKeyer.setWPM(13);
m_cwKeyer.setMode(CWKeyerSettings::CWNone);
@ -139,7 +140,7 @@ void AMMod::pull(Sample& sample)
void AMMod::pullAudio(int nbSamples)
{
// qDebug("AMMod::pullAudio: %d", nbSamples);
unsigned int nbAudioSamples = nbSamples * ((Real) m_settings.m_audioSampleRate / (Real) m_basebandSampleRate);
unsigned int nbAudioSamples = nbSamples * ((Real) m_audioSampleRate / (Real) m_basebandSampleRate);
if (nbAudioSamples > m_audioBuffer.size())
{
@ -335,6 +336,20 @@ bool AMMod::handleMessage(const Message& cmd)
return true;
}
else if (DSPConfigureAudio::match(cmd))
{
DSPConfigureAudio& cfg = (DSPConfigureAudio&) cmd;
uint32_t sampleRate = cfg.getSampleRate();
qDebug() << "AMMod::handleMessage: DSPConfigureAudio:"
<< " sampleRate: " << sampleRate;
if (sampleRate != m_audioSampleRate) {
applyAudioSampleRate(sampleRate);
}
return true;
}
else if (DSPSignalNotification::match(cmd))
{
return true;
@ -380,6 +395,28 @@ void AMMod::seekFileStream(int seekPercentage)
}
}
void AMMod::applyAudioSampleRate(int sampleRate)
{
qDebug("AMMod::applyAudioSampleRate: %d", sampleRate);
MsgConfigureChannelizer* channelConfigMsg = MsgConfigureChannelizer::create(
sampleRate, m_settings.m_inputFrequencyOffset);
m_inputMessageQueue.push(channelConfigMsg);
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_toneNco.setFreq(m_settings.m_toneFrequency, sampleRate);
m_cwKeyer.setSampleRate(sampleRate);
m_settingsMutex.unlock();
m_audioSampleRate = sampleRate;
}
void AMMod::applyChannelSettings(int basebandSampleRate, int outputSampleRate, int inputFrequencyOffset, bool force)
{
qDebug() << "AMMod::applyChannelSettings:"
@ -400,8 +437,8 @@ void AMMod::applyChannelSettings(int basebandSampleRate, int outputSampleRate, i
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);
m_settingsMutex.unlock();
}
@ -419,30 +456,37 @@ void AMMod::applySettings(const AMModSettings& settings, bool force)
<< " m_toneFrequency: " << settings.m_toneFrequency
<< " m_volumeFactor: " << settings.m_volumeFactor
<< " m_audioMute: " << settings.m_channelMute
<< " m_playLoop: " << settings.m_playLoop;
<< " m_playLoop: " << settings.m_playLoop
<< " m_audioDeviceName: " << settings.m_audioDeviceName
<< " force: " << force;
if((settings.m_rfBandwidth != m_settings.m_rfBandwidth) ||
(settings.m_audioSampleRate != m_settings.m_audioSampleRate) || force)
if((settings.m_rfBandwidth != m_settings.m_rfBandwidth) || 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();
}
if ((settings.m_toneFrequency != m_settings.m_toneFrequency) ||
(settings.m_audioSampleRate != m_settings.m_audioSampleRate) || force)
if ((settings.m_toneFrequency != m_settings.m_toneFrequency) || force)
{
m_settingsMutex.lock();
m_toneNco.setFreq(settings.m_toneFrequency, settings.m_audioSampleRate);
m_toneNco.setFreq(settings.m_toneFrequency, m_audioSampleRate);
m_settingsMutex.unlock();
}
if ((settings.m_audioSampleRate != m_settings.m_audioSampleRate) || force)
if ((settings.m_audioDeviceName != m_settings.m_audioDeviceName) || force)
{
m_cwKeyer.setSampleRate(settings.m_audioSampleRate);
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;

View File

@ -276,6 +276,7 @@ private:
int m_outputSampleRate;
int m_inputFrequencyOffset;
AMModSettings m_settings;
quint32 m_audioSampleRate;
NCO m_carrierNco;
NCOF m_toneNco;
@ -309,6 +310,7 @@ private:
static const int m_levelNbSamples;
void applyAudioSampleRate(int sampleRate);
void applyChannelSettings(int basebandSampleRate, int outputSampleRate, int inputFrequencyOffset, bool force = false);
void applySettings(const AMModSettings& settings, bool force = false);
void pullAF(Real& sample);

View File

@ -31,6 +31,8 @@
#include "util/simpleserializer.h"
#include "util/db.h"
#include "dsp/dspengine.h"
#include "gui/crightclickenabler.h"
#include "gui/audioselectdialog.h"
#include "mainwindow.h"
AMModGUI* AMModGUI::create(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSource *channelTx)
@ -282,6 +284,9 @@ AMModGUI::AMModGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSampl
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);
@ -391,6 +396,19 @@ void AMModGUI::enterEvent(QEvent*)
m_channelMarker.setHighlighted(true);
}
void AMModGUI::audioSelect()
{
qDebug("AMModGUI::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 AMModGUI::tick()
{
double powDb = CalcDb::dbPower(m_amMod->getMagSq());

View File

@ -110,6 +110,7 @@ private slots:
void onWidgetRolled(QWidget* widget, bool rollDown);
void configureFileName();
void audioSelect();
void tick();
};

View File

@ -56,16 +56,7 @@
<property name="spacing">
<number>3</number>
</property>
<property name="leftMargin">
<number>2</number>
</property>
<property name="topMargin">
<number>2</number>
</property>
<property name="rightMargin">
<number>2</number>
</property>
<property name="bottomMargin">
<property name="margin">
<number>2</number>
</property>
<item>
@ -449,7 +440,7 @@
<item>
<widget class="ButtonSwitch" name="mic">
<property name="toolTip">
<string>Audio input</string>
<string>Left: Source audio input Right: Select audio input device</string>
</property>
<property name="text">
<string>...</string>

View File

@ -34,12 +34,12 @@ void AMModSettings::resetToDefaults()
m_rfBandwidth = 12500.0;
m_modFactor = 0.2f;
m_toneFrequency = 1000.0f;
m_audioSampleRate = DSPEngine::instance()->getDefaultAudioSampleRate();
m_volumeFactor = 1.0f;
m_channelMute = false;
m_playLoop = false;
m_rgbColor = QColor(255, 255, 0).rgb();
m_title = "AM Modulator";
m_audioDeviceName = AudioDeviceManager::m_defaultDeviceName;
}
QByteArray AMModSettings::serialize() const
@ -62,6 +62,7 @@ QByteArray AMModSettings::serialize() const
}
s.writeString(9, m_title);
s.writeString(10, m_audioDeviceName);
return s.final();
}
@ -100,6 +101,7 @@ bool AMModSettings::deserialize(const QByteArray& data)
}
d.readString(9, &m_title, "AM Modulator");
d.readString(10, &m_audioDeviceName, AudioDeviceManager::m_defaultDeviceName);
return true;
}

View File

@ -28,11 +28,11 @@ struct AMModSettings
float m_modFactor;
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;

View File

@ -56,9 +56,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>9.4: Audio input select</h4>
<h4>9.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>10: CW (Morse) text</h3>