/*
***********************************************************************
* COPYRIGHT AND WARRANTY INFORMATION
*
* Copyright 2004,  Audio Video Coding Standard, Part III
*
* This software module was originally developed by
*
* JungHoe Kim (kjh94@samsung.com), Samsung AIT
*
* edited by
*
* Lei Miao (win.miaolei@samsung.com), Samsung AIT
* Lei Miao, CBC Multi-channel extension, 2005-09-19
* Lei Miao, CBC codebook reduction, 2005-12-22
*
* DISCLAIMER OF WARRANTY
*
* These software programs are available to the users without any
* license fee or royalty on an "as is" basis. The AVS disclaims
* any and all warranties, whether express, implied, or statutory,
* including any implied warranties of merchantability or of fitness
* for a particular purpose. In no event shall the contributors or 
* the AVS be liable for any incidental, punitive, or consequential
* damages of any kind whatsoever arising from the use of this program.
*
* This disclaimer of warranty extends to the user of this program
* and user's customers, employees, agents, transferees, successors,
* and assigns.
*
* The AVS does not represent or warrant that the program furnished
* hereunder are free of infringement of any third-party patents.
* Commercial implementations of AVS, including shareware, may be
* subject to royalty fees to patent holders. Information regarding
* the AVS patent policy is available from the AVS Web site at
* http://www.avs.org.cn
*
* THIS IS NOT A GRANT OF PATENT RIGHTS - SEE THE AVS PATENT POLICY.
************************************************************************
*/

#include "stdlib.h"
#include "stdio.h"
#include <memory.h>
#include <math.h>

/* codebook reduction */
unsigned int codeBook[36][7][16] = {
{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}},
{{1, 0, 6, 22, 7, 20, 21, 36, 1, 47, 19, 187, 8, 92, 37, 186}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}},
{{5, 15, 9, 8, 13, 3, 7, 29, 0, 5, 4, 28, 6, 25, 2, 24}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}},
{{1, 2, 6, 5, 7, 28, 15, 19, 0, 16, 29, 75, 6, 36, 17, 74}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}},
{{1, 6, 2, 9, 3, 23, 31, 17, 0, 29, 28, 16, 10, 61, 22, 60}, {1, 24, 0, 28, 13, 59, 15, 19, 8, 116, 11, 36, 25, 117, 10, 37}, {4, 3, 59, 6, 2, 6, 4, 28, 11, 10, 14, 58, 15, 0, 15, 5}, {6, 14, 1, 10, 0, 8, 4, 19, 15, 7, 5, 22, 6, 47, 18, 46}, {4, 11, 2, 14, 61, 14, 4, 60, 3, 10, 6, 0, 6, 15, 31, 5}, {1, 4, 15, 26, 14, 27, 10, 22, 1, 24, 1, 1, 25, 47, 0, 46}, {1, 8, 13, 25, 0, 10, 15, 11, 24, 117, 59, 116, 28, 36, 19, 37}},
{{1, 7, 5, 5, 6, 17, 4, 39, 0, 16, 18, 31, 6, 38, 14, 30}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}},
{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {12, 36, 15, 17, 14, 16, 5, 23, 13, 37, 4, 22, 3, 19, 0, 10}, {10, 0, 244, 121, 14, 6, 120, 125, 11, 1, 245, 123, 4, 1, 124, 63}, {2, 1, 0, 12, 14, 8, 6, 55, 15, 11, 9, 15, 10, 26, 14, 54}, {10, 11, 14, 4, 244, 245, 121, 123, 2, 3, 6, 0, 120, 126, 127, 62}, {6, 5, 1, 29, 2, 31, 30, 18, 3, 0, 8, 39, 28, 2, 3, 38}, {12, 13, 14, 3, 15, 4, 5, 0, 36, 37, 16, 19, 17, 22, 23, 10}},
{{1, 0, 7, 26, 1, 110, 24, 222, 2, 446, 108, 894, 25, 1790, 109, 1791}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}},
{{1, 0, 5, 14, 6, 61, 31, 39, 1, 36, 60, 76, 8, 154, 37, 155}, {0, 14, 2, 12, 27, 124, 30, 52, 126, 854, 127, 426, 107, 855, 125, 212}, {2, 7, 1, 26, 3, 2, 7, 24, 0, 55, 12, 109, 2, 25, 13, 108}, {2, 14, 3, 30, 0, 26, 4, 62, 1, 63, 27, 103, 5, 50, 24, 102}, {1, 0, 5, 9, 1, 110, 25, 111, 7, 16, 1, 17, 26, 109, 24, 108}, {1, 15, 4, 25, 1, 0, 10, 47, 14, 2, 24, 6, 13, 46, 22, 7}, {0, 47, 9, 35, 7, 46, 10, 45, 13, 138, 44, 136, 12, 139, 16, 137}},
{{0, 12, 9, 26, 10, 16, 22, 61, 14, 63, 17, 60, 27, 47, 62, 46}, {5, 4, 6, 3, 14, 30, 0, 2, 7, 62, 8, 63, 5, 13, 9, 12}, {0, 2, 17, 16, 1, 3, 20, 24, 13, 11, 18, 19, 14, 15, 25, 21}, {2, 13, 14, 7, 12, 9, 3, 23, 15, 8, 6, 1, 10, 2, 0, 22}, {1, 12, 2, 14, 17, 18, 16, 21, 3, 13, 0, 15, 20, 23, 22, 19}, {5, 15, 13, 7, 14, 4, 8, 2, 0, 3, 6, 19, 5, 25, 24, 18}, {6, 7, 14, 4, 5, 8, 15, 9, 1, 1, 2, 13, 5, 0, 3, 12}},
{{1, 7, 5, 2, 6, 17, 1, 37, 1, 16, 19, 3, 3, 36, 0, 2}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}},
{{2, 14, 5, 3, 6, 27, 2, 24, 0, 31, 30, 14, 4, 15, 26, 25}, {6, 44, 4, 45, 0, 42, 2, 46, 14, 40, 1, 43, 15, 41, 3, 47}, {2, 3, 78, 35, 0, 5, 34, 38, 14, 15, 79, 36, 1, 6, 37, 16}, {3, 14, 0, 11, 15, 5, 4, 18, 1, 12, 8, 19, 10, 26, 55, 54}, {2, 14, 0, 1, 79, 78, 34, 37, 3, 15, 5, 6, 35, 36, 38, 16}, {6, 4, 15, 28, 1, 29, 1, 21, 3, 5, 4, 47, 0, 20, 22, 46}, {6, 11, 0, 14, 4, 1, 2, 3, 60, 40, 42, 41, 61, 43, 63, 62}},
{{22, 1, 0, 6, 23, 5, 4, 15, 2, 7, 3, 13, 10, 12, 14, 4}, {31, 0, 11, 3, 8, 1, 3, 29, 9, 2, 2, 28, 1, 30, 6, 10}, {27, 10, 0, 3, 11, 3, 2, 26, 9, 1, 1, 24, 2, 7, 25, 8}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {27, 8, 10, 2, 0, 2, 1, 26, 11, 1, 3, 7, 3, 25, 24, 9}, {2, 15, 13, 6, 12, 9, 7, 1, 14, 10, 8, 23, 3, 0, 2, 22}, {31, 10, 8, 0, 11, 2, 3, 6, 4, 5, 6, 30, 7, 28, 29, 9}},
{{1, 2, 7, 25, 0, 97, 26, 193, 1, 385, 99, 1537, 27, 1536, 98, 769}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}},
{{1, 3, 2, 7, 1, 15, 0, 6, 2, 28, 5, 58, 6, 118, 4, 119}, {1, 2, 0, 6, 29, 112, 15, 115, 226, 1817, 228, 909, 459, 1816, 458, 455}, {3, 0, 11, 5, 4, 6, 4, 40, 14, 122, 31, 246, 21, 60, 41, 247}, {2, 15, 2, 0, 3, 3, 12, 5, 1, 19, 27, 17, 14, 16, 26, 18}, {2, 12, 6, 13, 2, 123, 15, 60, 0, 491, 14, 244, 31, 980, 14, 981}, {0, 17, 5, 16, 7, 14, 6, 15, 9, 37, 8, 36, 5, 39, 6, 38}, {1, 251, 30, 249, 0, 500, 14, 248, 2, 2005, 127, 2007, 6, 2004, 126, 2006}},
{{1, 0, 4, 11, 6, 62, 29, 57, 1, 123, 63, 122, 10, 113, 60, 112}, {1, 5, 7, 0, 13, 2, 9, 3, 17, 33, 51, 49, 32, 97, 50, 96}, {7, 4, 0, 7, 1, 11, 4, 24, 10, 11, 27, 52, 6, 53, 25, 10}, {6, 14, 1, 5, 0, 8, 10, 22, 15, 23, 7, 9, 6, 18, 19, 8}, {7, 10, 13, 3, 12, 23, 4, 14, 4, 2, 0, 22, 6, 11, 15, 10}, {2, 3, 15, 21, 14, 2, 11, 24, 0, 8, 3, 25, 9, 26, 27, 20}, {1, 17, 9, 6, 7, 52, 12, 7, 5, 33, 2, 106, 0, 107, 27, 32}},
{{1, 5, 2, 8, 3, 1, 3, 26, 7, 27, 0, 5, 12, 18, 19, 4}, {0, 11, 4, 5, 12, 4, 14, 7, 27, 52, 30, 53, 31, 21, 6, 20}, {1, 3, 16, 20, 2, 14, 30, 21, 12, 9, 17, 26, 0, 11, 31, 27}, {3, 13, 12, 10, 11, 8, 3, 0, 15, 5, 4, 2, 9, 29, 1, 28}, {2, 10, 1, 0, 17, 16, 28, 24, 3, 11, 13, 15, 19, 18, 25, 29}, {4, 12, 13, 6, 15, 11, 4, 3, 14, 2, 5, 21, 7, 0, 1, 20}, {0, 30, 9, 6, 5, 8, 13, 4, 12, 56, 31, 10, 7, 57, 29, 11}},
{{1, 0, 6, 22, 7, 18, 21, 95, 1, 46, 19, 83, 8, 94, 40, 82}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}},
{{0, 13, 9, 24, 10, 63, 22, 61, 14, 17, 16, 47, 25, 60, 62, 46}, {1, 2, 6, 28, 15, 58, 0, 59, 11, 13, 9, 15, 8, 12, 10, 14}, {7, 4, 6, 5, 3, 2, 4, 7, 12, 11, 40, 41, 13, 0, 42, 43}, {6, 15, 0, 9, 1, 4, 5, 47, 14, 6, 7, 22, 8, 21, 20, 46}, {7, 12, 2, 13, 5, 40, 4, 41, 4, 11, 3, 0, 6, 42, 7, 43}, {6, 3, 2, 29, 15, 8, 0, 22, 1, 28, 1, 21, 9, 20, 47, 46}, {1, 11, 15, 3, 6, 10, 0, 9, 2, 33, 58, 32, 28, 34, 59, 35}},
{{1, 11, 10, 3, 9, 28, 0, 30, 12, 1, 29, 26, 8, 27, 31, 2}, {14, 17, 1, 23, 10, 18, 2, 0, 12, 16, 15, 19, 13, 22, 3, 1}, {10, 14, 12, 14, 13, 2, 15, 30, 12, 0, 13, 23, 1, 4, 22, 31}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {10, 11, 13, 0, 12, 13, 14, 24, 14, 1, 2, 4, 15, 25, 30, 31}, {2, 0, 12, 8, 15, 7, 9, 29, 13, 3, 10, 23, 6, 28, 2, 22}, {2, 9, 12, 13, 1, 14, 0, 3, 20, 16, 17, 21, 23, 22, 30, 31}},
{{28, 4, 29, 10, 0, 6, 7, 13, 1, 9, 5, 11, 8, 12, 15, 1}, {2, 22, 10, 23, 8, 26, 0, 3, 9, 27, 15, 4, 14, 5, 3, 12}, {2, 10, 24, 27, 8, 0, 26, 4, 9, 15, 25, 3, 14, 3, 5, 11}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {2, 8, 9, 14, 24, 27, 25, 4, 10, 15, 0, 3, 26, 5, 3, 11}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {2, 9, 8, 14, 10, 13, 0, 3, 24, 30, 31, 4, 25, 3, 5, 11}},
{{6, 11, 6, 5, 9, 30, 0, 7, 14, 31, 1, 3, 2, 4, 8, 10}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}},
{{2, 7, 5, 3, 6, 26, 1, 31, 12, 30, 28, 29, 4, 27, 0, 2}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}},
{{0, 11, 31, 27, 8, 19, 26, 61, 12, 20, 21, 60, 28, 59, 18, 58}, {3, 5, 1, 4, 13, 0, 14, 1, 9, 24, 10, 30, 8, 25, 11, 31}, {3, 2, 0, 1, 15, 13, 29, 2, 8, 9, 22, 23, 10, 12, 28, 3}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {3, 8, 13, 10, 31, 22, 1, 30, 2, 9, 14, 12, 0, 23, 3, 2}, {0, 11, 13, 7, 12, 9, 10, 4, 14, 5, 6, 2, 8, 31, 3, 30}, {3, 10, 13, 8, 1, 9, 14, 11, 5, 24, 0, 25, 4, 30, 1, 31}},
{{1, 6, 3, 9, 2, 23, 3, 17, 7, 0, 1, 16, 10, 5, 22, 4}, {0, 9, 5, 6, 14, 25, 13, 24, 8, 11, 7, 61, 31, 60, 4, 10}, {6, 2, 1, 0, 1, 15, 29, 28, 11, 9, 15, 13, 10, 8, 14, 12}, {4, 13, 14, 5, 15, 4, 10, 1, 12, 3, 7, 0, 6, 23, 2, 22}, {6, 11, 1, 10, 31, 11, 28, 9, 3, 8, 0, 9, 30, 8, 29, 10}, {2, 11, 13, 6, 15, 7, 10, 2, 12, 3, 8, 29, 9, 1, 0, 28}, {1, 10, 14, 30, 4, 3, 13, 0, 11, 2, 24, 63, 2, 3, 25, 62}},
{{1, 7, 5, 6, 6, 17, 4, 39, 0, 16, 18, 38, 7, 23, 10, 22}, {2, 0, 6, 3, 7, 13, 5, 12, 4, 63, 2, 62, 30, 58, 28, 59}, {0, 4, 6, 28, 2, 13, 23, 22, 12, 7, 63, 61, 10, 29, 62, 60}, {5, 12, 14, 6, 15, 4, 8, 2, 0, 3, 5, 19, 7, 26, 27, 18}, {0, 9, 2, 8, 7, 13, 25, 12, 5, 31, 13, 30, 29, 57, 24, 56}, {4, 12, 14, 4, 15, 5, 10, 1, 11, 3, 7, 27, 6, 0, 2, 26}, {2, 3, 7, 0, 6, 2, 5, 29, 15, 3, 13, 57, 4, 2, 12, 56}},
{{1, 0, 5, 30, 6, 18, 29, 39, 1, 62, 63, 38, 8, 115, 56, 114}, {3, 0, 4, 3, 10, 14, 6, 8, 5, 47, 2, 46, 22, 31, 9, 30}, {1, 5, 8, 30, 1, 14, 25, 24, 9, 31, 3, 55, 0, 26, 2, 54}, {6, 11, 1, 7, 0, 4, 6, 20, 14, 31, 5, 21, 8, 19, 30, 18}, {1, 9, 1, 1, 8, 63, 25, 62, 5, 0, 14, 26, 30, 55, 24, 54}, {4, 12, 14, 5, 15, 10, 7, 0, 13, 3, 6, 1, 4, 23, 2, 22}, {3, 4, 8, 18, 5, 2, 3, 11, 0, 39, 14, 30, 6, 31, 10, 38}},
{{1, 0, 6, 23, 7, 45, 21, 40, 1, 44, 17, 67, 9, 32, 41, 66}, {3, 1, 5, 6, 9, 11, 8, 8, 1, 1, 15, 0, 14, 19, 10, 18}, {2, 3, 12, 26, 2, 15, 29, 5, 3, 28, 3, 55, 0, 4, 2, 54}, {6, 0, 15, 8, 1, 7, 4, 21, 11, 29, 5, 19, 6, 20, 28, 18}, {1, 12, 1, 1, 8, 1, 18, 53, 5, 29, 15, 27, 28, 52, 19, 0}, {5, 12, 1, 5, 0, 7, 6, 30, 13, 31, 4, 28, 8, 19, 29, 18}, {3, 1, 9, 15, 5, 0, 8, 5, 2, 27, 14, 8, 3, 9, 12, 26}},
{{1, 0, 6, 15, 7, 27, 14, 17, 2, 25, 9, 49, 5, 16, 26, 48}, {0, 4, 5, 27, 31, 24, 26, 50, 28, 122, 59, 123, 60, 102, 58, 103}, {2, 3, 3, 31, 2, 14, 24, 61, 13, 1, 60, 11, 0, 25, 4, 10}, {7, 13, 11, 7, 0, 6, 8, 19, 2, 2, 3, 18, 10, 51, 24, 50}, {2, 7, 1, 1, 4, 59, 12, 22, 6, 0, 15, 10, 28, 23, 13, 58}, {5, 12, 4, 1, 1, 7, 13, 12, 15, 5, 1, 13, 4, 28, 29, 0}, {0, 21, 30, 47, 6, 59, 28, 46, 4, 41, 58, 88, 31, 40, 45, 89}},
{{1, 2, 6, 6, 7, 11, 7, 9, 1, 10, 0, 17, 1, 2, 3, 16}, {0, 2, 15, 24, 26, 109, 58, 119, 28, 205, 118, 204, 55, 108, 50, 103}, {3, 3, 2, 36, 2, 5, 3, 0, 8, 19, 297, 296, 3, 2, 149, 75}, {1, 8, 15, 26, 5, 29, 12, 28, 1, 55, 0, 54, 9, 2, 7, 6}, {2, 27, 1, 13, 0, 16, 12, 35, 7, 53, 12, 9, 7, 34, 5, 52}, {2, 0, 15, 3, 6, 14, 1, 2, 1, 29, 28, 31, 2, 13, 12, 30}, {0, 58, 28, 236, 6, 22, 10, 119, 4, 377, 95, 376, 15, 237, 46, 189}},
{{1, 0, 6, 60, 1, 123, 29, 245, 2, 114, 115, 977, 31, 489, 56, 976}, {1, 10, 1, 23, 6, 22, 1, 0, 3, 2, 29, 28, 31, 30, 9, 8}, {0, 4, 58, 119, 6, 15, 118, 45, 44, 47, 46, 41, 28, 40, 43, 42}, {2, 29, 1, 28, 31, 30, 25, 24, 27, 26, 5, 4, 7, 6, 1, 0}, {0, 48, 15, 51, 28, 99, 98, 105, 2, 104, 27, 107, 29, 106, 101, 100}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {1, 9, 3, 8, 3, 11, 1, 10, 0, 21, 20, 23, 9, 22, 17, 16}},
{{1, 0, 3, 20, 3, 17, 16, 42, 2, 87, 86, 37, 11, 36, 39, 38}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {2, 12, 27, 26, 5, 4, 7, 6, 1, 0, 3, 2, 29, 28, 31, 30}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {6, 14, 31, 30, 9, 8, 11, 10, 5, 4, 7, 6, 1, 0, 3, 2}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {6, 14, 31, 30, 9, 8, 11, 10, 5, 4, 7, 6, 1, 0, 3, 2}},
{{1, 1, 3, 0, 2, 3, 2, 21, 3, 20, 23, 22, 17, 16, 19, 18}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}},
{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}},
{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}},
{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}}
};
unsigned int codeBookLen[36][7][16] = {
{{4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}},
{{1, 3, 4, 6, 4, 6, 6, 7, 3, 7, 6, 9, 5, 8, 7, 9}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}},
{{3, 4, 4, 4, 4, 4, 4, 5, 3, 4, 4, 5, 4, 5, 4, 5}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}},
{{1, 3, 4, 5, 4, 7, 6, 7, 3, 7, 7, 9, 5, 8, 7, 9}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}},
{{1, 4, 4, 5, 4, 6, 6, 6, 3, 6, 6, 6, 5, 7, 6, 7}, {2, 5, 2, 5, 4, 6, 4, 5, 4, 7, 4, 6, 5, 7, 4, 6}, {3, 3, 6, 5, 3, 3, 5, 5, 4, 4, 6, 6, 4, 3, 6, 5}, {3, 4, 3, 4, 3, 4, 4, 5, 4, 4, 4, 5, 4, 6, 5, 6}, {3, 4, 3, 4, 6, 6, 5, 6, 3, 4, 3, 3, 5, 6, 5, 5}, {2, 3, 4, 5, 4, 5, 4, 5, 3, 5, 4, 5, 5, 6, 5, 6}, {2, 4, 4, 5, 2, 4, 4, 4, 5, 7, 6, 7, 5, 6, 5, 6}},
{{1, 4, 4, 5, 4, 6, 5, 7, 3, 6, 6, 7, 5, 7, 6, 7}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}},
{{4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 7, 4, 6, 4, 6, 3, 6, 4, 7, 3, 6, 3, 6, 2, 5}, {4, 3, 8, 7, 4, 3, 7, 7, 4, 3, 8, 7, 3, 2, 7, 6}, {3, 3, 3, 4, 4, 4, 4, 6, 4, 4, 4, 5, 4, 5, 5, 6}, {4, 4, 4, 3, 8, 8, 7, 7, 3, 3, 3, 2, 7, 7, 7, 6}, {3, 3, 3, 5, 3, 5, 5, 5, 3, 4, 4, 6, 5, 5, 5, 6}, {4, 4, 4, 3, 4, 3, 3, 2, 7, 7, 6, 6, 6, 6, 6, 5}},
{{1, 3, 4, 6, 3, 8, 6, 9, 3, 10, 8, 11, 6, 12, 8, 12}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}},
{{1, 3, 4, 5, 4, 7, 6, 7, 3, 7, 7, 8, 5, 9, 7, 9}, {1, 4, 2, 4, 5, 7, 5, 6, 7, 10, 7, 9, 7, 10, 7, 8}, {2, 3, 4, 5, 3, 3, 5, 5, 4, 6, 6, 7, 4, 5, 6, 7}, {2, 4, 3, 5, 3, 5, 4, 6, 3, 6, 5, 7, 4, 6, 5, 7}, {2, 4, 3, 4, 4, 7, 5, 7, 3, 5, 3, 5, 5, 7, 5, 7}, {2, 4, 3, 5, 3, 4, 4, 6, 4, 5, 5, 6, 4, 6, 5, 6}, {1, 6, 4, 6, 3, 6, 4, 6, 4, 8, 6, 8, 4, 8, 5, 8}},
{{1, 4, 4, 5, 4, 5, 5, 6, 4, 6, 5, 6, 5, 6, 6, 6}, {3, 4, 3, 4, 4, 5, 3, 4, 4, 6, 4, 6, 4, 5, 4, 5}, {3, 3, 5, 5, 3, 3, 5, 5, 4, 4, 5, 5, 4, 4, 5, 5}, {3, 4, 4, 4, 4, 4, 4, 5, 4, 4, 4, 4, 4, 4, 4, 5}, {3, 4, 3, 4, 5, 5, 5, 5, 3, 4, 3, 4, 5, 5, 5, 5}, {3, 4, 4, 4, 4, 4, 4, 4, 3, 4, 4, 5, 4, 5, 5, 5}, {3, 4, 4, 4, 3, 4, 4, 4, 4, 5, 4, 5, 4, 5, 4, 5}},
{{1, 4, 4, 5, 4, 6, 5, 7, 3, 6, 6, 7, 5, 7, 6, 7}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}},
{{2, 4, 4, 4, 4, 5, 4, 5, 3, 5, 5, 5, 4, 5, 5, 5}, {3, 6, 3, 6, 3, 6, 3, 6, 4, 6, 3, 6, 4, 6, 3, 6}, {3, 3, 7, 6, 3, 3, 6, 6, 4, 4, 7, 6, 3, 3, 6, 5}, {3, 4, 3, 4, 4, 4, 4, 5, 3, 4, 4, 5, 4, 5, 6, 6}, {3, 4, 3, 3, 7, 7, 6, 6, 3, 4, 3, 3, 6, 6, 6, 5}, {3, 3, 4, 5, 3, 5, 4, 5, 3, 4, 4, 6, 4, 5, 5, 6}, {3, 4, 3, 4, 3, 3, 3, 3, 6, 6, 6, 6, 6, 6, 6, 6}},
{{5, 4, 4, 4, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3}, {5, 5, 4, 5, 4, 5, 3, 5, 4, 5, 3, 5, 3, 5, 3, 4}, {5, 4, 5, 5, 4, 3, 5, 5, 4, 3, 5, 5, 3, 3, 5, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {5, 4, 4, 3, 5, 5, 5, 5, 4, 3, 3, 3, 5, 5, 5, 4}, {3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 4, 4, 4, 5}, {5, 4, 4, 3, 4, 3, 3, 3, 5, 5, 5, 5, 5, 5, 5, 4}},
{{1, 3, 4, 6, 3, 8, 6, 9, 3, 10, 8, 12, 6, 12, 8, 11}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}},
{{1, 3, 4, 5, 4, 8, 5, 7, 3, 9, 7, 10, 5, 11, 7, 11}, {1, 3, 2, 4, 6, 8, 5, 8, 9, 12, 9, 11, 10, 12, 10, 10}, {2, 2, 4, 4, 3, 4, 4, 6, 5, 8, 6, 9, 5, 7, 6, 9}, {2, 4, 3, 4, 3, 5, 4, 6, 3, 8, 5, 8, 4, 8, 5, 8}, {2, 5, 3, 5, 3, 7, 5, 6, 2, 9, 4, 8, 5, 10, 5, 10}, {2, 6, 3, 6, 3, 5, 3, 5, 4, 7, 4, 7, 4, 7, 4, 7}, {1, 9, 6, 9, 2, 10, 5, 9, 3, 12, 8, 12, 4, 12, 8, 12}},
{{1, 3, 4, 5, 4, 7, 6, 7, 3, 8, 7, 8, 5, 8, 7, 8}, {2, 3, 3, 3, 4, 4, 4, 4, 5, 6, 6, 6, 6, 7, 6, 7}, {3, 3, 3, 4, 3, 4, 4, 5, 4, 5, 5, 6, 4, 6, 5, 5}, {3, 4, 3, 4, 3, 4, 4, 5, 4, 5, 4, 5, 4, 5, 5, 5}, {3, 4, 4, 4, 4, 5, 4, 5, 3, 4, 3, 5, 4, 5, 5, 5}, {3, 3, 4, 5, 4, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 5}, {2, 5, 4, 5, 3, 6, 4, 5, 3, 6, 4, 7, 3, 7, 5, 6}},
{{1, 4, 4, 5, 4, 5, 5, 6, 4, 6, 5, 6, 5, 6, 6, 6}, {2, 4, 3, 4, 4, 4, 4, 4, 5, 6, 5, 6, 5, 5, 4, 5}, {3, 3, 5, 5, 3, 4, 5, 5, 4, 4, 5, 5, 3, 4, 5, 5}, {3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 4, 5}, {3, 4, 3, 3, 5, 5, 5, 5, 3, 4, 4, 4, 5, 5, 5, 5}, {3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 4, 4, 4, 5}, {2, 5, 4, 4, 3, 4, 4, 4, 4, 6, 5, 5, 4, 6, 5, 5}},
{{1, 3, 4, 6, 4, 6, 6, 8, 3, 7, 6, 8, 5, 8, 7, 8}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}},
{{1, 4, 4, 5, 4, 6, 5, 6, 4, 5, 5, 6, 5, 6, 6, 6}, {2, 4, 3, 5, 4, 6, 3, 6, 4, 6, 4, 6, 4, 6, 4, 6}, {3, 3, 5, 5, 3, 3, 5, 5, 4, 4, 6, 6, 4, 3, 6, 6}, {3, 4, 3, 4, 3, 4, 4, 6, 4, 4, 4, 5, 4, 5, 5, 6}, {3, 4, 3, 4, 5, 6, 5, 6, 3, 4, 3, 3, 5, 6, 5, 6}, {3, 3, 3, 5, 4, 4, 4, 5, 3, 5, 4, 5, 4, 5, 6, 6}, {2, 4, 4, 4, 3, 4, 3, 4, 4, 6, 6, 6, 5, 6, 6, 6}},
{{2, 4, 4, 4, 4, 5, 4, 5, 4, 4, 5, 5, 4, 5, 5, 4}, {4, 5, 3, 5, 4, 5, 3, 4, 4, 5, 4, 5, 4, 5, 3, 4}, {4, 4, 5, 5, 4, 3, 5, 5, 4, 3, 5, 5, 3, 3, 5, 5}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 3, 5, 5, 5, 5, 4, 3, 3, 3, 5, 5, 5, 5}, {3, 3, 4, 4, 4, 4, 4, 5, 4, 4, 4, 5, 4, 5, 4, 5}, {3, 4, 4, 4, 3, 4, 3, 3, 5, 5, 5, 5, 5, 5, 5, 5}},
{{5, 4, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3}, {4, 5, 4, 5, 4, 5, 3, 4, 4, 5, 4, 4, 4, 4, 3, 4}, {4, 4, 5, 5, 4, 3, 5, 4, 4, 4, 5, 4, 4, 3, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 5, 5, 5, 4, 4, 4, 3, 3, 5, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 3, 3, 5, 5, 5, 4, 5, 4, 4, 4}},
{{3, 4, 4, 4, 4, 5, 4, 4, 4, 5, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}},
{{2, 4, 4, 4, 4, 5, 4, 5, 4, 5, 5, 5, 4, 5, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}},
{{1, 4, 5, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 5, 6}, {3, 4, 3, 4, 4, 4, 4, 4, 4, 5, 4, 5, 4, 5, 4, 5}, {3, 3, 4, 4, 4, 4, 5, 4, 4, 4, 5, 5, 4, 4, 5, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {3, 4, 4, 4, 5, 5, 4, 5, 3, 4, 4, 4, 4, 5, 4, 4}, {3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 4, 5}, {3, 4, 4, 4, 3, 4, 4, 4, 4, 5, 4, 5, 4, 5, 4, 5}},
{{1, 4, 4, 5, 4, 6, 5, 6, 4, 5, 5, 6, 5, 6, 6, 6}, {2, 4, 3, 4, 4, 5, 4, 5, 4, 5, 4, 6, 5, 6, 4, 5}, {3, 3, 4, 4, 3, 4, 5, 5, 4, 4, 5, 5, 4, 4, 5, 5}, {3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 4, 5}, {3, 4, 3, 4, 5, 5, 5, 5, 3, 4, 3, 4, 5, 5, 5, 5}, {3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 4, 4, 4, 5}, {2, 4, 4, 5, 3, 4, 4, 4, 4, 5, 5, 6, 4, 5, 5, 6}},
{{1, 4, 4, 5, 4, 6, 5, 7, 3, 6, 6, 7, 5, 7, 6, 7}, {2, 3, 3, 4, 4, 5, 4, 5, 4, 6, 4, 6, 5, 6, 5, 6}, {2, 3, 4, 5, 3, 4, 5, 5, 4, 4, 6, 6, 4, 5, 6, 6}, {3, 4, 4, 4, 4, 4, 4, 4, 3, 4, 4, 5, 4, 5, 5, 5}, {2, 4, 3, 4, 4, 5, 5, 5, 3, 5, 4, 5, 5, 6, 5, 6}, {3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 4, 4, 4, 5}, {2, 4, 4, 4, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6}},
{{1, 3, 4, 6, 4, 6, 6, 7, 3, 7, 7, 7, 5, 8, 7, 8}, {2, 3, 3, 4, 4, 5, 4, 5, 4, 6, 4, 6, 5, 6, 5, 6}, {2, 3, 4, 5, 3, 4, 5, 5, 4, 5, 5, 6, 4, 5, 5, 6}, {3, 4, 3, 4, 3, 4, 4, 5, 4, 5, 4, 5, 4, 5, 5, 5}, {2, 4, 3, 4, 4, 6, 5, 6, 3, 4, 4, 5, 5, 6, 5, 6}, {3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 4, 5}, {2, 4, 4, 5, 3, 4, 4, 5, 3, 6, 5, 6, 4, 6, 5, 6}},
{{1, 3, 4, 6, 4, 7, 6, 7, 3, 7, 6, 8, 5, 7, 7, 8}, {2, 3, 3, 4, 4, 5, 4, 5, 4, 5, 5, 5, 5, 6, 5, 6}, {2, 3, 4, 5, 3, 4, 5, 5, 4, 5, 5, 6, 4, 5, 5, 6}, {3, 3, 4, 4, 3, 4, 4, 5, 4, 5, 4, 5, 4, 5, 5, 5}, {2, 4, 3, 4, 4, 5, 5, 6, 3, 5, 4, 5, 5, 6, 5, 5}, {3, 4, 3, 4, 3, 4, 4, 5, 4, 5, 4, 5, 4, 5, 5, 5}, {2, 4, 4, 5, 3, 4, 4, 5, 3, 6, 5, 6, 4, 6, 5, 6}},
{{1, 3, 4, 6, 4, 7, 6, 7, 3, 7, 6, 8, 5, 7, 7, 8}, {1, 3, 3, 5, 5, 5, 5, 6, 5, 7, 6, 7, 6, 7, 6, 7}, {2, 3, 4, 5, 3, 4, 5, 6, 4, 4, 6, 6, 4, 5, 5, 6}, {3, 4, 4, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 6, 5, 6}, {2, 4, 3, 4, 4, 6, 5, 6, 3, 4, 4, 5, 5, 6, 5, 6}, {3, 4, 3, 4, 3, 4, 4, 5, 4, 4, 5, 5, 4, 5, 5, 5}, {1, 5, 5, 6, 3, 6, 5, 6, 3, 6, 6, 7, 5, 6, 6, 7}},
{{1, 3, 4, 6, 4, 7, 6, 7, 3, 7, 6, 8, 5, 7, 7, 8}, {1, 2, 4, 5, 5, 7, 6, 7, 5, 8, 7, 8, 6, 7, 6, 7}, {2, 3, 4, 6, 3, 3, 5, 4, 4, 5, 9, 9, 4, 5, 8, 7}, {2, 4, 4, 5, 3, 5, 4, 5, 3, 6, 4, 6, 4, 5, 6, 6}, {2, 5, 3, 5, 3, 6, 5, 7, 3, 6, 4, 5, 4, 7, 4, 6}, {2, 5, 4, 6, 3, 4, 4, 6, 3, 6, 6, 6, 3, 5, 5, 6}, {1, 6, 5, 8, 3, 5, 4, 7, 3, 9, 7, 9, 4, 8, 6, 8}},
{{1, 3, 4, 7, 3, 8, 6, 9, 3, 8, 8, 11, 6, 10, 7, 11}, {1, 5, 3, 6, 4, 6, 5, 5, 5, 5, 6, 6, 6, 6, 5, 5}, {1, 3, 6, 7, 3, 4, 7, 6, 6, 6, 6, 6, 5, 6, 6, 6}, {2, 5, 3, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4}, {1, 6, 4, 6, 5, 7, 7, 7, 2, 7, 5, 7, 5, 7, 7, 7}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {1, 6, 4, 6, 3, 6, 4, 6, 4, 6, 6, 6, 5, 6, 6, 6}},
{{1, 3, 4, 7, 3, 7, 7, 8, 3, 9, 9, 8, 6, 8, 8, 8}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {2, 4, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {3, 4, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {3, 4, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}},
{{1, 5, 3, 5, 4, 5, 5, 6, 4, 6, 6, 6, 6, 6, 6, 6}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}},
{{4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}},
{{4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}},
{{4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}}
};

#define SI_NUM (30+1)
unsigned int codeBookSi[SI_NUM] = {
	103653, 51827, 12957, 808, 504, 246, 121, 120, 203, 122, 247, 51, 127, 14, 13,
		0, 4, 5, 24, 62, 100, 253, 405, 1011, 1010, 1618, 3238, 6479, 25912, 207305, 207304};
unsigned int codeBookLenSi[SI_NUM] = {
	17, 16, 14, 10, 9, 8, 7, 7, 8, 7, 8, 6, 7, 4, 4, 1, 3, 3, 5, 6, 7, 8, 9, 10, 10, 11, 12, 13, 15, 18, 18};

#define SF_NUM 128
unsigned int codeBookSf[SF_NUM] = {
	61533, 61532, 61535, 61534, 61529, 61528, 61531, 61530, 153365, 153364, 153367, 153366, 153361, 153360, 153363, 153362,
	153373, 153372, 153375, 153374, 153369, 153368, 153371, 153370, 15381, 15380, 19173, 19172, 4935, 9590, 4934, 2466,
	2310, 960, 4794, 1217, 1219, 1232, 2311, 481, 1185, 617, 1199, 241, 312, 309, 598, 89,
	153, 289, 33, 45, 79, 20, 31, 75, 14, 39, 8, 25, 8, 13, 3, 7,
	1, 5, 0, 5, 24, 6, 38, 18, 9, 73, 23, 17, 145, 61, 43, 32,
	297, 157, 155, 121, 88, 85, 597, 576, 313, 305, 169, 1192, 1186, 1193, 1187, 1184,
	168, 2309, 2308, 1218, 1216, 1923, 9591, 3844, 19175, 153349, 76697, 153348, 153351, 153350, 153345, 153344,
	153347, 153346, 153357, 153356, 153359, 153358, 153353, 153352, 153355, 153354, 153397, 153396, 153399, 153398, 153393, 153392};
unsigned int codeBookLenSf[SF_NUM] = {
	19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
	19, 19, 19, 19, 19, 19, 19, 19, 17, 17, 16, 16, 15, 15, 15, 14,
	13, 13, 14, 13, 13, 13, 13, 12, 12, 12, 12, 11, 11, 11, 11, 10,
	10, 10, 9, 9, 9, 8, 8, 8, 7, 7, 6, 6, 5, 5, 4, 4,
	1, 4, 4, 5, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9,
	10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 12,	12, 12, 12, 12,
	11, 13, 13, 13, 13, 14, 15, 15,	16, 19, 18, 19, 19, 19, 19, 19,
	19, 19, 19, 19,	19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19
};


//bs
int BitstreamOpen(FILE *fname);
void BitstreamClose(void);
void output_byte(long byte,int len);
void start_outputing_bits();
void done_outputing_bits();
void FlushBuffer(void);
void FlushBufferWithLength(void);
int GetBitstreamSize(void);
int ByteAlign(void);
//~bs
void BSHCInit(FILE *name);
void BSHCClose(void);
int EncodeBSHCQuant(int model,int upper,int cur);
int EncodeBSHCSi(int siVal);
int EncodeBSHCSf(int sfVal);
int EncodeBSHCBin(int ms);
void EncodeBSHCStart(void);
void EncodeBSHCEnd(void);
void EncodeBSHCPutBits(int val,int len);
int EncodeBSHCGetSize();
void EncodeBSHCHeader(int ch,int freq);
int EncodeBSHCByteAlign(void);
int BSHCModelSelect(int bshcModel,int bpl);
void EncodeBSHCFlush(void);
int WriteAASFHeader(int ch,int freq,int bitrate,int aasf_flag);		//for AASF



extern void FlushAASFHeaderBuffer();

extern void get_end_band (
						  int signal_type,
						  int num_window_groups,
						  int window_group_length[],
						  int maxSfb,
						  short	*swb_offset[],
						  int top_layer,
						  int base_maxSfb[],
						  int end_sfb[],
						  int end_freq[],
						  int end_cband[]
);

void BSHCInit(FILE *name)
{
	BitstreamOpen(name);
}
void BSHCClose(void)
{
	BitstreamClose();
}

void EncodeBSHCStart(void)
{
	start_outputing_bits();
}
void EncodeBSHCEnd(void)
{
	done_outputing_bits();
	
}
void EncodeBSHCFlush(void)
{
	FlushBufferWithLength();
}
void EncodeBSHCHeader(int ch,int freq)
{
	output_byte('A',8);
	output_byte('V',8);
	output_byte('S',8);
	output_byte('3',8);
	output_byte(ch,4);
	output_byte(freq,4);
    FlushBuffer();
}

/************************************************************************/
/*                          AASF header                                 */
/************************************************************************/
/* quick search element */
typedef struct{
	int				no_search_points;
	int				search_point_dcption_present;
	unsigned int	search_point_offset[128];
	int				search_dcption_size[128];
	unsigned char	search_point_dcption[128][64];
}Quick_search_element;

/* general info element */
typedef struct{
	unsigned char	Title[32];
	unsigned char	Artist[32];
	unsigned char	Album[32];
	unsigned char	Year[4];
	unsigned char	Genre;
	unsigned char	Comment[32];
	unsigned char	Composer[32];
	unsigned char	Encoded_by[32];
}General_info_element;    /* 197 bytes, fixed length */

/* lyrics element */
typedef struct{
	int				synchronised_id;
	unsigned char	text_coding;
	unsigned char	language[3];
	int				lyrics_size;
	char*			lyrics_text;
	int				timestamp_format;   /* 0 -- MPEG frames, 1 -- ms */
	int				lyrics_timestamp;
}Lyrics_element;

/* user defined text element */
typedef struct{
	unsigned char	text_coding;
	unsigned char	language[3];
	int				user_text_size;
	char*			user_define_text;
}User_text_element;

int WriteAASFHeader(int ch,int freq,int bitrate,int aasf_flag)
{
	int num_stream_element;
	int quick_searching_flag;
//	int drm_flag;	// wlei [20060320]
	int general_info_flag;
	int text_info_flag;
	
	int lyrics_present;
	int user_define_present;
	
	int bitstream_type = 1;
	
	int bitused = 0;
	int byteused;
	int i, j;
	
	Quick_search_element m_quick_search;
	General_info_element m_general_info;
	Lyrics_element		m_lyrics;
	User_text_element	m_user_text;	
	
	lyrics_present = 1;
	user_define_present = 1;
	//defaut only one stream
    num_stream_element = 1;
	
	/* write AVS AASF ID */
	output_byte('A',8);
	output_byte('A',8);
	output_byte('S',8);
	output_byte('F',8);
	bitused += 32;

	/* write AASF header size */
	output_byte(0, 24);
	bitused += 24;
	/* NUM_STREAM_ELEMENT */
	output_byte(num_stream_element,8);
	bitused += 8;
	

	for(i = 0; i < num_stream_element; i++)
	{	
		//aasf_flag = 0x40;    //0100 0000
		//aasf_flag = 0x80;   /* with quick search flag, 1000 0000 */
		//aasf_flag = 0xA0;   /* with general info flag, 1010 0000 */
		aasf_flag = 0x0;
		
		/* write AASF flag */
		output_byte(aasf_flag, 8);
		bitused += 8;
		
		/* get flag status */
		quick_searching_flag = (aasf_flag>>7)&0x1;
//		drm_flag = (aasf_flag>>6)&0x1;		// wlei [20060320]
		general_info_flag = (aasf_flag>>5)&0x1;
		text_info_flag = (aasf_flag>>4)&0x1;
		
		// wlei [20060223]
		/* raw stream length */
		output_byte(0, 32);
		bitused += 32;
		
		/* version */
		output_byte(0,2);
		
		/* coding profile */
		output_byte(0,2);
		
		/* sampling freq. index */
		//output_byte(freq+3,4);
		output_byte(freq, 4); 
		/* bitrate */
		output_byte(bitrate, 23);
		
		/* bitstream type */
		output_byte(bitstream_type, 1);
		bitused += 32;
		
		/* buffer fullness */
		if(bitstream_type == 0)
		{
			/* dull */
			output_byte(0, 20);
			bitused += 20;
		}
		
		/* channel config */
		if(ch <= 2)
			output_byte(ch-1, 2);
		else if(ch == 6)  /* 5.1 ch */
			output_byte(2, 2);
		else
			output_byte(3, 2);
		//	bitused += 4;	// wlei [20060223]
		bitused += 2;
		
		/* decoding information alignment */
		EncodeBSHCByteAlign();
		bitused = ((bitused+7)>>3)<<3;
		
		if(quick_searching_flag)
		{
			/* initialization */
			m_quick_search.no_search_points = 2;
			m_quick_search.search_point_dcption_present = 1;
			
			for(i = 0; i < m_quick_search.no_search_points; i++)
			{
				/* dummy value */
				m_quick_search.search_point_offset[i] = (i+1)*1024;
				m_quick_search.search_dcption_size[i] = 5;
				sprintf((char*)(m_quick_search.search_point_dcption[i]), "test");
			}
			
			/* write quick search info. */
			output_byte(m_quick_search.no_search_points, 7);
			output_byte(m_quick_search.search_point_dcption_present, 1);
			bitused += 8;
			
			for(i = 0; i < m_quick_search.no_search_points; i++)
			{
				output_byte(m_quick_search.search_point_offset[i], 32);
				bitused += 32;
				if(m_quick_search.search_point_dcption_present)
				{
					output_byte(m_quick_search.search_dcption_size[i], 8);
					for(j = 0; j < m_quick_search.search_dcption_size[i]; j ++)
					{
						output_byte(m_quick_search.search_point_dcption[i][j], 8);
						bitused += 8;
					}
				}
			}
			/* donot need byte alignment */
		}
		
		// wlei [20060320]
//		if(drm_flag)
//		{
//		}

		
		if(general_info_flag)
		{
			/* initialization */
			memcpy(m_general_info.Title, "NoName song", 12);
			memcpy(m_general_info.Artist, "NoName guy", 11);
			memcpy(m_general_info.Album, "NoName album", 13);
			memcpy(m_general_info.Year, "2005", 5);
			m_general_info.Genre = 0;
			memcpy(m_general_info.Comment, "comment", 8);
			memcpy(m_general_info.Composer, "NoName guy2", 12);
			memcpy(m_general_info.Encoded_by, "NoName encoder", 15);
			
			/*	Title, 32 bytes */
			for(i = 0; i < 32; i ++)
				output_byte(m_general_info.Title[i], 8);
			/*	Artist, 32 bytes */
			for(i = 0; i < 32; i ++)
				output_byte(m_general_info.Artist[i], 8);
			/*	Album, 32 bytes */
			for(i = 0; i < 32; i ++)
				output_byte(m_general_info.Album[i], 8);
			/*	Year, 4 bytes */
			for(i = 0; i < 4; i ++)
				output_byte(m_general_info.Year[i], 8);
			/*	Genre, 1 bytes */
			output_byte(m_general_info.Genre, 8);
			/*	Comment, 32 bytes */
			for(i = 0; i < 32; i ++)
				output_byte(m_general_info.Comment[i], 8);
			/*	Composer, 32 bytes */
			for(i = 0; i < 32; i ++)
				output_byte(m_general_info.Composer[i], 8);
			/*	Encoded_by, 32 bytes */
			for(i = 0; i < 32; i ++)
				output_byte(m_general_info.Encoded_by[i], 8);
			
			bitused += 1576;    //197 bytes
		}
		
		if(text_info_flag)
		{
			output_byte(lyrics_present, 1);
			bitused += 1;
			if(lyrics_present)
			{
				/* initialization */
				// m_lyrics.synchronised_id = 0;     /* non-sync */
				m_lyrics.synchronised_id = 1;       /* sync */
				m_lyrics.lyrics_size = 12;
				m_lyrics.lyrics_text = (char *)malloc(m_lyrics.lyrics_size);
				memcpy(m_lyrics.lyrics_text, "lyrics text", 12);
				
				/* synchronised_id */
				output_byte(m_lyrics.synchronised_id, 1);
				
				/* text coding */
				output_byte(m_lyrics.text_coding, 8);
				
				/* language */
				for(i = 0; i < 3; i ++)
					output_byte(m_lyrics.language[i], 8);
				
				/* synchronised or not */
				if(m_lyrics.synchronised_id == 0)
				{
					/* lyrics size */
					output_byte(m_lyrics.lyrics_size, 22);
					
					/* lyrics text */
					for(i = 0; i < m_lyrics.lyrics_size; i ++)
						output_byte(m_lyrics.lyrics_text[i], 8);
				}
				else
				{
					/* timestamp format */
					output_byte(m_lyrics.timestamp_format, 2);
					bitused += 2;
					
					memcpy(m_lyrics.lyrics_text, "lyrics", 7);
					m_lyrics.lyrics_timestamp = 1;
					m_lyrics.lyrics_size = 7;
					
					/* lyrics size */
					output_byte(m_lyrics.lyrics_size+4, 22);
					
					/* lyrics text */
					for(i = 0; i < m_lyrics.lyrics_size; i ++)
						output_byte(m_lyrics.lyrics_text[i], 8);
					
					/* timestamp */
					output_byte(m_lyrics.lyrics_timestamp, 32);
					bitused += 32;
				}
				
				free(m_lyrics.lyrics_text);
				
				bitused += (m_lyrics.lyrics_size*8+1+8+24+22);
			}
			
			output_byte(user_define_present, 1);
			bitused += 1;
			if(user_define_present)
			{
				/* initialization */
				m_user_text.user_text_size = 17;
				m_user_text.user_define_text = (char *)malloc(m_user_text.user_text_size);
				memcpy(m_user_text.user_define_text, "user define text", 17);
				
				/* text coding */
				output_byte(m_user_text.text_coding, 8);
				
				/* language */
				for(i = 0; i < 3; i ++)
					output_byte(m_user_text.language[i], 8);
				
				/* user text size */
				output_byte(m_user_text.user_text_size, 22);
				
				/* user text info */
				for(i = 0; i < m_user_text.user_text_size; i ++)
					output_byte(m_user_text.user_define_text[i], 8);
				
				free(m_user_text.user_define_text);
				
				bitused += (m_user_text.user_text_size+8+24+22);
			}
			
			/* reserved_bit */
			output_byte(0, 1);
			bitused += 1;
			
			/* text information alignment */
			EncodeBSHCByteAlign();
			bitused = ((bitused+7)>>3)<<3;
		}
    }
      byteused = (bitused+7)>>3;
      FlushAASFHeaderBuffer();

return byteused;
}

int EncodeBSHCQuant(int model,int upper,int cur)
{
	output_byte((long)codeBook[model][upper][cur],codeBookLen[model][upper][cur]);
	return codeBookLen[model][upper][cur];
}
int EncodeBSHCSi(int siVal)
{
	output_byte((long)codeBookSi[siVal],codeBookLenSi[siVal]);
	return codeBookLenSi[siVal];
}
int EncodeBSHCSf(int sfVal)
{
	output_byte((long)codeBookSf[sfVal],codeBookLenSf[sfVal]);
	return codeBookLenSf[sfVal];
}
int EncodeBSHCBin(int ms)
{
	if(ms==1)
		output_byte(1,1);
	else
		output_byte(0,1);
	return 1;
}
void EncodeBSHCPutBits(int val,int len)
{
	output_byte((long)val,len);
}
int EncodeBSHCGetSize(void)
{
	//in bits
	return GetBitstreamSize();

}
int EncodeBSHCByteAlign(void)
{
	return ByteAlign();
}
int BSHCModelSelect(int bshcModel,int bpl)
{
	int modelNum;
	int msb;   /*model decision*/

	if(bshcModel >= 9)
		msb = bshcModel -4;
	else
	{
		msb = (bshcModel+1)/2;
	}
	if(msb==1)
	{
		modelNum = bshcModel;
	}
	if(msb==2)
	{
		if(bpl==2 && bshcModel==3) modelNum = 3;
		if(bpl==1 && bshcModel==3) modelNum = 4;
		
		if(bpl==2 && bshcModel==4) modelNum = 5;
		if(bpl==1 && bshcModel==4) modelNum = 6;
	}
	if(msb==3)
	{
		if(bpl==3 && bshcModel==5) modelNum = 7;
		if(bpl==2 && bshcModel==5) modelNum = 8;
		if(bpl==1 && bshcModel==5) modelNum = 9;

		if(bpl==3 && bshcModel==6) modelNum = 10;
		if(bpl==2 && bshcModel==6) modelNum = 11;
		if(bpl==1 && bshcModel==6) modelNum = 12;
	}
	if(msb==4)
	{
		if(bpl==4 && bshcModel==7) modelNum = 13;
		if(bpl==3 && bshcModel==7) modelNum = 14;
		if(bpl==2 && bshcModel==7) modelNum = 15;
		if(bpl==1 && bshcModel==7) modelNum = 16;

		if(bpl==4 && bshcModel==8) modelNum = 17;
		if(bpl==3 && bshcModel==8) modelNum = 18;
		if(bpl==2 && bshcModel==8) modelNum = 19;
		if(bpl==1 && bshcModel==8) modelNum = 20;
	}
	if(msb>4)
	{
		modelNum = 20+bpl;
	}
	return modelNum;

}
int BSHCFindModelBase(int msb)
{
	int modelNum;  /*model decision*/
	
	if(msb<=4)
	{
		modelNum = msb*msb-msb+1;
	}
	else
	{
		modelNum = 20;
	}
	return modelNum;

}

static int my_log2(int value)
{
    int i, step;

    if(value < 0) {
        fprintf(stderr, "my_log2:error : %d\n", value);
        return 0;
    }

    if(value == 0)  return 0;

    step = 2;
    for(i = 1; i < 24; i++) {
        if(value < step) return i;
        step *= 2;
    }

    return ( 1 + (int)(log10((double)value)/log10(2.0)));
}

int get_msb_of_samples (
    int sample[],
    int num_sample
)
{
    int i;
    int bal;
    int max = 0;

    for (i = 0; i < num_sample; i++) {
        if (abs(sample[i])>max) 
            max = abs(sample[i]);
    }

    if(max > 0) bal = my_log2(max);
    else        bal = 0;

    return bal;
}

void get_cband_msb (
    int num_window_groups,
    int *sample[],
    int max_cband[],
    int *band_qbit[]
)
{
    int g, cband, offset;

    for(g=0; g<num_window_groups; g++)  
    for (cband = 0; cband < max_cband[g]; cband++) {
        offset = 32 * cband;
        band_qbit[g][cband] = get_msb_of_samples(&(sample[g][offset]), 32);
    }
}

int siCodeMode = 0;

extern int cb_tab[16];

void BSHCFindModel(
	int nch,
	int	signal_type,
	int	num_window_groups,
	int window_group_length[],
	int	*sample[][8],
	int	*scalefactors[][8],
	int	maxSfb,
	short	*swb_offset[],
	int top_layer,
	int     *bshc_model[2][8]
)
{
	int		ch, g;
	int		cband;
	int		end_cband[8];     /* Array Size : 64 -> 8  shpark 2000.04.20 */
	int     end_sfb[8];
	int     end_freq[8];
	int     scf_model;
	int 	used_bits=0;
	int     u_bits;
	int     base_maxSfb[8];		/* maxsfb in each group */

	int		band_snf[2][128];
	int		*cband_qbit[2][8];
	int model;
	int curMask;
	int upperMask,bplMask;
	int bpl;
	int t1,t2,t3,t4;
	int cbBitCount1,cbBitCount2;
	int idx,i;
	int prevSi[2];
	int prevSf[2];

	if(maxSfb == 0) {
	    used_bits = (int)((used_bits + 7) / 8) * 8;
        return;
	}
	/* Calculate base_maxSfb & maximum cband, qband, frequency */
	get_end_band (signal_type, num_window_groups, window_group_length,
         maxSfb, swb_offset, top_layer, base_maxSfb, end_sfb, 
		 end_freq, end_cband);

	/* Determine the arithmetic model for the Slice-Bits */
	for(ch = 0; ch < nch; ch++) {
		cband_qbit[ch][0] = &(band_snf[ch][0]);
		for (g = 1; g < num_window_groups; g++) {
			cband_qbit[ch][g] = cband_qbit[ch][g-1] + end_cband[g-1];
		}

		get_cband_msb ( num_window_groups, sample[ch], end_cband, 
			cband_qbit[ch]);
		/*bshc model selection*/
		for (g = 0; g < num_window_groups; g++)
		for(cband=0;cband<end_cband[g];cband++)
		{
			if(cband_qbit[ch][g][cband]==0)
				bshc_model[ch][g][cband] = 0;
			else if(cband_qbit[ch][g][cband]>=5)
			{
				bshc_model[ch][g][cband] = (cband_qbit[ch][g][cband]+4);
			}
			else
			{
				/*BSHCFindModelBase(cband_qbit[ch][g][cband])*/
				/*count cband bits*/
				bshc_model[ch][g][cband] = cband_qbit[ch][g][cband]*2-1; 
				for(cbBitCount1=0,i=0;i<8;i++)
				{
					idx = cband*32+i*4;
					for(upperMask=0,bpl=cband_qbit[ch][g][cband];bpl>0;bpl--)
					{
						
						bplMask = 1<<(bpl-1);
						if(abs(sample[ch][g][idx]) & bplMask)
							t1 = 1;
						else t1 = 0;
						if(abs(sample[ch][g][idx+1]) & bplMask)
							t2 = 1;
						else t2 = 0;
						if(abs(sample[ch][g][idx+2]) & bplMask)
							t3 = 1;
						else t3 = 0;
						if(abs(sample[ch][g][idx+3]) & bplMask)
							t4 = 1;
						else t4 = 0;
						curMask = (t1<<3) + (t2<<2) + (t3<<1) +t4;
						model = BSHCFindModelBase(cband_qbit[ch][g][cband])+(cband_qbit[ch][g][cband]-bpl);
						/* codebook reduction */
						upperMask = cb_tab[upperMask];
						cbBitCount1 += codeBookLen[model][upperMask][curMask];
						upperMask = curMask;

					}
				}
				bshc_model[ch][g][cband] = cband_qbit[ch][g][cband]*2;
				for(cbBitCount2=0,i=0;i<8;i++)
				{
					idx = cband*32+i*4;
					for(upperMask=0,bpl= cband_qbit[ch][g][cband];bpl>0;bpl--)
					{
						bplMask = 1<<(bpl-1);
						if(abs(sample[ch][g][idx]) & bplMask)
							t1 = 1;
						else t1 = 0;
						if(abs(sample[ch][g][idx+1]) & bplMask)
							t2 = 1;
						else t2 = 0;
						if(abs(sample[ch][g][idx+2]) & bplMask)
							t3 = 1;
						else t3 = 0;
						if(abs(sample[ch][g][idx+3]) & bplMask)
							t4 = 1;
						else t4 = 0;
						curMask = (t1<<3) + (t2<<2) + (t3<<1) +t4;
						model = BSHCFindModelBase(cband_qbit[ch][g][cband])+(2*cband_qbit[ch][g][cband]-bpl);
						/* codebook reduction */
						upperMask = cb_tab[upperMask];
						cbBitCount2 += codeBookLen[model][upperMask][curMask];
						upperMask = curMask;

					}
				}
				if(cbBitCount2>cbBitCount1)
				{
					bshc_model[ch][g][cband] = cband_qbit[ch][g][cband]*2-1;			
					cbBitCount2 = cbBitCount1;
				}
				used_bits += cbBitCount2;
			}
		}
	}
}


/*+----------------------------------------------------+
|													   |
|			AATF header write						   |	
|													   | 	
+----------------------------------------------------+*/

#define	SYNCWORD 				0x00000001

#define ID		 				0x00000000
#define CODING_PROFILE  		0x00000000
#define DECODING_STATUS_PRESENT	0x00000001
#define DRM_PRESENT				0x00000000

#define GENERAL_INFO_PRESENT	0x00000000
#define	TEXT_INFO_PRESENT		0x00000000
#define BITSTREAM_TYPE			0x00000001
#define CHANNEL_CONFIG			0x00000000
#define LYRICS_PRESENT			0x00000001

/* vacant function */
int aatf_error_check()
{
	return 0;
}

/* vacant function */
int aatf_raw_data_block_error_check()
{
	return 0;
}

/* vacant function */
int	aatf_header_error_check()
{
	return 0;
}

/* vacant function */
// wlei [20060320]
//int DRM_element()
//{
//	return 0;


int general_info_element()
{
	int i;

	General_info_element m_general_info;
	
	memcpy(m_general_info.Title, "NoName song", 12);
	memcpy(m_general_info.Artist, "NoName guy", 11);
	memcpy(m_general_info.Album, "NoName album", 13);
	memcpy(m_general_info.Year, "2005", 5);
	m_general_info.Genre = 0;
	memcpy(m_general_info.Comment, "comment", 8);
	memcpy(m_general_info.Composer, "NoName guy2", 12);
	memcpy(m_general_info.Encoded_by, "NoName encoder", 15);

	/*	Title, 32 bytes */
	for(i = 0; i < 32; i ++)
		output_byte(m_general_info.Title[i], 8);
	/*	Artist, 32 bytes */
	for(i = 0; i < 32; i ++)
		output_byte(m_general_info.Artist[i], 8);
	/*	Album, 32 bytes */
	for(i = 0; i < 32; i ++)
		output_byte(m_general_info.Album[i], 8);
	/*	Year, 4 bytes */
	for(i = 0; i < 4; i ++)
		output_byte(m_general_info.Year[i], 8);
	/*	Genre, 1 bytes */
	output_byte(m_general_info.Genre, 8);
	/*	Comment, 32 bytes */
	for(i = 0; i < 32; i ++)
		output_byte(m_general_info.Comment[i], 8);
	/*	Composer, 32 bytes */
	for(i = 0; i < 32; i ++)
		output_byte(m_general_info.Composer[i], 8);
	/*	Encoded_by, 32 bytes */
	for(i = 0; i < 32; i ++)
		output_byte(m_general_info.Encoded_by[i], 8);

	return 1576;	// 197 * 8 bits
}

int text_info_element()
{
	int i;
	int bitused;
	int lyrics_present;

	Lyrics_element		m_lyrics;
	
	bitused = 0;
	lyrics_present = LYRICS_PRESENT;

	output_byte(lyrics_present, 1);
	bitused += 1;
	
	if(lyrics_present)
	{
		/* initialization */
		// m_lyrics.synchronised_id = 0;     /* non-sync */
		m_lyrics.synchronised_id = 1;       /* sync */
		m_lyrics.lyrics_size = 12;
		m_lyrics.lyrics_text = (char *)malloc(m_lyrics.lyrics_size);
		memcpy(m_lyrics.lyrics_text, "lyrics text", 12);

		/* synchronised_id */
		output_byte(m_lyrics.synchronised_id, 1);

		/* text coding */
		output_byte(m_lyrics.text_coding, 8);

		/* language */
		for(i = 0; i < 3; i ++)
			output_byte(m_lyrics.language[i], 8);

		/* synchronised or not */
		if(m_lyrics.synchronised_id == 0)
		{
			/* lyrics size */
			output_byte(m_lyrics.lyrics_size, 22);

			/* lyrics text */
			for(i = 0; i < m_lyrics.lyrics_size; i ++)
				output_byte(m_lyrics.lyrics_text[i], 8);
		}
		else
		{
			/* timestamp format */
			output_byte(m_lyrics.timestamp_format, 2);
			bitused += 2;

			memcpy(m_lyrics.lyrics_text, "lyrics", 7);
			m_lyrics.lyrics_timestamp = 1;
			m_lyrics.lyrics_size = 7;

			/* lyrics size */
			output_byte(m_lyrics.lyrics_size+4, 22);

			/* lyrics text */
			for(i = 0; i < m_lyrics.lyrics_size; i ++)
				output_byte(m_lyrics.lyrics_text[i], 8);

			/* timestamp */
			output_byte(m_lyrics.lyrics_timestamp, 32);
			bitused += 32;
		}

		free(m_lyrics.lyrics_text);

		bitused += (m_lyrics.lyrics_size*8+1+8+24+22);
	}
	
	return bitused;
}


int aatf_decoding_header(int freqIdx, int channel_config)
{
	output_byte(SYNCWORD,		12);	// syncword
	output_byte(ID,				2);		// ID
	output_byte(freqIdx,		4);		// sampling_frequency_index
	output_byte(channel_config,	2);		// num_channel 
	output_byte(CODING_PROFILE,	2);		// coding_profile

	return (12+2+4+2+2);
}



int aatf_info_header(int nr_of_blocks, 
					 int aatf_flag, 
					 int bitrate, 
					 int aatf_buffer_fullness)
{

	int i;
	int bit_count;
//	int DRM_present;	// wlei [20060320]
	int general_info_present;
	int text_info_present;
	int bitstream_type;

	bit_count = 0;
//	DRM_present				= (aatf_flag & 0x4);	// wlei [20060320]
	general_info_present 	= (aatf_flag & 0x2);
	text_info_present 		= (aatf_flag & 0x1);
	bitstream_type			= BITSTREAM_TYPE;

	output_byte(nr_of_blocks, 	2); 	// number_of_raw_data_blocks_in_frame;
	bit_count += 2;

	// 2006-01-19 xusen, deleted frameLenght in aatf header
//	output_byte(0,				13);   	// frame_length, real writing delayed; 
//	bit_count += 13;

	output_byte(aatf_flag,		3);		// aatf_flag;
	bit_count += 3;

	output_byte(BITSTREAM_TYPE,	1);		//bitstream_type
	bit_count += 1;

	output_byte(aatf_buffer_fullness, 	11);	// aatf_buffer_fullness
	bit_count += 11;

	// wlei [20060320]
//	if(DRM_present) 
//		bit_count += DRM_element();

	if (general_info_present)
		bit_count += general_info_element();

	if(text_info_present)
		bit_count += text_info_element();

	return bit_count;
}

int WriteAATFHeader(int nr_of_blocks, 
					int freqIdx,
					int	nch,
					int bitrate, 
					int aatf_buffer_fullness, 
					int aatf_flag)
{
	int bit_count;
	int channel_config;
	
	if(nch == 1)
		channel_config = 0;
	else if(nch == 2)
		channel_config = 1;
	else if(nch == 6)
		channel_config = 2;
	else
		channel_config = 3;

	bit_count = 0;

	bit_count += aatf_decoding_header(freqIdx, channel_config);

	bit_count += aatf_info_header(nr_of_blocks, aatf_flag, bitrate, aatf_buffer_fullness);

	bit_count += ByteAlign();	// lixun 2008-7-28, follow spec. here should do byte alignment

	if (nr_of_blocks == 0) 
		bit_count += aatf_error_check();	//->not implemented
	else 
		bit_count += aatf_header_error_check();	//->not implemented

	/* remove due to byteAlign before -- lixun 2008-7-28 */
	//output_byte(0, 1);
	// 2006-01-19 xusen 
	//bit_count += 4;
	//bit_count += 1;

	return bit_count;				

}
