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
20f83973
Commit
20f83973
authored
Dec 13, 2004
by
Robert Reif
Committed by
Alexandre Julliard
Dec 13, 2004
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Make the PCM conversion routines of msacm produce identical results to
the native dll. Allow any PCM to PCM conversion, not just advertised ones.
parent
97b7e0de
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
284 additions
and
420 deletions
+284
-420
pcmconverter.c
dlls/msacm/pcmconverter.c
+284
-420
No files found.
dlls/msacm/pcmconverter.c
View file @
20f83973
...
...
@@ -4,6 +4,7 @@
* MSACM32 library
*
* Copyright 2000 Eric Pouech
* Copyright 2004 Robert Reif
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
...
...
@@ -20,10 +21,6 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* FIXME / TODO list
* + most of the computation should be done in fixed point arithmetic
* instead of floating point (16 bits for integral part, and 16 bits
* for fractional part for example)
* + implement PCM_FormatSuggest function
* + get rid of hack for PCM_DriverProc (msacm32.dll shouldn't export
* a DriverProc, but this would require implementing a generic
* embedded driver handling scheme in msacm32.dll which isn't done yet
...
...
@@ -75,7 +72,7 @@ static DWORD PCM_drvClose(DWORD dwDevID)
}
#define NUM_PCM_FORMATS (sizeof(PCM_Formats) / sizeof(PCM_Formats[0]))
#define NUM_OF(a,b) ((
(a)+(b)-1
)/(b))
#define NUM_OF(a,b) ((
a
)/(b))
/* flags for fdwDriver */
#define PCM_RESAMPLE 1
...
...
@@ -85,19 +82,9 @@ typedef struct tagAcmPcmData {
/* conversion routine, depending if rate conversion is required */
union
{
void
(
*
cvtKeepRate
)(
const
unsigned
char
*
,
int
,
unsigned
char
*
);
void
(
*
cvtChangeRate
)(
struct
tagAcmPcmData
*
,
const
unsigned
char
*
,
LP
DWORD
,
unsigned
char
*
,
LPDWORD
);
void
(
*
cvtChangeRate
)(
DWORD
,
const
unsigned
char
*
,
LPDWORD
,
DWORD
,
unsigned
char
*
,
LPDWORD
);
}
cvt
;
/* the following fields are used only with rate conversion) */
DWORD
srcPos
;
/* position in source stream */
double
dstPos
;
/* position in destination stream */
double
dstIncr
;
/* value to increment dst stream when src stream
is incremented by 1 */
/* last source stream value read */
union
{
unsigned
char
b
;
/* 8 bit value */
short
s
;
/* 16 bit value */
}
last
[
2
];
/* two channels max (stereo) */
}
AcmPcmData
;
/* table to list all supported formats... those are the basic ones. this
...
...
@@ -142,11 +129,7 @@ static DWORD PCM_GetFormatIndex(LPWAVEFORMATEX wfx)
* shall work in all cases)
*
* mono => stereo: copy the same sample on Left & Right channels
* stereo =) mono: use the average value of samples from Left & Right channels
* resampling; we lookup for each destination sample the two source adjacent
* samples were src <= dst < src+1 (dst is increased by a fractional
* value which is equivalent to the increment by one on src); then we
* use a linear interpolation between src and src+1
* stereo => mono: use the sum of Left & Right channels
*/
/***********************************************************************
...
...
@@ -156,7 +139,7 @@ static DWORD PCM_GetFormatIndex(LPWAVEFORMATEX wfx)
*/
static
inline
short
C816
(
unsigned
char
b
)
{
return
(
short
)((
b
+
(
b
<<
8
))
-
32768
)
;
return
(
b
-
128
)
<<
8
;
}
/***********************************************************************
...
...
@@ -194,22 +177,40 @@ static inline void W16(unsigned char* dst, short s)
* M16
*
* Convert the (l,r) 16 bit stereo sample into a 16 bit mono
* (takes the
mid-point
of the two values)
* (takes the
sum
of the two values)
*/
static
inline
short
M16
(
short
l
,
short
r
)
{
return
(
l
+
r
)
/
2
;
int
sum
=
l
+
r
;
/* clip sum to saturation */
if
(
sum
>
32767
)
sum
=
32767
;
else
if
(
sum
<
-
32768
)
sum
=
-
32768
;
return
sum
;
}
/***********************************************************************
* M8
*
* Convert the (l,r) 8 bit stereo sample into a 8 bit mono
* (takes the
mid-point
of the two values)
* (takes the
sum
of the two values)
*/
static
inline
unsigned
char
M8
(
unsigned
char
a
,
unsigned
char
b
)
{
return
(
unsigned
char
)((
a
+
b
)
/
2
);
int
l
=
a
-
128
;
int
r
=
b
-
128
;
int
sum
=
(
l
+
r
)
+
128
;
/* clip sum to saturation */
if
(
sum
>
0xff
)
sum
=
0xff
;
else
if
(
sum
<
0
)
sum
=
0
;
return
sum
;
}
/* the conversion routines without rate conversion are labelled cvt<X><Y><N><M>K
...
...
@@ -275,7 +276,7 @@ static void cvtMS168K(const unsigned char* src, int ns, unsigned char* dst)
TRACE
(
"(%p, %d, %p)
\n
"
,
src
,
ns
,
dst
);
while
(
ns
--
)
{
v
=
C168
(
R16
(
src
));
src
+=
2
;
v
=
C168
(
R16
(
src
));
src
+=
2
;
*
dst
++
=
v
;
*
dst
++
=
v
;
}
...
...
@@ -380,40 +381,6 @@ static void (*PCM_ConvertKeepRate[16])(const unsigned char*, int, unsigned char*
cvtSS1616K
,
cvtSM1616K
,
cvtMS1616K
,
cvtMM1616K
,
};
/***********************************************************************
* I
*
* Interpolate the value at r (r in ]0, 1]) between the two points v1 and v2
* Linear interpolation is used
*/
static
inline
double
I
(
double
v1
,
double
v2
,
double
r
)
{
if
(
0
.
0
>=
r
||
r
>
1
.
0
)
FIXME
(
"r!! %f
\n
"
,
r
);
return
(
1
.
0
-
r
)
*
v1
+
r
*
v2
;
}
static
void
cvtSS88C
(
AcmPcmData
*
apd
,
const
unsigned
char
*
src
,
LPDWORD
nsrc
,
unsigned
char
*
dst
,
LPDWORD
ndst
)
{
double
r
;
TRACE
(
"(%p, %p, %p, %p, %p)
\n
"
,
apd
,
src
,
nsrc
,
dst
,
ndst
);
while
(
*
nsrc
!=
0
&&
*
ndst
!=
0
)
{
while
((
r
=
(
double
)
apd
->
srcPos
-
apd
->
dstPos
)
<=
0
)
{
if
(
*
nsrc
==
0
)
return
;
apd
->
last
[
0
].
b
=
*
src
++
;
apd
->
last
[
1
].
b
=
*
src
++
;
apd
->
srcPos
++
;
(
*
nsrc
)
--
;
}
/* now do the interpolation */
*
dst
++
=
I
(
apd
->
last
[
0
].
b
,
src
[
0
],
r
);
*
dst
++
=
I
(
apd
->
last
[
1
].
b
,
src
[
1
],
r
);
apd
->
dstPos
+=
apd
->
dstIncr
;
(
*
ndst
)
--
;
}
}
/* the conversion routines with rate conversion are labelled cvt<X><Y><N><M>C
* where :
* <X> is the (M)ono/(S)tereo configuration of input channel
...
...
@@ -422,393 +389,320 @@ static void cvtSS88C(AcmPcmData* apd, const unsigned char* src, LPDWORD nsrc,
* <M> is the number of bits of output channel (8 or 16)
*
*/
static
void
cvtS
M88C
(
AcmPcmData
*
apd
,
const
unsigned
char
*
src
,
LPDWORD
nsrc
,
unsigned
char
*
dst
,
LPDWORD
ndst
)
static
void
cvtS
S88C
(
DWORD
srcRate
,
const
unsigned
char
*
src
,
LPDWORD
nsrc
,
DWORD
dstRate
,
unsigned
char
*
dst
,
LPDWORD
ndst
)
{
double
r
;
TRACE
(
"(%p, %p, %p, %p, %p)
\n
"
,
apd
,
src
,
nsrc
,
dst
,
ndst
);
while
(
*
nsrc
!=
0
&&
*
ndst
!=
0
)
{
while
((
r
=
(
double
)
apd
->
srcPos
-
apd
->
dstPos
)
<=
0
)
{
if
(
*
nsrc
==
0
)
return
;
apd
->
last
[
0
].
b
=
*
src
++
;
apd
->
last
[
1
].
b
=
*
src
++
;
apd
->
srcPos
++
;
(
*
nsrc
)
--
;
}
/* now do the interpolation */
if
(
*
nsrc
)
/* don't go off end of data */
*
dst
++
=
I
(
M8
(
apd
->
last
[
0
].
b
,
apd
->
last
[
1
].
b
),
M8
(
src
[
0
],
src
[
1
]),
r
);
else
*
dst
++
=
M8
(
apd
->
last
[
0
].
b
,
apd
->
last
[
1
].
b
);
apd
->
dstPos
+=
apd
->
dstIncr
;
(
*
ndst
)
--
;
DWORD
error
=
dstRate
/
2
;
TRACE
(
"(%ld, %p, %p, %ld, %p, %p)
\n
"
,
srcRate
,
src
,
nsrc
,
dstRate
,
dst
,
ndst
);
while
((
*
ndst
)
--
)
{
*
dst
++
=
*
src
;
*
dst
++
=
*
src
;
error
=
error
+
srcRate
;
while
(
error
>
dstRate
)
{
src
+=
2
;
(
*
nsrc
)
--
;
if
(
*
nsrc
==
0
)
return
;
error
=
error
-
dstRate
;
}
}
}
static
void
cvt
MS88C
(
AcmPcmData
*
apd
,
const
unsigned
char
*
src
,
LPDWORD
nsrc
,
unsigned
char
*
dst
,
LPDWORD
ndst
)
static
void
cvt
SM88C
(
DWORD
srcRate
,
const
unsigned
char
*
src
,
LPDWORD
nsrc
,
DWORD
dstRate
,
unsigned
char
*
dst
,
LPDWORD
ndst
)
{
double
r
;
TRACE
(
"(%p, %p, %p, %p, %p)
\n
"
,
apd
,
src
,
nsrc
,
dst
,
ndst
);
while
(
*
nsrc
!=
0
&&
*
ndst
!=
0
)
{
while
((
r
=
(
double
)
apd
->
srcPos
-
apd
->
dstPos
)
<=
0
)
{
if
(
*
nsrc
==
0
)
return
;
apd
->
last
[
0
].
b
=
*
src
++
;
apd
->
srcPos
++
;
(
*
nsrc
)
--
;
}
/* now do the interpolation */
if
(
*
nsrc
)
/* don't go off end of data */
dst
[
0
]
=
dst
[
1
]
=
I
(
apd
->
last
[
0
].
b
,
src
[
0
],
r
);
else
dst
[
0
]
=
dst
[
1
]
=
apd
->
last
[
0
].
b
;
dst
+=
2
;
apd
->
dstPos
+=
apd
->
dstIncr
;
(
*
ndst
)
--
;
DWORD
error
=
dstRate
/
2
;
TRACE
(
"(%ld, %p, %p, %ld, %p, %p)
\n
"
,
srcRate
,
src
,
nsrc
,
dstRate
,
dst
,
ndst
);
while
((
*
ndst
)
--
)
{
*
dst
++
=
M8
(
src
[
0
],
src
[
1
]);
error
=
error
+
srcRate
;
while
(
error
>
dstRate
)
{
src
+=
2
;
(
*
nsrc
)
--
;
if
(
*
nsrc
==
0
)
return
;
error
=
error
-
dstRate
;
}
}
}
static
void
cvtM
M88C
(
AcmPcmData
*
apd
,
const
unsigned
char
*
src
,
LPDWORD
nsrc
,
unsigned
char
*
dst
,
LPDWORD
ndst
)
static
void
cvtM
S88C
(
DWORD
srcRate
,
const
unsigned
char
*
src
,
LPDWORD
nsrc
,
DWORD
dstRate
,
unsigned
char
*
dst
,
LPDWORD
ndst
)
{
double
r
;
TRACE
(
"(%p, %p, %p, %p, %p)
\n
"
,
apd
,
src
,
nsrc
,
dst
,
ndst
);
while
(
*
nsrc
!=
0
&&
*
ndst
!=
0
)
{
while
((
r
=
(
double
)
apd
->
srcPos
-
apd
->
dstPos
)
<=
0
)
{
if
(
*
nsrc
==
0
)
return
;
apd
->
last
[
0
].
b
=
*
src
++
;
apd
->
srcPos
++
;
(
*
nsrc
)
--
;
}
/* now do the interpolation */
if
(
*
nsrc
)
/* don't go off end of data */
*
dst
++
=
I
(
apd
->
last
[
0
].
b
,
src
[
0
],
r
);
else
*
dst
++
=
apd
->
last
[
0
].
b
;
apd
->
dstPos
+=
apd
->
dstIncr
;
(
*
ndst
)
--
;
DWORD
error
=
dstRate
/
2
;
TRACE
(
"(%ld, %p, %p, %ld, %p, %p)
\n
"
,
srcRate
,
src
,
nsrc
,
dstRate
,
dst
,
ndst
);
while
((
*
ndst
)
--
)
{
*
dst
++
=
*
src
;
*
dst
++
=
*
src
;
error
=
error
+
srcRate
;
while
(
error
>
dstRate
)
{
src
++
;
(
*
nsrc
)
--
;
if
(
*
nsrc
==
0
)
return
;
error
=
error
-
dstRate
;
}
}
}
static
void
cvt
SS816C
(
AcmPcmData
*
apd
,
const
unsigned
char
*
src
,
LPDWORD
nsrc
,
unsigned
char
*
dst
,
LPDWORD
ndst
)
static
void
cvt
MM88C
(
DWORD
srcRate
,
const
unsigned
char
*
src
,
LPDWORD
nsrc
,
DWORD
dstRate
,
unsigned
char
*
dst
,
LPDWORD
ndst
)
{
double
r
;
TRACE
(
"(%p, %p, %p, %p, %p)
\n
"
,
apd
,
src
,
nsrc
,
dst
,
ndst
);
while
(
*
nsrc
!=
0
&&
*
ndst
!=
0
)
{
while
((
r
=
(
double
)
apd
->
srcPos
-
apd
->
dstPos
)
<=
0
)
{
if
(
*
nsrc
==
0
)
return
;
apd
->
last
[
0
].
b
=
*
src
++
;
apd
->
last
[
1
].
b
=
*
src
++
;
apd
->
srcPos
++
;
(
*
nsrc
)
--
;
}
/* now do the interpolation */
if
(
*
nsrc
)
/* don't go off end of data */
W16
(
dst
,
I
(
C816
(
apd
->
last
[
0
].
b
),
C816
(
src
[
0
]),
r
));
else
W16
(
dst
,
C816
(
apd
->
last
[
0
].
b
));
dst
+=
2
;
if
(
*
nsrc
)
/* don't go off end of data */
W16
(
dst
,
I
(
C816
(
apd
->
last
[
1
].
b
),
C816
(
src
[
1
]),
r
));
else
W16
(
dst
,
C816
(
apd
->
last
[
1
].
b
));
dst
+=
2
;
apd
->
dstPos
+=
apd
->
dstIncr
;
(
*
ndst
)
--
;
DWORD
error
=
dstRate
/
2
;
TRACE
(
"(%ld, %p, %p, %ld, %p, %p)
\n
"
,
srcRate
,
src
,
nsrc
,
dstRate
,
dst
,
ndst
);
while
((
*
ndst
)
--
)
{
*
dst
++
=
*
src
;
error
=
error
+
srcRate
;
while
(
error
>
dstRate
)
{
src
++
;
(
*
nsrc
)
--
;
if
(
*
nsrc
==
0
)
return
;
error
=
error
-
dstRate
;
}
}
}
static
void
cvtS
M816C
(
AcmPcmData
*
apd
,
const
unsigned
char
*
src
,
LPDWORD
nsrc
,
unsigned
char
*
dst
,
LPDWORD
ndst
)
static
void
cvtS
S816C
(
DWORD
srcRate
,
const
unsigned
char
*
src
,
LPDWORD
nsrc
,
DWORD
dstRate
,
unsigned
char
*
dst
,
LPDWORD
ndst
)
{
double
r
;
TRACE
(
"(%p, %p, %p, %p, %p)
\n
"
,
apd
,
src
,
nsrc
,
dst
,
ndst
);
while
(
*
nsrc
!=
0
&&
*
ndst
!=
0
)
{
while
((
r
=
(
double
)
apd
->
srcPos
-
apd
->
dstPos
)
<=
0
)
{
if
(
*
nsrc
==
0
)
return
;
apd
->
last
[
0
].
b
=
*
src
++
;
apd
->
last
[
1
].
b
=
*
src
++
;
apd
->
srcPos
++
;
(
*
nsrc
)
--
;
}
/* now do the interpolation */
if
(
*
nsrc
)
/* don't go off end of data */
W16
(
dst
,
I
(
M16
(
C816
(
apd
->
last
[
0
].
b
),
C816
(
apd
->
last
[
1
].
b
)),
M16
(
C816
(
src
[
0
]),
C816
(
src
[
1
])),
r
));
else
W16
(
dst
,
M16
(
C816
(
apd
->
last
[
0
].
b
),
C816
(
apd
->
last
[
1
].
b
)));
dst
+=
2
;
apd
->
dstPos
+=
apd
->
dstIncr
;
(
*
ndst
)
--
;
DWORD
error
=
dstRate
/
2
;
TRACE
(
"(%ld, %p, %p, %ld, %p, %p)
\n
"
,
srcRate
,
src
,
nsrc
,
dstRate
,
dst
,
ndst
);
while
((
*
ndst
)
--
)
{
W16
(
dst
,
C816
(
src
[
0
]));
dst
+=
2
;
W16
(
dst
,
C816
(
src
[
1
]));
dst
+=
2
;
error
=
error
+
srcRate
;
while
(
error
>
dstRate
)
{
src
+=
2
;
(
*
nsrc
)
--
;
if
(
*
nsrc
==
0
)
return
;
error
=
error
-
dstRate
;
}
}
}
static
void
cvt
MS816C
(
AcmPcmData
*
apd
,
const
unsigned
char
*
src
,
LPDWORD
nsrc
,
unsigned
char
*
dst
,
LPDWORD
ndst
)
static
void
cvt
SM816C
(
DWORD
srcRate
,
const
unsigned
char
*
src
,
LPDWORD
nsrc
,
DWORD
dstRate
,
unsigned
char
*
dst
,
LPDWORD
ndst
)
{
double
r
;
short
v
;
TRACE
(
"(%p, %p, %p->(%ld), %p, %p->(%ld))
\n
"
,
apd
,
src
,
nsrc
,
*
nsrc
,
dst
,
ndst
,
*
ndst
);
while
(
*
nsrc
!=
0
&&
*
ndst
!=
0
)
{
while
((
r
=
(
double
)
apd
->
srcPos
-
apd
->
dstPos
)
<=
0
)
{
if
(
*
nsrc
==
0
)
return
;
apd
->
last
[
0
].
b
=
*
src
++
;
apd
->
srcPos
++
;
(
*
nsrc
)
--
;
}
/* now do the interpolation */
if
(
*
nsrc
)
/* don't go off end of data */
v
=
I
(
C816
(
apd
->
last
[
0
].
b
),
C816
(
src
[
0
]),
r
);
else
v
=
C816
(
apd
->
last
[
0
].
b
);
W16
(
dst
,
v
);
dst
+=
2
;
W16
(
dst
,
v
);
dst
+=
2
;
apd
->
dstPos
+=
apd
->
dstIncr
;
(
*
ndst
)
--
;
DWORD
error
=
dstRate
/
2
;
TRACE
(
"(%ld, %p, %p, %ld, %p, %p)
\n
"
,
srcRate
,
src
,
nsrc
,
dstRate
,
dst
,
ndst
);
while
((
*
ndst
)
--
)
{
W16
(
dst
,
M16
(
C816
(
src
[
0
]),
C816
(
src
[
1
])));
dst
+=
2
;
error
=
error
+
srcRate
;
while
(
error
>
dstRate
)
{
src
+=
2
;
(
*
nsrc
)
--
;
if
(
*
nsrc
==
0
)
return
;
error
=
error
-
dstRate
;
}
}
}
static
void
cvtM
M816C
(
AcmPcmData
*
apd
,
const
unsigned
char
*
src
,
LPDWORD
nsrc
,
unsigned
char
*
dst
,
LPDWORD
ndst
)
static
void
cvtM
S816C
(
DWORD
srcRate
,
const
unsigned
char
*
src
,
LPDWORD
nsrc
,
DWORD
dstRate
,
unsigned
char
*
dst
,
LPDWORD
ndst
)
{
double
r
;
TRACE
(
"(%p, %p, %p, %p, %p)
\n
"
,
apd
,
src
,
nsrc
,
dst
,
ndst
);
while
(
*
nsrc
!=
0
&&
*
ndst
!=
0
)
{
while
((
r
=
(
double
)
apd
->
srcPos
-
apd
->
dstPos
)
<=
0
)
{
if
(
*
nsrc
==
0
)
return
;
apd
->
last
[
0
].
b
=
*
src
++
;
apd
->
srcPos
++
;
(
*
nsrc
)
--
;
}
/* now do the interpolation */
if
(
*
nsrc
)
/* don't go off end of data */
W16
(
dst
,
I
(
C816
(
apd
->
last
[
0
].
b
),
C816
(
src
[
0
]),
r
));
else
W16
(
dst
,
C816
(
apd
->
last
[
0
].
b
));
dst
+=
2
;
apd
->
dstPos
+=
apd
->
dstIncr
;
(
*
ndst
)
--
;
DWORD
error
=
dstRate
/
2
;
TRACE
(
"(%ld, %p, %p, %ld, %p, %p)
\n
"
,
srcRate
,
src
,
nsrc
,
dstRate
,
dst
,
ndst
);
while
((
*
ndst
)
--
)
{
W16
(
dst
,
C816
(
*
src
));
dst
+=
2
;
W16
(
dst
,
C816
(
*
src
));
dst
+=
2
;
error
=
error
+
srcRate
;
while
(
error
>
dstRate
)
{
src
++
;
(
*
nsrc
)
--
;
if
(
*
nsrc
==
0
)
return
;
error
=
error
-
dstRate
;
}
}
}
static
void
cvt
SS168C
(
AcmPcmData
*
apd
,
const
unsigned
char
*
src
,
LPDWORD
nsrc
,
unsigned
char
*
dst
,
LPDWORD
ndst
)
static
void
cvt
MM816C
(
DWORD
srcRate
,
const
unsigned
char
*
src
,
LPDWORD
nsrc
,
DWORD
dstRate
,
unsigned
char
*
dst
,
LPDWORD
ndst
)
{
double
r
;
TRACE
(
"(%p, %p, %p, %p, %p)
\n
"
,
apd
,
src
,
nsrc
,
dst
,
ndst
);
while
(
*
nsrc
!=
0
&&
*
ndst
!=
0
)
{
while
((
r
=
(
double
)
apd
->
srcPos
-
apd
->
dstPos
)
<=
0
)
{
if
(
*
nsrc
==
0
)
return
;
apd
->
last
[
0
].
s
=
R16
(
src
);
src
+=
2
;
apd
->
last
[
1
].
s
=
R16
(
src
);
src
+=
2
;
apd
->
srcPos
++
;
(
*
nsrc
)
--
;
}
/* now do the interpolation */
if
(
*
nsrc
)
{
/* don't go off end of data */
*
dst
++
=
C168
(
I
(
apd
->
last
[
0
].
s
,
R16
(
src
)
,
r
));
*
dst
++
=
C168
(
I
(
apd
->
last
[
1
].
s
,
R16
(
src
+
2
),
r
));
}
else
{
*
dst
++
=
C168
(
apd
->
last
[
0
].
s
);
*
dst
++
=
C168
(
apd
->
last
[
1
].
s
);
DWORD
error
=
dstRate
/
2
;
TRACE
(
"(%ld, %p, %p, %ld, %p, %p)
\n
"
,
srcRate
,
src
,
nsrc
,
dstRate
,
dst
,
ndst
);
while
((
*
ndst
)
--
)
{
W16
(
dst
,
C816
(
*
src
));
dst
+=
2
;
error
=
error
+
srcRate
;
while
(
error
>
dstRate
)
{
src
++
;
(
*
nsrc
)
--
;
if
(
*
nsrc
==
0
)
return
;
error
=
error
-
dstRate
;
}
apd
->
dstPos
+=
apd
->
dstIncr
;
(
*
ndst
)
--
;
}
}
static
void
cvtS
M168C
(
AcmPcmData
*
apd
,
const
unsigned
char
*
src
,
LPDWORD
nsrc
,
unsigned
char
*
dst
,
LPDWORD
ndst
)
static
void
cvtS
S168C
(
DWORD
srcRate
,
const
unsigned
char
*
src
,
LPDWORD
nsrc
,
DWORD
dstRate
,
unsigned
char
*
dst
,
LPDWORD
ndst
)
{
double
r
;
TRACE
(
"(%p, %p, %p, %p, %p)
\n
"
,
apd
,
src
,
nsrc
,
dst
,
ndst
);
while
(
*
nsrc
!=
0
&&
*
ndst
!=
0
)
{
while
((
r
=
(
double
)
apd
->
srcPos
-
apd
->
dstPos
)
<=
0
)
{
if
(
*
nsrc
==
0
)
return
;
apd
->
last
[
0
].
s
=
R16
(
src
);
src
+=
2
;
apd
->
last
[
1
].
s
=
R16
(
src
);
src
+=
2
;
apd
->
srcPos
++
;
(
*
nsrc
)
--
;
}
/* now do the interpolation */
if
(
*
nsrc
)
/* don't go off end of data */
*
dst
++
=
C168
(
I
(
M16
(
apd
->
last
[
0
].
s
,
apd
->
last
[
1
].
s
),
M16
(
R16
(
src
),
R16
(
src
+
2
)),
r
));
else
*
dst
++
=
C168
(
M16
(
apd
->
last
[
0
].
s
,
apd
->
last
[
1
].
s
));
apd
->
dstPos
+=
apd
->
dstIncr
;
(
*
ndst
)
--
;
DWORD
error
=
dstRate
/
2
;
TRACE
(
"(%ld, %p, %p, %ld, %p, %p)
\n
"
,
srcRate
,
src
,
nsrc
,
dstRate
,
dst
,
ndst
);
while
((
*
ndst
)
--
)
{
*
dst
++
=
C168
(
R16
(
src
));
*
dst
++
=
C168
(
R16
(
src
+
2
));
error
=
error
+
srcRate
;
while
(
error
>
dstRate
)
{
src
+=
4
;
(
*
nsrc
)
--
;
if
(
*
nsrc
==
0
)
return
;
error
=
error
-
dstRate
;
}
}
}
static
void
cvtMS168C
(
AcmPcmData
*
apd
,
const
unsigned
char
*
src
,
LPDWORD
nsrc
,
unsigned
char
*
dst
,
LPDWORD
ndst
)
static
void
cvtSM168C
(
DWORD
srcRate
,
const
unsigned
char
*
src
,
LPDWORD
nsrc
,
DWORD
dstRate
,
unsigned
char
*
dst
,
LPDWORD
ndst
)
{
double
r
;
TRACE
(
"(%p, %p, %p, %p, %p)
\n
"
,
apd
,
src
,
nsrc
,
dst
,
ndst
);
while
(
*
nsrc
!=
0
&&
*
ndst
!=
0
)
{
while
((
r
=
(
double
)
apd
->
srcPos
-
apd
->
dstPos
)
<=
0
)
{
if
(
*
nsrc
==
0
)
return
;
apd
->
last
[
0
].
s
=
R16
(
src
);
src
+=
2
;
apd
->
srcPos
++
;
(
*
nsrc
)
--
;
}
/* now do the interpolation */
if
(
*
nsrc
)
/* don't go off end of data */
dst
[
0
]
=
dst
[
1
]
=
C168
(
I
(
apd
->
last
[
0
].
s
,
R16
(
src
),
r
));
else
dst
[
0
]
=
dst
[
1
]
=
C168
(
apd
->
last
[
0
].
s
);
dst
+=
2
;
apd
->
dstPos
+=
apd
->
dstIncr
;
(
*
ndst
)
--
;
DWORD
error
=
dstRate
/
2
;
TRACE
(
"(%ld, %p, %p, %ld, %p, %p)
\n
"
,
srcRate
,
src
,
nsrc
,
dstRate
,
dst
,
ndst
);
while
((
*
ndst
)
--
)
{
*
dst
++
=
C168
(
M16
(
R16
(
src
),
R16
(
src
+
2
)));
error
=
error
+
srcRate
;
while
(
error
>
dstRate
)
{
src
+=
4
;
(
*
nsrc
)
--
;
if
(
*
nsrc
==
0
)
return
;
error
=
error
-
dstRate
;
}
}
}
static
void
cvtMS168C
(
DWORD
srcRate
,
const
unsigned
char
*
src
,
LPDWORD
nsrc
,
DWORD
dstRate
,
unsigned
char
*
dst
,
LPDWORD
ndst
)
{
DWORD
error
=
dstRate
/
2
;
TRACE
(
"(%ld, %p, %p, %ld, %p, %p)
\n
"
,
srcRate
,
src
,
nsrc
,
dstRate
,
dst
,
ndst
);
while
((
*
ndst
)
--
)
{
*
dst
++
=
C168
(
R16
(
src
));
*
dst
++
=
C168
(
R16
(
src
));
error
=
error
+
srcRate
;
while
(
error
>
dstRate
)
{
src
+=
2
;
(
*
nsrc
)
--
;
if
(
*
nsrc
==
0
)
return
;
error
=
error
-
dstRate
;
}
}
}
static
void
cvtMM168C
(
AcmPcmData
*
apd
,
const
unsigned
char
*
src
,
LPDWORD
nsrc
,
unsigned
char
*
dst
,
LPDWORD
ndst
)
static
void
cvtMM168C
(
DWORD
srcRate
,
const
unsigned
char
*
src
,
LPDWORD
nsrc
,
DWORD
dstRate
,
unsigned
char
*
dst
,
LPDWORD
ndst
)
{
double
r
;
TRACE
(
"(%p, %p, %p, %p, %p)
\n
"
,
apd
,
src
,
nsrc
,
dst
,
ndst
);
while
(
*
nsrc
!=
0
&&
*
ndst
!=
0
)
{
while
((
r
=
(
double
)
apd
->
srcPos
-
apd
->
dstPos
)
<=
0
)
{
if
(
*
nsrc
==
0
)
return
;
apd
->
last
[
0
].
s
=
R16
(
src
);
src
+=
2
;
apd
->
srcPos
++
;
(
*
nsrc
)
--
;
}
/* now do the interpolation */
if
(
*
nsrc
)
/* don't go off end of data */
*
dst
++
=
C168
(
I
(
apd
->
last
[
0
].
s
,
R16
(
src
),
r
));
else
*
dst
++
=
C168
(
apd
->
last
[
0
].
s
);
apd
->
dstPos
+=
apd
->
dstIncr
;
(
*
ndst
)
--
;
DWORD
error
=
dstRate
/
2
;
TRACE
(
"(%ld, %p, %p, %ld, %p, %p)
\n
"
,
srcRate
,
src
,
nsrc
,
dstRate
,
dst
,
ndst
);
while
((
*
ndst
)
--
)
{
*
dst
++
=
C168
(
R16
(
src
));
error
=
error
+
srcRate
;
while
(
error
>
dstRate
)
{
src
+=
2
;
(
*
nsrc
)
--
;
if
(
*
nsrc
==
0
)
return
;
error
=
error
-
dstRate
;
}
}
}
static
void
cvtSS1616C
(
AcmPcmData
*
apd
,
const
unsigned
char
*
src
,
LPDWORD
nsrc
,
unsigned
char
*
dst
,
LPDWORD
ndst
)
static
void
cvtSS1616C
(
DWORD
srcRate
,
const
unsigned
char
*
src
,
LPDWORD
nsrc
,
DWORD
dstRate
,
unsigned
char
*
dst
,
LPDWORD
ndst
)
{
double
r
;
TRACE
(
"(%p, %p, %p, %p, %p)
\n
"
,
apd
,
src
,
nsrc
,
dst
,
ndst
);
while
(
*
nsrc
!=
0
&&
*
ndst
!=
0
)
{
while
((
r
=
(
double
)
apd
->
srcPos
-
apd
->
dstPos
)
<=
0
)
{
if
(
*
nsrc
==
0
)
return
;
apd
->
last
[
0
].
s
=
R16
(
src
);
src
+=
2
;
apd
->
last
[
1
].
s
=
R16
(
src
);
src
+=
2
;
apd
->
srcPos
++
;
(
*
nsrc
)
--
;
}
/* now do the interpolation */
if
(
*
nsrc
)
/* don't go off end of data */
W16
(
dst
,
I
(
apd
->
last
[
0
].
s
,
R16
(
src
),
r
));
else
W16
(
dst
,
apd
->
last
[
0
].
s
);
dst
+=
2
;
if
(
*
nsrc
)
/* don't go off end of data */
W16
(
dst
,
I
(
apd
->
last
[
1
].
s
,
R16
(
src
+
2
),
r
));
else
W16
(
dst
,
apd
->
last
[
1
].
s
);
dst
+=
2
;
apd
->
dstPos
+=
apd
->
dstIncr
;
(
*
ndst
)
--
;
DWORD
error
=
dstRate
/
2
;
TRACE
(
"(%ld, %p, %p, %ld, %p, %p)
\n
"
,
srcRate
,
src
,
nsrc
,
dstRate
,
dst
,
ndst
);
while
((
*
ndst
)
--
)
{
W16
(
dst
,
R16
(
src
));
dst
+=
2
;
W16
(
dst
,
R16
(
src
));
dst
+=
2
;
error
=
error
+
srcRate
;
while
(
error
>
dstRate
)
{
src
+=
4
;
(
*
nsrc
)
--
;
if
(
*
nsrc
==
0
)
return
;
error
=
error
-
dstRate
;
}
}
}
static
void
cvtSM1616C
(
AcmPcmData
*
apd
,
const
unsigned
char
*
src
,
LPDWORD
nsrc
,
unsigned
char
*
dst
,
LPDWORD
ndst
)
static
void
cvtSM1616C
(
DWORD
srcRate
,
const
unsigned
char
*
src
,
LPDWORD
nsrc
,
DWORD
dstRate
,
unsigned
char
*
dst
,
LPDWORD
ndst
)
{
double
r
;
TRACE
(
"(%p, %p, %p, %p, %p)
\n
"
,
apd
,
src
,
nsrc
,
dst
,
ndst
);
while
(
*
nsrc
!=
0
&&
*
ndst
!=
0
)
{
while
((
r
=
(
double
)
apd
->
srcPos
-
apd
->
dstPos
)
<=
0
)
{
if
(
*
nsrc
==
0
)
return
;
apd
->
last
[
0
].
s
=
R16
(
src
);
src
+=
2
;
apd
->
last
[
1
].
s
=
R16
(
src
);
src
+=
2
;
apd
->
srcPos
++
;
(
*
nsrc
)
--
;
}
/* now do the interpolation */
if
(
*
nsrc
)
/* don't go off end of data */
W16
(
dst
,
I
(
M16
(
apd
->
last
[
0
].
s
,
apd
->
last
[
1
].
s
),
M16
(
R16
(
src
),
R16
(
src
+
2
)),
r
));
else
W16
(
dst
,
M16
(
apd
->
last
[
0
].
s
,
apd
->
last
[
1
].
s
));
dst
+=
2
;
apd
->
dstPos
+=
apd
->
dstIncr
;
(
*
ndst
)
--
;
DWORD
error
=
dstRate
/
2
;
TRACE
(
"(%ld, %p, %p, %ld, %p, %p)
\n
"
,
srcRate
,
src
,
nsrc
,
dstRate
,
dst
,
ndst
);
while
((
*
ndst
)
--
)
{
W16
(
dst
,
M16
(
R16
(
src
),
R16
(
src
+
2
)));
dst
+=
2
;
error
=
error
+
srcRate
;
while
(
error
>
dstRate
)
{
src
+=
4
;
(
*
nsrc
)
--
;
if
(
*
nsrc
==
0
)
return
;
error
=
error
-
dstRate
;
}
}
}
static
void
cvtMS1616C
(
AcmPcmData
*
apd
,
const
unsigned
char
*
src
,
LPDWORD
nsrc
,
unsigned
char
*
dst
,
LPDWORD
ndst
)
static
void
cvtMS1616C
(
DWORD
srcRate
,
const
unsigned
char
*
src
,
LPDWORD
nsrc
,
DWORD
dstRate
,
unsigned
char
*
dst
,
LPDWORD
ndst
)
{
double
r
;
short
v
;
TRACE
(
"(%p, %p, %p, %p, %p)
\n
"
,
apd
,
src
,
nsrc
,
dst
,
ndst
);
while
(
*
nsrc
!=
0
&&
*
ndst
!=
0
)
{
while
((
r
=
(
double
)
apd
->
srcPos
-
apd
->
dstPos
)
<=
0
)
{
if
(
*
nsrc
==
0
)
return
;
apd
->
last
[
0
].
s
=
R16
(
src
);
src
+=
2
;
apd
->
srcPos
++
;
(
*
nsrc
)
--
;
}
/* now do the interpolation */
if
(
*
nsrc
)
/* don't go off end of data */
v
=
I
(
apd
->
last
[
0
].
s
,
R16
(
src
),
r
);
else
v
=
apd
->
last
[
0
].
s
;
W16
(
dst
,
v
);
dst
+=
2
;
W16
(
dst
,
v
);
dst
+=
2
;
apd
->
dstPos
+=
apd
->
dstIncr
;
(
*
ndst
)
--
;
DWORD
error
=
dstRate
/
2
;
TRACE
(
"(%ld, %p, %p, %ld, %p, %p)
\n
"
,
srcRate
,
src
,
nsrc
,
dstRate
,
dst
,
ndst
);
while
((
*
ndst
)
--
)
{
W16
(
dst
,
R16
(
src
));
dst
+=
2
;
W16
(
dst
,
R16
(
src
));
dst
+=
2
;
error
=
error
+
srcRate
;
while
(
error
>
dstRate
)
{
src
+=
2
;
(
*
nsrc
)
--
;
if
(
*
nsrc
==
0
)
return
;
error
=
error
-
dstRate
;
}
}
}
static
void
cvtMM1616C
(
AcmPcmData
*
apd
,
const
unsigned
char
*
src
,
LPDWORD
nsrc
,
unsigned
char
*
dst
,
LPDWORD
ndst
)
static
void
cvtMM1616C
(
DWORD
srcRate
,
const
unsigned
char
*
src
,
LPDWORD
nsrc
,
DWORD
dstRate
,
unsigned
char
*
dst
,
LPDWORD
ndst
)
{
double
r
;
TRACE
(
"(%p, %p, %p, %p, %p)
\n
"
,
apd
,
src
,
nsrc
,
dst
,
ndst
);
while
(
*
nsrc
!=
0
&&
*
ndst
!=
0
)
{
while
((
r
=
(
double
)
apd
->
srcPos
-
apd
->
dstPos
)
<=
0
)
{
if
(
*
nsrc
==
0
)
return
;
apd
->
last
[
0
].
s
=
R16
(
src
);
src
+=
2
;
apd
->
srcPos
++
;
(
*
nsrc
)
--
;
}
/* now do the interpolation */
if
(
*
nsrc
)
/* don't go off end of data */
W16
(
dst
,
I
(
apd
->
last
[
0
].
s
,
R16
(
src
),
r
));
else
W16
(
dst
,
apd
->
last
[
0
].
s
);
dst
+=
2
;
apd
->
dstPos
+=
apd
->
dstIncr
;
(
*
ndst
)
--
;
DWORD
error
=
dstRate
/
2
;
TRACE
(
"(%ld, %p, %p, %ld, %p, %p)
\n
"
,
srcRate
,
src
,
nsrc
,
dstRate
,
dst
,
ndst
);
while
((
*
ndst
)
--
)
{
W16
(
dst
,
R16
(
src
));
dst
+=
2
;
error
=
error
+
srcRate
;
while
(
error
>
dstRate
)
{
src
+=
2
;
(
*
nsrc
)
--
;
if
(
*
nsrc
==
0
)
return
;
error
=
error
-
dstRate
;
}
}
}
static
void
(
*
PCM_ConvertChangeRate
[
16
])(
AcmPcmData
*
apd
,
const
unsigned
char
*
src
,
LPDWORD
nsrc
,
unsigned
char
*
dst
,
LPDWORD
ndst
)
=
{
static
void
(
*
PCM_ConvertChangeRate
[
16
])(
DWORD
srcRate
,
const
unsigned
char
*
src
,
LPDWORD
nsrc
,
DWORD
dstRate
,
unsigned
char
*
dst
,
LPDWORD
ndst
)
=
{
cvtSS88C
,
cvtSM88C
,
cvtMS88C
,
cvtMM88C
,
cvtSS816C
,
cvtSM816C
,
cvtMS816C
,
cvtMM816C
,
cvtSS168C
,
cvtSM168C
,
cvtMS168C
,
cvtMM168C
,
...
...
@@ -945,7 +839,7 @@ static LRESULT PCM_FormatSuggest(PACMDRVFORMATSUGGEST adfs)
PCM_GetFormatIndex
(
adfs
->
pwfxSrc
)
==
0xFFFFFFFF
)
{
WARN
(
"not possible
\n
"
);
return
ACMERR_NOTPOSSIBLE
;
}
}
/* is no suggestion for destination, then copy source value */
if
(
!
(
adfs
->
fdwSuggest
&
ACM_FORMATSUGGESTF_NCHANNELS
))
{
...
...
@@ -978,26 +872,6 @@ static LRESULT PCM_FormatSuggest(PACMDRVFORMATSUGGEST adfs)
}
/***********************************************************************
* PCM_Reset
*
*/
static
void
PCM_Reset
(
AcmPcmData
*
apd
,
int
srcNumBits
)
{
TRACE
(
"(%p, %d)
\n
"
,
apd
,
srcNumBits
);
apd
->
srcPos
=
0
;
apd
->
dstPos
=
0
;
/* initialize with neutral value */
if
(
srcNumBits
==
16
)
{
apd
->
last
[
0
].
s
=
0
;
apd
->
last
[
1
].
s
=
0
;
}
else
{
apd
->
last
[
0
].
b
=
(
BYTE
)
0x80
;
apd
->
last
[
1
].
b
=
(
BYTE
)
0x80
;
}
}
/***********************************************************************
* PCM_StreamOpen
*
*/
...
...
@@ -1010,12 +884,6 @@ static LRESULT PCM_StreamOpen(PACMDRVSTREAMINSTANCE adsi)
assert
(
!
(
adsi
->
fdwOpen
&
ACM_STREAMOPENF_ASYNC
));
if
(
PCM_GetFormatIndex
(
adsi
->
pwfxSrc
)
==
0xFFFFFFFF
||
PCM_GetFormatIndex
(
adsi
->
pwfxDst
)
==
0xFFFFFFFF
)
{
WARN
(
"not possible
\n
"
);
return
ACMERR_NOTPOSSIBLE
;
}
apd
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
AcmPcmData
));
if
(
apd
==
0
)
{
WARN
(
"no memory
\n
"
);
...
...
@@ -1034,9 +902,6 @@ static LRESULT PCM_StreamOpen(PACMDRVSTREAMINSTANCE adsi)
apd
->
cvt
.
cvtKeepRate
=
PCM_ConvertKeepRate
[
idx
];
}
else
{
adsi
->
fdwDriver
|=
PCM_RESAMPLE
;
apd
->
dstIncr
=
(
double
)(
adsi
->
pwfxSrc
->
nSamplesPerSec
)
/
(
double
)(
adsi
->
pwfxDst
->
nSamplesPerSec
);
PCM_Reset
(
apd
,
adsi
->
pwfxSrc
->
wBitsPerSample
);
apd
->
cvt
.
cvtChangeRate
=
PCM_ConvertChangeRate
[
idx
];
}
...
...
@@ -1131,15 +996,14 @@ static LRESULT PCM_StreamConvert(PACMDRVSTREAMINSTANCE adsi, PACMDRVSTREAMHEADER
*/
if
((
adsh
->
fdwConvert
&
ACM_STREAMCONVERTF_START
)
&&
(
adsi
->
fdwDriver
&
PCM_RESAMPLE
))
{
PCM_Reset
(
apd
,
adsi
->
pwfxSrc
->
wBitsPerSample
);
}
/* do the job */
if
(
adsi
->
fdwDriver
&
PCM_RESAMPLE
)
{
DWORD
nsrc2
=
nsrc
;
DWORD
ndst2
=
ndst
;
apd
->
cvt
.
cvtChangeRate
(
apd
,
adsh
->
pbSrc
,
&
nsrc2
,
adsh
->
pbDst
,
&
ndst2
);
apd
->
cvt
.
cvtChangeRate
((
DWORD
)
adsi
->
pwfxSrc
->
nSamplesPerSec
,
adsh
->
pbSrc
,
&
nsrc2
,
(
DWORD
)
adsi
->
pwfxDst
->
nSamplesPerSec
,
adsh
->
pbDst
,
&
ndst2
);
nsrc
-=
nsrc2
;
ndst
-=
ndst2
;
}
else
{
...
...
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