mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
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
This commit is contained in:
parent
e22192ecc3
commit
200de8c6bb
@ -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] = {
|
|||||||
};
|
};
|
||||||
#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],
|
|||||||
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,
|
|||||||
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"),
|
||||||
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user