Tx plugins fixes and further refactoring around MsgConfigureChannelizer and audio

pull/448/head
f4exb 2019-11-21 00:40:55 +01:00
rodzic b135a9582b
commit c3e3044b98
38 zmienionych plików z 264 dodań i 845 usunięć

Wyświetl plik

@ -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);

Wyświetl plik

@ -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

Wyświetl plik

@ -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)

Wyświetl plik

@ -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;
}

Wyświetl plik

@ -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

Wyświetl plik

@ -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);

Wyświetl plik

@ -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

Wyświetl plik

@ -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;
}

Wyświetl plik

@ -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();

Wyświetl plik

@ -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);
}

Wyświetl plik

@ -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),

Wyświetl plik

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

Wyświetl plik

@ -2,7 +2,7 @@
<h1>Introduction</h1>
This plugin can be used to generate an analog TV signal mostly used in amateur radio. It is limited to black and white images as only the luminance (256 levels) is supported.
This plugin can be used to generate an analog TV signal mostly used in amateur radio. It is limited to black and white images as only the luminance (256 levels) is supported.
There is no sound either. You could imagine using any of the plugins supporting audio to create a mixed signal. This is not working well however for various reasons. It is better to use two physical transmitters and two physical receivers.
@ -20,24 +20,33 @@ 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.
The right figure is the corresponding number of points and therefore also samples per full line including line synchronization.
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"
Let's take an example with a 405 lines and 20 FPS video signal and a 3000 kS/s sink input sample rate:
The right figure is the corresponding number of points and therefore also samples per full line including line synchronization.
Let's take an example with a 405 lines and 20 FPS video signal and a 3000 kS/s sink input sample rate:
- the line frequency is 405 &#215; 25 = 10125 Hz
- 2400 kS/s fit 237.037037037 points per line and therefore is not an integer number
- closest 10 S/s multiple sample rate to fit an integer number of points is 236 &#215; 10125 = 2389.5 kS/s
- therefore decimated sample rate is 2389.5 kS/s and the number of points per line is 236
The example taken in the screenshot is from a 405 lines &#215; 20 FPS video signal:
- source sample rate is 3000 kS/s
- line frequency is 8100 Hz
- 371 points fit in 8100 &#215; 371 = 3005.1 kS/s
- 370 points fit in 8100 &#215; 370 = 2997 kS/s
- therefore the closest sample rate is 2997 kS/s for 370 points per line
- 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>
@ -56,27 +65,27 @@ Use this button to toggle mute for this channel. The radio waves on the icon are
The video signal can modulate the carrier in the following modes:
- AM: Amplitude modulation. Modulation index is 90%.
- FM: Frequency modulation. Excursion is a percentage of the bandwidth available given the channel sample rate. This percentage is controlled by button (2). e.g. at 25% for 4 MS/s sample rate this is 1 MHz (&#177;0.5 MHz)
- FM: Frequency modulation. Excursion is a percentage of the bandwidth available given the channel sample rate. This percentage is controlled by button (2). e.g. at 25% for 4 MS/s sample rate this is 1 MHz (&#177;0.5 MHz)
- USB: SSB upper side band: video signal is transposed only in positive frequencies including DC component
- LSB: SSB lower side band: video signal is transposed only in negative frequencies excluding DC component
- VUSB: SSB upper sideband with vestigial lower sideband. The cutoff frequency of the lower sideband is controlled by slider (3)
- VLSB: SSB lower sideband with vestigial upper sideband. The cutoff frequency of the upper sideband is controlled by slider (3)
<h3>A.2: FM deviation percentage of total bandwidth</h3>
Use this button to control FM deviation in FM modulation mode. This is a percentage of total available channel bandwidth. e.g for the sample rate of 2997 kS/s of the screenshot and a percentage of 19% this yields a full deviation of 2997 &#215; 0.19 = 569.43 kHz that is &#177;284.715 kHz
&#9758; You can adjust this value and see the result for yourself. A good starting point is half of the signal bandwidth.
<h3>A.3: Opposite sideband FFT filter cutoff</h3>
This slider is effective only on SSB and vestigial modes (USB, LSB, VUSB, VLSB). This slider controls the cutoff frequency of the FFT filter in the opposite sideband to the main in band sideband. That is:
- for LSB and VLSB: this is the upper sideband
- for USB and VUSB: this is the lower sideband
The cutoff frequency in kHz is displayed on the left of the slider
<h3>A.4: In band filter cutoff</h3>
This slider acts on both the FFT filter in SSB modes and the rational decimator FIR filter in other modes.
@ -89,7 +98,7 @@ This slider acts on both the FFT filter in SSB modes and the rational decimator
The cutoff frequency in kHz is displayed on the right of the slider
<h3>A.5: Modulated signal level before filtering stages</h3>
This button controls the scaling from the +1/-1 modulated signal level to the -32768/+32768 2 bytes samples. This is useful to control the saturation of the FFT or FIR filters. Looking at the output spectrum you can precisely control the limit above which distortion appears.
<h3>A.6: Video signal level meter</h3>
@ -179,7 +188,7 @@ This controls the frame synchronization scheme and number of black lines:
<td>HSkip</td>
</tr>
</table>
<h2>A.10: Input source</h2>
This combo box lets you choose between various inputs for the video signal:
@ -196,9 +205,9 @@ This combo box lets you choose between various inputs for the video signal:
<h2>A.11: Video inversion toggle</h2>
Use this checkbox to toggle video signal inversion before modulation.
<h2>A.12. Luminance level</h2>
Use this checkbox to toggle video signal inversion before modulation.
<h2>A.12. Luminance level</h2>
This button lets you adjust the luminance level of the "blank" screens displays, the lighter squares on the chessboard and the overlay text.
@ -210,11 +219,11 @@ The text area lets you type a text up to 12 characters.
<h2>6. Still picture file select</h2>
Clicking on this button will open a file dialog to let you choose an image file for still image display. When the dialog is closed and the choice is validated the name of the file will appear on the space at the right of the button.
Clicking on this button will open a file dialog to let you choose an image file for still image display. When the dialog is closed and the choice is validated the name of the file will appear on the space at the right of the button.
<h2>7. Video file select</h2>
Clicking on this button will open a file dialog to let you choose a video file for video play. When the dialog is closed and the choice is validated the name of the file will appear on the space at the right of the button.
Clicking on this button will open a file dialog to let you choose a video file for video play. When the dialog is closed and the choice is validated the name of the file will appear on the space at the right of the button.
<h2>8. Play loop video</h2>
@ -222,7 +231,7 @@ Use this button to toggle on/off playing the video file in a loop
<h2>9. Play/Pause video</h2>
Use this button to toggle on/off the video file play. When play stops the current image is displayed as a still image. When video is stopped the button is dark and a play (&#9658;) icon is displayed on the button. When video runs the button is lit and a pause (&#9611;&#9611;) icon is displayed on the button.
Use this button to toggle on/off the video file play. When play stops the current image is displayed as a still image. When video is stopped the button is dark and a play (&#9658;) icon is displayed on the button. When video runs the button is lit and a pause (&#9611;&#9611;) icon is displayed on the button.
<h2>10. Current video position</h2>
@ -238,13 +247,13 @@ This slider can be used to randomly set the current position in the file when fi
<h2>23. Play/Pause camera</h2>
Use this button to toggle on/off the camera play. When play stops the current image is displayed as a still image. When camera is stopped the button is dark and a play (&#9658;) icon is displayed on the button. When camera runs the button is lit and a pause (&#9611;&#9611;) icon is displayed on the button.
Use this button to toggle on/off the camera play. When play stops the current image is displayed as a still image. When camera is stopped the button is dark and a play (&#9658;) icon is displayed on the button. When camera runs the button is lit and a pause (&#9611;&#9611;) icon is displayed on the button.
On Linux systems when the play button is engaged for the first time the FPS of the camera is scanned which can take some time (100 frames are read). A message box appears while the operation is running.
<h2>14. Camera select</h2>
Use this combo to select the camera source when more than one is available. the number corresponds to the index of the camera during the camera scan at the startup of the plugin instance. A maximum of 4 cameras are scanned in whichever order presented by the system.
Use this combo to select the camera source when more than one is available. the number corresponds to the index of the camera during the camera scan at the startup of the plugin instance. A maximum of 4 cameras are scanned in whichever order presented by the system.
<h2>15. Camera device number</h2>

Wyświetl plik

@ -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);

Wyświetl plik

@ -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

Wyświetl plik

@ -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;
}

Wyświetl plik

@ -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();

Wyświetl plik

@ -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);
}

Wyświetl plik

@ -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;
}

Wyświetl plik

@ -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);

Wyświetl plik

@ -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

Wyświetl plik

@ -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;
}

Wyświetl plik

@ -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();

Wyświetl plik

@ -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);
}

Wyświetl plik

@ -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>

Wyświetl plik

@ -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);

Wyświetl plik

@ -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

Wyświetl plik

@ -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;
}

Wyświetl plik

@ -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();

Wyświetl plik

@ -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;

Wyświetl plik

@ -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);

Wyświetl plik

@ -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

Wyświetl plik

@ -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;
}

Wyświetl plik

@ -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();

Wyświetl plik

@ -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);
}

Wyświetl plik

@ -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);
}

Wyświetl plik

@ -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

Wyświetl plik

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