mode_number=get_bits(gb, ilog(vc->mode_count-1));
if (vc->mode_count==1) { mode_number=0; } else { mode_number=get_bits(gb, ilog(vc->mode_count-1)); }
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;    if (get_bits1(gb)) {        av_log(vc->avccontext, AV_LOG_ERROR, "Not a Vorbis I audio packet.\n");        return -1; // packet type not audio    }    mode_number=get_bits(gb, ilog(vc->mode_count-1));    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->modes[mode_number].blockflag ? vc->blocksize_1 : vc->blocksize_0;    memset(ch_res_ptr, 0, sizeof(float)*vc->audio_channels*blocksize/2); //FIXME can this be removed ?    memset(ch_floor_ptr, 0, sizeof(float)*vc->audio_channels*blocksize/2); //FIXME can this be removed ?// Decode floor(1)    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]=vorbis_floor1_decode(vc, floor, ch_floor_ptr);        ch_floor_ptr+=blocksize/2;    }// Nonzero vector propagate    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;        }    }// Decode residue    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;    }// Inverse coupling    for(i=mapping->coupling_steps-1;i>=0;--i) { //warning: i has to be signed        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;        for(j=0;j<blocksize/2;++j) {            float temp;            if (mag[j]>0.0) {                if (ang[j]>0.0) {                    ang[j]=mag[j]-ang[j];                } else {                    temp=ang[j];                    ang[j]=mag[j];                    mag[j]+=temp;                }            } else {                if (ang[j]>0.0) {                    ang[j]+=mag[j];                } else {                    temp=ang[j];                    ang[j]=mag[j];                    mag[j]-=temp;                }            }        }    }// Dotproduct    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;        for(i=0;i<blocksize/2;++i) {            ch_floor_ptr[i]*=ch_res_ptr[i]; //FPMATH        }    }// MDCT, overlap/add, save data for next overlapping  FPMATH    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->lwin;        const float *swin=vc->swin;        float buf[blocksize];        float buf_tmp[blocksize];        ch_floor_ptr=vc->channel_floors+j*blocksize/2;        saved_start=vc->saved_start;        ff_imdct_calc(vc->modes[mode_number].blockflag ? &vc->mdct1 : &vc->mdct0, buf, ch_floor_ptr, buf_tmp);        if (vc->modes[mode_number].blockflag) {            // -- overlap/add            if (previous_window) {                for(k=j, i=0;i<vc->blocksize_1/2;++i, k+=step) {                    ret[k]=saved[i]+buf[i]*lwin[i];                }                retlen=vc->blocksize_1/2;            } else {                for(k=j, i=0;i<vc->blocksize_0/2;++i, k+=step) {                    ret[k]=saved[i]+buf[(vc->blocksize_1-vc->blocksize_0)/4+i]*swin[i];                }                for(i=0;i<(vc->blocksize_1-vc->blocksize_0)/4;++i, k+=step) {                    ret[k]=buf[vc->blocksize_0/2+(vc->blocksize_1-vc->blocksize_0)/4+i];                }                retlen=vc->blocksize_0/2+(vc->blocksize_1-vc->blocksize_0)/4;            }            // -- save            if (next_window) {                for(i=0;i<vc->blocksize_1/2;++i) {                    saved[i]=buf[vc->blocksize_1/2+i]*lwin[vc->blocksize_1/2-1-i];                }                saved_start=0;            } else {                saved_start=(vc->blocksize_1-vc->blocksize_0)/4;                for(i=0;i<saved_start;++i) {                    saved[i]=buf[vc->blocksize_1/2+i];                }                for(i=0;i<vc->blocksize_0/2;++i) {                    saved[saved_start+i]=buf[vc->blocksize_1/2+saved_start+i]*swin[vc->blocksize_0/2-1-i];                }            }        } else {            // --overlap/add            for(k=j, i=0;i<saved_start;++i, k+=step) {                ret[k]=saved[i];            }            for(i=0;i<vc->blocksize_0/2;++i, k+=step) {                ret[k]=saved[saved_start+i]+buf[i]*swin[i];            }            retlen=saved_start+vc->blocksize_0/2;            // -- save            for(i=0;i<vc->blocksize_0/2;++i) {                saved[i]=buf[vc->blocksize_0/2+i]*swin[vc->blocksize_0/2-1-i];            }            saved_start=0;        }    }    vc->saved_start=saved_start;    return retlen*vc->audio_channels;}