25 #include <QNetworkAccessManager> 26 #include <QNetworkReply> 53 m_deviceAPI(deviceAPI),
54 m_inputSampleRate(384000),
55 m_inputFrequencyOffset(0),
62 m_settingsMutex(QMutex::Recursive)
100 void WFMDemod::feed(
const SampleVector::const_iterator& begin,
const SampleVector::const_iterator& end,
bool firstOfBurst)
112 for (SampleVector::const_iterator it = begin; it != end; ++it)
114 Complex c(it->real(), it->imag());
119 for (
int i = 0 ;
i < rf_out;
i++)
121 msq = rf[
i].real()*rf[
i].real() + rf[
i].imag()*rf[
i].imag();
213 qDebug() <<
"WFMDemod::handleMessage: MsgChannelizerNotification: m_inputSampleRate: " << notif.
getSampleRate()
223 qDebug() <<
"WFMDemod::handleMessage: MsgConfigureChannelizer:" 236 qDebug(
"WFMDemod::handleMessage: MsgConfigureWFMDemod");
246 qDebug(
"WFMDemod::handleMessage: BasebandSampleSink::MsgThreadedSink: %p", thread);
254 qDebug() <<
"WFMDemod::handleMessage: DSPConfigureAudio:" 255 <<
" sampleRate: " << sampleRate;
275 qDebug(
"WFMDemod::applyAudioSampleRate: %d", sampleRate);
290 qDebug() <<
"WFMDemod::applyChannelSettings:" 291 <<
" inputSampleRate: " << inputSampleRate
292 <<
" inputFrequencyOffset: " << inputFrequencyOffset;
302 qDebug() <<
"WFMDemod::applyChannelSettings: m_interpolator.create";
308 qDebug() <<
"WFMDemod::applySettings: m_rfFilter->create_filter";
314 qDebug(
"WFMDemod::applySettings: m_fmExcursion: %f",
m_fmExcursion);
323 qDebug() <<
"WFMDemod::applySettings:" 327 <<
" m_volume: " << settings.
m_volume 336 <<
" force: " << force;
338 QList<QString> reverseAPIKeys;
341 reverseAPIKeys.append(
"inputFrequencyOffset");
344 reverseAPIKeys.append(
"rfBandwidth");
347 reverseAPIKeys.append(
"afBandwidth");
350 reverseAPIKeys.append(
"volume");
353 reverseAPIKeys.append(
"squelch");
356 reverseAPIKeys.append(
"audioMute");
359 reverseAPIKeys.append(
"audioDeviceName");
362 reverseAPIKeys.append(
"title");
365 reverseAPIKeys.append(
"rgbColor");
372 qDebug() <<
"WFMDemod::applySettings: m_interpolator.create";
376 qDebug() <<
"WFMDemod::applySettings: m_rfFilter->create_filter";
382 qDebug(
"WFMDemod::applySettings: m_fmExcursion: %f",
m_fmExcursion);
388 qDebug() <<
"WFMDemod::applySettings: set m_squelchLevel";
442 QString& errorMessage)
453 const QStringList& channelSettingsKeys,
455 QString& errorMessage)
459 bool frequencyOffsetChanged =
false;
461 if (channelSettingsKeys.contains(
"inputFrequencyOffset"))
464 frequencyOffsetChanged =
true;
466 if (channelSettingsKeys.contains(
"rfBandwidth")) {
469 if (channelSettingsKeys.contains(
"afBandwidth")) {
472 if (channelSettingsKeys.contains(
"volume")) {
475 if (channelSettingsKeys.contains(
"squelch")) {
478 if (channelSettingsKeys.contains(
"audioMute")) {
481 if (channelSettingsKeys.contains(
"rgbColor")) {
484 if (channelSettingsKeys.contains(
"title")) {
487 if (channelSettingsKeys.contains(
"audioDeviceName")) {
490 if (channelSettingsKeys.contains(
"useReverseAPI")) {
493 if (channelSettingsKeys.contains(
"reverseAPIAddress")) {
496 if (channelSettingsKeys.contains(
"reverseAPIPort")) {
499 if (channelSettingsKeys.contains(
"reverseAPIDeviceIndex")) {
502 if (channelSettingsKeys.contains(
"reverseAPIChannelIndex")) {
506 if (frequencyOffsetChanged)
516 qDebug(
"WFMDemod::webapiSettingsPutPatch: forward to GUI: %p",
m_guiMessageQueue);
530 QString& errorMessage)
576 double magsqAvg, magsqPeak;
598 if (channelSettingsKeys.contains(
"inputFrequencyOffset") || force) {
601 if (channelSettingsKeys.contains(
"rfBandwidth") || force) {
604 if (channelSettingsKeys.contains(
"afBandwidth") || force) {
607 if (channelSettingsKeys.contains(
"volume") || force) {
610 if (channelSettingsKeys.contains(
"squelch") || force) {
613 if (channelSettingsKeys.contains(
"audioMute") || force) {
616 if (channelSettingsKeys.contains(
"rgbColor") || force) {
619 if (channelSettingsKeys.contains(
"title") || force) {
622 if (channelSettingsKeys.contains(
"audioDeviceName") || force) {
626 QString channelSettingsURL = QString(
"http://%1:%2/sdrangel/deviceset/%3/channel/%4/settings")
632 m_networkRequest.setHeader(QNetworkRequest::ContentTypeHeader,
"application/json");
634 QBuffer *buffer=
new QBuffer();
635 buffer->open((QBuffer::ReadWrite));
636 buffer->write(swgChannelSettings->
asJson().toUtf8());
642 delete swgChannelSettings;
647 QNetworkReply::NetworkError replyError = reply->error();
651 qWarning() <<
"WFMDemod::networkManagerFinished:" 652 <<
" error(" << (int) replyError
653 <<
"): " << replyError
654 <<
": " << reply->errorString();
658 QString answer = reply->readAll();
660 qDebug(
"WFMDemod::networkManagerFinished: reply:\n%s", answer.toStdString().c_str());
void setOriginatorChannelIndex(qint32 originator_channel_index)
void setReverseApiAddress(QString *reverse_api_address)
void addAudioSink(AudioFifo *audioFifo, MessageQueue *sampleSinkMessageQueue, int outputDeviceIndex=-1)
Add the audio sink.
const QThread * getThread() const
qint64 m_inputFrequencyOffset
void networkManagerFinished(QNetworkReply *reply)
int getOutputSampleRate(int outputDeviceIndex=-1)
Complex nextIQ()
Return next complex sample.
bool decimate(Real *distance, const Complex &next, Complex *result)
void configure(MessageQueue *messageQueue, int sampleRate, int centerFrequency)
void setChannelSampleRate(qint32 channel_sample_rate)
ThreadedBasebandSampleSink * m_threadedChannelizer
void push(Message *message, bool emitSignal=true)
Push message onto queue.
void setSquelch(qint32 squelch)
void removeChannelSinkAPI(ChannelAPI *channelAPI, int streamIndex=0)
static double dbPower(double magsq, double floor=1e-12)
void addChannelSinkAPI(ChannelAPI *channelAPI, int streamIndex=0)
void setWfmDemodSettings(SWGWFMDemodSettings *wfm_demod_settings)
virtual QByteArray serialize() const
void create(int phaseSteps, double sampleRate, double cutoff, double nbTapsPerPhase=4.5)
WFMDemodSettings m_settings
MessageQueue * getInputMessageQueue()
Get the queue for asynchronous inbound communication.
void setFMScaling(Real fmScaling)
uint16_t m_reverseAPIPort
void setRgbColor(qint32 rgb_color)
int getDeviceSetIndex() const
int getOutputDeviceIndex(const QString &deviceName) const
uint16_t m_reverseAPIChannelIndex
int runFilt(const cmplx &in, cmplx **out)
void setReverseApiDeviceIndex(qint32 reverse_api_device_index)
int getSampleRate() const
void setSquelch(float squelch)
virtual int webapiReportGet(SWGSDRangel::SWGChannelReport &response, QString &errorMessage)
void removeAudioSink(AudioFifo *audioFifo)
Remove the audio sink.
QByteArray serialize() const
qint32 getUseReverseApi()
void setVolume(float volume)
void setChannelType(QString *channel_type)
void setOriginatorDeviceSetIndex(qint32 originator_device_set_index)
MessageQueue m_inputMessageQueue
Queue for asynchronous inbound communication.
std::complex< float > cmplx
bool deserialize(const QByteArray &data)
virtual int webapiSettingsPutPatch(bool force, const QStringList &channelSettingsKeys, SWGSDRangel::SWGChannelSettings &response, QString &errorMessage)
void setReverseApiChannelIndex(qint32 reverse_api_channel_index)
SWGWFMDemodSettings * getWfmDemodSettings()
MessageQueue * m_guiMessageQueue
Input message queue to the GUI.
void setAudioMute(qint32 audio_mute)
uint16_t m_reverseAPIDeviceIndex
SWGWFMDemodReport * getWfmDemodReport()
#define MESSAGE_CLASS_DEFINITION(Name, BaseClass)
qint32 getReverseApiPort()
AudioVector m_audioBuffer
void create_filter(float f1, float f2)
static int requiredBW(int rfBW)
static DSPEngine * instance()
void getMagSqLevels(double &avg, double &peak, int &nbSamples)
QString m_reverseAPIAddress
QNetworkRequest m_networkRequest
static const int m_udpBlockSize
void setWfmDemodReport(SWGWFMDemodReport *wfm_demod_report)
Real m_interpolatorDistance
void setReverseApiPort(qint32 reverse_api_port)
static bool match(const Message *message)
QString m_audioDeviceName
void setFreq(Real freq, Real sampleRate)
Interpolator m_interpolator
Interpolator between sample rate sent from DSP engine and requested RF bandwidth (rational) ...
void removeChannelSink(ThreadedBasebandSampleSink *sink, int streamIndex=0)
Remove a channel sink (Rx)
void setInputFrequencyOffset(qint64 input_frequency_offset)
void setDirection(qint32 direction)
void setAfBandwidth(float af_bandwidth)
quint32 m_audioSampleRate
void applyAudioSampleRate(int sampleRate)
void applyChannelSettings(int inputSampleRate, int inputFrequencyOffset, bool force=false)
virtual void feed(const SampleVector::const_iterator &begin, const SampleVector::const_iterator &end, bool po)
QNetworkAccessManager * m_networkManager
virtual QString asJson() override
static const QString m_channelIdURI
void applySettings(const WFMDemodSettings &settings, bool force=false)
void setRfBandwidth(float rf_bandwidth)
void webapiReverseSendSettings(QList< QString > &channelSettingsKeys, const WFMDemodSettings &settings, bool force)
MovingAverageUtil< Real, double, 16 > m_movingAverage
static const QString m_channelId
AudioDeviceManager * getAudioDeviceManager()
void addChannelSink(ThreadedBasebandSampleSink *sink, int streamIndex=0)
Add a channel sink (Rx)
WFMDemod(DeviceAPI *deviceAPI)
void setAudioSampleRate(qint32 audio_sample_rate)
QString * getReverseApiAddress()
qint32 getReverseApiChannelIndex()
void webapiFormatChannelReport(SWGSDRangel::SWGChannelReport &response)
SampleVector m_sampleBuffer
int m_inputFrequencyOffset
Real m_interpolatorDistanceRemain
DownChannelizer * m_channelizer
QString * getAudioDeviceName()
void webapiFormatChannelSettings(SWGSDRangel::SWGChannelSettings &response, const WFMDemodSettings &settings)
int getIndexInDeviceSet() const
qint32 getReverseApiDeviceIndex()
virtual int webapiSettingsGet(SWGSDRangel::SWGChannelSettings &response, QString &errorMessage)
std::complex< Real > Complex
qint64 getInputFrequencyOffset()
#define rfFilterFftLength
qint64 getFrequencyOffset() const
Real phaseDiscriminatorDelta(const Complex &sample, double &magsq, Real &fmDev)
PhaseDiscriminators m_phaseDiscri
void setUseReverseApi(qint32 use_reverse_api)
virtual bool handleMessage(const Message &cmd)
Processing of a message. Returns true if message has actually been processed.
virtual bool deserialize(const QByteArray &data)
uint32_t write(const quint8 *data, uint32_t numSamples)
void setTitle(QString *title)
void setChannelPowerDb(float channel_power_db)
void setAudioDeviceName(QString *audio_device_name)