/**
 * @file
 * Vorbis I decoder
 * @author Denes Balatoni  ( dbalatoni programozo hu )
 *
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * FFmpeg is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with FFmpeg; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/**
 * @file
 * Vorbis I decoder
 * @author Denes Balatoni  ( dbalatoni programozo hu )
 */

#include <inttypes.h>
#include <math.h>

#define BITSTREAM_READER_LE
#include "avcodec.h"
#include "internal.h"
#include "get_bits.h"
#include "dsputil.h"
#include "fft.h"
#include "fmtconvert.h"

#include "vorbis.h"
#include "xiph.h"

#define V_NB_BITS 8
#define V_NB_BITS2 11
#define V_MAX_VLCS (1 << 16)
#define V_MAX_PARTITIONS (1 << 20)

#undef NDEBUG
#include <assert.h>

typedef struct {
    uint8_t      dimensions;
    uint8_t      lookup_type;
    uint8_t      maxdepth;
    VLC          vlc;
    float       *codevectors;
    unsigned int nb_bits;
} vorbis_codebook;

typedef union  vorbis_floor_u  vorbis_floor_data;
typedef struct vorbis_floor0_s vorbis_floor0;
typedef struct vorbis_floor1_s vorbis_floor1;
struct vorbis_context_s;
typedef
int (* vorbis_floor_decode_func)
    (struct vorbis_context_s *, vorbis_floor_data *, float *);
typedef struct {
    uint8_t floor_type;
    vorbis_floor_decode_func decode;
    union vorbis_floor_u {
        struct vorbis_floor0_s {
            uint8_t       order;
            uint16_t      rate;
            uint16_t      bark_map_size;
            int32_t      *map[2];
            uint32_t      map_size[2];
            uint8_t       amplitude_bits;
            uint8_t       amplitude_offset;
            uint8_t       num_books;
            uint8_t      *book_list;
            float        *lsp;
        } t0;
        struct vorbis_floor1_s {
            uint8_t       partitions;
            uint8_t       partition_class[32];
            uint8_t       class_dimensions[16];
            uint8_t       class_subclasses[16];
            uint8_t       class_masterbook[16];
            int16_t       subclass_books[16][8];
            uint8_t       multiplier;
            uint16_t      x_list_dim;
            vorbis_floor1_entry *list;
        } t1;
    } data;
} vorbis_floor;

typedef struct {
    uint16_t      type;
    uint32_t      begin;
    uint32_t      end;
    unsigned      partition_size;
    uint8_t       classifications;
    uint8_t       classbook;
    int16_t       books[64][8];
    uint8_t       maxpass;
    uint16_t      ptns_to_read;
    uint8_t      *classifs;
} vorbis_residue;

typedef struct {
    uint8_t       submaps;
    uint16_t      coupling_steps;
    uint8_t      *magnitude;
    uint8_t      *angle;
    uint8_t      *mux;
    uint8_t       submap_floor[16];
    uint8_t       submap_residue[16];
} vorbis_mapping;

typedef struct {
    uint8_t       blockflag;
    uint16_t      windowtype;
    uint16_t      transformtype;
    uint8_t       mapping;
} vorbis_mode;

typedef struct vorbis_context_s {
    AVCodecContext *avccontext;
    AVFrame frame;
    GetBitContext gb;
    DSPContext dsp;
    FmtConvertContext fmt_conv;

    FFTContext mdct[2];
    uint8_t       first_frame;
    uint32_t      version;
    uint8_t       audio_channels;
    uint32_t      audio_samplerate;
    uint32_t      bitrate_maximum;
    uint32_t      bitrate_nominal;
    uint32_t      bitrate_minimum;
    uint32_t      blocksize[2];
    const float  *win[2];
    uint16_t      codebook_count;
    vorbis_codebook *codebooks;
    uint8_t       floor_count;
    vorbis_floor *floors;
    uint8_t       residue_count;
    vorbis_residue *residues;
    uint8_t       mapping_count;
    vorbis_mapping *mappings;
    uint8_t       mode_count;
    vorbis_mode  *modes;
    uint8_t       mode_number; // mode number for the current packet
    uint8_t       previous_window;
    float        *channel_residues;
    float        *channel_floors;
    float        *saved;
    float         scale_bias; // for float->int conversion
} vorbis_context;

/* Helper functions */

#define BARK(x) \
    (13.1f * atan(0.00074f * (x)) + 2.24f * atan(1.85e-8f * (x) * (x)) + 1e-4f * (x))

static const char idx_err_str[] = "Index value %d out of range (0 - %d) for %s at %s:%i\n";
#define VALIDATE_INDEX(idx, limit) \
    if (idx >= limit) {\
        av_log(vc->avccontext, AV_LOG_ERROR,\
               idx_err_str,\
               (int)(idx), (int)(limit - 1), #idx, __FILE__, __LINE__);\
        return AVERROR_INVALIDDATA;\
    }
#define GET_VALIDATED_INDEX(idx, bits, limit) \
    {\
        idx = get_bits(gb, bits);\
        VALIDATE_INDEX(idx, limit)\
    }

static float vorbisfloat2float(unsigned val)
{
    double mant = val & 0x1fffff;
    long exp    = (val & 0x7fe00000L) >> 21;
    if (val & 0x80000000)
        mant = -mant;
    return ldexp(mant, exp - 20 - 768);
}


// Free all allocated memory -----------------------------------------

static void vorbis_free(vorbis_context *vc)
{
    int i;

    av_freep(&vc->channel_residues);
    av_freep(&vc->channel_floors);
    av_freep(&vc->saved);

    for (i = 0; i < vc->residue_count; i++)
        av_free(vc->residues[i].classifs);
    av_freep(&vc->residues);
    av_freep(&vc->modes);

    ff_mdct_end(&vc->mdct[0]);
    ff_mdct_end(&vc->mdct[1]);

    for (i = 0; i < vc->codebook_count; ++i) {
        av_free(vc->codebooks[i].codevectors);
        ff_free_vlc(&vc->codebooks[i].vlc);
    }
    av_freep(&vc->codebooks);

    for (i = 0; i < vc->floor_count; ++i) {
        if (vc->floors[i].floor_type == 0) {
            av_free(vc->floors[i].data.t0.map[0]);
            av_free(vc->floors[i].data.t0.map[1]);
            av_free(vc->floors[i].data.t0.book_list);
            av_free(vc->floors[i].data.t0.lsp);
        } else {
            av_free(vc->floors[i].data.t1.list);
        }
    }
    av_freep(&vc->floors);

    for (i = 0; i < vc->mapping_count; ++i) {
        av_free(vc->mappings[i].magnitude);
        av_free(vc->mappings[i].angle);
        av_free(vc->mappings[i].mux);
    }
    av_freep(&vc->mappings);
}

// Parse setup header -------------------------------------------------

// Process codebooks part

static int vorbis_parse_setup_hdr_codebooks(vorbis_context *vc)
{
    unsigned cb;
    uint8_t  *tmp_vlc_bits;
    uint32_t *tmp_vlc_codes;
    GetBitContext *gb = &vc->gb;
    uint16_t *codebook_multiplicands;
    int ret = 0;

    vc->codebook_count = get_bits(gb, 8) + 1;

    av_dlog(NULL, " Codebooks: %d \n", vc->codebook_count);

    vc->codebooks = av_mallocz(vc->codebook_count * sizeof(*vc->codebooks));
    tmp_vlc_bits  = av_mallocz(V_MAX_VLCS * sizeof(*tmp_vlc_bits));
    tmp_vlc_codes = av_mallocz(V_MAX_VLCS * sizeof(*tmp_vlc_codes));
    codebook_multiplicands = av_malloc(V_MAX_VLCS * sizeof(*codebook_multiplicands));

    for (cb = 0; cb < vc->codebook_count; ++cb) {
        vorbis_codebook *codebook_setup = &vc->codebooks[cb];
        unsigned ordered, t, entries, used_entries = 0;

        av_dlog(NULL, " %u. Codebook\n", cb);

        if (get_bits(gb, 24) != 0x564342) {
            av_log(vc->avccontext, AV_LOG_ERROR,
                   " %u. Codebook setup data corrupt.\n", cb);
            ret = AVERROR_INVALIDDATA;
            goto error;
        }

        codebook_setup->dimensions=get_bits(gb, 16);
        if (codebook_setup->dimensions > 16 || codebook_setup->dimensions == 0) {
            av_log(vc->avccontext, AV_LOG_ERROR,
                   " %u. Codebook's dimension is invalid (%d).\n",
                   cb, codebook_setup->dimensions);
            ret = AVERROR_INVALIDDATA;
            goto error;
        }
        entries = get_bits(gb, 24);
        if (entries > V_MAX_VLCS) {
            av_log(vc->avccontext, AV_LOG_ERROR,
                   " %u. Codebook has too many entries (%u).\n",
                   cb, entries);
            ret = AVERROR_INVALIDDATA;
            goto error;
        }

        ordered = get_bits1(gb);

        av_dlog(NULL, " codebook_dimensions %d, codebook_entries %u\n",
                codebook_setup->dimensions, entries);

        if (!ordered) {
            unsigned ce, flag;
            unsigned sparse = get_bits1(gb);

            av_dlog(NULL, " not ordered \n");

            if (sparse) {
                av_dlog(NULL, " sparse \n");

                used_entries = 0;
                for (ce = 0; ce < entries; ++ce) {
                    flag = get_bits1(gb);
                    if (flag) {
                        tmp_vlc_bits[ce] = get_bits(gb, 5) + 1;
                        ++used_entries;
                    } else
                        tmp_vlc_bits[ce] = 0;
                }
            } else {
                av_dlog(NULL, " not sparse \n");

                used_entries = entries;
                for (ce = 0; ce < entries; ++ce)
                    tmp_vlc_bits[ce] = get_bits(gb, 5) + 1;
            }
        } else {
            unsigned current_entry  = 0;
            unsigned current_length = get_bits(gb, 5) + 1;

            av_dlog(NULL, " ordered, current length: %u\n", current_length);  //FIXME

            used_entries = entries;
            for (; current_entry < used_entries && current_length <= 32; ++current_length) {
                unsigned i, number;

                av_dlog(NULL, " number bits: %u ", ilog(entries - current_entry));

                number = get_bits(gb, ilog(entries - current_entry));

                av_dlog(NULL, " number: %u\n", number);

                for (i = current_entry; i < number+current_entry; ++i)
                    if (i < used_entries)
                        tmp_vlc_bits[i] = current_length;

                current_entry+=number;
            }
            if (current_entry>used_entries) {
                av_log(vc->avccontext, AV_LOG_ERROR, " More codelengths than codes in codebook. \n");
                ret = AVERROR_INVALIDDATA;
                goto error;
            }
        }

        codebook_setup->lookup_type = get_bits(gb, 4);

        av_dlog(NULL, " lookup type: %d : %s \n", codebook_setup->lookup_type,
                codebook_setup->lookup_type ? "vq" : "no lookup");

// If the codebook is used for (inverse) VQ, calculate codevectors.

        if (codebook_setup->lookup_type == 1) {
            unsigned i, j, k;
            unsigned codebook_lookup_values = ff_vorbis_nth_root(entries, codebook_setup->dimensions);

            float codebook_minimum_value = vorbisfloat2float(get_bits_long(gb, 32));
            float codebook_delta_value   = vorbisfloat2float(get_bits_long(gb, 32));
            unsigned codebook_value_bits = get_bits(gb, 4) + 1;
            unsigned codebook_sequence_p = get_bits1(gb);

            av_dlog(NULL, " We expect %d numbers for building the codevectors. \n",
                    codebook_lookup_values);
            av_dlog(NULL, "  delta %f minmum %f \n",
                    codebook_delta_value, codebook_minimum_value);

            for (i = 0; i < codebook_lookup_values; ++i) {
                codebook_multiplicands[i] = get_bits(gb, codebook_value_bits);

                av_dlog(NULL, " multiplicands*delta+minmum : %e \n",
                        (float)codebook_multiplicands[i] * codebook_delta_value + codebook_minimum_value);
                av_dlog(NULL, " multiplicand %u\n", codebook_multiplicands[i]);
            }

// Weed out unused vlcs and build codevector vector
            codebook_setup->codevectors = used_entries ? av_mallocz(used_entries *
                                                                    codebook_setup->dimensions *
                                                                    sizeof(*codebook_setup->codevectors))
                                                       : NULL;
            for (j = 0, i = 0; i < entries; ++i) {
                unsigned dim = codebook_setup->dimensions;

                if (tmp_vlc_bits[i]) {
                    float last = 0.0;
                    unsigned lookup_offset = i;

                    av_dlog(vc->avccontext, "Lookup offset %u ,", i);

                    for (k = 0; k < dim; ++k) {
                        unsigned multiplicand_offset = lookup_offset % codebook_lookup_values;
                        codebook_setup->codevectors[j * dim + k] = codebook_multiplicands[multiplicand_offset] * codebook_delta_value + codebook_minimum_value + last;
                        if (codebook_sequence_p)
                            last = codebook_setup->codevectors[j * dim + k];
                        lookup_offset/=codebook_lookup_values;
                    }
                    tmp_vlc_bits[j] = tmp_vlc_bits[i];

                    av_dlog(vc->avccontext, "real lookup offset %u, vector: ", j);
                    for (k = 0; k < dim; ++k)
                        av_dlog(vc->avccontext, " %f ",
                                codebook_setup->codevectors[j * dim + k]);
                    av_dlog(vc->avccontext, "\n");

                    ++j;
                }
            }
            if (j != used_entries) {
                av_log(vc->avccontext, AV_LOG_ERROR, "Bug in codevector vector building code. \n");
                ret = AVERROR_INVALIDDATA;
                goto error;
            }
            entries = used_entries;
        } else if (codebook_setup->lookup_type >= 2) {
            av_log(vc->avccontext, AV_LOG_ERROR, "Codebook lookup type not supported. \n");
            ret = AVERROR_INVALIDDATA;
            goto error;
        }

// Initialize VLC table
        if (ff_vorbis_len2vlc(tmp_vlc_bits, tmp_vlc_codes, entries)) {
            av_log(vc->avccontext, AV_LOG_ERROR, " Invalid code lengths while generating vlcs. \n");
            ret = AVERROR_INVALIDDATA;
            goto error;
        }
        codebook_setup->maxdepth = 0;
        for (t = 0; t < entries; ++t)
            if (tmp_vlc_bits[t] >= codebook_setup->maxdepth)
                codebook_setup->maxdepth = tmp_vlc_bits[t];

        if (codebook_setup->maxdepth > 3 * V_NB_BITS)
            codebook_setup->nb_bits = V_NB_BITS2;
        else
            codebook_setup->nb_bits = V_NB_BITS;

        codebook_setup->maxdepth = (codebook_setup->maxdepth+codebook_setup->nb_bits - 1) / codebook_setup->nb_bits;

        if ((ret = init_vlc(&codebook_setup->vlc, codebook_setup->nb_bits,
                            entries, tmp_vlc_bits, sizeof(*tmp_vlc_bits),
                            sizeof(*tmp_vlc_bits), tmp_vlc_codes,
                            sizeof(*tmp_vlc_codes), sizeof(*tmp_vlc_codes),
                            INIT_VLC_LE))) {
            av_log(vc->avccontext, AV_LOG_ERROR, " Error generating vlc tables. \n");
            goto error;
        }
    }

    av_free(tmp_vlc_bits);
    av_free(tmp_vlc_codes);
    av_free(codebook_multiplicands);
    return 0;

// Error:
error:
    av_free(tmp_vlc_bits);
    av_free(tmp_vlc_codes);
    av_free(codebook_multiplicands);
    return ret;
}

// Process time domain transforms part (unused in Vorbis I)

static int vorbis_parse_setup_hdr_tdtransforms(vorbis_context *vc)
{
    GetBitContext *gb = &vc->gb;
    unsigned i, vorbis_time_count = get_bits(gb, 6) + 1;

    for (i = 0; i < vorbis_time_count; ++i) {
        unsigned vorbis_tdtransform = get_bits(gb, 16);

        av_dlog(NULL, " Vorbis time domain transform %u: %u\n",
                vorbis_time_count, vorbis_tdtransform);

        if (vorbis_tdtransform) {
            av_log(vc->avccontext, AV_LOG_ERROR, "Vorbis time domain transform data nonzero. \n");
            return AVERROR_INVALIDDATA;
        }
    }
    return 0;
}

// Process floors part

static int vorbis_floor0_decode(vorbis_context *vc,
                                vorbis_floor_data *vfu, float *vec);
static void create_map(vorbis_context *vc, unsigned floor_number);
static int vorbis_floor1_decode(vorbis_context *vc,
                                vorbis_floor_data *vfu, float *vec);
static int vorbis_parse_setup_hdr_floors(vorbis_context *vc)
{
    GetBitContext *gb = &vc->gb;
    int i,j,k;

    vc->floor_count = get_bits(gb, 6) + 1;

    vc->floors = av_mallocz(vc->floor_count * sizeof(*vc->floors));

    for (i = 0; i < vc->floor_count; ++i) {
        vorbis_floor *floor_setup = &vc->floors[i];

        floor_setup->floor_type = get_bits(gb, 16);

        av_dlog(NULL, " %d. floor type %d \n", i, floor_setup->floor_type);

        if (floor_setup->floor_type == 1) {
            int maximum_class = -1;
            unsigned rangebits, rangemax, floor1_values = 2;

            floor_setup->decode = vorbis_floor1_decode;

            floor_setup->data.t1.partitions = get_bits(gb, 5);

            av_dlog(NULL, " %d.floor: %d partitions \n",
                    i, floor_setup->data.t1.partitions);

            for (j = 0; j < floor_setup->data.t1.partitions; ++j) {
                floor_setup->data.t1.partition_class[j] = get_bits(gb, 4);
                if (floor_setup->data.t1.partition_class[j] > maximum_class)
                    maximum_class = floor_setup->data.t1.partition_class[j];

                av_dlog(NULL, " %d. floor %d partition class %d \n",
                        i, j, floor_setup->data.t1.partition_class[j]);

            }

            av_dlog(NULL, " maximum class %d \n", maximum_class);

            for (j = 0; j <= maximum_class; ++j) {
                floor_setup->data.t1.class_dimensions[j] = get_bits(gb, 3) + 1;
                floor_setup->data.t1.class_subclasses[j] = get_bits(gb, 2);

                av_dlog(NULL, " %d floor %d class dim: %d subclasses %d \n", i, j,
                        floor_setup->data.t1.class_dimensions[j],
                        floor_setup->data.t1.class_subclasses[j]);

                if (floor_setup->data.t1.class_subclasses[j]) {
                    GET_VALIDATED_INDEX(floor_setup->data.t1.class_masterbook[j], 8, vc->codebook_count)

                    av_dlog(NULL, "   masterbook: %d \n", floor_setup->data.t1.class_masterbook[j]);
                }

                for (k = 0; k < (1 << floor_setup->data.t1.class_subclasses[j]); ++k) {
                    int16_t bits = get_bits(gb, 8) - 1;
                    if (bits != -1)
                        VALIDATE_INDEX(bits, vc->codebook_count)
                    floor_setup->data.t1.subclass_books[j][k] = bits;

                    av_dlog(NULL, "    book %d. : %d \n", k, floor_setup->data.t1.subclass_books[j][k]);
                }
            }

            floor_setup->data.t1.multiplier = get_bits(gb, 2) + 1;
            floor_setup->data.t1.x_list_dim = 2;

            for (j = 0; j < floor_setup->data.t1.partitions; ++j)
                floor_setup->data.t1.x_list_dim+=floor_setup->data.t1.class_dimensions[floor_setup->data.t1.partition_class[j]];

            floor_setup->data.t1.list = av_mallocz(floor_setup->data.t1.x_list_dim *
                                                   sizeof(*floor_setup->data.t1.list));


            rangebits = get_bits(gb, 4);
            rangemax = (1 << rangebits);
            if (rangemax > vc->blocksize[1] / 2) {
                av_log(vc->avccontext, AV_LOG_ERROR,
                       "Floor value is too large for blocksize: %u (%"PRIu32")\n",
                       rangemax, vc->blocksize[1] / 2);
                return AVERROR_INVALIDDATA;
            }
            floor_setup->data.t1.list[0].x = 0;
            floor_setup->data.t1.list[1].x = rangemax;

            for (j = 0; j < floor_setup->data.t1.partitions; ++j) {
                for (k = 0; k < floor_setup->data.t1.class_dimensions[floor_setup->data.t1.partition_class[j]]; ++k, ++floor1_values) {
                    floor_setup->data.t1.list[floor1_values].x = get_bits(gb, rangebits);

                    av_dlog(NULL, " %u. floor1 Y coord. %d\n", floor1_values,
                            floor_setup->data.t1.list[floor1_values].x);
                }
            }

// Precalculate order of x coordinates - needed for decode
            if (ff_vorbis_ready_floor1_list(vc->avccontext,
                                            floor_setup->data.t1.list,
                                            floor_setup->data.t1.x_list_dim)) {
                return AVERROR_INVALIDDATA;
            }

            for (j=1; j<floor_setup->data.t1.x_list_dim; j++) {
                if (   floor_setup->data.t1.list[ floor_setup->data.t1.list[j-1].sort ].x
                    == floor_setup->data.t1.list[ floor_setup->data.t1.list[j  ].sort ].x) {
                    av_log(vc->avccontext, AV_LOG_ERROR, "Non unique x values in floor type 1\n");
                    return AVERROR_INVALIDDATA;
                }
            }
        } else if (floor_setup->floor_type == 0) {
            unsigned max_codebook_dim = 0;

            floor_setup->decode = vorbis_floor0_decode;

            floor_setup->data.t0.order          = get_bits(gb,  8);
            floor_setup->data.t0.rate           = get_bits(gb, 16);
            floor_setup->data.t0.bark_map_size  = get_bits(gb, 16);
            if (floor_setup->data.t0.bark_map_size == 0) {
                av_log(vc->avccontext, AV_LOG_ERROR,
                       "Floor 0 bark map size is 0.\n");
                return AVERROR_INVALIDDATA;
            }
            floor_setup->data.t0.amplitude_bits = get_bits(gb,  6);
            /* zero would result in a div by zero later *
             * 2^0 - 1 == 0                             */
            if (floor_setup->data.t0.amplitude_bits == 0) {
                av_log(vc->avccontext, AV_LOG_ERROR,
                       "Floor 0 amplitude bits is 0.\n");
                return AVERROR_INVALIDDATA;
            }
            floor_setup->data.t0.amplitude_offset = get_bits(gb, 8);
            floor_setup->data.t0.num_books        = get_bits(gb, 4) + 1;

            /* allocate mem for booklist */
            floor_setup->data.t0.book_list =
                av_malloc(floor_setup->data.t0.num_books);
            if (!floor_setup->data.t0.book_list)
                return AVERROR(ENOMEM);
            /* read book indexes */
            {
                int idx;
                unsigned book_idx;
                for (idx = 0; idx < floor_setup->data.t0.num_books; ++idx) {
                    GET_VALIDATED_INDEX(book_idx, 8, vc->codebook_count)
                    floor_setup->data.t0.book_list[idx] = book_idx;
                    if (vc->codebooks[book_idx].dimensions > max_codebook_dim)
                        max_codebook_dim = vc->codebooks[book_idx].dimensions;
                }
            }

            create_map(vc, i);

            /* codebook dim is for padding if codebook dim doesn't *
             * divide order+1 then we need to read more data       */
            floor_setup->data.t0.lsp =
                av_malloc((floor_setup->data.t0.order + 1 + max_codebook_dim)
                          * sizeof(*floor_setup->data.t0.lsp));
            if (!floor_setup->data.t0.lsp)
                return AVERROR(ENOMEM);

            /* debug output parsed headers */
            av_dlog(NULL, "floor0 order: %u\n", floor_setup->data.t0.order);
            av_dlog(NULL, "floor0 rate: %u\n", floor_setup->data.t0.rate);
            av_dlog(NULL, "floor0 bark map size: %u\n",
                    floor_setup->data.t0.bark_map_size);
            av_dlog(NULL, "floor0 amplitude bits: %u\n",
                    floor_setup->data.t0.amplitude_bits);
            av_dlog(NULL, "floor0 amplitude offset: %u\n",
                    floor_setup->data.t0.amplitude_offset);
            av_dlog(NULL, "floor0 number of books: %u\n",
                    floor_setup->data.t0.num_books);
            av_dlog(NULL, "floor0 book list pointer: %p\n",
                    floor_setup->data.t0.book_list);
            {
                int idx;
                for (idx = 0; idx < floor_setup->data.t0.num_books; ++idx) {
                    av_dlog(NULL, "  Book %d: %u\n", idx + 1,
                            floor_setup->data.t0.book_list[idx]);
                }
            }
        } else {
            av_log(vc->avccontext, AV_LOG_ERROR, "Invalid floor type!\n");
            return AVERROR_INVALIDDATA;
        }
    }
    return 0;
}

// Process residues part

static int vorbis_parse_setup_hdr_residues(vorbis_context *vc)
{
    GetBitContext *gb = &vc->gb;
    unsigned i, j, k;

    vc->residue_count = get_bits(gb, 6)+1;
    vc->residues      = av_mallocz(vc->residue_count * sizeof(*vc->residues));

    av_dlog(NULL, " There are %d residues. \n", vc->residue_count);

    for (i = 0; i < vc->residue_count; ++i) {
        vorbis_residue *res_setup = &vc->residues[i];
        uint8_t cascade[64];
        unsigned high_bits, low_bits;

        res_setup->type = get_bits(gb, 16);

        av_dlog(NULL, " %u. residue type %d\n", i, res_setup->type);

        res_setup->begin          = get_bits(gb, 24);
        res_setup->end            = get_bits(gb, 24);
        res_setup->partition_size = get_bits(gb, 24) + 1;
        /* Validations to prevent a buffer overflow later. */
        if (res_setup->begin>res_setup->end ||
            res_setup->end > (res_setup->type == 2 ? vc->avccontext->channels : 1) * vc->blocksize[1] / 2 ||
            (res_setup->end-res_setup->begin) / res_setup->partition_size > V_MAX_PARTITIONS) {
            av_log(vc->avccontext, AV_LOG_ERROR,
                   "partition out of bounds: type, begin, end, size, blocksize: %"PRIu16", %"PRIu32", %"PRIu32", %u, %"PRIu32"\n",
                   res_setup->type, res_setup->begin, res_setup->end,
                   res_setup->partition_size, vc->blocksize[1] / 2);
            return AVERROR_INVALIDDATA;
        }

        res_setup->classifications = get_bits(gb, 6) + 1;
        GET_VALIDATED_INDEX(res_setup->classbook, 8, vc->codebook_count)

        res_setup->ptns_to_read =
            (res_setup->end - res_setup->begin) / res_setup->partition_size;
        res_setup->classifs = av_malloc(res_setup->ptns_to_read *
                                        vc->audio_channels *
                                        sizeof(*res_setup->classifs));
        if (!res_setup->classifs)
            return AVERROR(ENOMEM);

        av_dlog(NULL, "    begin %d end %d part.size %d classif.s %d classbook %d \n",
                res_setup->begin, res_setup->end, res_setup->partition_size,
                res_setup->classifications, res_setup->classbook);

        for (j = 0; j < res_setup->classifications; ++j) {
            high_bits = 0;
            low_bits  = get_bits(gb, 3);
            if (get_bits1(gb))
                high_bits = get_bits(gb, 5);
            cascade[j] = (high_bits << 3) + low_bits;

            av_dlog(NULL, "     %u class cascade depth: %d\n", j, ilog(cascade[j]));
        }

        res_setup->maxpass = 0;
        for (j = 0; j < res_setup->classifications; ++j) {
            for (k = 0; k < 8; ++k) {
                if (cascade[j]&(1 << k)) {
                    GET_VALIDATED_INDEX(res_setup->books[j][k], 8, vc->codebook_count)

                    av_dlog(NULL, "     %u class cascade depth %u book: %d\n",
                            j, k, res_setup->books[j][k]);

                    if (k>res_setup->maxpass)
                        res_setup->maxpass = k;
                } else {
                    res_setup->books[j][k] = -1;
                }
            }
        }
    }
    return 0;
}

// Process mappings part

static int vorbis_parse_setup_hdr_mappings(vorbis_context *vc)
{
    GetBitContext *gb = &vc->gb;
    unsigned i, j;

    vc->mapping_count = get_bits(gb, 6)+1;
    vc->mappings      = av_mallocz(vc->mapping_count * sizeof(*vc->mappings));

    av_dlog(NULL, " There are %d mappings. \n", vc->mapping_count);

    for (i = 0; i < vc->mapping_count; ++i) {
        vorbis_mapping *mapping_setup = &vc->mappings[i];

        if (get_bits(gb, 16)) {
            av_log(vc->avccontext, AV_LOG_ERROR, "Other mappings than type 0 are not compliant with the Vorbis I specification. \n");
            return AVERROR_INVALIDDATA;
        }
        if (get_bits1(gb)) {
            mapping_setup->submaps = get_bits(gb, 4) + 1;
        } else {
            mapping_setup->submaps = 1;
        }

        if (get_bits1(gb)) {
            mapping_setup->coupling_steps = get_bits(gb, 8) + 1;
            mapping_setup->magnitude      = av_mallocz(mapping_setup->coupling_steps *
                                                       sizeof(*mapping_setup->magnitude));
            mapping_setup->angle          = av_mallocz(mapping_setup->coupling_steps *
                                                       sizeof(*mapping_setup->angle));
            for (j = 0; j < mapping_setup->coupling_steps; ++j) {
                GET_VALIDATED_INDEX(mapping_setup->magnitude[j], ilog(vc->audio_channels - 1), vc->audio_channels)
                GET_VALIDATED_INDEX(mapping_setup->angle[j],     ilog(vc->audio_channels - 1), vc->audio_channels)
            }
        } else {
            mapping_setup->coupling_steps = 0;
        }

        av_dlog(NULL, "   %u mapping coupling steps: %d\n",
                i, mapping_setup->coupling_steps);

        if (get_bits(gb, 2)) {
            av_log(vc->avccontext, AV_LOG_ERROR, "%u. mapping setup data invalid.\n", i);
            return AVERROR_INVALIDDATA; // following spec.
        }

        if (mapping_setup->submaps>1) {
            mapping_setup->mux = av_mallocz(vc->audio_channels *
                                            sizeof(*mapping_setup->mux));
            for (j = 0; j < vc->audio_channels; ++j)
                mapping_setup->mux[j] = get_bits(gb, 4);
        }

        for (j = 0; j < mapping_setup->submaps; ++j) {
            skip_bits(gb, 8); // FIXME check?
            GET_VALIDATED_INDEX(mapping_setup->submap_floor[j],   8, vc->floor_count)
            GET_VALIDATED_INDEX(mapping_setup->submap_residue[j], 8, vc->residue_count)

            av_dlog(NULL, "   %u mapping %u submap : floor %d, residue %d\n", i, j,
                    mapping_setup->submap_floor[j],
                    mapping_setup->submap_residue[j]);
        }
    }
    return 0;
}

// Process modes part

static void create_map(vorbis_context *vc, unsigned floor_number)
{
    vorbis_floor *floors = vc->floors;
    vorbis_floor0 *vf;
    int idx;
    int blockflag, n;
    int32_t *map;

    for (blockflag = 0; blockflag < 2; ++blockflag) {
        n = vc->blocksize[blockflag] / 2;
        floors[floor_number].data.t0.map[blockflag] =
            av_malloc((n + 1) * sizeof(int32_t)); // n + sentinel

        map =  floors[floor_number].data.t0.map[blockflag];
        vf  = &floors[floor_number].data.t0;

        for (idx = 0; idx < n; ++idx) {
            map[idx] = floor(BARK((vf->rate * idx) / (2.0f * n)) *
                             (vf->bark_map_size / BARK(vf->rate / 2.0f)));
            if (vf->bark_map_size-1 < map[idx])
                map[idx] = vf->bark_map_size - 1;
        }
        map[n] = -1;
        vf->map_size[blockflag] = n;
    }

    for (idx = 0; idx <= n; ++idx) {
        av_dlog(NULL, "floor0 map: map at pos %d is %d\n", idx, map[idx]);
    }
}

static int vorbis_parse_setup_hdr_modes(vorbis_context *vc)
{
    GetBitContext *gb = &vc->gb;
    unsigned i;

    vc->mode_count = get_bits(gb, 6) + 1;
    vc->modes      = av_mallocz(vc->mode_count * sizeof(*vc->modes));

    av_dlog(NULL, " There are %d modes.\n", vc->mode_count);

    for (i = 0; i < vc->mode_count; ++i) {
        vorbis_mode *mode_setup = &vc->modes[i];

        mode_setup->blockflag     = get_bits1(gb);
        mode_setup->windowtype    = get_bits(gb, 16); //FIXME check
        mode_setup->transformtype = get_bits(gb, 16); //FIXME check
        GET_VALIDATED_INDEX(mode_setup->mapping, 8, vc->mapping_count);

        av_dlog(NULL, " %u mode: blockflag %d, windowtype %d, transformtype %d, mapping %d\n",
                i, mode_setup->blockflag, mode_setup->windowtype,
                mode_setup->transformtype, mode_setup->mapping);
    }
    return 0;
}

// Process the whole setup header using the functions above

static int vorbis_parse_setup_hdr(vorbis_context *vc)
{
    GetBitContext *gb = &vc->gb;
    int ret;

    if ((get_bits(gb, 8) != 'v') || (get_bits(gb, 8) != 'o') ||
        (get_bits(gb, 8) != 'r') || (get_bits(gb, 8) != 'b') ||
        (get_bits(gb, 8) != 'i') || (get_bits(gb, 8) != 's')) {
        av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (no vorbis signature). \n");
        return AVERROR_INVALIDDATA;
    }

    if ((ret = vorbis_parse_setup_hdr_codebooks(vc))) {
        av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (codebooks). \n");
        return ret;
    }
    if ((ret = vorbis_parse_setup_hdr_tdtransforms(vc))) {
        av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (time domain transforms). \n");
        return ret;
    }
    if ((ret = vorbis_parse_setup_hdr_floors(vc))) {
        av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (floors). \n");
        return ret;
    }
    if ((ret = vorbis_parse_setup_hdr_residues(vc))) {
        av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (residues). \n");
        return ret;
    }
    if ((ret = vorbis_parse_setup_hdr_mappings(vc))) {
        av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (mappings). \n");
        return ret;
    }
    if ((ret = vorbis_parse_setup_hdr_modes(vc))) {
        av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (modes). \n");
        return ret;
    }
    if (!get_bits1(gb)) {
        av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (framing flag). \n");
        return AVERROR_INVALIDDATA; // framing flag bit unset error
    }

    return 0;
}

// Process the identification header

static int vorbis_parse_id_hdr(vorbis_context *vc)
{
    GetBitContext *gb = &vc->gb;
    unsigned bl0, bl1;

    if ((get_bits(gb, 8) != 'v') || (get_bits(gb, 8) != 'o') ||
        (get_bits(gb, 8) != 'r') || (get_bits(gb, 8) != 'b') ||
        (get_bits(gb, 8) != 'i') || (get_bits(gb, 8) != 's')) {
        av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis id header packet corrupt (no vorbis signature). \n");
        return AVERROR_INVALIDDATA;
    }

    vc->version        = get_bits_long(gb, 32);    //FIXME check 0
    vc->audio_channels = get_bits(gb, 8);
    if (vc->audio_channels <= 0) {
        av_log(vc->avccontext, AV_LOG_ERROR, "Invalid number of channels\n");
        return AVERROR_INVALIDDATA;
    }
    vc->audio_samplerate = get_bits_long(gb, 32);
    if (vc->audio_samplerate <= 0) {
        av_log(vc->avccontext, AV_LOG_ERROR, "Invalid samplerate\n");
        return AVERROR_INVALIDDATA;
    }
    vc->bitrate_maximum = get_bits_long(gb, 32);
    vc->bitrate_nominal = get_bits_long(gb, 32);
    vc->bitrate_minimum = get_bits_long(gb, 32);
    bl0 = get_bits(gb, 4);
    bl1 = get_bits(gb, 4);
    if (bl0 > 13 || bl0 < 6 || bl1 > 13 || bl1 < 6 || bl1 < bl0) {
        av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis id header packet corrupt (illegal blocksize). \n");
        return AVERROR_INVALIDDATA;
    }
    vc->blocksize[0] = (1 << bl0);
    vc->blocksize[1] = (1 << bl1);
    vc->win[0] = ff_vorbis_vwin[bl0 - 6];
    vc->win[1] = ff_vorbis_vwin[bl1 - 6];

    if ((get_bits1(gb)) == 0) {
        av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis id header packet corrupt (framing flag not set). \n");
        return AVERROR_INVALIDDATA;
    }

    vc->channel_residues =  av_malloc((vc->blocksize[1]  / 2) * vc->audio_channels * sizeof(*vc->channel_residues));
    vc->channel_floors   =  av_malloc((vc->blocksize[1]  / 2) * vc->audio_channels * sizeof(*vc->channel_floors));
    vc->saved            =  av_mallocz((vc->blocksize[1] / 4) * vc->audio_channels * sizeof(*vc->saved));
    vc->previous_window  = 0;

    ff_mdct_init(&vc->mdct[0], bl0, 1, -vc->scale_bias);
    ff_mdct_init(&vc->mdct[1], bl1, 1, -vc->scale_bias);

    av_dlog(NULL, " vorbis version %d \n audio_channels %d \n audio_samplerate %d \n bitrate_max %d \n bitrate_nom %d \n bitrate_min %d \n blk_0 %d blk_1 %d \n ",
            vc->version, vc->audio_channels, vc->audio_samplerate, vc->bitrate_maximum, vc->bitrate_nominal, vc->bitrate_minimum, vc->blocksize[0], vc->blocksize[1]);

/*
    BLK = vc->blocksize[0];
    for (i = 0; i < BLK / 2; ++i) {
        vc->win[0][i] = sin(0.5*3.14159265358*(sin(((float)i + 0.5) / (float)BLK*3.14159265358))*(sin(((float)i + 0.5) / (float)BLK*3.14159265358)));
    }
*/

    return 0;
}

// Process the extradata using the functions above (identification header, setup header)

static av_cold int vorbis_decode_init(AVCodecContext *avccontext)
{
    vorbis_context *vc = avccontext->priv_data;
    uint8_t *headers   = avccontext->extradata;
    int headers_len    = avccontext->extradata_size;
    uint8_t *header_start[3];
    int header_len[3];
    GetBitContext *gb = &vc->gb;
    int hdr_type, ret;

    vc->avccontext = avccontext;
    dsputil_init(&vc->dsp, avccontext);
    ff_fmt_convert_init(&vc->fmt_conv, avccontext);

    if (avccontext->request_sample_fmt == AV_SAMPLE_FMT_FLT) {
        avccontext->sample_fmt = AV_SAMPLE_FMT_FLT;
        vc->scale_bias = 1.0f;
    } else {
        avccontext->sample_fmt = AV_SAMPLE_FMT_S16;
        vc->scale_bias = 32768.0f;
    }

    if (!headers_len) {
        av_log(avccontext, AV_LOG_ERROR, "Extradata missing.\n");
        return AVERROR_INVALIDDATA;
    }

    if ((ret = avpriv_split_xiph_headers(headers, headers_len, 30, header_start, header_len)) < 0) {
        av_log(avccontext, AV_LOG_ERROR, "Extradata corrupt.\n");
        return ret;
    }

    init_get_bits(gb, header_start[0], header_len[0]*8);
    hdr_type = get_bits(gb, 8);
    if (hdr_type != 1) {
        av_log(avccontext, AV_LOG_ERROR, "First header is not the id header.\n");
        return AVERROR_INVALIDDATA;
    }
    if ((ret = vorbis_parse_id_hdr(vc))) {
        av_log(avccontext, AV_LOG_ERROR, "Id header corrupt.\n");
        vorbis_free(vc);
        return ret;
    }

    init_get_bits(gb, header_start[2], header_len[2]*8);
    hdr_type = get_bits(gb, 8);
    if (hdr_type != 5) {
        av_log(avccontext, AV_LOG_ERROR, "Third header is not the setup header.\n");
        vorbis_free(vc);
        return AVERROR_INVALIDDATA;
    }
    if ((ret = vorbis_parse_setup_hdr(vc))) {
        av_log(avccontext, AV_LOG_ERROR, "Setup header corrupt.\n");
        vorbis_free(vc);
        return ret;
    }

    if (vc->audio_channels > 8)
        avccontext->channel_layout = 0;
    else
        avccontext->channel_layout = ff_vorbis_channel_layouts[vc->audio_channels - 1];

    avccontext->channels    = vc->audio_channels;
    avccontext->sample_rate = vc->audio_samplerate;
    avccontext->frame_size  = FFMIN(vc->blocksize[0], vc->blocksize[1]) >> 2;

    avcodec_get_frame_defaults(&vc->frame);
    avccontext->coded_frame = &vc->frame;

    return 0;
}

// Decode audiopackets -------------------------------------------------

// Read and decode floor

static int vorbis_floor0_decode(vorbis_context *vc,
                                vorbis_floor_data *vfu, float *vec)
{
    vorbis_floor0 *vf = &vfu->t0;
    float *lsp = vf->lsp;
    unsigned amplitude, book_idx;
    unsigned blockflag = vc->modes[vc->mode_number].blockflag;

    amplitude = get_bits(&vc->gb, vf->amplitude_bits);
    if (amplitude > 0) {
        float last = 0;
        unsigned idx, lsp_len = 0;
        vorbis_codebook codebook;

        book_idx = get_bits(&vc->gb, ilog(vf->num_books));
        if (book_idx >= vf->num_books) {
            av_log(vc->avccontext, AV_LOG_ERROR,
                    "floor0 dec: booknumber too high!\n");
            book_idx =  0;
        }
        av_dlog(NULL, "floor0 dec: booknumber: %u\n", book_idx);
        codebook = vc->codebooks[vf->book_list[book_idx]];
        /* Invalid codebook! */
        if (!codebook.codevectors)
            return AVERROR_INVALIDDATA;

        while (lsp_len<vf->order) {
            int vec_off;

            av_dlog(NULL, "floor0 dec: book dimension: %d\n", codebook.dimensions);
            av_dlog(NULL, "floor0 dec: maximum depth: %d\n", codebook.maxdepth);
            /* read temp vector */
            vec_off = get_vlc2(&vc->gb, codebook.vlc.table,
                               codebook.nb_bits, codebook.maxdepth)
                      * codebook.dimensions;
            av_dlog(NULL, "floor0 dec: vector offset: %d\n", vec_off);
            /* copy each vector component and add last to it */
            for (idx = 0; idx < codebook.dimensions; ++idx)
                lsp[lsp_len+idx] = codebook.codevectors[vec_off+idx] + last;
            last = lsp[lsp_len+idx-1]; /* set last to last vector component */

            lsp_len += codebook.dimensions;
        }
        /* DEBUG: output lsp coeffs */
        {
            int idx;
            for (idx = 0; idx < lsp_len; ++idx)
                av_dlog(NULL, "floor0 dec: coeff at %d is %f\n", idx, lsp[idx]);
        }

        /* synthesize floor output vector */
        {
            int i;
            int order = vf->order;
            float wstep = M_PI / vf->bark_map_size;

            for (i = 0; i < order; i++)
                lsp[i] = 2.0f * cos(lsp[i]);

            av_dlog(NULL, "floor0 synth: map_size = %"PRIu32"; m = %d; wstep = %f\n",
                    vf->map_size[blockflag], order, wstep);

            i = 0;
            while (i < vf->map_size[blockflag]) {
                int j, iter_cond = vf->map[blockflag][i];
                float p = 0.5f;
                float q = 0.5f;
                float two_cos_w = 2.0f * cos(wstep * iter_cond); // needed all times

                /* similar part for the q and p products */
                for (j = 0; j + 1 < order; j += 2) {
                    q *= lsp[j]     - two_cos_w;
                    p *= lsp[j + 1] - two_cos_w;
                }
                if (j == order) { // even order
                    p *= p * (2.0f - two_cos_w);
                    q *= q * (2.0f + two_cos_w);
                } else { // odd order
                    q *= two_cos_w-lsp[j]; // one more time for q

                    /* final step and square */
                    p *= p * (4.f - two_cos_w * two_cos_w);
                    q *= q;
                }

                /* calculate linear floor value */
                q = exp((((amplitude*vf->amplitude_offset) /
                          (((1 << vf->amplitude_bits) - 1) * sqrt(p + q)))
                         - vf->amplitude_offset) * .11512925f);

                /* fill vector */
                do {
                    vec[i] = q; ++i;
                } while (vf->map[blockflag][i] == iter_cond);
            }
        }
    } else {
        /* this channel is unused */
        return 1;
    }

    av_dlog(NULL, " Floor0 decoded\n");

    return 0;
}

static int vorbis_floor1_decode(vorbis_context *vc,
                                vorbis_floor_data *vfu, float *vec)
{
    vorbis_floor1 *vf = &vfu->t1;
    GetBitContext *gb = &vc->gb;
    uint16_t range_v[4] = { 256, 128, 86, 64 };
    unsigned range = range_v[vf->multiplier - 1];
    uint16_t floor1_Y[258];
    uint16_t floor1_Y_final[258];
    int floor1_flag[258];
    unsigned partition_class, cdim, cbits, csub, cval, offset, i, j;
    int book, adx, ady, dy, off, predicted, err;


    if (!get_bits1(gb)) // silence
        return 1;

// Read values (or differences) for the floor's points

    floor1_Y[0] = get_bits(gb, ilog(range - 1));
    floor1_Y[1] = get_bits(gb, ilog(range - 1));

    av_dlog(NULL, "floor 0 Y %d floor 1 Y %d \n", floor1_Y[0], floor1_Y[1]);

    offset = 2;
    for (i = 0; i < vf->partitions; ++i) {
        partition_class = vf->partition_class[i];
        cdim   = vf->class_dimensions[partition_class];
        cbits  = vf->class_subclasses[partition_class];
        csub = (1 << cbits) - 1;
        cval = 0;

        av_dlog(NULL, "Cbits %u\n", cbits);

        if (cbits) // this reads all subclasses for this partition's class
            cval = get_vlc2(gb, vc->codebooks[vf->class_masterbook[partition_class]].vlc.table,
                            vc->codebooks[vf->class_masterbook[partition_class]].nb_bits, 3);

        for (j = 0; j < cdim; ++j) {
            book = vf->subclass_books[partition_class][cval & csub];

            av_dlog(NULL, "book %d Cbits %u cval %u  bits:%d\n",
                    book, cbits, cval, get_bits_count(gb));

            cval = cval >> cbits;
            if (book > -1) {
                floor1_Y[offset+j] = get_vlc2(gb, vc->codebooks[book].vlc.table,
                vc->codebooks[book].nb_bits, 3);
            } else {
                floor1_Y[offset+j] = 0;
            }

            av_dlog(NULL, " floor(%d) = %d \n",
                    vf->list[offset+j].x, floor1_Y[offset+j]);
        }
        offset+=cdim;
    }

// Amplitude calculation from the differences

    floor1_flag[0] = 1;
    floor1_flag[1] = 1;
    floor1_Y_final[0] = floor1_Y[0];
    floor1_Y_final[1] = floor1_Y[1];

    for (i = 2; i < vf->x_list_dim; ++i) {
        unsigned val, highroom, lowroom, room, high_neigh_offs, low_neigh_offs;

        low_neigh_offs  = vf->list[i].low;
        high_neigh_offs = vf->list[i].high;
        dy  = floor1_Y_final[high_neigh_offs] - floor1_Y_final[low_neigh_offs];  // render_point begin
        adx = vf->list[high_neigh_offs].x - vf->list[low_neigh_offs].x;
        ady = FFABS(dy);
        err = ady * (vf->list[i].x - vf->list[low_neigh_offs].x);
        off = err / adx;
        if (dy < 0) {
            predicted = floor1_Y_final[low_neigh_offs] - off;
        } else {
            predicted = floor1_Y_final[low_neigh_offs] + off;
        } // render_point end

        val = floor1_Y[i];
        highroom = range-predicted;
        lowroom  = predicted;
        if (highroom < lowroom) {
            room = highroom * 2;
        } else {
            room = lowroom * 2;   // SPEC mispelling
        }
        if (val) {
            floor1_flag[low_neigh_offs]  = 1;
            floor1_flag[high_neigh_offs] = 1;
            floor1_flag[i]               = 1;
            if (val >= room) {
                if (highroom > lowroom) {
                    floor1_Y_final[i] = av_clip_uint16(val - lowroom + predicted);
                } else {
                    floor1_Y_final[i] = av_clip_uint16(predicted - val + highroom - 1);
                }
            } else {
                if (val & 1) {
                    floor1_Y_final[i] = av_clip_uint16(predicted - (val + 1) / 2);
                } else {
                    floor1_Y_final[i] = av_clip_uint16(predicted + val / 2);
                }
            }
        } else {
            floor1_flag[i]    = 0;
            floor1_Y_final[i] = av_clip_uint16(predicted);
        }

        av_dlog(NULL, " Decoded floor(%d) = %u / val %u\n",
                vf->list[i].x, floor1_Y_final[i], val);
    }

// Curve synth - connect the calculated dots and convert from dB scale FIXME optimize ?

    ff_vorbis_floor1_render_list(vf->list, vf->x_list_dim, floor1_Y_final, floor1_flag, vf->multiplier, vec, vf->list[1].x);

    av_dlog(NULL, " Floor decoded\n");

    return 0;
}

// Read and decode residue

static av_always_inline int vorbis_residue_decode_internal(vorbis_context *vc,
                                                           vorbis_residue *vr,
                                                           unsigned ch,
                                                           uint8_t *do_not_decode,
                                                           float *vec,
                                                           unsigned vlen,
                                                           unsigned ch_left,
                                                           int vr_type)
{
    GetBitContext *gb = &vc->gb;
    unsigned c_p_c        = vc->codebooks[vr->classbook].dimensions;
    unsigned ptns_to_read = vr->ptns_to_read;
    uint8_t *classifs = vr->classifs;
    unsigned pass, ch_used, i, j, k, l;
    unsigned max_output = (ch - 1) * vlen;

    if (vr_type == 2) {
        for (j = 1; j < ch; ++j)
            do_not_decode[0] &= do_not_decode[j];  // FIXME - clobbering input
        if (do_not_decode[0])
            return 0;
        ch_used = 1;
        max_output += vr->end / ch;
    } else {
        ch_used = ch;
        max_output += vr->end;
    }

    if (max_output > ch_left * vlen) {
        av_log(vc->avccontext, AV_LOG_ERROR, "Insufficient output buffer\n");
        return -1;
    }

    av_dlog(NULL, " residue type 0/1/2 decode begin, ch: %d  cpc %d  \n", ch, c_p_c);

    for (pass = 0; pass <= vr->maxpass; ++pass) { // FIXME OPTIMIZE?
        uint16_t voffset, partition_count, j_times_ptns_to_read;

        voffset = vr->begin;
        for (partition_count = 0; partition_count < ptns_to_read;) {  // SPEC        error
            if (!pass) {
                unsigned inverse_class = ff_inverse[vr->classifications];
                for (j_times_ptns_to_read = 0, j = 0; j < ch_used; ++j) {
                    if (!do_not_decode[j]) {
                        unsigned temp = get_vlc2(gb, vc->codebooks[vr->classbook].vlc.table,
                                                 vc->codebooks[vr->classbook].nb_bits, 3);

                        av_dlog(NULL, "Classword: %u\n", temp);

                        assert(vr->classifications > 1 && temp <= 65536); //needed for inverse[]
                        for (i = 0; i < c_p_c; ++i) {
                            unsigned temp2;

                            temp2 = (((uint64_t)temp) * inverse_class) >> 32;
                            if (partition_count + c_p_c - 1 - i < ptns_to_read)
                                classifs[j_times_ptns_to_read + partition_count + c_p_c - 1 - i] = temp - temp2 * vr->classifications;
                            temp = temp2;
                        }
                    }
                    j_times_ptns_to_read += ptns_to_read;
                }
            }
            for (i = 0; (i < c_p_c) && (partition_count < ptns_to_read); ++i) {
                for (j_times_ptns_to_read = 0, j = 0; j < ch_used; ++j) {
                    unsigned voffs;

                    if (!do_not_decode[j]) {
                        unsigned vqclass = classifs[j_times_ptns_to_read + partition_count];
                        int vqbook  = vr->books[vqclass][pass];

                        if (vqbook >= 0 && vc->codebooks[vqbook].codevectors) {
                            unsigned coffs;
                            unsigned dim  = vc->codebooks[vqbook].dimensions;
                            unsigned step = dim == 1 ? vr->partition_size
                                                     : FASTDIV(vr->partition_size, dim);
                            vorbis_codebook codebook = vc->codebooks[vqbook];

                            if (vr_type == 0) {

                                voffs = voffset+j*vlen;
                                for (k = 0; k < step; ++k) {
                                    coffs = get_vlc2(gb, codebook.vlc.table, codebook.nb_bits, 3) * dim;
                                    for (l = 0; l < dim; ++l)
                                        vec[voffs + k + l * step] += codebook.codevectors[coffs + l];  // FPMATH
                                }
                            } else if (vr_type == 1) {
                                voffs = voffset + j * vlen;
                                for (k = 0; k < step; ++k) {
                                    coffs = get_vlc2(gb, codebook.vlc.table, codebook.nb_bits, 3) * dim;
                                    for (l = 0; l < dim; ++l, ++voffs) {
                                        vec[voffs]+=codebook.codevectors[coffs+l];  // FPMATH

                                        av_dlog(NULL, " pass %d offs: %d curr: %f change: %f cv offs.: %d  \n",
                                                pass, voffs, vec[voffs], codebook.codevectors[coffs+l], coffs);
                                    }
                                }
                            } else if (vr_type == 2 && ch == 2 && (voffset & 1) == 0 && (dim & 1) == 0) { // most frequent case optimized
                                voffs = voffset >> 1;

                                if (dim == 2) {
                                    for (k = 0; k < step; ++k) {
                                        coffs = get_vlc2(gb, codebook.vlc.table, codebook.nb_bits, 3) * 2;
                                        vec[voffs + k       ] += codebook.codevectors[coffs    ];  // FPMATH
                                        vec[voffs + k + vlen] += codebook.codevectors[coffs + 1];  // FPMATH
                                    }
                                } else if (dim == 4) {
                                    for (k = 0; k < step; ++k, voffs += 2) {
                                        coffs = get_vlc2(gb, codebook.vlc.table, codebook.nb_bits, 3) * 4;
                                        vec[voffs           ] += codebook.codevectors[coffs    ];  // FPMATH
                                        vec[voffs + 1       ] += codebook.codevectors[coffs + 2];  // FPMATH
                                        vec[voffs + vlen    ] += codebook.codevectors[coffs + 1];  // FPMATH
                                        vec[voffs + vlen + 1] += codebook.codevectors[coffs + 3];  // FPMATH
                                    }
                                } else
                                for (k = 0; k < step; ++k) {
                                    coffs = get_vlc2(gb, codebook.vlc.table, codebook.nb_bits, 3) * dim;
                                    for (l = 0; l < dim; l += 2, voffs++) {
                                        vec[voffs       ] += codebook.codevectors[coffs + l    ];  // FPMATH
                                        vec[voffs + vlen] += codebook.codevectors[coffs + l + 1];  // FPMATH

                                        av_dlog(NULL, " pass %d offs: %d curr: %f change: %f cv offs.: %d+%d  \n",
                                                pass, voffset / ch + (voffs % ch) * vlen,
                                                vec[voffset / ch + (voffs % ch) * vlen],
                                                codebook.codevectors[coffs + l], coffs, l);
                                    }
                                }

                            } else if (vr_type == 2) {
                                voffs = voffset;

                                for (k = 0; k < step; ++k) {
                                    coffs = get_vlc2(gb, codebook.vlc.table, codebook.nb_bits, 3) * dim;
                                    for (l = 0; l < dim; ++l, ++voffs) {
                                        vec[voffs / ch + (voffs % ch) * vlen] += codebook.codevectors[coffs + l];  // FPMATH FIXME use if and counter instead of / and %

                                        av_dlog(NULL, " pass %d offs: %d curr: %f change: %f cv offs.: %d+%d  \n",
                                                pass, voffset / ch + (voffs % ch) * vlen,
                                                vec[voffset / ch + (voffs % ch) * vlen],
                                                codebook.codevectors[coffs + l], coffs, l);
                                    }
                                }
                            }
                        }
                    }
                    j_times_ptns_to_read += ptns_to_read;
                }
                ++partition_count;
                voffset += vr->partition_size;
            }
        }
    }
    return 0;
}

static inline int vorbis_residue_decode(vorbis_context *vc, vorbis_residue *vr,
                                        unsigned ch,
                                        uint8_t *do_not_decode,
                                        float *vec, unsigned vlen,
                                        unsigned ch_left)
{
    if (vr->type == 2)
        return vorbis_residue_decode_internal(vc, vr, ch, do_not_decode, vec, vlen, ch_left, 2);
    else if (vr->type == 1)
        return vorbis_residue_decode_internal(vc, vr, ch, do_not_decode, vec, vlen, ch_left, 1);
    else if (vr->type == 0)
        return vorbis_residue_decode_internal(vc, vr, ch, do_not_decode, vec, vlen, ch_left, 0);
    else {
        av_log(vc->avccontext, AV_LOG_ERROR, " Invalid residue type while residue decode?! \n");
        return AVERROR_INVALIDDATA;
    }
}

void vorbis_inverse_coupling(float *mag, float *ang, int blocksize)
{
    int i;
    for (i = 0;  i < blocksize;  i++) {
        if (mag[i] > 0.0) {
            if (ang[i] > 0.0) {
                ang[i] = mag[i] - ang[i];
            } else {
                float temp = ang[i];
                ang[i]     = mag[i];
                mag[i]    += temp;
            }
        } else {
            if (ang[i] > 0.0) {
                ang[i] += mag[i];
            } else {
                float temp = ang[i];
                ang[i]     = mag[i];
                mag[i]    -= temp;
            }
        }
    }
}

// Decode the audio packet using the functions above

static int vorbis_parse_audio_packet(vorbis_context *vc)
{
    GetBitContext *gb = &vc->gb;
    FFTContext *mdct;
    unsigned previous_window = vc->previous_window;
    unsigned mode_number, blockflag, blocksize;
    int i, j;
    uint8_t no_residue[255];
    uint8_t do_not_decode[255];
    vorbis_mapping *mapping;
    float *ch_res_ptr   = vc->channel_residues;
    float *ch_floor_ptr = vc->channel_floors;
    uint8_t res_chan[255];
    unsigned res_num = 0;
    int retlen  = 0;
    unsigned ch_left = vc->audio_channels;
    unsigned vlen;

    if (get_bits1(gb)) {
        av_log(vc->avccontext, AV_LOG_ERROR, "Not a Vorbis I audio packet.\n");
        return AVERROR_INVALIDDATA; // packet type not audio
    }

    if (vc->mode_count == 1) {
        mode_number = 0;
    } else {
        GET_VALIDATED_INDEX(mode_number, ilog(vc->mode_count-1), vc->mode_count)
    }
    vc->mode_number = mode_number;
    mapping = &vc->mappings[vc->modes[mode_number].mapping];

    av_dlog(NULL, " Mode number: %u , mapping: %d , blocktype %d\n", mode_number,
            vc->modes[mode_number].mapping, vc->modes[mode_number].blockflag);

    blockflag = vc->modes[mode_number].blockflag;
    blocksize = vc->blocksize[blockflag];
    vlen = blocksize / 2;
    if (blockflag)
        skip_bits(gb, 2); // previous_window, next_window

    memset(ch_res_ptr,   0, sizeof(float) * vc->audio_channels * vlen); //FIXME can this be removed ?
    memset(ch_floor_ptr, 0, sizeof(float) * vc->audio_channels * vlen); //FIXME can this be removed ?

// Decode floor

    for (i = 0; i < vc->audio_channels; ++i) {
        vorbis_floor *floor;
        int ret;
        if (mapping->submaps > 1) {
            floor = &vc->floors[mapping->submap_floor[mapping->mux[i]]];
        } else {
            floor = &vc->floors[mapping->submap_floor[0]];
        }

        ret = floor->decode(vc, &floor->data, ch_floor_ptr);

        if (ret < 0) {
            av_log(vc->avccontext, AV_LOG_ERROR, "Invalid codebook in vorbis_floor_decode.\n");
            return AVERROR_INVALIDDATA;
        }
        no_residue[i] = ret;
        ch_floor_ptr += vlen;
    }

// 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;
        unsigned ch = 0;
        int ret;

        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]];
        if (ch_left < ch) {
            av_log(vc->avccontext, AV_LOG_ERROR, "Too many channels in vorbis_floor_decode.\n");
            return -1;
        }
        if (ch) {
            ret = vorbis_residue_decode(vc, residue, ch, do_not_decode, ch_res_ptr, vlen, ch_left);
            if (ret < 0)
                return ret;
        }

        ch_res_ptr += ch * vlen;
        ch_left -= ch;
    }

// 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;
        vc->dsp.vorbis_inverse_coupling(mag, ang, blocksize / 2);
    }

// Dotproduct, MDCT

    mdct = &vc->mdct[blockflag];

    for (j = vc->audio_channels-1;j >= 0; j--) {
        ch_floor_ptr = vc->channel_floors   + j           * blocksize / 2;
        ch_res_ptr   = vc->channel_residues + res_chan[j] * blocksize / 2;
        vc->dsp.vector_fmul(ch_floor_ptr, ch_floor_ptr, ch_res_ptr, blocksize / 2);
        mdct->imdct_half(mdct, ch_res_ptr, ch_floor_ptr);
    }

// Overlap/add, save data for next overlapping  FPMATH

    retlen = (blocksize + vc->blocksize[previous_window]) / 4;
    for (j = 0; j < vc->audio_channels; j++) {
        unsigned bs0 = vc->blocksize[0];
        unsigned bs1 = vc->blocksize[1];
        float *residue    = vc->channel_residues + res_chan[j] * blocksize / 2;
        float *saved      = vc->saved + j * bs1 / 4;
        float *ret        = vc->channel_floors + j * retlen;
        float *buf        = residue;
        const float *win  = vc->win[blockflag & previous_window];

        if (blockflag == previous_window) {
            vc->dsp.vector_fmul_window(ret, saved, buf, win, blocksize / 4);
        } else if (blockflag > previous_window) {
            vc->dsp.vector_fmul_window(ret, saved, buf, win, bs0 / 4);
            memcpy(ret+bs0/2, buf+bs0/4, ((bs1-bs0)/4) * sizeof(float));
        } else {
            memcpy(ret, saved, ((bs1 - bs0) / 4) * sizeof(float));
            vc->dsp.vector_fmul_window(ret + (bs1 - bs0) / 4, saved + (bs1 - bs0) / 4, buf, win, bs0 / 4);
        }
        memcpy(saved, buf + blocksize / 4, blocksize / 4 * sizeof(float));
    }

    vc->previous_window = blockflag;
    return retlen;
}

// Return the decoded audio packet through the standard api

static int vorbis_decode_frame(AVCodecContext *avccontext, void *data,
                               int *got_frame_ptr, AVPacket *avpkt)
{
    const uint8_t *buf = avpkt->data;
    int buf_size       = avpkt->size;
    vorbis_context *vc = avccontext->priv_data;
    GetBitContext *gb = &vc->gb;
    const float *channel_ptrs[255];
    int i, len, ret;

    av_dlog(NULL, "packet length %d \n", buf_size);

    init_get_bits(gb, buf, buf_size*8);

    if ((len = vorbis_parse_audio_packet(vc)) <= 0)
        return len;

    if (!vc->first_frame) {
        vc->first_frame = 1;
        *got_frame_ptr = 0;
        return buf_size;
    }

    av_dlog(NULL, "parsed %d bytes %d bits, returned %d samples (*ch*bits) \n",
            get_bits_count(gb) / 8, get_bits_count(gb) % 8, len);

    /* get output buffer */
    vc->frame.nb_samples = len;
    if ((ret = ff_get_buffer(avccontext, &vc->frame)) < 0) {
        av_log(avccontext, AV_LOG_ERROR, "get_buffer() failed\n");
        return ret;
    }

    if (vc->audio_channels > 8) {
        for (i = 0; i < vc->audio_channels; i++)
            channel_ptrs[i] = vc->channel_floors + i * len;
    } else {
        for (i = 0; i < vc->audio_channels; i++)
            channel_ptrs[i] = vc->channel_floors +
                              len * ff_vorbis_channel_layout_offsets[vc->audio_channels - 1][i];
    }

    if (avccontext->sample_fmt == AV_SAMPLE_FMT_FLT)
        vc->fmt_conv.float_interleave((float *)vc->frame.data[0], channel_ptrs,
                                      len, vc->audio_channels);
    else
        vc->fmt_conv.float_to_int16_interleave((int16_t *)vc->frame.data[0],
                                               channel_ptrs, len,
                                               vc->audio_channels);

    *got_frame_ptr   = 1;
    *(AVFrame *)data = vc->frame;

    return buf_size;
}

// Close decoder

static av_cold int vorbis_decode_close(AVCodecContext *avccontext)
{
    vorbis_context *vc = avccontext->priv_data;

    vorbis_free(vc);

    return 0;
}

AVCodec ff_vorbis_decoder = {
    .name           = "vorbis",
    .type           = AVMEDIA_TYPE_AUDIO,
    .id             = CODEC_ID_VORBIS,
    .priv_data_size = sizeof(vorbis_context),
    .init           = vorbis_decode_init,
    .close          = vorbis_decode_close,
    .decode         = vorbis_decode_frame,
    .capabilities   = CODEC_CAP_DR1,
    .long_name = NULL_IF_CONFIG_SMALL("Vorbis"),
    .channel_layouts = ff_vorbis_channel_layouts,
    .sample_fmts = (const enum AVSampleFormat[]) {
        AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE
    },
};

