22 #include <QMutexLocker> 23 #include <QNetworkAccessManager> 24 #include <QNetworkReply> 57 m_deviceAPI(deviceAPI),
58 m_basebandSampleRate(48000),
59 m_outputSampleRate(48000),
60 m_inputFrequencyOffset(0),
65 m_SSBFilterBufferIndex(0),
66 m_DSBFilterBufferIndex(0),
69 m_feedbackAudioFifo(48000),
70 m_settingsMutex(QMutex::Recursive),
185 double magsq = ci.real() * ci.real() + ci.imag() * ci.imag();
233 unsigned char decim_mask = decim - 1;
439 for (
int i = 0;
i < n_out;
i++)
546 qDebug(
"AMDemod::pushFeedback: %u/%u audio samples written m_feedbackInterpolatorDistance: %f",
557 Real t = sample.real();
594 qDebug() <<
"SSBMod::handleMessage: MsgChannelizerNotification";
603 qDebug() <<
"SSBMod::handleMessage: MsgConfigureChannelizer: sampleRate: " << cfg.
getSampleRate()
615 qDebug() <<
"SSBMod::handleMessage: MsgConfigureSSBMod";
638 std::size_t samplesCount;
671 qDebug() <<
"SSBMod::handleMessage: DSPConfigureAudio:" 672 <<
" sampleRate: " << sampleRate
673 <<
" audioType: " << audioType;
713 qDebug() <<
"SSBMod::openFileStream: " <<
m_fileName.toStdString().c_str()
732 seekPoint *=
sizeof(
Real);
740 qDebug(
"SSBMod::applyAudioSampleRate: %d", sampleRate);
764 if (band - lowCutoff < 100.0f) {
765 lowCutoff = band - 100.0f;
796 qDebug(
"SSBMod::applyFeedbackAudioSampleRate: %u", sampleRate);
813 qDebug() <<
"SSBMod::applyChannelSettings:" 814 <<
" basebandSampleRate: " << basebandSampleRate
815 <<
" outputSampleRate: " << outputSampleRate
816 <<
" inputFrequencyOffset: " << inputFrequencyOffset;
845 bool usb = settings.
m_usb;
846 QList<QString> reverseAPIKeys;
849 reverseAPIKeys.append(
"inputFrequencyOffset");
852 reverseAPIKeys.append(
"bandwidth");
855 reverseAPIKeys.append(
"lowCutoff");
858 reverseAPIKeys.append(
"usb");
861 reverseAPIKeys.append(
"toneFrequency");
864 reverseAPIKeys.append(
"volumeFactor");
867 reverseAPIKeys.append(
"spanLog2");
870 reverseAPIKeys.append(
"audioBinaural");
873 reverseAPIKeys.append(
"audioFlipChannels");
876 reverseAPIKeys.append(
"dsb");
879 reverseAPIKeys.append(
"audioMute");
882 reverseAPIKeys.append(
"playLoop");
885 reverseAPIKeys.append(
"agc");
888 reverseAPIKeys.append(
"rgbColor");
891 reverseAPIKeys.append(
"title");
894 reverseAPIKeys.append(
"modAFInput");
897 reverseAPIKeys.append(
"audioDeviceName");
909 if (band - lowCutoff < 100.0f) {
910 lowCutoff = band - 100.0f;
960 reverseAPIKeys.append(
"feedbackAudioDeviceName");
967 reverseAPIKeys.append(
"feedbackAudioSampleRate");
1012 QString& errorMessage)
1014 (void) errorMessage;
1023 const QStringList& channelSettingsKeys,
1025 QString& errorMessage)
1027 (void) errorMessage;
1029 bool frequencyOffsetChanged =
false;
1031 if (channelSettingsKeys.contains(
"inputFrequencyOffset"))
1034 frequencyOffsetChanged =
true;
1036 if (channelSettingsKeys.contains(
"bandwidth")) {
1039 if (channelSettingsKeys.contains(
"lowCutoff")) {
1042 if (channelSettingsKeys.contains(
"usb")) {
1045 if (channelSettingsKeys.contains(
"toneFrequency")) {
1048 if (channelSettingsKeys.contains(
"volumeFactor")) {
1051 if (channelSettingsKeys.contains(
"spanLog2")) {
1054 if (channelSettingsKeys.contains(
"audioBinaural")) {
1057 if (channelSettingsKeys.contains(
"audioFlipChannels")) {
1060 if (channelSettingsKeys.contains(
"dsb")) {
1063 if (channelSettingsKeys.contains(
"audioMute")) {
1066 if (channelSettingsKeys.contains(
"playLoop")) {
1069 if (channelSettingsKeys.contains(
"agc")) {
1072 if (channelSettingsKeys.contains(
"rgbColor")) {
1075 if (channelSettingsKeys.contains(
"title")) {
1078 if (channelSettingsKeys.contains(
"modAFInput")) {
1081 if (channelSettingsKeys.contains(
"audioDeviceName")) {
1084 if (channelSettingsKeys.contains(
"useReverseAPI")) {
1087 if (channelSettingsKeys.contains(
"reverseAPIAddress")) {
1090 if (channelSettingsKeys.contains(
"reverseAPIPort")) {
1093 if (channelSettingsKeys.contains(
"reverseAPIDeviceIndex")) {
1096 if (channelSettingsKeys.contains(
"reverseAPIChannelIndex")) {
1100 if (channelSettingsKeys.contains(
"cwKeyer"))
1116 if (frequencyOffsetChanged)
1139 QString& errorMessage)
1141 (void) errorMessage;
1219 if (channelSettingsKeys.contains(
"inputFrequencyOffset") || force) {
1222 if (channelSettingsKeys.contains(
"bandwidth") || force) {
1225 if (channelSettingsKeys.contains(
"lowCutoff") || force) {
1228 if (channelSettingsKeys.contains(
"usb") || force) {
1229 swgSSBModSettings->
setUsb(settings.
m_usb ? 1 : 0);
1231 if (channelSettingsKeys.contains(
"toneFrequency") || force) {
1234 if (channelSettingsKeys.contains(
"volumeFactor") || force) {
1237 if (channelSettingsKeys.contains(
"spanLog2") || force) {
1240 if (channelSettingsKeys.contains(
"audioBinaural") || force) {
1243 if (channelSettingsKeys.contains(
"audioFlipChannels") || force) {
1246 if (channelSettingsKeys.contains(
"dsb") || force) {
1247 swgSSBModSettings->
setDsb(settings.
m_dsb ? 1 : 0);
1249 if (channelSettingsKeys.contains(
"audioMute") || force) {
1252 if (channelSettingsKeys.contains(
"playLoop") || force) {
1255 if (channelSettingsKeys.contains(
"agc") || force) {
1256 swgSSBModSettings->
setAgc(settings.
m_agc ? 1 : 0);
1258 if (channelSettingsKeys.contains(
"rgbColor") || force) {
1261 if (channelSettingsKeys.contains(
"title") || force) {
1264 if (channelSettingsKeys.contains(
"modAFInput") || force) {
1267 if (channelSettingsKeys.contains(
"audioDeviceName") || force) {
1279 QString channelSettingsURL = QString(
"http://%1:%2/sdrangel/deviceset/%3/channel/%4/settings")
1285 m_networkRequest.setHeader(QNetworkRequest::ContentTypeHeader,
"application/json");
1287 QBuffer *buffer=
new QBuffer();
1288 buffer->open((QBuffer::ReadWrite));
1289 buffer->write(swgChannelSettings->
asJson().toUtf8());
1295 delete swgChannelSettings;
1310 QString channelSettingsURL = QString(
"http://%1:%2/sdrangel/deviceset/%3/channel/%4/settings")
1316 m_networkRequest.setHeader(QNetworkRequest::ContentTypeHeader,
"application/json");
1318 QBuffer *buffer=
new QBuffer();
1319 buffer->open((QBuffer::ReadWrite));
1320 buffer->write(swgChannelSettings->
asJson().toUtf8());
1326 delete swgChannelSettings;
1331 QNetworkReply::NetworkError replyError = reply->error();
1335 qWarning() <<
"SSBMod::networkManagerFinished:" 1336 <<
" error(" << (int) replyError
1337 <<
"): " << replyError
1338 <<
": " << reply->errorString();
1342 QString answer = reply->readAll();
1344 qDebug(
"SSBMod::networkManagerFinished: reply:\n%s", answer.toStdString().c_str());
void setReverseApiAddress(QString *reverse_api_address)
void setOriginatorChannelIndex(qint32 originator_channel_index)
void addAudioSink(AudioFifo *audioFifo, MessageQueue *sampleSinkMessageQueue, int outputDeviceIndex=-1)
Add the audio sink.
void calculateLevel(Complex &sample)
int getOutputSampleRate(int outputDeviceIndex=-1)
void setSpanLog2(qint32 span_log2)
void webapiFormatChannelReport(SWGSDRangel::SWGChannelReport &response)
void setSsbModReport(SWGSSBModReport *ssb_mod_report)
bool decimate(Real *distance, const Complex &next, Complex *result)
SWGSSBModReport * getSsbModReport()
qint32 getReverseApiDeviceIndex()
Complex * m_SSBFilterBuffer
void push(Message *message, bool emitSignal=true)
Push message onto queue.
void setReverseApiChannelIndex(qint32 reverse_api_channel_index)
Interpolator m_interpolator
int m_inputFrequencyOffset
void removeChannelSourceAPI(ChannelAPI *channelAPI, int streamIndex=0)
static double dbPower(double magsq, double floor=1e-12)
void webapiReverseSendSettings(QList< QString > &channelSettingsKeys, const SSBModSettings &settings, bool force)
void networkManagerFinished(QNetworkReply *reply)
void applyFeedbackAudioSampleRate(unsigned int sampleRate)
int getInputSampleRate(int inputDeviceIndex=-1)
void create(int phaseSteps, double sampleRate, double cutoff, double nbTapsPerPhase=4.5)
bool interpolate(Real *distance, const Complex &next, Complex *result)
void pullAF(Complex &sample)
quint64 m_fileSize
raw file size (bytes)
int getDeviceSetIndex() const
int getOutputDeviceIndex(const QString &deviceName) const
void setAudioBinaural(qint32 audio_binaural)
void initSimple(int rate, float pregain, float threshold, float knee, float ratio, float attack, float release)
quint32 m_audioSampleRate
void removeChannelSource(ThreadedBasebandSampleSource *sink, int streamIndex=0)
Remove a channel source (Tx)
qint64 m_inputFrequencyOffset
Complex * m_DSBFilterBuffer
uint16_t m_reverseAPIChannelIndex
qint32 getUseReverseApi()
bool m_feedbackInterpolatorConsumed
void removeAudioSink(AudioFifo *audioFifo)
Remove the audio sink.
void setCwKeyer(SWGCWKeyerSettings *cw_keyer)
void setToneFrequency(float tone_frequency)
void applySettings(const SSBModSettings &settings, bool force=false)
void seekFileStream(int seekPercentage)
QString m_feedbackAudioDeviceName
This is the audio device you send the audio samples to for audio feedback.
QString * getAudioDeviceName()
AudioVector m_audioBuffer
MovingAverageUtil< double, double, 16 > m_movingAverage
uint m_feedbackAudioBufferFill
MessageQueue * getInputMessageQueue()
Get the queue for asynchronous inbound communication.
void setVolumeFactor(float volume_factor)
SampleVector m_sampleBuffer
AudioFifo m_feedbackAudioFifo
void setChannelType(QString *channel_type)
virtual void feed(const SampleVector::const_iterator &begin, const SampleVector::const_iterator &end, bool positiveOnly)=0
void addChannelSource(ThreadedBasebandSampleSource *sink, int streamIndex=0)
Add a channel source (Tx)
void setOriginatorDeviceSetIndex(qint32 originator_device_set_index)
void setReverseApiDeviceIndex(qint32 reverse_api_device_index)
Interpolator m_feedbackInterpolator
std::complex< float > cmplx
qint32 getReverseApiPort()
Complex nextIQ()
Return next complex sample.
virtual QByteArray serialize() const
void addAudioSource(AudioFifo *audioFifo, MessageQueue *sampleSourceMessageQueue, int inputDeviceIndex=-1)
Add an audio source.
qint32 getReverseApiChannelIndex()
MessageQueue * getInputMessageQueue()
Get the queue for asynchronous inbound communication.
float m_feedbackVolumeFactor
SWGCWKeyerSettings * getCwKeyer()
void setPhase(Real phase)
void setAudioDeviceName(QString *audio_device_name)
void setUseReverseApi(qint32 use_reverse_api)
int getBasebandSampleRate() const
virtual void pullAudio(int nbSamples)
#define MESSAGE_CLASS_DEFINITION(Name, BaseClass)
bool getFadeSample(bool on, float &sample)
static const QString m_channelId
void create_filter(float f1, float f2)
Real m_interpolatorDistance
static DSPEngine * instance()
QString m_audioDeviceName
This is the audio device you get the audio samples from.
SSBModInputAF m_modAFInput
void setInputFrequencyOffset(qint64 input_frequency_offset)
void processOneSample(Complex &ci)
CWSmoother & getCWSmoother()
uint16_t m_reverseAPIDeviceIndex
void setChannelSampleRate(qint32 channel_sample_rate)
QNetworkRequest m_networkRequest
Real m_feedbackInterpolatorDistance
void setLowCutoff(float low_cutoff)
void setTitle(QString *title)
void setSsbModSettings(SWGSSBModSettings *ssb_mod_settings)
Real m_interpolatorDistanceRemain
SSBMod(DeviceAPI *deviceAPI)
void webapiReverseSendCWSettings(const CWKeyerSettings &settings)
void pushFeedback(Complex sample)
qint32 getAudioFlipChannels()
AudioVector m_feedbackAudioBuffer
static bool match(const Message *message)
void setRgbColor(qint32 rgb_color)
qint32 getAudioBinaural()
void webapiFormatChannelSettings(SWGSDRangel::SWGChannelSettings &response, const SSBModSettings &settings)
SWGSSBModSettings * getSsbModSettings()
virtual bool deserialize(const QByteArray &data)
SSBModSettings m_settings
QByteArray serialize() const
void setPlayLoop(qint32 play_loop)
Fixed< IntType, IntBits > sqrt(Fixed< IntType, IntBits > const &x)
static MsgReportFileSourceStreamData * create(int sampleRate, quint32 recordLength)
quint32 m_recordLength
record length in seconds computed from file size
void setDirection(qint32 direction)
virtual int webapiSettingsGet(SWGSDRangel::SWGChannelSettings &response, QString &errorMessage)
AudioCompressorSnd m_audioCompressor
uint32_t read(quint8 *data, uint32_t numSamples)
void setAudioMute(qint32 audio_mute)
uint16_t m_reverseAPIPort
virtual QString asJson() override
void setChannelPowerDb(float channel_power_db)
void applyAudioSampleRate(int sampleRate)
static void webapiFormatChannelSettings(SWGSDRangel::SWGCWKeyerSettings *apiCwKeyerSettings, const CWKeyerSettings &cwKeyerSettings)
void setReverseApiPort(qint32 reverse_api_port)
Complex nextQI()
Return next complex sample (reversed)
AudioDeviceManager * getAudioDeviceManager()
void setAudioFlipChannels(qint32 audio_flip_channels)
qint64 getFrequencyOffset() const
int m_DSBFilterBufferIndex
virtual int webapiSettingsPutPatch(bool force, const QStringList &channelSettingsKeys, SWGSDRangel::SWGChannelSettings &response, QString &errorMessage)
static const int m_ssbFftLen
bool m_interpolatorConsumed
BasebandSampleSink * m_sampleSink
qint64 getInputFrequencyOffset()
MessageQueue * getMessageQueueToGUI()
virtual bool handleMessage(const Message &cmd)
Processing of a message. Returns true if message has actually been processed.
static void webapiSettingsPutPatch(const QStringList &channelSettingsKeys, CWKeyerSettings &cwKeyerSettings, SWGSDRangel::SWGCWKeyerSettings *apiCwKeyerSettings)
MessageQueue * m_guiMessageQueue
Input message queue to the GUI.
int runSSB(const cmplx &in, cmplx **out, bool usb, bool getDC=true)
MessageQueue m_inputMessageQueue
Queue for asynchronous inbound communication.
void setModAfInput(qint32 mod_af_input)
void setFreq(Real freq, Real sampleRate)
int m_SSBFilterBufferIndex
QString m_reverseAPIAddress
Real m_feedbackInterpolatorDistanceRemain
int getInputDeviceIndex(const QString &deviceName) const
QNetworkAccessManager * m_networkManager
static MsgReportFileSourceStreamTiming * create(std::size_t samplesCount)
int getSampleRate() const
void applyChannelSettings(int basebandSampleRate, int outputSampleRate, int inputFrequencyOffset, bool force=false)
virtual void pull(Sample &sample)
void addChannelSourceAPI(ChannelAPI *channelAPI, int streamIndex=0)
void levelChanged(qreal rmsLevel, qreal peakLevel, int numSamples)
bool deserialize(const QByteArray &data)
const CWKeyerSettings & getSettings() const
UpChannelizer * m_channelizer
float compress(float sample)
int getIndexInDeviceSet() const
Real next()
Return next real sample.
std::complex< Real > Complex
void setAudioSampleRate(qint32 audio_sample_rate)
static const int m_levelNbSamples
int runDSB(const cmplx &in, cmplx **out, bool getDC=true)
QString * getReverseApiAddress()
void setSampleRate(int sampleRate)
bool m_feedbackAudioEnable
T max(const T &x, const T &y)
uint32_t write(const quint8 *data, uint32_t numSamples)
void removeAudioSource(AudioFifo *audioFifo)
Remove an audio source.
ThreadedBasebandSampleSource * m_threadedChannelizer
quint32 m_feedbackAudioSampleRate
void create_dsb_filter(float f2)
void setBandwidth(float bandwidth)
static const QString m_channelIdURI
void configure(MessageQueue *messageQueue, int sampleRate, int centerFrequency)
T min(const T &x, const T &y)
virtual int webapiReportGet(SWGSDRangel::SWGChannelReport &response, QString &errorMessage)