[FFmpeg-devel] [PATCH] WMA Voice decoder

Vitor Sessak vitor1001
Thu Feb 4 06:06:15 CET 2010


Ronald S. Bultje wrote:
> Hi,
> 
> On Tue, Feb 2, 2010 at 11:35 AM, Ronald S. Bultje <rsbultje at gmail.com> wrote:
>> (Work on aw_*() is still ongoing...)
> 
> I have something without the crazy loops and using av_log2(), maybe
> this is better?

I'll give just a look now, will do a full review later

> +/**
> + * @}
> + * @defgroup aw Pitch-adaptive window coding functions
> + * The next few functions are for pitch-adaptive window coding.
> + * @{
> + */
> +#define NO_OFFSET -255
> +/**
> + * Parse the offset of the first pitch-adaptive window pulses, and
> + * the distribution of pulses between the two blocks in this frame.
> + * @param ctx WMA Voice decoding context
> + * @param gb bit I/O context
> + * @param pitch pitch for each block in this frame
> + */
> +static void aw_parse_coords(AVCodecContext *ctx, GetBitContext *gb,
> +                            const int *pitch)
> +{
> +    static const int16_t start_offset[94] = {
> +        -11,  -9,  -7,  -5,  -3,  -1,   1,   3,   5,   7,   9,  11,
> +         13,  15,  18,  17,  19,  20,  21,  22,  23,  24,  25,  26,
> +         27,  28,  29,  30,  31,  32,  33,  35,  37,  39,  41,  43,
> +         45,  47,  49,  51,  53,  55,  57,  59,  61,  63,  65,  67,
> +         69,  71,  73,  75,  77,  79,  81,  83,  85,  87,  89,  91,
> +         93,  95,  97,  99, 101, 103, 105, 107, 109, 111, 113, 115,
> +        117, 119, 121, 123, 125, 127, 129, 131, 133, 135, 137, 139,
> +        141, 143, 145, 147, 149, 151, 153, 155, 157, 159
> +    };
> +    WMAVoiceContext *s = ctx->priv_data;
> +    int bits, n, offset, off_table[11], first_idx[2];
> +
> +    s->aw_idx_is_ext = 0;
> +    if ((bits = get_bits(gb, 6)) >= 54) {
> +        s->aw_idx_is_ext = 1;
> +        bits += (bits - 54) * 3 + get_bits(gb, 2);
> +    }
> +    s->aw_pitch_range = FFMIN(pitch[0], pitch[1]) > 32 ? 24 : 16;
> +
> +    offset = start_offset[bits];
> +    for (n = 0; n < 11 && offset < MAX_FRAMESIZE; n++) {
> +        off_table[n] = offset;
> +        offset += pitch[offset >= MAX_FRAMESIZE / 2];
> +    }

nmax = x;

> +    if (n < 11)
> +        memset(&off_table[n], -1, (11 - n) * sizeof(int));
> +
> +    s->aw_n_pulses[0]        = s->aw_n_pulses[1]        = 0;
> +    s->aw_first_pulse_off[0] = s->aw_first_pulse_off[1] = NO_OFFSET;
> +    first_idx[0]             = first_idx[1]             = 0;
> +    for (n = 0; n < 11; n++) {

It looks like the memset can go away if you do "for(n=0; n < nmax; n++)"

> +        if (off_table[n] >= 0) {

Maybe you can get rid of this loop by starting the loop on n with the 
right value

> +            int idx = off_table[n] >= MAX_FRAMESIZE / 2;
> +
> +            if (s->aw_n_pulses[idx]++ == 0) {
> +                s->aw_first_pulse_off[idx] = off_table[n] -
> +                    (idx * MAX_FRAMESIZE + s->aw_pitch_range) / 2;
> +                first_idx[idx]             = n;
> +            }
> +        }
> +    }
> +    for (n = 0; n < 2; n++)
> +        if (first_idx[n] > 0)
> +            while (s->aw_first_pulse_off[n] - pitch[n] + s->aw_pitch_range > 0)
> +                s->aw_first_pulse_off[n] -= pitch[n];
> +}

> +/**
> + * Apply second set of pitch-adaptive window pulses.
> + * @param s WMA Voice decoding context private data
> + * @param gb bit I/O context
> + * @param block_idx block index in frame [0, 1]
> + * @param fcb structure containing fixed codebook vector info
> + */
> +static void aw_pulse_set2(WMAVoiceContext *s, GetBitContext *gb,
> +                          int block_idx, AMRFixed *fcb)
> +{
> +    uint16_t use_mask[7]; // only 5 are used, rest is padding
> +    int pulse_off = s->aw_first_pulse_off[block_idx],
> +        pulse_start, n, idx, range, aidx, start_off = 0;
> +
> +    /* set offset of first pulse to within this block */
> +    if (pulse_off != NO_OFFSET)
> +        while (pulse_off + s->aw_pitch_range < 1)
> +            pulse_off += fcb->pitch_lag;
> +
> +    /* find range per pulse */
> +    if (s->aw_n_pulses[0]) {
> +        if (block_idx == 0) {
> +            range = 32;
> +        } else /* block_idx = 1 */ {
> +            range = 8;
> +            if (pulse_off != NO_OFFSET) pulse_off = s->aw_next_pulse_off_cache;
> +        }
> +    } else
> +        range = 16;
> +    pulse_start = pulse_off != NO_OFFSET ? pulse_off - range / 2 : 0;
> +
> +    /* exclude ranges from pulses */
> +    memset(use_mask, -1, 10);
> +    if (pulse_off != NO_OFFSET)
> +        for (idx = pulse_off; idx < MAX_FRAMESIZE / 2; idx += fcb->pitch_lag) {
> +            int range             = s->aw_pitch_range; // always 16 or 24
> +            int idx_sh            = idx >> 4;
> +            int idx_mask          = idx & 15;
> +            use_mask[idx_sh++]   &= ~(0xFFFF >> idx_mask);
> +            range                -= 16 - idx_mask;
> +            use_mask[idx_sh++]   &=   0xFFFF >> range;
> +            range                -= 16;
> +            if (range > 0)
> +                use_mask[idx_sh] &=   0xFFFF >> range;
> +        }

Does those excluded indexes correspond to some other pulses set (i.e. 
those set in aw_pulse_set1() or those set by aw_pulse_set2() in the last 
frame)?

-Vitor



More information about the ffmpeg-devel mailing list