[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