From cb5d5dd3a8ba3b879811361406b0d1422478c6cd Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 11 Nov 2014 16:57:25 -0800 Subject: [PATCH] handle looping via AudioInjectorLocalBuffer --- examples/lobby.js | 2 +- libraries/audio/src/AudioInjector.cpp | 4 +- .../audio/src/AudioInjectorLocalBuffer.cpp | 45 ++++++++++++++++--- .../audio/src/AudioInjectorLocalBuffer.h | 9 +++- 4 files changed, 47 insertions(+), 13 deletions(-) diff --git a/examples/lobby.js b/examples/lobby.js index eb2611fd29..682e8dbd80 100644 --- a/examples/lobby.js +++ b/examples/lobby.js @@ -92,7 +92,7 @@ function drawLobby() { MyAvatar.attach(HELMET_ATTACHMENT_URL, "Neck", {x: 0, y: 0, z: 0}, Quat.fromPitchYawRollDegrees(0, 0, 0), 1.15); // start the drone sound - currentDrone = Audio.playSound(droneSound, { stereo: true, localOnly: true }); + currentDrone = Audio.playSound(droneSound, { stereo: true, loop: true, localOnly: true }); } } diff --git a/libraries/audio/src/AudioInjector.cpp b/libraries/audio/src/AudioInjector.cpp index ddd4f05630..6716d525da 100644 --- a/libraries/audio/src/AudioInjector.cpp +++ b/libraries/audio/src/AudioInjector.cpp @@ -83,9 +83,7 @@ void AudioInjector::injectLocally() { _localBuffer = new AudioInjectorLocalBuffer(_sound->getByteArray(), this); _localBuffer->open(QIODevice::ReadOnly); - _localBuffer->setIsLooping(_options.loop); - - qDebug() << "Passing off AudioInjectorLocatBuffer to localAudioInterface"; + _localBuffer->setShouldLoop(_options.loop); QMetaObject::invokeMethod(_localAudioInterface, "outputLocalInjector", Qt::BlockingQueuedConnection, diff --git a/libraries/audio/src/AudioInjectorLocalBuffer.cpp b/libraries/audio/src/AudioInjectorLocalBuffer.cpp index 19c92276f9..bdf084091d 100644 --- a/libraries/audio/src/AudioInjectorLocalBuffer.cpp +++ b/libraries/audio/src/AudioInjectorLocalBuffer.cpp @@ -14,8 +14,9 @@ AudioInjectorLocalBuffer::AudioInjectorLocalBuffer(const QByteArray& rawAudioArray, QObject* parent) : QIODevice(parent), _rawAudioArray(rawAudioArray), - _isLooping(false), - _isStopped(false) + _shouldLoop(false), + _isStopped(false), + _currentOffset(0) { } @@ -27,17 +28,47 @@ void AudioInjectorLocalBuffer::stop() { qint64 AudioInjectorLocalBuffer::readData(char* data, qint64 maxSize) { if (!_isStopped) { - int bytesToEnd = _rawAudioArray.size() - pos(); - int bytesToRead = maxSize; + // first copy to the end of the raw audio + int bytesToEnd = _rawAudioArray.size() - _currentOffset; + + int bytesRead = maxSize; if (maxSize > bytesToEnd) { - bytesToRead = bytesToEnd; + bytesRead = bytesToEnd; } - memcpy(data, _rawAudioArray.data() + pos(), bytesToRead); - return bytesToRead; + memcpy(data, _rawAudioArray.data() + _currentOffset, bytesRead); + + // now check if we are supposed to loop and if we can copy more from the beginning + if (_shouldLoop && maxSize != bytesRead) { + bytesRead += recursiveReadFromFront(data + bytesRead, maxSize - bytesRead); + } else { + _currentOffset += bytesRead; + } + + return bytesRead; } else { return 0; } +} + +qint64 AudioInjectorLocalBuffer::recursiveReadFromFront(char* data, qint64 maxSize) { + // see how much we can get in this pass + int bytesRead = maxSize; + + if (bytesRead > _rawAudioArray.size()) { + bytesRead = _rawAudioArray.size(); + } + + // copy that amount + memcpy(data, _rawAudioArray.data(), bytesRead); + + // check if we need to call ourselves again and pull from the front again + if (bytesRead < maxSize) { + return bytesRead + recursiveReadFromFront(data, maxSize); + } else { + _currentOffset = bytesRead; + return bytesRead; + } } \ No newline at end of file diff --git a/libraries/audio/src/AudioInjectorLocalBuffer.h b/libraries/audio/src/AudioInjectorLocalBuffer.h index 6d234066ef..8b32c6fbc7 100644 --- a/libraries/audio/src/AudioInjectorLocalBuffer.h +++ b/libraries/audio/src/AudioInjectorLocalBuffer.h @@ -24,12 +24,17 @@ public: qint64 readData(char* data, qint64 maxSize); qint64 writeData(const char* data, qint64 maxSize) { return 0; } - void setIsLooping(bool isLooping) { _isLooping = isLooping; } + void setShouldLoop(bool shouldLoop) { _shouldLoop = shouldLoop; } private: + + qint64 recursiveReadFromFront(char* data, qint64 maxSize); + QByteArray _rawAudioArray; - bool _isLooping; + bool _shouldLoop; bool _isStopped; + + int _currentOffset; }; #endif // hifi_AudioInjectorLocalBuffer_h \ No newline at end of file