* AMR wideband decoder
*/
+#include "libavutil/channel_layout.h"
#include "libavutil/common.h"
#include "libavutil/lfg.h"
#include "avcodec.h"
+#include "dsputil.h"
#include "lsp.h"
-#include "celp_math.h"
#include "celp_filters.h"
#include "acelp_filters.h"
#include "acelp_vectors.h"
#include "acelp_pitch_delay.h"
+#include "internal.h"
#define AMR_USE_16BIT_TABLES
#include "amr.h"
AMRWBContext *ctx = avctx->priv_data;
int i;
- avctx->sample_fmt = AV_SAMPLE_FMT_FLT;
+ if (avctx->channels > 1) {
+ av_log_missing_feature(avctx, "multi-channel AMR", 0);
+ return AVERROR_PATCHWELCOME;
+ }
+
+ avctx->channels = 1;
+ avctx->channel_layout = AV_CH_LAYOUT_MONO;
+ avctx->sample_rate = 16000;
+ avctx->sample_fmt = AV_SAMPLE_FMT_FLT;
av_lfg_init(&ctx->prng, 1);
{
/* Decode frame header (1st octet) */
ctx->fr_cur_mode = buf[0] >> 3 & 0x0F;
- ctx->fr_quality = (buf[0] & 0x4) != 0x4;
+ ctx->fr_quality = (buf[0] & 0x4) == 0x4;
return 1;
}
static float voice_factor(float *p_vector, float p_gain,
float *f_vector, float f_gain)
{
- double p_ener = (double) ff_dot_productf(p_vector, p_vector,
- AMRWB_SFR_SIZE) * p_gain * p_gain;
- double f_ener = (double) ff_dot_productf(f_vector, f_vector,
- AMRWB_SFR_SIZE) * f_gain * f_gain;
+ double p_ener = (double) ff_scalarproduct_float_c(p_vector, p_vector,
+ AMRWB_SFR_SIZE) *
+ p_gain * p_gain;
+ double f_ener = (double) ff_scalarproduct_float_c(f_vector, f_vector,
+ AMRWB_SFR_SIZE) *
+ f_gain * f_gain;
return (p_ener - f_ener) / (p_ener + f_ener);
}
/* emphasize pitch vector contribution in low bitrate modes */
if (ctx->pitch_gain[0] > 0.5 && ctx->fr_cur_mode <= MODE_8k85) {
int i;
- float energy = ff_dot_productf(excitation, excitation,
- AMRWB_SFR_SIZE);
+ float energy = ff_scalarproduct_float_c(excitation, excitation,
+ AMRWB_SFR_SIZE);
// XXX: Weird part in both ref code and spec. A unknown parameter
// {beta} seems to be identical to the current pitch gain
i++;
for (k = 1; k < 5; k++) {
- out[i] = ff_dot_productf(in0 + int_part, upsample_fir[4 - frac_part],
- UPS_MEM_SIZE);
+ out[i] = ff_scalarproduct_float_c(in0 + int_part,
+ upsample_fir[4 - frac_part],
+ UPS_MEM_SIZE);
int_part++;
frac_part--;
i++;
if (ctx->fr_cur_mode == MODE_23k85)
return qua_hb_gain[hb_idx] * (1.0f / (1 << 14));
- tilt = ff_dot_productf(synth, synth + 1, AMRWB_SFR_SIZE - 1) /
- ff_dot_productf(synth, synth, AMRWB_SFR_SIZE);
+ tilt = ff_scalarproduct_float_c(synth, synth + 1, AMRWB_SFR_SIZE - 1) /
+ ff_scalarproduct_float_c(synth, synth, AMRWB_SFR_SIZE);
/* return gain bounded by [0.1, 1.0] */
return av_clipf((1.0 - FFMAX(0.0, tilt)) * (1.25 - 0.25 * wsp), 0.1, 1.0);
const float *synth_exc, float hb_gain)
{
int i;
- float energy = ff_dot_productf(synth_exc, synth_exc, AMRWB_SFR_SIZE);
+ float energy = ff_scalarproduct_float_c(synth_exc, synth_exc, AMRWB_SFR_SIZE);
/* Generate a white-noise excitation */
for (i = 0; i < AMRWB_SFR_SIZE_16k; i++)
static void extrapolate_isf(float isf[LP_ORDER_16k])
{
float diff_isf[LP_ORDER - 2], diff_mean;
- float *diff_hi = diff_isf - LP_ORDER + 1; // diff array for extrapolated indexes
float corr_lag[3];
float est, scale;
- int i, i_max_corr;
+ int i, j, i_max_corr;
isf[LP_ORDER_16k - 1] = isf[LP_ORDER - 1];
scale = 0.5 * (FFMIN(est, 7600) - isf[LP_ORDER - 2]) /
(isf[LP_ORDER_16k - 2] - isf[LP_ORDER - 2]);
- for (i = LP_ORDER - 1; i < LP_ORDER_16k - 1; i++)
- diff_hi[i] = scale * (isf[i] - isf[i - 1]);
+ for (i = LP_ORDER - 1, j = 0; i < LP_ORDER_16k - 1; i++, j++)
+ diff_isf[j] = scale * (isf[i] - isf[i - 1]);
/* Stability insurance */
- for (i = LP_ORDER; i < LP_ORDER_16k - 1; i++)
- if (diff_hi[i] + diff_hi[i - 1] < 5.0) {
- if (diff_hi[i] > diff_hi[i - 1]) {
- diff_hi[i - 1] = 5.0 - diff_hi[i];
+ for (i = 1; i < LP_ORDER_16k - LP_ORDER; i++)
+ if (diff_isf[i] + diff_isf[i - 1] < 5.0) {
+ if (diff_isf[i] > diff_isf[i - 1]) {
+ diff_isf[i - 1] = 5.0 - diff_isf[i];
} else
- diff_hi[i] = 5.0 - diff_hi[i - 1];
+ diff_isf[i] = 5.0 - diff_isf[i - 1];
}
- for (i = LP_ORDER - 1; i < LP_ORDER_16k - 1; i++)
- isf[i] = isf[i - 1] + diff_hi[i] * (1.0f / (1 << 15));
+ for (i = LP_ORDER - 1, j = 0; i < LP_ORDER_16k - 1; i++, j++)
+ isf[i] = isf[i - 1] + diff_isf[j] * (1.0f / (1 << 15));
/* Scale the ISF vector for 16000 Hz */
for (i = 0; i < LP_ORDER_16k - 1; i++)
/* get output buffer */
ctx->avframe.nb_samples = 4 * AMRWB_SFR_SIZE_16k;
- if ((ret = avctx->get_buffer(avctx, &ctx->avframe)) < 0) {
+ if ((ret = ff_get_buffer(avctx, &ctx->avframe)) < 0) {
av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
return ret;
}
if (ctx->fr_cur_mode == MODE_SID) { /* Comfort noise frame */
av_log_missing_feature(avctx, "SID mode", 1);
- return -1;
+ return AVERROR_PATCHWELCOME;
}
ff_amr_bit_reorder((uint16_t *) &ctx->frame, sizeof(AMRWBFrame),
ctx->fixed_gain[0] =
ff_amr_set_fixed_gain(fixed_gain_factor,
- ff_dot_productf(ctx->fixed_vector, ctx->fixed_vector,
- AMRWB_SFR_SIZE) / AMRWB_SFR_SIZE,
+ ff_scalarproduct_float_c(ctx->fixed_vector,
+ ctx->fixed_vector,
+ AMRWB_SFR_SIZE) /
+ AMRWB_SFR_SIZE,
ctx->prediction_error,
ENERGY_MEAN, energy_pred_fac);