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
f5abeb84
Commit
f5abeb84
authored
Dec 19, 2012
by
Maarten Lankhorst
Committed by
Alexandre Julliard
Dec 27, 2012
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
dsound: Use a thread instead of a timer for greater precision.
parent
8dc7a72a
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
62 additions
and
32 deletions
+62
-32
dsound.c
dlls/dsound/dsound.c
+11
-10
dsound_private.h
dlls/dsound/dsound_private.h
+4
-3
mixer.c
dlls/dsound/mixer.c
+23
-16
primary.c
dlls/dsound/primary.c
+24
-3
No files found.
dlls/dsound/dsound.c
View file @
f5abeb84
...
...
@@ -670,14 +670,13 @@ ULONG DirectSoundDevice_Release(DirectSoundDevice * device)
TRACE
(
"(%p) ref was %u
\n
"
,
device
,
ref
+
1
);
if
(
!
ref
)
{
int
i
;
timeKillEvent
(
device
->
timerID
);
timeEndPeriod
(
DS_TIME_RES
);
/* The kill event should have allowed the timer process to expire
* but try to grab the lock just in case. Can't hold lock because
* secondarybuffer_destroy also grabs the lock */
RtlAcquireResourceShared
(
&
(
device
->
buffer_list_lock
),
TRUE
);
RtlReleaseResource
(
&
(
device
->
buffer_list_lock
));
SetEvent
(
device
->
sleepev
);
if
(
device
->
thread
)
{
WaitForSingleObject
(
device
->
thread
,
INFINITE
);
CloseHandle
(
device
->
thread
);
}
CloseHandle
(
device
->
sleepev
);
EnterCriticalSection
(
&
DSOUND_renderers_lock
);
list_remove
(
&
device
->
entry
);
...
...
@@ -813,6 +812,7 @@ HRESULT DirectSoundDevice_Initialize(DirectSoundDevice ** ppDevice, LPCGUID lpcG
device
->
mmdevice
=
mmdevice
;
device
->
guid
=
devGUID
;
device
->
sleepev
=
CreateEventW
(
0
,
0
,
0
,
0
);
hr
=
DSOUND_ReopenDevice
(
device
,
FALSE
);
if
(
FAILED
(
hr
))
...
...
@@ -869,9 +869,10 @@ HRESULT DirectSoundDevice_Initialize(DirectSoundDevice ** ppDevice, LPCGUID lpcG
ZeroMemory
(
&
device
->
volpan
,
sizeof
(
device
->
volpan
));
hr
=
DSOUND_PrimaryCreate
(
device
);
if
(
hr
==
DS_OK
)
device
->
timerID
=
DSOUND_create_timer
(
DSOUND_timer
,
(
DWORD_PTR
)
device
);
else
if
(
hr
==
DS_OK
)
{
device
->
thread
=
CreateThread
(
0
,
0
,
DSOUND_mixthread
,
device
,
0
,
0
);
SetThreadPriority
(
device
->
thread
,
THREAD_PRIORITY_TIME_CRITICAL
);
}
else
WARN
(
"DSOUND_PrimaryCreate failed: %08x
\n
"
,
hr
);
*
ppDevice
=
device
;
...
...
dlls/dsound/dsound_private.h
View file @
f5abeb84
...
...
@@ -68,9 +68,9 @@ struct DirectSoundDevice
GUID
guid
;
DSCAPS
drvcaps
;
DWORD
priolevel
;
DWORD
priolevel
,
sleeptime
;
PWAVEFORMATEX
pwfx
,
primary_pwfx
;
UINT
timerID
,
playing_offs_bytes
,
in_mmdev_bytes
,
prebuf
;
UINT
playing_offs_bytes
,
in_mmdev_bytes
,
prebuf
;
DWORD
fraglen
;
LPBYTE
buffer
;
DWORD
writelead
,
buflen
,
state
,
playpos
,
mixpos
;
...
...
@@ -97,6 +97,7 @@ struct DirectSoundDevice
IAudioStreamVolume
*
volume
;
IAudioRenderClient
*
render
;
HANDLE
sleepev
,
thread
;
struct
list
entry
;
};
...
...
@@ -226,7 +227,7 @@ void DSOUND_AmpFactorToVolPan(PDSVOLUMEPAN volpan) DECLSPEC_HIDDEN;
void
DSOUND_RecalcFormat
(
IDirectSoundBufferImpl
*
dsb
)
DECLSPEC_HIDDEN
;
DWORD
DSOUND_secpos_to_bufpos
(
const
IDirectSoundBufferImpl
*
dsb
,
DWORD
secpos
,
DWORD
secmixpos
,
float
*
overshot
)
DECLSPEC_HIDDEN
;
void
CALLBACK
DSOUND_timer
(
UINT
timerID
,
UINT
msg
,
DWORD_PTR
dwUser
,
DWORD_PTR
dw1
,
DWORD_PTR
dw2
)
DECLSPEC_HIDDEN
;
DWORD
CALLBACK
DSOUND_mixthread
(
void
*
ptr
)
DECLSPEC_HIDDEN
;
/* sound3d.c */
...
...
dlls/dsound/mixer.c
View file @
f5abeb84
...
...
@@ -820,7 +820,7 @@ static void DSOUND_PerformMix(DirectSoundDevice *device)
DSOUND_PrimaryStop
(
device
);
}
}
else
{
}
else
if
(
device
->
state
!=
STATE_STOPPED
)
{
DSOUND_WaveQueue
(
device
,
TRUE
);
...
...
@@ -843,22 +843,29 @@ static void DSOUND_PerformMix(DirectSoundDevice *device)
/* **** */
}
void
CALLBACK
DSOUND_timer
(
UINT
timerID
,
UINT
msg
,
DWORD_PTR
dwUser
,
DWORD_PTR
dw1
,
DWORD_PTR
dw2
)
DWORD
CALLBACK
DSOUND_mixthread
(
void
*
p
)
{
DirectSoundDevice
*
device
=
(
DirectSoundDevice
*
)
dwUser
;
DWORD
start_time
=
GetTickCount
();
DWORD
end_time
;
TRACE
(
"(%d,%d,0x%lx,0x%lx,0x%lx)
\n
"
,
timerID
,
msg
,
dwUser
,
dw1
,
dw2
);
TRACE
(
"entering at %d
\n
"
,
start_time
);
RtlAcquireResourceShared
(
&
(
device
->
buffer_list_lock
),
TRUE
);
if
(
device
->
ref
)
DSOUND_PerformMix
(
device
);
DirectSoundDevice
*
dev
=
p
;
TRACE
(
"(%p)
\n
"
,
dev
);
RtlReleaseResource
(
&
(
device
->
buffer_list_lock
));
while
(
dev
->
ref
)
{
DWORD
ret
;
end_time
=
GetTickCount
();
TRACE
(
"completed processing at %d, duration = %d
\n
"
,
end_time
,
end_time
-
start_time
);
/*
* Some audio drivers are retarded and won't fire after being
* stopped, add a timeout to handle this.
*/
ret
=
WaitForSingleObject
(
dev
->
sleepev
,
dev
->
sleeptime
);
if
(
ret
==
WAIT_FAILED
)
WARN
(
"wait returned error %u %08x!
\n
"
,
GetLastError
(),
GetLastError
());
else
if
(
ret
!=
WAIT_OBJECT_0
)
WARN
(
"wait returned %08x!
\n
"
,
ret
);
if
(
!
dev
->
ref
)
break
;
RtlAcquireResourceShared
(
&
(
dev
->
buffer_list_lock
),
TRUE
);
DSOUND_PerformMix
(
dev
);
RtlReleaseResource
(
&
(
dev
->
buffer_list_lock
));
}
return
0
;
}
dlls/dsound/primary.c
View file @
f5abeb84
...
...
@@ -152,6 +152,8 @@ HRESULT DSOUND_ReopenDevice(DirectSoundDevice *device, BOOL forcewave)
REFERENCE_TIME
prebuf_rt
;
WAVEFORMATEX
*
wfx
=
NULL
;
HRESULT
hres
;
REFERENCE_TIME
period
;
DWORD
period_ms
;
TRACE
(
"(%p, %d)
\n
"
,
device
,
forcewave
);
...
...
@@ -192,14 +194,15 @@ HRESULT DSOUND_ReopenDevice(DirectSoundDevice *device, BOOL forcewave)
prebuf_rt
=
(
10000000
*
(
UINT64
)
prebuf_frames
)
/
device
->
pwfx
->
nSamplesPerSec
;
hres
=
IAudioClient_Initialize
(
device
->
client
,
AUDCLNT_SHAREMODE_SHARED
,
AUDCLNT_STREAMFLAGS_NOPERSIST
,
prebuf_rt
,
0
,
device
->
pwfx
,
NULL
);
AUDCLNT_SHAREMODE_SHARED
,
AUDCLNT_STREAMFLAGS_NOPERSIST
|
AUDCLNT_STREAMFLAGS_EVENTCALLBACK
,
prebuf_rt
,
0
,
device
->
pwfx
,
NULL
);
if
(
FAILED
(
hres
)){
IAudioClient_Release
(
device
->
client
);
device
->
client
=
NULL
;
WARN
(
"Initialize failed: %08x
\n
"
,
hres
);
return
hres
;
}
IAudioClient_SetEventHandle
(
device
->
client
,
device
->
sleepev
);
hres
=
IAudioClient_GetService
(
device
->
client
,
&
IID_IAudioRenderClient
,
(
void
**
)
&
device
->
render
);
...
...
@@ -234,6 +237,24 @@ HRESULT DSOUND_ReopenDevice(DirectSoundDevice *device, BOOL forcewave)
return
hres
;
}
/* Now kick off the timer so the event fires periodically */
hres
=
IAudioClient_Start
(
device
->
client
);
if
(
FAILED
(
hres
))
WARN
(
"starting failed with %08x
\n
"
,
hres
);
hres
=
IAudioClient_GetStreamLatency
(
device
->
client
,
&
period
);
if
(
FAILED
(
hres
))
{
WARN
(
"GetStreamLatency failed with %08x
\n
"
,
hres
);
period_ms
=
10
;
}
else
period_ms
=
(
period
+
9999
)
/
10000
;
TRACE
(
"period %u ms fraglen %u prebuf %u
\n
"
,
period_ms
,
device
->
fraglen
,
device
->
prebuf
);
if
(
period_ms
<
3
)
device
->
sleeptime
=
5
;
else
device
->
sleeptime
=
period_ms
*
5
/
2
;
return
S_OK
;
}
...
...
@@ -379,7 +400,7 @@ HRESULT DSOUND_PrimaryPlay(DirectSoundDevice *device)
TRACE
(
"(%p)
\n
"
,
device
);
hr
=
IAudioClient_Start
(
device
->
client
);
if
(
FAILED
(
hr
)){
if
(
FAILED
(
hr
)
&&
hr
!=
AUDCLNT_E_NOT_STOPPED
){
WARN
(
"Start failed: %08x
\n
"
,
hr
);
return
hr
;
}
...
...
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