Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
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-cw
Commits
ff60a9a2
Commit
ff60a9a2
authored
May 11, 2002
by
Joris Beugnies
Committed by
Alexandre Julliard
May 11, 2002
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Make defines configurable at run-time.
parent
5d019367
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
166 additions
and
78 deletions
+166
-78
dsound_main.c
dlls/dsound/dsound_main.c
+166
-78
No files found.
dlls/dsound/dsound_main.c
View file @
ff60a9a2
...
...
@@ -51,12 +51,15 @@
#include "windef.h"
#include "winbase.h"
#include "winreg.h"
#include "winuser.h"
#include "wingdi.h"
#include "winuser.h"
#include "winerror.h"
#include "mmsystem.h"
#include "mmddk.h"
#include "wine/windef16.h"
#include "wine/winbase16.h"
#include "wine/debug.h"
#include "dsound.h"
#include "dsdriver.h"
...
...
@@ -93,6 +96,7 @@ typedef struct IDirectSoundCaptureImpl IDirectSoundCaptureImpl;
typedef
struct
IDirectSoundCaptureBufferImpl
IDirectSoundCaptureBufferImpl
;
typedef
struct
IKsPropertySetImpl
IKsPropertySetImpl
;
/*****************************************************************************
* IDirectSound implementation structure
*/
...
...
@@ -278,6 +282,98 @@ static HRESULT mmErr(UINT err)
}
}
static
int
ds_emuldriver
=
DS_EMULDRIVER
;
static
int
ds_hel_margin
=
DS_HEL_MARGIN
;
static
int
ds_hel_queue
=
DS_HEL_QUEUE
;
static
int
ds_snd_queue_max
=
DS_SND_QUEUE_MAX
;
static
int
ds_snd_queue_min
=
DS_SND_QUEUE_MIN
;
/*
* Get a config key from either the app-specific or the default config
*/
inline
static
DWORD
get_config_key
(
HKEY
defkey
,
HKEY
appkey
,
const
char
*
name
,
char
*
buffer
,
DWORD
size
)
{
if
(
appkey
&&
!
RegQueryValueExA
(
appkey
,
name
,
0
,
NULL
,
buffer
,
&
size
))
return
0
;
return
RegQueryValueExA
(
defkey
,
name
,
0
,
NULL
,
buffer
,
&
size
);
}
/*
* Setup the dsound options.
*/
inline
static
void
setup_dsound_options
(
void
)
{
char
buffer
[
MAX_PATH
+
1
];
HKEY
hkey
,
appkey
=
0
;
buffer
[
MAX_PATH
]
=
'\0'
;
if
(
RegCreateKeyExA
(
HKEY_LOCAL_MACHINE
,
"Software
\\
Wine
\\
Wine
\\
Config
\\
dsound"
,
0
,
NULL
,
REG_OPTION_VOLATILE
,
KEY_ALL_ACCESS
,
NULL
,
&
hkey
,
NULL
))
{
ERR
(
"Cannot create config registry key
\n
"
);
ExitProcess
(
1
);
}
if
(
GetModuleFileName16
(
GetCurrentTask
(),
buffer
,
MAX_PATH
)
||
GetModuleFileNameA
(
0
,
buffer
,
MAX_PATH
))
{
HKEY
tmpkey
;
if
(
!
RegOpenKeyA
(
HKEY_LOCAL_MACHINE
,
"Software
\\
Wine
\\
Wine
\\
Config
\\
AppDefaults"
,
&
tmpkey
))
{
char
appname
[
MAX_PATH
+
16
];
char
*
p
=
strrchr
(
buffer
,
'\\'
);
if
(
p
!=
NULL
)
{
appname
[
MAX_PATH
]
=
'\0'
;
strncpy
(
appname
,
p
+
1
,
MAX_PATH
);
strcat
(
appname
,
"
\\
dsound"
);
TRACE
(
"appname = [%s]
\n
"
,
appname
);
if
(
RegOpenKeyA
(
tmpkey
,
appname
,
&
appkey
))
appkey
=
0
;
RegCloseKey
(
tmpkey
);
}
}
}
/* get options */
if
(
!
get_config_key
(
hkey
,
appkey
,
"EmulDriver"
,
buffer
,
MAX_PATH
))
ds_emuldriver
=
atoi
(
buffer
);
if
(
!
get_config_key
(
hkey
,
appkey
,
"HELmargin"
,
buffer
,
MAX_PATH
))
ds_hel_margin
=
atoi
(
buffer
);
if
(
!
get_config_key
(
hkey
,
appkey
,
"HELqueue"
,
buffer
,
MAX_PATH
))
ds_hel_queue
=
atoi
(
buffer
);
if
(
!
get_config_key
(
hkey
,
appkey
,
"SndQueueMax"
,
buffer
,
MAX_PATH
))
ds_snd_queue_max
=
atoi
(
buffer
);
if
(
!
get_config_key
(
hkey
,
appkey
,
"SndQueueMin"
,
buffer
,
MAX_PATH
))
ds_snd_queue_min
=
atoi
(
buffer
);
if
(
appkey
)
RegCloseKey
(
appkey
);
RegCloseKey
(
hkey
);
if
(
ds_emuldriver
!=
DS_EMULDRIVER
)
WARN
(
"ds_emuldriver = %d (default=%d)
\n
"
,
ds_emuldriver
,
DS_EMULDRIVER
);
if
(
ds_hel_margin
!=
DS_HEL_MARGIN
)
WARN
(
"ds_hel_margin = %d (default=%d)
\n
"
,
ds_hel_margin
,
DS_HEL_MARGIN
);
if
(
ds_hel_queue
!=
DS_HEL_QUEUE
)
WARN
(
"ds_hel_queue = %d (default=%d)
\n
"
,
ds_hel_queue
,
DS_HEL_QUEUE
);
if
(
ds_snd_queue_max
!=
DS_SND_QUEUE_MAX
)
WARN
(
"ds_snd_queue_max = %d (default=%d)
\n
"
,
ds_snd_queue_max
,
DS_SND_QUEUE_MAX
);
if
(
ds_snd_queue_min
!=
DS_SND_QUEUE_MIN
)
WARN
(
"ds_snd_queue_min = %d (default=%d)
\n
"
,
ds_snd_queue_min
,
DS_SND_QUEUE_MIN
);
}
/***************************************************************************
* DirectSoundEnumerateA [DSOUND.2]
*
...
...
@@ -1508,7 +1604,7 @@ static DWORD DSOUND_CalcPlayPosition(IDirectSoundBufferImpl *This,
/* detect buffer underrun */
if
(
pwrite
<
pplay
)
pwrite
+=
primarybuf
->
buflen
;
/* wraparound */
pwrite
-=
pplay
;
if
(
pmix
>
(
DS_SND_QUEUE_MAX
*
primarybuf
->
dsound
->
fraglen
+
pwrite
+
primarybuf
->
writelead
))
{
if
(
pmix
>
(
ds_snd_queue_max
*
primarybuf
->
dsound
->
fraglen
+
pwrite
+
primarybuf
->
writelead
))
{
WARN
(
"detected an underrun: primary queue was %ld
\n
"
,
pmix
);
pmix
=
0
;
}
...
...
@@ -1555,7 +1651,7 @@ static HRESULT WINAPI IDirectSoundBufferImpl_GetCurrentPosition(
if
(
writepos
)
{
/* the writepos should only be used by apps with WRITEPRIMARY priority,
* in which case our software mixer is disabled anyway */
*
writepos
=
(
This
->
dsound
->
pwplay
+
DS_HEL_MARGIN
)
*
This
->
dsound
->
fraglen
;
*
writepos
=
(
This
->
dsound
->
pwplay
+
ds_hel_margin
)
*
This
->
dsound
->
fraglen
;
while
(
*
writepos
>=
This
->
buflen
)
*
writepos
-=
This
->
buflen
;
}
...
...
@@ -1593,7 +1689,7 @@ static HRESULT WINAPI IDirectSoundBufferImpl_GetCurrentPosition(
* behind write cursor, hmm... */
/* let's just do what might work for Half-Life */
DWORD
wp
;
wp
=
(
This
->
dsound
->
pwplay
+
DS_HEL_MARGIN
)
*
This
->
dsound
->
fraglen
;
wp
=
(
This
->
dsound
->
pwplay
+
ds_hel_margin
)
*
This
->
dsound
->
fraglen
;
while
(
wp
>=
primarybuf
->
buflen
)
wp
-=
primarybuf
->
buflen
;
*
playpos
=
DSOUND_CalcPlayPosition
(
This
,
pstate
,
wp
,
pwrite
,
lplay
,
splay
);
...
...
@@ -2602,75 +2698,66 @@ static inline BYTE cvtS16toU8(INT16 word)
}
/* We should be able to optimize these two inline functions */
/* so that we aren't doing 8->16->8 conversions when it is */
/* not necessary. But this is still a WIP. Optimize later. */
static
inline
void
get_fields
(
const
IDirectSoundBufferImpl
*
dsb
,
BYTE
*
buf
,
INT
*
fl
,
INT
*
fr
)
static
inline
void
cp_fields
(
const
IDirectSoundBufferImpl
*
dsb
,
BYTE
*
ibuf
,
BYTE
*
obuf
)
{
INT16
*
bufs
=
(
INT16
*
)
buf
;
/* TRACE("(%p)\n", buf); */
if
((
dsb
->
wfx
.
wBitsPerSample
==
8
)
&&
dsb
->
wfx
.
nChannels
==
2
)
{
*
fl
=
cvtU8toS16
(
*
buf
);
*
fr
=
cvtU8toS16
(
*
(
buf
+
1
));
return
;
}
if
((
dsb
->
wfx
.
wBitsPerSample
==
16
)
&&
dsb
->
wfx
.
nChannels
==
2
)
{
*
fl
=
*
bufs
;
*
fr
=
*
(
bufs
+
1
);
return
;
}
if
((
dsb
->
wfx
.
wBitsPerSample
==
8
)
&&
dsb
->
wfx
.
nChannels
==
1
)
{
*
fl
=
cvtU8toS16
(
*
buf
);
*
fr
=
*
fl
;
return
;
}
if
((
dsb
->
wfx
.
wBitsPerSample
==
16
)
&&
dsb
->
wfx
.
nChannels
==
1
)
{
*
fl
=
*
bufs
;
*
fr
=
*
bufs
;
return
;
}
FIXME
(
"get_fields found an unsupported configuration
\n
"
);
return
;
}
static
inline
void
set_fields
(
BYTE
*
buf
,
INT
fl
,
INT
fr
)
{
INT16
*
bufs
=
(
INT16
*
)
buf
;
if
((
primarybuf
->
wfx
.
wBitsPerSample
==
8
)
&&
(
primarybuf
->
wfx
.
nChannels
==
2
))
{
*
buf
=
cvtS16toU8
(
fl
);
*
(
buf
+
1
)
=
cvtS16toU8
(
fr
);
return
;
}
if
((
primarybuf
->
wfx
.
wBitsPerSample
==
16
)
&&
(
primarybuf
->
wfx
.
nChannels
==
2
))
{
*
bufs
=
fl
;
*
(
bufs
+
1
)
=
fr
;
return
;
}
if
((
primarybuf
->
wfx
.
wBitsPerSample
==
8
)
&&
(
primarybuf
->
wfx
.
nChannels
==
1
))
{
*
buf
=
cvtS16toU8
((
fl
+
fr
)
>>
1
);
return
;
INT
fl
=
0
,
fr
=
0
;
if
(
dsb
->
wfx
.
nChannels
==
2
)
{
if
(
dsb
->
wfx
.
wBitsPerSample
==
8
)
{
/* avoid needless 8->16->8 conversion */
if
(
(
primarybuf
->
wfx
.
wBitsPerSample
==
8
)
&&
(
primarybuf
->
wfx
.
nChannels
==
2
)
)
{
*
obuf
=*
ibuf
;
*
(
obuf
+
1
)
=*
(
ibuf
+
1
);
return
;
}
fl
=
cvtU8toS16
(
*
ibuf
);
fr
=
cvtU8toS16
(
*
(
ibuf
+
1
));
}
else
if
(
dsb
->
wfx
.
wBitsPerSample
==
16
)
{
fl
=
*
((
INT16
*
)
ibuf
);
fr
=
*
(((
INT16
*
)
ibuf
)
+
1
);
}
}
else
if
(
dsb
->
wfx
.
nChannels
==
1
)
{
if
(
dsb
->
wfx
.
wBitsPerSample
==
8
)
{
/* avoid needless 8->16->8 conversion */
if
(
(
primarybuf
->
wfx
.
wBitsPerSample
==
8
)
&&
(
primarybuf
->
wfx
.
nChannels
==
1
)
)
{
*
obuf
=*
ibuf
;
return
;
}
fl
=
cvtU8toS16
(
*
ibuf
);
fr
=
fl
;
}
else
if
(
dsb
->
wfx
.
wBitsPerSample
==
16
)
{
fl
=
*
((
INT16
*
)
ibuf
);
fr
=
fl
;
}
}
if
((
primarybuf
->
wfx
.
wBitsPerSample
==
16
)
&&
(
primarybuf
->
wfx
.
nChannels
==
1
))
{
*
bufs
=
(
fl
+
fr
)
>>
1
;
return
;
if
(
primarybuf
->
wfx
.
nChannels
==
2
)
{
if
(
primarybuf
->
wfx
.
wBitsPerSample
==
8
)
{
*
obuf
=
cvtS16toU8
(
fl
);
*
(
obuf
+
1
)
=
cvtS16toU8
(
fr
);
return
;
}
if
(
primarybuf
->
wfx
.
wBitsPerSample
==
16
)
{
*
((
INT16
*
)
obuf
)
=
fl
;
*
(((
INT16
*
)
obuf
)
+
1
)
=
fr
;
return
;
}
}
if
(
primarybuf
->
wfx
.
nChannels
==
1
)
{
fl
=
(
fl
+
fr
)
>>
1
;
if
(
primarybuf
->
wfx
.
wBitsPerSample
==
8
)
{
*
obuf
=
cvtS16toU8
(
fl
);
return
;
}
if
(
primarybuf
->
wfx
.
wBitsPerSample
==
16
)
{
*
((
INT16
*
)
obuf
)
=
fl
;
return
;
}
}
FIXME
(
"set_fields found an unsupported configuration
\n
"
);
return
;
}
/* Now with PerfectPitch (tm) technology */
static
INT
DSOUND_MixerNorm
(
IDirectSoundBufferImpl
*
dsb
,
BYTE
*
buf
,
INT
len
)
{
INT
i
,
size
,
ipos
,
ilen
,
fieldL
,
fieldR
;
INT
i
,
size
,
ipos
,
ilen
;
BYTE
*
ibp
,
*
obp
;
INT
iAdvance
=
dsb
->
wfx
.
nBlockAlign
;
INT
oAdvance
=
primarybuf
->
wfx
.
nBlockAlign
;
...
...
@@ -2700,10 +2787,9 @@ static INT DSOUND_MixerNorm(IDirectSoundBufferImpl *dsb, BYTE *buf, INT len)
dsb
->
freq
,
primarybuf
->
wfx
.
nSamplesPerSec
);
ilen
=
0
;
for
(
i
=
0
;
i
<
len
;
i
+=
oAdvance
)
{
get_fields
(
dsb
,
ibp
,
&
fieldL
,
&
fieldR
);
cp_fields
(
dsb
,
ibp
,
obp
);
ibp
+=
iAdvance
;
ilen
+=
iAdvance
;
set_fields
(
obp
,
fieldL
,
fieldR
);
obp
+=
oAdvance
;
if
(
ibp
>=
(
BYTE
*
)(
dsb
->
buffer
+
dsb
->
buflen
))
ibp
=
dsb
->
buffer
;
/* wrap */
...
...
@@ -2719,17 +2805,15 @@ static INT DSOUND_MixerNorm(IDirectSoundBufferImpl *dsb, BYTE *buf, INT len)
/* Patent enhancements (c) 2000 Ove Kven,
* TransGaming Technologies Inc. */
FIXME
(
"(%p) Adjusting frequency: %ld -> %ld (need optimization)
\n
"
,
/*
FIXME("(%p) Adjusting frequency: %ld -> %ld (need optimization)\n",
dsb, dsb->freq, primarybuf->wfx.nSamplesPerSec);
*/
size
=
len
/
oAdvance
;
ilen
=
0
;
ipos
=
dsb
->
buf_mixpos
;
for
(
i
=
0
;
i
<
size
;
i
++
)
{
get_fields
(
dsb
,
(
dsb
->
buffer
+
ipos
),
&
fieldL
,
&
fieldR
);
set_fields
(
obp
,
fieldL
,
fieldR
);
cp_fields
(
dsb
,
(
dsb
->
buffer
+
ipos
),
obp
);
obp
+=
oAdvance
;
dsb
->
freqAcc
+=
dsb
->
freqAdjust
;
if
(
dsb
->
freqAcc
>=
(
1
<<
DSOUND_FREQSHIFT
))
{
ULONG
adv
=
(
dsb
->
freqAcc
>>
DSOUND_FREQSHIFT
)
*
iAdvance
;
...
...
@@ -3260,16 +3344,16 @@ static void DSOUND_CheckReset(IDirectSoundImpl *dsound, DWORD writepos)
DSOUND_MixReset
(
writepos
);
primarybuf
->
need_remix
=
FALSE
;
/* maximize Half-Life performance */
dsound
->
prebuf
=
DS_SND_QUEUE_MIN
;
dsound
->
prebuf
=
ds_snd_queue_min
;
}
else
{
/* if (dsound->prebuf <
DS_SND_QUEUE_MAX
) dsound->prebuf++; */
/* if (dsound->prebuf <
ds_snd_queue_max
) dsound->prebuf++; */
}
TRACE
(
"premix adjust: %d
\n
"
,
dsound
->
prebuf
);
}
static
void
DSOUND_WaveQueue
(
IDirectSoundImpl
*
dsound
,
DWORD
mixq
)
{
if
(
mixq
+
dsound
->
pwqueue
>
DS_HEL_QUEUE
)
mixq
=
DS_HEL_QUEUE
-
dsound
->
pwqueue
;
if
(
mixq
+
dsound
->
pwqueue
>
ds_hel_queue
)
mixq
=
ds_hel_queue
-
dsound
->
pwqueue
;
TRACE
(
"queueing %ld buffers, starting at %d
\n
"
,
mixq
,
dsound
->
pwwrite
);
for
(;
mixq
;
mixq
--
)
{
waveOutWrite
(
dsound
->
hwo
,
dsound
->
pwave
[
dsound
->
pwwrite
],
sizeof
(
WAVEHDR
));
...
...
@@ -3325,7 +3409,7 @@ static void DSOUND_PerformMix(void)
playpos
=
dsound
->
pwplay
*
dsound
->
fraglen
;
writepos
=
playpos
;
if
(
!
paused
)
{
writepos
+=
DS_HEL_MARGIN
*
dsound
->
fraglen
;
writepos
+=
ds_hel_margin
*
dsound
->
fraglen
;
while
(
writepos
>=
primarybuf
->
buflen
)
writepos
-=
primarybuf
->
buflen
;
}
...
...
@@ -3515,7 +3599,7 @@ HRESULT WINAPI DirectSoundCreate(REFGUID lpGUID,LPDIRECTSOUND *ppDS,IUnknown *pU
PIDSDRIVER
drv
=
NULL
;
WAVEOUTCAPSA
wcaps
;
unsigned
wod
,
wodn
;
HRESULT
err
=
DS_OK
;
HRESULT
err
=
DS_OK
;
if
(
lpGUID
)
TRACE
(
"(%p,%p,%p)
\n
"
,
lpGUID
,
ippDS
,
pUnkOuter
);
...
...
@@ -3531,6 +3615,9 @@ HRESULT WINAPI DirectSoundCreate(REFGUID lpGUID,LPDIRECTSOUND *ppDS,IUnknown *pU
return
DS_OK
;
}
/* get dsound configuration */
setup_dsound_options
();
/* Enumerate WINMM audio devices and find the one we want */
wodn
=
waveOutGetNumDevs
();
if
(
!
wodn
)
return
DSERR_NODRIVER
;
...
...
@@ -3559,7 +3646,7 @@ HRESULT WINAPI DirectSoundCreate(REFGUID lpGUID,LPDIRECTSOUND *ppDS,IUnknown *pU
(
*
ippDS
)
->
primary
=
NULL
;
(
*
ippDS
)
->
listener
=
NULL
;
(
*
ippDS
)
->
prebuf
=
DS_SND_QUEUE_MAX
;
(
*
ippDS
)
->
prebuf
=
ds_snd_queue_max
;
/* Get driver description */
if
(
drv
)
{
...
...
@@ -3619,10 +3706,11 @@ HRESULT WINAPI DirectSoundCreate(REFGUID lpGUID,LPDIRECTSOUND *ppDS,IUnknown *pU
}
else
{
unsigned
c
;
/* FIXME: look at wcaps */
(
*
ippDS
)
->
drvcaps
.
dwFlags
=
DSCAPS_PRIMARY16BIT
|
DSCAPS_PRIMARYSTEREO
;
if
(
DS_EMULDRIVER
)
if
(
ds_emuldriver
)
(
*
ippDS
)
->
drvcaps
.
dwFlags
|=
DSCAPS_EMULDRIVER
;
/* Allocate memory for HEL buffer headers */
...
...
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