Commit 200de8c6 authored by Kenan Gillet's avatar Kenan Gillet Committed by Vitor Sessak

More OKed parts of the QCELP decoder

patch by Kenan Gillet, kenan.gillet gmail com

Originally committed as revision 15802 to svn://svn.ffmpeg.org/ffmpeg/trunk
parent e22192ec
...@@ -378,6 +378,38 @@ static const qcelp_vector * const qcelp_lspvq[5] = { ...@@ -378,6 +378,38 @@ static const qcelp_vector * const qcelp_lspvq[5] = {
qcelp_lspvq5 qcelp_lspvq5
}; };
/**
* the final gain scalefactor before clipping into a usable output float
*/
#define QCELP_SCALE 8192.
/**
* table for computing Ga (decoded linear codebook gain magnitude)
*
* @note The table could fit in int16_t in x*8 form, but it seems
* to be slower on x86
*
* TIA/EIA/IS-733 2.4.6.2.1-3
*/
static const float qcelp_g12ga[61] = {
1.000/QCELP_SCALE, 1.125/QCELP_SCALE, 1.250/QCELP_SCALE, 1.375/QCELP_SCALE,
1.625/QCELP_SCALE, 1.750/QCELP_SCALE, 2.000/QCELP_SCALE, 2.250/QCELP_SCALE,
2.500/QCELP_SCALE, 2.875/QCELP_SCALE, 3.125/QCELP_SCALE, 3.500/QCELP_SCALE,
4.000/QCELP_SCALE, 4.500/QCELP_SCALE, 5.000/QCELP_SCALE, 5.625/QCELP_SCALE,
6.250/QCELP_SCALE, 7.125/QCELP_SCALE, 8.000/QCELP_SCALE, 8.875/QCELP_SCALE,
10.000/QCELP_SCALE, 11.250/QCELP_SCALE, 12.625/QCELP_SCALE, 14.125/QCELP_SCALE,
15.875/QCELP_SCALE, 17.750/QCELP_SCALE, 20.000/QCELP_SCALE, 22.375/QCELP_SCALE,
25.125/QCELP_SCALE, 28.125/QCELP_SCALE, 31.625/QCELP_SCALE, 35.500/QCELP_SCALE,
39.750/QCELP_SCALE, 44.625/QCELP_SCALE, 50.125/QCELP_SCALE, 56.250/QCELP_SCALE,
63.125/QCELP_SCALE, 70.750/QCELP_SCALE, 79.375/QCELP_SCALE, 89.125/QCELP_SCALE,
100.000/QCELP_SCALE, 112.250/QCELP_SCALE, 125.875/QCELP_SCALE, 141.250/QCELP_SCALE,
158.500/QCELP_SCALE, 177.875/QCELP_SCALE, 199.500/QCELP_SCALE, 223.875/QCELP_SCALE,
251.250/QCELP_SCALE, 281.875/QCELP_SCALE, 316.250/QCELP_SCALE, 354.875/QCELP_SCALE,
398.125/QCELP_SCALE, 446.625/QCELP_SCALE, 501.125/QCELP_SCALE, 563.375/QCELP_SCALE,
631.000/QCELP_SCALE, 708.000/QCELP_SCALE, 794.375/QCELP_SCALE, 891.250/QCELP_SCALE,
1000.000/QCELP_SCALE};
/** /**
* circular codebook for rate 1 frames in x*100 form * circular codebook for rate 1 frames in x*100 form
* *
...@@ -428,4 +460,18 @@ static const int8_t qcelp_rate_half_codebook[128] = { ...@@ -428,4 +460,18 @@ static const int8_t qcelp_rate_half_codebook[128] = {
}; };
#define QCELP_RATE_HALF_CODEBOOK_RATIO 0.5 #define QCELP_RATE_HALF_CODEBOOK_RATIO 0.5
/**
* table for impulse response of BPF used to filter
* the white excitation for framerate 1/4 synthesis
*
* Only half the tables are needed because of symetry.
*
* TIA/EIA/IS-733 2.4.8.1.2-1.1
*/
static const double qcelp_rnd_fir_coefs[11] = {
-1.344519e-1, 1.735384e-2, -6.905826e-2, 2.434368e-2,
-8.210701e-2, 3.041388e-2, -9.251384e-2, 3.501983e-2,
-9.918777e-2, 3.749518e-2, 8.985137e-1
};
#endif /* AVCODEC_QCELPDATA_H */ #endif /* AVCODEC_QCELPDATA_H */
...@@ -103,6 +103,39 @@ static const float *do_pitchfilter(float memory[303], ...@@ -103,6 +103,39 @@ static const float *do_pitchfilter(float memory[303],
return memory + 143; return memory + 143;
} }
/**
* Interpolates LSP frequencies and computes LPC coefficients
* for a given framerate & pitch subframe.
*
* TIA/EIA/IS-733 2.4.3.3.4
*
* @param q the context
* @param curr_lspf LSP frequencies vector of the current frame
* @param lpc float vector for the resulting LPC
* @param subframe_num frame number in decoded stream
*/
void interpolate_lpc(QCELPContext *q,
const float *curr_lspf,
float *lpc,
const int subframe_num) {
float interpolated_lspf[10];
float weight;
if (q->framerate >= RATE_QUARTER) {
weight = 0.25 * (subframe_num + 1);
} else if (q->framerate == RATE_OCTAVE && !subframe_num) {
weight = 0.625;
} else {
weight = 1.0;
}
if (weight != 1.0) {
weighted_vector_sumf(interpolated_lspf, curr_lspf, q->prev_lspf, weight, 1.0 - weight, 10);
lspf2lpc(q, interpolated_lspf, lpc);
} else if (q->framerate >= RATE_QUARTER || (q->framerate == I_F_Q && !subframe_num))
lspf2lpc(q, curr_lspf, lpc);
}
static int buf_size2framerate(const int buf_size) { static int buf_size2framerate(const int buf_size) {
switch (buf_size) { switch (buf_size) {
case 35: case 35:
...@@ -123,3 +156,14 @@ static void warn_insufficient_frame_quality(AVCodecContext *avctx, ...@@ -123,3 +156,14 @@ static void warn_insufficient_frame_quality(AVCodecContext *avctx,
const char *message) { const char *message) {
av_log(avctx, AV_LOG_WARNING, "Frame #%d, IFQ: %s\n", avctx->frame_number, message); av_log(avctx, AV_LOG_WARNING, "Frame #%d, IFQ: %s\n", avctx->frame_number, message);
} }
AVCodec qcelp_decoder =
{
.name = "qcelp",
.type = CODEC_TYPE_AUDIO,
.id = CODEC_ID_QCELP,
.init = qcelp_decode_init,
.decode = qcelp_decode_frame,
.priv_data_size = sizeof(QCELPContext),
.long_name = NULL_IF_CONFIG_SMALL("QCELP / PureVoice"),
};
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment