[FFmpeg-devel] Bink audio decoder

Vitor Sessak vitor1001
Wed Apr 9 19:55:32 CEST 2008


Hi

pross at xvid.org wrote:
> Hi,
> 
> Enclosed is a working demuxer and audio decoder for the Bink multimedia
> format. The patch has been tested on PPC hardware only, but should run
> elsewhere.
> 
> The audio codec makes use of a windowed real-value FFT (and DCT for more
> recent files). Benjamin L tells me that there are NO equivalent dsp
> routines in FFmpeg, so as a starting point a well known public domain
> routine is included.

A few suggestions...

(...)

> +    return 0;
> +}
> +
> +static float get_float(GetBitContext *gb)
> +{
> +    int power = get_bits(gb, 5);
> +    float f = get_bits(gb, 23) / (float)(1 << (23-power));

something like

float f = ldexpf(get_bits(gb, 23), power-23);

would avoid the division

> +    if(get_bits1(gb))
> +        f = -f;
> +    return f;
> +}


> +static int decode_block(BinkAudioContext *s, short *out)
> +{
> +    // coeffs is a double because rdft() and ddct() take doubles
> +    DECLARE_ALIGNED_16(double, coeffs[BLOCK_MAX_SIZE]);
> +
> +    // temporary workspace for ddct() and rdft()
> +    DECLARE_ALIGNED_16(double, ddct_w[BLOCK_MAX_SIZE*5/4]);    ///< max size = block_size*5/4
> +    DECLARE_ALIGNED_16(double, rdft_w[BLOCK_MAX_SIZE/2]); ///< max size = block_size*5/4
> +    DECLARE_ALIGNED_16(int,    fft4g_ip[48]);    ///< max size = 2+sqrt(block_max_size/2)
> +
> +    int ch,i,j,k;
> +    float q, quant[25];
> +    int width,coeff;
> +    int channels = s->channels;
> +
> +    if (s->use_mdct) {
> +        skip_bits(&s->gb, 2);
> +    }
> +
> +    for(ch=0; ch<channels; ch++) {
> +        q = 0.0;
> +        coeffs[0] = get_float(&s->gb);
> +        coeffs[1] = get_float(&s->gb);
> +
> +        for(i=0; i<s->num_bands; i++) {
> +            int value = get_bits(&s->gb, 8);
> +            quant[i] = pow(10.0, FFMIN(value, 95) * 0.0664);
> +        }
> +
> +        // find band (k)
> +        for(k=0; s->bands[k]*2 < 2; k++) {
> +            q = quant[k];
> +        }
> +
> +        // parse coefficients
> +        i=2;
> +        while(i<s->frame_len) {
> +            if (get_bits1(&s->gb)) {
> +                j = i + rle_length_tab[get_bits(&s->gb, 4)]*8;
> +            }else{
> +                j = i + 8;
> +            }
> +
> +            if (j > s->frame_len)
> +                j = s->frame_len;
> +
> +            width = get_bits(&s->gb, 4);
> +            if (width==0) {
> +                memset(coeffs+i, 0, (j-i)*sizeof(double));

sizeof(*coeffs) will make it easier to switch float/double

> +    // windowing
> +    if (s->first>0) {
> +        int count = s->overlap_len*channels;
> +        for(i=0; i<count; i++) {
> +            out[i] = (s->window[i]*(count-i) + out[i]*i) / count;
> +        }
> +    }
> +    memcpy(s->window,
> +           out + (s->frame_len-s->overlap_len)*channels,
> +           s->overlap_len*channels*sizeof(short));

ditto

-Vitor




More information about the ffmpeg-devel mailing list