22 #include <QNetworkAccessManager> 23 #include <QNetworkReply> 54 m_deviceAPI(deviceAPI),
55 m_inputSampleRate(48000),
56 m_inputFrequencyOffset(0),
59 m_squelchDelayLine(9600),
64 m_syncAMAGC(12000, 0.1, 1e-2),
66 m_settingsMutex(QMutex::Recursive)
116 void AMDemod::feed(
const SampleVector::const_iterator& begin,
const SampleVector::const_iterator& end,
bool firstOfBurst)
127 for (SampleVector::const_iterator it = begin; it != end; ++it)
129 Complex c(it->real(), it->imag());
169 Real magsq = re*re + im*im;
206 std::complex<float> s(re, im);
213 std::complex<float> cs(yr, yi);
222 for (
int i = 0;
i < n_out;
i++)
287 qDebug(
"AMDemod::processOneSample: %u/%u audio samples written", res,
m_audioBufferFill);
297 qDebug(
"AMDemod::start");
306 qDebug(
"AMDemod::stop");
316 qDebug() <<
"AMDemod::handleMessage: MsgChannelizerNotification:" 328 qDebug() <<
"AMDemod::handleMessage: MsgConfigureChannelizer:" 341 qDebug() <<
"AMDemod::handleMessage: MsgConfigureAMDemod";
350 qDebug(
"AMDemod::handleMessage: BasebandSampleSink::MsgThreadedSink: %p", thread);
362 qDebug() <<
"AMDemod::handleMessage: DSPConfigureAudio:" 363 <<
" sampleRate: " << sampleRate;
379 qDebug(
"AMDemod::applyAudioSampleRate: sampleRate: %d m_inputSampleRate: %d", sampleRate,
m_inputSampleRate);
412 qDebug() <<
"AMDemod::applyChannelSettings:" 413 <<
" inputSampleRate: " << inputSampleRate
414 <<
" inputFrequencyOffset: " << inputFrequencyOffset
438 qDebug() <<
"AMDemod::applySettings:" 441 <<
" m_volume: " << settings.
m_volume 446 <<
" m_pll: " << settings.
m_pll 454 <<
" force: " << force;
456 QList<QString> reverseAPIKeys;
471 reverseAPIKeys.append(
"rfBandwidth");
474 reverseAPIKeys.append(
"bandpassEnable");
481 reverseAPIKeys.append(
"squelch");
496 reverseAPIKeys.append(
"audioDeviceName");
511 reverseAPIKeys.append(
"pll");
512 reverseAPIKeys.append(
"syncAMOperation");
518 reverseAPIKeys.append(
"pll");
519 reverseAPIKeys.append(
"syncAMOperation");
523 reverseAPIKeys.append(
"inputFrequencyOffset");
527 reverseAPIKeys.append(
"audioMute");
531 reverseAPIKeys.append(
"volume");
546 reverseAPIKeys.append(
"streamIndex");
586 QString& errorMessage)
597 const QStringList& channelSettingsKeys,
599 QString& errorMessage)
603 bool frequencyOffsetChanged =
false;
605 if (channelSettingsKeys.contains(
"audioMute")) {
608 if (channelSettingsKeys.contains(
"inputFrequencyOffset"))
611 frequencyOffsetChanged =
true;
613 if (channelSettingsKeys.contains(
"rfBandwidth")) {
616 if (channelSettingsKeys.contains(
"rgbColor")) {
619 if (channelSettingsKeys.contains(
"squelch")) {
622 if (channelSettingsKeys.contains(
"title")) {
625 if (channelSettingsKeys.contains(
"volume")) {
628 if (channelSettingsKeys.contains(
"bandpassEnable")) {
631 if (channelSettingsKeys.contains(
"audioDeviceName")) {
635 if (channelSettingsKeys.contains(
"pll")) {
639 if (channelSettingsKeys.contains(
"syncAMOperation")) {
646 if (channelSettingsKeys.contains(
"streamIndex")) {
649 if (channelSettingsKeys.contains(
"useReverseAPI")) {
652 if (channelSettingsKeys.contains(
"reverseAPIAddress")) {
655 if (channelSettingsKeys.contains(
"reverseAPIPort")) {
658 if (channelSettingsKeys.contains(
"reverseAPIDeviceIndex")) {
661 if (channelSettingsKeys.contains(
"reverseAPIChannelIndex")) {
665 if (frequencyOffsetChanged)
675 qDebug(
"AMDemod::webapiSettingsPutPatch: forward to GUI: %p",
m_guiMessageQueue);
689 QString& errorMessage)
738 double magsqAvg, magsqPeak;
760 if (channelSettingsKeys.contains(
"audioMute") || force) {
763 if (channelSettingsKeys.contains(
"inputFrequencyOffset") || force) {
766 if (channelSettingsKeys.contains(
"rfBandwidth") || force) {
769 if (channelSettingsKeys.contains(
"rgbColor") || force) {
772 if (channelSettingsKeys.contains(
"squelch") || force) {
775 if (channelSettingsKeys.contains(
"title") || force) {
778 if (channelSettingsKeys.contains(
"volume") || force) {
781 if (channelSettingsKeys.contains(
"bandpassEnable") || force) {
784 if (channelSettingsKeys.contains(
"audioDeviceName") || force) {
787 if (channelSettingsKeys.contains(
"pll") || force) {
790 if (channelSettingsKeys.contains(
"syncAMOperation") || force) {
793 if (channelSettingsKeys.contains(
"streamIndex") || force) {
797 QString channelSettingsURL = QString(
"http://%1:%2/sdrangel/deviceset/%3/channel/%4/settings")
803 m_networkRequest.setHeader(QNetworkRequest::ContentTypeHeader,
"application/json");
805 QBuffer *buffer=
new QBuffer();
806 buffer->open((QBuffer::ReadWrite));
807 buffer->write(swgChannelSettings->
asJson().toUtf8());
813 delete swgChannelSettings;
818 QNetworkReply::NetworkError replyError = reply->error();
822 qWarning() <<
"AMDemod::networkManagerFinished:" 823 <<
" error(" << (int) replyError
824 <<
"): " << replyError
825 <<
": " << reply->errorString();
829 QString answer = reply->readAll();
831 qDebug(
"AMDemod::networkManagerFinished: reply:\n%s", answer.toStdString().c_str());
Real m_syncAMBuff[2 *1024]
void setOriginatorChannelIndex(qint32 originator_channel_index)
void addAudioSink(AudioFifo *audioFifo, MessageQueue *sampleSinkMessageQueue, int outputDeviceIndex=-1)
Add the audio sink.
void applyChannelSettings(int inputSampleRate, int inputFrequencyOffset, bool force=false)
const QThread * getThread() const
int getOutputSampleRate(int outputDeviceIndex=-1)
void setSquelch(qint32 squelch)
Complex nextIQ()
Return next complex sample.
bool decimate(Real *distance, const Complex &next, Complex *result)
void configure(MessageQueue *messageQueue, int sampleRate, int centerFrequency)
void webapiReverseSendSettings(QList< QString > &channelSettingsKeys, const AMDemodSettings &settings, bool force)
void push(Message *message, bool emitSignal=true)
Push message onto queue.
qint32 getReverseApiPort()
uint32_t getNumberOfDeviceStreams() const
QNetworkAccessManager * m_networkManager
void removeChannelSinkAPI(ChannelAPI *channelAPI, int streamIndex=0)
void create(int nTaps, double sampleRate, double lowCutoff, double highCutoff)
void setThresholdEnable(bool enable)
static double dbPower(double magsq, double floor=1e-12)
void addChannelSinkAPI(ChannelAPI *channelAPI, int streamIndex=0)
void getMagSqLevels(double &avg, double &peak, int &nbSamples)
void create(int phaseSteps, double sampleRate, double cutoff, double nbTapsPerPhase=4.5)
void setAudioDeviceName(QString *audio_device_name)
MessageQueue * getInputMessageQueue()
Get the queue for asynchronous inbound communication.
AMDemodSettings m_settings
bool interpolate(Real *distance, const Complex &next, Complex *result)
void create(int nTaps, double sampleRate, double cutoff)
int getDeviceSetIndex() const
void webapiFormatChannelSettings(SWGSDRangel::SWGChannelSettings &response, const AMDemodSettings &settings)
int getOutputDeviceIndex(const QString &deviceName) const
qint32 getReverseApiChannelIndex()
void setSquelch(float squelch)
int getSampleRate() const
virtual QByteArray serialize() const
void removeAudioSink(AudioFifo *audioFifo)
Remove the audio sink.
SWGAMDemodReport * getAmDemodReport()
virtual bool deserialize(const QByteArray &data)
void setChannelPowerDb(float channel_power_db)
void setSyncAmOperation(qint32 sync_am_operation)
void webapiFormatChannelReport(SWGSDRangel::SWGChannelReport &response)
static float smootherstep(float x)
uint16_t m_reverseAPIChannelIndex
void setChannelType(QString *channel_type)
void setOriginatorDeviceSetIndex(qint32 originator_device_set_index)
void setReverseApiAddress(QString *reverse_api_address)
MessageQueue m_inputMessageQueue
Queue for asynchronous inbound communication.
QString * getAudioDeviceName()
double feedAndGetValue(const Complex &ci)
std::complex< float > cmplx
void write(const T &element)
MovingAverageUtil< Real, double, 16 > m_movingAverage
int m_streamIndex
MIMO channel. Not relevant when connected to SI (single Rx).
MessageQueue * m_guiMessageQueue
Input message queue to the GUI.
void resize(int historySize, int stepLength, Real R)
qint32 getUseReverseApi()
Real m_interpolatorDistance
Lowpass< Real > m_lowpass
#define MESSAGE_CLASS_DEFINITION(Name, BaseClass)
uint16_t m_reverseAPIDeviceIndex
AMDemod(DeviceAPI *deviceAPI)
SWGAMDemodSettings * getAmDemodSettings()
static DSPEngine * instance()
qint32 getBandpassEnable()
void setAmDemodSettings(SWGAMDemodSettings *am_demod_settings)
void setUseReverseApi(qint32 use_reverse_api)
void setBandpassEnable(qint32 bandpass_enable)
int m_inputFrequencyOffset
QByteArray serialize() const
void setRfBandwidth(float rf_bandwidth)
qint32 getSyncAmOperation()
virtual bool handleMessage(const Message &cmd)
Processing of a message. Returns true if message has actually been processed.
Interpolator m_interpolator
SyncAMOperation m_syncAMOperation
virtual int webapiReportGet(SWGSDRangel::SWGChannelReport &response, QString &errorMessage)
QString m_audioDeviceName
void setRgbColor(qint32 rgb_color)
static bool match(const Message *message)
uint32_t m_audioSampleRate
virtual void feed(const SampleVector::const_iterator &begin, const SampleVector::const_iterator &end, bool po)
void setFreq(Real freq, Real sampleRate)
bool deserialize(const QByteArray &data)
void setInputFrequencyOffset(qint64 input_frequency_offset)
ThreadedBasebandSampleSink * m_threadedChannelizer
void removeChannelSink(ThreadedBasebandSampleSink *sink, int streamIndex=0)
Remove a channel sink (Rx)
DoubleBufferFIFO< Real > m_squelchDelayLine
DownChannelizer * m_channelizer
Fixed< IntType, IntBits > sqrt(Fixed< IntType, IntBits > const &x)
virtual int webapiSettingsPutPatch(bool force, const QStringList &channelSettingsKeys, SWGSDRangel::SWGChannelSettings &response, QString &errorMessage)
void setDirection(qint32 direction)
void applySettings(const AMDemodSettings &settings, bool force=false)
virtual QString asJson() override
static const QString m_channelId
void processOneSample(Complex &ci)
qint64 getInputFrequencyOffset()
void applyAudioSampleRate(int sampleRate)
Lowpass< std::complex< float > > m_pllFilt
AudioDeviceManager * getAudioDeviceManager()
void addChannelSink(ThreadedBasebandSampleSink *sink, int streamIndex=0)
Add a channel sink (Rx)
AudioVector m_audioBuffer
qint32 getReverseApiDeviceIndex()
void setChannelSampleRate(qint32 channel_sample_rate)
QString m_reverseAPIAddress
bool setSize(uint32_t numSamples)
uint32_t m_audioBufferFill
void resizeNew(uint32_t newSize, Real initial, Real cutoff=0, Real clip=0)
virtual int webapiSettingsGet(SWGSDRangel::SWGChannelSettings &response, QString &errorMessage)
void setAmDemodReport(SWGAMDemodReport *am_demod_report)
void setVolume(float volume)
uint16_t m_reverseAPIPort
int runSSB(const cmplx &in, cmplx **out, bool usb, bool getDC=true)
void setReverseApiChannelIndex(qint32 reverse_api_channel_index)
void setAudioSampleRate(qint32 audio_sample_rate)
void networkManagerFinished(QNetworkReply *reply)
qint32 m_inputFrequencyOffset
virtual int getSourceSampleRate(int index) const =0
Sample rate exposed by the source at index.
Bandpass< Real > m_bandpass
void setAudioMute(qint32 audio_mute)
uint32_t getNbSourceStreams() const
void setReverseApiDeviceIndex(qint32 reverse_api_device_index)
Real m_interpolatorDistanceRemain
QNetworkRequest m_networkRequest
void computeCoefficients(Real wn, Real zeta, Real K)
int getIndexInDeviceSet() const
void setReverseApiPort(qint32 reverse_api_port)
uint32_t m_syncAMBuffIndex
std::complex< Real > Complex
static const QString m_channelIdURI
qint64 getFrequencyOffset() const
DeviceSampleMIMO * getSampleMIMO()
Return pointer to the device sample MIMO or nullptr.
int runDSB(const cmplx &in, cmplx **out, bool getDC=true)
void setStreamIndex(qint32 stream_index)
static double powerFromdB(double powerdB)
void feed(float re, float im)
uint32_t write(const quint8 *data, uint32_t numSamples)
SimpleAGC< 4800 > m_volumeAGC
void create_dsb_filter(float f2)
QString * getReverseApiAddress()
void setSampleRate(unsigned int sampleRate)
static const int m_udpBlockSize
void setTitle(QString *title)