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
4d1129f7
Commit
4d1129f7
authored
Nov 07, 2007
by
Maarten Lankhorst
Committed by
Alexandre Julliard
Nov 09, 2007
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
dsound: Use a 2 stage mixing/normalization for sound.
parent
a938f693
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
69 additions
and
75 deletions
+69
-75
dsound.c
dlls/dsound/dsound.c
+3
-2
dsound_private.h
dlls/dsound/dsound_private.h
+6
-3
mixer.c
dlls/dsound/mixer.c
+40
-69
primary.c
dlls/dsound/primary.c
+20
-1
No files found.
dlls/dsound/dsound.c
View file @
4d1129f7
...
...
@@ -1275,8 +1275,9 @@ ULONG DirectSoundDevice_Release(DirectSoundDevice * device)
DSOUND_renderer
[
device
->
drvdesc
.
dnDevNode
]
=
NULL
;
HeapFree
(
GetProcessHeap
(),
0
,
device
->
tmp_buffer
);
HeapFree
(
GetProcessHeap
(),
0
,
device
->
buffer
);
HeapFree
(
GetProcessHeap
(),
0
,
device
->
tmp_buffer
);
HeapFree
(
GetProcessHeap
(),
0
,
device
->
mix_buffer
);
HeapFree
(
GetProcessHeap
(),
0
,
device
->
buffer
);
RtlDeleteResource
(
&
device
->
buffer_list_lock
);
device
->
mixlock
.
DebugInfo
->
Spare
[
0
]
=
0
;
DeleteCriticalSection
(
&
device
->
mixlock
);
...
...
dlls/dsound/dsound_private.h
View file @
4d1129f7
...
...
@@ -104,8 +104,11 @@ struct DirectSoundDevice
PrimaryBufferImpl
*
primary
;
DSBUFFERDESC
dsbd
;
DWORD
speaker_config
;
LPBYTE
tmp_buffer
;
DWORD
tmp_buffer_len
;
LPBYTE
tmp_buffer
,
mix_buffer
;
DWORD
tmp_buffer_len
,
mix_buffer_len
;
mixfunc
mixfunction
;
normfunc
normfunction
;
/* DirectSound3DListener fields */
IDirectSound3DListenerImpl
*
listener
;
...
...
@@ -441,7 +444,7 @@ HRESULT DSOUND_ReopenDevice(DirectSoundDevice *device, BOOL forcewave);
HRESULT
DSOUND_FullDuplexCreate
(
REFIID
riid
,
LPDIRECTSOUNDFULLDUPLEX
*
ppDSFD
);
/* mixer.c */
DWORD
DSOUND_bufpos_to_mixpos
(
const
DirectSoundDevice
*
device
,
DWORD
pos
);
void
DSOUND_CheckEvent
(
const
IDirectSoundBufferImpl
*
dsb
,
DWORD
playpos
,
int
len
);
void
DSOUND_RecalcVolPan
(
PDSVOLUMEPAN
volpan
);
void
DSOUND_AmpFactorToVolPan
(
PDSVOLUMEPAN
volpan
);
...
...
dlls/dsound/mixer.c
View file @
4d1129f7
...
...
@@ -90,6 +90,19 @@ void DSOUND_AmpFactorToVolPan(PDSVOLUMEPAN volpan)
TRACE
(
"Vol=%d Pan=%d
\n
"
,
volpan
->
lVolume
,
volpan
->
lPan
);
}
/** Convert a primary buffer position to a pointer position for device->mix_buffer
* device: DirectSoundDevice for which to calculate
* pos: Primary buffer position to converts
* Returns: Offset for mix_buffer
*/
DWORD
DSOUND_bufpos_to_mixpos
(
const
DirectSoundDevice
*
device
,
DWORD
pos
)
{
DWORD
ret
=
pos
*
32
/
device
->
pwfx
->
wBitsPerSample
;
if
(
device
->
pwfx
->
wBitsPerSample
==
32
)
ret
*=
2
;
return
ret
;
}
/* NOTE: Not all secpos have to always be mapped to a bufpos, other way around is always the case
* DWORD64 is used here because a single DWORD wouldn't be big enough to fit the freqAcc for big buffers
*/
...
...
@@ -466,9 +479,9 @@ static LPBYTE DSOUND_MixerVol(const IDirectSoundBufferImpl *dsb, DWORD writepos,
*/
static
DWORD
DSOUND_MixInBuffer
(
IDirectSoundBufferImpl
*
dsb
,
DWORD
writepos
,
DWORD
fraglen
)
{
INT
i
,
len
=
fraglen
,
field
,
todo
,
ilen
;
INT
len
=
fraglen
,
ilen
;
BYTE
*
ibuf
=
(
dsb
->
tmp_buffer
?
dsb
->
tmp_buffer
:
dsb
->
buffer
->
memory
)
+
dsb
->
buf_mixpos
,
*
volbuf
;
DWORD
oldpos
;
DWORD
oldpos
,
mixbufpos
;
TRACE
(
"buf_mixpos=%d/%d sec_mixpos=%d/%d
\n
"
,
dsb
->
buf_mixpos
,
dsb
->
tmp_buffer_len
,
dsb
->
sec_mixpos
,
dsb
->
buflen
);
TRACE
(
"(%p,%d,%d)
\n
"
,
dsb
,
writepos
,
fraglen
);
...
...
@@ -486,82 +499,26 @@ static DWORD DSOUND_MixInBuffer(IDirectSoundBufferImpl *dsb, DWORD writepos, DWO
if
(
volbuf
)
ibuf
=
volbuf
;
mixbufpos
=
DSOUND_bufpos_to_mixpos
(
dsb
->
device
,
writepos
);
/* Now mix the temporary buffer into the devices main buffer */
if
(
dsb
->
device
->
pwfx
->
wBitsPerSample
==
8
)
{
BYTE
*
obuf
=
dsb
->
device
->
buffer
+
writepos
;
if
((
writepos
+
len
)
<=
dsb
->
device
->
buflen
)
todo
=
len
;
else
todo
=
dsb
->
device
->
buflen
-
writepos
;
for
(
i
=
0
;
i
<
todo
;
i
++
)
{
/* 8-bit WAV is unsigned */
field
=
(
*
ibuf
++
-
128
);
field
+=
(
*
obuf
-
128
);
if
(
field
>
127
)
field
=
127
;
else
if
(
field
<
-
128
)
field
=
-
128
;
*
obuf
++
=
field
+
128
;
}
if
(
todo
<
len
)
{
todo
=
len
-
todo
;
obuf
=
dsb
->
device
->
buffer
;
for
(
i
=
0
;
i
<
todo
;
i
++
)
{
/* 8-bit WAV is unsigned */
field
=
(
*
ibuf
++
-
128
);
field
+=
(
*
obuf
-
128
);
if
(
field
>
127
)
field
=
127
;
else
if
(
field
<
-
128
)
field
=
-
128
;
*
obuf
++
=
field
+
128
;
}
}
}
else
{
INT16
*
ibufs
,
*
obufs
;
ibufs
=
(
INT16
*
)
ibuf
;
obufs
=
(
INT16
*
)(
dsb
->
device
->
buffer
+
writepos
);
if
((
writepos
+
len
)
<=
dsb
->
device
->
buflen
)
todo
=
len
/
2
;
else
todo
=
(
dsb
->
device
->
buflen
-
writepos
)
/
2
;
for
(
i
=
0
;
i
<
todo
;
i
++
)
{
/* 16-bit WAV is signed */
field
=
*
ibufs
++
;
field
+=
*
obufs
;
if
(
field
>
32767
)
field
=
32767
;
else
if
(
field
<
-
32768
)
field
=
-
32768
;
*
obufs
++
=
field
;
}
if
(
todo
<
(
len
/
2
))
{
todo
=
(
len
/
2
)
-
todo
;
obufs
=
(
INT16
*
)
dsb
->
device
->
buffer
;
for
(
i
=
0
;
i
<
todo
;
i
++
)
{
/* 16-bit WAV is signed */
field
=
*
ibufs
++
;
field
+=
*
obufs
;
if
(
field
>
32767
)
field
=
32767
;
else
if
(
field
<
-
32768
)
field
=
-
32768
;
*
obufs
++
=
field
;
}
}
if
((
writepos
+
len
)
<=
dsb
->
device
->
buflen
)
dsb
->
device
->
mixfunction
(
ibuf
,
dsb
->
device
->
mix_buffer
+
mixbufpos
,
len
);
else
{
DWORD
todo
=
dsb
->
device
->
buflen
-
writepos
;
dsb
->
device
->
mixfunction
(
ibuf
,
dsb
->
device
->
mix_buffer
+
mixbufpos
,
todo
);
dsb
->
device
->
mixfunction
(
ibuf
+
todo
,
dsb
->
device
->
mix_buffer
,
len
-
todo
);
}
oldpos
=
dsb
->
sec_mixpos
;
dsb
->
buf_mixpos
+=
len
;
if
(
dsb
->
buf_mixpos
>=
dsb
->
tmp_buffer_len
)
{
if
(
dsb
->
buf_mixpos
>
dsb
->
tmp_buffer_len
)
ERR
(
"Mixpos (%u) past buflen (%u), capping...
\n
"
,
dsb
->
buf_mixpos
,
dsb
->
tmp_buffer_len
);
if
(
dsb
->
playflags
&
DSBPLAY_LOOPING
)
{
dsb
->
buf_mixpos
-=
dsb
->
tmp_buffer_len
;
}
else
if
(
dsb
->
buf_mixpos
>=
dsb
->
tmp_buffer_len
)
{
if
(
dsb
->
buf_mixpos
>
dsb
->
tmp_buffer_len
)
ERR
(
"Mixpos (%u) past buflen (%u), capping...
\n
"
,
dsb
->
buf_mixpos
,
dsb
->
tmp_buffer_len
);
dsb
->
buf_mixpos
=
dsb
->
sec_mixpos
=
0
;
dsb
->
state
=
STATE_STOPPED
;
}
...
...
@@ -817,7 +774,7 @@ static void DSOUND_PerformMix(DirectSoundDevice *device)
if
(
device
->
priolevel
!=
DSSCL_WRITEPRIMARY
)
{
BOOL
recover
=
FALSE
,
all_stopped
=
FALSE
;
DWORD
playpos
,
writepos
,
writelead
,
maxq
,
frag
,
prebuff_max
,
prebuff_left
,
size1
,
size2
;
DWORD
playpos
,
writepos
,
writelead
,
maxq
,
frag
,
prebuff_max
,
prebuff_left
,
size1
,
size2
,
mixplaypos
,
mixplaypos2
;
LPVOID
buf1
,
buf2
;
BOOL
lock
=
(
device
->
hwbuf
&&
!
(
device
->
drvdesc
.
dwFlags
&
DSDDESC_DONTNEEDPRIMARYLOCK
));
BOOL
mustlock
=
FALSE
;
...
...
@@ -836,12 +793,16 @@ static void DSOUND_PerformMix(DirectSoundDevice *device)
playpos
,
writepos
,
device
->
playpos
,
device
->
mixpos
,
device
->
buflen
);
assert
(
device
->
playpos
<
device
->
buflen
);
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
)
{
buf1
=
device
->
buffer
+
device
->
playpos
;
buf2
=
device
->
buffer
;
size1
=
device
->
buflen
-
device
->
playpos
;
size2
=
playpos
;
FillMemory
(
device
->
mix_buffer
+
mixplaypos
,
device
->
mix_buffer_len
-
mixplaypos
,
0
);
FillMemory
(
device
->
mix_buffer
,
mixplaypos2
,
0
);
if
(
lock
)
IDsDriverBuffer_Lock
(
device
->
hwbuf
,
&
buf1
,
&
size1
,
&
buf2
,
&
size2
,
device
->
playpos
,
size1
+
size2
,
0
);
FillMemory
(
buf1
,
size1
,
nfiller
);
...
...
@@ -855,6 +816,7 @@ static void DSOUND_PerformMix(DirectSoundDevice *device)
buf2
=
NULL
;
size1
=
playpos
-
device
->
playpos
;
size2
=
0
;
FillMemory
(
device
->
mix_buffer
+
mixplaypos
,
mixplaypos2
-
mixplaypos
,
0
);
if
(
lock
)
IDsDriverBuffer_Lock
(
device
->
hwbuf
,
&
buf1
,
&
size1
,
&
buf2
,
&
size2
,
device
->
playpos
,
size1
+
size2
,
0
);
FillMemory
(
buf1
,
size1
,
nfiller
);
...
...
@@ -906,6 +868,15 @@ static void DSOUND_PerformMix(DirectSoundDevice *device)
/* do the mixing */
frag
=
DSOUND_MixToPrimary
(
device
,
writepos
,
maxq
,
mustlock
,
recover
,
&
all_stopped
);
if
(
frag
+
writepos
>
device
->
buflen
)
{
DWORD
todo
=
device
->
buflen
-
writepos
;
device
->
normfunction
(
device
->
mix_buffer
+
DSOUND_bufpos_to_mixpos
(
device
,
writepos
),
device
->
buffer
+
writepos
,
todo
);
device
->
normfunction
(
device
->
mix_buffer
,
device
->
buffer
,
frag
-
todo
);
}
else
device
->
normfunction
(
device
->
mix_buffer
+
DSOUND_bufpos_to_mixpos
(
device
,
writepos
),
device
->
buffer
+
writepos
,
frag
);
/* update the mix position, taking wrap-around into acount */
device
->
mixpos
=
writepos
+
frag
;
device
->
mixpos
%=
device
->
buflen
;
...
...
dlls/dsound/primary.c
View file @
4d1129f7
...
...
@@ -188,6 +188,16 @@ static HRESULT DSOUND_PrimaryOpen(DirectSoundDevice *device)
device
->
prebuf
=
device
->
helfrags
;
}
device
->
mix_buffer_len
=
DSOUND_bufpos_to_mixpos
(
device
,
device
->
buflen
);
device
->
mix_buffer
=
HeapAlloc
(
GetProcessHeap
(),
0
,
device
->
mix_buffer_len
);
if
(
!
device
->
mix_buffer
)
{
if
(
device
->
hwbuf
)
IDsDriverBuffer_Release
(
device
->
hwbuf
);
device
->
hwbuf
=
NULL
;
return
DSERR_OUTOFMEMORY
;
}
if
(
device
->
state
==
STATE_PLAYING
)
device
->
state
=
STATE_STARTING
;
else
if
(
device
->
state
==
STATE_STOPPING
)
device
->
state
=
STATE_STOPPED
;
...
...
@@ -256,7 +266,10 @@ static HRESULT DSOUND_PrimaryOpen(DirectSoundDevice *device)
TRACE
(
"fraglen=%d, overshot=%d
\n
"
,
device
->
fraglen
,
overshot
);
}
device
->
mixfunction
=
mixfunctions
[
device
->
pwfx
->
wBitsPerSample
/
8
-
1
];
device
->
normfunction
=
normfunctions
[
device
->
pwfx
->
wBitsPerSample
/
8
-
1
];
FillMemory
(
device
->
buffer
,
device
->
buflen
,
(
device
->
pwfx
->
wBitsPerSample
==
8
)
?
128
:
0
);
FillMemory
(
device
->
mix_buffer
,
device
->
mix_buffer_len
,
0
);
device
->
pwplay
=
device
->
pwqueue
=
device
->
playpos
=
device
->
mixpos
=
0
;
return
err
;
}
...
...
@@ -443,7 +456,7 @@ HRESULT DSOUND_PrimarySetFormat(DirectSoundDevice *device, LPCWAVEFORMATEX wfex,
RtlAcquireResourceExclusive
(
&
(
device
->
buffer_list_lock
),
TRUE
);
EnterCriticalSection
(
&
(
device
->
mixlock
));
if
(
wfex
->
wFormatTag
==
WAVE_FORMAT_PCM
)
{
if
(
wfex
->
wFormatTag
==
WAVE_FORMAT_PCM
)
{
alloc_size
=
sizeof
(
WAVEFORMATEX
);
cp_size
=
sizeof
(
PCMWAVEFORMAT
);
}
else
...
...
@@ -520,6 +533,12 @@ HRESULT DSOUND_PrimarySetFormat(DirectSoundDevice *device, LPCWAVEFORMATEX wfex,
}
}
device
->
mix_buffer_len
=
DSOUND_bufpos_to_mixpos
(
device
,
device
->
buflen
);
device
->
mix_buffer
=
HeapReAlloc
(
GetProcessHeap
(),
0
,
device
->
mix_buffer
,
device
->
mix_buffer_len
);
FillMemory
(
device
->
mix_buffer
,
device
->
mix_buffer_len
,
0
);
device
->
mixfunction
=
mixfunctions
[
device
->
pwfx
->
wBitsPerSample
/
8
-
1
];
device
->
normfunction
=
normfunctions
[
device
->
pwfx
->
wBitsPerSample
/
8
-
1
];
if
(
nSamplesPerSec
!=
device
->
pwfx
->
nSamplesPerSec
||
bpp
!=
device
->
pwfx
->
wBitsPerSample
||
chans
!=
device
->
pwfx
->
nChannels
)
{
IDirectSoundBufferImpl
**
dsb
=
device
->
buffers
;
for
(
i
=
0
;
i
<
device
->
nrofbuffers
;
i
++
,
dsb
++
)
{
...
...
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