diff --git a/libraries/audio/src/AudioConstants.h b/libraries/audio/src/AudioConstants.h index 6c12c6aa15..d5fd3f15e7 100644 --- a/libraries/audio/src/AudioConstants.h +++ b/libraries/audio/src/AudioConstants.h @@ -29,7 +29,10 @@ namespace AudioConstants { const int NETWORK_FRAME_SAMPLES_PER_CHANNEL = NETWORK_FRAME_BYTES_PER_CHANNEL / sizeof(AudioSample); const float NETWORK_FRAME_MSECS = (AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL / (float)AudioConstants::SAMPLE_RATE) * 1000.0f; + + // be careful with overflows when using this constant const int NETWORK_FRAME_USECS = static_cast(NETWORK_FRAME_MSECS * 1000.0f); + const int MIN_SAMPLE_VALUE = std::numeric_limits::min(); const int MAX_SAMPLE_VALUE = std::numeric_limits::max(); } diff --git a/libraries/audio/src/AudioInjector.cpp b/libraries/audio/src/AudioInjector.cpp index 8eb032f8a8..ea63df7f17 100644 --- a/libraries/audio/src/AudioInjector.cpp +++ b/libraries/audio/src/AudioInjector.cpp @@ -295,14 +295,7 @@ int64_t AudioInjector::injectNextFrame() { if (audioMixer) { // send off this audio packet - auto bytesWritten = nodeList->sendUnreliablePacket(*_currentPacket, *audioMixer); - if (bytesWritten < 0) { - auto currentTime = _frameTimer->nsecsElapsed() / 1000; - qDebug() << this << "error sending audio injector packet. NF:" - << _nextFrame << "CT:" << currentTime - << "CF:" << currentTime / AudioConstants::NETWORK_FRAME_USECS; - } - + nodeList->sendUnreliablePacket(*_currentPacket, *audioMixer); _outgoingSequenceNumber++; } @@ -321,14 +314,16 @@ int64_t AudioInjector::injectNextFrame() { const int MAX_ALLOWED_FRAMES_TO_FALL_BEHIND = 7; int64_t currentTime = _frameTimer->nsecsElapsed() / 1000; auto currentFrameBasedOnElapsedTime = currentTime / AudioConstants::NETWORK_FRAME_USECS; + if (currentFrameBasedOnElapsedTime - _nextFrame > MAX_ALLOWED_FRAMES_TO_FALL_BEHIND) { // If we are falling behind by more frames than our threshold, let's skip the frames ahead - qDebug() << "AudioInjector::injectNextFrame() skipping ahead, fell behind by " << (currentFrameBasedOnElapsedTime - _nextFrame) << " frames"; + qDebug() << this << "injectNextFrame() skipping ahead, fell behind by " << (currentFrameBasedOnElapsedTime - _nextFrame) << " frames"; _nextFrame = currentFrameBasedOnElapsedTime; _currentSendOffset = _nextFrame * AudioConstants::NETWORK_FRAME_BYTES_PER_CHANNEL * (_options.stereo ? 2 : 1) % _audioData.size(); } int64_t playNextFrameAt = ++_nextFrame * AudioConstants::NETWORK_FRAME_USECS; + return std::max(INT64_C(0), playNextFrameAt - currentTime); } diff --git a/libraries/audio/src/AudioInjector.h b/libraries/audio/src/AudioInjector.h index acfbc2b04a..79e2e645dd 100644 --- a/libraries/audio/src/AudioInjector.h +++ b/libraries/audio/src/AudioInjector.h @@ -99,7 +99,7 @@ private: AbstractAudioInterface* _localAudioInterface { nullptr }; AudioInjectorLocalBuffer* _localBuffer { nullptr }; - int _nextFrame { 0 }; + int64_t _nextFrame { 0 }; std::unique_ptr _frameTimer { nullptr }; quint16 _outgoingSequenceNumber { 0 }; diff --git a/libraries/audio/src/AudioInjectorManager.cpp b/libraries/audio/src/AudioInjectorManager.cpp index b91bddc553..2327bda0e7 100644 --- a/libraries/audio/src/AudioInjectorManager.cpp +++ b/libraries/audio/src/AudioInjectorManager.cpp @@ -87,7 +87,7 @@ void AudioInjectorManager::run() { if (!injector.isNull()) { // this is an injector that's ready to go, have it send a frame now auto nextCallDelta = injector->injectNextFrame(); - + if (nextCallDelta >= 0 && !injector->isFinished()) { // re-enqueue the injector with the correct timing _injectors.emplace(usecTimestampNow() + nextCallDelta, injector);