static int vorbis_parse_audio_packet(vorbis_context *vc) {
    GetBitContext *gb=&vc->gb;
    uint_fast8_t previous_window=0,next_window=0;
    uint_fast8_t mode_number;
    uint_fast16_t blocksize;
    int_fast32_t i,j;
    uint_fast8_t no_residue[vc->audio_channels];
    uint_fast8_t do_not_decode[vc->audio_channels];
    vorbis_mapping *mapping;
    float *ch_res_ptr=vc->channel_residues;
    float *ch_floor_ptr=vc->channel_floors;
    uint_fast8_t res_chan[vc->audio_channels];
    uint_fast8_t res_num=0;
    int_fast16_t retlen=0;
    uint_fast16_t saved_start=0;
    float fadd_bias = vc->add_bias;
    if (get_bits1(gb)) {
        av_log(vc->avccontext, AV_LOG_ERROR, "Not a Vorbis I audio packet.\n");
        return -1;
    }
    if (vc->mode_count==1) {
        mode_number=0;
    } else {
        mode_number=get_bits(gb, ilog(vc->mode_count-1));
    }
    vc->mode_number=mode_number;
    mapping=&vc->mappings[vc->modes[mode_number].mapping];
    AV_DEBUG(" Mode number: %d , mapping: %d , blocktype %d \n", mode_number, vc->modes[mode_number].mapping, vc->modes[mode_number].blockflag);
    if (vc->modes[mode_number].blockflag) {
        previous_window=get_bits1(gb);
        next_window=get_bits1(gb);
    }
    blocksize=vc->blocksize[vc->modes[mode_number].blockflag];
    memset(ch_res_ptr, 0, sizeof(float)*vc->audio_channels*blocksize/2);
    memset(ch_floor_ptr, 0, sizeof(float)*vc->audio_channels*blocksize/2);
    for(i=0;i<vc->audio_channels;++i) {
        vorbis_floor *floor;
        if (mapping->submaps>1) {
            floor=&vc->floors[mapping->submap_floor[mapping->mux[i]]];
        } else {
            floor=&vc->floors[mapping->submap_floor[0]];
        }
        no_residue[i]=floor->decode(vc, &floor->data, ch_floor_ptr);
        ch_floor_ptr+=blocksize/2;
    }
    for(i=mapping->coupling_steps-1;i>=0;--i) {
        if (!(no_residue[mapping->magnitude[i]] & no_residue[mapping->angle[i]])) {
            no_residue[mapping->magnitude[i]]=0;
            no_residue[mapping->angle[i]]=0;
        }
    }
    for(i=0;i<mapping->submaps;++i) {
        vorbis_residue *residue;
        uint_fast8_t ch=0;
        for(j=0;j<vc->audio_channels;++j) {
            if ((mapping->submaps==1) || (i=mapping->mux[j])) {
                res_chan[j]=res_num;
                if (no_residue[j]) {
                    do_not_decode[ch]=1;
                } else {
                    do_not_decode[ch]=0;
                }
                ++ch;
                ++res_num;
            }
        }
        residue=&vc->residues[mapping->submap_residue[i]];
        vorbis_residue_decode(vc, residue, ch, do_not_decode, ch_res_ptr, blocksize/2);
        ch_res_ptr+=ch*blocksize/2;
    }
    for(i=mapping->coupling_steps-1;i>=0;--i) {
        float *mag, *ang;
        mag=vc->channel_residues+res_chan[mapping->magnitude[i]]*blocksize/2;
        ang=vc->channel_residues+res_chan[mapping->angle[i]]*blocksize/2;
        vc->dsp.vorbis_inverse_coupling(mag, ang, blocksize/2);
    }
    for(j=0, ch_floor_ptr=vc->channel_floors;j<vc->audio_channels;++j,ch_floor_ptr+=blocksize/2) {
        ch_res_ptr=vc->channel_residues+res_chan[j]*blocksize/2;
        vc->dsp.vector_fmul(ch_floor_ptr, ch_res_ptr, blocksize/2);
    }
    for(j=0;j<vc->audio_channels;++j) {
        uint_fast8_t step=vc->audio_channels;
        uint_fast16_t k;
        float *saved=vc->saved+j*vc->blocksize[1]/2;
        float *ret=vc->ret;
        const float *lwin=vc->win[1];
        const float *swin=vc->win[0];
        float *buf=vc->buf;
        float *buf_tmp=vc->buf_tmp;
        ch_floor_ptr=vc->channel_floors+j*blocksize/2;
        saved_start=vc->saved_start;
        vc->mdct[0].fft.imdct_calc(&vc->mdct[vc->modes[mode_number].blockflag], buf, ch_floor_ptr, buf_tmp);
        if (vc->modes[mode_number].blockflag) {
            if (previous_window) {
                vc->dsp.vector_fmul_add_add(ret+j, buf, lwin, saved, vc->add_bias, vc->blocksize[1]/2, step);
                retlen=vc->blocksize[1]/2;
            } else {
                int len = (vc->blocksize[1]-vc->blocksize[0])/4;
                buf += len;
                vc->dsp.vector_fmul_add_add(ret+j, buf, swin, saved, vc->add_bias, vc->blocksize[0]/2, step);
                k = vc->blocksize[0]/2*step + j;
                buf += vc->blocksize[0]/2;
                if(vc->exp_bias){
                    for(i=0; i<len; i++, k+=step)
                        ((uint32_t*)ret)[k] = ((uint32_t*)buf)[i] + vc->exp_bias;
                } else {
                    for(i=0; i<len; i++, k+=step)
                        ret[k] = buf[i] + fadd_bias;
                }
                buf=vc->buf;
                retlen=vc->blocksize[0]/2+len;
            }
            if (next_window) {
                buf += vc->blocksize[1]/2;
                vc->dsp.vector_fmul_reverse(saved, buf, lwin, vc->blocksize[1]/2);
                saved_start=0;
            } else {
                saved_start=(vc->blocksize[1]-vc->blocksize[0])/4;
                buf += vc->blocksize[1]/2;
                for(i=0; i<saved_start; i++)
                    ((uint32_t*)saved)[i] = ((uint32_t*)buf)[i] + vc->exp_bias;
                vc->dsp.vector_fmul_reverse(saved+saved_start, buf+saved_start, swin, vc->blocksize[0]/2);
            }
        } else {
            if(vc->add_bias) {
                for(k=j, i=0;i<saved_start;++i, k+=step)
                    ret[k] = saved[i] + fadd_bias;
            } else {
                for(k=j, i=0;i<saved_start;++i, k+=step)
                    ret[k] = saved[i];
            }
            vc->dsp.vector_fmul_add_add(ret+k, buf, swin, saved+saved_start, vc->add_bias, vc->blocksize[0]/2, step);
            retlen=saved_start+vc->blocksize[0]/2;
            buf += vc->blocksize[0]/2;
            vc->dsp.vector_fmul_reverse(saved, buf, swin, vc->blocksize[0]/2);
            saved_start=0;
        }
    }
    vc->saved_start=saved_start;
    return retlen*vc->audio_channels;
}
['static int vorbis_decode_frame(AVCodecContext *avccontext,\n                        void *data, int *data_size,\n                        const uint8_t *buf, int buf_size)\n{\n    vorbis_context *vc = avccontext->priv_data ;\n    GetBitContext *gb = &(vc->gb);\n    int_fast16_t len;\n    if(!buf_size){\n        return 0;\n    }\n    AV_DEBUG("packet length %d \\n", buf_size);\n    init_get_bits(gb, buf, buf_size*8);\n    len=vorbis_parse_audio_packet(vc);\n    if (len<=0) {\n        *data_size=0;\n        return buf_size;\n    }\n    if (!vc->first_frame) {\n        vc->first_frame=1;\n        *data_size=0;\n        return buf_size ;\n    }\n    AV_DEBUG("parsed %d bytes %d bits, returned %d samples (*ch*bits) \\n", get_bits_count(gb)/8, get_bits_count(gb)%8, len);\n    vc->dsp.float_to_int16(data, vc->ret, len);\n    *data_size=len*2;\n    return buf_size ;\n}', 'static int vorbis_parse_audio_packet(vorbis_context *vc) {\n    GetBitContext *gb=&vc->gb;\n    uint_fast8_t previous_window=0,next_window=0;\n    uint_fast8_t mode_number;\n    uint_fast16_t blocksize;\n    int_fast32_t i,j;\n    uint_fast8_t no_residue[vc->audio_channels];\n    uint_fast8_t do_not_decode[vc->audio_channels];\n    vorbis_mapping *mapping;\n    float *ch_res_ptr=vc->channel_residues;\n    float *ch_floor_ptr=vc->channel_floors;\n    uint_fast8_t res_chan[vc->audio_channels];\n    uint_fast8_t res_num=0;\n    int_fast16_t retlen=0;\n    uint_fast16_t saved_start=0;\n    float fadd_bias = vc->add_bias;\n    if (get_bits1(gb)) {\n        av_log(vc->avccontext, AV_LOG_ERROR, "Not a Vorbis I audio packet.\\n");\n        return -1;\n    }\n    if (vc->mode_count==1) {\n        mode_number=0;\n    } else {\n        mode_number=get_bits(gb, ilog(vc->mode_count-1));\n    }\n    vc->mode_number=mode_number;\n    mapping=&vc->mappings[vc->modes[mode_number].mapping];\n    AV_DEBUG(" Mode number: %d , mapping: %d , blocktype %d \\n", mode_number, vc->modes[mode_number].mapping, vc->modes[mode_number].blockflag);\n    if (vc->modes[mode_number].blockflag) {\n        previous_window=get_bits1(gb);\n        next_window=get_bits1(gb);\n    }\n    blocksize=vc->blocksize[vc->modes[mode_number].blockflag];\n    memset(ch_res_ptr, 0, sizeof(float)*vc->audio_channels*blocksize/2);\n    memset(ch_floor_ptr, 0, sizeof(float)*vc->audio_channels*blocksize/2);\n    for(i=0;i<vc->audio_channels;++i) {\n        vorbis_floor *floor;\n        if (mapping->submaps>1) {\n            floor=&vc->floors[mapping->submap_floor[mapping->mux[i]]];\n        } else {\n            floor=&vc->floors[mapping->submap_floor[0]];\n        }\n        no_residue[i]=floor->decode(vc, &floor->data, ch_floor_ptr);\n        ch_floor_ptr+=blocksize/2;\n    }\n    for(i=mapping->coupling_steps-1;i>=0;--i) {\n        if (!(no_residue[mapping->magnitude[i]] & no_residue[mapping->angle[i]])) {\n            no_residue[mapping->magnitude[i]]=0;\n            no_residue[mapping->angle[i]]=0;\n        }\n    }\n    for(i=0;i<mapping->submaps;++i) {\n        vorbis_residue *residue;\n        uint_fast8_t ch=0;\n        for(j=0;j<vc->audio_channels;++j) {\n            if ((mapping->submaps==1) || (i=mapping->mux[j])) {\n                res_chan[j]=res_num;\n                if (no_residue[j]) {\n                    do_not_decode[ch]=1;\n                } else {\n                    do_not_decode[ch]=0;\n                }\n                ++ch;\n                ++res_num;\n            }\n        }\n        residue=&vc->residues[mapping->submap_residue[i]];\n        vorbis_residue_decode(vc, residue, ch, do_not_decode, ch_res_ptr, blocksize/2);\n        ch_res_ptr+=ch*blocksize/2;\n    }\n    for(i=mapping->coupling_steps-1;i>=0;--i) {\n        float *mag, *ang;\n        mag=vc->channel_residues+res_chan[mapping->magnitude[i]]*blocksize/2;\n        ang=vc->channel_residues+res_chan[mapping->angle[i]]*blocksize/2;\n        vc->dsp.vorbis_inverse_coupling(mag, ang, blocksize/2);\n    }\n    for(j=0, ch_floor_ptr=vc->channel_floors;j<vc->audio_channels;++j,ch_floor_ptr+=blocksize/2) {\n        ch_res_ptr=vc->channel_residues+res_chan[j]*blocksize/2;\n        vc->dsp.vector_fmul(ch_floor_ptr, ch_res_ptr, blocksize/2);\n    }\n    for(j=0;j<vc->audio_channels;++j) {\n        uint_fast8_t step=vc->audio_channels;\n        uint_fast16_t k;\n        float *saved=vc->saved+j*vc->blocksize[1]/2;\n        float *ret=vc->ret;\n        const float *lwin=vc->win[1];\n        const float *swin=vc->win[0];\n        float *buf=vc->buf;\n        float *buf_tmp=vc->buf_tmp;\n        ch_floor_ptr=vc->channel_floors+j*blocksize/2;\n        saved_start=vc->saved_start;\n        vc->mdct[0].fft.imdct_calc(&vc->mdct[vc->modes[mode_number].blockflag], buf, ch_floor_ptr, buf_tmp);\n        if (vc->modes[mode_number].blockflag) {\n            if (previous_window) {\n                vc->dsp.vector_fmul_add_add(ret+j, buf, lwin, saved, vc->add_bias, vc->blocksize[1]/2, step);\n                retlen=vc->blocksize[1]/2;\n            } else {\n                int len = (vc->blocksize[1]-vc->blocksize[0])/4;\n                buf += len;\n                vc->dsp.vector_fmul_add_add(ret+j, buf, swin, saved, vc->add_bias, vc->blocksize[0]/2, step);\n                k = vc->blocksize[0]/2*step + j;\n                buf += vc->blocksize[0]/2;\n                if(vc->exp_bias){\n                    for(i=0; i<len; i++, k+=step)\n                        ((uint32_t*)ret)[k] = ((uint32_t*)buf)[i] + vc->exp_bias;\n                } else {\n                    for(i=0; i<len; i++, k+=step)\n                        ret[k] = buf[i] + fadd_bias;\n                }\n                buf=vc->buf;\n                retlen=vc->blocksize[0]/2+len;\n            }\n            if (next_window) {\n                buf += vc->blocksize[1]/2;\n                vc->dsp.vector_fmul_reverse(saved, buf, lwin, vc->blocksize[1]/2);\n                saved_start=0;\n            } else {\n                saved_start=(vc->blocksize[1]-vc->blocksize[0])/4;\n                buf += vc->blocksize[1]/2;\n                for(i=0; i<saved_start; i++)\n                    ((uint32_t*)saved)[i] = ((uint32_t*)buf)[i] + vc->exp_bias;\n                vc->dsp.vector_fmul_reverse(saved+saved_start, buf+saved_start, swin, vc->blocksize[0]/2);\n            }\n        } else {\n            if(vc->add_bias) {\n                for(k=j, i=0;i<saved_start;++i, k+=step)\n                    ret[k] = saved[i] + fadd_bias;\n            } else {\n                for(k=j, i=0;i<saved_start;++i, k+=step)\n                    ret[k] = saved[i];\n            }\n            vc->dsp.vector_fmul_add_add(ret+k, buf, swin, saved+saved_start, vc->add_bias, vc->blocksize[0]/2, step);\n            retlen=saved_start+vc->blocksize[0]/2;\n            buf += vc->blocksize[0]/2;\n            vc->dsp.vector_fmul_reverse(saved, buf, swin, vc->blocksize[0]/2);\n            saved_start=0;\n        }\n    }\n    vc->saved_start=saved_start;\n    return retlen*vc->audio_channels;\n}']