Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Mark Harris
Opus
Commits
d69c1cb3
Commit
d69c1cb3
authored
Dec 28, 2009
by
Jean-Marc Valin
Browse files
Making new PLC code work in fixed-point even though it's still using float
arithmetic.
parent
aec0ee41
Changes
2
Hide whitespace changes
Inline
Side-by-side
libcelt/celt.c
View file @
d69c1cb3
...
...
@@ -55,6 +55,9 @@
#include <stdarg.h>
#define LPC_ORDER 24
#if !defined(FIXED_POINT) || defined(NEW_PLC)
#include "plc.c"
#endif
static
const
celt_word16
preemph
=
QCONST16
(
0
.
8
f
,
15
);
...
...
@@ -1092,8 +1095,8 @@ struct CELTDecoder {
celt_word16
*
oldBandE
;
#if
n
def
FIXED_POINT
celt_word16
*
lpc
;
#ifdef
NEW_PLC
float
*
lpc
;
#endif
int
last_pitch_index
;
...
...
@@ -1170,14 +1173,14 @@ CELTDecoder *celt_decoder_create(const CELTMode *mode, int channels, int *error)
st
->
preemph_memD
=
(
celt_sig
*
)
celt_alloc
(
C
*
sizeof
(
celt_sig
));
#if
n
def
FIXED_POINT
st
->
lpc
=
(
celt_word16
*
)
celt_alloc
(
C
*
LPC_ORDER
*
sizeof
(
celt_word16
));
#ifdef
NEW_PLC
st
->
lpc
=
(
float
*
)
celt_alloc
(
C
*
LPC_ORDER
*
sizeof
(
float
));
#endif
st
->
loss_count
=
0
;
if
((
st
->
decode_mem
!=
NULL
)
&&
(
st
->
out_mem
!=
NULL
)
&&
(
st
->
oldBandE
!=
NULL
)
&&
#if
n
def
FIXED_POINT
#ifdef
NEW_PLC
(
st
->
lpc
!=
NULL
)
&&
#endif
(
st
->
preemph_memD
!=
NULL
))
...
...
@@ -1223,7 +1226,7 @@ void celt_decoder_destroy(CELTDecoder *st)
celt_free
(
st
->
oldBandE
);
celt_free
(
st
->
preemph_memD
);
#if
n
def
FIXED_POINT
#ifdef
NEW_PLC
celt_free
(
st
->
lpc
);
#endif
...
...
@@ -1232,9 +1235,6 @@ void celt_decoder_destroy(CELTDecoder *st)
celt_free
(
st
);
}
#ifndef FIXED_POINT
#include "plc.c"
#endif
static
void
celt_decode_lost
(
CELTDecoder
*
restrict
st
,
celt_word16
*
restrict
pcm
)
{
int
c
,
N
;
...
...
@@ -1270,7 +1270,7 @@ static void celt_decode_lost(CELTDecoder * restrict st, celt_word16 * restrict p
fade
=
0
;
}
#ifdef
FIXED_POINT
#if
n
def
NEW_PLC
offset
=
MAX_PERIOD
-
pitch_index
;
ALLOC
(
freq
,
C
*
N
,
celt_sig
);
/**< Interleaved signal MDCTs */
while
(
offset
+
len
>=
MAX_PERIOD
)
...
...
@@ -1285,12 +1285,12 @@ static void celt_decode_lost(CELTDecoder * restrict st, celt_word16 * restrict p
#else
for
(
c
=
0
;
c
<
C
;
c
++
)
{
float
e
[
MAX_PERIOD
];
celt_word32
e
[
MAX_PERIOD
];
float
exc
[
MAX_PERIOD
];
float
ac
[
LPC_ORDER
+
1
];
float
decay
=
1
;
float
S1
=
0
;
celt_word32
mem
[
LPC_ORDER
]
=
{
0
};
float
mem
[
LPC_ORDER
]
=
{
0
};
offset
=
MAX_PERIOD
-
pitch_index
;
for
(
i
=
0
;
i
<
MAX_PERIOD
;
i
++
)
...
...
@@ -1341,7 +1341,7 @@ static void celt_decode_lost(CELTDecoder * restrict st, celt_word16 * restrict p
decay
*=
decay
;
}
e
[
i
]
=
decay
*
exc
[
offset
+
i
];
S1
+=
st
->
out_mem
[
offset
+
i
]
*
st
->
out_mem
[
offset
+
i
];
S1
+=
st
->
out_mem
[
offset
+
i
]
*
1
.
*
st
->
out_mem
[
offset
+
i
];
}
iir
(
e
,
st
->
lpc
,
e
,
len
+
st
->
mode
->
overlap
,
LPC_ORDER
,
mem
);
...
...
@@ -1349,7 +1349,7 @@ static void celt_decode_lost(CELTDecoder * restrict st, celt_word16 * restrict p
{
float
ratio
,
S2
=
0
;
for
(
i
=
0
;
i
<
len
+
overlap
;
i
++
)
S2
+=
e
[
i
]
*
e
[
i
];
S2
+=
e
[
i
]
*
1
.
*
e
[
i
];
ratio
=
sqrt
((
S1
+
1
)
/
(
S2
+
1
));
if
(
ratio
<
1
)
for
(
i
=
0
;
i
<
len
+
overlap
;
i
++
)
...
...
@@ -1363,20 +1363,20 @@ static void celt_decode_lost(CELTDecoder * restrict st, celt_word16 * restrict p
previous and next frames */
for
(
i
=
0
;
i
<
overlap
/
2
;
i
++
)
{
float
tmp1
,
tmp2
;
tmp1
=
e
[
i
]
*
st
->
mode
->
window
[
i
]
-
e
[
overlap
-
i
-
1
]
*
st
->
mode
->
window
[
overlap
-
i
-
1
];
tmp2
=
e
[
N
+
overlap
-
1
-
i
]
*
st
->
mode
->
window
[
i
]
+
e
[
N
+
i
]
*
st
->
mode
->
window
[
overlap
-
i
-
1
];
tmp1
*
=
fade
;
tmp2
*
=
fade
;
st
->
out_mem
[
C
*
(
MAX_PERIOD
+
i
)
+
c
]
=
tmp2
*
st
->
mode
->
window
[
overlap
-
i
-
1
];
st
->
out_mem
[
C
*
(
MAX_PERIOD
+
overlap
-
i
-
1
)
+
c
]
=
tmp2
*
st
->
mode
->
window
[
i
];
st
->
out_mem
[
C
*
(
MAX_PERIOD
-
N
+
i
)
+
c
]
+=
tmp1
*
st
->
mode
->
window
[
i
];
st
->
out_mem
[
C
*
(
MAX_PERIOD
-
N
+
overlap
-
i
-
1
)
+
c
]
-=
tmp1
*
st
->
mode
->
window
[
overlap
-
i
-
1
];
celt_word32
tmp1
,
tmp2
;
tmp1
=
MULT16_32_Q15
(
st
->
mode
->
window
[
i
]
,
e
[
i
])
-
MULT16_32_Q15
(
st
->
mode
->
window
[
overlap
-
i
-
1
]
,
e
[
overlap
-
i
-
1
])
;
tmp2
=
MULT16_32_Q15
(
st
->
mode
->
window
[
i
]
,
e
[
N
+
overlap
-
1
-
i
])
+
MULT16_32_Q15
(
st
->
mode
->
window
[
overlap
-
i
-
1
]
,
e
[
N
+
i
])
;
tmp1
=
MULT16_32_Q15
(
fade
,
tmp1
)
;
tmp2
=
MULT16_32_Q15
(
fade
,
tmp2
)
;
st
->
out_mem
[
C
*
(
MAX_PERIOD
+
i
)
+
c
]
=
MULT16_32_Q15
(
st
->
mode
->
window
[
overlap
-
i
-
1
]
,
tmp2
)
;
st
->
out_mem
[
C
*
(
MAX_PERIOD
+
overlap
-
i
-
1
)
+
c
]
=
MULT16_32_Q15
(
st
->
mode
->
window
[
i
]
,
tmp2
)
;
st
->
out_mem
[
C
*
(
MAX_PERIOD
-
N
+
i
)
+
c
]
+=
MULT16_32_Q15
(
st
->
mode
->
window
[
i
]
,
tmp1
)
;
st
->
out_mem
[
C
*
(
MAX_PERIOD
-
N
+
overlap
-
i
-
1
)
+
c
]
-=
MULT16_32_Q15
(
st
->
mode
->
window
[
overlap
-
i
-
1
]
,
tmp1
)
;
}
for
(
i
=
0
;
i
<
N
-
overlap
;
i
++
)
st
->
out_mem
[
C
*
(
MAX_PERIOD
-
N
+
overlap
+
i
)
+
c
]
=
fade
*
e
[
overlap
+
i
];
st
->
out_mem
[
C
*
(
MAX_PERIOD
-
N
+
overlap
+
i
)
+
c
]
=
MULT16_32_Q15
(
fade
,
e
[
overlap
+
i
]
)
;
}
#endif
...
...
libcelt/plc.c
View file @
d69c1cb3
#ifndef NEW_PLC
#define NEW_PLC
#endif
celt_word32
_celt_lpc
(
celt_word16
*
lpc
,
/* out: [0...p-1] LPC coefficients */
const
celt_word16
*
ac
,
/* in: [0...p] autocorrelation values */
float
_celt_lpc
(
float
*
lpc
,
/* out: [0...p-1] LPC coefficients */
const
float
*
ac
,
/* in: [0...p] autocorrelation values */
int
p
)
{
int
i
,
j
;
celt_word16
r
;
celt_word16
error
=
ac
[
0
];
float
r
;
float
error
=
ac
[
0
];
if
(
ac
[
0
]
==
0
)
{
...
...
@@ -22,38 +23,34 @@ int p
for
(
i
=
0
;
i
<
p
;
i
++
)
{
/* Sum up this iteration's reflection coefficient */
celt_word32
rr
=
NEG32
(
SHL32
(
EXTEND32
(
ac
[
i
+
1
]
),
13
))
;
float
rr
=
-
ac
[
i
+
1
];
for
(
j
=
0
;
j
<
i
;
j
++
)
rr
=
SUB32
(
rr
,
MULT16_16
(
lpc
[
j
],
ac
[
i
-
j
]));
#ifdef FIXED_POINT
r
=
DIV32_16
(
rr
+
PSHR32
(
error
,
1
),
ADD16
(
error
,
1
));
#else
rr
=
rr
-
lpc
[
j
]
*
ac
[
i
-
j
];
r
=
rr
/
(
error
+
1e-15
);
#endif
/* Update LPC coefficients and total error */
lpc
[
i
]
=
r
;
for
(
j
=
0
;
j
<
i
>>
1
;
j
++
)
{
celt_word16
tmp
=
lpc
[
j
];
lpc
[
j
]
=
MAC16_16_P13
(
lpc
[
j
],
r
,
lpc
[
i
-
1
-
j
]
)
;
lpc
[
i
-
1
-
j
]
=
MAC16_16_P13
(
lpc
[
i
-
1
-
j
]
,
r
,
tmp
)
;
float
tmp
=
lpc
[
j
];
lpc
[
j
]
=
lpc
[
j
]
+
r
*
lpc
[
i
-
1
-
j
];
lpc
[
i
-
1
-
j
]
=
lpc
[
i
-
1
-
j
]
+
r
*
tmp
;
}
if
(
i
&
1
)
lpc
[
j
]
=
MAC16_16_P13
(
lpc
[
j
]
,
lpc
[
j
]
,
r
)
;
lpc
[
j
]
=
lpc
[
j
]
+
lpc
[
j
]
*
r
;
error
=
SUB16
(
error
,
MULT16_16_Q13
(
r
,
MULT16_16_Q13
(
error
,
r
)))
;
error
=
error
-
r
*
r
*
error
;
if
(
error
<
.
00001
*
ac
[
0
])
break
;
}
return
error
;
}
void
fir
(
const
celt_word16
*
x
,
const
celt_word16
*
num
,
celt_word16
*
y
,
void
fir
(
const
float
*
x
,
const
float
*
num
,
float
*
y
,
int
N
,
int
ord
,
celt_word32
*
mem
)
float
*
mem
)
{
int
i
,
j
;
...
...
@@ -73,12 +70,12 @@ void fir(const celt_word16 *x,
}
}
void
iir
(
const
celt_word
16
*
x
,
const
celt_word16
*
den
,
celt_word
16
*
y
,
void
iir
(
const
celt_word
32
*
x
,
const
float
*
den
,
celt_word
32
*
y
,
int
N
,
int
ord
,
celt_word32
*
mem
)
float
*
mem
)
{
int
i
,
j
;
for
(
i
=
0
;
i
<
N
;
i
++
)
...
...
@@ -98,9 +95,9 @@ void iir(const celt_word16 *x,
}
void
_celt_autocorr
(
const
celt_word16
*
x
,
/* in: [0...n-1] samples x */
const
float
*
x
,
/* in: [0...n-1] samples x */
float
*
ac
,
/* out: [0...lag-1] ac values */
const
float
*
window
,
const
celt_word16
*
window
,
int
overlap
,
int
lag
,
int
n
...
...
@@ -115,8 +112,8 @@ void _celt_autocorr(
xx
[
i
]
=
x
[
i
];
for
(
i
=
0
;
i
<
overlap
;
i
++
)
{
xx
[
i
]
*=
window
[
i
];
xx
[
n
-
i
-
1
]
*=
window
[
i
];
xx
[
i
]
*=
(
1
.
/
Q15ONE
)
*
window
[
i
];
xx
[
n
-
i
-
1
]
*=
(
1
.
/
Q15ONE
)
*
window
[
i
];
}
while
(
lag
>=
0
)
{
...
...
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