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
6d009b98
Commit
6d009b98
authored
Dec 27, 2014
by
Marton Balint
Committed by
Alexandre Julliard
Dec 29, 2014
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
dsound: Convert freqAdjust and freqAcc to integers.
Fixes resampling errors caused by truncating floating point numbers.
parent
acccdce4
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
25 additions
and
22 deletions
+25
-22
buffer.c
dlls/dsound/buffer.c
+4
-2
dsound_private.h
dlls/dsound/dsound_private.h
+3
-1
mixer.c
dlls/dsound/mixer.c
+18
-19
No files found.
dlls/dsound/buffer.c
View file @
6d009b98
...
@@ -274,7 +274,8 @@ static HRESULT WINAPI IDirectSoundBufferImpl_SetFrequency(IDirectSoundBuffer8 *i
...
@@ -274,7 +274,8 @@ static HRESULT WINAPI IDirectSoundBufferImpl_SetFrequency(IDirectSoundBuffer8 *i
oldFreq
=
This
->
freq
;
oldFreq
=
This
->
freq
;
This
->
freq
=
freq
;
This
->
freq
=
freq
;
if
(
freq
!=
oldFreq
)
{
if
(
freq
!=
oldFreq
)
{
This
->
freqAdjust
=
This
->
freq
/
(
float
)
This
->
device
->
pwfx
->
nSamplesPerSec
;
This
->
freqAdjustNum
=
This
->
freq
;
This
->
freqAdjustDen
=
This
->
device
->
pwfx
->
nSamplesPerSec
;
This
->
nAvgBytesPerSec
=
freq
*
This
->
pwfx
->
nBlockAlign
;
This
->
nAvgBytesPerSec
=
freq
*
This
->
pwfx
->
nBlockAlign
;
DSOUND_RecalcFormat
(
This
);
DSOUND_RecalcFormat
(
This
);
}
}
...
@@ -935,7 +936,8 @@ HRESULT IDirectSoundBufferImpl_Create(
...
@@ -935,7 +936,8 @@ HRESULT IDirectSoundBufferImpl_Create(
dsb
->
sec_mixpos
=
0
;
dsb
->
sec_mixpos
=
0
;
dsb
->
state
=
STATE_STOPPED
;
dsb
->
state
=
STATE_STOPPED
;
dsb
->
freqAdjust
=
dsb
->
freq
/
(
float
)
device
->
pwfx
->
nSamplesPerSec
;
dsb
->
freqAdjustNum
=
dsb
->
freq
;
dsb
->
freqAdjustDen
=
device
->
pwfx
->
nSamplesPerSec
;
dsb
->
nAvgBytesPerSec
=
dsb
->
freq
*
dsb
->
nAvgBytesPerSec
=
dsb
->
freq
*
dsbd
->
lpwfxFormat
->
nBlockAlign
;
dsbd
->
lpwfxFormat
->
nBlockAlign
;
...
...
dlls/dsound/dsound_private.h
View file @
6d009b98
...
@@ -152,7 +152,9 @@ struct IDirectSoundBufferImpl
...
@@ -152,7 +152,9 @@ struct IDirectSoundBufferImpl
/* used for frequency conversion (PerfectPitch) */
/* used for frequency conversion (PerfectPitch) */
ULONG
freqneeded
;
ULONG
freqneeded
;
DWORD
firstep
;
DWORD
firstep
;
float
freqAcc
,
freqAdjust
,
firgain
;
float
firgain
;
LONG64
freqAdjustNum
,
freqAdjustDen
;
LONG64
freqAccNum
;
/* used for mixing */
/* used for mixing */
DWORD
sec_mixpos
;
DWORD
sec_mixpos
;
...
...
dlls/dsound/mixer.c
View file @
6d009b98
...
@@ -104,7 +104,8 @@ void DSOUND_RecalcFormat(IDirectSoundBufferImpl *dsb)
...
@@ -104,7 +104,8 @@ void DSOUND_RecalcFormat(IDirectSoundBufferImpl *dsb)
TRACE
(
"(%p)
\n
"
,
dsb
);
TRACE
(
"(%p)
\n
"
,
dsb
);
pwfxe
=
(
WAVEFORMATEXTENSIBLE
*
)
dsb
->
pwfx
;
pwfxe
=
(
WAVEFORMATEXTENSIBLE
*
)
dsb
->
pwfx
;
dsb
->
freqAdjust
=
(
float
)
dsb
->
freq
/
dsb
->
device
->
pwfx
->
nSamplesPerSec
;
dsb
->
freqAdjustNum
=
dsb
->
freq
;
dsb
->
freqAdjustDen
=
dsb
->
device
->
pwfx
->
nSamplesPerSec
;
if
((
pwfxe
->
Format
.
wFormatTag
==
WAVE_FORMAT_IEEE_FLOAT
)
||
((
pwfxe
->
Format
.
wFormatTag
==
WAVE_FORMAT_EXTENSIBLE
)
if
((
pwfxe
->
Format
.
wFormatTag
==
WAVE_FORMAT_IEEE_FLOAT
)
||
((
pwfxe
->
Format
.
wFormatTag
==
WAVE_FORMAT_EXTENSIBLE
)
&&
(
IsEqualGUID
(
&
pwfxe
->
SubFormat
,
&
KSDATAFORMAT_SUBTYPE_IEEE_FLOAT
))))
&&
(
IsEqualGUID
(
&
pwfxe
->
SubFormat
,
&
KSDATAFORMAT_SUBTYPE_IEEE_FLOAT
))))
...
@@ -117,12 +118,12 @@ void DSOUND_RecalcFormat(IDirectSoundBufferImpl *dsb)
...
@@ -117,12 +118,12 @@ void DSOUND_RecalcFormat(IDirectSoundBufferImpl *dsb)
* sample in the secondary buffer. firgain specifies what
* sample in the secondary buffer. firgain specifies what
* to multiply the FIR output by in order to attenuate it correctly.
* to multiply the FIR output by in order to attenuate it correctly.
*/
*/
if
(
dsb
->
freqAdjust
>
1
.
0
f
)
{
if
(
dsb
->
freqAdjust
Num
/
dsb
->
freqAdjustDen
>
0
)
{
/**
/**
* Yes, round it a bit to make sure that the
* Yes, round it a bit to make sure that the
* linear interpolation factor never changes.
* linear interpolation factor never changes.
*/
*/
dsb
->
firstep
=
ceil
(
fir_step
/
dsb
->
freqAdjust
)
;
dsb
->
firstep
=
fir_step
*
dsb
->
freqAdjustDen
/
dsb
->
freqAdjustNum
;
}
else
{
}
else
{
dsb
->
firstep
=
fir_step
;
dsb
->
firstep
=
fir_step
;
}
}
...
@@ -131,7 +132,7 @@ void DSOUND_RecalcFormat(IDirectSoundBufferImpl *dsb)
...
@@ -131,7 +132,7 @@ void DSOUND_RecalcFormat(IDirectSoundBufferImpl *dsb)
/* calculate the 10ms write lead */
/* calculate the 10ms write lead */
dsb
->
writelead
=
(
dsb
->
freq
/
100
)
*
dsb
->
pwfx
->
nBlockAlign
;
dsb
->
writelead
=
(
dsb
->
freq
/
100
)
*
dsb
->
pwfx
->
nBlockAlign
;
dsb
->
freqAcc
=
0
;
dsb
->
freqAcc
Num
=
0
;
dsb
->
get_aux
=
ieee
?
getbpp
[
4
]
:
getbpp
[
dsb
->
pwfx
->
wBitsPerSample
/
8
-
1
];
dsb
->
get_aux
=
ieee
?
getbpp
[
4
]
:
getbpp
[
dsb
->
pwfx
->
wBitsPerSample
/
8
-
1
];
dsb
->
put_aux
=
putieee32
;
dsb
->
put_aux
=
putieee32
;
...
@@ -262,18 +263,17 @@ static UINT cp_fields_noresample(IDirectSoundBufferImpl *dsb, UINT count)
...
@@ -262,18 +263,17 @@ static UINT cp_fields_noresample(IDirectSoundBufferImpl *dsb, UINT count)
return
count
;
return
count
;
}
}
static
UINT
cp_fields_resample
(
IDirectSoundBufferImpl
*
dsb
,
UINT
count
,
float
*
freqAcc
)
static
UINT
cp_fields_resample
(
IDirectSoundBufferImpl
*
dsb
,
UINT
count
,
LONG64
*
freqAccNum
)
{
{
UINT
i
,
channel
;
UINT
i
,
channel
;
UINT
istride
=
dsb
->
pwfx
->
nBlockAlign
;
UINT
istride
=
dsb
->
pwfx
->
nBlockAlign
;
UINT
ostride
=
dsb
->
device
->
pwfx
->
nChannels
*
sizeof
(
float
);
UINT
ostride
=
dsb
->
device
->
pwfx
->
nChannels
*
sizeof
(
float
);
float
freqAdjust
=
dsb
->
freqAdjust
;
LONG64
freqAcc_start
=
*
freqAccNum
;
float
freqAcc_start
=
*
freqAcc
;
LONG64
freqAcc_end
=
freqAcc_start
+
count
*
dsb
->
freqAdjustNum
;
float
freqAcc_end
=
freqAcc_start
+
count
*
freqAdjust
;
UINT
dsbfirstep
=
dsb
->
firstep
;
UINT
dsbfirstep
=
dsb
->
firstep
;
UINT
channels
=
dsb
->
mix_channels
;
UINT
channels
=
dsb
->
mix_channels
;
UINT
max_ipos
=
freqAcc_start
+
count
*
freqAdjust
;
UINT
max_ipos
=
(
freqAcc_start
+
count
*
dsb
->
freqAdjustNum
)
/
dsb
->
freqAdjustDen
;
UINT
fir_cachesize
=
(
fir_len
+
dsbfirstep
-
2
)
/
dsbfirstep
;
UINT
fir_cachesize
=
(
fir_len
+
dsbfirstep
-
2
)
/
dsbfirstep
;
UINT
required_input
=
max_ipos
+
fir_cachesize
;
UINT
required_input
=
max_ipos
+
fir_cachesize
;
...
@@ -295,8 +295,8 @@ static UINT cp_fields_resample(IDirectSoundBufferImpl *dsb, UINT count, float *f
...
@@ -295,8 +295,8 @@ static UINT cp_fields_resample(IDirectSoundBufferImpl *dsb, UINT count, float *f
dsb
->
sec_mixpos
+
i
*
istride
,
channel
);
dsb
->
sec_mixpos
+
i
*
istride
,
channel
);
for
(
i
=
0
;
i
<
count
;
++
i
)
{
for
(
i
=
0
;
i
<
count
;
++
i
)
{
float
total_fir_steps
=
(
freqAcc_start
+
i
*
freqAdjust
)
*
dsbfirstep
;
UINT
int_fir_steps
=
(
freqAcc_start
+
i
*
dsb
->
freqAdjustNum
)
*
dsbfirstep
/
dsb
->
freqAdjustDen
;
UINT
int_fir_steps
=
total_fir_steps
;
float
total_fir_steps
=
(
freqAcc_start
+
i
*
dsb
->
freqAdjustNum
)
*
dsbfirstep
/
(
float
)
dsb
->
freqAdjustDen
;
UINT
ipos
=
int_fir_steps
/
dsbfirstep
;
UINT
ipos
=
int_fir_steps
/
dsbfirstep
;
UINT
idx
=
(
ipos
+
1
)
*
dsbfirstep
-
int_fir_steps
-
1
;
UINT
idx
=
(
ipos
+
1
)
*
dsbfirstep
-
int_fir_steps
-
1
;
...
@@ -321,8 +321,7 @@ static UINT cp_fields_resample(IDirectSoundBufferImpl *dsb, UINT count, float *f
...
@@ -321,8 +321,7 @@ static UINT cp_fields_resample(IDirectSoundBufferImpl *dsb, UINT count, float *f
}
}
}
}
freqAcc_end
-=
(
int
)
freqAcc_end
;
*
freqAccNum
=
freqAcc_end
%
dsb
->
freqAdjustDen
;
*
freqAcc
=
freqAcc_end
;
HeapFree
(
GetProcessHeap
(),
0
,
fir_copy
);
HeapFree
(
GetProcessHeap
(),
0
,
fir_copy
);
HeapFree
(
GetProcessHeap
(),
0
,
intermediate
);
HeapFree
(
GetProcessHeap
(),
0
,
intermediate
);
...
@@ -330,14 +329,14 @@ static UINT cp_fields_resample(IDirectSoundBufferImpl *dsb, UINT count, float *f
...
@@ -330,14 +329,14 @@ static UINT cp_fields_resample(IDirectSoundBufferImpl *dsb, UINT count, float *f
return
max_ipos
;
return
max_ipos
;
}
}
static
void
cp_fields
(
IDirectSoundBufferImpl
*
dsb
,
UINT
count
,
float
*
freqAcc
)
static
void
cp_fields
(
IDirectSoundBufferImpl
*
dsb
,
UINT
count
,
LONG64
*
freqAccNum
)
{
{
DWORD
ipos
,
adv
;
DWORD
ipos
,
adv
;
if
(
dsb
->
freqAdjust
==
1
.
0
)
if
(
dsb
->
freqAdjust
Num
==
dsb
->
freqAdjustDen
)
adv
=
cp_fields_noresample
(
dsb
,
count
);
/* *freqAcc is unmodified */
adv
=
cp_fields_noresample
(
dsb
,
count
);
/* *freqAcc
Num
is unmodified */
else
else
adv
=
cp_fields_resample
(
dsb
,
count
,
freqAcc
);
adv
=
cp_fields_resample
(
dsb
,
count
,
freqAcc
Num
);
ipos
=
dsb
->
sec_mixpos
+
adv
*
dsb
->
pwfx
->
nBlockAlign
;
ipos
=
dsb
->
sec_mixpos
+
adv
*
dsb
->
pwfx
->
nBlockAlign
;
if
(
ipos
>=
dsb
->
buflen
)
{
if
(
ipos
>=
dsb
->
buflen
)
{
...
@@ -393,7 +392,7 @@ static void DSOUND_MixToTemporary(IDirectSoundBufferImpl *dsb, DWORD frames)
...
@@ -393,7 +392,7 @@ static void DSOUND_MixToTemporary(IDirectSoundBufferImpl *dsb, DWORD frames)
dsb
->
device
->
tmp_buffer
=
HeapAlloc
(
GetProcessHeap
(),
0
,
size_bytes
);
dsb
->
device
->
tmp_buffer
=
HeapAlloc
(
GetProcessHeap
(),
0
,
size_bytes
);
}
}
cp_fields
(
dsb
,
frames
,
&
dsb
->
freqAcc
);
cp_fields
(
dsb
,
frames
,
&
dsb
->
freqAcc
Num
);
}
}
static
void
DSOUND_MixerVol
(
const
IDirectSoundBufferImpl
*
dsb
,
INT
frames
)
static
void
DSOUND_MixerVol
(
const
IDirectSoundBufferImpl
*
dsb
,
INT
frames
)
...
@@ -505,7 +504,7 @@ static DWORD DSOUND_MixOne(IDirectSoundBufferImpl *dsb, DWORD writepos, DWORD mi
...
@@ -505,7 +504,7 @@ static DWORD DSOUND_MixOne(IDirectSoundBufferImpl *dsb, DWORD writepos, DWORD mi
mixlen
=
2
*
dsb
->
device
->
fraglen
;
mixlen
=
2
*
dsb
->
device
->
fraglen
;
writepos
+=
primary_done
;
writepos
+=
primary_done
;
dsb
->
sec_mixpos
+=
(
primary_done
/
dsb
->
device
->
pwfx
->
nBlockAlign
)
*
dsb
->
sec_mixpos
+=
(
primary_done
/
dsb
->
device
->
pwfx
->
nBlockAlign
)
*
dsb
->
pwfx
->
nBlockAlign
*
dsb
->
freqAdjust
;
dsb
->
pwfx
->
nBlockAlign
*
dsb
->
freqAdjust
Num
/
dsb
->
freqAdjustDen
;
}
}
}
}
...
...
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