From faba165408e79dfd787e1b91bef96f77cdcd2ebf Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Thu, 22 Sep 2016 11:36:03 -0700 Subject: [PATCH] fix injector fail on lack of local if - consolidate codepaths for new/restarted injections - allow network injection without local injection --- libraries/audio/src/AudioInjector.cpp | 92 ++++++-------------- libraries/audio/src/AudioInjector.h | 4 +- libraries/audio/src/AudioInjectorManager.cpp | 20 +++-- 3 files changed, 41 insertions(+), 75 deletions(-) diff --git a/libraries/audio/src/AudioInjector.cpp b/libraries/audio/src/AudioInjector.cpp index fdf5a4fc55..43701a51d8 100644 --- a/libraries/audio/src/AudioInjector.cpp +++ b/libraries/audio/src/AudioInjector.cpp @@ -96,26 +96,6 @@ void AudioInjector::finish() { } } -void AudioInjector::setupInjection() { - if (!_hasSetup) { - _hasSetup = true; - - // check if we need to offset the sound by some number of seconds - if (_options.secondOffset > 0.0f) { - - // convert the offset into a number of bytes - int byteOffset = (int) floorf(AudioConstants::SAMPLE_RATE * _options.secondOffset * (_options.stereo ? 2.0f : 1.0f)); - byteOffset *= sizeof(int16_t); - - _currentSendOffset = byteOffset; - } else { - _currentSendOffset = 0; - } - } else { - qCDebug(audio) << "AudioInjector::setupInjection called but already setup."; - } -} - void AudioInjector::restart() { // grab the AudioInjectorManager auto injectorManager = DependencyManager::get(); @@ -143,30 +123,37 @@ void AudioInjector::restart() { // check our state to decide if we need extra handling for the restart request if (stateHas(AudioInjectorState::Finished)) { - // we finished playing, need to reset state so we can get going again - _hasSetup = false; - _shouldStop = false; - _state = AudioInjectorState::NotFinished; - - // call inject audio to start injection over again - setupInjection(); - - // inject locally - if(injectLocally()) { - - // if not localOnly, wake the AudioInjectorManager back up if it is stuck waiting - if (!_options.localOnly) { - - if (!injectorManager->restartFinishedInjector(this)) { - _state = AudioInjectorState::Finished; // we're not playing, so reset the state used by isPlaying. - } - } - } else { - _state = AudioInjectorState::Finished; // we failed to play, so we are finished again + if (!inject(&AudioInjectorManager::restartFinishedInjector)) { + qWarning() << "AudioInjector::restart failed to thread injector"; } } } +bool AudioInjector::inject(bool(AudioInjectorManager::*injection)(AudioInjector*)) { + _state = AudioInjectorState::NotFinished; + + int byteOffset = 0; + if (_options.secondOffset > 0.0f) { + byteOffset = (int)floorf(AudioConstants::SAMPLE_RATE * _options.secondOffset * (_options.stereo ? 2.0f : 1.0f)); + byteOffset *= sizeof(AudioConstants::SAMPLE_SIZE); + } + _currentSendOffset = byteOffset; + + if (!injectLocally()) { + finishLocalInjection(); + } + + bool success = true; + if (!_options.localOnly) { + auto injectorManager = DependencyManager::get(); + if (!(*injectorManager.*injection)(this)) { + success = false; + finishNetworkInjection(); + } + } + return success; +} + bool AudioInjector::injectLocally() { bool success = false; if (_localAudioInterface) { @@ -195,11 +182,6 @@ bool AudioInjector::injectLocally() { qCDebug(audio) << "AudioInjector::injectLocally cannot inject locally with no local audio interface present."; } - if (!success) { - // we never started so we are finished with local injection - finishLocalInjection(); - } - return success; } @@ -474,24 +456,8 @@ AudioInjector* AudioInjector::playSoundAndDelete(const QByteArray& buffer, const AudioInjector* AudioInjector::playSound(const QByteArray& buffer, const AudioInjectorOptions options) { AudioInjector* injector = new AudioInjector(buffer, options); - - // grab the AudioInjectorManager - auto injectorManager = DependencyManager::get(); - - // setup parameters required for injection - injector->setupInjection(); - - // we always inject locally, except when there is no localInterface - injector->injectLocally(); - - // if localOnly, we are done, just return injector. - if (!options.localOnly) { - - // send off to server for everyone else - if (!injectorManager->threadInjector(injector)) { - // we failed to thread the new injector (we are at the max number of injector threads) - qDebug() << "AudioInjector::playSound failed to thread injector"; - } + if (!injector->inject(&AudioInjectorManager::threadInjector)) { + qWarning() << "AudioInjector::playSound failed to thread injector"; } return injector; } diff --git a/libraries/audio/src/AudioInjector.h b/libraries/audio/src/AudioInjector.h index 5f2b1064fa..7ee15a1b45 100644 --- a/libraries/audio/src/AudioInjector.h +++ b/libraries/audio/src/AudioInjector.h @@ -92,8 +92,8 @@ signals: void restarting(); private: - void setupInjection(); int64_t injectNextFrame(); + bool inject(bool(AudioInjectorManager::*injection)(AudioInjector*)); bool injectLocally(); static AbstractAudioInterface* _localAudioInterface; @@ -102,8 +102,6 @@ private: AudioInjectorOptions _options; AudioInjectorState _state { AudioInjectorState::NotFinished }; bool _hasSentFirstFrame { false }; - bool _hasSetup { false }; - bool _shouldStop { false }; float _loudness { 0.0f }; int _currentSendOffset { 0 }; std::unique_ptr _currentPacket { nullptr }; diff --git a/libraries/audio/src/AudioInjectorManager.cpp b/libraries/audio/src/AudioInjectorManager.cpp index b39da1c148..b8560d1267 100644 --- a/libraries/audio/src/AudioInjectorManager.cpp +++ b/libraries/audio/src/AudioInjectorManager.cpp @@ -157,8 +157,6 @@ bool AudioInjectorManager::threadInjector(AudioInjector* injector) { // move the injector to the QThread injector->moveToThread(_thread); - // handle a restart once the injector has finished - // add the injector to the queue with a send timestamp of now _injectors.emplace(usecTimestampNow(), InjectorQPointer { injector }); @@ -170,13 +168,17 @@ bool AudioInjectorManager::threadInjector(AudioInjector* injector) { } bool AudioInjectorManager::restartFinishedInjector(AudioInjector* injector) { - if (!_shouldStop) { - // guard the injectors vector with a mutex - Lock lock(_injectorsMutex); - - if (wouldExceedLimits()) { - return false; - } + if (_shouldStop) { + qDebug() << "AudioInjectorManager::threadInjector asked to thread injector but is shutting down."; + return false; + } + + // guard the injectors vector with a mutex + Lock lock(_injectorsMutex); + + if (wouldExceedLimits()) { + return false; + } else { // add the injector to the queue with a send timestamp of now _injectors.emplace(usecTimestampNow(), InjectorQPointer { injector });