[FFmpeg-devel] [PATCH] TwinVQ decoder

Vitor Sessak vitor1001
Mon Jul 13 15:45:58 CEST 2009


Michael Niedermayer wrote:
> On Mon, Jun 08, 2009 at 10:01:40PM +0200, Vitor Sessak wrote:
>> Michael Niedermayer wrote:
>>> On Mon, May 18, 2009 at 06:32:55PM +0200, Vitor Sessak wrote:
>>>> Michael Niedermayer wrote:
>>>>> On Wed, May 06, 2009 at 05:09:50PM +0200, Vitor Sessak wrote:
>>>>>> Vitor Sessak wrote:
> [...]
>>>> /**
>>>>  * Evaluate a single LPC amplitude spectrum envelope coefficient from the 
>>>> line
>>>>  * spectrum pairs
>>>>  *
>>>>  * @param cos_lsp a vector of the cosinus of the LSP values
>>>>  * @param cos_val cos(PI*i/N) where i is the index of the LPC amplitude
>>>>  * @return the LPC value
>>>>  *
>>>>  * @todo reuse code from vorbis_dec.c: vorbis_floor0_decode
                                             ^^^^^^^^^^^^^^^^^^^^

>>>>  */
>>>> static float eval_lpc_spectrum(const float *cos_lsp, float cos_val, int 
>>>> size)
>>>> {
>>>>     int i;
>>>>     float a = .5;
>>>>     float b = .5;
>>>>
>>>>     for (i=0; i < size; i += 2) {
>>>>         a *= 2*cos_val - cos_lsp[i  ];
>>>>         b *= 2*cos_val - cos_lsp[i+1];
>>>>     }
>>>>
>>>>     a *= a*(2+2*cos_val);
>>>>     b *= b*(2-2*cos_val);
>>>>
>>>>     return .5/(a+b);
>>>> }
>>> if iam not too tired the .5 and 2 are useless
>> It is, but it is like that to make it easier to see in what way it is 
>> similar to vorbis_floor0_decode().
> 
> add a comment that says that please

See above...


[... Comments that where changes as suggestion ...]

>> /**
>>  * Evaluates the LPC amplitude spectrum envelope from the line spectrum pairs.
>>  * Probably for speed reasons, the coefficients are evaluated like
>>  * siiiibiiiiisiiiibiiiiisiiiibiiiiisiiiibiiiiis ...
>>  * where s is an evaluated value, i is a value interpolated from the others
>>  * and b might be either calculated or interpolated, dependent on a
>>  * unexplained condition.
>>  *
>>  * @param step the size of a block "siiiibiiii"
>>  * @param in the cosinus of the LSP data
>>  */
>> static inline void eval_lpcenv_or_interp(float *out, const float *in,
>>                                          int size, int step, int sub,
>>                                          const ModeTab *mtab, int forward)
>> {
>>     int i;
>>     const float *cos_tab = ff_cos_tabs[av_log2(mtab->size)-1];
>>
>>     // Fill the 's'
>>     for (i=0; i < size; i += step)
>>         out[i] =
>>             eval_lpc_spectrum(in,
>>                               GET_COS(sub, i*4+2, forward,
>>                                       cos_tab, 2*mtab->size - sub*size*2),
>>                               mtab->n_lsp);
>>
>>     // Fill the 'b'
>>     for (i=step; i < size - step; i += step) {
>>         if ((out[i + step] + out[i - step] > 1.95*out[i]) ||
>>             (out[i - step]               <= out[i + step])) {
>>             out[i - step/2] = (out[i] + out[i-step])*.5;
>>         } else {
>>             out[i - step/2] =
>>                 eval_lpc_spectrum(in,
>>                                   GET_COS(sub, 4*i-2*step+2, forward,
>>                                           cos_tab,
>>                                           2*mtab->size - sub*size*2),
>>                                   mtab->n_lsp);
>>         }
>>     }
>>
>>     // Fill the 'i'
>>     for (i=step; i < size - step; i += step/2)
>>         interpolate(out + i-step  +1, out[i-step/2], out[i-step  ], step/2);
>>
>>     interpolate(out+i-step+1, out[i], out[i-step], step);
> 
> hmm, still ugly
> 
> what about something like: (note its buggy but the idea should be clear)
> {
>     if(!(i&step) || (out[i + step]  + out[i - step] <= 1.95*out[i] &&
>                      out[i + step] < out[i - step]                   )){
>         eval_lpc_spectrum
>         if(i)
>             interpolate(i, last_point);
>         last_point= i
>     }
> }
> 
> the b really is just a longer interpolation AFAICS

The problem is that to know if the "b" will be evaluated or 
interpolated, one needs to have the previous and the following "s" 
already calculated. So doing in one pass is not really possible cleanly. 
I've made it in two passes ("i"s, then "s" and "b");

[... more comments that have been taken care of ...]

>> static void extend_pitch(int a1, const float *pitch, float pit_gain,
>>                          float *speech, TwinContext *tctx)
>> {
>>     const ModeTab *mtab = tctx->mtab;
>>     int pos;
> 
>>     int unk1;
>>     int unk2;
> 
> ehm
> 
> 
>>     int fcmax_i, fcmin_i;
>>     int i, j;
>>     int basf_step = (1 << mtab->basf_bit) - 1;
>>     int isampf = tctx->avctx->sample_rate/1000;
>>     int ibps = tctx->avctx->bit_rate/(1000 * tctx->avctx->channels);
>>
>>     fcmin_i = (  40*2*mtab->size + isampf/2)/isampf;
>>     fcmax_i = (6*40*2*mtab->size + isampf/2)/isampf;
>>
>>     unk1 = fcmin_i +  (a1*(fcmax_i - fcmin_i) + basf_step/2)/basf_step;
>>
>>     if ((isampf == 22) && (ibps == 32)) {
>>         unk2 = ((unk1 + 800LL)* mtab->pitch_cst * mtab->pit_cb_len * unk1 +
>>                200LL * mtab->size*unk1)/
>>             (400LL * mtab->size * unk1);
>>     } else
>>         unk2 = (mtab->pitch_cst * mtab->pit_cb_len * unk1)/(400 * mtab->size);
>>
>>     for (i=0; i < unk2/2; i++)
>>         speech[i] += pit_gain * pitch[i];
>>
>>     pos = unk2/2;
>>
>>     for (i=0; i < mtab->pit_cb_len; i++) {
>>         int v38 = very_broken_op(unk1, i + 1);
> 
> v38 ?
> 
> also i should mention that a 1:1 convertion to C from disassembly might not
> be legal, we need an independant implementation of things
> variables with names that look like they are copied from a disassembler
> raise a big red flag here and you will have to convince me that you really
> wrote an independant implementation if you want to see this in svn

Rewritten all the functions that were not reimplemented from scratch.

New patch attached. Now tables were converted to int16_t, and now 
stripped twinvq.o weights "only" 200kb.

To avoid the need for moderation the twinvq_data.c file was trimmed. One 
can find the full version at http://vsessak.googlepages.com/twinvq_data.h .

-Vitor
-------------- next part --------------
A non-text attachment was scrubbed...
Name: twinvq.c
Type: text/x-csrc
Size: 37233 bytes
Desc: not available
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20090713/ea2345e9/attachment.c>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: twinvq_data.h
Type: text/x-chdr
Size: 13509 bytes
Desc: not available
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20090713/ea2345e9/attachment.h>



More information about the ffmpeg-devel mailing list