[FFmpeg-devel] AAC decoder round 9

Robert Swain robert.swain
Tue Aug 19 16:23:12 CEST 2008


2008/8/18 Michael Niedermayer <michaelni at gmx.at>:
> On Mon, Aug 18, 2008 at 08:42:53PM +0100, Robert Swain wrote:
>> $subj
>>
>> Will this be the last...? :)
>
> No, not yet :)

It may be, if I fix this bit of apply_tns(), I don't think there's
much point resubmitting as you'll know what the code looks like. :)

>> Rob
>
>> Index: libavcodec/aac.c
>> ===================================================================
>> --- libavcodec/aac.c  (revision 14828)
>> +++ libavcodec/aac.c  (working copy)
>> @@ -94,6 +94,17 @@
>>  static VLC vlc_spectral[11];
>>
>>
>> +// TODO: Maybe add to dsputil?!
>> +#if 0
>> +static void vector_fmul_add_add_add(DSPContext * dsp, float * dst, const float * src0, const float * src1,
>> +        const float * src2, const float * src3, float src4, int len) {
>> +    int i;
>> +    dsp->vector_fmul_add_add(dst, src0, src1, src2, src4, len, 1);
>> +    for (i = 0; i < len; i++)
>> +        dst[i] += src3[i];
>> +}
>> +#endif
>> +
>>  /**
>>   * Configure output channel order based on the current program configuration element.
>>   *
>
> ohh well, if you want this #if 0 code so be it
> ok, but please remove the "// TODO: Maybe add to dsputil?!" we do not want
> to move this there unless we find out that it is actually needed for these
> windows ...

I don't mind either way. I'm probably going to rip out the code which
calls this anyway and it's no problem to grab it from SoC if we ever
need it. So I won't bother with this one.

>>   * Decode Mid/Side data; reference: table 4.54.
>>   *
>>   * @param   ms_present  Indicates mid/side stereo presence. [0] mask is all 0s;
>> @@ -1067,6 +1116,57 @@
>>  }
>>
>>  /**
>> + * Decode Temporal Noise Shaping filter coefficients and apply all-pole filters; reference: 4.6.9.3.
>> + *
>> + * @param   decode  1 if tool is used normally, 0 if tool is used in LTP.
>> + * @param   coef    spectral coefficients
>> + */
>> +static void apply_tns(float coef[1024], TemporalNoiseShaping * tns, IndividualChannelStream * ics, int decode) {
>> +    const int mmm = FFMIN(ics->tns_max_bands,  ics->max_sfb);
>> +    int w, filt, m, i, ib;
>> +    int bottom, top, order, start, end, size, inc;
>> +    float tmp;
>> +    float lpc[TNS_MAX_ORDER + 1], b[TNS_MAX_ORDER + 1];
>> +
>> +    for (w = 0; w < ics->num_windows; w++) {
>> +        bottom = ics->num_swb;
>> +        for (filt = 0; filt < tns->n_filt[w]; filt++) {
>> +            top    = bottom;
>> +            bottom = FFMAX(0, top - tns->length[w][filt]);
>> +            order  = tns->order[w][filt];
>> +            if (order == 0)
>> +                continue;
>> +
>
>> +            // tns_decode_coef
>> +            lpc[0] = 1;
>> +            for (m = 1; m <= order; m++) {
>> +                lpc[m] = tns->coef[w][filt][m - 1];
>> +                for (i = 1; i < m; i++)
>> +                    b[i] = lpc[i] + lpc[m] * lpc[m-i];
>> +                for (i = 1; i < m; i++)
>> +                    lpc[i] = b[i];
>> +            }
>
> This loop looks oddly similar to the end of compute_lpc_coefs()
> and eval_lpc_coeffs() can something be factored out here?

Indeed, the 3GPP ref source calls this code the conversion of PARCOR
(PARtial autoCORrelation, according to a quick google) coefficients to
LPC coefficients. It doesn't, however, say what algorithm is used.

Short of fully unrolling the Levinson-Durbin algorithm functions you
mentioned and comparing to the aac.c code, it's not easy to see if
they're identical or not, nor which should be used. I'll try comparing
the results of some conversions before I resort to manual unrolling
with pen and paper. :)

Rob




More information about the ffmpeg-devel mailing list