From 2e73ac8bc116b23ba42e841c1d1d39b3a24f330d Mon Sep 17 00:00:00 2001 From: wangyix Date: Tue, 8 Jul 2014 11:16:39 -0700 Subject: [PATCH] changed Audio.cpp to not overflow _audioOutput buffer, and 2 other things added _consecutiveNotMixedCount to prevent premature injector stream deletion; made silent-frame drop only occur in dynamic jitter buffer mode --- .../src/audio/AudioMixerClientData.cpp | 5 ++++- interface/src/Audio.cpp | 20 ++++++++++--------- .../audio/src/PositionalAudioRingBuffer.cpp | 10 +++++++--- .../audio/src/PositionalAudioRingBuffer.h | 6 +++--- 4 files changed, 25 insertions(+), 16 deletions(-) diff --git a/assignment-client/src/audio/AudioMixerClientData.cpp b/assignment-client/src/audio/AudioMixerClientData.cpp index f6437f9c97..d3883501d6 100644 --- a/assignment-client/src/audio/AudioMixerClientData.cpp +++ b/assignment-client/src/audio/AudioMixerClientData.cpp @@ -138,11 +138,14 @@ void AudioMixerClientData::pushBuffersAfterFrameSend() { // this was a used buffer, push the output pointer forwards PositionalAudioRingBuffer* audioBuffer = *i; + const int INJECTOR_CONSECUTIVE_NOT_MIXED_THRESHOLD = 100; + if (audioBuffer->willBeAddedToMix()) { audioBuffer->shiftReadPosition(audioBuffer->getSamplesPerFrame()); audioBuffer->setWillBeAddedToMix(false); } else if (audioBuffer->getType() == PositionalAudioRingBuffer::Injector - && audioBuffer->hasStarted() && audioBuffer->isStarved()) { + && audioBuffer->hasStarted() && audioBuffer->isStarved() + && audioBuffer->getConsecutiveNotMixedCount() > INJECTOR_CONSECUTIVE_NOT_MIXED_THRESHOLD) { // this is an empty audio buffer that has starved, safe to delete // also delete its sequence number stats QUuid streamIdentifier = ((InjectedAudioRingBuffer*)audioBuffer)->getStreamIdentifier(); diff --git a/interface/src/Audio.cpp b/interface/src/Audio.cpp index 6bbd769d25..c604040bc8 100644 --- a/interface/src/Audio.cpp +++ b/interface/src/Audio.cpp @@ -67,7 +67,7 @@ Audio::Audio(int16_t initialJitterBufferSamples, QObject* parent) : _proceduralAudioOutput(NULL), _proceduralOutputDevice(NULL), _inputRingBuffer(0), - _ringBuffer(NETWORK_BUFFER_LENGTH_SAMPLES_STEREO), + _ringBuffer(NETWORK_BUFFER_LENGTH_SAMPLES_STEREO, false, 100), _isStereoInput(false), _averagedLatency(0.0), _measuredJitter(0), @@ -869,14 +869,11 @@ void Audio::processReceivedAudio(const QByteArray& audioByteArray) { _numFramesDisplayStarve = 10; } - // if there is anything in the ring buffer, decide what to do - if (_ringBuffer.samplesAvailable() > 0) { - - int numNetworkOutputSamples = _ringBuffer.samplesAvailable(); - int numDeviceOutputSamples = numNetworkOutputSamples / networkOutputToOutputRatio; - - QByteArray outputBuffer; - outputBuffer.resize(numDeviceOutputSamples * sizeof(int16_t)); + int numSamplesAudioOutputRoomFor = _audioOutput->bytesFree() / sizeof(int16_t); + int numNetworkOutputSamples = std::min(_ringBuffer.samplesAvailable(), (int)(numSamplesAudioOutputRoomFor * networkOutputToOutputRatio)); + + // if there is data in the ring buffer and room in the audio output, decide what to do + if (numNetworkOutputSamples > 0) { int numSamplesNeededToStartPlayback = std::min(NETWORK_BUFFER_LENGTH_SAMPLES_STEREO + (_jitterBufferSamples * 2), _ringBuffer.getSampleCapacity()); @@ -885,6 +882,11 @@ void Audio::processReceivedAudio(const QByteArray& audioByteArray) { // We are still waiting for enough samples to begin playback // qDebug() << numNetworkOutputSamples << " samples so far, waiting for " << numSamplesNeededToStartPlayback; } else { + int numDeviceOutputSamples = numNetworkOutputSamples / networkOutputToOutputRatio; + + QByteArray outputBuffer; + outputBuffer.resize(numDeviceOutputSamples * sizeof(int16_t)); + // We are either already playing back, or we have enough audio to start playing back. //qDebug() << "pushing " << numNetworkOutputSamples; _ringBuffer.setIsStarved(false); diff --git a/libraries/audio/src/PositionalAudioRingBuffer.cpp b/libraries/audio/src/PositionalAudioRingBuffer.cpp index 0fe75f1239..6b3a1eb94f 100644 --- a/libraries/audio/src/PositionalAudioRingBuffer.cpp +++ b/libraries/audio/src/PositionalAudioRingBuffer.cpp @@ -99,7 +99,8 @@ PositionalAudioRingBuffer::PositionalAudioRingBuffer(PositionalAudioRingBuffer:: _listenerUnattenuatedZone(NULL), _desiredJitterBufferFrames(1), _currentJitterBufferFrames(-1), - _dynamicJitterBuffers(dynamicJitterBuffers) + _dynamicJitterBuffers(dynamicJitterBuffers), + _consecutiveNotMixedCount(0) { } @@ -129,7 +130,7 @@ int PositionalAudioRingBuffer::parseData(const QByteArray& packet) { numSilentSamples = getSamplesPerFrame(); if (numSilentSamples > 0) { - if (_currentJitterBufferFrames > _desiredJitterBufferFrames) { + if (_dynamicJitterBuffers && _currentJitterBufferFrames > _desiredJitterBufferFrames) { // our current jitter buffer size exceeds its desired value, so ignore some silent // frames to get that size as close to desired as possible int samplesPerFrame = getSamplesPerFrame(); @@ -206,11 +207,12 @@ bool PositionalAudioRingBuffer::shouldBeAddedToMix() { if (!isNotStarvedOrHasMinimumSamples(samplesPerFrame + desiredJitterBufferSamples)) { // if the buffer was starved, allow it to accrue at least the desired number of // jitter buffer frames before we start taking frames from it for mixing - + if (_shouldOutputStarveDebug) { _shouldOutputStarveDebug = false; } + _consecutiveNotMixedCount++; return false; } else if (samplesAvailable() < samplesPerFrame) { // if the buffer doesn't have a full frame of samples to take for mixing, it is starved @@ -222,6 +224,7 @@ bool PositionalAudioRingBuffer::shouldBeAddedToMix() { // reset our _shouldOutputStarveDebug to true so the next is printed _shouldOutputStarveDebug = true; + _consecutiveNotMixedCount++; return false; } @@ -231,6 +234,7 @@ bool PositionalAudioRingBuffer::shouldBeAddedToMix() { // minus one (since a frame will be read immediately after this) is the length of the jitter buffer _currentJitterBufferFrames = samplesAvailable() / samplesPerFrame - 1; _isStarved = false; + _consecutiveNotMixedCount = 0; } // since we've read data from ring buffer at least once - we've started diff --git a/libraries/audio/src/PositionalAudioRingBuffer.h b/libraries/audio/src/PositionalAudioRingBuffer.h index 0322afb47b..31b0524b3b 100644 --- a/libraries/audio/src/PositionalAudioRingBuffer.h +++ b/libraries/audio/src/PositionalAudioRingBuffer.h @@ -83,6 +83,8 @@ public: int getDesiredJitterBufferFrames() const { return _desiredJitterBufferFrames; } int getCurrentJitterBufferFrames() const { return _currentJitterBufferFrames; } + int getConsecutiveNotMixedCount() const { return _consecutiveNotMixedCount; } + protected: // disallow copying of PositionalAudioRingBuffer objects PositionalAudioRingBuffer(const PositionalAudioRingBuffer&); @@ -107,9 +109,7 @@ protected: bool _dynamicJitterBuffers; // extra stats - int _starveCount; - int _silentFramesDropped; - + int _consecutiveNotMixedCount; }; #endif // hifi_PositionalAudioRingBuffer_h