[FFmpeg-devel] [PATCH] WMA Voice postfilter
Vitor Sessak
vitor1001
Thu Apr 1 13:48:49 CEST 2010
Ronald S. Bultje wrote:
> Hi Vitor,
>
> On Thu, Mar 18, 2010 at 6:52 PM, Vitor Sessak <vitor1001 at gmail.com> wrote:
>> Ronald S. Bultje wrote:
>>> On Thu, Mar 18, 2010 at 4:33 PM, Vitor Sessak <vitor1001 at gmail.com> wrote:
>>>>> + /* calculate the Hilbert transform of the gains, which we do (since
>>>>> this
>>>>> + * is a sinus input) by doing a phase shift (in theory,
>>>>> H(sin())=cos()).
>>>>> + * Because input is symmetric (mirror above), every im[n] is zero.
>>>>> */
>>>>> + ff_rdft_calc(&s->rdft, &lpcs[1]);
>>>>> + lpcs[1] = lpcs[2];
>>>>> + lpcs[2] = lpcs[0] = 0;
>>>>> + ff_rdft_calc(&s->irdft, lpcs);
>>>> I think this deserve to be in a separate function (and that would include
>>>> the mirroring), it could be reused in case we need a Hilbert transform in
>>>> another codec. Also I think it should be possible to do it with a half as
>>>> big FFT...
>>> Hm. That's a good idea. Now, I can't assume input to be aligned or
>>> padded, so that'd add an extra memcpy, is that OK?
>> I didn't mean to make it a shared function, but just move the code in its
>> own function, so when any other codec need it will be trivial to make it
>> public. So IMHO you can just assume whatever alignment/padding is needed
>> (but document it).
>>
>> Also, you do both
>>
>>> + ff_rdft_calc(&s->rdft, &lpcs[1]);
>>> + ff_rdft_calc(&s->irdft, lpcs);
>> Since either &lpcs[1] or lpcs will be unaligned this code will segfault when
>> compiled with YASM assembly enabled. But there is no point in fixing this
>> before looking in a way to do the Hilbert transform with a buffer half the
>> size. I'll give a look this weekend if I have time.
>
> The *_calc() on array + 1 is gone now (that was relatively easy),
> leaving the Hilbert transform as per your new functions (and thank to
> your patch) as:
>
> /* calculate the Hilbert transform of the gains, which we do (since this
> * is a sinus input) by doing a phase shift (in theory, H(sin())=cos()). */
> ff_dct_calc(&s->dct, lpcs);
> ff_dct_calc(&s->dst, lpcs);
Nice!
> Should that still be its own function? Seems like desperate overkill
> to me, so I didn't yet. If you really want me to, I'll do it.
I don't see the point any more to separate it either.
> New patch with my current version attached, the calc_coeffs() might be
> a bit rough because I basically just changed it to work and didn't pay
> much attention to the comments yet... Comments welcome.
It very likely still crashes with YASM enabled. You are still passing
buffers to {D,RD}FT that has whatever random alignment the compiler
decided to give them. You should move some buffers to the context and
use DECLARE_ALIGNED(16, ...).
> + for (n = 0x3F; n > 0; n--) {
> + float sin, cos;
> +
> + idx = av_clip((n & 1 ? -lpcs[64] : +lpcs[64]) - 2 * lpcs[n - 1], -255, 255);
> + if (idx >= 0) {
> + sin = ff_sine_256[ idx];
> + cos = ff_sine_256[255 - idx];
> + } else {
> + sin = -ff_sine_256[ -idx];
> + cos = ff_sine_256[255 + idx];
> + }
> + coeffs[n * 2 + 1] = coeffs[n + 1] * sin;
> + coeffs[n * 2] = coeffs[n + 1] * cos;
> + }
The branches are expensive and can be easily avoided with a bigger table
and unrolling the loop once.
-Vitor
More information about the ffmpeg-devel
mailing list