[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