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 15901 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
31fb59ec98
commit
148c31b9c2
@ -390,6 +390,16 @@ static const qcelp_vector * const qcelp_lspvq[5] = {
|
||||
*/
|
||||
#define QCELP_SCALE 8192.
|
||||
|
||||
/**
|
||||
* the upper boundary of the clipping, depends on QCELP_SCALE
|
||||
*/
|
||||
#define QCELP_CLIP_UPPER_BOUND (8191.75/8192.)
|
||||
|
||||
/**
|
||||
* the lower boundary of the clipping, depends on QCELP_SCALE
|
||||
*/
|
||||
#define QCELP_CLIP_LOWER_BOUND -1.
|
||||
|
||||
/**
|
||||
* table for computing Ga (decoded linear codebook gain magnitude)
|
||||
*
|
||||
@ -470,7 +480,7 @@ static const int8_t qcelp_rate_half_codebook[128] = {
|
||||
/**
|
||||
* sqrt(1.887) is the maximum of the pseudorandom
|
||||
* white sequence used to generate the scaled codebook
|
||||
* vector for framerate 1/4.
|
||||
* vector for bitrate 1/4.
|
||||
*
|
||||
* TIA/EIA/IS-733 2.4.8.1.2
|
||||
*/
|
||||
@ -478,7 +488,7 @@ static const int8_t qcelp_rate_half_codebook[128] = {
|
||||
|
||||
/**
|
||||
* table for impulse response of BPF used to filter
|
||||
* the white excitation for framerate 1/4 synthesis
|
||||
* the white excitation for bitrate 1/4 synthesis
|
||||
*
|
||||
* Only half the tables are needed because of symmetry.
|
||||
*
|
||||
@ -490,4 +500,20 @@ static const double qcelp_rnd_fir_coefs[11] = {
|
||||
-9.918777e-2, 3.749518e-2, 8.985137e-1
|
||||
};
|
||||
|
||||
/**
|
||||
* This spread factor is used, for bitrate 1/8 and I_F_Q,
|
||||
* to force the LSP frequencies to be at least 80 Hz apart.
|
||||
*
|
||||
* TIA/EIA/IS-733 2.4.3.3.2
|
||||
*/
|
||||
#define QCELP_LSP_SPREAD_FACTOR 0.02
|
||||
|
||||
/**
|
||||
* predictor coefficient for the conversion of LSP codes
|
||||
* to LSP frequencies for 1/8 and I_F_Q
|
||||
*
|
||||
* TIA/EIA/IS-733 2.4.3.2.7-2
|
||||
*/
|
||||
#define QCELP_LSP_OCTAVE_PREDICTOR 29.0/32
|
||||
|
||||
#endif /* AVCODEC_QCELPDATA_H */
|
||||
|
@ -68,6 +68,116 @@ static av_cold int qcelp_decode_init(AVCodecContext *avctx) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes the 10 quantized LSP frequencies from the LSPV/LSP
|
||||
* transmission codes of any bitrate and checks for badly received packets.
|
||||
*
|
||||
* @param q the context
|
||||
* @param lspf line spectral pair frequencies
|
||||
*
|
||||
* @return 0 on success, -1 if the packet is badly received
|
||||
*
|
||||
* TIA/EIA/IS-733 2.4.3.2.6.2-2, 2.4.8.7.3
|
||||
*/
|
||||
static int decode_lspf(QCELPContext *q,
|
||||
float *lspf) {
|
||||
int i;
|
||||
float tmp_lspf;
|
||||
|
||||
if (q->bitrate == RATE_OCTAVE ||
|
||||
q->bitrate == I_F_Q) {
|
||||
float smooth;
|
||||
const float *predictors = (q->prev_bitrate != RATE_OCTAVE &&
|
||||
q->prev_bitrate != I_F_Q ? q->prev_lspf
|
||||
: q->predictor_lspf);
|
||||
|
||||
if (q->bitrate == RATE_OCTAVE) {
|
||||
q->octave_count++;
|
||||
|
||||
for (i = 0; i < 10; i++) {
|
||||
q->predictor_lspf[i] =
|
||||
lspf[i] = (q->lspv[i] ? QCELP_LSP_SPREAD_FACTOR
|
||||
: -QCELP_LSP_SPREAD_FACTOR)
|
||||
+ predictors[i] * QCELP_LSP_OCTAVE_PREDICTOR
|
||||
+ (i + 1) * ((1 - QCELP_LSP_OCTAVE_PREDICTOR)/11);
|
||||
}
|
||||
smooth = (q->octave_count < 10 ? .875 : 0.1);
|
||||
} else {
|
||||
float erasure_coeff = QCELP_LSP_OCTAVE_PREDICTOR;
|
||||
|
||||
assert(q->bitrate == I_F_Q);
|
||||
|
||||
if (q->erasure_count > 1)
|
||||
erasure_coeff *= (q->erasure_count < 4 ? 0.9 : 0.7);
|
||||
|
||||
for (i = 0; i < 10; i++) {
|
||||
q->predictor_lspf[i] =
|
||||
lspf[i] = (i + 1) * ( 1 - erasure_coeff)/11
|
||||
+ erasure_coeff * predictors[i];
|
||||
}
|
||||
smooth = 0.125;
|
||||
}
|
||||
|
||||
// Check the stability of the LSP frequencies.
|
||||
lspf[0] = FFMAX(lspf[0], QCELP_LSP_SPREAD_FACTOR);
|
||||
for (i = 1; i < 10; i++)
|
||||
lspf[i] = FFMAX(lspf[i], (lspf[i-1] + QCELP_LSP_SPREAD_FACTOR));
|
||||
|
||||
lspf[9] = FFMIN(lspf[9], (1.0 - QCELP_LSP_SPREAD_FACTOR));
|
||||
for (i = 9; i > 0; i--)
|
||||
lspf[i-1] = FFMIN(lspf[i-1], (lspf[i] - QCELP_LSP_SPREAD_FACTOR));
|
||||
|
||||
// Low-pass filter the LSP frequencies.
|
||||
weighted_vector_sumf(lspf, lspf, q->prev_lspf, smooth, 1.0 - smooth, 10);
|
||||
} else {
|
||||
q->octave_count = 0;
|
||||
|
||||
tmp_lspf = 0.;
|
||||
for (i = 0; i < 5 ; i++) {
|
||||
lspf[2*i+0] = tmp_lspf += qcelp_lspvq[i][q->lspv[i]][0] * 0.0001;
|
||||
lspf[2*i+1] = tmp_lspf += qcelp_lspvq[i][q->lspv[i]][1] * 0.0001;
|
||||
}
|
||||
|
||||
// Check for badly received packets.
|
||||
if (q->bitrate == RATE_QUARTER) {
|
||||
if (lspf[9] <= .70 || lspf[9] >= .97)
|
||||
return -1;
|
||||
for (i = 3; i < 10; i++)
|
||||
if (fabs(lspf[i] - lspf[i-2]) < .08)
|
||||
return -1;
|
||||
} else {
|
||||
if (lspf[9] <= .66 || lspf[9] >= .985)
|
||||
return -1;
|
||||
for (i = 4; i < 10; i++)
|
||||
if (fabs(lspf[i] - lspf[i-4]) < .0931)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the received packet is Rate 1/4 a further sanity check is made of the codebook gain.
|
||||
*
|
||||
* @param cbgain the unpacked cbgain array
|
||||
* @return -1 if the sanity check fails, 0 otherwise
|
||||
*
|
||||
* TIA/EIA/IS-733 2.4.8.7.3
|
||||
*/
|
||||
static int codebook_sanity_check_for_rate_quarter(const uint8_t *cbgain) {
|
||||
int i, prev_diff=0;
|
||||
|
||||
for (i = 1; i < 5; i++) {
|
||||
int diff = cbgain[i] - cbgain[i-1];
|
||||
if (FFABS(diff) > 10)
|
||||
return -1;
|
||||
else if (FFABS(diff - prev_diff) > 12)
|
||||
return -1;
|
||||
prev_diff = diff;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the scaled codebook vector Cdn From INDEX and GAIN
|
||||
* for all rates.
|
||||
@ -96,7 +206,7 @@ static void compute_svector(const QCELPContext *q,
|
||||
uint16_t cbseed, cindex;
|
||||
float *rnd, tmp_gain, fir_filter_value;
|
||||
|
||||
switch (q->framerate) {
|
||||
switch (q->bitrate) {
|
||||
case RATE_FULL:
|
||||
for (i = 0; i < 16; i++) {
|
||||
tmp_gain = gain[i] * QCELP_RATE_FULL_CODEBOOK_RATIO;
|
||||
@ -248,7 +358,7 @@ static const float *do_pitchfilter(float memory[303], const float v_in[160],
|
||||
|
||||
/**
|
||||
* Interpolates LSP frequencies and computes LPC coefficients
|
||||
* for a given framerate & pitch subframe.
|
||||
* for a given bitrate & pitch subframe.
|
||||
*
|
||||
* TIA/EIA/IS-733 2.4.3.3.4
|
||||
*
|
||||
@ -263,9 +373,9 @@ void interpolate_lpc(QCELPContext *q, const float *curr_lspf, float *lpc,
|
||||
float interpolated_lspf[10];
|
||||
float weight;
|
||||
|
||||
if(q->framerate >= RATE_QUARTER)
|
||||
if(q->bitrate >= RATE_QUARTER)
|
||||
weight = 0.25 * (subframe_num + 1);
|
||||
else if(q->framerate == RATE_OCTAVE && !subframe_num)
|
||||
else if(q->bitrate == RATE_OCTAVE && !subframe_num)
|
||||
weight = 0.625;
|
||||
else
|
||||
weight = 1.0;
|
||||
@ -275,11 +385,11 @@ void interpolate_lpc(QCELPContext *q, const float *curr_lspf, float *lpc,
|
||||
weighted_vector_sumf(interpolated_lspf, curr_lspf, q->prev_lspf,
|
||||
weight, 1.0 - weight, 10);
|
||||
qcelp_lspf2lpc(interpolated_lspf, lpc);
|
||||
}else if(q->framerate >= RATE_QUARTER || (q->framerate == I_F_Q && !subframe_num))
|
||||
}else if(q->bitrate >= RATE_QUARTER || (q->bitrate == I_F_Q && !subframe_num))
|
||||
qcelp_lspf2lpc(curr_lspf, lpc);
|
||||
}
|
||||
|
||||
static int buf_size2framerate(const int buf_size)
|
||||
static int buf_size2bitrate(const int buf_size)
|
||||
{
|
||||
switch(buf_size)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user