kopia lustrzana https://github.com/f4exb/sdrangel
				
				
				
			Reverse API: AM mod changes
							rodzic
							
								
									67a33e3084
								
							
						
					
					
						commit
						0dea488163
					
				| 
						 | 
				
			
			@ -14,19 +14,23 @@
 | 
			
		|||
// along with this program. If not, see <http://www.gnu.org/licenses/>.          //
 | 
			
		||||
///////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
#include "ammod.h"
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <complex.h>
 | 
			
		||||
 | 
			
		||||
#include <QTime>
 | 
			
		||||
#include <QDebug>
 | 
			
		||||
#include <QMutexLocker>
 | 
			
		||||
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <complex.h>
 | 
			
		||||
#include <QNetworkAccessManager>
 | 
			
		||||
#include <QNetworkReply>
 | 
			
		||||
#include <QBuffer>
 | 
			
		||||
#include <QJsonParseError>
 | 
			
		||||
 | 
			
		||||
#include "SWGChannelSettings.h"
 | 
			
		||||
#include "SWGChannelReport.h"
 | 
			
		||||
#include "SWGAMModReport.h"
 | 
			
		||||
 | 
			
		||||
#include "ammod.h"
 | 
			
		||||
 | 
			
		||||
#include "dsp/upchannelizer.h"
 | 
			
		||||
#include "dsp/dspengine.h"
 | 
			
		||||
#include "dsp/threadedbasebandsamplesource.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -84,10 +88,15 @@ AMMod::AMMod(DeviceSinkAPI *deviceAPI) :
 | 
			
		|||
    m_threadedChannelizer = new ThreadedBasebandSampleSource(m_channelizer, this);
 | 
			
		||||
    m_deviceAPI->addThreadedSource(m_threadedChannelizer);
 | 
			
		||||
    m_deviceAPI->addChannelAPI(this);
 | 
			
		||||
 | 
			
		||||
    m_networkManager = new QNetworkAccessManager();
 | 
			
		||||
    connect(m_networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(networkManagerFinished(QNetworkReply*)));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
AMMod::~AMMod()
 | 
			
		||||
{
 | 
			
		||||
    disconnect(m_networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(networkManagerFinished(QNetworkReply*)));
 | 
			
		||||
    delete m_networkManager;
 | 
			
		||||
    m_deviceAPI->removeChannelAPI(this);
 | 
			
		||||
    m_deviceAPI->removeThreadedSource(m_threadedChannelizer);
 | 
			
		||||
    delete m_threadedChannelizer;
 | 
			
		||||
| 
						 | 
				
			
			@ -332,6 +341,16 @@ bool AMMod::handleMessage(const Message& cmd)
 | 
			
		|||
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
    else if (CWKeyer::MsgConfigureCWKeyer::match(cmd))
 | 
			
		||||
    {
 | 
			
		||||
        const CWKeyer::MsgConfigureCWKeyer& cfg = (CWKeyer::MsgConfigureCWKeyer&) cmd;
 | 
			
		||||
 | 
			
		||||
        if (m_settings.m_useReverseAPI) {
 | 
			
		||||
            webapiReverseSendCWSettings(cfg.getSettings());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
    else if (DSPConfigureAudio::match(cmd))
 | 
			
		||||
    {
 | 
			
		||||
        DSPConfigureAudio& cfg = (DSPConfigureAudio&) cmd;
 | 
			
		||||
| 
						 | 
				
			
			@ -451,14 +470,46 @@ void AMMod::applySettings(const AMModSettings& settings, bool force)
 | 
			
		|||
            << " m_modFactor: " << settings.m_modFactor
 | 
			
		||||
            << " m_toneFrequency: " << settings.m_toneFrequency
 | 
			
		||||
            << " m_volumeFactor: " << settings.m_volumeFactor
 | 
			
		||||
            << " m_audioMute: " << settings.m_channelMute
 | 
			
		||||
            << " m_channelMute: " << settings.m_channelMute
 | 
			
		||||
            << " m_playLoop: " << settings.m_playLoop
 | 
			
		||||
            << " m_modAFInput " << settings.m_modAFInput
 | 
			
		||||
            << " m_audioDeviceName: " << settings.m_audioDeviceName
 | 
			
		||||
            << " m_useReverseAPI: " << settings.m_useReverseAPI
 | 
			
		||||
            << " m_reverseAPIAddress: " << settings.m_reverseAPIAddress
 | 
			
		||||
            << " m_reverseAPIAddress: " << settings.m_reverseAPIPort
 | 
			
		||||
            << " m_reverseAPIDeviceIndex: " << settings.m_reverseAPIDeviceIndex
 | 
			
		||||
            << " m_reverseAPIChannelIndex: " << settings.m_reverseAPIChannelIndex
 | 
			
		||||
            << " force: " << force;
 | 
			
		||||
 | 
			
		||||
    if((settings.m_rfBandwidth != m_settings.m_rfBandwidth) || force)
 | 
			
		||||
    QList<QString> reverseAPIKeys;
 | 
			
		||||
 | 
			
		||||
    if ((settings.m_inputFrequencyOffset != m_settings.m_inputFrequencyOffset) || force) {
 | 
			
		||||
        reverseAPIKeys.append("inputFrequencyOffset");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if ((settings.m_modFactor != m_settings.m_modFactor) || force) {
 | 
			
		||||
        reverseAPIKeys.append("modFactor");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if ((settings.m_volumeFactor != m_settings.m_volumeFactor) || force) {
 | 
			
		||||
        reverseAPIKeys.append("volumeFactor");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if ((settings.m_channelMute != m_settings.m_channelMute) || force) {
 | 
			
		||||
        reverseAPIKeys.append("channelMute");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if ((settings.m_playLoop != m_settings.m_playLoop) || force) {
 | 
			
		||||
        reverseAPIKeys.append("playLoop");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if ((settings.m_modAFInput != m_settings.m_modAFInput) || force) {
 | 
			
		||||
        reverseAPIKeys.append("modAFInput");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if ((settings.m_rfBandwidth != m_settings.m_rfBandwidth) || force)
 | 
			
		||||
    {
 | 
			
		||||
        reverseAPIKeys.append("rfBandwidth");
 | 
			
		||||
        m_settingsMutex.lock();
 | 
			
		||||
        m_interpolatorDistanceRemain = 0;
 | 
			
		||||
        m_interpolatorConsumed = false;
 | 
			
		||||
| 
						 | 
				
			
			@ -469,6 +520,7 @@ void AMMod::applySettings(const AMModSettings& settings, bool force)
 | 
			
		|||
 | 
			
		||||
    if ((settings.m_toneFrequency != m_settings.m_toneFrequency) || force)
 | 
			
		||||
    {
 | 
			
		||||
        reverseAPIKeys.append("toneFrequency");
 | 
			
		||||
        m_settingsMutex.lock();
 | 
			
		||||
        m_toneNco.setFreq(settings.m_toneFrequency, m_audioSampleRate);
 | 
			
		||||
        m_settingsMutex.unlock();
 | 
			
		||||
| 
						 | 
				
			
			@ -476,16 +528,28 @@ void AMMod::applySettings(const AMModSettings& settings, bool 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_audioFifo, getInputMessageQueue(), audioDeviceIndex);
 | 
			
		||||
        uint32_t audioSampleRate = audioDeviceManager->getInputSampleRate(audioDeviceIndex);
 | 
			
		||||
 | 
			
		||||
        if (m_audioSampleRate != audioSampleRate) {
 | 
			
		||||
            reverseAPIKeys.append("audioSampleRate");
 | 
			
		||||
            applyAudioSampleRate(audioSampleRate);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (settings.m_useReverseAPI)
 | 
			
		||||
    {
 | 
			
		||||
        bool fullUpdate = ((m_settings.m_useReverseAPI != settings.m_useReverseAPI) && settings.m_useReverseAPI) ||
 | 
			
		||||
                (m_settings.m_reverseAPIAddress != settings.m_reverseAPIAddress) ||
 | 
			
		||||
                (m_settings.m_reverseAPIPort != settings.m_reverseAPIPort) ||
 | 
			
		||||
                (m_settings.m_reverseAPIDeviceIndex != settings.m_reverseAPIDeviceIndex) ||
 | 
			
		||||
                (m_settings.m_reverseAPIChannelIndex != settings.m_reverseAPIChannelIndex);
 | 
			
		||||
        webapiReverseSendSettings(reverseAPIKeys, settings, fullUpdate || force);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    m_settings = settings;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -684,3 +748,131 @@ void AMMod::webapiFormatChannelReport(SWGSDRangel::SWGChannelReport& response)
 | 
			
		|||
    response.getAmModReport()->setAudioSampleRate(m_audioSampleRate);
 | 
			
		||||
    response.getAmModReport()->setChannelSampleRate(m_outputSampleRate);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void AMMod::webapiReverseSendSettings(QList<QString>& channelSettingsKeys, const AMModSettings& settings, bool force)
 | 
			
		||||
{
 | 
			
		||||
    SWGSDRangel::SWGChannelSettings *swgChannelSettings = new SWGSDRangel::SWGChannelSettings();
 | 
			
		||||
    swgChannelSettings->setTx(1);
 | 
			
		||||
    swgChannelSettings->setChannelType(new QString("AMMod"));
 | 
			
		||||
    swgChannelSettings->setAmModSettings(new SWGSDRangel::SWGAMModSettings());
 | 
			
		||||
    SWGSDRangel::SWGAMModSettings *swgAMModSettings = swgChannelSettings->getAmModSettings();
 | 
			
		||||
 | 
			
		||||
    // transfer data that has been modified. When force is on transfer all data except reverse API data
 | 
			
		||||
 | 
			
		||||
    if (channelSettingsKeys.contains("channelMute") || force) {
 | 
			
		||||
        swgAMModSettings->setChannelMute(settings.m_channelMute ? 1 : 0);
 | 
			
		||||
    }
 | 
			
		||||
    if (channelSettingsKeys.contains("inputFrequencyOffset") || force) {
 | 
			
		||||
        swgAMModSettings->setInputFrequencyOffset(settings.m_inputFrequencyOffset);
 | 
			
		||||
    }
 | 
			
		||||
    if (channelSettingsKeys.contains("modAFInput") || force) {
 | 
			
		||||
        swgAMModSettings->setModAfInput((int) settings.m_modAFInput);
 | 
			
		||||
    }
 | 
			
		||||
    if (channelSettingsKeys.contains("audioDeviceName") || force) {
 | 
			
		||||
        swgAMModSettings->setAudioDeviceName(new QString(settings.m_audioDeviceName));
 | 
			
		||||
    }
 | 
			
		||||
    if (channelSettingsKeys.contains("playLoop") || force) {
 | 
			
		||||
        swgAMModSettings->setPlayLoop(settings.m_playLoop ? 1 : 0);
 | 
			
		||||
    }
 | 
			
		||||
    if (channelSettingsKeys.contains("rfBandwidth") || force) {
 | 
			
		||||
        swgAMModSettings->setRfBandwidth(settings.m_rfBandwidth);
 | 
			
		||||
    }
 | 
			
		||||
    if (channelSettingsKeys.contains("rgbColor") || force) {
 | 
			
		||||
        swgAMModSettings->setRgbColor(settings.m_rgbColor);
 | 
			
		||||
    }
 | 
			
		||||
    if (channelSettingsKeys.contains("title") || force) {
 | 
			
		||||
        swgAMModSettings->setTitle(new QString(settings.m_title));
 | 
			
		||||
    }
 | 
			
		||||
    if (channelSettingsKeys.contains("toneFrequency") || force) {
 | 
			
		||||
        swgAMModSettings->setToneFrequency(settings.m_toneFrequency);
 | 
			
		||||
    }
 | 
			
		||||
    if (channelSettingsKeys.contains("volumeFactor") || force) {
 | 
			
		||||
        swgAMModSettings->setVolumeFactor(settings.m_volumeFactor);
 | 
			
		||||
    }
 | 
			
		||||
    if (channelSettingsKeys.contains("modFactor") || force) {
 | 
			
		||||
        swgAMModSettings->setModFactor(settings.m_modFactor);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (force)
 | 
			
		||||
    {
 | 
			
		||||
        const CWKeyerSettings& cwKeyerSettings = m_cwKeyer.getSettings();
 | 
			
		||||
        swgAMModSettings->setCwKeyer(new SWGSDRangel::SWGCWKeyerSettings());
 | 
			
		||||
        SWGSDRangel::SWGCWKeyerSettings *apiCwKeyerSettings = swgAMModSettings->getCwKeyer();
 | 
			
		||||
        apiCwKeyerSettings->setLoop(cwKeyerSettings.m_loop ? 1 : 0);
 | 
			
		||||
        apiCwKeyerSettings->setMode(cwKeyerSettings.m_mode);
 | 
			
		||||
        apiCwKeyerSettings->setSampleRate(cwKeyerSettings.m_sampleRate);
 | 
			
		||||
        apiCwKeyerSettings->setText(new QString(cwKeyerSettings.m_text));
 | 
			
		||||
        apiCwKeyerSettings->setWpm(cwKeyerSettings.m_wpm);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    QString channelSettingsURL = QString("http://%1:%2/sdrangel/deviceset/%3/channel/%4/settings")
 | 
			
		||||
            .arg(settings.m_reverseAPIAddress)
 | 
			
		||||
            .arg(settings.m_reverseAPIPort)
 | 
			
		||||
            .arg(settings.m_reverseAPIDeviceIndex)
 | 
			
		||||
            .arg(settings.m_reverseAPIChannelIndex);
 | 
			
		||||
    m_networkRequest.setUrl(QUrl(channelSettingsURL));
 | 
			
		||||
    m_networkRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
 | 
			
		||||
 | 
			
		||||
    QBuffer *buffer=new QBuffer();
 | 
			
		||||
    buffer->open((QBuffer::ReadWrite));
 | 
			
		||||
    buffer->write(swgChannelSettings->asJson().toUtf8());
 | 
			
		||||
    buffer->seek(0);
 | 
			
		||||
 | 
			
		||||
    // Always use PATCH to avoid passing reverse API settings
 | 
			
		||||
    m_networkManager->sendCustomRequest(m_networkRequest, "PATCH", buffer);
 | 
			
		||||
 | 
			
		||||
    delete swgChannelSettings;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void AMMod::webapiReverseSendCWSettings(const CWKeyerSettings& cwKeyerSettings)
 | 
			
		||||
{
 | 
			
		||||
    SWGSDRangel::SWGChannelSettings *swgChannelSettings = new SWGSDRangel::SWGChannelSettings();
 | 
			
		||||
    swgChannelSettings->setTx(1);
 | 
			
		||||
    swgChannelSettings->setChannelType(new QString("AMMod"));
 | 
			
		||||
    swgChannelSettings->setAmModSettings(new SWGSDRangel::SWGAMModSettings());
 | 
			
		||||
    SWGSDRangel::SWGAMModSettings *swgAMModSettings = swgChannelSettings->getAmModSettings();
 | 
			
		||||
 | 
			
		||||
    swgAMModSettings->setCwKeyer(new SWGSDRangel::SWGCWKeyerSettings());
 | 
			
		||||
    SWGSDRangel::SWGCWKeyerSettings *apiCwKeyerSettings = swgAMModSettings->getCwKeyer();
 | 
			
		||||
    apiCwKeyerSettings->setLoop(cwKeyerSettings.m_loop ? 1 : 0);
 | 
			
		||||
    apiCwKeyerSettings->setMode(cwKeyerSettings.m_mode);
 | 
			
		||||
    apiCwKeyerSettings->setSampleRate(cwKeyerSettings.m_sampleRate);
 | 
			
		||||
    apiCwKeyerSettings->setText(new QString(cwKeyerSettings.m_text));
 | 
			
		||||
    apiCwKeyerSettings->setWpm(cwKeyerSettings.m_wpm);
 | 
			
		||||
 | 
			
		||||
    QString channelSettingsURL = QString("http://%1:%2/sdrangel/deviceset/%3/channel/%4/settings")
 | 
			
		||||
            .arg(m_settings.m_reverseAPIAddress)
 | 
			
		||||
            .arg(m_settings.m_reverseAPIPort)
 | 
			
		||||
            .arg(m_settings.m_reverseAPIDeviceIndex)
 | 
			
		||||
            .arg(m_settings.m_reverseAPIChannelIndex);
 | 
			
		||||
    m_networkRequest.setUrl(QUrl(channelSettingsURL));
 | 
			
		||||
    m_networkRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
 | 
			
		||||
 | 
			
		||||
    QBuffer *buffer=new QBuffer();
 | 
			
		||||
    buffer->open((QBuffer::ReadWrite));
 | 
			
		||||
    buffer->write(swgChannelSettings->asJson().toUtf8());
 | 
			
		||||
    buffer->seek(0);
 | 
			
		||||
 | 
			
		||||
    // Always use PATCH to avoid passing reverse API settings
 | 
			
		||||
    m_networkManager->sendCustomRequest(m_networkRequest, "PATCH", buffer);
 | 
			
		||||
 | 
			
		||||
    delete swgChannelSettings;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void AMMod::networkManagerFinished(QNetworkReply *reply)
 | 
			
		||||
{
 | 
			
		||||
    QNetworkReply::NetworkError replyError = reply->error();
 | 
			
		||||
 | 
			
		||||
    if (replyError)
 | 
			
		||||
    {
 | 
			
		||||
        qWarning() << "AMMod::networkManagerFinished:"
 | 
			
		||||
                << " error(" << (int) replyError
 | 
			
		||||
                << "): " << replyError
 | 
			
		||||
                << ": " << reply->errorString();
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    QString answer = reply->readAll();
 | 
			
		||||
    answer.chop(1); // remove last \n
 | 
			
		||||
    qDebug("AMMod::networkManagerFinished: reply:\n%s", answer.toStdString().c_str());
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -17,11 +17,13 @@
 | 
			
		|||
#ifndef PLUGINS_CHANNELTX_MODAM_AMMOD_H_
 | 
			
		||||
#define PLUGINS_CHANNELTX_MODAM_AMMOD_H_
 | 
			
		||||
 | 
			
		||||
#include <QMutex>
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <fstream>
 | 
			
		||||
 | 
			
		||||
#include <QMutex>
 | 
			
		||||
#include <QNetworkRequest>
 | 
			
		||||
 | 
			
		||||
#include "dsp/basebandsamplesource.h"
 | 
			
		||||
#include "channel/channelsourceapi.h"
 | 
			
		||||
#include "dsp/nco.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -35,6 +37,8 @@
 | 
			
		|||
 | 
			
		||||
#include "ammodsettings.h"
 | 
			
		||||
 | 
			
		||||
class QNetworkAccessManager;
 | 
			
		||||
class QNetworkReply;
 | 
			
		||||
class ThreadedBasebandSampleSource;
 | 
			
		||||
class UpChannelizer;
 | 
			
		||||
class DeviceSinkAPI;
 | 
			
		||||
| 
						 | 
				
			
			@ -291,6 +295,9 @@ private:
 | 
			
		|||
 | 
			
		||||
    static const int m_levelNbSamples;
 | 
			
		||||
 | 
			
		||||
    QNetworkAccessManager *m_networkManager;
 | 
			
		||||
    QNetworkRequest m_networkRequest;
 | 
			
		||||
 | 
			
		||||
    void applyAudioSampleRate(int sampleRate);
 | 
			
		||||
    void applyChannelSettings(int basebandSampleRate, int outputSampleRate, int inputFrequencyOffset, bool force = false);
 | 
			
		||||
    void applySettings(const AMModSettings& settings, bool force = false);
 | 
			
		||||
| 
						 | 
				
			
			@ -301,6 +308,11 @@ private:
 | 
			
		|||
    void seekFileStream(int seekPercentage);
 | 
			
		||||
    void webapiFormatChannelSettings(SWGSDRangel::SWGChannelSettings& response, const AMModSettings& settings);
 | 
			
		||||
    void webapiFormatChannelReport(SWGSDRangel::SWGChannelReport& response);
 | 
			
		||||
    void webapiReverseSendSettings(QList<QString>& channelSettingsKeys, const AMModSettings& settings, bool force);
 | 
			
		||||
    void webapiReverseSendCWSettings(const CWKeyerSettings& settings);
 | 
			
		||||
 | 
			
		||||
private slots:
 | 
			
		||||
    void networkManagerFinished(QNetworkReply *reply);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -279,12 +279,22 @@ void AMModGUI::onWidgetRolled(QWidget* widget, bool rollDown)
 | 
			
		|||
void AMModGUI::onMenuDialogCalled(const QPoint &p)
 | 
			
		||||
{
 | 
			
		||||
    BasicChannelSettingsDialog dialog(&m_channelMarker, this);
 | 
			
		||||
    dialog.setUseReverseAPI(m_settings.m_useReverseAPI);
 | 
			
		||||
    dialog.setReverseAPIAddress(m_settings.m_reverseAPIAddress);
 | 
			
		||||
    dialog.setReverseAPIPort(m_settings.m_reverseAPIPort);
 | 
			
		||||
    dialog.setReverseAPIDeviceIndex(m_settings.m_reverseAPIDeviceIndex);
 | 
			
		||||
    dialog.setReverseAPIChannelIndex(m_settings.m_reverseAPIChannelIndex);
 | 
			
		||||
    dialog.move(p);
 | 
			
		||||
    dialog.exec();
 | 
			
		||||
 | 
			
		||||
    m_settings.m_inputFrequencyOffset = m_channelMarker.getCenterFrequency();
 | 
			
		||||
    m_settings.m_rgbColor = m_channelMarker.getColor().rgb();
 | 
			
		||||
    m_settings.m_title = m_channelMarker.getTitle();
 | 
			
		||||
    m_settings.m_useReverseAPI = dialog.useReverseAPI();
 | 
			
		||||
    m_settings.m_reverseAPIAddress = dialog.getReverseAPIAddress();
 | 
			
		||||
    m_settings.m_reverseAPIPort = dialog.getReverseAPIPort();
 | 
			
		||||
    m_settings.m_reverseAPIDeviceIndex = dialog.getReverseAPIDeviceIndex();
 | 
			
		||||
    m_settings.m_reverseAPIChannelIndex = dialog.getReverseAPIChannelIndex();
 | 
			
		||||
 | 
			
		||||
    setWindowTitle(m_settings.m_title);
 | 
			
		||||
    setTitleColor(m_settings.m_rgbColor);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -41,6 +41,11 @@ void AMModSettings::resetToDefaults()
 | 
			
		|||
    m_title = "AM Modulator";
 | 
			
		||||
    m_modAFInput = AMModInputAF::AMModInputNone;
 | 
			
		||||
    m_audioDeviceName = AudioDeviceManager::m_defaultDeviceName;
 | 
			
		||||
    m_useReverseAPI = false;
 | 
			
		||||
    m_reverseAPIAddress = "127.0.0.1";
 | 
			
		||||
    m_reverseAPIPort = 8888;
 | 
			
		||||
    m_reverseAPIDeviceIndex = 0;
 | 
			
		||||
    m_reverseAPIChannelIndex = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QByteArray AMModSettings::serialize() const
 | 
			
		||||
| 
						 | 
				
			
			@ -65,6 +70,11 @@ QByteArray AMModSettings::serialize() const
 | 
			
		|||
    s.writeString(9, m_title);
 | 
			
		||||
    s.writeString(10, m_audioDeviceName);
 | 
			
		||||
    s.writeS32(11, (int) m_modAFInput);
 | 
			
		||||
    s.writeBool(12, m_useReverseAPI);
 | 
			
		||||
    s.writeString(13, m_reverseAPIAddress);
 | 
			
		||||
    s.writeU32(14, m_reverseAPIPort);
 | 
			
		||||
    s.writeU32(15, m_reverseAPIDeviceIndex);
 | 
			
		||||
    s.writeU32(16, m_reverseAPIChannelIndex);
 | 
			
		||||
 | 
			
		||||
    return s.final();
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -83,6 +93,7 @@ bool AMModSettings::deserialize(const QByteArray& data)
 | 
			
		|||
    {
 | 
			
		||||
        QByteArray bytetmp;
 | 
			
		||||
        qint32 tmp;
 | 
			
		||||
        uint32_t utmp;
 | 
			
		||||
 | 
			
		||||
        d.readS32(1, &tmp, 0);
 | 
			
		||||
        m_inputFrequencyOffset = tmp;
 | 
			
		||||
| 
						 | 
				
			
			@ -112,6 +123,21 @@ bool AMModSettings::deserialize(const QByteArray& data)
 | 
			
		|||
            m_modAFInput = (AMModInputAF) tmp;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        d.readBool(12, &m_useReverseAPI, false);
 | 
			
		||||
        d.readString(13, &m_reverseAPIAddress, "127.0.0.1");
 | 
			
		||||
        d.readU32(14, &utmp, 0);
 | 
			
		||||
 | 
			
		||||
        if ((utmp > 1023) && (utmp < 65535)) {
 | 
			
		||||
            m_reverseAPIPort = utmp;
 | 
			
		||||
        } else {
 | 
			
		||||
            m_reverseAPIPort = 8888;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        d.readU32(15, &utmp, 0);
 | 
			
		||||
        m_reverseAPIDeviceIndex = utmp > 99 ? 99 : utmp;
 | 
			
		||||
        d.readU32(16, &utmp, 0);
 | 
			
		||||
        m_reverseAPIChannelIndex = utmp > 99 ? 99 : utmp;
 | 
			
		||||
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -43,6 +43,11 @@ struct AMModSettings
 | 
			
		|||
    QString m_title;
 | 
			
		||||
    AMModInputAF m_modAFInput;
 | 
			
		||||
    QString m_audioDeviceName;
 | 
			
		||||
    bool m_useReverseAPI;
 | 
			
		||||
    QString m_reverseAPIAddress;
 | 
			
		||||
    uint16_t m_reverseAPIPort;
 | 
			
		||||
    uint16_t m_reverseAPIDeviceIndex;
 | 
			
		||||
    uint16_t m_reverseAPIChannelIndex;
 | 
			
		||||
 | 
			
		||||
    Serializable *m_channelMarker;
 | 
			
		||||
    Serializable *m_cwKeyerGUI;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,6 +22,7 @@
 | 
			
		|||
#include "ui_cwkeyergui.h"
 | 
			
		||||
#include "dsp/cwkeyer.h"
 | 
			
		||||
#include "util/simpleserializer.h"
 | 
			
		||||
#include "util/messagequeue.h"
 | 
			
		||||
 | 
			
		||||
CWKeyerGUI::CWKeyerGUI(QWidget* parent) :
 | 
			
		||||
    QWidget(parent),
 | 
			
		||||
| 
						 | 
				
			
			@ -44,6 +45,7 @@ void CWKeyerGUI::setBuddies(MessageQueue* messageQueue, CWKeyer* cwKeyer)
 | 
			
		|||
    m_messageQueue = messageQueue;
 | 
			
		||||
    m_cwKeyer = cwKeyer;
 | 
			
		||||
    applySettings();
 | 
			
		||||
    sendSettings();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CWKeyerGUI::resetToDefaults()
 | 
			
		||||
| 
						 | 
				
			
			@ -83,6 +85,8 @@ bool CWKeyerGUI::deserialize(const QByteArray& data)
 | 
			
		|||
        ui->cwSpeed->setValue(aValue);
 | 
			
		||||
 | 
			
		||||
        applySettings();
 | 
			
		||||
        sendSettings();
 | 
			
		||||
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
| 
						 | 
				
			
			@ -102,13 +106,22 @@ void CWKeyerGUI::on_cwTextClear_clicked(bool checked)
 | 
			
		|||
 | 
			
		||||
void CWKeyerGUI::on_cwTextEdit_editingFinished()
 | 
			
		||||
{
 | 
			
		||||
    if (m_doApplySettings) { m_cwKeyer->setText(ui->cwTextEdit->text()); }
 | 
			
		||||
    if (m_doApplySettings)
 | 
			
		||||
    {
 | 
			
		||||
        m_cwKeyer->setText(ui->cwTextEdit->text());
 | 
			
		||||
        sendSettings();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CWKeyerGUI::on_cwSpeed_valueChanged(int value)
 | 
			
		||||
{
 | 
			
		||||
    ui->cwSpeedText->setText(QString("%1").arg(value));
 | 
			
		||||
    if (m_doApplySettings) { m_cwKeyer->setWPM(value); }
 | 
			
		||||
 | 
			
		||||
    if (m_doApplySettings)
 | 
			
		||||
    {
 | 
			
		||||
        m_cwKeyer->setWPM(value);
 | 
			
		||||
        sendSettings();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CWKeyerGUI::on_playDots_toggled(bool checked)
 | 
			
		||||
| 
						 | 
				
			
			@ -117,7 +130,11 @@ void CWKeyerGUI::on_playDots_toggled(bool checked)
 | 
			
		|||
    ui->playDashes->setEnabled(!checked);
 | 
			
		||||
    ui->playText->setEnabled(!checked);
 | 
			
		||||
 | 
			
		||||
    if (m_doApplySettings) { m_cwKeyer->setMode(checked ? CWKeyerSettings::CWDots : CWKeyerSettings::CWNone); }
 | 
			
		||||
    if (m_doApplySettings)
 | 
			
		||||
    {
 | 
			
		||||
        m_cwKeyer->setMode(checked ? CWKeyerSettings::CWDots : CWKeyerSettings::CWNone);
 | 
			
		||||
        sendSettings();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CWKeyerGUI::on_playDashes_toggled(bool checked)
 | 
			
		||||
| 
						 | 
				
			
			@ -126,7 +143,11 @@ void CWKeyerGUI::on_playDashes_toggled(bool checked)
 | 
			
		|||
    //ui->playDashes->setEnabled(!checked);
 | 
			
		||||
    ui->playText->setEnabled(!checked);
 | 
			
		||||
 | 
			
		||||
    if (m_doApplySettings) { m_cwKeyer->setMode(checked ? CWKeyerSettings::CWDashes : CWKeyerSettings::CWNone); }
 | 
			
		||||
    if (m_doApplySettings)
 | 
			
		||||
    {
 | 
			
		||||
        m_cwKeyer->setMode(checked ? CWKeyerSettings::CWDashes : CWKeyerSettings::CWNone);
 | 
			
		||||
        sendSettings();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CWKeyerGUI::on_playText_toggled(bool checked)
 | 
			
		||||
| 
						 | 
				
			
			@ -135,7 +156,11 @@ void CWKeyerGUI::on_playText_toggled(bool checked)
 | 
			
		|||
    ui->playDashes->setEnabled(!checked);
 | 
			
		||||
    //ui->playText->setEnabled(!checked);
 | 
			
		||||
 | 
			
		||||
    if (m_doApplySettings) { m_cwKeyer->setMode(checked ? CWKeyerSettings::CWText : CWKeyerSettings::CWNone); }
 | 
			
		||||
    if (m_doApplySettings)
 | 
			
		||||
    {
 | 
			
		||||
        m_cwKeyer->setMode(checked ? CWKeyerSettings::CWText : CWKeyerSettings::CWNone);
 | 
			
		||||
        sendSettings();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (checked) {
 | 
			
		||||
        ui->playStop->setChecked(true);
 | 
			
		||||
| 
						 | 
				
			
			@ -146,17 +171,18 @@ void CWKeyerGUI::on_playText_toggled(bool checked)
 | 
			
		|||
 | 
			
		||||
void CWKeyerGUI::on_playLoopCW_toggled(bool checked)
 | 
			
		||||
{
 | 
			
		||||
    if (m_doApplySettings) { m_cwKeyer->setLoop(checked); }
 | 
			
		||||
    if (m_doApplySettings)
 | 
			
		||||
    {
 | 
			
		||||
        m_cwKeyer->setLoop(checked);
 | 
			
		||||
        sendSettings();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CWKeyerGUI::on_playStop_toggled(bool checked)
 | 
			
		||||
{
 | 
			
		||||
    if (checked)
 | 
			
		||||
    {
 | 
			
		||||
    if (checked) {
 | 
			
		||||
        m_cwKeyer->resetText();
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
    } else {
 | 
			
		||||
        m_cwKeyer->stopText();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -200,3 +226,12 @@ void CWKeyerGUI::blockApplySettings(bool block)
 | 
			
		|||
{
 | 
			
		||||
    m_doApplySettings = !block;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CWKeyerGUI::sendSettings()
 | 
			
		||||
{
 | 
			
		||||
    if (m_cwKeyer && m_messageQueue)
 | 
			
		||||
    {
 | 
			
		||||
        CWKeyer::MsgConfigureCWKeyer *msg = CWKeyer::MsgConfigureCWKeyer::create(m_cwKeyer->getSettings(), false);
 | 
			
		||||
        m_messageQueue->push(msg);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -54,6 +54,7 @@ private:
 | 
			
		|||
    bool m_doApplySettings;
 | 
			
		||||
 | 
			
		||||
    void applySettings();
 | 
			
		||||
    void sendSettings();
 | 
			
		||||
    void blockApplySettings(bool block);
 | 
			
		||||
 | 
			
		||||
private slots:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Ładowanie…
	
		Reference in New Issue