summaryrefslogtreecommitdiff
path: root/libavcodec/g723_1dec.c
diff options
context:
space:
mode:
Diffstat (limited to 'libavcodec/g723_1dec.c')
-rw-r--r--libavcodec/g723_1dec.c467
1 files changed, 235 insertions, 232 deletions
diff --git a/libavcodec/g723_1dec.c b/libavcodec/g723_1dec.c
index 0cb5ba70c5..676c4bbac3 100644
--- a/libavcodec/g723_1dec.c
+++ b/libavcodec/g723_1dec.c
@@ -3,20 +3,20 @@
* Copyright (c) 2006 Benjamin Larsson
* Copyright (c) 2010 Mohamed Naufal Basheer
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -32,8 +32,9 @@
#define BITSTREAM_READER_LE
#include "acelp_vectors.h"
#include "avcodec.h"
-#include "bitstream.h"
#include "celp_filters.h"
+#include "celp_math.h"
+#include "get_bits.h"
#include "internal.h"
#include "g723_1.h"
@@ -41,19 +42,25 @@
static av_cold int g723_1_decode_init(AVCodecContext *avctx)
{
- G723_1_Context *p = avctx->priv_data;
+ G723_1_Context *s = avctx->priv_data;
- avctx->channel_layout = AV_CH_LAYOUT_MONO;
- avctx->sample_fmt = AV_SAMPLE_FMT_S16;
- avctx->channels = 1;
- avctx->sample_rate = 8000;
- p->pf_gain = 1 << 12;
+ avctx->sample_fmt = AV_SAMPLE_FMT_S16P;
+ if (avctx->channels < 1 || avctx->channels > 2) {
+ av_log(avctx, AV_LOG_ERROR, "Only mono and stereo are supported (requested channels: %d).\n", avctx->channels);
+ return AVERROR(EINVAL);
+ }
+ avctx->channel_layout = avctx->channels == 1 ? AV_CH_LAYOUT_MONO : AV_CH_LAYOUT_STEREO;
+ for (int ch = 0; ch < avctx->channels; ch++) {
+ G723_1_ChannelContext *p = &s->ch[ch];
+
+ p->pf_gain = 1 << 12;
- memcpy(p->prev_lsp, dc_lsp, LPC_ORDER * sizeof(*p->prev_lsp));
- memcpy(p->sid_lsp, dc_lsp, LPC_ORDER * sizeof(*p->sid_lsp));
+ memcpy(p->prev_lsp, dc_lsp, LPC_ORDER * sizeof(*p->prev_lsp));
+ memcpy(p->sid_lsp, dc_lsp, LPC_ORDER * sizeof(*p->sid_lsp));
- p->cng_random_seed = CNG_RANDOM_SEED;
- p->past_frame_type = SID_FRAME;
+ p->cng_random_seed = CNG_RANDOM_SEED;
+ p->past_frame_type = SID_FRAME;
+ }
return 0;
}
@@ -65,17 +72,20 @@ static av_cold int g723_1_decode_init(AVCodecContext *avctx)
* @param buf pointer to the input buffer
* @param buf_size size of the input buffer
*/
-static int unpack_bitstream(G723_1_Context *p, const uint8_t *buf,
+static int unpack_bitstream(G723_1_ChannelContext *p, const uint8_t *buf,
int buf_size)
{
- BitstreamContext bc;
+ GetBitContext gb;
int ad_cb_len;
int temp, info_bits, i;
+ int ret;
- bitstream_init8(&bc, buf, buf_size);
+ ret = init_get_bits8(&gb, buf, buf_size);
+ if (ret < 0)
+ return ret;
/* Extract frame type and rate info */
- info_bits = bitstream_read(&bc, 2);
+ info_bits = get_bits(&gb, 2);
if (info_bits == 3) {
p->cur_frame_type = UNTRANSMITTED_FRAME;
@@ -83,13 +93,13 @@ static int unpack_bitstream(G723_1_Context *p, const uint8_t *buf,
}
/* Extract 24 bit lsp indices, 8 bit for each band */
- p->lsp_index[2] = bitstream_read(&bc, 8);
- p->lsp_index[1] = bitstream_read(&bc, 8);
- p->lsp_index[0] = bitstream_read(&bc, 8);
+ p->lsp_index[2] = get_bits(&gb, 8);
+ p->lsp_index[1] = get_bits(&gb, 8);
+ p->lsp_index[0] = get_bits(&gb, 8);
if (info_bits == 2) {
p->cur_frame_type = SID_FRAME;
- p->subframe[0].amp_index = bitstream_read(&bc, 6);
+ p->subframe[0].amp_index = get_bits(&gb, 6);
return 0;
}
@@ -97,23 +107,23 @@ static int unpack_bitstream(G723_1_Context *p, const uint8_t *buf,
p->cur_rate = info_bits ? RATE_5300 : RATE_6300;
p->cur_frame_type = ACTIVE_FRAME;
- p->pitch_lag[0] = bitstream_read(&bc, 7);
+ p->pitch_lag[0] = get_bits(&gb, 7);
if (p->pitch_lag[0] > 123) /* test if forbidden code */
return -1;
p->pitch_lag[0] += PITCH_MIN;
- p->subframe[1].ad_cb_lag = bitstream_read(&bc, 2);
+ p->subframe[1].ad_cb_lag = get_bits(&gb, 2);
- p->pitch_lag[1] = bitstream_read(&bc, 7);
+ p->pitch_lag[1] = get_bits(&gb, 7);
if (p->pitch_lag[1] > 123)
return -1;
p->pitch_lag[1] += PITCH_MIN;
- p->subframe[3].ad_cb_lag = bitstream_read(&bc, 2);
+ p->subframe[3].ad_cb_lag = get_bits(&gb, 2);
p->subframe[0].ad_cb_lag = 1;
p->subframe[2].ad_cb_lag = 1;
for (i = 0; i < SUBFRAMES; i++) {
/* Extract combined gain */
- temp = bitstream_read(&bc, 12);
+ temp = get_bits(&gb, 12);
ad_cb_len = 170;
p->subframe[i].dirac_train = 0;
if (p->cur_rate == RATE_6300 && p->pitch_lag[i >> 1] < SUBFRAME_LEN - 2) {
@@ -130,16 +140,16 @@ static int unpack_bitstream(G723_1_Context *p, const uint8_t *buf,
}
}
- p->subframe[0].grid_index = bitstream_read(&bc, 1);
- p->subframe[1].grid_index = bitstream_read(&bc, 1);
- p->subframe[2].grid_index = bitstream_read(&bc, 1);
- p->subframe[3].grid_index = bitstream_read(&bc, 1);
+ p->subframe[0].grid_index = get_bits1(&gb);
+ p->subframe[1].grid_index = get_bits1(&gb);
+ p->subframe[2].grid_index = get_bits1(&gb);
+ p->subframe[3].grid_index = get_bits1(&gb);
if (p->cur_rate == RATE_6300) {
- bitstream_skip(&bc, 1); /* skip reserved bit */
+ skip_bits1(&gb); /* skip reserved bit */
/* Compute pulse_pos index using the 13-bit combined position index */
- temp = bitstream_read(&bc, 13);
+ temp = get_bits(&gb, 13);
p->subframe[0].pulse_pos = temp / 810;
temp -= p->subframe[0].pulse_pos * 810;
@@ -150,28 +160,28 @@ static int unpack_bitstream(G723_1_Context *p, const uint8_t *buf,
p->subframe[3].pulse_pos = temp - p->subframe[2].pulse_pos * 9;
p->subframe[0].pulse_pos = (p->subframe[0].pulse_pos << 16) +
- bitstream_read(&bc, 16);
+ get_bits(&gb, 16);
p->subframe[1].pulse_pos = (p->subframe[1].pulse_pos << 14) +
- bitstream_read(&bc, 14);
+ get_bits(&gb, 14);
p->subframe[2].pulse_pos = (p->subframe[2].pulse_pos << 16) +
- bitstream_read(&bc, 16);
+ get_bits(&gb, 16);
p->subframe[3].pulse_pos = (p->subframe[3].pulse_pos << 14) +
- bitstream_read(&bc, 14);
+ get_bits(&gb, 14);
- p->subframe[0].pulse_sign = bitstream_read(&bc, 6);
- p->subframe[1].pulse_sign = bitstream_read(&bc, 5);
- p->subframe[2].pulse_sign = bitstream_read(&bc, 6);
- p->subframe[3].pulse_sign = bitstream_read(&bc, 5);
+ p->subframe[0].pulse_sign = get_bits(&gb, 6);
+ p->subframe[1].pulse_sign = get_bits(&gb, 5);
+ p->subframe[2].pulse_sign = get_bits(&gb, 6);
+ p->subframe[3].pulse_sign = get_bits(&gb, 5);
} else { /* 5300 bps */
- p->subframe[0].pulse_pos = bitstream_read(&bc, 12);
- p->subframe[1].pulse_pos = bitstream_read(&bc, 12);
- p->subframe[2].pulse_pos = bitstream_read(&bc, 12);
- p->subframe[3].pulse_pos = bitstream_read(&bc, 12);
-
- p->subframe[0].pulse_sign = bitstream_read(&bc, 4);
- p->subframe[1].pulse_sign = bitstream_read(&bc, 4);
- p->subframe[2].pulse_sign = bitstream_read(&bc, 4);
- p->subframe[3].pulse_sign = bitstream_read(&bc, 4);
+ p->subframe[0].pulse_pos = get_bits(&gb, 12);
+ p->subframe[1].pulse_pos = get_bits(&gb, 12);
+ p->subframe[2].pulse_pos = get_bits(&gb, 12);
+ p->subframe[3].pulse_pos = get_bits(&gb, 12);
+
+ p->subframe[0].pulse_sign = get_bits(&gb, 4);
+ p->subframe[1].pulse_sign = get_bits(&gb, 4);
+ p->subframe[2].pulse_sign = get_bits(&gb, 4);
+ p->subframe[3].pulse_sign = get_bits(&gb, 4);
}
return 0;
@@ -180,31 +190,14 @@ static int unpack_bitstream(G723_1_Context *p, const uint8_t *buf,
/**
* Bitexact implementation of sqrt(val/2).
*/
-static int16_t square_root(int val)
+static int16_t square_root(unsigned val)
{
- int16_t res = 0;
- int16_t exp = 0x4000;
- int i;
+ av_assert2(!(val & 0x80000000));
- for (i = 0; i < 14; i ++) {
- int res_exp = res + exp;
- if (val >= res_exp * res_exp << 1)
- res += exp;
- exp >>= 1;
- }
- return res;
+ return (ff_sqrt(val << 1) >> 1) & (~1);
}
/**
- * Bitexact implementation of 2ab scaled by 1/2^16.
- *
- * @param a 32 bit multiplicand
- * @param b 16 bit multiplier
- */
-#define MULL2(a, b) \
- ((((a) >> 16) * (b) << 1) + (((a) & 0xffff) * (b) >> 15))
-
-/**
* Generate fixed codebook excitation vector.
*
* @param vector decoded excitation vector
@@ -361,7 +354,7 @@ static void comp_ppf_gains(int lag, PPFParam *ppf, enum Rate cur_rate,
* @param ppf pitch postfilter parameters
* @param cur_rate current bitrate
*/
-static void comp_ppf_coeff(G723_1_Context *p, int offset, int pitch_lag,
+static void comp_ppf_coeff(G723_1_ChannelContext *p, int offset, int pitch_lag,
PPFParam *ppf, enum Rate cur_rate)
{
@@ -447,7 +440,7 @@ static void comp_ppf_coeff(G723_1_Context *p, int offset, int pitch_lag,
*
* @return residual interpolation index if voiced, 0 otherwise
*/
-static int comp_interp_index(G723_1_Context *p, int pitch_lag,
+static int comp_interp_index(G723_1_ChannelContext *p, int pitch_lag,
int *exc_eng, int *scale)
{
int offset = PITCH_MAX + 2 * SUBFRAME_LEN;
@@ -477,9 +470,9 @@ static int comp_interp_index(G723_1_Context *p, int pitch_lag,
temp = best_eng * *exc_eng >> 3;
- if (temp < ccr * ccr)
+ if (temp < ccr * ccr) {
return index;
- else
+ } else
return 0;
}
@@ -505,7 +498,7 @@ static void residual_interp(int16_t *buf, int16_t *out, int lag,
(FRAME_LEN - lag) * sizeof(*out));
} else { /* Unvoiced */
for (i = 0; i < FRAME_LEN; i++) {
- *rseed = *rseed * 521 + 259;
+ *rseed = (int16_t)(*rseed * 521 + 259);
out[i] = gain * *rseed >> 15;
}
memset(buf, 0, (FRAME_LEN + PITCH_MAX) * sizeof(*buf));
@@ -519,21 +512,24 @@ static void residual_interp(int16_t *buf, int16_t *out, int lag,
* @param iir_coef IIR coefficients
* @param src source vector
* @param dest destination vector
+ * @param width width of the output, 16 bits(0) / 32 bits(1)
*/
-static void iir_filter(int16_t *fir_coef, int16_t *iir_coef,
- int16_t *src, int *dest)
-{
- int m, n;
-
- for (m = 0; m < SUBFRAME_LEN; m++) {
- int64_t filter = 0;
- for (n = 1; n <= LPC_ORDER; n++) {
- filter -= fir_coef[n - 1] * src[m - n] -
- iir_coef[n - 1] * (dest[m - n] >> 16);
- }
-
- dest[m] = av_clipl_int32((src[m] << 16) + (filter << 3) + (1 << 15));
- }
+#define iir_filter(fir_coef, iir_coef, src, dest, width)\
+{\
+ int m, n;\
+ int res_shift = 16 & ~-(width);\
+ int in_shift = 16 - res_shift;\
+\
+ for (m = 0; m < SUBFRAME_LEN; m++) {\
+ int64_t filter = 0;\
+ for (n = 1; n <= LPC_ORDER; n++) {\
+ filter -= (fir_coef)[n - 1] * (src)[m - n] -\
+ (iir_coef)[n - 1] * ((dest)[m - n] >> in_shift);\
+ }\
+\
+ (dest)[m] = av_clipl_int32(((src)[m] * 65536) + (filter * 8) +\
+ (1 << 15)) >> res_shift;\
+ }\
}
/**
@@ -543,7 +539,7 @@ static void iir_filter(int16_t *fir_coef, int16_t *iir_coef,
* @param buf postfiltered output vector
* @param energy input energy coefficient
*/
-static void gain_scale(G723_1_Context *p, int16_t * buf, int energy)
+static void gain_scale(G723_1_ChannelContext *p, int16_t * buf, int energy)
{
int num, denom, gain, bits1, bits2;
int i;
@@ -563,7 +559,7 @@ static void gain_scale(G723_1_Context *p, int16_t * buf, int energy)
denom <<= bits2;
bits2 = 5 + bits1 - bits2;
- bits2 = FFMAX(0, bits2);
+ bits2 = av_clip_uintp2(bits2, 5);
gain = (num >> 1) / (denom >> 16);
gain = square_root(gain << 16 >> bits2);
@@ -586,7 +582,7 @@ static void gain_scale(G723_1_Context *p, int16_t * buf, int energy)
* @param buf input buffer
* @param dst output buffer
*/
-static void formant_postfilter(G723_1_Context *p, int16_t *lpc,
+static void formant_postfilter(G723_1_ChannelContext *p, int16_t *lpc,
int16_t *buf, int16_t *dst)
{
int16_t filter_coef[2][LPC_ORDER];
@@ -603,13 +599,12 @@ static void formant_postfilter(G723_1_Context *p, int16_t *lpc,
filter_coef[1][k] = (-lpc[k] * postfilter_tbl[1][k] +
(1 << 14)) >> 15;
}
- iir_filter(filter_coef[0], filter_coef[1], buf + i, filter_signal + i);
+ iir_filter(filter_coef[0], filter_coef[1], buf + i, filter_signal + i, 1);
lpc += LPC_ORDER;
}
- memcpy(p->fir_mem, buf + FRAME_LEN, LPC_ORDER * sizeof(*p->fir_mem));
- memcpy(p->iir_mem, filter_signal + FRAME_LEN,
- LPC_ORDER * sizeof(*p->iir_mem));
+ memcpy(p->fir_mem, buf + FRAME_LEN, LPC_ORDER * sizeof(int16_t));
+ memcpy(p->iir_mem, filter_signal + FRAME_LEN, LPC_ORDER * sizeof(int));
buf += LPC_ORDER;
signal_ptr = filter_signal + LPC_ORDER;
@@ -670,16 +665,22 @@ static inline int cng_rand(int *state, int base)
return (*state & 0x7FFF) * base >> 15;
}
-static int estimate_sid_gain(G723_1_Context *p)
+static int estimate_sid_gain(G723_1_ChannelContext *p)
{
int i, shift, seg, seg2, t, val, val_add, x, y;
shift = 16 - p->cur_gain * 2;
- if (shift > 0)
- t = p->sid_gain << shift;
- else
+ if (shift > 0) {
+ if (p->sid_gain == 0) {
+ t = 0;
+ } else if (shift >= 31 || (int32_t)((uint32_t)p->sid_gain << shift) >> shift != p->sid_gain) {
+ if (p->sid_gain < 0) t = INT32_MIN;
+ else t = INT32_MAX;
+ } else
+ t = p->sid_gain << shift;
+ }else
t = p->sid_gain >> -shift;
- x = t * cng_filt[0] >> 16;
+ x = av_clipl_int32(t * (int64_t)cng_filt[0] >> 16);
if (x >= cng_bseg[2])
return 0x3F;
@@ -710,13 +711,13 @@ static int estimate_sid_gain(G723_1_Context *p)
if (y <= 0) {
t = seg * 32 + (val + 1 << seg2);
t = t * t - x;
- val = (seg2 - 1 << 4) + val;
+ val = (seg2 - 1) * 16 + val;
if (t >= y)
val++;
} else {
t = seg * 32 + (val - 1 << seg2);
t = t * t - x;
- val = (seg2 - 1 << 4) + val;
+ val = (seg2 - 1) * 16 + val;
if (t >= y)
val--;
}
@@ -724,7 +725,7 @@ static int estimate_sid_gain(G723_1_Context *p)
return val;
}
-static void generate_noise(G723_1_Context *p)
+static void generate_noise(G723_1_ChannelContext *p)
{
int i, j, idx, t;
int off[SUBFRAMES];
@@ -748,7 +749,7 @@ static void generate_noise(G723_1_Context *p)
off[i * 2 + 1] = ((t >> 1) & 1) + SUBFRAME_LEN;
t >>= 2;
for (j = 0; j < 11; j++) {
- signs[i * 11 + j] = (t & 1) * 2 - 1 << 14;
+ signs[i * 11 + j] = ((t & 1) * 2 - 1) * (1 << 14);
t >>= 1;
}
}
@@ -792,7 +793,7 @@ static void generate_noise(G723_1_Context *p)
sum = 0;
if (shift < 0) {
for (j = 0; j < SUBFRAME_LEN * 2; j++) {
- t = vector_ptr[j] << -shift;
+ t = vector_ptr[j] * (1 << -shift);
sum += t * t;
tmp[j] = t;
}
@@ -830,7 +831,7 @@ static void generate_noise(G723_1_Context *p)
if (shift < 0)
x >>= -shift;
else
- x <<= shift;
+ x *= 1 << shift;
x = av_clip(x, -10000, 10000);
for (j = 0; j < 11; j++) {
@@ -852,7 +853,7 @@ static void generate_noise(G723_1_Context *p)
static int g723_1_decode_frame(AVCodecContext *avctx, void *data,
int *got_frame_ptr, AVPacket *avpkt)
{
- G723_1_Context *p = avctx->priv_data;
+ G723_1_Context *s = avctx->priv_data;
AVFrame *frame = data;
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
@@ -864,9 +865,8 @@ static int g723_1_decode_frame(AVCodecContext *avctx, void *data,
int16_t acb_vector[SUBFRAME_LEN];
int16_t *out;
int bad_frame = 0, i, j, ret;
- int16_t *audio = p->audio;
- if (buf_size < frame_size[dec_mode]) {
+ if (buf_size < frame_size[dec_mode] * avctx->channels) {
if (buf_size)
av_log(avctx, AV_LOG_WARNING,
"Expected %d bytes, got %d - skipping packet\n",
@@ -875,151 +875,154 @@ static int g723_1_decode_frame(AVCodecContext *avctx, void *data,
return buf_size;
}
- if (unpack_bitstream(p, buf, buf_size) < 0) {
- bad_frame = 1;
- if (p->past_frame_type == ACTIVE_FRAME)
- p->cur_frame_type = ACTIVE_FRAME;
- else
- p->cur_frame_type = UNTRANSMITTED_FRAME;
- }
-
frame->nb_samples = FRAME_LEN;
- if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
- av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
- return ret;
- }
+ if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
+ return ret;
+
+ for (int ch = 0; ch < avctx->channels; ch++) {
+ G723_1_ChannelContext *p = &s->ch[ch];
+ int16_t *audio = p->audio;
+
+ if (unpack_bitstream(p, buf, buf_size) < 0) {
+ bad_frame = 1;
+ if (p->past_frame_type == ACTIVE_FRAME)
+ p->cur_frame_type = ACTIVE_FRAME;
+ else
+ p->cur_frame_type = UNTRANSMITTED_FRAME;
+ }
- out = (int16_t *)frame->data[0];
-
- if (p->cur_frame_type == ACTIVE_FRAME) {
- if (!bad_frame)
- p->erased_frames = 0;
- else if (p->erased_frames != 3)
- p->erased_frames++;
-
- ff_g723_1_inverse_quant(cur_lsp, p->prev_lsp, p->lsp_index, bad_frame);
- ff_g723_1_lsp_interpolate(lpc, cur_lsp, p->prev_lsp);
-
- /* Save the lsp_vector for the next frame */
- memcpy(p->prev_lsp, cur_lsp, LPC_ORDER * sizeof(*p->prev_lsp));
-
- /* Generate the excitation for the frame */
- memcpy(p->excitation, p->prev_excitation,
- PITCH_MAX * sizeof(*p->excitation));
- if (!p->erased_frames) {
- int16_t *vector_ptr = p->excitation + PITCH_MAX;
-
- /* Update interpolation gain memory */
- p->interp_gain = fixed_cb_gain[(p->subframe[2].amp_index +
- p->subframe[3].amp_index) >> 1];
- for (i = 0; i < SUBFRAMES; i++) {
- gen_fcb_excitation(vector_ptr, &p->subframe[i], p->cur_rate,
- p->pitch_lag[i >> 1], i);
- ff_g723_1_gen_acb_excitation(acb_vector,
- &p->excitation[SUBFRAME_LEN * i],
- p->pitch_lag[i >> 1],
- &p->subframe[i], p->cur_rate);
- /* Get the total excitation */
- for (j = 0; j < SUBFRAME_LEN; j++) {
- int v = av_clip_int16(vector_ptr[j] << 1);
- vector_ptr[j] = av_clip_int16(v + acb_vector[j]);
- }
- vector_ptr += SUBFRAME_LEN;
- }
+ out = (int16_t *)frame->extended_data[ch];
- vector_ptr = p->excitation + PITCH_MAX;
-
- p->interp_index = comp_interp_index(p, p->pitch_lag[1],
- &p->sid_gain, &p->cur_gain);
-
- /* Perform pitch postfiltering */
- if (p->postfilter) {
- i = PITCH_MAX;
- for (j = 0; j < SUBFRAMES; i += SUBFRAME_LEN, j++)
- comp_ppf_coeff(p, i, p->pitch_lag[j >> 1],
- ppf + j, p->cur_rate);
-
- for (i = 0, j = 0; j < SUBFRAMES; i += SUBFRAME_LEN, j++)
- ff_acelp_weighted_vector_sum(p->audio + LPC_ORDER + i,
- vector_ptr + i,
- vector_ptr + i + ppf[j].index,
- ppf[j].sc_gain,
- ppf[j].opt_gain,
- 1 << 14, 15, SUBFRAME_LEN);
- } else {
- audio = vector_ptr - LPC_ORDER;
- }
+ if (p->cur_frame_type == ACTIVE_FRAME) {
+ if (!bad_frame)
+ p->erased_frames = 0;
+ else if (p->erased_frames != 3)
+ p->erased_frames++;
+
+ ff_g723_1_inverse_quant(cur_lsp, p->prev_lsp, p->lsp_index, bad_frame);
+ ff_g723_1_lsp_interpolate(lpc, cur_lsp, p->prev_lsp);
+
+ /* Save the lsp_vector for the next frame */
+ memcpy(p->prev_lsp, cur_lsp, LPC_ORDER * sizeof(*p->prev_lsp));
- /* Save the excitation for the next frame */
- memcpy(p->prev_excitation, p->excitation + FRAME_LEN,
+ /* Generate the excitation for the frame */
+ memcpy(p->excitation, p->prev_excitation,
PITCH_MAX * sizeof(*p->excitation));
- } else {
- p->interp_gain = (p->interp_gain * 3 + 2) >> 2;
- if (p->erased_frames == 3) {
- /* Mute output */
- memset(p->excitation, 0,
- (FRAME_LEN + PITCH_MAX) * sizeof(*p->excitation));
- memset(p->prev_excitation, 0,
- PITCH_MAX * sizeof(*p->excitation));
- memset(frame->data[0], 0,
- (FRAME_LEN + LPC_ORDER) * sizeof(int16_t));
- } else {
- int16_t *buf = p->audio + LPC_ORDER;
+ if (!p->erased_frames) {
+ int16_t *vector_ptr = p->excitation + PITCH_MAX;
+
+ /* Update interpolation gain memory */
+ p->interp_gain = fixed_cb_gain[(p->subframe[2].amp_index +
+ p->subframe[3].amp_index) >> 1];
+ for (i = 0; i < SUBFRAMES; i++) {
+ gen_fcb_excitation(vector_ptr, &p->subframe[i], p->cur_rate,
+ p->pitch_lag[i >> 1], i);
+ ff_g723_1_gen_acb_excitation(acb_vector,
+ &p->excitation[SUBFRAME_LEN * i],
+ p->pitch_lag[i >> 1],
+ &p->subframe[i], p->cur_rate);
+ /* Get the total excitation */
+ for (j = 0; j < SUBFRAME_LEN; j++) {
+ int v = av_clip_int16(vector_ptr[j] * 2);
+ vector_ptr[j] = av_clip_int16(v + acb_vector[j]);
+ }
+ vector_ptr += SUBFRAME_LEN;
+ }
- /* Regenerate frame */
- residual_interp(p->excitation, buf, p->interp_index,
- p->interp_gain, &p->random_seed);
+ vector_ptr = p->excitation + PITCH_MAX;
+
+ p->interp_index = comp_interp_index(p, p->pitch_lag[1],
+ &p->sid_gain, &p->cur_gain);
+
+ /* Perform pitch postfiltering */
+ if (s->postfilter) {
+ i = PITCH_MAX;
+ for (j = 0; j < SUBFRAMES; i += SUBFRAME_LEN, j++)
+ comp_ppf_coeff(p, i, p->pitch_lag[j >> 1],
+ ppf + j, p->cur_rate);
+
+ for (i = 0, j = 0; j < SUBFRAMES; i += SUBFRAME_LEN, j++)
+ ff_acelp_weighted_vector_sum(p->audio + LPC_ORDER + i,
+ vector_ptr + i,
+ vector_ptr + i + ppf[j].index,
+ ppf[j].sc_gain,
+ ppf[j].opt_gain,
+ 1 << 14, 15, SUBFRAME_LEN);
+ } else {
+ audio = vector_ptr - LPC_ORDER;
+ }
/* Save the excitation for the next frame */
- memcpy(p->prev_excitation, buf + (FRAME_LEN - PITCH_MAX),
+ memcpy(p->prev_excitation, p->excitation + FRAME_LEN,
PITCH_MAX * sizeof(*p->excitation));
+ } else {
+ p->interp_gain = (p->interp_gain * 3 + 2) >> 2;
+ if (p->erased_frames == 3) {
+ /* Mute output */
+ memset(p->excitation, 0,
+ (FRAME_LEN + PITCH_MAX) * sizeof(*p->excitation));
+ memset(p->prev_excitation, 0,
+ PITCH_MAX * sizeof(*p->excitation));
+ memset(frame->data[0], 0,
+ (FRAME_LEN + LPC_ORDER) * sizeof(int16_t));
+ } else {
+ int16_t *buf = p->audio + LPC_ORDER;
+
+ /* Regenerate frame */
+ residual_interp(p->excitation, buf, p->interp_index,
+ p->interp_gain, &p->random_seed);
+
+ /* Save the excitation for the next frame */
+ memcpy(p->prev_excitation, buf + (FRAME_LEN - PITCH_MAX),
+ PITCH_MAX * sizeof(*p->excitation));
+ }
+ }
+ p->cng_random_seed = CNG_RANDOM_SEED;
+ } else {
+ if (p->cur_frame_type == SID_FRAME) {
+ p->sid_gain = sid_gain_to_lsp_index(p->subframe[0].amp_index);
+ ff_g723_1_inverse_quant(p->sid_lsp, p->prev_lsp, p->lsp_index, 0);
+ } else if (p->past_frame_type == ACTIVE_FRAME) {
+ p->sid_gain = estimate_sid_gain(p);
}
- }
- p->cng_random_seed = CNG_RANDOM_SEED;
- } else {
- if (p->cur_frame_type == SID_FRAME) {
- p->sid_gain = sid_gain_to_lsp_index(p->subframe[0].amp_index);
- ff_g723_1_inverse_quant(p->sid_lsp, p->prev_lsp, p->lsp_index, 0);
- } else if (p->past_frame_type == ACTIVE_FRAME) {
- p->sid_gain = estimate_sid_gain(p);
- }
- if (p->past_frame_type == ACTIVE_FRAME)
- p->cur_gain = p->sid_gain;
- else
- p->cur_gain = (p->cur_gain * 7 + p->sid_gain) >> 3;
- generate_noise(p);
- ff_g723_1_lsp_interpolate(lpc, p->sid_lsp, p->prev_lsp);
- /* Save the lsp_vector for the next frame */
- memcpy(p->prev_lsp, p->sid_lsp, LPC_ORDER * sizeof(*p->prev_lsp));
- }
+ if (p->past_frame_type == ACTIVE_FRAME)
+ p->cur_gain = p->sid_gain;
+ else
+ p->cur_gain = (p->cur_gain * 7 + p->sid_gain) >> 3;
+ generate_noise(p);
+ ff_g723_1_lsp_interpolate(lpc, p->sid_lsp, p->prev_lsp);
+ /* Save the lsp_vector for the next frame */
+ memcpy(p->prev_lsp, p->sid_lsp, LPC_ORDER * sizeof(*p->prev_lsp));
+ }
- p->past_frame_type = p->cur_frame_type;
+ p->past_frame_type = p->cur_frame_type;
- memcpy(p->audio, p->synth_mem, LPC_ORDER * sizeof(*p->audio));
- for (i = LPC_ORDER, j = 0; j < SUBFRAMES; i += SUBFRAME_LEN, j++)
- ff_celp_lp_synthesis_filter(p->audio + i, &lpc[j * LPC_ORDER],
- audio + i, SUBFRAME_LEN, LPC_ORDER,
- 0, 1, 1 << 12);
- memcpy(p->synth_mem, p->audio + FRAME_LEN, LPC_ORDER * sizeof(*p->audio));
+ memcpy(p->audio, p->synth_mem, LPC_ORDER * sizeof(*p->audio));
+ for (i = LPC_ORDER, j = 0; j < SUBFRAMES; i += SUBFRAME_LEN, j++)
+ ff_celp_lp_synthesis_filter(p->audio + i, &lpc[j * LPC_ORDER],
+ audio + i, SUBFRAME_LEN, LPC_ORDER,
+ 0, 1, 1 << 12);
+ memcpy(p->synth_mem, p->audio + FRAME_LEN, LPC_ORDER * sizeof(*p->audio));
- if (p->postfilter) {
- formant_postfilter(p, lpc, p->audio, out);
- } else { // if output is not postfiltered it should be scaled by 2
- for (i = 0; i < FRAME_LEN; i++)
- out[i] = av_clip_int16(p->audio[LPC_ORDER + i] << 1);
+ if (s->postfilter) {
+ formant_postfilter(p, lpc, p->audio, out);
+ } else { // if output is not postfiltered it should be scaled by 2
+ for (i = 0; i < FRAME_LEN; i++)
+ out[i] = av_clip_int16(p->audio[LPC_ORDER + i] << 1);
+ }
}
*got_frame_ptr = 1;
- return frame_size[dec_mode];
+ return frame_size[dec_mode] * avctx->channels;
}
#define OFFSET(x) offsetof(G723_1_Context, x)
#define AD AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM
static const AVOption options[] = {
- { "postfilter", "postfilter on/off", OFFSET(postfilter), AV_OPT_TYPE_INT,
+ { "postfilter", "enable postfilter", OFFSET(postfilter), AV_OPT_TYPE_BOOL,
{ .i64 = 1 }, 0, 1, AD },
{ NULL }
};