Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
e2c73fc3
Commit
e2c73fc3
authored
Nov 30, 2017
by
Andrew Eikum
Committed by
Alexandre Julliard
Nov 30, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
xaudio2: Ignore buffers returned from OpenAL after Stop.
Signed-off-by:
Andrew Eikum
<
aeikum@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
b802f883
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
128 additions
and
31 deletions
+128
-31
xaudio2.c
dlls/xaudio2_7/tests/xaudio2.c
+78
-0
xaudio_dll.c
dlls/xaudio2_7/xaudio_dll.c
+49
-30
xaudio_private.h
dlls/xaudio2_7/xaudio_private.h
+1
-1
No files found.
dlls/xaudio2_7/tests/xaudio2.c
View file @
e2c73fc3
...
...
@@ -841,6 +841,82 @@ static void test_submix(IXAudio2 *xa)
IXAudio2MasteringVoice_DestroyVoice
(
master
);
}
static
void
test_flush
(
IXAudio2
*
xa
)
{
HRESULT
hr
;
IXAudio2MasteringVoice
*
master
;
IXAudio2SourceVoice
*
src
;
WAVEFORMATEX
fmt
;
XAUDIO2_BUFFER
buf
;
XAUDIO2_VOICE_STATE
state
;
XA2CALL_0V
(
StopEngine
);
if
(
xaudio27
)
hr
=
IXAudio27_CreateMasteringVoice
((
IXAudio27
*
)
xa
,
&
master
,
2
,
44100
,
0
,
0
,
NULL
);
else
hr
=
IXAudio2_CreateMasteringVoice
(
xa
,
&
master
,
2
,
44100
,
0
,
NULL
,
NULL
,
AudioCategory_GameEffects
);
ok
(
hr
==
S_OK
,
"CreateMasteringVoice failed: %08x
\n
"
,
hr
);
fmt
.
wFormatTag
=
WAVE_FORMAT_IEEE_FLOAT
;
fmt
.
nChannels
=
2
;
fmt
.
nSamplesPerSec
=
44100
;
fmt
.
wBitsPerSample
=
32
;
fmt
.
nBlockAlign
=
fmt
.
nChannels
*
fmt
.
wBitsPerSample
/
8
;
fmt
.
nAvgBytesPerSec
=
fmt
.
nSamplesPerSec
*
fmt
.
nBlockAlign
;
fmt
.
cbSize
=
0
;
XA2CALL
(
CreateSourceVoice
,
&
src
,
&
fmt
,
0
,
1
.
f
,
NULL
,
NULL
,
NULL
);
ok
(
hr
==
S_OK
,
"CreateSourceVoice failed: %08x
\n
"
,
hr
);
memset
(
&
buf
,
0
,
sizeof
(
buf
));
buf
.
AudioBytes
=
22050
*
fmt
.
nBlockAlign
;
buf
.
pAudioData
=
HeapAlloc
(
GetProcessHeap
(),
0
,
buf
.
AudioBytes
);
fill_buf
((
float
*
)
buf
.
pAudioData
,
&
fmt
,
440
,
22050
);
hr
=
IXAudio2SourceVoice_SubmitSourceBuffer
(
src
,
&
buf
,
NULL
);
ok
(
hr
==
S_OK
,
"SubmitSourceBuffer failed: %08x
\n
"
,
hr
);
hr
=
IXAudio2SourceVoice_Start
(
src
,
0
,
XAUDIO2_COMMIT_NOW
);
ok
(
hr
==
S_OK
,
"Start failed: %08x
\n
"
,
hr
);
XA2CALL_0
(
StartEngine
);
ok
(
hr
==
S_OK
,
"StartEngine failed: %08x
\n
"
,
hr
);
while
(
1
){
if
(
xaudio27
)
IXAudio27SourceVoice_GetState
((
IXAudio27SourceVoice
*
)
src
,
&
state
);
else
IXAudio2SourceVoice_GetState
(
src
,
&
state
,
0
);
if
(
state
.
SamplesPlayed
>=
2205
)
break
;
Sleep
(
10
);
}
hr
=
IXAudio2SourceVoice_Stop
(
src
,
0
,
XAUDIO2_COMMIT_NOW
);
ok
(
hr
==
S_OK
,
"Stop failed: %08x
\n
"
,
hr
);
hr
=
IXAudio2SourceVoice_FlushSourceBuffers
(
src
);
ok
(
hr
==
S_OK
,
"FlushSourceBuffers failed: %08x
\n
"
,
hr
);
hr
=
IXAudio2SourceVoice_Start
(
src
,
0
,
XAUDIO2_COMMIT_NOW
);
ok
(
hr
==
S_OK
,
"Start failed: %08x
\n
"
,
hr
);
Sleep
(
100
);
hr
=
IXAudio2SourceVoice_SubmitSourceBuffer
(
src
,
&
buf
,
NULL
);
ok
(
hr
==
S_OK
,
"SubmitSourceBuffer failed: %08x
\n
"
,
hr
);
if
(
xaudio27
){
IXAudio27SourceVoice_DestroyVoice
((
IXAudio27SourceVoice
*
)
src
);
}
else
{
IXAudio2SourceVoice_DestroyVoice
(
src
);
}
IXAudio2MasteringVoice_DestroyVoice
(
master
);
HeapFree
(
GetProcessHeap
(),
0
,
(
void
*
)
buf
.
pAudioData
);
}
static
UINT32
test_DeviceDetails
(
IXAudio27
*
xa
)
{
HRESULT
hr
;
...
...
@@ -1136,6 +1212,7 @@ START_TEST(xaudio2)
test_buffer_callbacks
((
IXAudio2
*
)
xa27
);
test_looping
((
IXAudio2
*
)
xa27
);
test_submix
((
IXAudio2
*
)
xa27
);
test_flush
((
IXAudio2
*
)
xa27
);
}
else
skip
(
"No audio devices available
\n
"
);
...
...
@@ -1159,6 +1236,7 @@ START_TEST(xaudio2)
test_buffer_callbacks
(
xa
);
test_looping
(
xa
);
test_submix
(
xa
);
test_flush
(
xa
);
}
else
skip
(
"No audio devices available
\n
"
);
...
...
dlls/xaudio2_7/xaudio_dll.c
View file @
e2c73fc3
...
...
@@ -414,6 +414,7 @@ static void WINAPI XA2SRC_DestroyVoice(IXAudio2SourceVoice *iface)
This
->
nbufs
=
0
;
This
->
first_buf
=
0
;
This
->
cur_buf
=
0
;
This
->
abandoned_albufs
=
0
;
LeaveCriticalSection
(
&
This
->
lock
);
}
...
...
@@ -438,11 +439,18 @@ static HRESULT WINAPI XA2SRC_Stop(IXAudio2SourceVoice *iface, UINT32 Flags,
UINT32
OperationSet
)
{
XA2SourceImpl
*
This
=
impl_from_IXAudio2SourceVoice
(
iface
);
ALint
bufs
;
TRACE
(
"%p, 0x%x, 0x%x
\n
"
,
This
,
Flags
,
OperationSet
);
palcSetThreadContext
(
This
->
xa2
->
al_ctx
);
EnterCriticalSection
(
&
This
->
lock
);
alGetSourcei
(
This
->
al_src
,
AL_BUFFERS_QUEUED
,
&
bufs
);
This
->
abandoned_albufs
=
bufs
;
This
->
running
=
FALSE
;
LeaveCriticalSection
(
&
This
->
lock
);
...
...
@@ -2273,44 +2281,53 @@ static void update_source_state(XA2SourceImpl *src)
ALuint
al_buffers
[
XAUDIO2_MAX_QUEUED_BUFFERS
];
alSourceUnqueueBuffers
(
src
->
al_src
,
processed
,
al_buffers
);
src
->
first_al_buf
+=
processed
;
src
->
first_al_buf
%=
XAUDIO2_MAX_QUEUED_BUFFERS
;
src
->
al_bufs_used
-=
processed
;
for
(
i
=
0
;
i
<
processed
;
++
i
){
ALint
bufsize
;
alGetBufferi
(
al_buffers
[
i
],
AL_SIZE
,
&
bufsize
);
if
(
processed
>
src
->
abandoned_albufs
){
for
(
i
=
src
->
abandoned_albufs
;
i
<
processed
;
++
i
){
ALint
bufsize
;
src
->
in_al_bytes
-=
bufsize
;
src
->
played_frames
+=
bufsize
/
src
->
submit_blocksize
;
alGetBufferi
(
al_buffers
[
i
],
AL_SIZE
,
&
bufsize
);
if
(
al_buffers
[
i
]
==
src
->
buffers
[
src
->
first_buf
].
latest_al_buf
){
DWORD
old_buf
=
src
->
first_buf
;
src
->
in_al_bytes
-=
bufsize
;
src
->
played_frames
+=
bufsize
/
src
->
submit_blocksize
;
src
->
first_buf
++
;
src
->
first_buf
%=
XAUDIO2_MAX_QUEUED_BUFFERS
;
src
->
nbufs
--
;
if
(
al_buffers
[
i
]
==
src
->
buffers
[
src
->
first_buf
].
latest_al_buf
){
DWORD
old_buf
=
src
->
first_buf
;
TRACE
(
"%p: done with buffer %u
\n
"
,
src
,
old_buf
);
src
->
first_buf
++
;
src
->
first_buf
%=
XAUDIO2_MAX_QUEUED_BUFFERS
;
src
->
nbufs
--
;
if
(
src
->
buffers
[
old_buf
].
xa2buffer
.
Flags
&
XAUDIO2_END_OF_STREAM
)
src
->
played_frames
=
0
;
TRACE
(
"%p: done with buffer %u
\n
"
,
src
,
old_buf
);
if
(
src
->
cb
){
IXAudio2VoiceCallback_OnBufferEnd
(
src
->
cb
,
src
->
buffers
[
old_buf
].
xa2buffer
.
pContext
);
if
(
src
->
buffers
[
old_buf
].
xa2buffer
.
Flags
&
XAUDIO2_END_OF_STREAM
)
IXAudio2VoiceCallback_OnStreamEnd
(
src
->
cb
);
if
(
src
->
nbufs
>
0
)
IXAudio2VoiceCallback_OnBufferStart
(
src
->
cb
,
src
->
buffers
[
src
->
first_buf
].
xa2buffer
.
pContext
);
src
->
played_frames
=
0
;
if
(
src
->
cb
){
IXAudio2VoiceCallback_OnBufferEnd
(
src
->
cb
,
src
->
buffers
[
old_buf
].
xa2buffer
.
pContext
);
if
(
src
->
buffers
[
old_buf
].
xa2buffer
.
Flags
&
XAUDIO2_END_OF_STREAM
)
IXAudio2VoiceCallback_OnStreamEnd
(
src
->
cb
);
if
(
src
->
nbufs
>
0
)
IXAudio2VoiceCallback_OnBufferStart
(
src
->
cb
,
src
->
buffers
[
src
->
first_buf
].
xa2buffer
.
pContext
);
}
}
}
}
src
->
abandoned_albufs
=
0
;
}
else
src
->
abandoned_albufs
-=
processed
;
}
if
(
!
src
->
running
)
return
;
alGetSourcei
(
src
->
al_src
,
AL_BYTE_OFFSET
,
&
bufpos
);
/* maintain IN_AL_PERIODS periods in AL */
...
...
@@ -2384,12 +2401,12 @@ static void do_engine_tick(IXAudio2Impl *This)
EnterCriticalSection
(
&
src
->
lock
);
if
(
!
src
->
in_use
||
!
src
->
running
){
if
(
!
src
->
in_use
){
LeaveCriticalSection
(
&
src
->
lock
);
continue
;
}
if
(
src
->
cb
){
if
(
src
->
cb
&&
This
->
running
){
#if XAUDIO2_VER == 0
IXAudio20VoiceCallback_OnVoiceProcessingPassStart
((
IXAudio20VoiceCallback
*
)
src
->
cb
);
#else
...
...
@@ -2403,12 +2420,14 @@ static void do_engine_tick(IXAudio2Impl *This)
update_source_state
(
src
);
alGetSourcei
(
src
->
al_src
,
AL_SOURCE_STATE
,
&
st
);
if
(
st
!=
AL_PLAYING
)
alSourcePlay
(
src
->
al_src
);
if
(
This
->
running
){
alGetSourcei
(
src
->
al_src
,
AL_SOURCE_STATE
,
&
st
);
if
(
st
!=
AL_PLAYING
)
alSourcePlay
(
src
->
al_src
);
if
(
src
->
cb
)
IXAudio2VoiceCallback_OnVoiceProcessingPassEnd
(
src
->
cb
);
if
(
src
->
cb
)
IXAudio2VoiceCallback_OnVoiceProcessingPassEnd
(
src
->
cb
);
}
LeaveCriticalSection
(
&
src
->
lock
);
}
...
...
dlls/xaudio2_7/xaudio_private.h
View file @
e2c73fc3
...
...
@@ -81,7 +81,7 @@ typedef struct _XA2SourceImpl {
/* most cases will only need about 4 AL buffers, but some corner cases
* could require up to MAX_QUEUED_BUFFERS */
ALuint
al_bufs
[
XAUDIO2_MAX_QUEUED_BUFFERS
];
DWORD
first_al_buf
,
al_bufs_used
;
DWORD
first_al_buf
,
al_bufs_used
,
abandoned_albufs
;
struct
list
entry
;
}
XA2SourceImpl
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment