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
c28bfbc5
Commit
c28bfbc5
authored
Sep 11, 2015
by
Andrew Eikum
Committed by
Alexandre Julliard
Sep 14, 2015
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
xaudio2: Support looping buffers.
Also shorten up the test runtime.
parent
031af2ca
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
382 additions
and
15 deletions
+382
-15
xaudio2.c
dlls/xaudio2_7/tests/xaudio2.c
+259
-6
xaudio_dll.c
dlls/xaudio2_7/xaudio_dll.c
+123
-9
No files found.
dlls/xaudio2_7/tests/xaudio2.c
View file @
c28bfbc5
...
...
@@ -209,9 +209,9 @@ static void test_simple_streaming(IXAudio2 *xa)
ok
(
hr
==
S_OK
,
"CreateSourceVoice failed: %08x
\n
"
,
hr
);
memset
(
&
buf
,
0
,
sizeof
(
buf
));
buf
.
AudioBytes
=
4410
0
*
fmt
.
nBlockAlign
;
buf
.
AudioBytes
=
2205
0
*
fmt
.
nBlockAlign
;
buf
.
pAudioData
=
HeapAlloc
(
GetProcessHeap
(),
0
,
buf
.
AudioBytes
);
fill_buf
((
float
*
)
buf
.
pAudioData
,
&
fmt
,
440
,
4410
0
);
fill_buf
((
float
*
)
buf
.
pAudioData
,
&
fmt
,
440
,
2205
0
);
hr
=
IXAudio2SourceVoice_SubmitSourceBuffer
(
src
,
&
buf
,
NULL
);
ok
(
hr
==
S_OK
,
"SubmitSourceBuffer failed: %08x
\n
"
,
hr
);
...
...
@@ -224,9 +224,9 @@ static void test_simple_streaming(IXAudio2 *xa)
ok
(
hr
==
S_OK
,
"CreateSourceVoice failed: %08x
\n
"
,
hr
);
memset
(
&
buf2
,
0
,
sizeof
(
buf2
));
buf2
.
AudioBytes
=
4410
0
*
fmt
.
nBlockAlign
;
buf2
.
AudioBytes
=
2205
0
*
fmt
.
nBlockAlign
;
buf2
.
pAudioData
=
HeapAlloc
(
GetProcessHeap
(),
0
,
buf2
.
AudioBytes
);
fill_buf
((
float
*
)
buf2
.
pAudioData
,
&
fmt
,
220
,
4410
0
);
fill_buf
((
float
*
)
buf2
.
pAudioData
,
&
fmt
,
220
,
2205
0
);
hr
=
IXAudio2SourceVoice_SubmitSourceBuffer
(
src2
,
&
buf2
,
NULL
);
ok
(
hr
==
S_OK
,
"SubmitSourceBuffer failed: %08x
\n
"
,
hr
);
...
...
@@ -264,12 +264,12 @@ static void test_simple_streaming(IXAudio2 *xa)
IXAudio27SourceVoice_GetState
((
IXAudio27SourceVoice
*
)
src
,
&
state
);
else
IXAudio2SourceVoice_GetState
(
src
,
&
state
,
0
);
if
(
state
.
SamplesPlayed
>=
4410
0
)
if
(
state
.
SamplesPlayed
>=
2205
0
)
break
;
Sleep
(
100
);
}
ok
(
state
.
SamplesPlayed
==
4410
0
,
"Got wrong samples played
\n
"
);
ok
(
state
.
SamplesPlayed
==
2205
0
,
"Got wrong samples played
\n
"
);
HeapFree
(
GetProcessHeap
(),
0
,
(
void
*
)
buf
.
pAudioData
);
HeapFree
(
GetProcessHeap
(),
0
,
(
void
*
)
buf2
.
pAudioData
);
...
...
@@ -373,6 +373,45 @@ static const IXAudio2VoiceCallbackVtbl vcb_buf_vtbl = {
static
IXAudio2VoiceCallback
vcb_buf
=
{
&
vcb_buf_vtbl
};
static
int
nloopends
=
0
;
static
void
WINAPI
loop_buf_OnStreamEnd
(
IXAudio2VoiceCallback
*
This
)
{
}
static
void
WINAPI
loop_buf_OnBufferStart
(
IXAudio2VoiceCallback
*
This
,
void
*
pBufferContext
)
{
}
static
void
WINAPI
loop_buf_OnBufferEnd
(
IXAudio2VoiceCallback
*
This
,
void
*
pBufferContext
)
{
}
static
void
WINAPI
loop_buf_OnLoopEnd
(
IXAudio2VoiceCallback
*
This
,
void
*
pBufferContext
)
{
++
nloopends
;
}
static
void
WINAPI
loop_buf_OnVoiceError
(
IXAudio2VoiceCallback
*
This
,
void
*
pBuffercontext
,
HRESULT
Error
)
{
}
static
const
IXAudio2VoiceCallbackVtbl
loop_buf_vtbl
=
{
vcb_buf_OnVoiceProcessingPassStart
,
vcb_buf_OnVoiceProcessingPassEnd
,
loop_buf_OnStreamEnd
,
loop_buf_OnBufferStart
,
loop_buf_OnBufferEnd
,
loop_buf_OnLoopEnd
,
loop_buf_OnVoiceError
};
static
IXAudio2VoiceCallback
loop_buf
=
{
&
loop_buf_vtbl
};
static
void
test_buffer_callbacks
(
IXAudio2
*
xa
)
{
HRESULT
hr
;
...
...
@@ -450,6 +489,218 @@ static void test_buffer_callbacks(IXAudio2 *xa)
IXAudio2MasteringVoice_DestroyVoice
(
master
);
}
static
UINT32
play_to_completion
(
IXAudio2SourceVoice
*
src
,
UINT32
max_samples
)
{
XAUDIO2_VOICE_STATE
state
;
HRESULT
hr
;
nloopends
=
0
;
hr
=
IXAudio2SourceVoice_Start
(
src
,
0
,
XAUDIO2_COMMIT_NOW
);
ok
(
hr
==
S_OK
,
"Start failed: %08x
\n
"
,
hr
);
while
(
1
){
if
(
xaudio27
)
IXAudio27SourceVoice_GetState
((
IXAudio27SourceVoice
*
)
src
,
&
state
);
else
IXAudio2SourceVoice_GetState
(
src
,
&
state
,
0
);
if
(
state
.
BuffersQueued
==
0
)
break
;
if
(
state
.
SamplesPlayed
>=
max_samples
){
if
(
xaudio27
)
IXAudio27SourceVoice_ExitLoop
((
IXAudio27SourceVoice
*
)
src
,
XAUDIO2_COMMIT_NOW
);
else
IXAudio2SourceVoice_ExitLoop
(
src
,
XAUDIO2_COMMIT_NOW
);
}
Sleep
(
100
);
}
hr
=
IXAudio2SourceVoice_Stop
(
src
,
0
,
XAUDIO2_COMMIT_NOW
);
ok
(
hr
==
S_OK
,
"Start failed: %08x
\n
"
,
hr
);
return
state
.
SamplesPlayed
;
}
static
void
test_looping
(
IXAudio2
*
xa
)
{
HRESULT
hr
;
IXAudio2MasteringVoice
*
master
;
IXAudio2SourceVoice
*
src
;
WAVEFORMATEX
fmt
;
XAUDIO2_BUFFER
buf
;
UINT32
played
,
running_total
=
0
;
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
,
&
loop_buf
,
NULL
,
NULL
);
ok
(
hr
==
S_OK
,
"CreateSourceVoice failed: %08x
\n
"
,
hr
);
memset
(
&
buf
,
0
,
sizeof
(
buf
));
buf
.
AudioBytes
=
44100
*
fmt
.
nBlockAlign
;
buf
.
pAudioData
=
HeapAlloc
(
GetProcessHeap
(),
0
,
buf
.
AudioBytes
);
fill_buf
((
float
*
)
buf
.
pAudioData
,
&
fmt
,
440
,
44100
);
XA2CALL_0
(
StartEngine
);
ok
(
hr
==
S_OK
,
"StartEngine failed: %08x
\n
"
,
hr
);
/* play from middle to end */
buf
.
PlayBegin
=
22050
;
buf
.
PlayLength
=
0
;
buf
.
LoopBegin
=
0
;
buf
.
LoopLength
=
0
;
buf
.
LoopCount
=
0
;
hr
=
IXAudio2SourceVoice_SubmitSourceBuffer
(
src
,
&
buf
,
NULL
);
ok
(
hr
==
S_OK
,
"SubmitSourceBuffer failed: %08x
\n
"
,
hr
);
played
=
play_to_completion
(
src
,
-
1
);
ok
(
played
-
running_total
==
22050
,
"Got wrong samples played: %u
\n
"
,
played
-
running_total
);
running_total
=
played
;
ok
(
nloopends
==
0
,
"Got wrong OnLoopEnd calls: %u
\n
"
,
nloopends
);
/* play 4410 samples from middle */
buf
.
PlayBegin
=
22050
;
buf
.
PlayLength
=
4410
;
buf
.
LoopBegin
=
0
;
buf
.
LoopLength
=
0
;
buf
.
LoopCount
=
0
;
hr
=
IXAudio2SourceVoice_SubmitSourceBuffer
(
src
,
&
buf
,
NULL
);
ok
(
hr
==
S_OK
,
"SubmitSourceBuffer failed: %08x
\n
"
,
hr
);
played
=
play_to_completion
(
src
,
-
1
);
ok
(
played
-
running_total
==
4410
,
"Got wrong samples played: %u
\n
"
,
played
-
running_total
);
running_total
=
played
;
ok
(
nloopends
==
0
,
"Got wrong OnLoopEnd calls: %u
\n
"
,
nloopends
);
/* loop 4410 samples in middle */
buf
.
PlayBegin
=
0
;
buf
.
PlayLength
=
0
;
buf
.
LoopBegin
=
22050
;
buf
.
LoopLength
=
4410
;
buf
.
LoopCount
=
1
;
hr
=
IXAudio2SourceVoice_SubmitSourceBuffer
(
src
,
&
buf
,
NULL
);
ok
(
hr
==
S_OK
,
"SubmitSourceBuffer failed: %08x
\n
"
,
hr
);
played
=
play_to_completion
(
src
,
-
1
);
ok
(
played
-
running_total
==
44100
+
4410
,
"Got wrong samples played: %u
\n
"
,
played
-
running_total
);
running_total
=
played
;
ok
(
nloopends
==
1
,
"Got wrong OnLoopEnd calls: %u
\n
"
,
nloopends
);
/* play last half, then loop the whole buffer */
buf
.
PlayBegin
=
22050
;
buf
.
PlayLength
=
0
;
buf
.
LoopBegin
=
0
;
buf
.
LoopLength
=
0
;
buf
.
LoopCount
=
1
;
hr
=
IXAudio2SourceVoice_SubmitSourceBuffer
(
src
,
&
buf
,
NULL
);
ok
(
hr
==
S_OK
,
"SubmitSourceBuffer failed: %08x
\n
"
,
hr
);
played
=
play_to_completion
(
src
,
-
1
);
ok
(
played
-
running_total
==
22050
+
44100
,
"Got wrong samples played: %u
\n
"
,
played
-
running_total
);
running_total
=
played
;
ok
(
nloopends
==
1
,
"Got wrong OnLoopEnd calls: %u
\n
"
,
nloopends
);
/* play short segment from middle, loop to the beginning, and end at PlayEnd */
buf
.
PlayBegin
=
22050
;
buf
.
PlayLength
=
4410
;
buf
.
LoopBegin
=
0
;
buf
.
LoopLength
=
0
;
buf
.
LoopCount
=
1
;
hr
=
IXAudio2SourceVoice_SubmitSourceBuffer
(
src
,
&
buf
,
NULL
);
ok
(
hr
==
S_OK
,
"SubmitSourceBuffer failed: %08x
\n
"
,
hr
);
played
=
play_to_completion
(
src
,
-
1
);
ok
(
played
-
running_total
==
4410
+
(
22050
+
4410
),
"Got wrong samples played: %u
\n
"
,
played
-
running_total
);
running_total
=
played
;
ok
(
nloopends
==
1
,
"Got wrong OnLoopEnd calls: %u
\n
"
,
nloopends
);
/* invalid: LoopEnd must be <= PlayEnd
* xaudio27: play until LoopEnd, loop to beginning, play until PlayEnd */
buf
.
PlayBegin
=
22050
;
buf
.
PlayLength
=
4410
;
buf
.
LoopBegin
=
0
;
buf
.
LoopLength
=
22050
+
4410
*
2
;
buf
.
LoopCount
=
1
;
hr
=
IXAudio2SourceVoice_SubmitSourceBuffer
(
src
,
&
buf
,
NULL
);
if
(
xaudio27
){
ok
(
hr
==
S_OK
,
"SubmitSourceBuffer failed: %08x
\n
"
,
hr
);
played
=
play_to_completion
(
src
,
-
1
);
ok
(
played
-
running_total
==
4410
+
(
22050
+
4410
*
2
),
"Got wrong samples played: %u
\n
"
,
played
-
running_total
);
running_total
=
played
;
ok
(
nloopends
==
1
,
"Got wrong OnLoopEnd calls: %u
\n
"
,
nloopends
);
}
else
ok
(
hr
==
XAUDIO2_E_INVALID_CALL
,
"SubmitSourceBuffer should have failed: %08x
\n
"
,
hr
);
/* invalid: LoopEnd must be within play range
* xaudio27: plays only play range */
buf
.
PlayBegin
=
22050
;
buf
.
PlayLength
=
0
;
/* == until end of buffer */
buf
.
LoopBegin
=
0
;
buf
.
LoopLength
=
22050
;
buf
.
LoopCount
=
1
;
hr
=
IXAudio2SourceVoice_SubmitSourceBuffer
(
src
,
&
buf
,
NULL
);
if
(
xaudio27
){
ok
(
hr
==
S_OK
,
"SubmitSourceBuffer failed: %08x
\n
"
,
hr
);
played
=
play_to_completion
(
src
,
-
1
);
ok
(
played
-
running_total
==
22050
,
"Got wrong samples played: %u
\n
"
,
played
-
running_total
);
running_total
=
played
;
ok
(
nloopends
==
0
,
"Got wrong OnLoopEnd calls: %u
\n
"
,
nloopends
);
}
else
ok
(
hr
==
XAUDIO2_E_INVALID_CALL
,
"SubmitSourceBuffer should have failed: %08x
\n
"
,
hr
);
/* invalid: LoopBegin must be before PlayEnd
* xaudio27: crashes */
if
(
!
xaudio27
){
buf
.
PlayBegin
=
0
;
buf
.
PlayLength
=
4410
;
buf
.
LoopBegin
=
22050
;
buf
.
LoopLength
=
4410
;
buf
.
LoopCount
=
1
;
hr
=
IXAudio2SourceVoice_SubmitSourceBuffer
(
src
,
&
buf
,
NULL
);
ok
(
hr
==
XAUDIO2_E_INVALID_CALL
,
"SubmitSourceBuffer should have failed: %08x
\n
"
,
hr
);
}
/* infinite looping buffer */
buf
.
PlayBegin
=
22050
;
buf
.
PlayLength
=
0
;
buf
.
LoopBegin
=
0
;
buf
.
LoopLength
=
0
;
buf
.
LoopCount
=
255
;
hr
=
IXAudio2SourceVoice_SubmitSourceBuffer
(
src
,
&
buf
,
NULL
);
ok
(
hr
==
S_OK
,
"SubmitSourceBuffer failed: %08x
\n
"
,
hr
);
played
=
play_to_completion
(
src
,
running_total
+
88200
);
ok
(
played
-
running_total
==
22050
+
44100
*
2
,
"Got wrong samples played: %u
\n
"
,
played
-
running_total
);
ok
(
nloopends
==
(
played
-
running_total
)
/
88200
+
1
,
"Got wrong OnLoopEnd calls: %u
\n
"
,
nloopends
);
running_total
=
played
;
}
static
UINT32
test_DeviceDetails
(
IXAudio27
*
xa
)
{
HRESULT
hr
;
...
...
@@ -519,6 +770,7 @@ START_TEST(xaudio2)
test_DeviceDetails
(
xa27
);
test_simple_streaming
((
IXAudio2
*
)
xa27
);
test_buffer_callbacks
((
IXAudio2
*
)
xa27
);
test_looping
((
IXAudio2
*
)
xa27
);
}
else
skip
(
"No audio devices available
\n
"
);
...
...
@@ -537,6 +789,7 @@ START_TEST(xaudio2)
if
(
has_devices
){
test_simple_streaming
(
xa
);
test_buffer_callbacks
(
xa
);
test_looping
(
xa
);
}
else
skip
(
"No audio devices available
\n
"
);
...
...
dlls/xaudio2_7/xaudio_dll.c
View file @
c28bfbc5
...
...
@@ -80,6 +80,9 @@ static void dump_fmt(const WAVEFORMATEX *fmt)
TRACE
(
"dwChannelMask: %08x
\n
"
,
fmtex
->
dwChannelMask
);
TRACE
(
"Samples: %04x
\n
"
,
fmtex
->
Samples
.
wReserved
);
TRACE
(
"SubFormat: %s
\n
"
,
wine_dbgstr_guid
(
&
fmtex
->
SubFormat
));
}
else
if
(
fmt
->
wFormatTag
==
WAVE_FORMAT_ADPCM
){
ADPCMWAVEFORMAT
*
fmtadpcm
=
(
void
*
)
fmt
;
TRACE
(
"wSamplesPerBlock: %u
\n
"
,
fmtadpcm
->
wSamplesPerBlock
);
}
}
...
...
@@ -127,7 +130,7 @@ HRESULT WINAPI DllUnregisterServer(void)
typedef
struct
_XA2Buffer
{
XAUDIO2_BUFFER
xa2buffer
;
DWORD
offs_bytes
;
UINT32
latest_al_buf
;
UINT32
latest_al_buf
,
looped
,
loop_end_bytes
,
play_end_bytes
,
cur_end_bytes
;
}
XA2Buffer
;
typedef
struct
_IXAudio2Impl
IXAudio2Impl
;
...
...
@@ -625,7 +628,67 @@ static HRESULT WINAPI XA2SRC_SubmitSourceBuffer(IXAudio2SourceVoice *iface,
* but pBuffer itself may be reused immediately */
memcpy
(
&
buf
->
xa2buffer
,
pBuffer
,
sizeof
(
*
pBuffer
));
buf
->
offs_bytes
=
0
;
/* convert samples offsets to bytes */
if
(
This
->
fmt
->
wFormatTag
==
WAVE_FORMAT_ADPCM
){
/* ADPCM gives us a number of samples per block, so round down to
* nearest block and convert to bytes */
buf
->
xa2buffer
.
PlayBegin
=
buf
->
xa2buffer
.
PlayBegin
/
((
ADPCMWAVEFORMAT
*
)
This
->
fmt
)
->
wSamplesPerBlock
*
This
->
fmt
->
nBlockAlign
;
buf
->
xa2buffer
.
PlayLength
=
buf
->
xa2buffer
.
PlayLength
/
((
ADPCMWAVEFORMAT
*
)
This
->
fmt
)
->
wSamplesPerBlock
*
This
->
fmt
->
nBlockAlign
;
buf
->
xa2buffer
.
LoopBegin
=
buf
->
xa2buffer
.
LoopBegin
/
((
ADPCMWAVEFORMAT
*
)
This
->
fmt
)
->
wSamplesPerBlock
*
This
->
fmt
->
nBlockAlign
;
buf
->
xa2buffer
.
LoopLength
=
buf
->
xa2buffer
.
LoopLength
/
((
ADPCMWAVEFORMAT
*
)
This
->
fmt
)
->
wSamplesPerBlock
*
This
->
fmt
->
nBlockAlign
;
}
else
{
buf
->
xa2buffer
.
PlayBegin
*=
This
->
fmt
->
nBlockAlign
;
buf
->
xa2buffer
.
PlayLength
*=
This
->
fmt
->
nBlockAlign
;
buf
->
xa2buffer
.
LoopBegin
*=
This
->
fmt
->
nBlockAlign
;
buf
->
xa2buffer
.
LoopLength
*=
This
->
fmt
->
nBlockAlign
;
}
if
(
buf
->
xa2buffer
.
PlayLength
==
0
)
/* set to end of buffer */
buf
->
xa2buffer
.
PlayLength
=
buf
->
xa2buffer
.
AudioBytes
-
buf
->
xa2buffer
.
PlayBegin
;
buf
->
play_end_bytes
=
buf
->
xa2buffer
.
PlayBegin
+
buf
->
xa2buffer
.
PlayLength
;
if
(
buf
->
xa2buffer
.
LoopCount
){
if
(
buf
->
xa2buffer
.
LoopLength
==
0
)
/* set to end of play range */
buf
->
xa2buffer
.
LoopLength
=
buf
->
play_end_bytes
-
buf
->
xa2buffer
.
LoopBegin
;
if
(
buf
->
xa2buffer
.
LoopBegin
>=
buf
->
play_end_bytes
){
/* this actually crashes on native xaudio 2.7 */
LeaveCriticalSection
(
&
This
->
lock
);
return
XAUDIO2_E_INVALID_CALL
;
}
buf
->
loop_end_bytes
=
buf
->
xa2buffer
.
LoopBegin
+
buf
->
xa2buffer
.
LoopLength
;
/* xaudio 2.7 allows some invalid looping setups, but later versions
* return an error */
if
(
This
->
xa2
->
version
>
27
){
if
(
buf
->
loop_end_bytes
>
buf
->
play_end_bytes
){
LeaveCriticalSection
(
&
This
->
lock
);
return
XAUDIO2_E_INVALID_CALL
;
}
if
(
buf
->
loop_end_bytes
<=
buf
->
xa2buffer
.
PlayBegin
){
LeaveCriticalSection
(
&
This
->
lock
);
return
XAUDIO2_E_INVALID_CALL
;
}
}
else
{
if
(
buf
->
loop_end_bytes
<=
buf
->
xa2buffer
.
PlayBegin
){
buf
->
xa2buffer
.
LoopCount
=
0
;
buf
->
loop_end_bytes
=
buf
->
play_end_bytes
;
}
}
}
else
{
buf
->
xa2buffer
.
LoopLength
=
buf
->
xa2buffer
.
PlayLength
;
buf
->
xa2buffer
.
LoopBegin
=
buf
->
xa2buffer
.
PlayBegin
;
buf
->
loop_end_bytes
=
buf
->
play_end_bytes
;
}
buf
->
offs_bytes
=
buf
->
xa2buffer
.
PlayBegin
;
buf
->
cur_end_bytes
=
buf
->
loop_end_bytes
;
buf
->
latest_al_buf
=
-
1
;
++
This
->
nbufs
;
...
...
@@ -692,7 +755,15 @@ static HRESULT WINAPI XA2SRC_Discontinuity(IXAudio2SourceVoice *iface)
static
HRESULT
WINAPI
XA2SRC_ExitLoop
(
IXAudio2SourceVoice
*
iface
,
UINT32
OperationSet
)
{
XA2SourceImpl
*
This
=
impl_from_IXAudio2SourceVoice
(
iface
);
TRACE
(
"%p, 0x%x
\n
"
,
This
,
OperationSet
);
EnterCriticalSection
(
&
This
->
lock
);
This
->
buffers
[
This
->
cur_buf
].
looped
=
XAUDIO2_LOOP_INFINITE
;
LeaveCriticalSection
(
&
This
->
lock
);
return
S_OK
;
}
...
...
@@ -2908,12 +2979,12 @@ static BOOL xa2buffer_queue_period(XA2SourceImpl *src, XA2Buffer *buf, ALuint al
UINT32
submit_bytes
;
const
BYTE
*
submit_buf
=
NULL
;
if
(
buf
->
offs_bytes
>=
buf
->
xa2buffer
.
AudioB
ytes
){
if
(
buf
->
offs_bytes
>=
buf
->
cur_end_b
ytes
){
WARN
(
"Shouldn't happen: Trying to push frames from a spent buffer?
\n
"
);
return
FALSE
;
}
submit_bytes
=
min
(
src
->
xa2
->
period_frames
*
src
->
submit_blocksize
,
buf
->
xa2buffer
.
AudioB
ytes
-
buf
->
offs_bytes
);
submit_bytes
=
min
(
src
->
xa2
->
period_frames
*
src
->
submit_blocksize
,
buf
->
cur_end_b
ytes
-
buf
->
offs_bytes
);
submit_buf
=
buf
->
xa2buffer
.
pAudioData
+
buf
->
offs_bytes
;
buf
->
offs_bytes
+=
submit_bytes
;
...
...
@@ -2929,9 +3000,32 @@ static BOOL xa2buffer_queue_period(XA2SourceImpl *src, XA2Buffer *buf, ALuint al
TRACE
(
"queueing %u bytes, now %u in AL
\n
"
,
submit_bytes
,
src
->
in_al_bytes
);
return
buf
->
offs_bytes
<
buf
->
xa2buffer
.
AudioB
ytes
;
return
buf
->
offs_bytes
<
buf
->
cur_end_b
ytes
;
}
/* Looping:
*
* The looped section of a buffer is a subset of the play area which is looped
* LoopCount times.
*
* v PlayBegin
* vvvvvvvvvvvvvvvvvv PlayLength
* v (PlayEnd)
* [-----PPPLLLLLLLLPPPPPPP------]
* ^ LoopBegin
* ^^^^^^^^ LoopLength
* ^ (LoopEnd)
*
* 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.
*
* If PlayLength is zero, then PlayEnd is the end of the buffer.
*
* If LoopLength is zero, then LoopEnd is PlayEnd.
*
* For corner cases and version differences, see tests.
*/
static
void
update_source_state
(
XA2SourceImpl
*
src
)
{
int
i
;
...
...
@@ -2985,15 +3079,35 @@ static void update_source_state(XA2SourceImpl *src)
TRACE
(
"%p: going to queue a period from buffer %u
\n
"
,
src
,
src
->
cur_buf
);
/* starting from an empty buffer */
if
(
src
->
cb
&&
src
->
cur_buf
==
src
->
first_buf
&&
src
->
buffers
[
src
->
cur_buf
].
offs_bytes
==
0
)
if
(
src
->
cb
&&
src
->
cur_buf
==
src
->
first_buf
&&
src
->
buffers
[
src
->
cur_buf
].
offs_bytes
==
0
&&
!
src
->
buffers
[
src
->
cur_buf
].
looped
)
IXAudio2VoiceCallback_OnBufferStart
(
src
->
cb
,
src
->
buffers
[
src
->
first_buf
].
xa2buffer
.
pContext
);
if
(
!
xa2buffer_queue_period
(
src
,
&
src
->
buffers
[
src
->
cur_buf
],
src
->
al_bufs
[(
src
->
first_al_buf
+
src
->
al_bufs_used
)
%
XAUDIO2_MAX_QUEUED_BUFFERS
])){
/* buffer is spent, move on */
src
->
cur_buf
++
;
src
->
cur_buf
%=
XAUDIO2_MAX_QUEUED_BUFFERS
;
XA2Buffer
*
cur
=
&
src
->
buffers
[
src
->
cur_buf
];
if
(
cur
->
looped
<
cur
->
xa2buffer
.
LoopCount
){
if
(
cur
->
xa2buffer
.
LoopCount
!=
XAUDIO2_LOOP_INFINITE
)
++
cur
->
looped
;
else
cur
->
looped
=
1
;
/* indicate that we are executing a loop */
cur
->
offs_bytes
=
cur
->
xa2buffer
.
LoopBegin
;
if
(
cur
->
looped
==
cur
->
xa2buffer
.
LoopCount
)
cur
->
cur_end_bytes
=
cur
->
play_end_bytes
;
else
cur
->
cur_end_bytes
=
cur
->
loop_end_bytes
;
if
(
src
->
cb
)
IXAudio2VoiceCallback_OnLoopEnd
(
src
->
cb
,
src
->
buffers
[
src
->
cur_buf
].
xa2buffer
.
pContext
);
}
else
{
/* buffer is spent, move on */
src
->
cur_buf
++
;
src
->
cur_buf
%=
XAUDIO2_MAX_QUEUED_BUFFERS
;
}
}
}
}
...
...
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