# HG changeset patch # User Eric Wing # Date 1319242459 25200 # Node ID db5bc1c80057283367fda0949aa3ba58c9dddf54 # Parent 4b0268d86298a6576c1d35aeacb061e9f16dfab6 Workaround for terrible iOS 5.0 regression bug in Apple's OpenAL implementation with regards to resetting streaming sources. The fix uses a version check to determine if the workaround is employed. Once Apple fixes the problem, an upper bounds version check should be added. diff -r 4b0268d86298 -r db5bc1c80057 ALmixer.c --- a/ALmixer.c Fri Sep 30 17:48:23 2011 -0700 +++ b/ALmixer.c Fri Oct 21 17:14:19 2011 -0700 @@ -1732,88 +1732,95 @@ */ if(kCFCoreFoundationVersionNumber >= 674.0) { - if(AL_FALSE == is_predecoded) + /* For OpenAL experts, this is contrary to what you know, but must be done because the OpenAL implementation is broken. + Instead of unqueuing buffers on only streaming sources, it appears that alSourcei(source, AL_BUFFER, AL_NONE) is not reliable at all. + In cases where I switch between stream and non-stream on the same source and then stream again, the bug breaks playback on the third playback + and only one buffer plays. + The workaround seems to be to always unqueue buffers regardless of whether the source is streamed or not. + And then avoid calling (source, AL_BUFFER, AL_NONE) + From past experience, I know it is a bad idea to try to unqueue buffers from a non-streamed source (which is the contrary to OpenAL part), + but this seems to work for this bug. + */ + ALint buffers_processed; + /* Wow this is the bug that just keeps on sucking. There is even a race condition bug where the unqueue may not actually work. + * So I have to keep doing it until it does. + */ + do { - ALint buffers_processed; + ALint temp_count; + /* Wow this is the bug that just keeps on sucking. There is even a race condition bug where the unqueue may not actually work. * So I have to keep doing it until it does. + * Sleeping for 20ms seems to help. 10ms was not long enough. (iPad 2) */ - do + ALmixer_Delay(20); + + alGetSourcei( + source_id, + AL_BUFFERS_PROCESSED, &buffers_processed + ); + if((error = alGetError()) != AL_NO_ERROR) { - ALint temp_count; - - /* Wow this is the bug that just keeps on sucking. There is even a race condition bug where the unqueue may not actually work. - * So I have to keep doing it until it does. - * Sleeping for 20ms seems to help. 10ms was not long enough. (iPad 2) - */ - ALmixer_Delay(20); - - alGetSourcei( + fprintf(stderr, "17aTesting Error with buffers_processed on Halt. (You may be seeing this because of a bad Apple OpenAL iOS 5.0 regression bug): %s", + alGetString(error)); + ALmixer_SetError("Failed detecting still processed buffers: %s", + alGetString(error) ); + /* This whole iOS 5.0 bug is so messed up that returning an error value probably isn't helpful. + retval = AL_FALSE; + */ + } + /* + fprintf(stderr, "Going to unqueue %d buffers\n", buffers_processed); + */ + for(temp_count=0; temp_count