@@ -97,42 +97,47 @@ void CSoundRender_TargetA::update()
9797{
9898 inherited::update ();
9999
100- ALint processed;
101- // Get status
102- A_CHK (alGetSourcei (pSource, AL_BUFFERS_PROCESSED, &processed));
100+ ALint processed, state;
101+ ALenum error;
103102
104- if (processed > 0 )
103+ /* Get relevant source info */
104+ alGetSourcei (pSource, AL_SOURCE_STATE, &state);
105+ alGetSourcei (pSource, AL_BUFFERS_PROCESSED, &processed);
106+ if ((error = alGetError ()) != AL_NO_ERROR)
105107 {
106- while (processed)
108+ Msg (" ! %s:: source state check failed (0x%d)" , __FUNCTION__, error);
109+ return ;
110+ }
111+
112+ while (processed > 0 )
113+ {
114+ ALuint BufferID;
115+ A_CHK (alSourceUnqueueBuffers (pSource, 1 , &BufferID));
116+ fill_block (BufferID);
117+ A_CHK (alSourceQueueBuffers (pSource, 1 , &BufferID));
118+ processed--;
119+ if ((error = alGetError ()) != AL_NO_ERROR)
107120 {
108- ALuint BufferID;
109- A_CHK (alSourceUnqueueBuffers (pSource, 1 , &BufferID));
110- fill_block (BufferID);
111- A_CHK (alSourceQueueBuffers (pSource, 1 , &BufferID));
112- --processed;
121+ Msg (" ! %s:: buffering data failed (0x%d)" , __FUNCTION__, error);
122+ return ;
113123 }
114-
115- // kcat: If there's a long enough freeze and the sources underrun, they go to an AL_STOPPED state.
116- // That update function will correctly see this and remove/refill/requeue the buffers, but doesn't restart the source
117- // (that's in the separate else block that didn't run this time).Because the source remains AL_STOPPED,
118- // the next update will still see all the buffers marked as processed and remove / refill / requeue them again.
119- // It keeps doing this and never actually restarts the source after an underrun.
120- ALint state;
121- A_CHK (alGetSourcei (pSource, AL_SOURCE_STATE, &state));
122- if (state == AL_STOPPED)
123- A_CHK (alSourcePlay (pSource));
124- //
125124 }
126- else
125+
126+ /* Make sure the source hasn't underrun */
127+ if (state != AL_PLAYING && state != AL_PAUSED)
127128 {
128- // processed == 0
129- // check play status -- if stopped then queue is not being filled fast enough
130- ALint state;
131- A_CHK (alGetSourcei (pSource, AL_SOURCE_STATE, &state));
132- if (state != AL_PLAYING)
129+ ALint queued;
130+
131+ /* If no buffers are queued, playback is finished */
132+ alGetSourcei (pSource, AL_BUFFERS_QUEUED, &queued);
133+ if (queued == 0 )
134+ return ;
135+
136+ alSourcePlay (pSource);
137+ if ((error = alGetError ()) != AL_NO_ERROR)
133138 {
134- // Log("Queuing underrun detected." );
135- A_CHK ( alSourcePlay (pSource)) ;
139+ Msg ( " ! %s:: restarting playback failed (0x%d) " , __FUNCTION__, error );
140+ return ;
136141 }
137142 }
138143}
0 commit comments