Audio: Fix a glitch at the end of a sound. (#5578)

This is happening because the processing function keeps reading audio
data from the AudioBuffer even after it has been marked as stopped.

There is also an error in ReadAudioBufferFramesInInternalFormat() where
if it is called on a stopped sound, it'll still return audio frames.
This has also been addressed with this commit.
This commit is contained in:
David Reid
2026-02-21 17:04:32 +10:00
committed by GitHub
parent 005ff74eb0
commit 0c91f230fd

View File

@ -2377,6 +2377,12 @@ static void OnLog(void *pUserData, ma_uint32 level, const char *pMessage)
// Reads audio data from an AudioBuffer object in internal format // Reads audio data from an AudioBuffer object in internal format
static ma_uint32 ReadAudioBufferFramesInInternalFormat(AudioBuffer *audioBuffer, void *framesOut, ma_uint32 frameCount) static ma_uint32 ReadAudioBufferFramesInInternalFormat(AudioBuffer *audioBuffer, void *framesOut, ma_uint32 frameCount)
{ {
// Don't read anything if the sound is not playing
if (!audioBuffer->playing)
{
return 0;
}
// Using audio buffer callback // Using audio buffer callback
if (audioBuffer->callback) if (audioBuffer->callback)
{ {
@ -2522,18 +2528,20 @@ static ma_uint32 ReadAudioBufferFramesInMixingFormat(AudioBuffer *audioBuffer, f
{ {
estimatedInputFrameCount = inputBufferFrameCap; estimatedInputFrameCount = inputBufferFrameCap;
} }
ma_uint32 inputFramesInInternalFormatCount = ReadAudioBufferFramesInInternalFormat(audioBuffer, inputBuffer, estimatedInputFrameCount);
estimatedInputFrameCount = ReadAudioBufferFramesInInternalFormat(audioBuffer, inputBuffer, estimatedInputFrameCount); ma_uint64 inputFramesProcessedThisIteration = inputFramesInInternalFormatCount;
ma_uint64 inputFramesProcessedThisIteration = estimatedInputFrameCount;
ma_uint64 outputFramesProcessedThisIteration = outputFramesToProcessThisIteration; ma_uint64 outputFramesProcessedThisIteration = outputFramesToProcessThisIteration;
ma_data_converter_process_pcm_frames(&audioBuffer->converter, inputBuffer, &inputFramesProcessedThisIteration, runningFramesOut, &outputFramesProcessedThisIteration); ma_data_converter_process_pcm_frames(&audioBuffer->converter, inputBuffer, &inputFramesProcessedThisIteration, runningFramesOut, &outputFramesProcessedThisIteration);
if (estimatedInputFrameCount > inputFramesProcessedThisIteration) totalOutputFramesProcessed += (ma_uint32)outputFramesProcessedThisIteration;
if (inputFramesInInternalFormatCount > inputFramesProcessedThisIteration)
{ {
// Getting here means the estimated input frame count was overestimated. The residual needs // Getting here means the estimated input frame count was overestimated. The residual needs
// be stored for later use. // be stored for later use.
ma_uint64 residualFrameCount = estimatedInputFrameCount - inputFramesProcessedThisIteration; ma_uint64 residualFrameCount = inputFramesInInternalFormatCount - inputFramesProcessedThisIteration;
// A safety check to make sure the capacity of the residual cache is not exceeded. // A safety check to make sure the capacity of the residual cache is not exceeded.
if (residualFrameCount > AUDIO_BUFFER_RESIDUAL_CAPACITY) if (residualFrameCount > AUDIO_BUFFER_RESIDUAL_CAPACITY)
@ -2545,7 +2553,9 @@ static ma_uint32 ReadAudioBufferFramesInMixingFormat(AudioBuffer *audioBuffer, f
audioBuffer->converterResidualCount = residualFrameCount; audioBuffer->converterResidualCount = residualFrameCount;
} }
totalOutputFramesProcessed += (ma_uint32)outputFramesProcessedThisIteration; if (inputFramesInInternalFormatCount < estimatedInputFrameCount) {
break; // Reached the end of the sound
}
} }
} }