@ -117,18 +117,15 @@ static int decode_lspf(QCELPContext *q, float *lspf)
float tmp_lspf , smooth , erasure_coeff ;
const float * predictors ;
if ( q - > bitrate = = RATE_OCTAVE | | q - > bitrate = = I_F_Q )
{
if ( q - > bitrate = = RATE_OCTAVE | | q - > bitrate = = I_F_Q ) {
predictors = ( q - > prev_bitrate ! = RATE_OCTAVE & &
q - > prev_bitrate ! = I_F_Q ?
q - > prev_lspf : q - > predictor_lspf ) ;
if ( q - > bitrate = = RATE_OCTAVE )
{
if ( q - > bitrate = = RATE_OCTAVE ) {
q - > octave_count + + ;
for ( i = 0 ; i < 10 ; i + + )
{
for ( i = 0 ; i < 10 ; i + + ) {
q - > predictor_lspf [ i ] =
lspf [ i ] = ( q - > frame . lspv [ i ] ? QCELP_LSP_SPREAD_FACTOR
: - QCELP_LSP_SPREAD_FACTOR )
@ -136,8 +133,7 @@ static int decode_lspf(QCELPContext *q, float *lspf)
+ ( i + 1 ) * ( ( 1 - QCELP_LSP_OCTAVE_PREDICTOR ) / 11 ) ;
}
smooth = ( q - > octave_count < 10 ? .875 : 0.1 ) ;
} else
{
} else {
erasure_coeff = QCELP_LSP_OCTAVE_PREDICTOR ;
assert ( q - > bitrate = = I_F_Q ) ;
@ -145,8 +141,7 @@ static int decode_lspf(QCELPContext *q, float *lspf)
if ( q - > erasure_count > 1 )
erasure_coeff * = ( q - > erasure_count < 4 ? 0.9 : 0.7 ) ;
for ( i = 0 ; i < 10 ; i + + )
{
for ( i = 0 ; i < 10 ; i + + ) {
q - > predictor_lspf [ i ] =
lspf [ i ] = ( i + 1 ) * ( 1 - erasure_coeff ) / 11
+ erasure_coeff * predictors [ i ] ;
@ -165,27 +160,23 @@ static int decode_lspf(QCELPContext *q, float *lspf)
// Low-pass filter the LSP frequencies.
ff_weighted_vector_sumf ( lspf , lspf , q - > prev_lspf , smooth , 1.0 - smooth , 10 ) ;
} else
{
} else {
q - > octave_count = 0 ;
tmp_lspf = 0. ;
for ( i = 0 ; i < 5 ; i + + )
{
for ( i = 0 ; i < 5 ; i + + ) {
lspf [ 2 * i + 0 ] = tmp_lspf + = qcelp_lspvq [ i ] [ q - > frame . lspv [ i ] ] [ 0 ] * 0.0001 ;
lspf [ 2 * i + 1 ] = tmp_lspf + = qcelp_lspvq [ i ] [ q - > frame . lspv [ i ] ] [ 1 ] * 0.0001 ;
}
// Check for badly received packets.
if ( q - > bitrate = = RATE_QUARTER )
{
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
{
} else {
if ( lspf [ 9 ] < = .66 | | lspf [ 9 ] > = .985 )
return - 1 ;
for ( i = 4 ; i < 10 ; i + + )
@ -209,26 +200,21 @@ static void decode_gain_and_index(QCELPContext *q,
int i , subframes_count , g1 [ 16 ] ;
float slope ;
if ( q - > bitrate > = RATE_QUARTER )
{
switch ( q - > bitrate )
{
if ( q - > bitrate > = RATE_QUARTER ) {
switch ( q - > bitrate ) {
case RATE_FULL : subframes_count = 16 ; break ;
case RATE_HALF : subframes_count = 4 ; break ;
default : subframes_count = 5 ;
}
for ( i = 0 ; i < subframes_count ; i + + )
{
for ( i = 0 ; i < subframes_count ; i + + ) {
g1 [ i ] = 4 * q - > frame . cbgain [ i ] ;
if ( q - > bitrate = = RATE_FULL & & ! ( ( i + 1 ) & 3 ) )
{
if ( q - > bitrate = = RATE_FULL & & ! ( ( i + 1 ) & 3 ) ) {
g1 [ i ] + = av_clip ( ( g1 [ i - 1 ] + g1 [ i - 2 ] + g1 [ i - 3 ] ) / 3 - 6 , 0 , 32 ) ;
}
gain [ i ] = qcelp_g12ga [ g1 [ i ] ] ;
if ( q - > frame . cbsign [ i ] )
{
if ( q - > frame . cbsign [ i ] ) {
gain [ i ] = - gain [ i ] ;
q - > frame . cindex [ i ] = ( q - > frame . cindex [ i ] - 89 ) & 127 ;
}
@ -238,8 +224,7 @@ static void decode_gain_and_index(QCELPContext *q,
q - > prev_g1 [ 1 ] = g1 [ i - 1 ] ;
q - > last_codebook_gain = qcelp_g12ga [ g1 [ i - 1 ] ] ;
if ( q - > bitrate = = RATE_QUARTER )
{
if ( q - > bitrate = = RATE_QUARTER ) {
// Provide smoothing of the unvoiced excitation energy.
gain [ 7 ] = gain [ 4 ] ;
gain [ 6 ] = 0.4 * gain [ 3 ] + 0.6 * gain [ 4 ] ;
@ -249,20 +234,16 @@ static void decode_gain_and_index(QCELPContext *q,
gain [ 2 ] = gain [ 1 ] ;
gain [ 1 ] = 0.6 * gain [ 0 ] + 0.4 * gain [ 1 ] ;
}
} else if ( q - > bitrate ! = SILENCE )
{
if ( q - > bitrate = = RATE_OCTAVE )
{
} else if ( q - > bitrate ! = SILENCE ) {
if ( q - > bitrate = = RATE_OCTAVE ) {
g1 [ 0 ] = 2 * q - > frame . cbgain [ 0 ]
+ av_clip ( ( q - > prev_g1 [ 0 ] + q - > prev_g1 [ 1 ] ) / 2 - 5 , 0 , 54 ) ;
subframes_count = 8 ;
} else
{
} else {
assert ( q - > bitrate = = I_F_Q ) ;
g1 [ 0 ] = q - > prev_g1 [ 1 ] ;
switch ( q - > erasure_count )
{
switch ( q - > erasure_count ) {
case 1 : break ;
case 2 : g1 [ 0 ] - = 1 ; break ;
case 3 : g1 [ 0 ] - = 2 ; break ;
@ -296,8 +277,7 @@ static int codebook_sanity_check_for_rate_quarter(const uint8_t *cbgain)
{
int i , diff , prev_diff = 0 ;
for ( i = 1 ; i < 5 ; i + + )
{
for ( i = 1 ; i < 5 ; i + + ) {
diff = cbgain [ i ] - cbgain [ i - 1 ] ;
if ( FFABS ( diff ) > 10 )
return - 1 ;
@ -336,11 +316,9 @@ static void compute_svector(QCELPContext *q, const float *gain,
uint16_t cbseed , cindex ;
float * rnd , tmp_gain , fir_filter_value ;
switch ( q - > bitrate )
{
switch ( q - > bitrate ) {
case RATE_FULL :
for ( i = 0 ; i < 16 ; i + + )
{
for ( i = 0 ; i < 16 ; i + + ) {
tmp_gain = gain [ i ] * QCELP_RATE_FULL_CODEBOOK_RATIO ;
cindex = - q - > frame . cindex [ i ] ;
for ( j = 0 ; j < 10 ; j + + )
@ -348,8 +326,7 @@ static void compute_svector(QCELPContext *q, const float *gain,
}
break ;
case RATE_HALF :
for ( i = 0 ; i < 4 ; i + + )
{
for ( i = 0 ; i < 4 ; i + + ) {
tmp_gain = gain [ i ] * QCELP_RATE_HALF_CODEBOOK_RATIO ;
cindex = - q - > frame . cindex [ i ] ;
for ( j = 0 ; j < 40 ; j + + )
@ -363,11 +340,9 @@ static void compute_svector(QCELPContext *q, const float *gain,
( 0x0007 & q - > frame . lspv [ 1 ] ) < < 3 |
( 0x0038 & q - > frame . lspv [ 0 ] ) > > 3 ;
rnd = q - > rnd_fir_filter_mem + 20 ;
for ( i = 0 ; i < 8 ; i + + )
{
for ( i = 0 ; i < 8 ; i + + ) {
tmp_gain = gain [ i ] * ( QCELP_SQRT1887 / 32768.0 ) ;
for ( k = 0 ; k < 20 ; k + + )
{
for ( k = 0 ; k < 20 ; k + + ) {
cbseed = 521 * cbseed + 259 ;
* rnd = ( int16_t ) cbseed ;
@ -386,11 +361,9 @@ static void compute_svector(QCELPContext *q, const float *gain,
break ;
case RATE_OCTAVE :
cbseed = q - > first16bits ;
for ( i = 0 ; i < 8 ; i + + )
{
for ( i = 0 ; i < 8 ; i + + ) {
tmp_gain = gain [ i ] * ( QCELP_SQRT1887 / 32768.0 ) ;
for ( j = 0 ; j < 20 ; j + + )
{
for ( j = 0 ; j < 20 ; j + + ) {
cbseed = 521 * cbseed + 259 ;
* cdn_vector + + = tmp_gain * ( int16_t ) cbseed ;
}
@ -398,8 +371,7 @@ static void compute_svector(QCELPContext *q, const float *gain,
break ;
case I_F_Q :
cbseed = - 44 ; // random codebook index
for ( i = 0 ; i < 4 ; i + + )
{
for ( i = 0 ; i < 4 ; i + + ) {
tmp_gain = gain [ i ] * QCELP_RATE_FULL_CODEBOOK_RATIO ;
for ( j = 0 ; j < 40 ; j + + )
* cdn_vector + + = tmp_gain * qcelp_rate_full_codebook [ cbseed + + & 127 ] ;
@ -459,15 +431,11 @@ static const float *do_pitchfilter(float memory[303], const float v_in[160],
v_out = memory + 143 ; // Output vector starts at memory[143].
for ( i = 0 ; i < 4 ; i + + )
{
if ( gain [ i ] )
{
for ( i = 0 ; i < 4 ; i + + ) {
if ( gain [ i ] ) {
v_lag = memory + 143 + 40 * i - lag [ i ] ;
for ( v_len = v_in + 40 ; v_in < v_len ; v_in + + )
{
if ( pfrac [ i ] ) // If it is a fractional lag...
{
for ( v_len = v_in + 40 ; v_in < v_len ; v_in + + ) {
if ( pfrac [ i ] ) { // If it is a fractional lag...
for ( j = 0 , * v_out = 0. ; j < 4 ; j + + )
* v_out + = qcelp_hammsinc_table [ j ] * ( v_lag [ j - 4 ] + v_lag [ 3 - j ] ) ;
} else
@ -478,8 +446,7 @@ static const float *do_pitchfilter(float memory[303], const float v_in[160],
v_lag + + ;
v_out + + ;
}
} else
{
} else {
memcpy ( v_out , v_in , 40 * sizeof ( float ) ) ;
v_in + = 40 ;
v_out + = 40 ;
@ -504,31 +471,25 @@ static void apply_pitch_filters(QCELPContext *q, float *cdn_vector)
if ( q - > bitrate > = RATE_HALF | |
q - > bitrate = = SILENCE | |
( q - > bitrate = = I_F_Q & & ( q - > prev_bitrate > = RATE_HALF ) ) )
{
( q - > bitrate = = I_F_Q & & ( q - > prev_bitrate > = RATE_HALF ) ) ) {
if ( q - > bitrate > = RATE_HALF )
{
if ( q - > bitrate > = RATE_HALF ) {
// Compute gain & lag for the whole frame.
for ( i = 0 ; i < 4 ; i + + )
{
for ( i = 0 ; i < 4 ; i + + ) {
q - > pitch_gain [ i ] = q - > frame . plag [ i ] ? ( q - > frame . pgain [ i ] + 1 ) * 0.25 : 0.0 ;
q - > pitch_lag [ i ] = q - > frame . plag [ i ] + 16 ;
}
} else
{
} else {
float max_pitch_gain ;
if ( q - > bitrate = = I_F_Q )
{
if ( q - > bitrate = = I_F_Q ) {
if ( q - > erasure_count < 3 )
max_pitch_gain = 0.9 - 0.3 * ( q - > erasure_count - 1 ) ;
else
max_pitch_gain = 0.0 ;
} else
{
} else {
assert ( q - > bitrate = = SILENCE ) ;
max_pitch_gain = 1.0 ;
}
@ -553,8 +514,7 @@ static void apply_pitch_filters(QCELPContext *q, float *cdn_vector)
q - > frame . pfrac ) ;
apply_gain_ctrl ( cdn_vector , v_synthesis_filtered , v_pre_filtered ) ;
} else
{
} else {
memcpy ( q - > pitch_synthesis_filter_mem , cdn_vector + 17 ,
143 * sizeof ( float ) ) ;
memcpy ( q - > pitch_pre_filter_mem , cdn_vector + 17 , 143 * sizeof ( float ) ) ;
@ -586,8 +546,7 @@ static void lspf2lpc(const float *lspf, float *lpc)
ff_acelp_lspd2lpc ( lsp , lpc , 5 ) ;
for ( i = 0 ; i < 10 ; i + + )
{
for ( i = 0 ; i < 10 ; i + + ) {
lpc [ i ] * = bandwidth_expansion_coeff ;
bandwidth_expansion_coeff * = QCELP_BANDWIDTH_EXPANSION_COEFF ;
}
@ -617,8 +576,7 @@ static void interpolate_lpc(QCELPContext *q, const float *curr_lspf,
else
weight = 1.0 ;
if ( weight ! = 1.0 )
{
if ( weight ! = 1.0 ) {
ff_weighted_vector_sumf ( interpolated_lspf , curr_lspf , q - > prev_lspf ,
weight , 1.0 - weight , 10 ) ;
lspf2lpc ( interpolated_lspf , lpc ) ;
@ -631,8 +589,7 @@ static void interpolate_lpc(QCELPContext *q, const float *curr_lspf,
static qcelp_packet_rate buf_size2bitrate ( const int buf_size )
{
switch ( buf_size )
{
switch ( buf_size ) {
case 35 : return RATE_FULL ;
case 17 : return RATE_HALF ;
case 8 : return RATE_QUARTER ;
@ -660,34 +617,28 @@ static qcelp_packet_rate determine_bitrate(AVCodecContext *avctx, const int buf_
{
qcelp_packet_rate bitrate ;
if ( ( bitrate = buf_size2bitrate ( buf_size ) ) > = 0 )
{
if ( bitrate > * * buf )
{
if ( ( bitrate = buf_size2bitrate ( buf_size ) ) > = 0 ) {
if ( bitrate > * * buf ) {
QCELPContext * q = avctx - > priv_data ;
if ( ! q - > warned_buf_mismatch_bitrate )
{
if ( ! q - > warned_buf_mismatch_bitrate ) {
av_log ( avctx , AV_LOG_WARNING ,
" Claimed bitrate and buffer size mismatch. \n " ) ;
q - > warned_buf_mismatch_bitrate = 1 ;
}
bitrate = * * buf ;
} else if ( bitrate < * * buf )
{
} else if ( bitrate < * * buf ) {
av_log ( avctx , AV_LOG_ERROR ,
" Buffer is too small for the claimed bitrate. \n " ) ;
return I_F_Q ;
}
( * buf ) + + ;
} else if ( ( bitrate = buf_size2bitrate ( buf_size + 1 ) ) > = 0 )
{
} else if ( ( bitrate = buf_size2bitrate ( buf_size + 1 ) ) > = 0 ) {
av_log ( avctx , AV_LOG_WARNING ,
" Bitrate byte is missing, guessing the bitrate from packet size. \n " ) ;
} else
return I_F_Q ;
if ( bitrate = = SILENCE )
{
if ( bitrate = = SILENCE ) {
//FIXME: Remove experimental warning when tested with samples.
av_log_ask_for_sample ( avctx , " 'Blank frame handling is experimental. " ) ;
}
@ -738,26 +689,29 @@ static int qcelp_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
int buf_size = avpkt - > size ;
QCELPContext * q = avctx - > priv_data ;
float * outbuffer = data ;
int i ;
int i , out_size ;
float quantized_lspf [ 10 ] , lpc [ 10 ] ;
float gain [ 16 ] ;
float * formant_mem ;
if ( ( q - > bitrate = determine_bitrate ( avctx , buf_size , & buf ) ) = = I_F_Q )
{
out_size = 160 * av_get_bytes_per_sample ( avctx - > sample_fmt ) ;
if ( * data_size < out_size ) {
av_log ( avctx , AV_LOG_ERROR , " Output buffer is too small \n " ) ;
return AVERROR ( EINVAL ) ;
}
if ( ( q - > bitrate = determine_bitrate ( avctx , buf_size , & buf ) ) = = I_F_Q ) {
warn_insufficient_frame_quality ( avctx , " bitrate cannot be determined. " ) ;
goto erasure ;
}
if ( q - > bitrate = = RATE_OCTAVE & &
( q - > first16bits = AV_RB16 ( buf ) ) = = 0xFFFF )
{
( q - > first16bits = AV_RB16 ( buf ) ) = = 0xFFFF ) {
warn_insufficient_frame_quality ( avctx , " Bitrate is 1/8 and first 16 bits are on. " ) ;
goto erasure ;
}
if ( q - > bitrate > SILENCE )
{
if ( q - > bitrate > SILENCE ) {
const QCELPBitmap * bitmaps = qcelp_unpacking_bitmaps_per_rate [ q - > bitrate ] ;
const QCELPBitmap * bitmaps_end = qcelp_unpacking_bitmaps_per_rate [ q - > bitrate ]
+ qcelp_unpacking_bitmaps_lengths [ q - > bitrate ] ;
@ -771,24 +725,19 @@ static int qcelp_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
unpacked_data [ bitmaps - > index ] | = get_bits ( & q - > gb , bitmaps - > bitlen ) < < bitmaps - > bitpos ;
// Check for erasures/blanks on rates 1, 1/4 and 1/8.
if ( q - > frame . reserved )
{
if ( q - > frame . reserved ) {
warn_insufficient_frame_quality ( avctx , " Wrong data in reserved frame area. " ) ;
goto erasure ;
}
if ( q - > bitrate = = RATE_QUARTER & &
codebook_sanity_check_for_rate_quarter ( q - > frame . cbgain ) )
{
codebook_sanity_check_for_rate_quarter ( q - > frame . cbgain ) ) {
warn_insufficient_frame_quality ( avctx , " Codebook gain sanity check failed. " ) ;
goto erasure ;
}
if ( q - > bitrate > = RATE_HALF )
{
for ( i = 0 ; i < 4 ; i + + )
{
if ( q - > frame . pfrac [ i ] & & q - > frame . plag [ i ] > = 124 )
{
if ( q - > bitrate > = RATE_HALF ) {
for ( i = 0 ; i < 4 ; i + + ) {
if ( q - > frame . pfrac [ i ] & & q - > frame . plag [ i ] > = 124 ) {
warn_insufficient_frame_quality ( avctx , " Cannot initialize pitch filter. " ) ;
goto erasure ;
}
@ -799,8 +748,7 @@ static int qcelp_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
decode_gain_and_index ( q , gain ) ;
compute_svector ( q , gain , outbuffer ) ;
if ( decode_lspf ( q , quantized_lspf ) < 0 )
{
if ( decode_lspf ( q , quantized_lspf ) < 0 ) {
warn_insufficient_frame_quality ( avctx , " Badly received packets in frame. " ) ;
goto erasure ;
}
@ -808,8 +756,7 @@ static int qcelp_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
apply_pitch_filters ( q , outbuffer ) ;
if ( q - > bitrate = = I_F_Q )
{
if ( q - > bitrate = = I_F_Q ) {
erasure :
q - > bitrate = I_F_Q ;
q - > erasure_count + + ;
@ -821,8 +768,7 @@ erasure:
q - > erasure_count = 0 ;
formant_mem = q - > formant_mem + 10 ;
for ( i = 0 ; i < 4 ; i + + )
{
for ( i = 0 ; i < 4 ; i + + ) {
interpolate_lpc ( q , quantized_lspf , lpc , i ) ;
ff_celp_lp_synthesis_filterf ( formant_mem , lpc , outbuffer + i * 40 , 40 ,
10 ) ;
@ -837,7 +783,7 @@ erasure:
memcpy ( q - > prev_lspf , quantized_lspf , sizeof ( q - > prev_lspf ) ) ;
q - > prev_bitrate = q - > bitrate ;
* data_size = 160 * sizeof ( * outbuffer ) ;
* data_size = out_size ;
return buf_size ;
}