diff --git a/interface/src/ui/PreferencesDialog.cpp b/interface/src/ui/PreferencesDialog.cpp index 2a0094de29..ab9cc45740 100644 --- a/interface/src/ui/PreferencesDialog.cpp +++ b/interface/src/ui/PreferencesDialog.cpp @@ -278,12 +278,18 @@ void setupPreferences() { preferences->addPreference(preference); } #if DEV_BUILD || PR_BUILD + { + auto getter = []()->bool { return DependencyManager::get()->isSimulatingJitter(); }; + auto setter = [](bool value) { return DependencyManager::get()->setIsSimulatingJitter(value); }; + auto preference = new CheckPreference(AUDIO, "Packet jitter simulator", getter, setter); + preferences->addPreference(preference); + } { auto getter = []()->float { return DependencyManager::get()->getGateThreshold(); }; auto setter = [](float value) { return DependencyManager::get()->setGateThreshold(value); }; - auto preference = new SpinnerPreference(AUDIO, "Debug gate threshold", getter, setter); + auto preference = new SpinnerPreference(AUDIO, "Packet throttle threshold", getter, setter); preference->setMin(1); - preference->setMax((float)100); + preference->setMax(200); preference->setStep(1); preferences->addPreference(preference); } diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index 99922284dc..3504687d83 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -55,8 +55,6 @@ static const int RECEIVED_AUDIO_STREAM_CAPACITY_FRAMES = 100; static const auto DEFAULT_POSITION_GETTER = []{ return Vectors::ZERO; }; static const auto DEFAULT_ORIENTATION_GETTER = [] { return Quaternions::IDENTITY; }; -static const int DEFAULT_AUDIO_OUTPUT_GATE_THRESHOLD = 1; - Setting::Handle dynamicJitterBuffers("dynamicJitterBuffers", DEFAULT_DYNAMIC_JITTER_BUFFERS); Setting::Handle maxFramesOverDesired("maxFramesOverDesired", DEFAULT_MAX_FRAMES_OVER_DESIRED); Setting::Handle staticDesiredJitterBufferFrames("staticDesiredJitterBufferFrames", @@ -101,8 +99,7 @@ private: AudioClient::AudioClient() : AbstractAudioInterface(), - _gateThreshold("audioOutputGateThreshold", DEFAULT_AUDIO_OUTPUT_GATE_THRESHOLD), - _gate(this, _gateThreshold.get()), + _gate(this), _audioInput(NULL), _desiredInputFormat(), _inputFormat(), @@ -551,18 +548,26 @@ void AudioClient::handleAudioDataPacket(QSharedPointer message) } } -AudioClient::Gate::Gate(AudioClient* audioClient, int threshold) : - _audioClient(audioClient), - _threshold(threshold) {} +AudioClient::Gate::Gate(AudioClient* audioClient) : + _audioClient(audioClient) {} + +void AudioClient::Gate::setIsSimulatingJitter(bool enable) { + std::lock_guard lock(_mutex); + flush(); + _isSimulatingJitter = true; +} void AudioClient::Gate::setThreshold(int threshold) { + std::lock_guard lock(_mutex); flush(); _threshold = std::max(threshold, 1); } void AudioClient::Gate::insert(QSharedPointer message) { + std::lock_guard lock(_mutex); + // Short-circuit for normal behavior - if (_threshold == 1) { + if (_threshold == 1 && !_isSimulatingJitter) { _audioClient->_receivedAudioStream.parseData(*message); return; } @@ -570,7 +575,11 @@ void AudioClient::Gate::insert(QSharedPointer message) { _queue.push(message); _index++; - if (_index % _threshold == 0) { + if (_isSimulatingJitter) { + if (randFloat() < 0.6f) { + flush(); // 60% of the time, it works every time + } + } else if (!(_index % _threshold)) { flush(); } } diff --git a/libraries/audio-client/src/AudioClient.h b/libraries/audio-client/src/AudioClient.h index 36cda8050e..e6807f7170 100644 --- a/libraries/audio-client/src/AudioClient.h +++ b/libraries/audio-client/src/AudioClient.h @@ -135,6 +135,9 @@ public: int getOutputStarveDetectionThreshold() { return _outputStarveDetectionThreshold.get(); } void setOutputStarveDetectionThreshold(int threshold) { _outputStarveDetectionThreshold.set(threshold); } + bool isSimulatingJitter() { return _gate.isSimulatingJitter(); } + void setIsSimulatingJitter(bool enable) { _gate.setIsSimulatingJitter(enable); } + int getGateThreshold() { return _gate.getThreshold(); } void setGateThreshold(int threshold) { _gate.setThreshold(threshold); } @@ -233,7 +236,10 @@ private: class Gate { public: - Gate(AudioClient* audioClient, int threshold); + Gate(AudioClient* audioClient); + + bool isSimulatingJitter() { return _isSimulatingJitter; } + void setIsSimulatingJitter(bool enable); int getThreshold() { return _threshold; } void setThreshold(int threshold); @@ -245,11 +251,13 @@ private: AudioClient* _audioClient; std::queue> _queue; + std::mutex _mutex; + int _index{ 0 }; - int _threshold; + int _threshold{ 1 }; + bool _isSimulatingJitter{ false }; }; - Setting::Handle _gateThreshold; Gate _gate; Mutex _injectorsMutex;