[FFmpeg-devel] [PATCH] WMA Voice decoder

Ronald S. Bultje rsbultje
Tue Feb 9 22:17:31 CET 2010


Hi,

On Tue, Feb 9, 2010 at 2:17 PM, Vitor Sessak <vitor1001 at gmail.com> wrote:
> Ronald S. Bultje wrote:
>> On Tue, Feb 9, 2010 at 1:21 PM, Vitor Sessak <vitor1001 at gmail.com> wrote:
>>>> ? /*
>>>> ? ?* Pitch (per ACB type):
>>>> ? ?* - type 0: unused
>>>> ? ?* - type 1: provided (globally) for the whole frame. In
>>>> #synth_block(),
>>>> ? ?* ? ? ? ? ? ?we derive the "pitch-per-sample" for adaptive codebook
>>>> ? ?* ? ? ? ? ? ?reading.
>>>> ? ?* - type 2: provided per block (see just before the call to
>>>> ? ?* ? ? ? ? ? ?#synth_block()), so not read here.
>>>> ? ?*/
>>>> ? switch (frame_descs[bd_idx].acb_type) {
>>>> ? case ACB_TYPE_NONE:
>>>> ? ? ? memset(pitch, 0, sizeof(pitch[0]) * frame_descs[bd_idx].n_blocks);
>>>> ? ? ? break;
>>>> ? case ACB_TYPE_ASYMMETRIC:
>>>> ? ? ? n_blocks_x2 ? ? ?= frame_descs[bd_idx].n_blocks << 1;
>>>> ? ? ? log_n_blocks_x2 ?= frame_descs[bd_idx].log_n_blocks + 1;
>>>> ? ? ? cur_pitch_val ? ?= s->min_pitch_val + get_bits(gb,
>>>> s->pitch_nbits);
>>>> ? ? ? if (s->last_acb_type == ACB_TYPE_NONE ||
>>>> ? ? ? ? ? 20 * abs(cur_pitch_val - s->last_pitch_val) >
>>>> ? ? ? ? ? ? ? (cur_pitch_val + s->last_pitch_val))
>>>> ? ? ? ? ? s->last_pitch_val = cur_pitch_val;
>>>>
>>>> ? ? ? /* pitch per frame/block */
>>>> ? ? ? for (n = 0; n < frame_descs[bd_idx].n_blocks; n++) {
>>>> ? ? ? ? ? int fac = n * 2 + 1;
>>>>
>>>> ? ? ? ? ? pitch[n] = (MUL16(fac, ? ? ? ? ? ? ? ? cur_pitch_val) +
>>>> ? ? ? ? ? ? ? ? ? ? ? MUL16((n_blocks_x2 - fac), s->last_pitch_val) +
>>>> ? ? ? ? ? ? ? ? ? ? ? frame_descs[bd_idx].n_blocks) >> log_n_blocks_x2;
>>>> ? ? ? }
>>>
>>> Here you calculate pitch[] for ACB_TYPE_NONE and ACB_TYPE_ASYMMETRIC
>>>
>>>> ? for (n = 0; n < frame_descs[bd_idx].n_blocks; n++) {
>>>> ? ? ? int bl_pitch_sh2 = pitch[n] << 2;
>>>>
>>>> ? ? ? /*
>>>> ? ? ? ?* If pitch is given per block, parse that first. Per-block
>>>> pitches
>>>> ? ? ? ?* are encoded as an absolute value for the first block, and then
>>>> ? ? ? ?* delta values for all subsequent blocks. The scale of this value
>>>> ? ? ? ?* is semi-logarithmic compared to normal scale, so convert also.
>>>> ? ? ? ?*/
>>>> ? ? ? if (frame_descs[bd_idx].acb_type == ACB_TYPE_HAMMING) {
>>>> ? ? ? ? ? int block_pitch,
>>>> ? ? ? ? ? ? ? t1 = (s->block_conv_table[1] - s->block_conv_table[0]) <<
>>>> 2,
>>>> ? ? ? ? ? ? ? t2 = (s->block_conv_table[2] - s->block_conv_table[1]) <<
>>>> 1,
>>>> ? ? ? ? ? ? ? t3 = ?s->block_conv_table[3] - s->block_conv_table[2] + 1;
>>>>
>>>> ? ? ? ? ? if (n == 0) {
>>>> ? ? ? ? ? ? ? block_pitch = get_bits(gb, s->block_pitch_nbits);
>>>> ? ? ? ? ? } else
>>>> ? ? ? ? ? ? ? block_pitch = last_block_pitch -
>>>> s->block_delta_pitch_hrange +
>>>> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?get_bits(gb, s->block_delta_pitch_nbits);
>>>> ? ? ? ? ? /* Convert last_ so that any next delta is within _range */
>>>> ? ? ? ? ? last_block_pitch = av_clip(block_pitch,
>>>> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?s->block_delta_pitch_hrange,
>>>> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?s->block_pitch_range -
>>>> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?s->block_delta_pitch_hrange);
>>>>
>>>> ? ? ? ? ? /* Convert semi-log-style scale back to normal scale */
>>>> ? ? ? ? ? if (block_pitch < t1) {
>>>> ? ? ? ? ? ? ? bl_pitch_sh2 = (s->block_conv_table[0] << 2) +
>>>> block_pitch;
>>>> ? ? ? ? ? } else {
>>>> ? ? ? ? ? ? ? block_pitch -= t1;
>>>> ? ? ? ? ? ? ? if (block_pitch < t2) {
>>>> ? ? ? ? ? ? ? ? ? bl_pitch_sh2 =
>>>> ? ? ? ? ? ? ? ? ? ? ? (s->block_conv_table[1] << 2) + (block_pitch <<
>>>> 1);
>>>> ? ? ? ? ? ? ? } else {
>>>> ? ? ? ? ? ? ? ? ? block_pitch -= t2;
>>>> ? ? ? ? ? ? ? ? ? if (block_pitch < t3) {
>>>> ? ? ? ? ? ? ? ? ? ? ? bl_pitch_sh2 =
>>>> ? ? ? ? ? ? ? ? ? ? ? ? ? (s->block_conv_table[2] + block_pitch) << 2;
>>>> ? ? ? ? ? ? ? ? ? } else
>>>> ? ? ? ? ? ? ? ? ? ? ? bl_pitch_sh2 = s->block_conv_table[3] << 2;
>>>> ? ? ? ? ? ? ? }
>>>> ? ? ? ? ? }
>>>> ? ? ? ? ? pitch[n] = bl_pitch_sh2 >> 2;
>>>> ? ? ? }
>>>
>>> And here you calculate it for ACB_TYPE_HAMMING. It is kind of
>>> inconsistent.
>>
>> Right, I calculate in order of appearance in the bitstream.
>
> Ugly bitstream format :p
>
>> Would you
>> prefer I do the for() loop calculating the asymmetric-acb-pitch within
>> the loop that calls synth_block()?
>
> Yes if it is more readable (what I expect).

Ugh that didn't work, pitch is used before the loop in that case, for
pitch-adaptive window coordinate calculation (but is not yet specified
in the bitstream otherwise).

I re-arranged it a bit to get rid of the memset() anyway.

Ronald



More information about the ffmpeg-devel mailing list