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
62510ddb
Commit
62510ddb
authored
Jan 13, 2001
by
Ove Kaaven
Committed by
Alexandre Julliard
Jan 13, 2001
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fixes for various underrun-related problems. Also added a mechanism
for the sound driver to request that a Stop should close and reopen the device.
parent
0a01fbda
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
50 additions
and
14 deletions
+50
-14
dsound_main.c
dlls/dsound/dsound_main.c
+50
-14
No files found.
dlls/dsound/dsound_main.c
View file @
62510ddb
...
@@ -1032,6 +1032,35 @@ static void DSOUND_PrimaryClose(IDirectSoundBufferImpl *dsb)
...
@@ -1032,6 +1032,35 @@ static void DSOUND_PrimaryClose(IDirectSoundBufferImpl *dsb)
}
}
}
}
static
HRESULT
DSOUND_PrimaryPlay
(
IDirectSoundBufferImpl
*
dsb
)
{
HRESULT
err
=
DS_OK
;
if
(
dsb
->
hwbuf
)
err
=
IDsDriverBuffer_Play
(
dsb
->
hwbuf
,
0
,
0
,
DSBPLAY_LOOPING
);
return
err
;
}
static
HRESULT
DSOUND_PrimaryStop
(
IDirectSoundBufferImpl
*
dsb
)
{
HRESULT
err
=
DS_OK
;
if
(
dsb
->
hwbuf
)
{
err
=
IDsDriverBuffer_Stop
(
dsb
->
hwbuf
);
if
(
err
==
DSERR_BUFFERLOST
)
{
/* Wine-only: the driver wants us to reopen the device */
/* FIXME: check for errors */
IDsDriverBuffer_Release
(
primarybuf
->
hwbuf
);
waveOutClose
(
dsb
->
dsound
->
hwo
);
dsb
->
dsound
->
hwo
=
0
;
waveOutOpen
(
&
(
dsb
->
dsound
->
hwo
),
dsb
->
dsound
->
drvdesc
.
dnDevNode
,
&
(
primarybuf
->
wfx
),
0
,
0
,
CALLBACK_NULL
|
WAVE_DIRECTSOUND
);
err
=
IDsDriver_CreateSoundBuffer
(
dsb
->
dsound
->
driver
,
&
(
dsb
->
wfx
),
dsb
->
dsbd
.
dwFlags
,
0
,
&
(
dsb
->
buflen
),
&
(
dsb
->
buffer
),
(
LPVOID
)
&
(
dsb
->
hwbuf
));
}
}
return
err
;
}
/* This sets this format for the <em>Primary Buffer Only</em> */
/* This sets this format for the <em>Primary Buffer Only</em> */
/* See file:///cdrom/sdk52/docs/worddoc/dsound.doc page 120 */
/* See file:///cdrom/sdk52/docs/worddoc/dsound.doc page 120 */
static
HRESULT
WINAPI
IDirectSoundBufferImpl_SetFormat
(
static
HRESULT
WINAPI
IDirectSoundBufferImpl_SetFormat
(
...
@@ -1304,7 +1333,7 @@ static DWORD WINAPI IDirectSoundBufferImpl_Release(LPDIRECTSOUNDBUFFER iface) {
...
@@ -1304,7 +1333,7 @@ static DWORD WINAPI IDirectSoundBufferImpl_Release(LPDIRECTSOUNDBUFFER iface) {
}
}
static
DWORD
DSOUND_CalcPlayPosition
(
IDirectSoundBufferImpl
*
This
,
static
DWORD
DSOUND_CalcPlayPosition
(
IDirectSoundBufferImpl
*
This
,
DWORD
state
,
DWORD
pplay
,
DWORD
pmix
,
DWORD
bmix
)
DWORD
state
,
DWORD
pplay
,
DWORD
p
write
,
DWORD
p
mix
,
DWORD
bmix
)
{
{
DWORD
bplay
;
DWORD
bplay
;
...
@@ -1325,7 +1354,9 @@ static DWORD DSOUND_CalcPlayPosition(IDirectSoundBufferImpl *This,
...
@@ -1325,7 +1354,9 @@ static DWORD DSOUND_CalcPlayPosition(IDirectSoundBufferImpl *This,
if
(
pmix
<
pplay
)
pmix
+=
primarybuf
->
buflen
;
/* wraparound */
if
(
pmix
<
pplay
)
pmix
+=
primarybuf
->
buflen
;
/* wraparound */
pmix
-=
pplay
;
pmix
-=
pplay
;
/* detect buffer underrun */
/* detect buffer underrun */
if
((
pmix
>
((
DS_SND_QUEUE
+
1
)
*
primarybuf
->
dsound
->
fraglen
+
primarybuf
->
writelead
)))
{
if
(
pwrite
<
pplay
)
pwrite
+=
primarybuf
->
buflen
;
/* wraparound */
pwrite
-=
pplay
;
if
(
pmix
>
(
DS_SND_QUEUE
*
primarybuf
->
dsound
->
fraglen
+
pwrite
+
primarybuf
->
writelead
))
{
TRACE
(
"detected an underrun: primary queue was %ld
\n
"
,
pmix
);
TRACE
(
"detected an underrun: primary queue was %ld
\n
"
,
pmix
);
pmix
=
0
;
pmix
=
0
;
}
}
...
@@ -1383,11 +1414,11 @@ static HRESULT WINAPI IDirectSoundBufferImpl_GetCurrentPosition(
...
@@ -1383,11 +1414,11 @@ static HRESULT WINAPI IDirectSoundBufferImpl_GetCurrentPosition(
*
playpos
=
This
->
buf_mixpos
;
*
playpos
=
This
->
buf_mixpos
;
}
}
else
if
(
playpos
)
{
else
if
(
playpos
)
{
DWORD
pplay
,
lplay
,
splay
,
pstate
;
DWORD
pplay
,
pwrite
,
lplay
,
splay
,
pstate
;
/* let's get this exact; first, recursively call GetPosition on the primary */
/* let's get this exact; first, recursively call GetPosition on the primary */
EnterCriticalSection
(
&
(
primarybuf
->
lock
));
EnterCriticalSection
(
&
(
primarybuf
->
lock
));
if
((
This
->
dsbd
.
dwFlags
&
DSBCAPS_GETCURRENTPOSITION2
)
||
primarybuf
->
hwbuf
||
!
DS_EMULDRIVER
)
{
if
((
This
->
dsbd
.
dwFlags
&
DSBCAPS_GETCURRENTPOSITION2
)
||
primarybuf
->
hwbuf
||
!
DS_EMULDRIVER
)
{
IDirectSoundBufferImpl_GetCurrentPosition
((
LPDIRECTSOUNDBUFFER
)
primarybuf
,
&
pplay
,
NULL
);
IDirectSoundBufferImpl_GetCurrentPosition
((
LPDIRECTSOUNDBUFFER
)
primarybuf
,
&
pplay
,
&
pwrite
);
/* detect HEL mode underrun */
/* detect HEL mode underrun */
pstate
=
primarybuf
->
state
;
pstate
=
primarybuf
->
state
;
if
(
!
(
primarybuf
->
hwbuf
||
primarybuf
->
dsound
->
pwqueue
))
{
if
(
!
(
primarybuf
->
hwbuf
||
primarybuf
->
dsound
->
pwqueue
))
{
...
@@ -1403,7 +1434,7 @@ static HRESULT WINAPI IDirectSoundBufferImpl_GetCurrentPosition(
...
@@ -1403,7 +1434,7 @@ static HRESULT WINAPI IDirectSoundBufferImpl_GetCurrentPosition(
lplay
=
This
->
primary_mixpos
;
lplay
=
This
->
primary_mixpos
;
splay
=
This
->
buf_mixpos
;
splay
=
This
->
buf_mixpos
;
/* calculate play position using this */
/* calculate play position using this */
*
playpos
=
DSOUND_CalcPlayPosition
(
This
,
pstate
,
pplay
,
lplay
,
splay
);
*
playpos
=
DSOUND_CalcPlayPosition
(
This
,
pstate
,
pplay
,
pwrite
,
lplay
,
splay
);
}
else
{
}
else
{
/* (unless the app isn't using GETCURRENTPOSITION2) */
/* (unless the app isn't using GETCURRENTPOSITION2) */
/* don't know exactly how this should be handled...
/* don't know exactly how this should be handled...
...
@@ -2081,6 +2112,7 @@ static HRESULT WINAPI IDirectSoundImpl_DuplicateSoundBuffer(
...
@@ -2081,6 +2112,7 @@ static HRESULT WINAPI IDirectSoundImpl_DuplicateSoundBuffer(
IDirectSoundBuffer_AddRef
(
pdsb
);
IDirectSoundBuffer_AddRef
(
pdsb
);
memcpy
(
*
ippdsb
,
ipdsb
,
sizeof
(
IDirectSoundBufferImpl
));
memcpy
(
*
ippdsb
,
ipdsb
,
sizeof
(
IDirectSoundBufferImpl
));
(
*
ippdsb
)
->
ref
=
1
;
(
*
ippdsb
)
->
ref
=
1
;
(
*
ippdsb
)
->
state
=
STATE_STOPPED
;
(
*
ippdsb
)
->
playpos
=
0
;
(
*
ippdsb
)
->
playpos
=
0
;
(
*
ippdsb
)
->
buf_mixpos
=
0
;
(
*
ippdsb
)
->
buf_mixpos
=
0
;
(
*
ippdsb
)
->
dsound
=
This
;
(
*
ippdsb
)
->
dsound
=
This
;
...
@@ -2710,7 +2742,7 @@ static DWORD DSOUND_MixOne(IDirectSoundBufferImpl *dsb, DWORD playpos, DWORD wri
...
@@ -2710,7 +2742,7 @@ static DWORD DSOUND_MixOne(IDirectSoundBufferImpl *dsb, DWORD playpos, DWORD wri
DWORD
len
,
slen
;
DWORD
len
,
slen
;
/* determine this buffer's write position */
/* determine this buffer's write position */
DWORD
buf_writepos
=
DSOUND_CalcPlayPosition
(
dsb
,
dsb
->
state
&
primarybuf
->
state
,
writepos
,
DWORD
buf_writepos
=
DSOUND_CalcPlayPosition
(
dsb
,
dsb
->
state
&
primarybuf
->
state
,
writepos
,
dsb
->
primary_mixpos
,
dsb
->
buf_mixpos
);
writepos
,
dsb
->
primary_mixpos
,
dsb
->
buf_mixpos
);
/* determine how much already-mixed data exist */
/* determine how much already-mixed data exist */
DWORD
buf_done
=
DWORD
buf_done
=
((
dsb
->
buf_mixpos
<
buf_writepos
)
?
dsb
->
buflen
:
0
)
+
((
dsb
->
buf_mixpos
<
buf_writepos
)
?
dsb
->
buflen
:
0
)
+
...
@@ -2734,9 +2766,13 @@ static DWORD DSOUND_MixOne(IDirectSoundBufferImpl *dsb, DWORD playpos, DWORD wri
...
@@ -2734,9 +2766,13 @@ static DWORD DSOUND_MixOne(IDirectSoundBufferImpl *dsb, DWORD playpos, DWORD wri
/* check whether CalcPlayPosition detected a mixing underrun */
/* check whether CalcPlayPosition detected a mixing underrun */
if
((
buf_done
==
0
)
&&
(
dsb
->
primary_mixpos
!=
writepos
))
{
if
((
buf_done
==
0
)
&&
(
dsb
->
primary_mixpos
!=
writepos
))
{
/* it did, try to recover */
/* it did, but did we have more to play? */
ERR
(
"underrun on sound buffer %p
\n
"
,
dsb
);
if
((
dsb
->
playflags
&
DSBPLAY_LOOPING
)
||
TRACE
(
"recovering from underrun: primary_mixpos=%ld
\n
"
,
writepos
);
(
dsb
->
buf_mixpos
<
dsb
->
buflen
))
{
/* yes, have to recover */
ERR
(
"underrun on sound buffer %p
\n
"
,
dsb
);
TRACE
(
"recovering from underrun: primary_mixpos=%ld
\n
"
,
writepos
);
}
dsb
->
primary_mixpos
=
writepos
;
dsb
->
primary_mixpos
=
writepos
;
primary_done
=
0
;
primary_done
=
0
;
}
}
...
@@ -2949,7 +2985,7 @@ static void CALLBACK DSOUND_timer(UINT timerID, UINT msg, DWORD dwUser, DWORD dw
...
@@ -2949,7 +2985,7 @@ static void CALLBACK DSOUND_timer(UINT timerID, UINT msg, DWORD dwUser, DWORD dw
TRACE
(
"reached end of mixed data (inq=%ld, maxq=%ld)
\n
"
,
inq
,
maxq
);
TRACE
(
"reached end of mixed data (inq=%ld, maxq=%ld)
\n
"
,
inq
,
maxq
);
inq
=
0
;
inq
=
0
;
/* stop the playback now, to allow buffers to refill */
/* stop the playback now, to allow buffers to refill */
IDsDriverBuffer_Stop
(
primarybuf
->
hw
buf
);
DSOUND_PrimaryStop
(
primary
buf
);
if
(
primarybuf
->
state
==
STATE_PLAYING
)
{
if
(
primarybuf
->
state
==
STATE_PLAYING
)
{
primarybuf
->
state
=
STATE_STARTING
;
primarybuf
->
state
=
STATE_STARTING
;
}
}
...
@@ -2988,14 +3024,14 @@ static void CALLBACK DSOUND_timer(UINT timerID, UINT msg, DWORD dwUser, DWORD dw
...
@@ -2988,14 +3024,14 @@ static void CALLBACK DSOUND_timer(UINT timerID, UINT msg, DWORD dwUser, DWORD dw
if
(
frag
)
{
if
(
frag
)
{
/* buffers have been filled, restart playback */
/* buffers have been filled, restart playback */
if
(
primarybuf
->
state
==
STATE_STARTING
)
{
if
(
primarybuf
->
state
==
STATE_STARTING
)
{
IDsDriverBuffer_Play
(
primarybuf
->
hwbuf
,
0
,
0
,
DSBPLAY_LOOPING
);
DSOUND_PrimaryPlay
(
primarybuf
);
primarybuf
->
state
=
STATE_PLAYING
;
primarybuf
->
state
=
STATE_PLAYING
;
TRACE
(
"starting playback
\n
"
);
TRACE
(
"starting playback
\n
"
);
}
}
else
if
(
primarybuf
->
state
==
STATE_STOPPED
)
{
else
if
(
primarybuf
->
state
==
STATE_STOPPED
)
{
/* the primarybuf is supposed to play if there's something to play
/* the primarybuf is supposed to play if there's something to play
* even if it is reported as stopped, so don't let this confuse you */
* even if it is reported as stopped, so don't let this confuse you */
IDsDriverBuffer_Play
(
primarybuf
->
hwbuf
,
0
,
0
,
DSBPLAY_LOOPING
);
DSOUND_PrimaryPlay
(
primarybuf
);
primarybuf
->
state
=
STATE_STOPPING
;
primarybuf
->
state
=
STATE_STOPPING
;
TRACE
(
"starting playback
\n
"
);
TRACE
(
"starting playback
\n
"
);
}
}
...
@@ -3004,11 +3040,11 @@ static void CALLBACK DSOUND_timer(UINT timerID, UINT msg, DWORD dwUser, DWORD dw
...
@@ -3004,11 +3040,11 @@ static void CALLBACK DSOUND_timer(UINT timerID, UINT msg, DWORD dwUser, DWORD dw
}
else
{
}
else
{
/* in the DSSCL_WRITEPRIMARY mode, the app is totally in charge... */
/* in the DSSCL_WRITEPRIMARY mode, the app is totally in charge... */
if
(
primarybuf
->
state
==
STATE_STARTING
)
{
if
(
primarybuf
->
state
==
STATE_STARTING
)
{
IDsDriverBuffer_Play
(
primarybuf
->
hwbuf
,
0
,
0
,
DSBPLAY_LOOPING
);
DSOUND_PrimaryPlay
(
primarybuf
);
primarybuf
->
state
=
STATE_PLAYING
;
primarybuf
->
state
=
STATE_PLAYING
;
}
}
else
if
(
primarybuf
->
state
==
STATE_STOPPING
)
{
else
if
(
primarybuf
->
state
==
STATE_STOPPING
)
{
IDsDriverBuffer_Stop
(
primarybuf
->
hw
buf
);
DSOUND_PrimaryStop
(
primary
buf
);
primarybuf
->
state
=
STATE_STOPPED
;
primarybuf
->
state
=
STATE_STOPPED
;
}
}
}
}
...
...
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