Browse Source

Work around occasional pops in streaming sources on iOS, by making the streaming source update code more like what was there in 0.10.x.

Alex Szpakowski 6 years ago
parent
commit
8b51dc831d
1 changed files with 25 additions and 22 deletions
  1. 25 22
      src/modules/audio/openal/Source.cpp

+ 25 - 22
src/modules/audio/openal/Source.cpp

@@ -396,36 +396,39 @@ bool Source::update()
 		case TYPE_STREAM:
 			if (!isFinished())
 			{
-				ALint processed;
-				ALuint buffers[MAX_BUFFERS];
-				float curOffsetSamples, curOffsetSecs, newOffsetSamples, newOffsetSecs;
 				int freq = decoder->getSampleRate();
 
-				alGetSourcef(source, AL_SAMPLE_OFFSET, &curOffsetSamples);
-				curOffsetSecs = curOffsetSamples / freq;
-
+				ALint processed;
 				alGetSourcei(source, AL_BUFFERS_PROCESSED, &processed);
-				alSourceUnqueueBuffers(source, processed, buffers);
 
-				alGetSourcef(source, AL_SAMPLE_OFFSET, &newOffsetSamples);
-				newOffsetSecs = newOffsetSamples / freq;
+				// It would theoretically be better to unqueue all processed
+				// buffers in a single call to alSourceUnqueueBuffers, but on
+				// iOS I observed occasional (every ~5-10 seconds) pops in the
+				// streaming source test I was using, when doing that. Perhaps
+				// there was a bug in this code when I was testing, or maybe
+				// this code runs into the same problem but now it's much harder
+				// to reproduce. The test I used is the play-stop-play .love
+				// from https://bitbucket.org/rude/love/issues/1484/
+				while (processed--)
+				{
+					float curOffsetSamples, curOffsetSecs;
+					alGetSourcef(source, AL_SAMPLE_OFFSET, &curOffsetSamples);
+					curOffsetSecs = curOffsetSamples / freq;
+
+					ALuint buffer;
+					alSourceUnqueueBuffers(source, 1, &buffer);
 
-				offsetSamples += (curOffsetSamples - newOffsetSamples);
-				offsetSeconds += (curOffsetSecs - newOffsetSecs);
+					float newOffsetSamples, newOffsetSecs;
+					alGetSourcef(source, AL_SAMPLE_OFFSET, &newOffsetSamples);
+					newOffsetSecs = newOffsetSamples / freq;
 
-				for (int i = 0; i < processed; i++)
-					unusedBuffers.push(buffers[i]);
+					offsetSamples += (curOffsetSamples - newOffsetSamples);
+					offsetSeconds += (curOffsetSecs - newOffsetSecs);
 
-				while (!unusedBuffers.empty())
-				{
-					auto b = unusedBuffers.top();
-					if (streamAtomic(b, decoder.get()) > 0)
-					{
-						alSourceQueueBuffers(source, 1, &b);
-						unusedBuffers.pop();
-					}
+					if (streamAtomic(buffer, decoder.get()) > 0)
+						alSourceQueueBuffers(source, 1, &buffer);
 					else
-						break;
+						unusedBuffers.push(buffer);
 				}
 
 				return true;