Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Mark Harris
Opus
Commits
5a0fae53
Commit
5a0fae53
authored
Dec 14, 2009
by
Jean-Marc Valin
Browse files
PLC: Added lag windowing and constraint to synthesis energy
parent
b8002a0e
Changes
2
Hide whitespace changes
Inline
Side-by-side
libcelt/celt.c
View file @
5a0fae53
...
...
@@ -54,6 +54,8 @@
#include "float_cast.h"
#include <stdarg.h>
#define LPC_ORDER 24
static
const
celt_word16
preemph
=
QCONST16
(
0
.
8
f
,
15
);
#ifdef FIXED_POINT
...
...
@@ -1089,6 +1091,10 @@ struct CELTDecoder {
celt_word16
*
oldBandE
;
#ifndef FIXED_POINT
celt_word16
*
lpc
;
#endif
int
last_pitch_index
;
int
loss_count
;
};
...
...
@@ -1163,9 +1169,16 @@ CELTDecoder *celt_decoder_create(const CELTMode *mode, int channels, int *error)
st
->
preemph_memD
=
(
celt_sig
*
)
celt_alloc
(
C
*
sizeof
(
celt_sig
));
#ifndef FIXED_POINT
st
->
lpc
=
(
celt_word16
*
)
celt_alloc
(
C
*
LPC_ORDER
*
sizeof
(
celt_word16
));
#endif
st
->
loss_count
=
0
;
if
((
st
->
decode_mem
!=
NULL
)
&&
(
st
->
out_mem
!=
NULL
)
&&
(
st
->
oldBandE
!=
NULL
)
&&
#ifndef FIXED_POINT
(
st
->
lpc
!=
NULL
)
&&
#endif
(
st
->
preemph_memD
!=
NULL
))
{
if
(
error
)
...
...
@@ -1208,6 +1221,10 @@ void celt_decoder_destroy(CELTDecoder *st)
celt_free
(
st
->
decode_mem
);
celt_free
(
st
->
oldBandE
);
celt_free
(
st
->
preemph_memD
);
#ifndef FIXED_POINT
celt_free
(
st
->
lpc
);
#endif
st
->
marker
=
DECODERFREED
;
...
...
@@ -1217,7 +1234,6 @@ void celt_decoder_destroy(CELTDecoder *st)
#ifndef FIXED_POINT
#include "plc.c"
#endif
#define LPC_ORDER 24
static
void
celt_decode_lost
(
CELTDecoder
*
restrict
st
,
celt_word16
*
restrict
pcm
)
{
int
c
,
N
;
...
...
@@ -1271,17 +1287,29 @@ static void celt_decode_lost(CELTDecoder * restrict st, celt_word16 * restrict p
float
e
[
MAX_PERIOD
];
float
exc
[
MAX_PERIOD
];
float
ac
[
LPC_ORDER
+
1
];
float
lpc
[
LPC_ORDER
];
float
decay
=
1
;
celt_word32
mem
[
LPC_ORDER
]
=
{
0
};
for
(
i
=
0
;
i
<
MAX_PERIOD
;
i
++
)
exc
[
i
]
=
st
->
out_mem
[
i
*
C
+
c
];
_celt_autocorr
(
exc
,
ac
,
st
->
mode
->
window
,
st
->
mode
->
overlap
,
LPC_ORDER
,
MAX_PERIOD
);
ac
[
0
]
*=
1
.
0001
;
_celt_lpc
(
lpc
,
ac
,
LPC_ORDER
);
fir
(
exc
,
lpc
,
exc
,
MAX_PERIOD
,
LPC_ORDER
,
mem
);
if
(
st
->
loss_count
==
0
)
{
_celt_autocorr
(
exc
,
ac
,
st
->
mode
->
window
,
st
->
mode
->
overlap
,
LPC_ORDER
,
MAX_PERIOD
);
/* Noise floor -50 dB */
ac
[
0
]
*=
1
.
00001
;
/* Lag windowing */
for
(
i
=
1
;
i
<=
LPC_ORDER
;
i
++
)
{
/*ac[i] *= exp(-.5*(2*M_PI*.002*i)*(2*M_PI*.002*i));*/
ac
[
i
]
-=
ac
[
i
]
*
(.
00
8
*
i
)
*
(.
00
8
*
i
);
}
_celt_lpc
(
st
->
lpc
,
ac
,
LPC_ORDER
);
}
fir
(
exc
,
st
->
lpc
,
exc
,
MAX_PERIOD
,
LPC_ORDER
,
mem
);
/* Check if the waveform is decaying (and if so how fast) */
{
...
...
@@ -1301,6 +1329,7 @@ static void celt_decode_lost(CELTDecoder * restrict st, celt_word16 * restrict p
decay
=
1
;
}
float
S1
=
0
;
/* Copy excitation, taking decay into account */
for
(
i
=
0
;
i
<
len
+
st
->
mode
->
overlap
;
i
++
)
{
...
...
@@ -1310,13 +1339,24 @@ 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
];
}
iir
(
e
,
st
->
lpc
,
e
,
len
+
st
->
mode
->
overlap
,
LPC_ORDER
,
mem
);
{
float
ratio
,
S2
=
0
;
for
(
i
=
0
;
i
<
len
+
overlap
;
i
++
)
S2
+=
e
[
i
]
*
e
[
i
];
ratio
=
sqrt
((
S1
+
1
)
/
(
S2
+
1
));
if
(
ratio
<
1
)
for
(
i
=
0
;
i
<
len
+
overlap
;
i
++
)
e
[
i
]
*=
ratio
;
}
for
(
i
=
0
;
i
<
MAX_PERIOD
+
st
->
mode
->
overlap
-
N
;
i
++
)
st
->
out_mem
[
C
*
i
+
c
]
=
st
->
out_mem
[
C
*
(
N
+
i
)
+
c
];
iir
(
e
,
lpc
,
e
,
len
+
st
->
mode
->
overlap
,
LPC_ORDER
,
mem
);
/* Apply TDAC to the concealed audio so that it blends with the
previous and next frames */
for
(
i
=
0
;
i
<
overlap
/
2
;
i
++
)
...
...
@@ -1338,17 +1378,7 @@ static void celt_decode_lost(CELTDecoder * restrict st, celt_word16 * restrict p
}
#endif
for
(
c
=
0
;
c
<
C
;
c
++
)
{
int
j
;
for
(
j
=
0
;
j
<
N
;
j
++
)
{
celt_sig
tmp
=
MAC16_32_Q15
(
st
->
out_mem
[
C
*
(
MAX_PERIOD
-
N
)
+
C
*
j
+
c
],
preemph
,
st
->
preemph_memD
[
c
]);
st
->
preemph_memD
[
c
]
=
tmp
;
pcm
[
C
*
j
+
c
]
=
SCALEOUT
(
SIG2WORD16
(
tmp
));
}
}
deemphasis
(
st
->
out_mem
,
pcm
,
N
,
C
,
preemph
,
st
->
preemph_memD
);
st
->
loss_count
++
;
...
...
libcelt/plc.c
View file @
5a0fae53
...
...
@@ -26,9 +26,9 @@ int p
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
,
8
));
r
=
DIV32_16
(
rr
+
PSHR32
(
error
,
1
),
ADD16
(
error
,
1
));
#else
r
=
rr
/
(
error
+
.
003
*
ac
[
0
]
);
r
=
rr
/
(
error
+
1e-15
);
#endif
/* Update LPC coefficients and total error */
lpc
[
i
]
=
r
;
...
...
@@ -42,6 +42,8 @@ int p
lpc
[
j
]
=
MAC16_16_P13
(
lpc
[
j
],
lpc
[
j
],
r
);
error
=
SUB16
(
error
,
MULT16_16_Q13
(
r
,
MULT16_16_Q13
(
error
,
r
)));
if
(
error
<
.
00001
*
ac
[
0
])
break
;
}
return
error
;
}
...
...
Write
Preview
Supports
Markdown
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