From 674c19a570e144073ed948d5295344076dd1d879 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 2 Jan 2014 12:17:18 -0800 Subject: [PATCH] leverage new AudioInjector API for throw and catch sounds --- interface/src/avatar/Hand.cpp | 22 +++++---------- interface/src/avatar/Hand.h | 4 +-- libraries/audio/src/AudioInjector.cpp | 39 +++++++++++++++++---------- libraries/audio/src/AudioInjector.h | 24 ++++++++++------- libraries/audio/src/Sound.cpp | 4 +-- 5 files changed, 50 insertions(+), 43 deletions(-) diff --git a/interface/src/avatar/Hand.cpp b/interface/src/avatar/Hand.cpp index 5f712d947b..b85fa94ef0 100644 --- a/interface/src/avatar/Hand.cpp +++ b/interface/src/avatar/Hand.cpp @@ -54,8 +54,8 @@ Hand::Hand(Avatar* owningAvatar) : _grabDeltaVelocity(0, 0, 0), _grabStartRotation(0, 0, 0, 1), _grabCurrentRotation(0, 0, 0, 1), - _throwInjector(QUrl("https://dl.dropboxusercontent.com/u/1864924/hifi-sounds/throw.raw")), - _catchInjector(QUrl("https://dl.dropboxusercontent.com/u/1864924/hifi-sounds/catch.raw")) + _throwSound(QUrl("https://dl.dropboxusercontent.com/u/1864924/hifi-sounds/throw.raw")), + _catchSound(QUrl("https://dl.dropboxusercontent.com/u/1864924/hifi-sounds/catch.raw")) { for (int i = 0; i < MAX_HANDS; i++) { _toyBallInHand[i] = false; @@ -63,10 +63,6 @@ Hand::Hand(Avatar* owningAvatar) : _whichBallColor[i] = 0; } _lastControllerButtons = 0; - - // the throw and catch sounds should not loopback, we'll play them locally - _throwInjector.setShouldLoopback(false); - _catchInjector.setShouldLoopback(false); } void Hand::init() { @@ -128,11 +124,8 @@ void Hand::simulateToyBall(PalmData& palm, const glm::vec3& fingerTipPosition, f _ballParticleEditHandles[handID] = caughtParticle; caughtParticle = NULL; - // set the position of the catch sound to the new position of the ball - _catchInjector.setPosition(targetPosition); - - // inject the catch sound to the mixer and play it locally - _catchInjector.injectViaThread(app->getAudio()); + // use the threadSound static method to inject the catch sound + AudioInjector::threadSound(&_catchSound, targetPosition); } } @@ -214,11 +207,8 @@ void Hand::simulateToyBall(PalmData& palm, const glm::vec3& fingerTipPosition, f delete _ballParticleEditHandles[handID]; _ballParticleEditHandles[handID] = NULL; - // move the throw injector to inject from the position of the ball - _throwInjector.setPosition(ballPosition); - - // inject the throw sound and play it locally - _throwInjector.injectViaThread(app->getAudio()); + // use the threadSound static method to inject the throw sound + AudioInjector::threadSound(&_throwSound, targetPosition); } } diff --git a/interface/src/avatar/Hand.h b/interface/src/avatar/Hand.h index e938135a29..88ca4a61e7 100755 --- a/interface/src/avatar/Hand.h +++ b/interface/src/avatar/Hand.h @@ -114,8 +114,8 @@ private: glm::quat _grabStartRotation; glm::quat _grabCurrentRotation; - AudioInjector _throwInjector; - AudioInjector _catchInjector; + Sound _throwSound; + Sound _catchSound; }; #endif diff --git a/libraries/audio/src/AudioInjector.cpp b/libraries/audio/src/AudioInjector.cpp index 315c384e8b..87a0b2c833 100644 --- a/libraries/audio/src/AudioInjector.cpp +++ b/libraries/audio/src/AudioInjector.cpp @@ -18,36 +18,46 @@ int abstractAudioPointerMeta = qRegisterMetaType("AbstractAudioInterface*"); -AudioInjector::AudioInjector(Sound* sound) : +AudioInjector::AudioInjector(Sound* sound, const glm::vec3 position, float volume, + const glm::quat orientation, bool shouldLoopback, + AbstractAudioInterface* loopbackAudioInterface) : _sound(sound), - _volume(1.0f), - _shouldLoopback(true), - _position(0.0f, 0.0f, 0.0f), - _orientation() + _volume(volume), + _shouldLoopback(shouldLoopback), + _position(position), + _orientation(orientation), + _loopbackAudioInterface(loopbackAudioInterface) { // we want to live on our own thread moveToThread(&_thread); - connect(&_thread, SIGNAL(started()), this, SLOT(startDownload())); - _thread.start(); } -void AudioInjector::injectViaThread(AbstractAudioInterface* localAudioInterface) { - // use Qt::AutoConnection so that this is called on our thread, if appropriate - QMetaObject::invokeMethod(this, "injectAudio", Qt::AutoConnection, Q_ARG(AbstractAudioInterface*, localAudioInterface)); +void AudioInjector::threadSound(Sound* sound, const glm::vec3 position, float volume, + const glm::quat orientation, bool shouldLoopback, AbstractAudioInterface* audioInterface) { + AudioInjector injector(sound, position, volume, orientation, shouldLoopback, audioInterface); + + // start injecting when the injector thread starts + connect(&injector._thread, SIGNAL(started()), &injector, SLOT(injectAudio())); + + // connect the right slots and signals so that the AudioInjector is killed once the injection is complete + connect(&injector, SIGNAL(finished()), &injector._thread, SLOT(quit())); + connect(&injector, SIGNAL(finished()), &injector, SLOT(deleteLater())); + + injector._thread.start(); } const uchar MAX_INJECTOR_VOLUME = 0xFF; -void AudioInjector::injectAudio(AbstractAudioInterface* localAudioInterface) { +void AudioInjector::injectAudio() { QByteArray soundByteArray = _sound->getByteArray(); // make sure we actually have samples downloaded to inject if (soundByteArray.size()) { // give our sample byte array to the local audio interface, if we have it, so it can be handled locally - if (localAudioInterface) { + if (_loopbackAudioInterface) { // assume that localAudioInterface could be on a separate thread, use Qt::AutoConnection to handle properly - QMetaObject::invokeMethod(localAudioInterface, "handleAudioByteArray", + QMetaObject::invokeMethod(_loopbackAudioInterface, "handleAudioByteArray", Qt::AutoConnection, Q_ARG(QByteArray, soundByteArray)); @@ -137,6 +147,7 @@ void AudioInjector::injectAudio(AbstractAudioInterface* localAudioInterface) { } } } - } + + emit finished(); } \ No newline at end of file diff --git a/libraries/audio/src/AudioInjector.h b/libraries/audio/src/AudioInjector.h index 38e280d623..9bfd486807 100644 --- a/libraries/audio/src/AudioInjector.h +++ b/libraries/audio/src/AudioInjector.h @@ -17,25 +17,31 @@ #include "Sound.h" +class AbstractAudioInterface; + class AudioInjector : public QObject { public: - AudioInjector(Sound* sound); - - void setPosition(const glm::vec3& position) { _position = position; } - void setOrientation(const glm::quat& orientation) { _orientation = orientation; } - void setVolume(float volume) { _volume = std::max(fabsf(volume), 1.0f); } - void setShouldLoopback(bool shouldLoopback) { _shouldLoopback = shouldLoopback; } -public slots: - void injectViaThread(AbstractAudioInterface* localAudioInterface = NULL); + static void threadSound(Sound* sound, + const glm::vec3 position = glm::vec3(0.0f, 0.0f, 0.0f), + float volume = 1.0f, + const glm::quat orientation = glm::quat(), + bool shouldLoopback = true, + AbstractAudioInterface* loopbackAudioInterface = NULL); private: + AudioInjector(Sound* sound, const glm::vec3 position, float volume, + const glm::quat orientation, bool shouldLoopback, AbstractAudioInterface* loopbackAudioInterface); + QThread _thread; Sound* _sound; float _volume; uchar _shouldLoopback; glm::vec3 _position; glm::quat _orientation; + AbstractAudioInterface* _loopbackAudioInterface; private slots: - void injectAudio(AbstractAudioInterface* localAudioInterface); + void injectAudio(); +signals: + void finished(); }; #endif /* defined(__hifi__AudioInjector__) */ diff --git a/libraries/audio/src/Sound.cpp b/libraries/audio/src/Sound.cpp index 147df5c10f..0362561fff 100644 --- a/libraries/audio/src/Sound.cpp +++ b/libraries/audio/src/Sound.cpp @@ -24,6 +24,6 @@ Sound::Sound(const QUrl& sampleURL) { } void Sound::replyFinished(QNetworkReply* reply) { - // replace our samples array with the downloaded data - _sampleByteArray = reply->readAll(); + // replace our byte array with the downloaded data + _byteArray = reply->readAll(); } \ No newline at end of file