From 8d1eea25b10c7ce7eaaa7e62bb1c0c29772813ab Mon Sep 17 00:00:00 2001 From: Roland Rossgotterer Date: Fri, 20 Sep 2019 21:46:51 +0200 Subject: [PATCH] Implement VolumeSampleProvider to gain in and output fixup! Implement VolumeSampleProvider to gain in and output --- src/blackcore/afv/audio/input.cpp | 26 +++++++----- src/blackcore/afv/audio/input.h | 8 ++-- src/blackcore/afv/clients/afvclient.cpp | 25 +++++++----- src/blackcore/afv/clients/afvclient.h | 15 +++---- .../sampleprovider/volumesampleprovider.cpp | 40 +++++++++++++++++++ .../sampleprovider/volumesampleprovider.h | 36 +++++++++++++++++ 6 files changed, 119 insertions(+), 31 deletions(-) create mode 100644 src/blacksound/sampleprovider/volumesampleprovider.cpp create mode 100644 src/blacksound/sampleprovider/volumesampleprovider.h diff --git a/src/blackcore/afv/audio/input.cpp b/src/blackcore/afv/audio/input.cpp index 28785dd91..e94f5a61f 100644 --- a/src/blackcore/afv/audio/input.cpp +++ b/src/blackcore/afv/audio/input.cpp @@ -76,12 +76,12 @@ namespace BlackCore m_opusBytesEncoded = opusBytesEncoded; } - float Input::volume() const + double Input::volume() const { return m_volume; } - void Input::setVolume(float volume) + void Input::setVolume(double volume) { m_volume = volume; } @@ -132,18 +132,24 @@ namespace BlackCore { const QVector samples = convertBytesTo16BitPCM(frame); + int value = 0; + for (qint16 &sample : samples) + { + value = sample * m_volume; + if (value > std::numeric_limits::max()) + value = std::numeric_limits::max(); + if (value < std::numeric_limits::min()) + value = std::numeric_limits::min(); + samples = static_cast(value); + + sampleInput = qAbs(sampleInput); + m_maxSampleInput = qMax(qAbs(sampleInput), m_maxSampleInput); + } + int length; QByteArray encodedBuffer = m_encoder.encode(samples, samples.size(), &length); m_opusBytesEncoded += length; - for (const qint16 sample : samples) - { - qint16 sampleInput = sample; - sampleInput = qAbs(sampleInput); - if (sampleInput > m_maxSampleInput) - m_maxSampleInput = sampleInput; - } - m_sampleCount += samples.size(); if (m_sampleCount >= c_sampleCountPerEvent) { diff --git a/src/blackcore/afv/audio/input.h b/src/blackcore/afv/audio/input.h index e8b25188a..9e1ad1981 100644 --- a/src/blackcore/afv/audio/input.h +++ b/src/blackcore/afv/audio/input.h @@ -74,8 +74,8 @@ namespace BlackCore int opusBytesEncoded() const; void setOpusBytesEncoded(int opusBytesEncoded); - float volume() const; - void setVolume(float volume); + double volume() const; + void setVolume(double volume); void start(const QAudioDeviceInfo &inputDevice); void stop(); @@ -95,9 +95,9 @@ namespace BlackCore bool m_started = false; int m_opusBytesEncoded = 0; - float m_volume = 1.0f; + double m_volume = 1.0; int m_sampleCount = 0; - float m_maxSampleInput = 0; + qint16 m_maxSampleInput = 0; const int c_sampleCountPerEvent = 4800; const float maxDb = 0; diff --git a/src/blackcore/afv/clients/afvclient.cpp b/src/blackcore/afv/clients/afvclient.cpp index 52e9a5b36..0a71d14c7 100644 --- a/src/blackcore/afv/clients/afvclient.cpp +++ b/src/blackcore/afv/clients/afvclient.cpp @@ -122,9 +122,10 @@ namespace BlackCore soundcardSampleProvider = new SoundcardSampleProvider(c_sampleRate, transceiverIDs, this); connect(soundcardSampleProvider, &SoundcardSampleProvider::receivingCallsignsChanged, this, &AFVClient::receivingCallsignsChanged); - // TODO outputSampleProvider = new VolumeSampleProvider(soundcardSampleProvider); + outputSampleProvider = new VolumeSampleProvider(soundcardSampleProvider, this); + outputSampleProvider->setVolume(m_outputVolume); - m_output->start(outputDevice, soundcardSampleProvider); + m_output->start(outputDevice, outputSampleProvider); m_input->start(inputDevice); m_startDateTimeUtc = QDateTime::currentDateTimeUtc(); @@ -140,7 +141,8 @@ namespace BlackCore soundcardSampleProvider = new SoundcardSampleProvider(c_sampleRate, { 0, 1 }, this); connect(soundcardSampleProvider, &SoundcardSampleProvider::receivingCallsignsChanged, this, &AFVClient::receivingCallsignsChanged); - // TODO outputSampleProvider = new VolumeSampleProvider(soundcardSampleProvider); + outputSampleProvider = new VolumeSampleProvider(soundcardSampleProvider, this); + outputSampleProvider->setVolume(m_outputVolume); QAudioDeviceInfo inputDevice = QAudioDeviceInfo::defaultInputDevice(); for (const auto &device : QAudioDeviceInfo::availableDevices(QAudio::AudioInput)) @@ -162,7 +164,7 @@ namespace BlackCore } } - m_output->start(outputDevice, soundcardSampleProvider); + m_output->start(outputDevice, outputSampleProvider); m_input->start(inputDevice); m_startDateTimeUtc = QDateTime::currentDateTimeUtc(); @@ -296,12 +298,12 @@ namespace BlackCore qDebug() << "PTT:" << active; } - void AFVClient::setInputVolumeDb(float value) + void AFVClient::setInputVolumeDb(double value) { if (value > 18) { value = 18; } if (value < -18) { value = -18; } m_inputVolumeDb = value; - // TODO input.Volume = (float)System.Math.Pow(10, value / 20); + m_input->setVolume(qPow(10, value / 20)); } void AFVClient::opusDataAvailable(const OpusDataAvailableArgs &args) @@ -404,17 +406,20 @@ namespace BlackCore updateTransceivers(); } - float AFVClient::getOutputVolume() const + float AFVClient::getOutputVolumeDb() const { return m_outputVolume; } - void AFVClient::setOutputVolume(float outputVolume) + void AFVClient::setOutputVolumeDb(double outputVolume) { if (outputVolume > 18) { m_outputVolume = 18; } if (outputVolume < -60) { m_outputVolume = -60; } - // m_outputVolume = (float)System.Math.Pow(10, value / 20); - // TODO outputSampleProvider.Volume = outputVolume; + m_outputVolume = qPow(10, m_outputVolume / 20); + if (outputSampleProvider) + { + outputSampleProvider->setVolume(outputVolume); + } } AFVClient::ConnectionStatus AFVClient::getConnectionStatus() const diff --git a/src/blackcore/afv/clients/afvclient.h b/src/blackcore/afv/clients/afvclient.h index ede391094..05c674979 100644 --- a/src/blackcore/afv/clients/afvclient.h +++ b/src/blackcore/afv/clients/afvclient.h @@ -19,6 +19,7 @@ #include "blackcore/blackcoreexport.h" #include "blackcore/context/contextownaircraft.h" +#include "blacksound/sampleprovider/volumesampleprovider.h" #include #include @@ -89,15 +90,15 @@ namespace BlackCore Q_INVOKABLE void setLoopBack(bool on) { m_loopbackOn = on; } - float inputVolumeDb() const + double inputVolumeDb() const { return m_inputVolumeDb; } - void setInputVolumeDb(float value); + void setInputVolumeDb(double value); - float getOutputVolume() const; - void setOutputVolume(float outputVolume); + float getOutputVolumeDb() const; + void setOutputVolumeDb(double outputVolume); float getInputVolumePeakVU() const { return m_inputVolumeStream.PeakVU; } float getOutputVolumePeakVU() const { return m_outputVolumeStream.PeakVU; } @@ -136,7 +137,7 @@ namespace BlackCore Audio::Output *m_output = nullptr; Audio::SoundcardSampleProvider *soundcardSampleProvider = nullptr; - // TODO VolumeSampleProvider outputSampleProvider; + VolumeSampleProvider *outputSampleProvider = nullptr; bool m_transmit = false; bool m_transmitHistory = false; @@ -145,8 +146,8 @@ namespace BlackCore bool m_isStarted = false; QDateTime m_startDateTimeUtc; - float m_inputVolumeDb; - float m_outputVolume = 1; + double m_inputVolumeDb; + double m_outputVolume = 1.0; double m_maxDbReadingInPTTInterval = -100; diff --git a/src/blacksound/sampleprovider/volumesampleprovider.cpp b/src/blacksound/sampleprovider/volumesampleprovider.cpp new file mode 100644 index 000000000..efddfbc9a --- /dev/null +++ b/src/blacksound/sampleprovider/volumesampleprovider.cpp @@ -0,0 +1,40 @@ +/* Copyright (C) 2019 + * swift project Community / Contributors + * + * This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level + * directory of this distribution. No part of swift project, including this file, may be copied, modified, propagated, + * or distributed except according to the terms contained in the LICENSE file. + */ + +//! \file + +#include "volumesampleprovider.h" + +VolumeSampleProvider::VolumeSampleProvider(ISampleProvider *sourceProvider, QObject *parent) : + ISampleProvider(parent), + m_sourceProvider(sourceProvider) +{ } + +int VolumeSampleProvider::readSamples(QVector &samples, qint64 count) +{ + int samplesRead = m_sourceProvider->readSamples(samples, count); + + if (! qFuzzyCompare(m_volume, 1.0)) + { + for (int n = 0; n < samplesRead; n++) + { + samples[n] *= m_volume; + } + } + return samplesRead; +} + +double VolumeSampleProvider::volume() const +{ + return m_volume; +} + +void VolumeSampleProvider::setVolume(double volume) +{ + m_volume = volume; +} diff --git a/src/blacksound/sampleprovider/volumesampleprovider.h b/src/blacksound/sampleprovider/volumesampleprovider.h new file mode 100644 index 000000000..07b06a15a --- /dev/null +++ b/src/blacksound/sampleprovider/volumesampleprovider.h @@ -0,0 +1,36 @@ +/* Copyright (C) 2019 + * swift project Community / Contributors + * + * This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level + * directory of this distribution. No part of swift project, including this file, may be copied, modified, propagated, + * or distributed except according to the terms contained in the LICENSE file. + */ + +//! \file + +#ifndef VOLUMESAMPLEPROVIDER_H +#define VOLUMESAMPLEPROVIDER_H + +#include "blacksound/blacksoundexport.h" +#include "blacksound/sampleprovider/sampleprovider.h" + +//! Pink noise generator +class BLACKSOUND_EXPORT VolumeSampleProvider : public ISampleProvider +{ + Q_OBJECT + +public: + //! Noise generator + VolumeSampleProvider(ISampleProvider *sourceProvider, QObject *parent = nullptr); + + virtual int readSamples(QVector &samples, qint64 count) override; + + double volume() const; + void setVolume(double volume); + +private: + ISampleProvider *m_sourceProvider; + double m_volume = 1.0; +}; + +#endif // guard