Commit b087ce2b authored by Martin Storsjö's avatar Martin Storsjö

g722: Fix the QMF scaling

This fixes clipping if the encoder input used the full 16 bit
input range (samples with a magnitude below 16383 worked fine).
The filtered subband samples should be 15 bit maximum, while
the code earlier produced them scaled to 16 bit.

This makes the decoder output have double the magnitude
compared to before.

The spec reference samples doesn't test the QMF at all, which
was why this part slipped past initially.
Signed-off-by: 's avatarMartin Storsjö <martin@martin.st>
parent 56bf24ad
...@@ -126,8 +126,8 @@ static int g722_decode_frame(AVCodecContext *avctx, void *data, ...@@ -126,8 +126,8 @@ static int g722_decode_frame(AVCodecContext *avctx, void *data,
c->prev_samples[c->prev_samples_pos++] = rlow - rhigh; c->prev_samples[c->prev_samples_pos++] = rlow - rhigh;
ff_g722_apply_qmf(c->prev_samples + c->prev_samples_pos - 24, ff_g722_apply_qmf(c->prev_samples + c->prev_samples_pos - 24,
&xout1, &xout2); &xout1, &xout2);
*out_buf++ = av_clip_int16(xout1 >> 12); *out_buf++ = av_clip_int16(xout1 >> 11);
*out_buf++ = av_clip_int16(xout2 >> 12); *out_buf++ = av_clip_int16(xout2 >> 11);
if (c->prev_samples_pos >= PREV_SAMPLES_BUF_SIZE) { if (c->prev_samples_pos >= PREV_SAMPLES_BUF_SIZE) {
memmove(c->prev_samples, c->prev_samples + c->prev_samples_pos - 22, memmove(c->prev_samples, c->prev_samples + c->prev_samples_pos - 22,
22 * sizeof(c->prev_samples[0])); 22 * sizeof(c->prev_samples[0]));
......
...@@ -136,8 +136,8 @@ static inline void filter_samples(G722Context *c, const int16_t *samples, ...@@ -136,8 +136,8 @@ static inline void filter_samples(G722Context *c, const int16_t *samples,
c->prev_samples[c->prev_samples_pos++] = samples[0]; c->prev_samples[c->prev_samples_pos++] = samples[0];
c->prev_samples[c->prev_samples_pos++] = samples[1]; c->prev_samples[c->prev_samples_pos++] = samples[1];
ff_g722_apply_qmf(c->prev_samples + c->prev_samples_pos - 24, &xout1, &xout2); ff_g722_apply_qmf(c->prev_samples + c->prev_samples_pos - 24, &xout1, &xout2);
*xlow = xout1 + xout2 >> 13; *xlow = xout1 + xout2 >> 14;
*xhigh = xout1 - xout2 >> 13; *xhigh = xout1 - xout2 >> 14;
if (c->prev_samples_pos >= PREV_SAMPLES_BUF_SIZE) { if (c->prev_samples_pos >= PREV_SAMPLES_BUF_SIZE) {
memmove(c->prev_samples, memmove(c->prev_samples,
c->prev_samples + c->prev_samples_pos - 22, c->prev_samples + c->prev_samples_pos - 22,
......
1975cc4a3521e374b33ae042e182f6b6 *./tests/data/acodec/g722.wav 7b0492eee76b04b710990235f97a0bf2 *./tests/data/acodec/g722.wav
48053 ./tests/data/acodec/g722.wav 48053 ./tests/data/acodec/g722.wav
ade04cdcf249e6946395f109b077dd62 *./tests/data/g722.acodec.out.wav b5568e0e3930ff563824156e8e1015f0 *./tests/data/g722.acodec.out.wav
stddev: 8841.24 PSNR: 17.40 MAXDIFF:36225 bytes: 191980/ 1058400 stddev: 8939.44 PSNR: 17.30 MAXDIFF:40370 bytes: 191980/ 1058400
This diff is collapsed.
750269cc236541df28e15da5c7b0df7a 94e2f200d6e05b47cec4aa3e94571cf3
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