[FFmpeg-devel] AAC decoder round 9

Vitor Sessak vitor1001
Wed Aug 20 15:47:18 CEST 2008


Robert Swain wrote:
> 2008/8/19 Robert Swain <robert.swain at gmail.com>:
>> 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. :)
> 
> Hrm. I can't get eval_lpc_coeffs() to work with a coef input vector
> populated from tns_tmp2_map.
> 
> static int eval_lpc_coeffs(const float *in, float *tgt, int n)
> {
>     int i, j;
>     double f0, f1, f2;
> 
>     if (in[n] == 0)
>         return -1;
> 
>     if ((f0 = *in) <= 0)
>         return -1;
> 
>     in--; // To avoid a -1 subtraction in the inner loop
> 
>     for (i=1; i <= n; i++) {
>         f1 = in[i+1];
> 
>         for (j=0; j < i - 1; j++)
>             f1 += in[i-j]*tgt[j];
> 
>         tgt[i-1] = f2 = -f1/f0;
>         for (j=0; j < i >> 1; j++) {
>             float temp = tgt[j] + tgt[i-j-2]*f2;
>             tgt[i-j-2] += tgt[j]*f2;
>             tgt[j] = temp;
>         }
>         if ((f0 += f1*f2) < 0)
>             return -1;
>     }
> 
>     return 0;
> }
> 
> It seems the various conditions on in[] and f0 cause it to exit with
> an error with the coef[] vectors I've tried and as they're potentially
> valid, that's disconcerting for using this code.
> 
> compute_lpc_coefs() accepts a two dimensional lpc array as an
> argument. I'm guessing this so that the coefficients are available for
> various orders ready for testing to choose which is best or something
> like that.
> 
> Do you have any advice for how to proceed? I'm going to keep prodding
> eval_lpc_coeffs() in the mean time.

Can the following patch be modified to work with AAC too?

-Vitor, who just came back from vacations

PS: Am I the only one who find confusing having a file named lpc.c but 
having a public lpc filtering function in acelp_filters.c 
(ff_acelp_lp_synthesis_filter())?
-------------- next part --------------
A non-text attachment was scrubbed...
Name: lpc.diff
Type: text/x-diff
Size: 7373 bytes
Desc: not available
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20080820/703d4e64/attachment.diff>



More information about the ffmpeg-devel mailing list