From 6d99d50f722e7bcd662e3e749e0f47d2a0b9453f Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Tue, 16 Jun 2015 10:51:42 -0700 Subject: [PATCH 1/2] Don't clip local audio sounds (https://app.asana.com/0/32622044445063/37633564937422) and quiet some warnings (of https://app.asana.com/0/32622044445063/37620738098871). --- libraries/audio/src/AudioInjector.cpp | 3 +-- libraries/audio/src/AudioInjectorLocalBuffer.cpp | 12 +++++++++--- libraries/audio/src/AudioInjectorLocalBuffer.h | 1 + 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/libraries/audio/src/AudioInjector.cpp b/libraries/audio/src/AudioInjector.cpp index 912351e21a..333a944e1b 100644 --- a/libraries/audio/src/AudioInjector.cpp +++ b/libraries/audio/src/AudioInjector.cpp @@ -51,7 +51,7 @@ void AudioInjector::setIsFinished(bool isFinished) { emit finished(); if (_localBuffer) { - _localBuffer->stop(); + // delete will stop (and nosily if we do so ourselves here first). _localBuffer->deleteLater(); _localBuffer = NULL; } @@ -60,7 +60,6 @@ void AudioInjector::setIsFinished(bool isFinished) { if (_shouldDeleteAfterFinish) { // we've been asked to delete after finishing, trigger a queued deleteLater here - qCDebug(audio) << "AudioInjector triggering delete from setIsFinished"; QMetaObject::invokeMethod(this, "deleteLater", Qt::QueuedConnection); } } diff --git a/libraries/audio/src/AudioInjectorLocalBuffer.cpp b/libraries/audio/src/AudioInjectorLocalBuffer.cpp index f40e613437..457abeb89e 100644 --- a/libraries/audio/src/AudioInjectorLocalBuffer.cpp +++ b/libraries/audio/src/AudioInjectorLocalBuffer.cpp @@ -17,7 +17,8 @@ AudioInjectorLocalBuffer::AudioInjectorLocalBuffer(const QByteArray& rawAudioArr _shouldLoop(false), _isStopped(false), _currentOffset(0), - _volume(1.0f) + _volume(1.0f), + _isFinished(false) { } @@ -51,6 +52,11 @@ void copy(char* to, char* from, int size, qreal factor) { qint64 AudioInjectorLocalBuffer::readData(char* data, qint64 maxSize) { if (!_isStopped) { + if (_isFinished) { + emit bufferEmpty(); + return -1; // qt docs say -1 is appropriate when subsequent calls will not write data + } + // first copy to the end of the raw audio int bytesToEnd = _rawAudioArray.size() - _currentOffset; @@ -70,8 +76,8 @@ qint64 AudioInjectorLocalBuffer::readData(char* data, qint64 maxSize) { } if (!_shouldLoop && bytesRead == bytesToEnd) { - // we hit the end of the buffer, emit a signal - emit bufferEmpty(); + // If we emit bufferEmpty now, we'll clip the end of the sound. Wait until the next call. + _isFinished = true; } else if (_shouldLoop && _currentOffset == _rawAudioArray.size()) { _currentOffset = 0; } diff --git a/libraries/audio/src/AudioInjectorLocalBuffer.h b/libraries/audio/src/AudioInjectorLocalBuffer.h index 9753cbbd83..270e730590 100644 --- a/libraries/audio/src/AudioInjectorLocalBuffer.h +++ b/libraries/audio/src/AudioInjectorLocalBuffer.h @@ -44,6 +44,7 @@ private: int _currentOffset; float _volume; + bool _isFinished; }; #endif // hifi_AudioInjectorLocalBuffer_h \ No newline at end of file From b4dfaba55ec57bf18830723e0691fc2a73ffed1d Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Wed, 17 Jun 2015 11:59:15 -0700 Subject: [PATCH 2/2] Incorporate ctrlaltdavid's changes. --- libraries/audio-client/src/AudioClient.cpp | 11 ++++++++++- libraries/audio-client/src/AudioClient.h | 5 +++++ libraries/audio/src/AudioInjector.cpp | 5 +---- libraries/audio/src/AudioInjectorLocalBuffer.cpp | 13 ++----------- libraries/audio/src/AudioInjectorLocalBuffer.h | 4 ---- 5 files changed, 18 insertions(+), 20 deletions(-) diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index 6450f25208..84022d0fb9 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -1011,7 +1011,10 @@ bool AudioClient::outputLocalInjector(bool isStereo, AudioInjector* injector) { localOutput->moveToThread(injector->getLocalBuffer()->thread()); // have it be stopped when that local buffer is about to close - connect(injector->getLocalBuffer(), &AudioInjectorLocalBuffer::bufferEmpty, localOutput, &QAudioOutput::stop); + connect(localOutput, &QAudioOutput::stateChanged, this, &AudioClient::audioStateChanged); + connect(this, &AudioClient::audioFinished, localOutput, &QAudioOutput::stop); + connect(this, &AudioClient::audioFinished, injector, &AudioInjector::stop); + connect(injector->getLocalBuffer(), &QIODevice::aboutToClose, localOutput, &QAudioOutput::stop); qCDebug(audioclient) << "Starting QAudioOutput for local injector" << localOutput; @@ -1329,3 +1332,9 @@ void AudioClient::saveSettings() { windowSecondsForDesiredReduction.set(_receivedAudioStream.getWindowSecondsForDesiredReduction()); repetitionWithFade.set(_receivedAudioStream.getRepetitionWithFade()); } + +void AudioClient::audioStateChanged(QAudio::State state) { + if (state == QAudio::IdleState) { + emit audioFinished(); + } +} diff --git a/libraries/audio-client/src/AudioClient.h b/libraries/audio-client/src/AudioClient.h index 642edde84a..d2492e1064 100644 --- a/libraries/audio-client/src/AudioClient.h +++ b/libraries/audio-client/src/AudioClient.h @@ -188,6 +188,8 @@ signals: void receivedFirstPacket(); void disconnected(); + void audioFinished(); + protected: AudioClient(); ~AudioClient(); @@ -196,6 +198,9 @@ protected: deleteLater(); } +private slots: + void audioStateChanged(QAudio::State state); + private: void outputFormatChanged(); diff --git a/libraries/audio/src/AudioInjector.cpp b/libraries/audio/src/AudioInjector.cpp index 333a944e1b..675a3b8b28 100644 --- a/libraries/audio/src/AudioInjector.cpp +++ b/libraries/audio/src/AudioInjector.cpp @@ -51,7 +51,7 @@ void AudioInjector::setIsFinished(bool isFinished) { emit finished(); if (_localBuffer) { - // delete will stop (and nosily if we do so ourselves here first). + _localBuffer->stop(); _localBuffer->deleteLater(); _localBuffer = NULL; } @@ -121,9 +121,6 @@ void AudioInjector::injectLocally() { 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); - if (!success) { qCDebug(audio) << "AudioInjector::injectLocally could not output locally via _localAudioInterface"; } diff --git a/libraries/audio/src/AudioInjectorLocalBuffer.cpp b/libraries/audio/src/AudioInjectorLocalBuffer.cpp index 457abeb89e..27e93a678e 100644 --- a/libraries/audio/src/AudioInjectorLocalBuffer.cpp +++ b/libraries/audio/src/AudioInjectorLocalBuffer.cpp @@ -17,8 +17,7 @@ AudioInjectorLocalBuffer::AudioInjectorLocalBuffer(const QByteArray& rawAudioArr _shouldLoop(false), _isStopped(false), _currentOffset(0), - _volume(1.0f), - _isFinished(false) + _volume(1.0f) { } @@ -52,11 +51,6 @@ void copy(char* to, char* from, int size, qreal factor) { qint64 AudioInjectorLocalBuffer::readData(char* data, qint64 maxSize) { if (!_isStopped) { - if (_isFinished) { - emit bufferEmpty(); - return -1; // qt docs say -1 is appropriate when subsequent calls will not write data - } - // first copy to the end of the raw audio int bytesToEnd = _rawAudioArray.size() - _currentOffset; @@ -75,10 +69,7 @@ qint64 AudioInjectorLocalBuffer::readData(char* data, qint64 maxSize) { _currentOffset += bytesRead; } - if (!_shouldLoop && bytesRead == bytesToEnd) { - // If we emit bufferEmpty now, we'll clip the end of the sound. Wait until the next call. - _isFinished = true; - } else if (_shouldLoop && _currentOffset == _rawAudioArray.size()) { + if (_shouldLoop && _currentOffset == _rawAudioArray.size()) { _currentOffset = 0; } diff --git a/libraries/audio/src/AudioInjectorLocalBuffer.h b/libraries/audio/src/AudioInjectorLocalBuffer.h index 270e730590..32a1221b78 100644 --- a/libraries/audio/src/AudioInjectorLocalBuffer.h +++ b/libraries/audio/src/AudioInjectorLocalBuffer.h @@ -32,9 +32,6 @@ public: void setCurrentOffset(int currentOffset) { _currentOffset = currentOffset; } void setVolume(float volume) { _volume = glm::clamp(volume, 0.0f, 1.0f); } -signals: - void bufferEmpty(); - private: qint64 recursiveReadFromFront(char* data, qint64 maxSize); @@ -44,7 +41,6 @@ private: int _currentOffset; float _volume; - bool _isFinished; }; #endif // hifi_AudioInjectorLocalBuffer_h \ No newline at end of file