mirror of https://git.ffmpeg.org/ffmpeg.git
Combine the window and overlap loops,
and get rid of the data swapping. Patch by Ian Braithwaite <dk dot braithwaite at ian> Originally committed as revision 8387 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
e057461dac
commit
85e7386ae0
|
@ -684,33 +684,6 @@ static void mono_decode(COOKContext *q, float* mlt_buffer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The modulated lapped transform, this takes transform coefficients
|
|
||||||
* and transforms them into timedomain samples. This is done through
|
|
||||||
* an FFT-based algorithm with pre- and postrotation steps.
|
|
||||||
* A window and reorder step is also included.
|
|
||||||
*
|
|
||||||
* @param q pointer to the COOKContext
|
|
||||||
* @param inbuffer pointer to the mltcoefficients
|
|
||||||
* @param outbuffer pointer to the timedomain buffer
|
|
||||||
* @param mlt_tmp pointer to temporary storage space
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void cook_imlt(COOKContext *q, float* inbuffer, float* outbuffer)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
q->mdct_ctx.fft.imdct_calc(&q->mdct_ctx, outbuffer, inbuffer, q->mdct_tmp);
|
|
||||||
|
|
||||||
for(i = 0; i < q->samples_per_channel; i++){
|
|
||||||
float tmp = outbuffer[i];
|
|
||||||
|
|
||||||
outbuffer[i] = q->mlt_window[i] * outbuffer[q->samples_per_channel + i];
|
|
||||||
outbuffer[q->samples_per_channel + i] = q->mlt_window[q->samples_per_channel - 1 - i] * -tmp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* the actual requantization of the timedomain samples
|
* the actual requantization of the timedomain samples
|
||||||
*
|
*
|
||||||
|
@ -743,36 +716,50 @@ static void interpolate(COOKContext *q, float* buffer,
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* mlt overlapping and buffer management
|
* The modulated lapped transform, this takes transform coefficients
|
||||||
|
* and transforms them into timedomain samples.
|
||||||
|
* Apply transform window, overlap buffers, apply gain profile
|
||||||
|
* and buffer management.
|
||||||
*
|
*
|
||||||
* @param q pointer to the COOKContext
|
* @param q pointer to the COOKContext
|
||||||
|
* @param inbuffer pointer to the mltcoefficients
|
||||||
* @param gains_ptr current and previous gains
|
* @param gains_ptr current and previous gains
|
||||||
* @param previous_buffer pointer to the previous buffer to be used for overlapping
|
* @param previous_buffer pointer to the previous buffer to be used for overlapping
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void gain_compensate(COOKContext *q, cook_gains *gains_ptr,
|
static void imlt_gain(COOKContext *q, float *inbuffer,
|
||||||
float* previous_buffer)
|
cook_gains *gains_ptr, float* previous_buffer)
|
||||||
{
|
{
|
||||||
const float fc = q->pow2tab[gains_ptr->previous[0] + 63];
|
const float fc = q->pow2tab[gains_ptr->previous[0] + 63];
|
||||||
float *buffer = q->mono_mdct_output;
|
float *buffer0 = q->mono_mdct_output;
|
||||||
|
float *buffer1 = q->mono_mdct_output + q->samples_per_channel;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* Overlap with the previous block. */
|
/* Inverse modified discrete cosine transform */
|
||||||
for(i=0 ; i<q->samples_per_channel ; i++) {
|
q->mdct_ctx.fft.imdct_calc(&q->mdct_ctx, q->mono_mdct_output,
|
||||||
buffer[i] *= fc;
|
inbuffer, q->mdct_tmp);
|
||||||
buffer[i] += previous_buffer[i];
|
|
||||||
|
/* The weird thing here, is that the two halves of the time domain
|
||||||
|
* buffer are swapped. Also, the newest data, that we save away for
|
||||||
|
* next frame, has the wrong sign. Hence the subtraction below.
|
||||||
|
* Almost sounds like a complex conjugate/reverse data/FFT effect.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Apply window and overlap */
|
||||||
|
for(i = 0; i < q->samples_per_channel; i++){
|
||||||
|
buffer1[i] = buffer1[i] * fc * q->mlt_window[i] -
|
||||||
|
previous_buffer[i] * q->mlt_window[q->samples_per_channel - 1 - i];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Apply gain profile */
|
/* Apply gain profile */
|
||||||
for (i = 0; i < 8; i++) {
|
for (i = 0; i < 8; i++) {
|
||||||
if (gains_ptr->now[i] || gains_ptr->now[i + 1])
|
if (gains_ptr->now[i] || gains_ptr->now[i + 1])
|
||||||
interpolate(q, &buffer[q->gain_size_factor * i],
|
interpolate(q, &buffer1[q->gain_size_factor * i],
|
||||||
gains_ptr->now[i], gains_ptr->now[i + 1]);
|
gains_ptr->now[i], gains_ptr->now[i + 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Save away the current to be previous block. */
|
/* Save away the current to be previous block. */
|
||||||
memcpy(previous_buffer, buffer+q->samples_per_channel,
|
memcpy(previous_buffer, buffer0, sizeof(float)*q->samples_per_channel);
|
||||||
sizeof(float)*q->samples_per_channel);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -902,16 +889,16 @@ mlt_compensate_output(COOKContext *q, float *decode_buffer,
|
||||||
cook_gains *gains, float *previous_buffer,
|
cook_gains *gains, float *previous_buffer,
|
||||||
int16_t *out, int chan)
|
int16_t *out, int chan)
|
||||||
{
|
{
|
||||||
|
float *output = q->mono_mdct_output + q->samples_per_channel;
|
||||||
int j;
|
int j;
|
||||||
|
|
||||||
cook_imlt(q, decode_buffer, q->mono_mdct_output);
|
imlt_gain(q, decode_buffer, gains, previous_buffer);
|
||||||
gain_compensate(q, gains, previous_buffer);
|
|
||||||
|
|
||||||
/* Clip and convert floats to 16 bits.
|
/* Clip and convert floats to 16 bits.
|
||||||
*/
|
*/
|
||||||
for (j = 0; j < q->samples_per_channel; j++) {
|
for (j = 0; j < q->samples_per_channel; j++) {
|
||||||
out[chan + q->nb_channels * j] =
|
out[chan + q->nb_channels * j] =
|
||||||
av_clip(lrintf(q->mono_mdct_output[j]), -32768, 32767);
|
av_clip(lrintf(output[j]), -32768, 32767);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue