[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