/* rebuilds an external Wwise codebook referenced by id to a Vorbis codebook */
        static int ww2ogg_codebook_library_rebuild_by_id(dBitWrite w_bits, uint codebook_id)
        {
            /* Wwise codebook buffer */
            var tmp = new BinaryReader(new MemoryStream(wvc_list_aotuv603[codebook_id]));

            ww2ogg_codebook_library_rebuild(w_bits, BitReader(tmp));
            tmp.Dispose();
            return(1);
        }
        /* rebuilds a Wwise codebook into a Vorbis codebook */
        static void ww2ogg_codebook_library_rebuild(dBitWrite w_bits, dBitRead r_bits)
        {
            w_bits(24, 0x564342); /* "VCB" */
            var dimensions = r_bits(4);

            w_bits(16, dimensions); /* 4 to 16 */
            var entries = r_bits(14);

            w_bits(24, entries); /* 14 to 24*/

            /* codeword lengths */
            var ordered = r_bits(1);

            w_bits(1, ordered);
            if (0 != ordered)
            {
                var initial_length = r_bits(5);
                w_bits(5, initial_length);

                var current_entry = 0;
                while (current_entry < entries)
                {
                    var number_bits = ww2ogg_tremor_ilog((uint)(entries - current_entry));

                    var number = r_bits(number_bits);
                    w_bits(number_bits, number);
                    current_entry += (int)number;
                }
                if (current_entry > entries)
                {
                    throw new System.Exception("Wwise Vorbis: current_entry out of range\n");
                }
            }
            else
            {
                var codeword_length_length = r_bits(3);
                var sparse = r_bits(1);
                w_bits(1, sparse);

                if (0 == codeword_length_length || 5 < codeword_length_length)
                {
                    throw new System.Exception("Wwise Vorbis: nonsense codeword length\n");
                }

                for (var i = 0; i < entries; i++)
                {
                    var present_bool = true;
                    if (0 != sparse)
                    {
                        var present = r_bits(1);
                        w_bits(1, present);

                        present_bool = (0 != present);
                    }

                    if (present_bool)
                    {
                        var codeword_length = r_bits(codeword_length_length);
                        w_bits(5, codeword_length); /* max 7 (3b) to 5 */
                    }
                }
            }


            /* lookup table */
            var lookup_type = r_bits(1);

            w_bits(4, lookup_type); /* 1 to 4 */

            if (0 == lookup_type)
            {
                //VGM_LOG("Wwise Vorbis: no lookup table\n");
            }
            else if (1 == lookup_type)
            {
                //VGM_LOG("Wwise Vorbis: lookup type 1\n");
                var min = r_bits(32);
                w_bits(32, min);
                var max = r_bits(32);
                w_bits(32, max);
                var value_length = r_bits(4);
                w_bits(4, value_length);
                var sequence_flag = r_bits(1);
                w_bits(1, sequence_flag);

                var quantvals = ww2ogg_tremor_book_maptype1_quantvals(entries, dimensions);
                for (var i = 0; i < quantvals; i++)
                {
                    var val_bits = value_length + 1;

                    var val = r_bits(val_bits);
                    w_bits(val_bits, val);
                }
            }
            else if (2 == lookup_type)
            {
                throw new System.Exception("Wwise Vorbis: didn't expect lookup type 2\n");
            }
            else
            {
                throw new System.Exception("Wwise Vorbis: invalid lookup type\n");
            }


            /* check that we used exactly all bytes */
            /* note: if all bits are used in the last byte there will be one extra 0 byte */
            //if (0 != cb_size && iw->b_off / 8 + 1 != cb_size)
            //{
            //VGM_LOG("Wwise Vorbis: codebook size mistach (expected 0x%x, wrote 0x%lx)\n", cb_size, iw->b_off/8+1);
            //}
        }