mirror of
https://github.com/overte-org/overte.git
synced 2025-07-23 02:30:14 +02:00
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
This commit is contained in:
parent
e34f592a83
commit
2e73ac8bc1
4 changed files with 25 additions and 16 deletions
|
@ -138,11 +138,14 @@ void AudioMixerClientData::pushBuffersAfterFrameSend() {
|
||||||
// this was a used buffer, push the output pointer forwards
|
// this was a used buffer, push the output pointer forwards
|
||||||
PositionalAudioRingBuffer* audioBuffer = *i;
|
PositionalAudioRingBuffer* audioBuffer = *i;
|
||||||
|
|
||||||
|
const int INJECTOR_CONSECUTIVE_NOT_MIXED_THRESHOLD = 100;
|
||||||
|
|
||||||
if (audioBuffer->willBeAddedToMix()) {
|
if (audioBuffer->willBeAddedToMix()) {
|
||||||
audioBuffer->shiftReadPosition(audioBuffer->getSamplesPerFrame());
|
audioBuffer->shiftReadPosition(audioBuffer->getSamplesPerFrame());
|
||||||
audioBuffer->setWillBeAddedToMix(false);
|
audioBuffer->setWillBeAddedToMix(false);
|
||||||
} else if (audioBuffer->getType() == PositionalAudioRingBuffer::Injector
|
} 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
|
// this is an empty audio buffer that has starved, safe to delete
|
||||||
// also delete its sequence number stats
|
// also delete its sequence number stats
|
||||||
QUuid streamIdentifier = ((InjectedAudioRingBuffer*)audioBuffer)->getStreamIdentifier();
|
QUuid streamIdentifier = ((InjectedAudioRingBuffer*)audioBuffer)->getStreamIdentifier();
|
||||||
|
|
|
@ -67,7 +67,7 @@ Audio::Audio(int16_t initialJitterBufferSamples, QObject* parent) :
|
||||||
_proceduralAudioOutput(NULL),
|
_proceduralAudioOutput(NULL),
|
||||||
_proceduralOutputDevice(NULL),
|
_proceduralOutputDevice(NULL),
|
||||||
_inputRingBuffer(0),
|
_inputRingBuffer(0),
|
||||||
_ringBuffer(NETWORK_BUFFER_LENGTH_SAMPLES_STEREO),
|
_ringBuffer(NETWORK_BUFFER_LENGTH_SAMPLES_STEREO, false, 100),
|
||||||
_isStereoInput(false),
|
_isStereoInput(false),
|
||||||
_averagedLatency(0.0),
|
_averagedLatency(0.0),
|
||||||
_measuredJitter(0),
|
_measuredJitter(0),
|
||||||
|
@ -869,14 +869,11 @@ void Audio::processReceivedAudio(const QByteArray& audioByteArray) {
|
||||||
_numFramesDisplayStarve = 10;
|
_numFramesDisplayStarve = 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if there is anything in the ring buffer, decide what to do
|
int numSamplesAudioOutputRoomFor = _audioOutput->bytesFree() / sizeof(int16_t);
|
||||||
if (_ringBuffer.samplesAvailable() > 0) {
|
int numNetworkOutputSamples = std::min(_ringBuffer.samplesAvailable(), (int)(numSamplesAudioOutputRoomFor * networkOutputToOutputRatio));
|
||||||
|
|
||||||
int numNetworkOutputSamples = _ringBuffer.samplesAvailable();
|
// if there is data in the ring buffer and room in the audio output, decide what to do
|
||||||
int numDeviceOutputSamples = numNetworkOutputSamples / networkOutputToOutputRatio;
|
if (numNetworkOutputSamples > 0) {
|
||||||
|
|
||||||
QByteArray outputBuffer;
|
|
||||||
outputBuffer.resize(numDeviceOutputSamples * sizeof(int16_t));
|
|
||||||
|
|
||||||
int numSamplesNeededToStartPlayback = std::min(NETWORK_BUFFER_LENGTH_SAMPLES_STEREO + (_jitterBufferSamples * 2),
|
int numSamplesNeededToStartPlayback = std::min(NETWORK_BUFFER_LENGTH_SAMPLES_STEREO + (_jitterBufferSamples * 2),
|
||||||
_ringBuffer.getSampleCapacity());
|
_ringBuffer.getSampleCapacity());
|
||||||
|
@ -885,6 +882,11 @@ void Audio::processReceivedAudio(const QByteArray& audioByteArray) {
|
||||||
// We are still waiting for enough samples to begin playback
|
// We are still waiting for enough samples to begin playback
|
||||||
// qDebug() << numNetworkOutputSamples << " samples so far, waiting for " << numSamplesNeededToStartPlayback;
|
// qDebug() << numNetworkOutputSamples << " samples so far, waiting for " << numSamplesNeededToStartPlayback;
|
||||||
} else {
|
} 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.
|
// We are either already playing back, or we have enough audio to start playing back.
|
||||||
//qDebug() << "pushing " << numNetworkOutputSamples;
|
//qDebug() << "pushing " << numNetworkOutputSamples;
|
||||||
_ringBuffer.setIsStarved(false);
|
_ringBuffer.setIsStarved(false);
|
||||||
|
|
|
@ -99,7 +99,8 @@ PositionalAudioRingBuffer::PositionalAudioRingBuffer(PositionalAudioRingBuffer::
|
||||||
_listenerUnattenuatedZone(NULL),
|
_listenerUnattenuatedZone(NULL),
|
||||||
_desiredJitterBufferFrames(1),
|
_desiredJitterBufferFrames(1),
|
||||||
_currentJitterBufferFrames(-1),
|
_currentJitterBufferFrames(-1),
|
||||||
_dynamicJitterBuffers(dynamicJitterBuffers)
|
_dynamicJitterBuffers(dynamicJitterBuffers),
|
||||||
|
_consecutiveNotMixedCount(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,7 +130,7 @@ int PositionalAudioRingBuffer::parseData(const QByteArray& packet) {
|
||||||
numSilentSamples = getSamplesPerFrame();
|
numSilentSamples = getSamplesPerFrame();
|
||||||
|
|
||||||
if (numSilentSamples > 0) {
|
if (numSilentSamples > 0) {
|
||||||
if (_currentJitterBufferFrames > _desiredJitterBufferFrames) {
|
if (_dynamicJitterBuffers && _currentJitterBufferFrames > _desiredJitterBufferFrames) {
|
||||||
// our current jitter buffer size exceeds its desired value, so ignore some silent
|
// our current jitter buffer size exceeds its desired value, so ignore some silent
|
||||||
// frames to get that size as close to desired as possible
|
// frames to get that size as close to desired as possible
|
||||||
int samplesPerFrame = getSamplesPerFrame();
|
int samplesPerFrame = getSamplesPerFrame();
|
||||||
|
@ -206,11 +207,12 @@ bool PositionalAudioRingBuffer::shouldBeAddedToMix() {
|
||||||
if (!isNotStarvedOrHasMinimumSamples(samplesPerFrame + desiredJitterBufferSamples)) {
|
if (!isNotStarvedOrHasMinimumSamples(samplesPerFrame + desiredJitterBufferSamples)) {
|
||||||
// if the buffer was starved, allow it to accrue at least the desired number of
|
// 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
|
// jitter buffer frames before we start taking frames from it for mixing
|
||||||
|
|
||||||
if (_shouldOutputStarveDebug) {
|
if (_shouldOutputStarveDebug) {
|
||||||
_shouldOutputStarveDebug = false;
|
_shouldOutputStarveDebug = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_consecutiveNotMixedCount++;
|
||||||
return false;
|
return false;
|
||||||
} else if (samplesAvailable() < samplesPerFrame) {
|
} else if (samplesAvailable() < samplesPerFrame) {
|
||||||
// if the buffer doesn't have a full frame of samples to take for mixing, it is starved
|
// 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
|
// reset our _shouldOutputStarveDebug to true so the next is printed
|
||||||
_shouldOutputStarveDebug = true;
|
_shouldOutputStarveDebug = true;
|
||||||
|
|
||||||
|
_consecutiveNotMixedCount++;
|
||||||
return false;
|
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
|
// minus one (since a frame will be read immediately after this) is the length of the jitter buffer
|
||||||
_currentJitterBufferFrames = samplesAvailable() / samplesPerFrame - 1;
|
_currentJitterBufferFrames = samplesAvailable() / samplesPerFrame - 1;
|
||||||
_isStarved = false;
|
_isStarved = false;
|
||||||
|
_consecutiveNotMixedCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// since we've read data from ring buffer at least once - we've started
|
// since we've read data from ring buffer at least once - we've started
|
||||||
|
|
|
@ -83,6 +83,8 @@ public:
|
||||||
int getDesiredJitterBufferFrames() const { return _desiredJitterBufferFrames; }
|
int getDesiredJitterBufferFrames() const { return _desiredJitterBufferFrames; }
|
||||||
int getCurrentJitterBufferFrames() const { return _currentJitterBufferFrames; }
|
int getCurrentJitterBufferFrames() const { return _currentJitterBufferFrames; }
|
||||||
|
|
||||||
|
int getConsecutiveNotMixedCount() const { return _consecutiveNotMixedCount; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// disallow copying of PositionalAudioRingBuffer objects
|
// disallow copying of PositionalAudioRingBuffer objects
|
||||||
PositionalAudioRingBuffer(const PositionalAudioRingBuffer&);
|
PositionalAudioRingBuffer(const PositionalAudioRingBuffer&);
|
||||||
|
@ -107,9 +109,7 @@ protected:
|
||||||
bool _dynamicJitterBuffers;
|
bool _dynamicJitterBuffers;
|
||||||
|
|
||||||
// extra stats
|
// extra stats
|
||||||
int _starveCount;
|
int _consecutiveNotMixedCount;
|
||||||
int _silentFramesDropped;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_PositionalAudioRingBuffer_h
|
#endif // hifi_PositionalAudioRingBuffer_h
|
||||||
|
|
Loading…
Reference in a new issue