Commit 6c7a0162 authored by Justin Ruggles's avatar Justin Ruggles

nellymoserenc: use proper MDCT overlap delay

parent 3e9cd8b4
...@@ -52,13 +52,11 @@ ...@@ -52,13 +52,11 @@
typedef struct NellyMoserEncodeContext { typedef struct NellyMoserEncodeContext {
AVCodecContext *avctx; AVCodecContext *avctx;
int last_frame; int last_frame;
int bufsel;
int have_saved;
DSPContext dsp; DSPContext dsp;
FFTContext mdct_ctx; FFTContext mdct_ctx;
DECLARE_ALIGNED(32, float, mdct_out)[NELLY_SAMPLES]; DECLARE_ALIGNED(32, float, mdct_out)[NELLY_SAMPLES];
DECLARE_ALIGNED(32, float, in_buff)[NELLY_SAMPLES]; DECLARE_ALIGNED(32, float, in_buff)[NELLY_SAMPLES];
DECLARE_ALIGNED(32, float, buf)[2][3 * NELLY_BUF_LEN]; ///< sample buffer DECLARE_ALIGNED(32, float, buf)[3 * NELLY_BUF_LEN]; ///< sample buffer
float (*opt )[NELLY_BANDS]; float (*opt )[NELLY_BANDS];
uint8_t (*path)[NELLY_BANDS]; uint8_t (*path)[NELLY_BANDS];
} NellyMoserEncodeContext; } NellyMoserEncodeContext;
...@@ -115,16 +113,17 @@ static const uint8_t quant_lut_offset[8] = { 0, 0, 1, 4, 11, 32, 81, 230 }; ...@@ -115,16 +113,17 @@ static const uint8_t quant_lut_offset[8] = { 0, 0, 1, 4, 11, 32, 81, 230 };
static void apply_mdct(NellyMoserEncodeContext *s) static void apply_mdct(NellyMoserEncodeContext *s)
{ {
s->dsp.vector_fmul(s->in_buff, s->buf[s->bufsel], ff_sine_128, NELLY_BUF_LEN); float *in0 = s->buf;
s->dsp.vector_fmul_reverse(s->in_buff + NELLY_BUF_LEN, s->buf[s->bufsel] + NELLY_BUF_LEN, ff_sine_128, float *in1 = s->buf + NELLY_BUF_LEN;
NELLY_BUF_LEN); float *in2 = s->buf + 2 * NELLY_BUF_LEN;
s->dsp.vector_fmul (s->in_buff, in0, ff_sine_128, NELLY_BUF_LEN);
s->dsp.vector_fmul_reverse(s->in_buff + NELLY_BUF_LEN, in1, ff_sine_128, NELLY_BUF_LEN);
s->mdct_ctx.mdct_calc(&s->mdct_ctx, s->mdct_out, s->in_buff); s->mdct_ctx.mdct_calc(&s->mdct_ctx, s->mdct_out, s->in_buff);
s->dsp.vector_fmul(s->buf[s->bufsel] + NELLY_BUF_LEN, s->buf[s->bufsel] + NELLY_BUF_LEN, s->dsp.vector_fmul (s->in_buff, in1, ff_sine_128, NELLY_BUF_LEN);
ff_sine_128, NELLY_BUF_LEN); s->dsp.vector_fmul_reverse(s->in_buff + NELLY_BUF_LEN, in2, ff_sine_128, NELLY_BUF_LEN);
s->dsp.vector_fmul_reverse(s->buf[s->bufsel] + 2 * NELLY_BUF_LEN, s->buf[1 - s->bufsel], ff_sine_128, s->mdct_ctx.mdct_calc(&s->mdct_ctx, s->mdct_out + NELLY_BUF_LEN, s->in_buff);
NELLY_BUF_LEN);
s->mdct_ctx.mdct_calc(&s->mdct_ctx, s->mdct_out + NELLY_BUF_LEN, s->buf[s->bufsel] + NELLY_BUF_LEN);
} }
static av_cold int encode_end(AVCodecContext *avctx) static av_cold int encode_end(AVCodecContext *avctx)
...@@ -161,6 +160,7 @@ static av_cold int encode_init(AVCodecContext *avctx) ...@@ -161,6 +160,7 @@ static av_cold int encode_init(AVCodecContext *avctx)
} }
avctx->frame_size = NELLY_SAMPLES; avctx->frame_size = NELLY_SAMPLES;
avctx->delay = NELLY_BUF_LEN;
s->avctx = avctx; s->avctx = avctx;
if ((ret = ff_mdct_init(&s->mdct_ctx, 8, 0, 32768.0)) < 0) if ((ret = ff_mdct_init(&s->mdct_ctx, 8, 0, 32768.0)) < 0)
goto error; goto error;
...@@ -369,32 +369,26 @@ static int encode_frame(AVCodecContext *avctx, uint8_t *frame, int buf_size, voi ...@@ -369,32 +369,26 @@ static int encode_frame(AVCodecContext *avctx, uint8_t *frame, int buf_size, voi
{ {
NellyMoserEncodeContext *s = avctx->priv_data; NellyMoserEncodeContext *s = avctx->priv_data;
const float *samples = data; const float *samples = data;
int i;
if (s->last_frame) if (s->last_frame)
return 0; return 0;
memcpy(s->buf, s->buf + NELLY_SAMPLES, NELLY_BUF_LEN * sizeof(*s->buf));
if (data) { if (data) {
memcpy(s->buf[s->bufsel], samples, avctx->frame_size * sizeof(*samples)); memcpy(s->buf + NELLY_BUF_LEN, samples, avctx->frame_size * sizeof(*s->buf));
for (i = avctx->frame_size; i < NELLY_SAMPLES; i++) { if (avctx->frame_size < NELLY_SAMPLES) {
s->buf[s->bufsel][i] = 0; memset(s->buf + NELLY_BUF_LEN + avctx->frame_size, 0,
} (NELLY_SAMPLES - avctx->frame_size) * sizeof(*s->buf));
s->bufsel = 1 - s->bufsel; if (avctx->frame_size >= NELLY_BUF_LEN)
if (!s->have_saved) { s->last_frame = 1;
s->have_saved = 1;
return 0;
} }
} else { } else {
memset(s->buf[s->bufsel], 0, sizeof(s->buf[0][0]) * NELLY_BUF_LEN); memset(s->buf + NELLY_BUF_LEN, 0, NELLY_SAMPLES * sizeof(*s->buf));
s->bufsel = 1 - s->bufsel;
s->last_frame = 1; s->last_frame = 1;
} }
if (s->have_saved) {
encode_block(s, frame, buf_size); encode_block(s, frame, buf_size);
return NELLY_BLOCK_LEN; return NELLY_BLOCK_LEN;
}
return 0;
} }
AVCodec ff_nellymoser_encoder = { AVCodec ff_nellymoser_encoder = {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment