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
ee126c96
Commit
ee126c96
authored
Dec 03, 2014
by
Andrew Eikum
Committed by
Alexandre Julliard
Dec 04, 2014
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
dsound: Report buffer notifications in offset order.
parent
5b7e49e8
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
165 additions
and
40 deletions
+165
-40
buffer.c
dlls/dsound/buffer.c
+22
-0
mixer.c
dlls/dsound/mixer.c
+59
-40
dsound.c
dlls/dsound/tests/dsound.c
+84
-0
No files found.
dlls/dsound/buffer.c
View file @
ee126c96
...
...
@@ -81,6 +81,27 @@ static ULONG WINAPI IDirectSoundNotifyImpl_Release(IDirectSoundNotify *iface)
return
ref
;
}
static
int
notify_compar
(
const
void
*
l
,
const
void
*
r
)
{
const
DSBPOSITIONNOTIFY
*
left
=
l
;
const
DSBPOSITIONNOTIFY
*
right
=
r
;
/* place DSBPN_OFFSETSTOP at the start of the sorted array */
if
(
left
->
dwOffset
==
DSBPN_OFFSETSTOP
){
if
(
right
->
dwOffset
!=
DSBPN_OFFSETSTOP
)
return
-
1
;
}
else
if
(
right
->
dwOffset
==
DSBPN_OFFSETSTOP
)
return
1
;
if
(
left
->
dwOffset
==
right
->
dwOffset
)
return
0
;
if
(
left
->
dwOffset
<
right
->
dwOffset
)
return
-
1
;
return
1
;
}
static
HRESULT
WINAPI
IDirectSoundNotifyImpl_SetNotificationPositions
(
IDirectSoundNotify
*
iface
,
DWORD
howmuch
,
const
DSBPOSITIONNOTIFY
*
notify
)
{
...
...
@@ -113,6 +134,7 @@ static HRESULT WINAPI IDirectSoundNotifyImpl_SetNotificationPositions(IDirectSou
}
CopyMemory
(
This
->
notifies
,
notify
,
howmuch
*
sizeof
(
DSBPOSITIONNOTIFY
));
This
->
nrofnotifies
=
howmuch
;
qsort
(
This
->
notifies
,
howmuch
,
sizeof
(
DSBPOSITIONNOTIFY
),
notify_compar
);
}
else
{
HeapFree
(
GetProcessHeap
(),
0
,
This
->
notifies
);
This
->
notifies
=
NULL
;
...
...
dlls/dsound/mixer.c
View file @
ee126c96
...
...
@@ -183,48 +183,67 @@ void DSOUND_RecalcFormat(IDirectSoundBufferImpl *dsb)
*/
void
DSOUND_CheckEvent
(
const
IDirectSoundBufferImpl
*
dsb
,
DWORD
playpos
,
int
len
)
{
int
i
;
DWORD
offset
;
LPDSBPOSITIONNOTIFY
event
;
TRACE
(
"(%p,%d)
\n
"
,
dsb
,
len
);
int
first
,
left
,
right
,
check
;
if
(
dsb
->
nrofnotifies
==
0
)
return
;
if
(
dsb
->
nrofnotifies
==
0
)
return
;
TRACE
(
"(%p) buflen = %d, playpos = %d, len = %d
\n
"
,
dsb
,
dsb
->
buflen
,
playpos
,
len
);
for
(
i
=
0
;
i
<
dsb
->
nrofnotifies
;
i
++
)
{
event
=
dsb
->
notifies
+
i
;
offset
=
event
->
dwOffset
;
TRACE
(
"checking %d, position %d, event = %p
\n
"
,
i
,
offset
,
event
->
hEventNotify
);
/* DSBPN_OFFSETSTOP has to be the last element. So this is */
/* OK. [Inside DirectX, p274] */
/* Windows does not seem to enforce this, and some apps rely */
/* on that, so we can't stop there. */
/* */
/* This also means we can't sort the entries by offset, */
/* because DSBPN_OFFSETSTOP == -1 */
if
(
offset
==
DSBPN_OFFSETSTOP
)
{
if
(
dsb
->
state
==
STATE_STOPPED
)
{
SetEvent
(
event
->
hEventNotify
);
TRACE
(
"signalled event %p (%d)
\n
"
,
event
->
hEventNotify
,
i
);
}
continue
;
}
if
((
playpos
+
len
)
>=
dsb
->
buflen
)
{
if
((
offset
<
((
playpos
+
len
)
%
dsb
->
buflen
))
||
(
offset
>=
playpos
))
{
TRACE
(
"signalled event %p (%d)
\n
"
,
event
->
hEventNotify
,
i
);
SetEvent
(
event
->
hEventNotify
);
}
}
else
{
if
((
offset
>=
playpos
)
&&
(
offset
<
(
playpos
+
len
)))
{
TRACE
(
"signalled event %p (%d)
\n
"
,
event
->
hEventNotify
,
i
);
SetEvent
(
event
->
hEventNotify
);
}
}
}
if
(
dsb
->
state
==
STATE_STOPPED
){
TRACE
(
"Stopped...
\n
"
);
/* DSBPN_OFFSETSTOP notifies are always at the start of the sorted array */
for
(
left
=
0
;
left
<
dsb
->
nrofnotifies
;
++
left
){
if
(
dsb
->
notifies
[
left
].
dwOffset
!=
DSBPN_OFFSETSTOP
)
break
;
TRACE
(
"Signalling %p
\n
"
,
dsb
->
notifies
[
left
].
hEventNotify
);
SetEvent
(
dsb
->
notifies
[
left
].
hEventNotify
);
}
return
;
}
for
(
first
=
0
;
first
<
dsb
->
nrofnotifies
&&
dsb
->
notifies
[
first
].
dwOffset
==
DSBPN_OFFSETSTOP
;
++
first
)
;
if
(
first
==
dsb
->
nrofnotifies
)
return
;
check
=
left
=
first
;
right
=
dsb
->
nrofnotifies
-
1
;
/* find leftmost notify that is greater than playpos */
while
(
left
!=
right
){
check
=
left
+
(
right
-
left
)
/
2
;
if
(
dsb
->
notifies
[
check
].
dwOffset
<
playpos
)
left
=
check
+
1
;
else
if
(
dsb
->
notifies
[
check
].
dwOffset
>
playpos
)
right
=
check
;
else
{
left
=
check
;
break
;
}
}
TRACE
(
"Not stopped: first notify: %u (%u), range: [%u,%u)
\n
"
,
first
,
dsb
->
notifies
[
check
].
dwOffset
,
playpos
,
(
playpos
+
len
)
%
dsb
->
buflen
);
/* send notifications in range */
for
(
check
=
left
;
check
<
dsb
->
nrofnotifies
;
++
check
){
if
(
dsb
->
notifies
[
check
].
dwOffset
>=
playpos
+
len
)
break
;
TRACE
(
"Signalling %p (%u)
\n
"
,
dsb
->
notifies
[
check
].
hEventNotify
,
dsb
->
notifies
[
check
].
dwOffset
);
SetEvent
(
dsb
->
notifies
[
check
].
hEventNotify
);
}
if
(
playpos
+
len
>
dsb
->
buflen
){
for
(
check
=
first
;
check
<
left
;
++
check
){
if
(
dsb
->
notifies
[
check
].
dwOffset
>=
(
playpos
+
len
)
%
dsb
->
buflen
)
break
;
TRACE
(
"Signalling %p (%u)
\n
"
,
dsb
->
notifies
[
check
].
hEventNotify
,
dsb
->
notifies
[
check
].
dwOffset
);
SetEvent
(
dsb
->
notifies
[
check
].
hEventNotify
);
}
}
}
static
inline
float
get_current_sample
(
const
IDirectSoundBufferImpl
*
dsb
,
...
...
dlls/dsound/tests/dsound.c
View file @
ee126c96
...
...
@@ -1486,6 +1486,89 @@ done:
return
S_OK
;
}
static
void
test_notifications
(
LPGUID
lpGuid
)
{
HRESULT
rc
;
IDirectSound
*
dso
;
IDirectSoundBuffer
*
buf
;
IDirectSoundNotify
*
buf_notif
;
DSBUFFERDESC
bufdesc
;
WAVEFORMATEX
wfx
;
DSBPOSITIONNOTIFY
notifies
[
2
];
HANDLE
handles
[
2
];
DWORD
expect
;
int
cycles
;
rc
=
pDirectSoundCreate
(
lpGuid
,
&
dso
,
NULL
);
ok
(
rc
==
DS_OK
||
rc
==
DSERR_NODRIVER
||
rc
==
DSERR_ALLOCATED
,
"DirectSoundCreate() failed: %08x
\n
"
,
rc
);
if
(
rc
!=
DS_OK
)
return
;
rc
=
IDirectSound_SetCooperativeLevel
(
dso
,
get_hwnd
(),
DSSCL_PRIORITY
);
ok
(
rc
==
DS_OK
,
"IDirectSound_SetCooperativeLevel() failed: %08x
\n
"
,
rc
);
if
(
rc
!=
DS_OK
){
IDirectSound_Release
(
dso
);
return
;
}
wfx
.
wFormatTag
=
WAVE_FORMAT_PCM
;
wfx
.
nChannels
=
1
;
wfx
.
nSamplesPerSec
=
44100
;
wfx
.
wBitsPerSample
=
16
;
wfx
.
nBlockAlign
=
wfx
.
nChannels
*
wfx
.
wBitsPerSample
/
8
;
wfx
.
nAvgBytesPerSec
=
wfx
.
nSamplesPerSec
*
wfx
.
nBlockAlign
;
wfx
.
cbSize
=
0
;
ZeroMemory
(
&
bufdesc
,
sizeof
(
bufdesc
));
bufdesc
.
dwSize
=
sizeof
(
bufdesc
);
bufdesc
.
dwFlags
=
DSBCAPS_CTRLPOSITIONNOTIFY
;
bufdesc
.
dwBufferBytes
=
wfx
.
nSamplesPerSec
*
wfx
.
nBlockAlign
/
2
;
/* 0.5s */
bufdesc
.
lpwfxFormat
=
&
wfx
;
rc
=
IDirectSound_CreateSoundBuffer
(
dso
,
&
bufdesc
,
&
buf
,
NULL
);
ok
(
rc
==
DS_OK
&&
buf
!=
NULL
,
"IDirectSound_CreateSoundBuffer() failed "
"to create a buffer %08x
\n
"
,
rc
);
rc
=
IDirectSoundBuffer_QueryInterface
(
buf
,
&
IID_IDirectSoundNotify
,
(
void
**
)
&
buf_notif
);
ok
(
rc
==
DS_OK
,
"QueryInterface(IID_IDirectSoundNotify): %08x
\n
"
,
rc
);
/* create notifications at each end of the buffer */
notifies
[
0
].
dwOffset
=
0
;
handles
[
0
]
=
notifies
[
0
].
hEventNotify
=
CreateEventW
(
NULL
,
FALSE
,
FALSE
,
NULL
);
notifies
[
1
].
dwOffset
=
bufdesc
.
dwBufferBytes
-
1
;
handles
[
1
]
=
notifies
[
1
].
hEventNotify
=
CreateEventW
(
NULL
,
FALSE
,
FALSE
,
NULL
);
rc
=
IDirectSoundNotify_SetNotificationPositions
(
buf_notif
,
2
,
notifies
);
ok
(
rc
==
DS_OK
,
"SetNotificationPositions: %08x
\n
"
,
rc
);
IDirectSoundNotify_Release
(
buf_notif
);
rc
=
IDirectSoundBuffer_Play
(
buf
,
0
,
0
,
DSBPLAY_LOOPING
);
ok
(
rc
==
DS_OK
,
"Play: %08x
\n
"
,
rc
);
expect
=
0
;
for
(
cycles
=
0
;
cycles
<
6
/* 1.5s */
;
++
cycles
){
DWORD
wait
;
/* since the notifications are on opposite ends of the entire buffer,
* they should arrive well-ordered in an alternating sequence. */
wait
=
WaitForMultipleObjects
(
2
,
handles
,
FALSE
,
1000
);
ok
(
wait
<=
WAIT_OBJECT_0
+
1
&&
wait
-
WAIT_OBJECT_0
==
expect
,
"Got unexpected notification order or timeout: %u
\n
"
,
wait
);
expect
=
!
expect
;
}
rc
=
IDirectSoundBuffer_Stop
(
buf
);
ok
(
rc
==
DS_OK
,
"Stop: %08x
\n
"
,
rc
);
CloseHandle
(
notifies
[
0
].
hEventNotify
);
CloseHandle
(
notifies
[
1
].
hEventNotify
);
IDirectSoundBuffer_Release
(
buf
);
IDirectSound_Release
(
dso
);
}
static
unsigned
int
number
;
static
BOOL
WINAPI
dsenum_callback
(
LPGUID
lpGuid
,
LPCSTR
lpcstrDescription
,
...
...
@@ -1516,6 +1599,7 @@ static BOOL WINAPI dsenum_callback(LPGUID lpGuid, LPCSTR lpcstrDescription,
test_frequency
(
lpGuid
);
test_duplicate
(
lpGuid
);
test_invalid_fmts
(
lpGuid
);
test_notifications
(
lpGuid
);
}
return
TRUE
;
...
...
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