[FFmpeg-devel] [PATCH] TwinVQ decoder
Vitor Sessak
vitor1001
Wed Jul 22 09:16:50 CEST 2009
Vitor Sessak wrote:
> 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 .
New version attached. Changes:
- Use DSP functions
- Do not alloc big buffers on the stack
- Some random optimizations
- Diego's cosmetics suggestions
-Vitor
-------------- next part --------------
A non-text attachment was scrubbed...
Name: twinvq.c
Type: text/x-csrc
Size: 38308 bytes
Desc: not available
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20090722/60c1f5b5/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/20090722/60c1f5b5/attachment.h>
More information about the ffmpeg-devel
mailing list