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
6e907563
Commit
6e907563
authored
Sep 04, 2008
by
Maarten Lankhorst
Committed by
Alexandre Julliard
Sep 04, 2008
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
winealsa.drv/dsound: Handle underruns better.
parent
09874bf7
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
30 additions
and
27 deletions
+30
-27
mixer.c
dlls/dsound/mixer.c
+26
-24
dsoutput.c
dlls/winealsa.drv/dsoutput.c
+4
-0
waveout.c
dlls/winealsa.drv/waveout.c
+0
-3
No files found.
dlls/dsound/mixer.c
View file @
6e907563
...
...
@@ -826,8 +826,32 @@ static void DSOUND_PerformMix(DirectSoundDevice *device)
mixplaypos
=
DSOUND_bufpos_to_mixpos
(
device
,
device
->
playpos
);
mixplaypos2
=
DSOUND_bufpos_to_mixpos
(
device
,
playpos
);
/* wipe out just-played sound data */
if
(
playpos
<
device
->
playpos
)
{
/* calc maximum prebuff */
prebuff_max
=
(
device
->
prebuf
*
device
->
fraglen
);
if
(
!
device
->
hwbuf
&&
playpos
+
prebuff_max
>=
device
->
helfrags
*
device
->
fraglen
)
prebuff_max
+=
device
->
buflen
-
device
->
helfrags
*
device
->
fraglen
;
/* check how close we are to an underrun. It occurs when the writepos overtakes the mixpos */
prebuff_left
=
DSOUND_BufPtrDiff
(
device
->
buflen
,
device
->
mixpos
,
playpos
);
writelead
=
DSOUND_BufPtrDiff
(
device
->
buflen
,
writepos
,
playpos
);
/* check for underrun. underrun occurs when the write position passes the mix position
* also wipe out just-played sound data */
if
((
prebuff_left
>
prebuff_max
)
||
(
device
->
state
==
STATE_STOPPED
)
||
(
device
->
state
==
STATE_STARTING
)){
if
(
device
->
state
==
STATE_STOPPING
||
device
->
state
==
STATE_PLAYING
)
WARN
(
"Probable buffer underrun
\n
"
);
else
TRACE
(
"Buffer starting or buffer underrun
\n
"
);
/* recover mixing for all buffers */
recover
=
TRUE
;
/* reset mix position to write position */
device
->
mixpos
=
writepos
;
ZeroMemory
(
device
->
mix_buffer
,
device
->
mix_buffer_len
);
ZeroMemory
(
device
->
buffer
,
device
->
buflen
);
}
else
if
(
playpos
<
device
->
playpos
)
{
buf1
=
device
->
buffer
+
device
->
playpos
;
buf2
=
device
->
buffer
;
size1
=
device
->
buflen
-
device
->
playpos
;
...
...
@@ -861,34 +885,12 @@ static void DSOUND_PerformMix(DirectSoundDevice *device)
}
device
->
playpos
=
playpos
;
/* calc maximum prebuff */
prebuff_max
=
(
device
->
prebuf
*
device
->
fraglen
);
if
(
!
device
->
hwbuf
&&
playpos
+
prebuff_max
>=
device
->
helfrags
*
device
->
fraglen
)
prebuff_max
+=
device
->
buflen
-
device
->
helfrags
*
device
->
fraglen
;
/* check how close we are to an underrun. It occurs when the writepos overtakes the mixpos */
prebuff_left
=
DSOUND_BufPtrDiff
(
device
->
buflen
,
device
->
mixpos
,
playpos
);
writelead
=
DSOUND_BufPtrDiff
(
device
->
buflen
,
writepos
,
playpos
);
/* find the maximum we can prebuffer from current write position */
maxq
=
(
writelead
<
prebuff_max
)
?
(
prebuff_max
-
writelead
)
:
0
;
TRACE
(
"prebuff_left = %d, prebuff_max = %dx%d=%d, writelead=%d
\n
"
,
prebuff_left
,
device
->
prebuf
,
device
->
fraglen
,
prebuff_max
,
writelead
);
/* check for underrun. underrun occurs when the write position passes the mix position */
if
((
prebuff_left
>
prebuff_max
)
||
(
device
->
state
==
STATE_STOPPED
)
||
(
device
->
state
==
STATE_STARTING
)){
if
(
device
->
state
==
STATE_STOPPING
||
device
->
state
==
STATE_PLAYING
)
WARN
(
"Probable buffer underrun
\n
"
);
else
TRACE
(
"Buffer starting or buffer underrun
\n
"
);
/* recover mixing for all buffers */
recover
=
TRUE
;
/* reset mix position to write position */
device
->
mixpos
=
writepos
;
}
/* Do we risk an 'underrun' if we don't advance pointer? */
if
(
writelead
/
device
->
fraglen
<=
ds_snd_queue_min
||
recover
)
mustlock
=
TRUE
;
...
...
dlls/winealsa.drv/dsoutput.c
View file @
6e907563
...
...
@@ -329,6 +329,8 @@ static HRESULT WINAPI IDsDriverBufferImpl_Lock(PIDSDRIVERBUFFER iface,
TRACE
(
"Hit mmap_pos, locking data!
\n
"
);
snd_pcm_mmap_begin
(
This
->
pcm
,
&
areas
,
&
This
->
mmap_pos
,
&
putin
);
}
else
WARN
(
"mmap_pos (%lu) != writepos (%lu) not locking data!
\n
"
,
This
->
mmap_pos
,
writepos
);
LeaveCriticalSection
(
&
This
->
pcm_crst
);
/* **** */
...
...
@@ -551,7 +553,9 @@ static HRESULT WINAPI IDsDriverBufferImpl_GetPosition(PIDSDRIVERBUFFER iface,
if
(
used
<
0
)
{
This
->
mmap_pos
+=
-
used
;
snd_pcm_forward
(
This
->
pcm
,
-
used
);
This
->
mmap_pos
%=
This
->
mmap_buflen_frames
;
used
=
0
;
}
...
...
dlls/winealsa.drv/waveout.c
View file @
6e907563
...
...
@@ -575,7 +575,6 @@ static DWORD wodOpen(WORD wDevID, LPWAVEOPENDESC lpDesc, DWORD dwFlags)
unsigned
int
period_time
=
20000
;
snd_pcm_uframes_t
buffer_size
;
snd_pcm_uframes_t
period_size
;
snd_pcm_uframes_t
boundary
;
int
flags
;
int
err
=
0
;
int
dir
=
0
;
...
...
@@ -758,13 +757,11 @@ static DWORD wodOpen(WORD wDevID, LPWAVEOPENDESC lpDesc, DWORD dwFlags)
err
=
snd_pcm_hw_params_get_buffer_size
(
hw_params
,
&
buffer_size
);
snd_pcm_sw_params_current
(
pcm
,
sw_params
);
snd_pcm_sw_params_get_boundary
(
sw_params
,
&
boundary
);
EXIT_ON_ERROR
(
snd_pcm_sw_params_set_start_threshold
(
pcm
,
sw_params
,
1
),
MMSYSERR_ERROR
,
"unable to set start threshold"
);
EXIT_ON_ERROR
(
snd_pcm_sw_params_set_silence_size
(
pcm
,
sw_params
,
0
),
MMSYSERR_ERROR
,
"unable to set silence size"
);
EXIT_ON_ERROR
(
snd_pcm_sw_params_set_avail_min
(
pcm
,
sw_params
,
period_size
),
MMSYSERR_ERROR
,
"unable to set avail min"
);
EXIT_ON_ERROR
(
snd_pcm_sw_params_set_silence_threshold
(
pcm
,
sw_params
,
0
),
MMSYSERR_ERROR
,
"unable to set silence threshold"
);
EXIT_ON_ERROR
(
snd_pcm_sw_params_set_stop_threshold
(
pcm
,
sw_params
,
boundary
),
MMSYSERR_ERROR
,
"unable to set stop threshold"
);
EXIT_ON_ERROR
(
snd_pcm_sw_params
(
pcm
,
sw_params
),
MMSYSERR_ERROR
,
"unable to set sw params for playback"
);
#undef EXIT_ON_ERROR
...
...
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