1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2024-09-27 15:26:33 -04:00

Tx plugins fixes and further refactoring around MsgConfigureChannelizer and audio

This commit is contained in:
f4exb 2019-11-21 00:40:55 +01:00
parent b135a9582b
commit c3e3044b98
38 changed files with 264 additions and 845 deletions

View File

@ -24,7 +24,6 @@
#include "filesourcebaseband.h"
MESSAGE_CLASS_DEFINITION(FileSourceBaseband::MsgConfigureFileSourceBaseband, Message)
MESSAGE_CLASS_DEFINITION(FileSourceBaseband::MsgConfigureChannelizer, Message)
MESSAGE_CLASS_DEFINITION(FileSourceBaseband::MsgConfigureFileSourceName, Message)
MESSAGE_CLASS_DEFINITION(FileSourceBaseband::MsgConfigureFileSourceWork, Message)
MESSAGE_CLASS_DEFINITION(FileSourceBaseband::MsgConfigureFileSourceSeek, Message)
@ -147,20 +146,6 @@ bool FileSourceBaseband::handleMessage(const Message& cmd)
return true;
}
else if (MsgConfigureChannelizer::match(cmd))
{
QMutexLocker mutexLocker(&m_mutex);
MsgConfigureChannelizer& cfg = (MsgConfigureChannelizer&) cmd;
m_settings.m_log2Interp = cfg.getLog2Interp();
m_settings.m_filterChainHash = cfg.getFilterChainHash();
qDebug() << "FileSourceBaseband::handleMessage: MsgConfigureChannelizer:"
<< " log2Interp: " << m_settings.m_log2Interp
<< " filterChainHash: " << m_settings.m_filterChainHash;
m_channelizer->setInterpolation(m_settings.m_log2Interp, m_settings.m_filterChainHash);
return true;
}
else if (DSPSignalNotification::match(cmd))
{
QMutexLocker mutexLocker(&m_mutex);

View File

@ -56,28 +56,6 @@ public:
{ }
};
class MsgConfigureChannelizer : public Message {
MESSAGE_CLASS_DECLARATION
public:
int getLog2Interp() const { return m_log2Interp; }
int getFilterChainHash() const { return m_filterChainHash; }
static MsgConfigureChannelizer* create(unsigned int m_log2Interp, unsigned int m_filterChainHash) {
return new MsgConfigureChannelizer(m_log2Interp, m_filterChainHash);
}
private:
unsigned int m_log2Interp;
unsigned int m_filterChainHash;
MsgConfigureChannelizer(unsigned int log2Interp, unsigned int filterChainHash) :
Message(),
m_log2Interp(log2Interp),
m_filterChainHash(filterChainHash)
{ }
};
class MsgConfigureFileSourceName : public Message {
MESSAGE_CLASS_DECLARATION

View File

@ -257,7 +257,6 @@ void LocalSource::applySettings(const LocalSourceSettings& settings, bool force)
if ((settings.m_localDeviceIndex != m_settings.m_localDeviceIndex) || force)
{
reverseAPIKeys.append("localDeviceIndex");
calculateFrequencyOffset(settings.m_log2Interp, settings.m_filterChainHash);
propagateSampleRateAndFrequency(settings.m_localDeviceIndex, settings.m_log2Interp);
DeviceSampleSink *deviceSampleSink = getLocalDevice(settings.m_localDeviceIndex);
LocalSourceBaseband::MsgConfigureLocalDeviceSampleSink *msg =
@ -270,11 +269,6 @@ void LocalSource::applySettings(const LocalSourceSettings& settings, bool force)
{
calculateFrequencyOffset(settings.m_log2Interp, settings.m_filterChainHash);
propagateSampleRateAndFrequency(m_settings.m_localDeviceIndex, settings.m_log2Interp);
LocalSourceBaseband::MsgConfigureChannelizer *msg = LocalSourceBaseband::MsgConfigureChannelizer::create(
settings.m_log2Interp,
settings.m_filterChainHash
);
m_basebandSource->getInputMessageQueue()->push(msg);
}
if ((settings.m_play != m_settings.m_play) || force)

View File

@ -24,7 +24,6 @@
#include "localsourcebaseband.h"
MESSAGE_CLASS_DEFINITION(LocalSourceBaseband::MsgConfigureLocalSourceBaseband, Message)
MESSAGE_CLASS_DEFINITION(LocalSourceBaseband::MsgConfigureChannelizer, Message)
MESSAGE_CLASS_DEFINITION(LocalSourceBaseband::MsgConfigureLocalSourceWork, Message)
MESSAGE_CLASS_DEFINITION(LocalSourceBaseband::MsgBasebandSampleRateNotification, Message)
MESSAGE_CLASS_DEFINITION(LocalSourceBaseband::MsgConfigureLocalDeviceSampleSink, Message)
@ -143,20 +142,6 @@ bool LocalSourceBaseband::handleMessage(const Message& cmd)
return true;
}
else if (MsgConfigureChannelizer::match(cmd))
{
QMutexLocker mutexLocker(&m_mutex);
MsgConfigureChannelizer& cfg = (MsgConfigureChannelizer&) cmd;
m_settings.m_log2Interp = cfg.getLog2Interp();
m_settings.m_filterChainHash = cfg.getFilterChainHash();
qDebug() << "LocalSourceBaseband::handleMessage: MsgConfigureChannelizer:"
<< " log2Interp: " << m_settings.m_log2Interp
<< " filterChainHash: " << m_settings.m_filterChainHash;
m_channelizer->setInterpolation(m_settings.m_log2Interp, m_settings.m_filterChainHash);
return true;
}
else if (MsgBasebandSampleRateNotification::match(cmd))
{
QMutexLocker mutexLocker(&m_mutex);
@ -209,6 +194,12 @@ void LocalSourceBaseband::applySettings(const LocalSourceSettings& settings, boo
<< "m_play:" << settings.m_play
<< " force: " << force;
if ((settings.m_log2Interp != m_settings.m_log2Interp)
|| (settings.m_filterChainHash != m_settings.m_filterChainHash) || force)
{
m_channelizer->setInterpolation(m_settings.m_log2Interp, m_settings.m_filterChainHash);
}
//m_source.applySettings(settings, force);
m_settings = settings;
}

View File

@ -57,28 +57,6 @@ public:
{ }
};
class MsgConfigureChannelizer : public Message {
MESSAGE_CLASS_DECLARATION
public:
int getLog2Interp() const { return m_log2Interp; }
int getFilterChainHash() const { return m_filterChainHash; }
static MsgConfigureChannelizer* create(unsigned int m_log2Interp, unsigned int m_filterChainHash) {
return new MsgConfigureChannelizer(m_log2Interp, m_filterChainHash);
}
private:
unsigned int m_log2Interp;
unsigned int m_filterChainHash;
MsgConfigureChannelizer(unsigned int log2Interp, unsigned int filterChainHash) :
Message(),
m_log2Interp(log2Interp),
m_filterChainHash(filterChainHash)
{ }
};
class MsgConfigureLocalSourceWork : public Message {
MESSAGE_CLASS_DECLARATION

View File

@ -41,7 +41,6 @@
#include "ammod.h"
MESSAGE_CLASS_DEFINITION(AMMod::MsgConfigureAMMod, Message)
MESSAGE_CLASS_DEFINITION(AMMod::MsgConfigureChannelizer, Message)
MESSAGE_CLASS_DEFINITION(AMMod::MsgConfigureFileSourceName, Message)
MESSAGE_CLASS_DEFINITION(AMMod::MsgConfigureFileSourceSeek, Message)
MESSAGE_CLASS_DEFINITION(AMMod::MsgConfigureFileSourceStreamTiming, Message)
@ -111,20 +110,7 @@ void AMMod::pull(SampleVector::iterator& begin, unsigned int nbSamples)
bool AMMod::handleMessage(const Message& cmd)
{
if (MsgConfigureChannelizer::match(cmd))
{
MsgConfigureChannelizer& cfg = (MsgConfigureChannelizer&) cmd;
qDebug() << "AMMod::handleMessage: MsgConfigureChannelizer:"
<< " getSourceSampleRate: " << cfg.getSourceSampleRate()
<< " getSourceCenterFrequency: " << cfg.getSourceCenterFrequency();
AMModBaseband::MsgConfigureChannelizer *msg
= AMModBaseband::MsgConfigureChannelizer::create(cfg.getSourceSampleRate(), cfg.getSourceCenterFrequency());
m_basebandSource->getInputMessageQueue()->push(msg);
return true;
}
else if (MsgConfigureAMMod::match(cmd))
if (MsgConfigureAMMod::match(cmd))
{
MsgConfigureAMMod& cfg = (MsgConfigureAMMod&) cmd;
qDebug() << "AMMod::handleMessage: MsgConfigureAMMod";
@ -281,37 +267,11 @@ void AMMod::applySettings(const AMModSettings& settings, bool force)
if ((settings.m_toneFrequency != m_settings.m_toneFrequency) || force) {
reverseAPIKeys.append("toneFrequency");
}
if ((settings.m_audioDeviceName != m_settings.m_audioDeviceName) || force)
{
if ((settings.m_audioDeviceName != m_settings.m_audioDeviceName) || force) {
reverseAPIKeys.append("audioDeviceName");
AudioDeviceManager *audioDeviceManager = DSPEngine::instance()->getAudioDeviceManager();
int audioDeviceIndex = audioDeviceManager->getInputDeviceIndex(settings.m_audioDeviceName);
audioDeviceManager->addAudioSource(m_basebandSource->getAudioFifo(), getInputMessageQueue(), audioDeviceIndex);
uint32_t audioSampleRate = audioDeviceManager->getInputSampleRate(audioDeviceIndex);
if (m_basebandSource->getAudioSampleRate() != audioSampleRate)
{
reverseAPIKeys.append("audioSampleRate");
DSPConfigureAudio *msg = new DSPConfigureAudio(audioSampleRate, DSPConfigureAudio::AudioInput);
m_basebandSource->getInputMessageQueue()->push(msg);
}
}
if ((settings.m_feedbackAudioDeviceName != m_settings.m_feedbackAudioDeviceName) || force)
{
if ((settings.m_feedbackAudioDeviceName != m_settings.m_feedbackAudioDeviceName) || force) {
reverseAPIKeys.append("feedbackAudioDeviceName");
AudioDeviceManager *audioDeviceManager = DSPEngine::instance()->getAudioDeviceManager();
int audioDeviceIndex = audioDeviceManager->getOutputDeviceIndex(settings.m_feedbackAudioDeviceName);
audioDeviceManager->addAudioSink(m_basebandSource->getFeedbackAudioFifo(), getInputMessageQueue(), audioDeviceIndex);
uint32_t audioSampleRate = audioDeviceManager->getOutputSampleRate(audioDeviceIndex);
if (m_basebandSource->getFeedbackAudioSampleRate() != audioSampleRate)
{
reverseAPIKeys.append("feedbackAudioSampleRate");
DSPConfigureAudio *msg = new DSPConfigureAudio(audioSampleRate, DSPConfigureAudio::AudioOutput);
m_basebandSource->getInputMessageQueue()->push(msg);
}
}
if (m_settings.m_streamIndex != settings.m_streamIndex)
@ -407,13 +367,6 @@ int AMMod::webapiSettingsPutPatch(
}
}
if (m_settings.m_inputFrequencyOffset != settings.m_inputFrequencyOffset)
{
AMModBaseband::MsgConfigureChannelizer *msgChan = AMModBaseband::MsgConfigureChannelizer::create(
m_basebandSource->getAudioSampleRate(), settings.m_inputFrequencyOffset);
m_inputMessageQueue.push(msgChan);
}
MsgConfigureAMMod *msg = MsgConfigureAMMod::create(settings, force);
m_inputMessageQueue.push(msg);

View File

@ -65,36 +65,6 @@ public:
{ }
};
/**
* |<------ Baseband from device (before device soft interpolation) -------------------------->|
* |<- Channel SR ------->|<- Channel SR ------->|<- Channel SR ------->|<- Channel SR ------->|
* | ^-------------------------------|
* | | Source CF
* | | Source SR |
*/
class MsgConfigureChannelizer : public Message {
MESSAGE_CLASS_DECLARATION
public:
int getSourceSampleRate() const { return m_sourceSampleRate; }
int getSourceCenterFrequency() const { return m_sourceCenterFrequency; }
static MsgConfigureChannelizer* create(int sourceSampleRate, int sourceCenterFrequency)
{
return new MsgConfigureChannelizer(sourceSampleRate, sourceCenterFrequency);
}
private:
int m_sourceSampleRate;
int m_sourceCenterFrequency;
MsgConfigureChannelizer(int sourceSampleRate, int sourceCenterFrequency) :
Message(),
m_sourceSampleRate(sourceSampleRate),
m_sourceCenterFrequency(sourceCenterFrequency)
{ }
};
class MsgConfigureFileSourceName : public Message
{
MESSAGE_CLASS_DECLARATION

View File

@ -24,7 +24,6 @@
#include "ammodbaseband.h"
MESSAGE_CLASS_DEFINITION(AMModBaseband::MsgConfigureAMModBaseband, Message)
MESSAGE_CLASS_DEFINITION(AMModBaseband::MsgConfigureChannelizer, Message)
AMModBaseband::AMModBaseband() :
m_mutex(QMutex::Recursive)
@ -141,33 +140,7 @@ void AMModBaseband::handleInputMessages()
bool AMModBaseband::handleMessage(const Message& cmd)
{
if (DSPConfigureAudio::match(cmd))
{
QMutexLocker mutexLocker(&m_mutex);
DSPConfigureAudio& cfg = (DSPConfigureAudio&) cmd;
uint32_t sampleRate = cfg.getSampleRate();
DSPConfigureAudio::AudioType audioType = cfg.getAudioType();
qDebug() << "AMModBaseband::handleMessage: DSPConfigureAudio:"
<< " sampleRate: " << sampleRate
<< " audioType: " << audioType;
if (audioType == DSPConfigureAudio::AudioInput)
{
if (sampleRate != m_source.getAudioSampleRate()) {
m_source.applyAudioSampleRate(sampleRate);
}
}
else if (audioType == DSPConfigureAudio::AudioOutput)
{
if (sampleRate != m_source.getFeedbackAudioSampleRate()) {
m_source.applyFeedbackAudioSampleRate(sampleRate);
}
}
return true;
}
else if (MsgConfigureAMModBaseband::match(cmd))
if (MsgConfigureAMModBaseband::match(cmd))
{
QMutexLocker mutexLocker(&m_mutex);
MsgConfigureAMModBaseband& cfg = (MsgConfigureAMModBaseband&) cmd;
@ -177,18 +150,6 @@ bool AMModBaseband::handleMessage(const Message& cmd)
return true;
}
else if (MsgConfigureChannelizer::match(cmd))
{
QMutexLocker mutexLocker(&m_mutex);
MsgConfigureChannelizer& cfg = (MsgConfigureChannelizer&) cmd;
qDebug() << "AMModBaseband::handleMessage: MsgConfigureChannelizer"
<< "(requested) sourceSampleRate: " << cfg.getSourceSampleRate()
<< "(requested) sourceCenterFrequency: " << cfg.getSourceCenterFrequency();
m_channelizer->setChannelization(cfg.getSourceSampleRate(), cfg.getSourceCenterFrequency());
m_source.applyChannelSettings(m_channelizer->getChannelSampleRate(), m_channelizer->getChannelFrequencyOffset());
return true;
}
else if (DSPSignalNotification::match(cmd))
{
QMutexLocker mutexLocker(&m_mutex);
@ -219,7 +180,38 @@ bool AMModBaseband::handleMessage(const Message& cmd)
void AMModBaseband::applySettings(const AMModSettings& settings, bool force)
{
if ((m_settings.m_inputFrequencyOffset != settings.m_inputFrequencyOffset) || force)
{
m_channelizer->setChannelization(48000, settings.m_inputFrequencyOffset);
m_source.applyChannelSettings(m_channelizer->getChannelSampleRate(), m_channelizer->getChannelFrequencyOffset());
}
if ((settings.m_audioDeviceName != m_settings.m_audioDeviceName) || force)
{
AudioDeviceManager *audioDeviceManager = DSPEngine::instance()->getAudioDeviceManager();
int audioDeviceIndex = audioDeviceManager->getInputDeviceIndex(settings.m_audioDeviceName);
audioDeviceManager->addAudioSource(getAudioFifo(), getInputMessageQueue(), audioDeviceIndex);
uint32_t audioSampleRate = audioDeviceManager->getInputSampleRate(audioDeviceIndex);
if (getAudioSampleRate() != audioSampleRate) {
m_source.applyAudioSampleRate(audioSampleRate);
}
}
if ((settings.m_feedbackAudioDeviceName != m_settings.m_feedbackAudioDeviceName) || force)
{
AudioDeviceManager *audioDeviceManager = DSPEngine::instance()->getAudioDeviceManager();
int audioDeviceIndex = audioDeviceManager->getOutputDeviceIndex(settings.m_feedbackAudioDeviceName);
audioDeviceManager->addAudioSink(getFeedbackAudioFifo(), getInputMessageQueue(), audioDeviceIndex);
uint32_t audioSampleRate = audioDeviceManager->getOutputSampleRate(audioDeviceIndex);
if (getFeedbackAudioSampleRate() != audioSampleRate) {
m_source.applyFeedbackAudioSampleRate(audioSampleRate);
}
}
m_source.applySettings(settings, force);
m_settings = settings;
}

View File

@ -56,29 +56,6 @@ public:
{ }
};
class MsgConfigureChannelizer : public Message {
MESSAGE_CLASS_DECLARATION
public:
int getSourceSampleRate() const { return m_sourceSampleRate; }
int getSourceCenterFrequency() const { return m_sourceCenterFrequency; }
static MsgConfigureChannelizer* create(int sourceSampleRate, int sourceCenterFrequency)
{
return new MsgConfigureChannelizer(sourceSampleRate, sourceCenterFrequency);
}
private:
int m_sourceSampleRate;
int m_sourceCenterFrequency;
MsgConfigureChannelizer(int sourceSampleRate, int sourceCenterFrequency) :
Message(),
m_sourceSampleRate(sourceSampleRate),
m_sourceCenterFrequency(sourceCenterFrequency)
{ }
};
AMModBaseband();
~AMModBaseband();
void reset();

View File

@ -419,11 +419,6 @@ void AMModGUI::applySettings(bool force)
if (m_doApplySettings)
{
setTitleColor(m_channelMarker.getColor());
AMMod::MsgConfigureChannelizer *msgConfigure = AMMod::MsgConfigureChannelizer::create(
48000, m_channelMarker.getCenterFrequency());
m_amMod->getInputMessageQueue()->push(msgConfigure);
AMMod::MsgConfigureAMMod* message = AMMod::MsgConfigureAMMod::create( m_settings, force);
m_amMod->getInputMessageQueue()->push(message);
}

View File

@ -40,8 +40,8 @@ const int ATVModSource::m_cameraFPSTestNbFrames = 100;
const int ATVModSource::m_ssbFftLen = 1024;
ATVModSource::ATVModSource() :
m_outputSampleRate(1000000),
m_inputFrequencyOffset(0),
m_channelSampleRate(1000000),
m_channelFrequencyOffset(0),
m_modPhasor(0.0f),
m_tvSampleRate(1000000),
m_evenImage(true),
@ -66,18 +66,18 @@ ATVModSource::ATVModSource() :
{
scanCameras();
m_SSBFilter = new fftfilt(0, m_settings.m_rfBandwidth / m_outputSampleRate, m_ssbFftLen);
m_SSBFilter = new fftfilt(0, m_settings.m_rfBandwidth / m_channelSampleRate, m_ssbFftLen);
m_SSBFilterBuffer = new Complex[m_ssbFftLen>>1]; // filter returns data exactly half of its size
memset(m_SSBFilterBuffer, 0, sizeof(Complex)*(m_ssbFftLen>>1));
m_DSBFilter = new fftfilt((2.0f * m_settings.m_rfBandwidth) / m_outputSampleRate, 2 * m_ssbFftLen);
m_DSBFilter = new fftfilt((2.0f * m_settings.m_rfBandwidth) / m_channelSampleRate, 2 * m_ssbFftLen);
m_DSBFilterBuffer = new Complex[m_ssbFftLen];
memset(m_DSBFilterBuffer, 0, sizeof(Complex)*(m_ssbFftLen));
m_interpolatorDistanceRemain = 0.0f;
m_interpolatorDistance = 1.0f;
applyChannelSettings(m_outputSampleRate, m_inputFrequencyOffset, true);
applyChannelSettings(m_channelSampleRate, m_channelFrequencyOffset, true);
applySettings(m_settings, true); // does applyStandard() too;
}
@ -123,7 +123,7 @@ void ATVModSource::pullOne(Sample& sample)
m_settingsMutex.lock();
if ((m_tvSampleRate == m_outputSampleRate) && (!m_settings.m_forceDecimator)) // no interpolation nor decimation
if ((m_tvSampleRate == m_channelSampleRate) && (!m_settings.m_forceDecimator)) // no interpolation nor decimation
{
modulateSample();
pullFinalize(m_modSample, sample);
@ -875,30 +875,30 @@ void ATVModSource::mixImageAndText(cv::Mat& image)
cv::putText(image, m_settings.m_overlayText.toStdString(), textOrg, fontFace, fontScale, cv::Scalar::all(255*m_settings.m_uniformLevel), thickness, CV_AA);
}
void ATVModSource::applyChannelSettings(int outputSampleRate, int inputFrequencyOffset, bool force)
void ATVModSource::applyChannelSettings(int channelSampleRate, int channelFrequencyOffset, bool force)
{
qDebug() << "ATVModSource::applyChannelSettings:"
<< " outputSampleRate: " << outputSampleRate
<< " inputFrequencyOffset: " << inputFrequencyOffset;
<< " channelSampleRate: " << channelSampleRate
<< " channelFrequencyOffset: " << channelFrequencyOffset;
if ((inputFrequencyOffset != m_inputFrequencyOffset) ||
(outputSampleRate != m_outputSampleRate) || force)
if ((channelFrequencyOffset != m_channelFrequencyOffset) ||
(channelSampleRate != m_channelSampleRate) || force)
{
m_settingsMutex.lock();
m_carrierNco.setFreq(inputFrequencyOffset, outputSampleRate);
m_carrierNco.setFreq(channelFrequencyOffset, channelSampleRate);
m_settingsMutex.unlock();
}
if ((outputSampleRate != m_outputSampleRate) || force)
if ((channelSampleRate != m_channelSampleRate) || force)
{
getBaseValues(outputSampleRate, m_settings.m_nbLines * m_settings.m_fps, m_tvSampleRate, m_pointsPerLine);
getBaseValues(channelSampleRate, m_settings.m_nbLines * m_settings.m_fps, m_tvSampleRate, m_pointsPerLine);
m_settingsMutex.lock();
if (m_tvSampleRate > 0)
{
m_interpolatorDistanceRemain = 0;
m_interpolatorDistance = (Real) m_tvSampleRate / (Real) outputSampleRate;
m_interpolatorDistance = (Real) m_tvSampleRate / (Real) channelSampleRate;
m_interpolator.create(32,
m_tvSampleRate,
m_settings.m_rfBandwidth / getRFBandwidthDivisor(m_settings.m_atvModulation),
@ -906,7 +906,7 @@ void ATVModSource::applyChannelSettings(int outputSampleRate, int inputFrequency
}
else
{
m_tvSampleRate = outputSampleRate;
m_tvSampleRate = channelSampleRate;
}
m_SSBFilter->create_filter(0, m_settings.m_rfBandwidth / m_tvSampleRate);
@ -924,8 +924,8 @@ void ATVModSource::applyChannelSettings(int outputSampleRate, int inputFrequency
}
}
m_outputSampleRate = outputSampleRate;
m_inputFrequencyOffset = inputFrequencyOffset;
m_channelSampleRate = channelSampleRate;
m_channelFrequencyOffset = channelFrequencyOffset;
}
void ATVModSource::applySettings(const ATVModSettings& settings, bool force)
@ -958,14 +958,14 @@ void ATVModSource::applySettings(const ATVModSettings& settings, bool force)
|| (settings.m_rfBandwidth != m_settings.m_rfBandwidth)
|| (settings.m_atvModulation != m_settings.m_atvModulation) || force)
{
getBaseValues(m_outputSampleRate, settings.m_nbLines * settings.m_fps, m_tvSampleRate, m_pointsPerLine);
getBaseValues(m_channelSampleRate, settings.m_nbLines * settings.m_fps, m_tvSampleRate, m_pointsPerLine);
m_settingsMutex.lock();
if (m_tvSampleRate > 0)
{
m_interpolatorDistanceRemain = 0;
m_interpolatorDistance = (Real) m_tvSampleRate / (Real) m_outputSampleRate;
m_interpolatorDistance = (Real) m_tvSampleRate / (Real) m_channelSampleRate;
m_interpolator.create(32,
m_tvSampleRate,
settings.m_rfBandwidth / getRFBandwidthDivisor(settings.m_atvModulation),

View File

@ -128,8 +128,8 @@ private:
{}
};
int m_outputSampleRate;
int m_inputFrequencyOffset;
int m_channelSampleRate;
int m_channelFrequencyOffset;
ATVModSettings m_settings;
NCO m_carrierNco;

View File

@ -20,7 +20,14 @@ Use the wheels to adjust the frequency shift in Hz from the center frequency of
The left button can be used to force the rational decimator even when the source and channel sample rates agree. This allows to use the FIR filter of the decimator in any case.
The middle figure is the sample rate in kS/s used in the channel which may differ of the source plugin output sample rate if the rational decimator is engaged. This sample rate is calculated as the closest 10 S/s multiple to the source sample rate to fit an integer number of line points. The number of line points is the full line including synchronization. This number is the sample rate divided by the line frequency. The line frequency is calculated as the nominal number of lines multiplied by the FPS.
The middle figure is the sample rate in kS/s used by the source which may differ from the channel sample rate which is also the baseband sample rate. If they do not agree the rational interpolator is automatically engaged. This sample rate is calculated as the closest 10 S/s multiple to the channel sample rate to fit an integer number of (virtual) line points. The number of line points accounts for the full line including synchronization. This number is the source sample rate divided by the line frequency. The line frequency is calculated as the nominal number of lines multiplied by the FPS.
S = L&times;F&times;n such as B&divide;10 &ge; S&divide;10 > (B&divide;10)&minus;1 where:
- B is the baseband or channel sample rate (they are made the same)
- S is the source sample rate
- L is the number of lines
- F is the number of frames per second
- n is the integer that we call the "number of points"
The right figure is the corresponding number of points and therefore also samples per full line including line synchronization.
@ -39,6 +46,8 @@ The example taken in the screenshot is from a 405 lines &#215; 20 FPS video sign
- 370 points fit in 8100 &#215; 370 = 2997 kS/s
- therefore the closest sample rate is 2997 kS/s for 370 points per line
&#9758; For a proper rendering of the image one should aim at having twice the number of points per line relative to the number of lines. This number may be lowered for closeups needing less details like a portrait scene. The less the number of points the less bandwidth the signal takes so as one would expect there is a balance between spectrum efficiency and image quality.
<h2>4: Channel power</h2>
Average total power in dB relative to a &#177;1.0 amplitude signal generated in the pass band.

View File

@ -40,7 +40,6 @@
#include "freedvmod.h"
MESSAGE_CLASS_DEFINITION(FreeDVMod::MsgConfigureFreeDVMod, Message)
MESSAGE_CLASS_DEFINITION(FreeDVMod::MsgConfigureChannelizer, Message)
MESSAGE_CLASS_DEFINITION(FreeDVMod::MsgConfigureFileSourceName, Message)
MESSAGE_CLASS_DEFINITION(FreeDVMod::MsgConfigureFileSourceSeek, Message)
MESSAGE_CLASS_DEFINITION(FreeDVMod::MsgConfigureFileSourceStreamTiming, Message)
@ -105,20 +104,7 @@ void FreeDVMod::pull(SampleVector::iterator& begin, unsigned int nbSamples)
bool FreeDVMod::handleMessage(const Message& cmd)
{
if (MsgConfigureChannelizer::match(cmd))
{
MsgConfigureChannelizer& cfg = (MsgConfigureChannelizer&) cmd;
qDebug() << "FreeDVMod::handleMessage: MsgConfigureChannelizer:"
<< " getSourceSampleRate: " << cfg.getSourceSampleRate()
<< " getSourceCenterFrequency: " << cfg.getSourceCenterFrequency();
FreeDVModBaseband::MsgConfigureChannelizer *msg
= FreeDVModBaseband::MsgConfigureChannelizer::create(cfg.getSourceSampleRate(), cfg.getSourceCenterFrequency());
m_basebandSource->getInputMessageQueue()->push(msg);
return true;
}
else if (MsgConfigureFreeDVMod::match(cmd))
if (MsgConfigureFreeDVMod::match(cmd))
{
MsgConfigureFreeDVMod& cfg = (MsgConfigureFreeDVMod&) cmd;
qDebug() << "FreeDVMod::handleMessage: MsgConfigureFreeDVMod";
@ -270,20 +256,8 @@ void FreeDVMod::applySettings(const FreeDVModSettings& settings, bool force)
if ((m_settings.m_freeDVMode != settings.m_freeDVMode) || force) {
reverseAPIKeys.append("freeDVMode");
}
if ((settings.m_audioDeviceName != m_settings.m_audioDeviceName) || force)
{
AudioDeviceManager *audioDeviceManager = DSPEngine::instance()->getAudioDeviceManager();
int audioDeviceIndex = audioDeviceManager->getInputDeviceIndex(settings.m_audioDeviceName);
audioDeviceManager->addAudioSource(m_basebandSource->getAudioFifo(), getInputMessageQueue(), audioDeviceIndex);
uint32_t audioSampleRate = audioDeviceManager->getInputSampleRate(audioDeviceIndex);
if (m_basebandSource->getAudioSampleRate() != audioSampleRate)
{
reverseAPIKeys.append("audioSampleRate");
DSPConfigureAudio *msg = new DSPConfigureAudio(audioSampleRate, DSPConfigureAudio::AudioInput);
m_basebandSource->getInputMessageQueue()->push(msg);
}
if ((settings.m_audioDeviceName != m_settings.m_audioDeviceName) || force) {
reverseAPIKeys.append("audioDeviceName");
}
if (m_settings.m_streamIndex != settings.m_streamIndex)
@ -379,13 +353,6 @@ int FreeDVMod::webapiSettingsPutPatch(
}
}
if (m_settings.m_inputFrequencyOffset != settings.m_inputFrequencyOffset)
{
FreeDVMod::MsgConfigureChannelizer *msgChan = FreeDVMod::MsgConfigureChannelizer::create(
m_basebandSource->getAudioSampleRate(), settings.m_inputFrequencyOffset);
m_inputMessageQueue.push(msgChan);
}
MsgConfigureFreeDVMod *msg = MsgConfigureFreeDVMod::create(settings, force);
m_inputMessageQueue.push(msg);

View File

@ -68,36 +68,6 @@ public:
{ }
};
/**
* |<------ Baseband from device (before device soft interpolation) -------------------------->|
* |<- Channel SR ------->|<- Channel SR ------->|<- Channel SR ------->|<- Channel SR ------->|
* | ^-------------------------------|
* | | Source CF
* | | Source SR |
*/
class MsgConfigureChannelizer : public Message {
MESSAGE_CLASS_DECLARATION
public:
int getSourceSampleRate() const { return m_sourceSampleRate; }
int getSourceCenterFrequency() const { return m_sourceCenterFrequency; }
static MsgConfigureChannelizer* create(int sourceSampleRate, int sourceCenterFrequency)
{
return new MsgConfigureChannelizer(sourceSampleRate, sourceCenterFrequency);
}
private:
int m_sourceSampleRate;
int m_sourceCenterFrequency;
MsgConfigureChannelizer(int sourceSampleRate, int sourceCenterFrequency) :
Message(),
m_sourceSampleRate(sourceSampleRate),
m_sourceCenterFrequency(sourceCenterFrequency)
{ }
};
class MsgConfigureFileSourceName : public Message
{
MESSAGE_CLASS_DECLARATION

View File

@ -24,7 +24,6 @@
#include "freedvmodbaseband.h"
MESSAGE_CLASS_DEFINITION(FreeDVModBaseband::MsgConfigureFreeDVModBaseband, Message)
MESSAGE_CLASS_DEFINITION(FreeDVModBaseband::MsgConfigureChannelizer, Message)
FreeDVModBaseband::FreeDVModBaseband() :
m_mutex(QMutex::Recursive)
@ -137,27 +136,7 @@ void FreeDVModBaseband::handleInputMessages()
bool FreeDVModBaseband::handleMessage(const Message& cmd)
{
if (DSPConfigureAudio::match(cmd))
{
QMutexLocker mutexLocker(&m_mutex);
DSPConfigureAudio& cfg = (DSPConfigureAudio&) cmd;
uint32_t sampleRate = cfg.getSampleRate();
DSPConfigureAudio::AudioType audioType = cfg.getAudioType();
qDebug() << "FreeDVModBaseband::handleMessage: DSPConfigureAudio:"
<< " sampleRate: " << sampleRate
<< " audioType: " << audioType;
if (audioType == DSPConfigureAudio::AudioInput)
{
if (sampleRate != m_source.getAudioSampleRate()) {
m_source.applyAudioSampleRate(sampleRate);
}
}
return true;
}
else if (MsgConfigureFreeDVModBaseband::match(cmd))
if (MsgConfigureFreeDVModBaseband::match(cmd))
{
QMutexLocker mutexLocker(&m_mutex);
MsgConfigureFreeDVModBaseband& cfg = (MsgConfigureFreeDVModBaseband&) cmd;
@ -167,18 +146,6 @@ bool FreeDVModBaseband::handleMessage(const Message& cmd)
return true;
}
else if (MsgConfigureChannelizer::match(cmd))
{
QMutexLocker mutexLocker(&m_mutex);
MsgConfigureChannelizer& cfg = (MsgConfigureChannelizer&) cmd;
qDebug() << "FreeDVModBaseband::handleMessage: MsgConfigureChannelizer"
<< "(requested) sourceSampleRate: " << cfg.getSourceSampleRate()
<< "(requested) sourceCenterFrequency: " << cfg.getSourceCenterFrequency();
m_channelizer->setChannelization(cfg.getSourceSampleRate(), cfg.getSourceCenterFrequency());
m_source.applyChannelSettings(m_channelizer->getChannelSampleRate(), m_channelizer->getChannelFrequencyOffset());
return true;
}
else if (DSPSignalNotification::match(cmd))
{
QMutexLocker mutexLocker(&m_mutex);
@ -208,7 +175,34 @@ bool FreeDVModBaseband::handleMessage(const Message& cmd)
void FreeDVModBaseband::applySettings(const FreeDVModSettings& settings, bool force)
{
if ((settings.m_freeDVMode != m_settings.m_freeDVMode) || force)
{
int modemSampleRate = FreeDVModSettings::getModSampleRate(settings.m_freeDVMode);
m_source.applyFreeDVMode(settings.m_freeDVMode);
m_channelizer->setChannelization(modemSampleRate, m_settings.m_inputFrequencyOffset); // use possibly old frequency offset (changed next)
m_source.applyChannelSettings(m_channelizer->getChannelSampleRate(), m_channelizer->getChannelFrequencyOffset());
}
if ((settings.m_inputFrequencyOffset != m_settings.m_inputFrequencyOffset) || force)
{
m_channelizer->setChannelization(m_source.getModemSampleRate(), settings.m_inputFrequencyOffset);
m_source.applyChannelSettings(m_channelizer->getChannelSampleRate(), m_channelizer->getChannelFrequencyOffset());
}
if ((settings.m_audioDeviceName != m_settings.m_audioDeviceName) || force)
{
AudioDeviceManager *audioDeviceManager = DSPEngine::instance()->getAudioDeviceManager();
int audioDeviceIndex = audioDeviceManager->getInputDeviceIndex(settings.m_audioDeviceName);
audioDeviceManager->addAudioSource(getAudioFifo(), getInputMessageQueue(), audioDeviceIndex);
uint32_t audioSampleRate = audioDeviceManager->getInputSampleRate(audioDeviceIndex);
if (getAudioSampleRate() != audioSampleRate) {
m_source.applyAudioSampleRate(audioSampleRate);
}
}
m_source.applySettings(settings, force);
m_settings = settings;
}

View File

@ -56,29 +56,6 @@ public:
{ }
};
class MsgConfigureChannelizer : public Message {
MESSAGE_CLASS_DECLARATION
public:
int getSourceSampleRate() const { return m_sourceSampleRate; }
int getSourceCenterFrequency() const { return m_sourceCenterFrequency; }
static MsgConfigureChannelizer* create(int sourceSampleRate, int sourceCenterFrequency)
{
return new MsgConfigureChannelizer(sourceSampleRate, sourceCenterFrequency);
}
private:
int m_sourceSampleRate;
int m_sourceCenterFrequency;
MsgConfigureChannelizer(int sourceSampleRate, int sourceCenterFrequency) :
Message(),
m_sourceSampleRate(sourceSampleRate),
m_sourceCenterFrequency(sourceCenterFrequency)
{ }
};
FreeDVModBaseband();
~FreeDVModBaseband();
void reset();

View File

@ -434,10 +434,6 @@ void FreeDVModGUI::applySettings(bool force)
{
if (m_doApplySettings)
{
FreeDVMod::MsgConfigureChannelizer *msgChan = FreeDVMod::MsgConfigureChannelizer::create(
48000, m_settings.m_inputFrequencyOffset);
m_freeDVMod->getInputMessageQueue()->push(msgChan);
FreeDVMod::MsgConfigureFreeDVMod *msg = FreeDVMod::MsgConfigureFreeDVMod::create(m_settings, force);
m_freeDVMod->getInputMessageQueue()->push(msg);
}

View File

@ -517,9 +517,5 @@ void FreeDVModSource::applySettings(const FreeDVModSettings& settings, bool forc
m_toneNco.setFreq(settings.m_toneFrequency, m_channelSampleRate);
}
if ((m_settings.m_freeDVMode != settings.m_freeDVMode) || force) {
applyFreeDVMode(settings.m_freeDVMode);
}
m_settings = settings;
}

View File

@ -42,7 +42,6 @@
#include "nfmmod.h"
MESSAGE_CLASS_DEFINITION(NFMMod::MsgConfigureNFMMod, Message)
MESSAGE_CLASS_DEFINITION(NFMMod::MsgConfigureChannelizer, Message)
MESSAGE_CLASS_DEFINITION(NFMMod::MsgConfigureFileSourceName, Message)
MESSAGE_CLASS_DEFINITION(NFMMod::MsgConfigureFileSourceSeek, Message)
MESSAGE_CLASS_DEFINITION(NFMMod::MsgConfigureFileSourceStreamTiming, Message)
@ -107,20 +106,7 @@ void NFMMod::pull(SampleVector::iterator& begin, unsigned int nbSamples)
bool NFMMod::handleMessage(const Message& cmd)
{
if (MsgConfigureChannelizer::match(cmd))
{
MsgConfigureChannelizer& cfg = (MsgConfigureChannelizer&) cmd;
qDebug() << "NFMMod::handleMessage: MsgConfigureChannelizer:"
<< " getSourceSampleRate: " << cfg.getSourceSampleRate()
<< " getSourceCenterFrequency: " << cfg.getSourceCenterFrequency();
NFMModBaseband::MsgConfigureChannelizer *msg
= NFMModBaseband::MsgConfigureChannelizer::create(cfg.getSourceSampleRate(), cfg.getSourceCenterFrequency());
m_basebandSource->getInputMessageQueue()->push(msg);
return true;
}
else if (MsgConfigureNFMMod::match(cmd))
if (MsgConfigureNFMMod::match(cmd))
{
MsgConfigureNFMMod& cfg = (MsgConfigureNFMMod&) cmd;
qDebug() << "NFMMod::handleMessage: MsgConfigureNFMMod";
@ -327,37 +313,11 @@ void NFMMod::applySettings(const NFMModSettings& settings, bool force)
if ((settings.m_ctcssIndex != m_settings.m_ctcssIndex) || force) {
reverseAPIKeys.append("ctcssIndex");
}
if ((settings.m_audioDeviceName != m_settings.m_audioDeviceName) || force)
{
if ((settings.m_audioDeviceName != m_settings.m_audioDeviceName) || force) {
reverseAPIKeys.append("audioDeviceName");
AudioDeviceManager *audioDeviceManager = DSPEngine::instance()->getAudioDeviceManager();
int audioDeviceIndex = audioDeviceManager->getInputDeviceIndex(settings.m_audioDeviceName);
audioDeviceManager->addAudioSource(m_basebandSource->getAudioFifo(), getInputMessageQueue(), audioDeviceIndex);
uint32_t audioSampleRate = audioDeviceManager->getInputSampleRate(audioDeviceIndex);
if (m_basebandSource->getAudioSampleRate() != audioSampleRate)
{
reverseAPIKeys.append("audioSampleRate");
DSPConfigureAudio *msg = new DSPConfigureAudio(audioSampleRate, DSPConfigureAudio::AudioInput);
m_basebandSource->getInputMessageQueue()->push(msg);
}
}
if ((settings.m_feedbackAudioDeviceName != m_settings.m_feedbackAudioDeviceName) || force)
{
if ((settings.m_feedbackAudioDeviceName != m_settings.m_feedbackAudioDeviceName) || force) {
reverseAPIKeys.append("feedbackAudioDeviceName");
AudioDeviceManager *audioDeviceManager = DSPEngine::instance()->getAudioDeviceManager();
int audioDeviceIndex = audioDeviceManager->getOutputDeviceIndex(settings.m_feedbackAudioDeviceName);
audioDeviceManager->addAudioSink(m_basebandSource->getFeedbackAudioFifo(), getInputMessageQueue(), audioDeviceIndex);
uint32_t audioSampleRate = audioDeviceManager->getOutputSampleRate(audioDeviceIndex);
if (m_basebandSource->getFeedbackAudioSampleRate() != audioSampleRate)
{
reverseAPIKeys.append("feedbackAudioSampleRate");
DSPConfigureAudio *msg = new DSPConfigureAudio(audioSampleRate, DSPConfigureAudio::AudioOutput);
m_basebandSource->getInputMessageQueue()->push(msg);
}
}
if (m_settings.m_streamIndex != settings.m_streamIndex)
@ -404,10 +364,6 @@ bool NFMMod::deserialize(const QByteArray& data)
success = false;
}
MsgConfigureChannelizer *msgChan = MsgConfigureChannelizer::create(
48000, m_settings.m_inputFrequencyOffset);
m_inputMessageQueue.push(msgChan);
MsgConfigureNFMMod *msg = MsgConfigureNFMMod::create(m_settings, true);
m_inputMessageQueue.push(msg);
@ -456,13 +412,6 @@ int NFMMod::webapiSettingsPutPatch(
}
}
if (m_settings.m_inputFrequencyOffset != settings.m_inputFrequencyOffset)
{
NFMModBaseband::MsgConfigureChannelizer *msgChan = NFMModBaseband::MsgConfigureChannelizer::create(
m_basebandSource->getAudioSampleRate(), settings.m_inputFrequencyOffset);
m_inputMessageQueue.push(msgChan);
}
MsgConfigureNFMMod *msg = MsgConfigureNFMMod::create(settings, force);
m_inputMessageQueue.push(msg);

View File

@ -65,36 +65,6 @@ public:
{ }
};
/**
* |<------ Baseband from device (before device soft interpolation) -------------------------->|
* |<- Channel SR ------->|<- Channel SR ------->|<- Channel SR ------->|<- Channel SR ------->|
* | ^-------------------------------|
* | | Source CF
* | | Source SR |
*/
class MsgConfigureChannelizer : public Message {
MESSAGE_CLASS_DECLARATION
public:
int getSourceSampleRate() const { return m_sourceSampleRate; }
int getSourceCenterFrequency() const { return m_sourceCenterFrequency; }
static MsgConfigureChannelizer* create(int sourceSampleRate, int sourceCenterFrequency)
{
return new MsgConfigureChannelizer(sourceSampleRate, sourceCenterFrequency);
}
private:
int m_sourceSampleRate;
int m_sourceCenterFrequency;
MsgConfigureChannelizer(int sourceSampleRate, int sourceCenterFrequency) :
Message(),
m_sourceSampleRate(sourceSampleRate),
m_sourceCenterFrequency(sourceCenterFrequency)
{ }
};
class MsgConfigureFileSourceName : public Message
{
MESSAGE_CLASS_DECLARATION

View File

@ -24,7 +24,6 @@
#include "nfmmodbaseband.h"
MESSAGE_CLASS_DEFINITION(NFMModBaseband::MsgConfigureNFMModBaseband, Message)
MESSAGE_CLASS_DEFINITION(NFMModBaseband::MsgConfigureChannelizer, Message)
NFMModBaseband::NFMModBaseband() :
m_mutex(QMutex::Recursive)
@ -141,33 +140,7 @@ void NFMModBaseband::handleInputMessages()
bool NFMModBaseband::handleMessage(const Message& cmd)
{
if (DSPConfigureAudio::match(cmd))
{
QMutexLocker mutexLocker(&m_mutex);
DSPConfigureAudio& cfg = (DSPConfigureAudio&) cmd;
uint32_t sampleRate = cfg.getSampleRate();
DSPConfigureAudio::AudioType audioType = cfg.getAudioType();
qDebug() << "NFMModBaseband::handleMessage: DSPConfigureAudio:"
<< " sampleRate: " << sampleRate
<< " audioType: " << audioType;
if (audioType == DSPConfigureAudio::AudioInput)
{
if (sampleRate != m_source.getAudioSampleRate()) {
m_source.applyAudioSampleRate(sampleRate);
}
}
else if (audioType == DSPConfigureAudio::AudioOutput)
{
if (sampleRate != m_source.getFeedbackAudioSampleRate()) {
m_source.applyFeedbackAudioSampleRate(sampleRate);
}
}
return true;
}
else if (MsgConfigureNFMModBaseband::match(cmd))
if (MsgConfigureNFMModBaseband::match(cmd))
{
QMutexLocker mutexLocker(&m_mutex);
MsgConfigureNFMModBaseband& cfg = (MsgConfigureNFMModBaseband&) cmd;
@ -177,18 +150,6 @@ bool NFMModBaseband::handleMessage(const Message& cmd)
return true;
}
else if (MsgConfigureChannelizer::match(cmd))
{
QMutexLocker mutexLocker(&m_mutex);
MsgConfigureChannelizer& cfg = (MsgConfigureChannelizer&) cmd;
qDebug() << "NFMModBaseband::handleMessage: MsgConfigureChannelizer"
<< "(requested) sourceSampleRate: " << cfg.getSourceSampleRate()
<< "(requested) sourceCenterFrequency: " << cfg.getSourceCenterFrequency();
m_channelizer->setChannelization(cfg.getSourceSampleRate(), cfg.getSourceCenterFrequency());
m_source.applyChannelSettings(m_channelizer->getChannelSampleRate(), m_channelizer->getChannelFrequencyOffset());
return true;
}
else if (DSPSignalNotification::match(cmd))
{
QMutexLocker mutexLocker(&m_mutex);
@ -218,7 +179,38 @@ bool NFMModBaseband::handleMessage(const Message& cmd)
void NFMModBaseband::applySettings(const NFMModSettings& settings, bool force)
{
if ((settings.m_inputFrequencyOffset != m_settings.m_inputFrequencyOffset) || force)
{
m_channelizer->setChannelization(48000, settings.m_inputFrequencyOffset); // Fixed 48000 S/s source sample rate
m_source.applyChannelSettings(m_channelizer->getChannelSampleRate(), m_channelizer->getChannelFrequencyOffset());
}
if ((settings.m_audioDeviceName != m_settings.m_audioDeviceName) || force)
{
AudioDeviceManager *audioDeviceManager = DSPEngine::instance()->getAudioDeviceManager();
int audioDeviceIndex = audioDeviceManager->getInputDeviceIndex(settings.m_audioDeviceName);
audioDeviceManager->addAudioSource(getAudioFifo(), getInputMessageQueue(), audioDeviceIndex);
uint32_t audioSampleRate = audioDeviceManager->getInputSampleRate(audioDeviceIndex);
if (getAudioSampleRate() != audioSampleRate) {
m_source.applyAudioSampleRate(audioSampleRate);
}
}
if ((settings.m_feedbackAudioDeviceName != m_settings.m_feedbackAudioDeviceName) || force)
{
AudioDeviceManager *audioDeviceManager = DSPEngine::instance()->getAudioDeviceManager();
int audioDeviceIndex = audioDeviceManager->getOutputDeviceIndex(settings.m_feedbackAudioDeviceName);
audioDeviceManager->addAudioSink(getFeedbackAudioFifo(), getInputMessageQueue(), audioDeviceIndex);
uint32_t audioSampleRate = audioDeviceManager->getOutputSampleRate(audioDeviceIndex);
if (getFeedbackAudioSampleRate() != audioSampleRate) {
m_source.applyFeedbackAudioSampleRate(audioSampleRate);
}
}
m_source.applySettings(settings, force);
m_settings = settings;
}

View File

@ -56,29 +56,6 @@ public:
{ }
};
class MsgConfigureChannelizer : public Message {
MESSAGE_CLASS_DECLARATION
public:
int getSourceSampleRate() const { return m_sourceSampleRate; }
int getSourceCenterFrequency() const { return m_sourceCenterFrequency; }
static MsgConfigureChannelizer* create(int sourceSampleRate, int sourceCenterFrequency)
{
return new MsgConfigureChannelizer(sourceSampleRate, sourceCenterFrequency);
}
private:
int m_sourceSampleRate;
int m_sourceCenterFrequency;
MsgConfigureChannelizer(int sourceSampleRate, int sourceCenterFrequency) :
Message(),
m_sourceSampleRate(sourceSampleRate),
m_sourceCenterFrequency(sourceCenterFrequency)
{ }
};
NFMModBaseband();
~NFMModBaseband();
void reset();

View File

@ -451,10 +451,6 @@ void NFMModGUI::applySettings(bool force)
{
if (m_doApplySettings)
{
NFMMod::MsgConfigureChannelizer *msgChan = NFMMod::MsgConfigureChannelizer::create(
48000, m_channelMarker.getCenterFrequency());
m_nfmMod->getInputMessageQueue()->push(msgChan);
NFMMod::MsgConfigureNFMMod *msg = NFMMod::MsgConfigureNFMMod::create(m_settings, force);
m_nfmMod->getInputMessageQueue()->push(msg);
}

View File

@ -358,7 +358,7 @@
<string>Audio input gain</string>
</property>
<property name="maximum">
<number>20</number>
<number>50</number>
</property>
<property name="pageStep">
<number>1</number>

View File

@ -41,7 +41,6 @@
#include "ssbmod.h"
MESSAGE_CLASS_DEFINITION(SSBMod::MsgConfigureSSBMod, Message)
MESSAGE_CLASS_DEFINITION(SSBMod::MsgConfigureChannelizer, Message)
MESSAGE_CLASS_DEFINITION(SSBMod::MsgConfigureFileSourceName, Message)
MESSAGE_CLASS_DEFINITION(SSBMod::MsgConfigureFileSourceSeek, Message)
MESSAGE_CLASS_DEFINITION(SSBMod::MsgConfigureFileSourceStreamTiming, Message)
@ -106,20 +105,7 @@ void SSBMod::pull(SampleVector::iterator& begin, unsigned int nbSamples)
bool SSBMod::handleMessage(const Message& cmd)
{
if (MsgConfigureChannelizer::match(cmd))
{
MsgConfigureChannelizer& cfg = (MsgConfigureChannelizer&) cmd;
qDebug() << "SSBMod::handleMessage: MsgConfigureChannelizer:"
<< " getSourceSampleRate: " << cfg.getSourceSampleRate()
<< " getSourceCenterFrequency: " << cfg.getSourceCenterFrequency();
SSBModBaseband::MsgConfigureChannelizer *msg
= SSBModBaseband::MsgConfigureChannelizer::create(cfg.getSourceSampleRate(), cfg.getSourceCenterFrequency());
m_basebandSource->getInputMessageQueue()->push(msg);
return true;
}
else if (MsgConfigureSSBMod::match(cmd))
if (MsgConfigureSSBMod::match(cmd))
{
MsgConfigureSSBMod& cfg = (MsgConfigureSSBMod&) cmd;
qDebug() << "NFMMod::handleMessage: MsgConfigureSSBMod";
@ -284,35 +270,11 @@ void SSBMod::applySettings(const SSBModSettings& settings, bool force)
if ((settings.m_audioDeviceName != m_settings.m_audioDeviceName) || force) {
reverseAPIKeys.append("audioDeviceName");
}
if ((settings.m_audioDeviceName != m_settings.m_audioDeviceName) || force)
{
AudioDeviceManager *audioDeviceManager = DSPEngine::instance()->getAudioDeviceManager();
int audioDeviceIndex = audioDeviceManager->getInputDeviceIndex(settings.m_audioDeviceName);
audioDeviceManager->addAudioSource(m_basebandSource->getAudioFifo(), getInputMessageQueue(), audioDeviceIndex);
uint32_t audioSampleRate = audioDeviceManager->getInputSampleRate(audioDeviceIndex);
if (m_basebandSource->getAudioSampleRate() != audioSampleRate)
{
reverseAPIKeys.append("audioSampleRate");
DSPConfigureAudio *msg = new DSPConfigureAudio(audioSampleRate, DSPConfigureAudio::AudioInput);
m_basebandSource->getInputMessageQueue()->push(msg);
}
if ((settings.m_audioDeviceName != m_settings.m_audioDeviceName) || force) {
reverseAPIKeys.append("audioDeviceName");
}
if ((settings.m_feedbackAudioDeviceName != m_settings.m_feedbackAudioDeviceName) || force)
{
if ((settings.m_feedbackAudioDeviceName != m_settings.m_feedbackAudioDeviceName) || force) {
reverseAPIKeys.append("feedbackAudioDeviceName");
AudioDeviceManager *audioDeviceManager = DSPEngine::instance()->getAudioDeviceManager();
int audioDeviceIndex = audioDeviceManager->getOutputDeviceIndex(settings.m_feedbackAudioDeviceName);
audioDeviceManager->addAudioSink(m_basebandSource->getFeedbackAudioFifo(), getInputMessageQueue(), audioDeviceIndex);
uint32_t audioSampleRate = audioDeviceManager->getOutputSampleRate(audioDeviceIndex);
if (m_basebandSource->getFeedbackAudioSampleRate() != audioSampleRate) {
reverseAPIKeys.append("feedbackAudioSampleRate");
DSPConfigureAudio *msg = new DSPConfigureAudio(audioSampleRate, DSPConfigureAudio::AudioOutput);
m_basebandSource->getInputMessageQueue()->push(msg);
}
}
if (m_settings.m_streamIndex != settings.m_streamIndex)
@ -411,13 +373,6 @@ int SSBMod::webapiSettingsPutPatch(
}
}
if (m_settings.m_inputFrequencyOffset != settings.m_inputFrequencyOffset)
{
SSBMod::MsgConfigureChannelizer *msgChan = SSBMod::MsgConfigureChannelizer::create(
m_basebandSource->getAudioSampleRate(), settings.m_inputFrequencyOffset);
m_inputMessageQueue.push(msgChan);
}
MsgConfigureSSBMod *msg = MsgConfigureSSBMod::create(settings, force);
m_inputMessageQueue.push(msg);

View File

@ -66,36 +66,6 @@ public:
{ }
};
/**
* |<------ Baseband from device (before device soft interpolation) -------------------------->|
* |<- Channel SR ------->|<- Channel SR ------->|<- Channel SR ------->|<- Channel SR ------->|
* | ^-------------------------------|
* | | Source CF
* | | Source SR |
*/
class MsgConfigureChannelizer : public Message {
MESSAGE_CLASS_DECLARATION
public:
int getSourceSampleRate() const { return m_sourceSampleRate; }
int getSourceCenterFrequency() const { return m_sourceCenterFrequency; }
static MsgConfigureChannelizer* create(int sourceSampleRate, int sourceCenterFrequency)
{
return new MsgConfigureChannelizer(sourceSampleRate, sourceCenterFrequency);
}
private:
int m_sourceSampleRate;
int m_sourceCenterFrequency;
MsgConfigureChannelizer(int sourceSampleRate, int sourceCenterFrequency) :
Message(),
m_sourceSampleRate(sourceSampleRate),
m_sourceCenterFrequency(sourceCenterFrequency)
{ }
};
class MsgConfigureFileSourceName : public Message
{
MESSAGE_CLASS_DECLARATION

View File

@ -24,7 +24,6 @@
#include "ssbmodbaseband.h"
MESSAGE_CLASS_DEFINITION(SSBModBaseband::MsgConfigureSSBModBaseband, Message)
MESSAGE_CLASS_DEFINITION(SSBModBaseband::MsgConfigureChannelizer, Message)
SSBModBaseband::SSBModBaseband() :
m_mutex(QMutex::Recursive)
@ -141,32 +140,7 @@ void SSBModBaseband::handleInputMessages()
bool SSBModBaseband::handleMessage(const Message& cmd)
{
if (DSPConfigureAudio::match(cmd))
{
DSPConfigureAudio& cfg = (DSPConfigureAudio&) cmd;
uint32_t sampleRate = cfg.getSampleRate();
DSPConfigureAudio::AudioType audioType = cfg.getAudioType();
qDebug() << "SSBModBaseband::handleMessage: DSPConfigureAudio:"
<< " sampleRate: " << sampleRate
<< " audioType: " << audioType;
if (audioType == DSPConfigureAudio::AudioInput)
{
if (sampleRate != m_source.getAudioSampleRate()) {
m_source.applyAudioSampleRate(sampleRate);
}
}
else if (audioType == DSPConfigureAudio::AudioOutput)
{
if (sampleRate != m_source.getFeedbackAudioSampleRate()) {
m_source.applyFeedbackAudioSampleRate(sampleRate);
}
}
return true;
}
else if (MsgConfigureSSBModBaseband::match(cmd))
if (MsgConfigureSSBModBaseband::match(cmd))
{
QMutexLocker mutexLocker(&m_mutex);
MsgConfigureSSBModBaseband& cfg = (MsgConfigureSSBModBaseband&) cmd;
@ -176,18 +150,6 @@ bool SSBModBaseband::handleMessage(const Message& cmd)
return true;
}
else if (MsgConfigureChannelizer::match(cmd))
{
QMutexLocker mutexLocker(&m_mutex);
MsgConfigureChannelizer& cfg = (MsgConfigureChannelizer&) cmd;
qDebug() << "SSBModBaseband::handleMessage: MsgConfigureChannelizer"
<< "(requested) sourceSampleRate: " << cfg.getSourceSampleRate()
<< "(requested) sourceCenterFrequency: " << cfg.getSourceCenterFrequency();
m_channelizer->setChannelization(cfg.getSourceSampleRate(), cfg.getSourceCenterFrequency());
m_source.applyChannelSettings(m_channelizer->getChannelSampleRate(), m_channelizer->getChannelFrequencyOffset());
return true;
}
else if (DSPSignalNotification::match(cmd))
{
QMutexLocker mutexLocker(&m_mutex);
@ -217,6 +179,39 @@ bool SSBModBaseband::handleMessage(const Message& cmd)
void SSBModBaseband::applySettings(const SSBModSettings& settings, bool force)
{
if ((settings.m_inputFrequencyOffset != m_settings.m_inputFrequencyOffset) || force)
{
m_channelizer->setChannelization(m_source.getAudioSampleRate(), settings.m_inputFrequencyOffset);
m_source.applyChannelSettings(m_channelizer->getChannelSampleRate(), m_channelizer->getChannelFrequencyOffset());
}
if ((settings.m_audioDeviceName != m_settings.m_audioDeviceName) || force)
{
AudioDeviceManager *audioDeviceManager = DSPEngine::instance()->getAudioDeviceManager();
int audioDeviceIndex = audioDeviceManager->getInputDeviceIndex(settings.m_audioDeviceName);
audioDeviceManager->addAudioSource(getAudioFifo(), getInputMessageQueue(), audioDeviceIndex);
uint32_t audioSampleRate = audioDeviceManager->getInputSampleRate(audioDeviceIndex);
if (getAudioSampleRate() != audioSampleRate)
{
m_source.applyAudioSampleRate(audioSampleRate);
m_channelizer->setChannelization(audioSampleRate, m_settings.m_inputFrequencyOffset);
m_source.applyChannelSettings(m_channelizer->getChannelSampleRate(), m_channelizer->getChannelFrequencyOffset());
}
}
if ((settings.m_feedbackAudioDeviceName != m_settings.m_feedbackAudioDeviceName) || force)
{
AudioDeviceManager *audioDeviceManager = DSPEngine::instance()->getAudioDeviceManager();
int audioDeviceIndex = audioDeviceManager->getOutputDeviceIndex(settings.m_feedbackAudioDeviceName);
audioDeviceManager->addAudioSink(getFeedbackAudioFifo(), getInputMessageQueue(), audioDeviceIndex);
uint32_t audioSampleRate = audioDeviceManager->getOutputSampleRate(audioDeviceIndex);
if (getFeedbackAudioSampleRate() != audioSampleRate) {
m_source.applyFeedbackAudioSampleRate(audioSampleRate);
}
}
m_source.applySettings(settings, force);
m_settings = settings;
}

View File

@ -57,29 +57,6 @@ public:
{ }
};
class MsgConfigureChannelizer : public Message {
MESSAGE_CLASS_DECLARATION
public:
int getSourceSampleRate() const { return m_sourceSampleRate; }
int getSourceCenterFrequency() const { return m_sourceCenterFrequency; }
static MsgConfigureChannelizer* create(int sourceSampleRate, int sourceCenterFrequency)
{
return new MsgConfigureChannelizer(sourceSampleRate, sourceCenterFrequency);
}
private:
int m_sourceSampleRate;
int m_sourceCenterFrequency;
MsgConfigureChannelizer(int sourceSampleRate, int sourceCenterFrequency) :
Message(),
m_sourceSampleRate(sourceSampleRate),
m_sourceCenterFrequency(sourceCenterFrequency)
{ }
};
SSBModBaseband();
~SSBModBaseband();
void reset();

View File

@ -501,15 +501,15 @@ void SSBModGUI::applySettings(bool force)
{
if (m_doApplySettings)
{
SSBMod::MsgConfigureChannelizer *msgChan = SSBMod::MsgConfigureChannelizer::create(
48000, m_settings.m_inputFrequencyOffset);
m_ssbMod->getInputMessageQueue()->push(msgChan);
SSBModSettings mod_settings; // different USB/LSB convention between modulator and GUI
mod_settings = m_settings;
if (mod_settings.m_bandwidth > 0) {
if (mod_settings.m_bandwidth > 0)
{
mod_settings.m_usb = true;
} else {
}
else
{
mod_settings.m_bandwidth = -mod_settings.m_bandwidth;
mod_settings.m_lowCutoff = -mod_settings.m_lowCutoff;
mod_settings.m_usb = false;

View File

@ -40,7 +40,6 @@
#include "wfmmod.h"
MESSAGE_CLASS_DEFINITION(WFMMod::MsgConfigureWFMMod, Message)
MESSAGE_CLASS_DEFINITION(WFMMod::MsgConfigureChannelizer, Message)
MESSAGE_CLASS_DEFINITION(WFMMod::MsgConfigureFileSourceName, Message)
MESSAGE_CLASS_DEFINITION(WFMMod::MsgConfigureFileSourceSeek, Message)
MESSAGE_CLASS_DEFINITION(WFMMod::MsgConfigureFileSourceStreamTiming, Message)
@ -105,20 +104,7 @@ void WFMMod::pull(SampleVector::iterator& begin, unsigned int nbSamples)
bool WFMMod::handleMessage(const Message& cmd)
{
if (MsgConfigureChannelizer::match(cmd))
{
MsgConfigureChannelizer& cfg = (MsgConfigureChannelizer&) cmd;
qDebug() << "WFMMod::handleMessage: MsgConfigureChannelizer:"
<< " getSourceSampleRate: " << cfg.getSourceSampleRate()
<< " getSourceCenterFrequency: " << cfg.getSourceCenterFrequency();
WFMModBaseband::MsgConfigureChannelizer *msg
= WFMModBaseband::MsgConfigureChannelizer::create(cfg.getSourceSampleRate(), cfg.getSourceCenterFrequency());
m_basebandSource->getInputMessageQueue()->push(msg);
return true;
}
else if (MsgConfigureWFMMod::match(cmd))
if (MsgConfigureWFMMod::match(cmd))
{
MsgConfigureWFMMod& cfg = (MsgConfigureWFMMod&) cmd;
qDebug() << "WFMMod::handleMessage: MsgConfigureWFMMod";
@ -270,21 +256,8 @@ void WFMMod::applySettings(const WFMModSettings& settings, bool force)
if ((settings.m_toneFrequency != m_settings.m_toneFrequency) || force) {
reverseAPIKeys.append("toneFrequency");
}
if ((settings.m_audioDeviceName != m_settings.m_audioDeviceName) || force)
{
if ((settings.m_audioDeviceName != m_settings.m_audioDeviceName) || force) {
reverseAPIKeys.append("audioDeviceName");
AudioDeviceManager *audioDeviceManager = DSPEngine::instance()->getAudioDeviceManager();
int audioDeviceIndex = audioDeviceManager->getInputDeviceIndex(settings.m_audioDeviceName);
audioDeviceManager->addAudioSource(m_basebandSource->getAudioFifo(), getInputMessageQueue(), audioDeviceIndex);
uint32_t audioSampleRate = audioDeviceManager->getInputSampleRate(audioDeviceIndex);
if (m_basebandSource->getAudioSampleRate() != audioSampleRate)
{
reverseAPIKeys.append("audioSampleRate");
DSPConfigureAudio *msg = new DSPConfigureAudio(audioSampleRate, DSPConfigureAudio::AudioInput);
m_basebandSource->getInputMessageQueue()->push(msg);
}
}
if (m_settings.m_streamIndex != settings.m_streamIndex)
@ -380,14 +353,6 @@ int WFMMod::webapiSettingsPutPatch(
}
}
if ((m_settings.m_inputFrequencyOffset != settings.m_inputFrequencyOffset)
||(m_settings.m_rfBandwidth != settings.m_rfBandwidth))
{
WFMMod::MsgConfigureChannelizer *msgChan = WFMMod::MsgConfigureChannelizer::create(
settings.m_rfBandwidth, settings.m_inputFrequencyOffset);
m_inputMessageQueue.push(msgChan);
}
MsgConfigureWFMMod *msg = MsgConfigureWFMMod::create(settings, force);
m_inputMessageQueue.push(msg);

View File

@ -65,36 +65,6 @@ public:
{ }
};
/**
* |<------ Baseband from device (before device soft interpolation) -------------------------->|
* |<- Channel SR ------->|<- Channel SR ------->|<- Channel SR ------->|<- Channel SR ------->|
* | ^-------------------------------|
* | | Source CF
* | | Source SR |
*/
class MsgConfigureChannelizer : public Message {
MESSAGE_CLASS_DECLARATION
public:
int getSourceSampleRate() const { return m_sourceSampleRate; }
int getSourceCenterFrequency() const { return m_sourceCenterFrequency; }
static MsgConfigureChannelizer* create(int sourceSampleRate, int sourceCenterFrequency)
{
return new MsgConfigureChannelizer(sourceSampleRate, sourceCenterFrequency);
}
private:
int m_sourceSampleRate;
int m_sourceCenterFrequency;
MsgConfigureChannelizer(int sourceSampleRate, int sourceCenterFrequency) :
Message(),
m_sourceSampleRate(sourceSampleRate),
m_sourceCenterFrequency(sourceCenterFrequency)
{ }
};
class MsgConfigureFileSourceName : public Message
{
MESSAGE_CLASS_DECLARATION

View File

@ -24,7 +24,6 @@
#include "wfmmodbaseband.h"
MESSAGE_CLASS_DEFINITION(WFMModBaseband::MsgConfigureWFMModBaseband, Message)
MESSAGE_CLASS_DEFINITION(WFMModBaseband::MsgConfigureChannelizer, Message)
WFMModBaseband::WFMModBaseband() :
m_mutex(QMutex::Recursive)
@ -137,27 +136,7 @@ void WFMModBaseband::handleInputMessages()
bool WFMModBaseband::handleMessage(const Message& cmd)
{
if (DSPConfigureAudio::match(cmd))
{
QMutexLocker mutexLocker(&m_mutex);
DSPConfigureAudio& cfg = (DSPConfigureAudio&) cmd;
uint32_t sampleRate = cfg.getSampleRate();
DSPConfigureAudio::AudioType audioType = cfg.getAudioType();
qDebug() << "WFMModBaseband::handleMessage: DSPConfigureAudio:"
<< " sampleRate: " << sampleRate
<< " audioType: " << audioType;
if (audioType == DSPConfigureAudio::AudioInput)
{
if (sampleRate != m_source.getAudioSampleRate()) {
m_source.applyAudioSampleRate(sampleRate);
}
}
return true;
}
else if (MsgConfigureWFMModBaseband::match(cmd))
if (MsgConfigureWFMModBaseband::match(cmd))
{
QMutexLocker mutexLocker(&m_mutex);
MsgConfigureWFMModBaseband& cfg = (MsgConfigureWFMModBaseband&) cmd;
@ -167,18 +146,6 @@ bool WFMModBaseband::handleMessage(const Message& cmd)
return true;
}
else if (MsgConfigureChannelizer::match(cmd))
{
QMutexLocker mutexLocker(&m_mutex);
MsgConfigureChannelizer& cfg = (MsgConfigureChannelizer&) cmd;
qDebug() << "WFMModBaseband::handleMessage: MsgConfigureChannelizer"
<< "(requested) sourceSampleRate: " << cfg.getSourceSampleRate()
<< "(requested) sourceCenterFrequency: " << cfg.getSourceCenterFrequency();
m_channelizer->setChannelization(cfg.getSourceSampleRate(), cfg.getSourceCenterFrequency());
m_source.applyChannelSettings(m_channelizer->getChannelSampleRate(), m_channelizer->getChannelFrequencyOffset());
return true;
}
else if (DSPSignalNotification::match(cmd))
{
QMutexLocker mutexLocker(&m_mutex);
@ -208,7 +175,27 @@ bool WFMModBaseband::handleMessage(const Message& cmd)
void WFMModBaseband::applySettings(const WFMModSettings& settings, bool force)
{
if ((m_settings.m_rfBandwidth != settings.m_rfBandwidth)
|| (m_settings.m_inputFrequencyOffset != settings.m_inputFrequencyOffset) || force)
{
m_channelizer->setChannelization(settings.m_rfBandwidth, settings.m_inputFrequencyOffset);
m_source.applyChannelSettings(m_channelizer->getChannelSampleRate(), m_channelizer->getChannelFrequencyOffset());
}
if ((settings.m_audioDeviceName != m_settings.m_audioDeviceName) || force)
{
AudioDeviceManager *audioDeviceManager = DSPEngine::instance()->getAudioDeviceManager();
int audioDeviceIndex = audioDeviceManager->getInputDeviceIndex(settings.m_audioDeviceName);
audioDeviceManager->addAudioSource(getAudioFifo(), getInputMessageQueue(), audioDeviceIndex);
uint32_t audioSampleRate = audioDeviceManager->getInputSampleRate(audioDeviceIndex);
if (getAudioSampleRate() != audioSampleRate) {
m_source.applyAudioSampleRate(audioSampleRate);
}
}
m_source.applySettings(settings, force);
m_settings = settings;
}

View File

@ -56,29 +56,6 @@ public:
{ }
};
class MsgConfigureChannelizer : public Message {
MESSAGE_CLASS_DECLARATION
public:
int getSourceSampleRate() const { return m_sourceSampleRate; }
int getSourceCenterFrequency() const { return m_sourceCenterFrequency; }
static MsgConfigureChannelizer* create(int sourceSampleRate, int sourceCenterFrequency)
{
return new MsgConfigureChannelizer(sourceSampleRate, sourceCenterFrequency);
}
private:
int m_sourceSampleRate;
int m_sourceCenterFrequency;
MsgConfigureChannelizer(int sourceSampleRate, int sourceCenterFrequency) :
Message(),
m_sourceSampleRate(sourceSampleRate),
m_sourceCenterFrequency(sourceCenterFrequency)
{ }
};
WFMModBaseband();
~WFMModBaseband();
void reset();

View File

@ -419,14 +419,7 @@ void WFMModGUI::applySettings(bool force)
if (m_doApplySettings)
{
setTitleColor(m_channelMarker.getColor());
WFMMod::MsgConfigureChannelizer *msgChan = WFMMod::MsgConfigureChannelizer::create(
requiredBW(WFMModSettings::getRFBW(ui->rfBW->currentIndex())),
m_channelMarker.getCenterFrequency());
m_wfmMod->getInputMessageQueue()->push(msgChan);
ui->deltaFrequency->setValue(m_channelMarker.getCenterFrequency());
WFMMod::MsgConfigureWFMMod *msgConf = WFMMod::MsgConfigureWFMMod::create(m_settings, force);
m_wfmMod->getInputMessageQueue()->push(msgConf);
}

View File

@ -78,14 +78,20 @@ void WFMModSource::pullOne(Sample& sample)
if ((m_settings.m_modAFInput == WFMModSettings::WFMModInputFile)
|| (m_settings.m_modAFInput == WFMModSettings::WFMModInputAudio))
{
if (m_interpolator.interpolate(&m_interpolatorDistanceRemain, m_modSample, &ri))
{
pullAF(t);
calculateLevel(t);
m_modSample.real(t);
m_modSample.imag(0.0f);
m_audioBufferFill++;
}
if (m_interpolatorDistance > 1.0f) // decimate
{
modulateAudio();
while (!m_interpolator.decimate(&m_interpolatorDistanceRemain, m_modSample, &ri)) {
modulateAudio();
}
}
else // interpolate
{
if (m_interpolator.interpolate(&m_interpolatorDistanceRemain, m_modSample, &ri)) {
modulateAudio();
}
}
t = ri.real();
m_interpolatorDistanceRemain += m_interpolatorDistance;
@ -128,6 +134,15 @@ void WFMModSource::pullOne(Sample& sample)
sample.m_imag = (FixReal) ci.imag();
}
void WFMModSource::modulateAudio()
{
Real t;
pullAF(t);
calculateLevel(t);
m_modSample.real(t);
m_modSample.imag(0.0f);
}
void WFMModSource::prefetch(unsigned int nbSamples)
{
unsigned int nbSamplesAudio = nbSamples * ((Real) m_audioSampleRate / (Real) m_channelSampleRate);
@ -183,7 +198,17 @@ void WFMModSource::pullAF(Real& sample)
break;
case WFMModSettings::WFMModInputAudio:
{
sample = ((m_audioBuffer[m_audioBufferFill].l + m_audioBuffer[m_audioBufferFill].r) / 65536.0f) * m_settings.m_volumeFactor;
if (m_audioBufferFill < m_audioBuffer.size())
{
sample = ((m_audioBuffer[m_audioBufferFill].l + m_audioBuffer[m_audioBufferFill].r) / 65536.0f) * m_settings.m_volumeFactor;
m_audioBufferFill++;
}
else
{
unsigned int size = m_audioBuffer.size();
qDebug("WFMModSource::pullAF: starve audio samples: size: %u", size);
sample = ((m_audioBuffer[size-1].l + m_audioBuffer[size-1].r) / 65536.0f) * m_settings.m_volumeFactor;
}
}
break;
case WFMModSettings::WFMModInputCWTone:
@ -256,8 +281,8 @@ void WFMModSource::applySettings(const WFMModSettings& settings, bool force)
if ((settings.m_rfBandwidth != m_settings.m_rfBandwidth) || force)
{
Real lowCut = -(settings.m_rfBandwidth / 2.0) / m_channelSampleRate;
Real hiCut = (settings.m_rfBandwidth / 2.0) / m_channelSampleRate;
Real lowCut = -(settings.m_rfBandwidth / 2.2) / m_channelSampleRate;
Real hiCut = (settings.m_rfBandwidth / 2.2) / m_channelSampleRate;
m_rfFilter->create_filter(lowCut, hiCut);
}

View File

@ -103,6 +103,7 @@ private:
void pullAF(Real& sample);
void pullAudio(unsigned int nbSamples);
void calculateLevel(const Real& sample);
void modulateAudio();
};
#endif // INCLUDE_WFMMODSOURCE_H

View File

@ -24,8 +24,6 @@
#include "export.h"
#include "dsptypes.h"
class Message;
class SDRBASE_API ChannelSampleSource {
public:
ChannelSampleSource();