From 1dcc2f7988dd8bf394a40ac7369239fb9bf73799 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 4 May 2015 15:26:43 +0200 Subject: [PATCH] Fix local injector modifying system volume --- libraries/audio-client/src/AudioClient.cpp | 4 +--- libraries/audio-client/src/AudioClient.h | 2 +- libraries/audio/src/AbstractAudioInterface.h | 2 +- libraries/audio/src/AudioInjector.cpp | 3 ++- .../audio/src/AudioInjectorLocalBuffer.cpp | 19 ++++++++++++++++--- .../audio/src/AudioInjectorLocalBuffer.h | 8 ++++++-- 6 files changed, 27 insertions(+), 11 deletions(-) diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index 331e62ec70..36308f6576 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -981,7 +981,7 @@ void AudioClient::selectAudioSourceSine440() { _noiseSourceEnabled = false; } -bool AudioClient::outputLocalInjector(bool isStereo, qreal volume, AudioInjector* injector) { +bool AudioClient::outputLocalInjector(bool isStereo, AudioInjector* injector) { if (injector->getLocalBuffer()) { QAudioFormat localFormat = _desiredOutputFormat; localFormat.setChannelCount(isStereo ? 2 : 1); @@ -990,8 +990,6 @@ bool AudioClient::outputLocalInjector(bool isStereo, qreal volume, AudioInjector localFormat, injector->getLocalBuffer()); - localOutput->setVolume(volume); - // move the localOutput to the same thread as the local injector buffer localOutput->moveToThread(injector->getLocalBuffer()->thread()); diff --git a/libraries/audio-client/src/AudioClient.h b/libraries/audio-client/src/AudioClient.h index 9d10184d13..f9392c6a10 100644 --- a/libraries/audio-client/src/AudioClient.h +++ b/libraries/audio-client/src/AudioClient.h @@ -157,7 +157,7 @@ public slots: void setOutputBufferSize(int numFrames); - virtual bool outputLocalInjector(bool isStereo, qreal volume, AudioInjector* injector); + virtual bool outputLocalInjector(bool isStereo, AudioInjector* injector); bool switchInputToAudioDevice(const QString& inputDeviceName); bool switchOutputToAudioDevice(const QString& outputDeviceName); diff --git a/libraries/audio/src/AbstractAudioInterface.h b/libraries/audio/src/AbstractAudioInterface.h index a5855d75d1..4961e9b58c 100644 --- a/libraries/audio/src/AbstractAudioInterface.h +++ b/libraries/audio/src/AbstractAudioInterface.h @@ -26,7 +26,7 @@ public: AbstractAudioInterface(QObject* parent = 0) : QObject(parent) {}; public slots: - virtual bool outputLocalInjector(bool isStereo, qreal volume, AudioInjector* injector) = 0; + virtual bool outputLocalInjector(bool isStereo, AudioInjector* injector) = 0; virtual void enableAudioSourceInject(bool enable) = 0; virtual void selectAudioSourcePinkNoise() = 0; diff --git a/libraries/audio/src/AudioInjector.cpp b/libraries/audio/src/AudioInjector.cpp index 95db7e6d0b..26140b82c8 100644 --- a/libraries/audio/src/AudioInjector.cpp +++ b/libraries/audio/src/AudioInjector.cpp @@ -105,11 +105,12 @@ void AudioInjector::injectLocally() { _localBuffer->open(QIODevice::ReadOnly); _localBuffer->setShouldLoop(_options.loop); + _localBuffer->setVolume(_options.volume); // give our current send position to the local buffer _localBuffer->setCurrentOffset(_currentSendPosition); - success = _localAudioInterface->outputLocalInjector(_options.stereo, _options.volume, this); + success = _localAudioInterface->outputLocalInjector(_options.stereo, this); // if we're not looping and the buffer tells us it is empty then emit finished connect(_localBuffer, &AudioInjectorLocalBuffer::bufferEmpty, this, &AudioInjector::stop); diff --git a/libraries/audio/src/AudioInjectorLocalBuffer.cpp b/libraries/audio/src/AudioInjectorLocalBuffer.cpp index 1b2d44fe24..f40e613437 100644 --- a/libraries/audio/src/AudioInjectorLocalBuffer.cpp +++ b/libraries/audio/src/AudioInjectorLocalBuffer.cpp @@ -16,7 +16,8 @@ AudioInjectorLocalBuffer::AudioInjectorLocalBuffer(const QByteArray& rawAudioArr _rawAudioArray(rawAudioArray), _shouldLoop(false), _isStopped(false), - _currentOffset(0) + _currentOffset(0), + _volume(1.0f) { } @@ -35,6 +36,18 @@ bool AudioInjectorLocalBuffer::seek(qint64 pos) { } } +void copy(char* to, char* from, int size, qreal factor) { + int16_t* toArray = (int16_t*) to; + int16_t* fromArray = (int16_t*) from; + int sampleSize = size / sizeof(int16_t); + + for (int i = 0; i < sampleSize; i++) { + *toArray = factor * (*fromArray); + toArray++; + fromArray++; + } +} + qint64 AudioInjectorLocalBuffer::readData(char* data, qint64 maxSize) { if (!_isStopped) { @@ -47,7 +60,7 @@ qint64 AudioInjectorLocalBuffer::readData(char* data, qint64 maxSize) { bytesRead = bytesToEnd; } - memcpy(data, _rawAudioArray.data() + _currentOffset, bytesRead); + copy(data, _rawAudioArray.data() + _currentOffset, bytesRead, _volume); // now check if we are supposed to loop and if we can copy more from the beginning if (_shouldLoop && maxSize != bytesRead) { @@ -78,7 +91,7 @@ qint64 AudioInjectorLocalBuffer::recursiveReadFromFront(char* data, qint64 maxSi } // copy that amount - memcpy(data, _rawAudioArray.data(), bytesRead); + copy(data, _rawAudioArray.data(), bytesRead, _volume); // check if we need to call ourselves again and pull from the front again if (bytesRead < maxSize) { diff --git a/libraries/audio/src/AudioInjectorLocalBuffer.h b/libraries/audio/src/AudioInjectorLocalBuffer.h index ce41052730..9753cbbd83 100644 --- a/libraries/audio/src/AudioInjectorLocalBuffer.h +++ b/libraries/audio/src/AudioInjectorLocalBuffer.h @@ -14,6 +14,8 @@ #include +#include + class AudioInjectorLocalBuffer : public QIODevice { Q_OBJECT public: @@ -27,12 +29,13 @@ public: qint64 writeData(const char* data, qint64 maxSize) { return 0; } void setShouldLoop(bool shouldLoop) { _shouldLoop = shouldLoop; } - void setCurrentOffset(int currentOffset) { _currentOffset = currentOffset; } + void setVolume(float volume) { _volume = glm::clamp(volume, 0.0f, 1.0f); } + signals: void bufferEmpty(); -private: +private: qint64 recursiveReadFromFront(char* data, qint64 maxSize); QByteArray _rawAudioArray; @@ -40,6 +43,7 @@ private: bool _isStopped; int _currentOffset; + float _volume; }; #endif // hifi_AudioInjectorLocalBuffer_h \ No newline at end of file