[PATCH] xaudio2: Report incoming underruns to the application

Andrew Eikum aeikum at codeweavers.com
Mon Jan 25 13:17:31 CST 2016


This won't apply. I'll send a new version.

Andrew

On Mon, Jan 25, 2016 at 12:54:49PM -0600, Andrew Eikum wrote:
> Signed-off-by: Andrew Eikum <aeikum at codeweavers.com>
> ---
> 
> This should fix Bug 39092.
> 
>  dlls/xaudio2_7/xaudio_dll.c | 41 ++++++++++++++++++++++++++++++++++++-----
>  1 file changed, 36 insertions(+), 5 deletions(-)
> 
> diff --git a/dlls/xaudio2_7/xaudio_dll.c b/dlls/xaudio2_7/xaudio_dll.c
> index 8ae1a24..4c41016 100644
> --- a/dlls/xaudio2_7/xaudio_dll.c
> +++ b/dlls/xaudio2_7/xaudio_dll.c
> @@ -40,6 +40,8 @@ static void (ALC_APIENTRY *palcRenderSamplesSOFT)(ALCdevice*, ALCvoid*, ALCsizei
>  
>  static HINSTANCE instance;
>  
> +#define IN_AL_PERIODS 4
> +
>  #if XAUDIO2_VER == 0
>  #define COMPAT_E_INVALID_CALL E_INVALIDARG
>  #define COMPAT_E_DEVICE_INVALIDATED XAUDIO20_E_DEVICE_INVALIDATED
> @@ -2485,6 +2487,32 @@ static BOOL xa2buffer_queue_period(XA2SourceImpl *src, XA2Buffer *buf, ALuint al
>      return buf->offs_bytes < buf->cur_end_bytes;
>  }
>  
> +static UINT32 get_underrun_warning(XA2SourceImpl *src)
> +{
> +    UINT32 period_bytes = src->xa2->period_frames * src->submit_blocksize;
> +    UINT32 total = 0, i;
> +
> +    if(IS_WMA(src->fmt->wFormatTag))
> +        /* PCM only */
> +        return 0;
> +
> +    for(i = 0; i < src->nbufs && total < IN_AL_PERIODS * period_bytes; ++i){
> +        XA2Buffer *buf = &src->buffers[(src->first_buf + i) % XAUDIO2_MAX_QUEUED_BUFFERS];
> +        total += buf->cur_end_bytes - buf->offs_bytes;
> +        if(buf->xa2buffer.LoopCount == XAUDIO2_LOOP_INFINITE)
> +            return 0;
> +        if(buf->xa2buffer.LoopCount > 0){
> +            total += (buf->loop_end_bytes - buf->xa2buffer.LoopBegin) * (buf->xa2buffer.LoopCount - buf->looped);
> +            total += buf->play_end_bytes - buf->loop_end_bytes;
> +        }
> +    }
> +
> +    if(total >= IN_AL_PERIODS * period_bytes)
> +        return 0;
> +
> +    return ((IN_AL_PERIODS * period_bytes - total) / period_bytes + 1) * period_bytes;
> +}
> +
>  /* Looping:
>   *
>   * The looped section of a buffer is a subset of the play area which is looped
> @@ -2500,7 +2528,7 @@ static BOOL xa2buffer_queue_period(XA2SourceImpl *src, XA2Buffer *buf, ALuint al
>   *
>   * In the simple case, playback will start at PlayBegin. At LoopEnd, playback
>   * will move to LoopBegin and repeat that loop LoopCount times. Then, playback
> - * will cease at LoopEnd.
> + * will cease at PlayEnd.
>   *
>   * If PlayLength is zero, then PlayEnd is the end of the buffer.
>   *
> @@ -2560,9 +2588,9 @@ static void update_source_state(XA2SourceImpl *src)
>  
>      alGetSourcei(src->al_src, AL_BYTE_OFFSET, &bufpos);
>  
> -    /* maintain 4 periods in AL */
> +    /* maintain IN_AL_PERIODS periods in AL */
>      while(src->cur_buf != (src->first_buf + src->nbufs) % XAUDIO2_MAX_QUEUED_BUFFERS &&
> -            src->in_al_bytes - bufpos < 4 * src->xa2->period_frames * src->submit_blocksize){
> +            src->in_al_bytes - bufpos < IN_AL_PERIODS * src->xa2->period_frames * src->submit_blocksize){
>          TRACE("%p: going to queue a period from buffer %u\n", src, src->cur_buf);
>  
>          /* starting from an empty buffer */
> @@ -2640,8 +2668,11 @@ static void do_engine_tick(IXAudio2Impl *This)
>  #if XAUDIO2_VER == 0
>              IXAudio20VoiceCallback_OnVoiceProcessingPassStart((IXAudio20VoiceCallback*)src->cb);
>  #else
> -            /* TODO: detect incoming underrun and inform callback */
> -            IXAudio2VoiceCallback_OnVoiceProcessingPassStart(src->cb, 0);
> +            UINT32 underrun;
> +            underrun = get_underrun_warning(src);
> +            if(underrun > 0)
> +                TRACE("Calling OnVoiceProcessingPassStart with BytesRequired: %u\n", underrun);
> +            IXAudio2VoiceCallback_OnVoiceProcessingPassStart(src->cb, underrun);
>  #endif
>          }
>  
> -- 
> 2.7.0
> 
> 
> 



More information about the wine-devel mailing list