diff --git a/ext_libs/clHCA.c b/ext_libs/clHCA.c index 8ae28172..29c81a9c 100644 --- a/ext_libs/clHCA.c +++ b/ext_libs/clHCA.c @@ -1,9 +1,20 @@ +/** + * HCA DECODER + */ +/* TODO: fixes + * - improve portability on types and float casts, sizeof(int) isn't necessarily sizeof(float) + * - check "packed_noise_level" vs VGAudio (CriHcaPacking.UnpackFrameHeader), weird behaviour + * - check "delta decode" vs VGAudio (CriHcaPacking.DeltaDecode), may be setting wrong values on bad data + * - check "read intensity" vs VGAudio (CriHcaPacking.ReadIntensity), skips intensities if first is 15 + * - simplify DCT4 code + * - add extra validations: encoder_delay/padding < sample_count, bands/totals (max: 128?), track count==1, etc + */ //-------------------------------------------------- -// インクルード +// Includes //-------------------------------------------------- #include "clHCA.h" -//#include +#include #include #include @@ -11,1707 +22,1658 @@ #define inline __inline #endif -//-------------------------------------------------- -// インライン関数 -//-------------------------------------------------- -#if 0 -static inline unsigned short get_le16(unsigned short v_){const unsigned char *v=(const unsigned char *)&v_;unsigned short r=v[1];r<<=8;r|=v[0];return r;} -static inline unsigned short get_be16(unsigned short v_){const unsigned char *v=(const unsigned char *)&v_;unsigned short r=v[0];r<<=8;r|=v[1];return r;} -static inline unsigned int get_be24(unsigned int v_){const unsigned char *v=(const unsigned char *)&v_;unsigned int r=v[0];r<<=8;r|=v[1];r<<=8;r|=v[2];return r;}; -static inline unsigned int get_le32(unsigned int v_){const unsigned char *v=(const unsigned char *)&v_;unsigned int r=v[3];r<<=8;r|=v[2];r<<=8;r|=v[1];r<<=8;r|=v[0];return r;} -static inline unsigned int get_be32(unsigned int v_){const unsigned char *v=(const unsigned char *)&v_;unsigned int r=v[0];r<<=8;r|=v[1];r<<=8;r|=v[2];r<<=8;r|=v[3];return r;} -static inline float get_bef32(float v_){union{float f;unsigned int i;}v;v.f=v_;v.i=get_be32(v.i);return v.f;} +#define HCA_MASK 0x7F7F7F7F /* chunk obfuscation when the HCA is encrypted (ciph type > 0) */ +#define HCA_SUBFRAMES_PER_FRAME 8 +#define HCA_SAMPLES_PER_SUBFRAME 128 +#define HCA_SAMPLES_PER_FRAME (HCA_SUBFRAMES_PER_FRAME*HCA_SAMPLES_PER_SUBFRAME) +#define HCA_MDCT_BITS 7 /* (1<<7) = 128 */ -static union { unsigned int i; unsigned char c[4]; } g_is_le = {1}; -static inline unsigned short swap_u16(unsigned short v){unsigned short r=v&0xFF;r<<=8;v>>=8;r|=v&0xFF;return r;} -static inline unsigned short swap_u32(unsigned int v){unsigned int r=v&0xFF;r<<=8;v>>=8;r|=v&0xFF;r<<=8;v>>=8;r|=v&0xFF;r<<=8;v>>=8;r|=v&0xFF;return r;} -static inline unsigned short ret_le16(unsigned short v){if (g_is_le.c[0]) return v; else return swap_u16(v);} -static inline unsigned short ret_le32(unsigned int v){if (g_is_le.c[0]) return v; else return swap_u32(v);} -#endif +#define HCA_MAX_CHANNELS 16 /* internal max? in practice only 8 can be encoded */ -static inline unsigned int ceil2(unsigned int a,unsigned int b){return (b>0)?(a/b+((a%b)?1:0)):0;} + +/* Disables some optimizations from the original decompilation, mainly avoiding dereferences in some loops. + * Mostly as a test (the compiler may generate similar code anyway), probably deleted later */ +#define HCA_DISABLE_OPTIMIZATIONS 0 //-------------------------------------------------- -// structure definitions +// header definitions //-------------------------------------------------- -typedef struct stHeader{//ファイル情報 (必須) - unsigned int hca; // 'HCA' - unsigned short version; // バージョン。v1.3とv2.0の存在を確認 - unsigned short dataOffset; // データオフセット +typedef struct stHeader { + unsigned int hca; + unsigned short version; + unsigned short header_size; } stHeader; -typedef struct stFormat{//フォーマット情報 (必須) - unsigned int fmt; // 'fmt' - unsigned int channelCount:8; // チャンネル数 1〜16 - unsigned int samplingRate:24; // サンプリングレート 1〜0x7FFFFF - unsigned int blockCount; // ブロック数 0以上 - unsigned short r01; // 先頭の無音部分(ブロック数*0x400+0x80) - unsigned short r02; // 末尾の無音部分?計算方法不明(0x226) +typedef struct stFormat { + unsigned int fmt; + unsigned int channels : 8; + unsigned int sample_rate : 24; + unsigned int frame_count; + unsigned short encoder_delay; + unsigned short encoder_padding; } stFormat; -typedef struct stCompress{//圧縮情報 (圧縮情報かデコード情報のどちらか一つが必須) - unsigned int comp; // 'comp' - unsigned short blockSize; // ブロックサイズ(CBRのときに有効?) 8〜0xFFFF、0のときはVBR - unsigned char r01; // 不明(1) 0〜r02 v2.0現在1のみ対応 - unsigned char r02; // 不明(15) r01〜0x1F v2.0現在15のみ対応 - unsigned char r03; // 不明(1)(1) - unsigned char r04; // 不明(1)(0) - unsigned char r05; // 不明(0x80)(0x80) - unsigned char r06; // 不明(0x80)(0x20) - unsigned char r07; // 不明(0)(0x20) - unsigned char r08; // 不明(0)(8) - unsigned char reserve1; // 予約 - unsigned char reserve2; // 予約 +typedef struct stCompress { + unsigned int comp; + unsigned short frame_size; + unsigned char min_resolution; + unsigned char max_resolution; + unsigned char track_count; + unsigned char channel_config; + unsigned char total_band_count; + unsigned char base_band_count; + unsigned char stereo_band_count; + unsigned char bands_per_hfr_group; + unsigned char reserved1; + unsigned char reserved2; } stCompress; -typedef struct stDecode{//デコード情報 (圧縮情報かデコード情報のどちらか一つが必須) - unsigned int dec; // 'dec' - unsigned short blockSize; // ブロックサイズ(CBRのときに有効?) 8〜0xFFFF、0のときはVBR - unsigned char r01; // 不明(1) 0〜r02 v2.0現在1のみ対応 - unsigned char r02; // 不明(15) r01〜0x1F v2.0現在15のみ対応 - unsigned char count1; // type0とtype1の数-1 - unsigned char count2; // type2の数-1 - unsigned char r03:4; // 不明(0) - unsigned char r04:4; // 不明(0) 0は1に修正される - unsigned char enableCount2; // count2を使うフラグ +typedef struct stDecode { + unsigned int dec; + unsigned short frame_size; + unsigned char min_resolution; + unsigned char max_resolution; + unsigned char total_band_count; + unsigned char base_band_count; + unsigned char track_count : 4; + unsigned char channel_config : 4; + unsigned char stereo_type; } stDecode; -typedef struct stVBR{//可変ビットレート情報 (廃止?) - unsigned int vbr; // 'vbr' - unsigned short r01; // 不明 0〜0x1FF - unsigned short r02; // 不明 +typedef struct stVBR { + unsigned int vbr; + unsigned short max_frame_size; + unsigned short noise_level; } stVBR; -typedef struct stATH{//ATHテーブル情報 (v2.0から廃止?) - unsigned int ath; // 'ath' - unsigned short type; // テーブルの種類(0:全て0 1:テーブル1) +typedef struct stATH { + unsigned int ath; + unsigned short type; } stATH; -typedef struct stLoop{//ループ情報 - unsigned int loop; // 'loop' - unsigned int loopStart; // ループ開始ブロックインデックス 0〜loopEnd - unsigned int loopEnd; // ループ終了ブロックインデックス loopStart〜(stFormat::blockCount-1) - unsigned short r01; // 不明(0x80)ループフラグ?ループ回数? - unsigned short r02; // 不明(0x226) +typedef struct stLoop { + unsigned int loop; + unsigned int loop_start_frame; + unsigned int loop_end_frame; + unsigned short loop_start_delay; + unsigned short loop_end_padding; } stLoop; -typedef struct stCipher{//暗号テーブル情報 - unsigned int ciph; // 'ciph' - unsigned short type; // 暗号化の種類(0:暗号化なし 1:鍵なし暗号化 0x38:鍵あり暗号化) +typedef struct stCipher { + unsigned int ciph; + unsigned short type; } stCipher; -typedef struct stRVA{//相対ボリューム調節情報 - unsigned int rva; // 'rva' - float volume; // ボリューム +typedef struct stRVA { + unsigned int rva; + float volume; } stRVA; -typedef struct stComment{//コメント情報 - unsigned int comm; // 'comm' - unsigned char len; // コメントの長さ? - //char comment[]; +typedef struct stComment { + unsigned int comm; + unsigned char len; + //char comment[]; /* variable, null terminated */ } stComment; -typedef struct stPadding{//パディング - unsigned int pad; // 'pad' +typedef struct stPadding { + unsigned int pad; + //unsigned char *padding; /* variable, up to header_size */ } stPadding; -typedef struct clATH{ - unsigned char _table[0x80]; -} clATH; -typedef struct clCipher{ - unsigned char _table[0x100]; -} clCipher; -typedef struct stChannel{ - float block[0x80]; - float base[0x80]; - char value[0x80]; - char scale[0x80]; - char value2[8]; - int type; - char *value3; - unsigned int count; - float wav1[0x80]; - float wav2[0x80]; - float wav3[0x80]; - float wave[8][0x80]; + + +//-------------------------------------------------- +// lib config/state +//-------------------------------------------------- +typedef enum { DISCRETE = 0, STEREO_PRIMARY = 1, STEREO_SECONDARY = 2 } channel_type_t; +typedef struct stChannel { + /* HCA channel config */ + int type; /* discrete / stereo-primary / stereo-secondary */ + unsigned int coded_scalefactor_count; /* scalefactors used (depending on channel type) */ + + /* subframe state */ + unsigned char *hfr_scales; /* high frequency scales, pointing to higher scalefactors (simplification) */ + unsigned char intensity[HCA_SUBFRAMES_PER_FRAME]; /* intensity indexes (value max: 15 / 4b) */ + unsigned char scalefactors[HCA_SAMPLES_PER_SUBFRAME]; /* scale indexes (value max: 64 / 6b)*/ + unsigned char resolution[HCA_SAMPLES_PER_SUBFRAME]; /* resolution indexes (value max: 15 / 4b) */ + + float gain[HCA_SAMPLES_PER_SUBFRAME]; /* gain to apply to quantized spectral data */ + float spectra[HCA_SAMPLES_PER_SUBFRAME]; /* resulting dequantized data */ + float temp[HCA_SAMPLES_PER_SUBFRAME]; /* temp for DCT-IV */ + float dct[HCA_SAMPLES_PER_SUBFRAME]; /* result of DCT-IV */ + float imdct_previous[HCA_SAMPLES_PER_SUBFRAME]; /* IMDCT */ + + /* frame state */ + float wave[HCA_SUBFRAMES_PER_FRAME][HCA_SAMPLES_PER_SUBFRAME]; /* resulting samples */ } stChannel; -typedef struct clHCA{ - unsigned int _validFile; - unsigned int _version; - unsigned int _dataOffset; - unsigned int _channelCount; - unsigned int _samplingRate; - unsigned int _blockCount; - unsigned int _fmt_r01; - unsigned int _fmt_r02; - unsigned int _blockSize; - unsigned int _comp_r01; - unsigned int _comp_r02; - unsigned int _comp_r03; - unsigned int _comp_r04; - unsigned int _comp_r05; - unsigned int _comp_r06; - unsigned int _comp_r07; - unsigned int _comp_r08; - unsigned int _comp_r09; - unsigned int _vbr_r01; - unsigned int _vbr_r02; - unsigned int _ath_type; - unsigned int _loopStart; - unsigned int _loopEnd; - unsigned int _loop_r01; - unsigned int _loop_r02; - unsigned int _loopFlg; - unsigned int _ciph_type; - unsigned int _ciph_key1; - unsigned int _ciph_key2; - float _rva_volume; - unsigned int _comm_len; - char *_comm_comment; - clATH _ath; - clCipher _cipher; - stChannel _channel[0x10]; + +typedef struct clHCA { + /* header config */ + unsigned int is_valid; + /* hca chunk */ + unsigned int version; + unsigned int header_size; + /* fmt chunk */ + unsigned int channels; + unsigned int sample_rate; + unsigned int frame_count; + unsigned int encoder_delay; + unsigned int encoder_padding; + /* comp/dec chunk */ + unsigned int frame_size; + unsigned int min_resolution; + unsigned int max_resolution; + unsigned int track_count; + unsigned int channel_config; + unsigned int stereo_type; + unsigned int total_band_count; + unsigned int base_band_count; + unsigned int stereo_band_count; + unsigned int bands_per_hfr_group; + unsigned int reserved1; + unsigned int reserved2; + /* vbr chunk */ + unsigned int vbr_max_frame_size; + unsigned int vbr_noise_Level; + /* ath chunk */ + unsigned int ath_type; + /* loop chunk */ + unsigned int loop_start_frame; + unsigned int loop_end_frame; + unsigned int loop_start_delay; + unsigned int loop_end_padding; + unsigned int loop_flag; + /* ciph chunk */ + unsigned int ciph_type; + unsigned int ciph_key_u; + unsigned int ciph_key_l; + /* rva chunk */ + float rva_volume; + /* comm chunk */ + unsigned int comment_len; + char *comment; + + /* initial state */ + unsigned int hfr_group_count; + unsigned char ath_curve[HCA_SAMPLES_PER_SUBFRAME]; + unsigned char cipher_table[256]; + /* variable state */ + stChannel channel[HCA_MAX_CHANNELS]; } clHCA; -typedef struct clData{ - const unsigned char *_data; - int _size; - int _bit; + +typedef struct clData { + const unsigned char *data; + int size; + int bit; } clData; -//-------------------------------------------------- -// コンストラクタ -//-------------------------------------------------- -static void clATH_constructor(clATH *ath); -static void clCipher_constructor(clCipher *cipher); - -static void clHCA_constructor(clHCA *hca,unsigned int ciphKey1,unsigned int ciphKey2){ - memset(hca,0,sizeof(*hca)); - hca->_ciph_key1 = ciphKey1; - hca->_ciph_key2 = ciphKey2; - clATH_constructor(&hca->_ath); - clCipher_constructor(&hca->_cipher); - hca->_validFile = 0; - hca->_comm_comment = 0; -} - -static void clHCA_destructor(clHCA *hca) -{ - if(hca->_comm_comment){free(hca->_comm_comment);hca->_comm_comment=0;} -} //-------------------------------------------------- -// HCAチェック +// Checksum //-------------------------------------------------- -#if 0 -static int clHCA_CheckFile(void *data,unsigned int size){ - return (data&&size>=4&&(get_be32(*(unsigned int *)data)&0x7F7F7F7F)==0x48434100);/*'HCA\0'*/ -} -#endif - -//-------------------------------------------------- -// チェックサム -//-------------------------------------------------- -static const unsigned short clHCA_CheckSum_v[]={ - 0x0000,0x8005,0x800F,0x000A,0x801B,0x001E,0x0014,0x8011,0x8033,0x0036,0x003C,0x8039,0x0028,0x802D,0x8027,0x0022, - 0x8063,0x0066,0x006C,0x8069,0x0078,0x807D,0x8077,0x0072,0x0050,0x8055,0x805F,0x005A,0x804B,0x004E,0x0044,0x8041, - 0x80C3,0x00C6,0x00CC,0x80C9,0x00D8,0x80DD,0x80D7,0x00D2,0x00F0,0x80F5,0x80FF,0x00FA,0x80EB,0x00EE,0x00E4,0x80E1, - 0x00A0,0x80A5,0x80AF,0x00AA,0x80BB,0x00BE,0x00B4,0x80B1,0x8093,0x0096,0x009C,0x8099,0x0088,0x808D,0x8087,0x0082, - 0x8183,0x0186,0x018C,0x8189,0x0198,0x819D,0x8197,0x0192,0x01B0,0x81B5,0x81BF,0x01BA,0x81AB,0x01AE,0x01A4,0x81A1, - 0x01E0,0x81E5,0x81EF,0x01EA,0x81FB,0x01FE,0x01F4,0x81F1,0x81D3,0x01D6,0x01DC,0x81D9,0x01C8,0x81CD,0x81C7,0x01C2, - 0x0140,0x8145,0x814F,0x014A,0x815B,0x015E,0x0154,0x8151,0x8173,0x0176,0x017C,0x8179,0x0168,0x816D,0x8167,0x0162, - 0x8123,0x0126,0x012C,0x8129,0x0138,0x813D,0x8137,0x0132,0x0110,0x8115,0x811F,0x011A,0x810B,0x010E,0x0104,0x8101, - 0x8303,0x0306,0x030C,0x8309,0x0318,0x831D,0x8317,0x0312,0x0330,0x8335,0x833F,0x033A,0x832B,0x032E,0x0324,0x8321, - 0x0360,0x8365,0x836F,0x036A,0x837B,0x037E,0x0374,0x8371,0x8353,0x0356,0x035C,0x8359,0x0348,0x834D,0x8347,0x0342, - 0x03C0,0x83C5,0x83CF,0x03CA,0x83DB,0x03DE,0x03D4,0x83D1,0x83F3,0x03F6,0x03FC,0x83F9,0x03E8,0x83ED,0x83E7,0x03E2, - 0x83A3,0x03A6,0x03AC,0x83A9,0x03B8,0x83BD,0x83B7,0x03B2,0x0390,0x8395,0x839F,0x039A,0x838B,0x038E,0x0384,0x8381, - 0x0280,0x8285,0x828F,0x028A,0x829B,0x029E,0x0294,0x8291,0x82B3,0x02B6,0x02BC,0x82B9,0x02A8,0x82AD,0x82A7,0x02A2, - 0x82E3,0x02E6,0x02EC,0x82E9,0x02F8,0x82FD,0x82F7,0x02F2,0x02D0,0x82D5,0x82DF,0x02DA,0x82CB,0x02CE,0x02C4,0x82C1, - 0x8243,0x0246,0x024C,0x8249,0x0258,0x825D,0x8257,0x0252,0x0270,0x8275,0x827F,0x027A,0x826B,0x026E,0x0264,0x8261, - 0x0220,0x8225,0x822F,0x022A,0x823B,0x023E,0x0234,0x8231,0x8213,0x0216,0x021C,0x8219,0x0208,0x820D,0x8207,0x0202, +static const unsigned short crc16_lookup_table[256] = { + 0x0000,0x8005,0x800F,0x000A,0x801B,0x001E,0x0014,0x8011,0x8033,0x0036,0x003C,0x8039,0x0028,0x802D,0x8027,0x0022, + 0x8063,0x0066,0x006C,0x8069,0x0078,0x807D,0x8077,0x0072,0x0050,0x8055,0x805F,0x005A,0x804B,0x004E,0x0044,0x8041, + 0x80C3,0x00C6,0x00CC,0x80C9,0x00D8,0x80DD,0x80D7,0x00D2,0x00F0,0x80F5,0x80FF,0x00FA,0x80EB,0x00EE,0x00E4,0x80E1, + 0x00A0,0x80A5,0x80AF,0x00AA,0x80BB,0x00BE,0x00B4,0x80B1,0x8093,0x0096,0x009C,0x8099,0x0088,0x808D,0x8087,0x0082, + 0x8183,0x0186,0x018C,0x8189,0x0198,0x819D,0x8197,0x0192,0x01B0,0x81B5,0x81BF,0x01BA,0x81AB,0x01AE,0x01A4,0x81A1, + 0x01E0,0x81E5,0x81EF,0x01EA,0x81FB,0x01FE,0x01F4,0x81F1,0x81D3,0x01D6,0x01DC,0x81D9,0x01C8,0x81CD,0x81C7,0x01C2, + 0x0140,0x8145,0x814F,0x014A,0x815B,0x015E,0x0154,0x8151,0x8173,0x0176,0x017C,0x8179,0x0168,0x816D,0x8167,0x0162, + 0x8123,0x0126,0x012C,0x8129,0x0138,0x813D,0x8137,0x0132,0x0110,0x8115,0x811F,0x011A,0x810B,0x010E,0x0104,0x8101, + 0x8303,0x0306,0x030C,0x8309,0x0318,0x831D,0x8317,0x0312,0x0330,0x8335,0x833F,0x033A,0x832B,0x032E,0x0324,0x8321, + 0x0360,0x8365,0x836F,0x036A,0x837B,0x037E,0x0374,0x8371,0x8353,0x0356,0x035C,0x8359,0x0348,0x834D,0x8347,0x0342, + 0x03C0,0x83C5,0x83CF,0x03CA,0x83DB,0x03DE,0x03D4,0x83D1,0x83F3,0x03F6,0x03FC,0x83F9,0x03E8,0x83ED,0x83E7,0x03E2, + 0x83A3,0x03A6,0x03AC,0x83A9,0x03B8,0x83BD,0x83B7,0x03B2,0x0390,0x8395,0x839F,0x039A,0x838B,0x038E,0x0384,0x8381, + 0x0280,0x8285,0x828F,0x028A,0x829B,0x029E,0x0294,0x8291,0x82B3,0x02B6,0x02BC,0x82B9,0x02A8,0x82AD,0x82A7,0x02A2, + 0x82E3,0x02E6,0x02EC,0x82E9,0x02F8,0x82FD,0x82F7,0x02F2,0x02D0,0x82D5,0x82DF,0x02DA,0x82CB,0x02CE,0x02C4,0x82C1, + 0x8243,0x0246,0x024C,0x8249,0x0258,0x825D,0x8257,0x0252,0x0270,0x8275,0x827F,0x027A,0x826B,0x026E,0x0264,0x8261, + 0x0220,0x8225,0x822F,0x022A,0x823B,0x023E,0x0234,0x8231,0x8213,0x0216,0x021C,0x8219,0x0208,0x820D,0x8207,0x0202, }; -static unsigned short clHCA_CheckSum(const void *data,int size,unsigned short sum){ - const unsigned char *s, *e; - for(s=(const unsigned char *)data,e=s+size;s>8)^*s]; - return sum; +static unsigned short crc16_checksum(const unsigned char *data, int size) { + int i; + unsigned short sum = 0; + + for (i = 0; i < size; i++) { + sum = (sum << 8) ^ crc16_lookup_table[(sum >> 8) ^ data[i]]; + } + return sum; } //-------------------------------------------------- -// データ +// Bitstream reader //-------------------------------------------------- -void clData_constructor(clData *ds,const void *data,int size){ - ds->_data=(const unsigned char *)data; - ds->_size=size*8; - ds->_bit=0; +static void bitreader_init(clData *br, const void *data, int size) { + br->data = data; + br->size = size * 8; + br->bit = 0; } -static unsigned int clData_CheckBit(clData *ds,int bitSize){ - unsigned int v=0; - if(ds->_bit+bitSize<=ds->_size){ - unsigned int bitOffset=bitSize+(ds->_bit&7); - if((ds->_size-ds->_bit)>=32&&bitOffset>=25){ - static const int mask[]={0xFFFFFFFF,0x7FFFFFFF,0x3FFFFFFF,0x1FFFFFFF,0x0FFFFFFF,0x07FFFFFF,0x03FFFFFF,0x01FFFFFF}; - const unsigned int _bit=ds->_bit; - const unsigned char *data=&ds->_data[_bit>>3]; - v=data[0];v=(v<<8)|data[1];v=(v<<8)|data[2];v=(v<<8)|data[3]; - v&=mask[_bit&7]; - v>>=32-(_bit&7)-bitSize; - } - else if((ds->_size-ds->_bit)>=24&&bitOffset>=17){ - static const int mask[]={0xFFFFFF,0x7FFFFF,0x3FFFFF,0x1FFFFF,0x0FFFFF,0x07FFFF,0x03FFFF,0x01FFFF}; - const unsigned int _bit=ds->_bit; - const unsigned char *data=&ds->_data[_bit>>3]; - v=data[0];v=(v<<8)|data[1];v=(v<<8)|data[2]; - v&=mask[_bit&7]; - v>>=24-(_bit&7)-bitSize; - } - else if((ds->_size-ds->_bit)>=16&&bitOffset>=9){ - static const int mask[]={0xFFFF,0x7FFF,0x3FFF,0x1FFF,0x0FFF,0x07FF,0x03FF,0x01FF}; - const unsigned int _bit=ds->_bit; - const unsigned char *data=&ds->_data[_bit>>3]; - v=data[0];v=(v<<8)|data[1]; - v&=mask[_bit&7]; - v>>=16-(_bit&7)-bitSize; - } - else{ - static const int mask[]={0xFF,0x7F,0x3F,0x1F,0x0F,0x07,0x03,0x01}; - const unsigned int _bit=ds->_bit; - const unsigned char *data=&ds->_data[_bit>>3]; - v=data[0]; - v&=mask[_bit&7]; - v>>=8-(_bit&7)-bitSize; - } - } - return v; +static unsigned int bitreader_check(clData *br, int bitsize) { + const unsigned int bit = br->bit; + const unsigned int bit_rem = bit & 7; + const unsigned int size = br->size; + unsigned int v = 0; + unsigned int bit_offset, bit_left; + + if (!(bit + bitsize <= size)) + return v; + + bit_offset = bitsize + bit_rem; + bit_left = size - bit; + if (bit_left >= 32 && bit_offset >= 25) { + static const unsigned int mask[8] = { + 0xFFFFFFFF,0x7FFFFFFF,0x3FFFFFFF,0x1FFFFFFF, + 0x0FFFFFFF,0x07FFFFFF,0x03FFFFFF,0x01FFFFFF + }; + const unsigned char *data = &br->data[bit >> 3]; + v = data[0]; + v = (v << 8) | data[1]; + v = (v << 8) | data[2]; + v = (v << 8) | data[3]; + v &= mask[bit_rem]; + v >>= 32 - bit_rem - bitsize; + } + else if (bit_left >= 24 && bit_offset >= 17) { + static const unsigned int mask[8] = { + 0xFFFFFF,0x7FFFFF,0x3FFFFF,0x1FFFFF, + 0x0FFFFF,0x07FFFF,0x03FFFF,0x01FFFF + }; + const unsigned char *data = &br->data[bit >> 3]; + v = data[0]; + v = (v << 8) | data[1]; + v = (v << 8) | data[2]; + v &= mask[bit_rem]; + v >>= 24 - bit_rem - bitsize; + } + else if (bit_left >= 16 && bit_offset >= 9) { + static const unsigned int mask[8] = { + 0xFFFF,0x7FFF,0x3FFF,0x1FFF,0x0FFF,0x07FF,0x03FF,0x01FF + }; + const unsigned char *data = &br->data[bit >> 3]; + v = data[0]; + v = (v << 8) | data[1]; + v &= mask[bit_rem]; + v >>= 16 - bit_rem - bitsize; + } + else { + static const unsigned int mask[8] = { + 0xFF,0x7F,0x3F,0x1F,0x0F,0x07,0x03,0x01 + }; + const unsigned char *data = &br->data[bit >> 3]; + v = data[0]; + v &= mask[bit_rem]; + v >>= 8 - bit_rem - bitsize; + } + return v; } -static unsigned int clData_GetBit(clData *ds,int bitSize){ - unsigned int v=clData_CheckBit(ds,bitSize); - ds->_bit+=bitSize; - return v; +static unsigned int bitreader_read(clData *br, int bitsize) { + unsigned int v = bitreader_check(br, bitsize); + br->bit += bitsize; + return v; } -static void clData_AddBit(clData *ds,int bitSize){ - ds->_bit+=bitSize; +static void bitreader_skip(clData *br, int bitsize) { + br->bit += bitsize; } -//-------------------------------------------------- -// ヘッダ情報をコンソール出力 -//-------------------------------------------------- -#if 0 -static int clHCA_PrintInfo(const char *filenameHCA){ - FILE *fp; - stHeader header; - unsigned char *data; - unsigned int size; - clData d; - - // temporaries, so we don't need a state structure - unsigned int _version; - unsigned int _dataOffset; - unsigned int _channelCount; - unsigned int _samplingRate; - unsigned int _blockCount; - unsigned int _fmt_r01; - unsigned int _fmt_r02; - unsigned int _blockSize; - unsigned int _comp_r01; - unsigned int _comp_r02; - unsigned int _comp_r03; - unsigned int _comp_r04; - unsigned int _comp_r05; - unsigned int _comp_r06; - unsigned int _comp_r07; - unsigned int _comp_r08; - unsigned int _comp_r09; - unsigned int _vbr_r01; - unsigned int _vbr_r02; - unsigned int _ath_type; - unsigned int _loopStart; - unsigned int _loopEnd; - unsigned int _loop_r01; - unsigned int _loop_r02; - unsigned int _loopFlg; - unsigned int _ciph_type; - unsigned int _ciph_key1; - unsigned int _ciph_key2; - float _rva_volume; - unsigned int _comm_len; - char *_comm_comment; - - // チェック - if(!(filenameHCA))return -1; - - // HCAファイルを開く - if((fp = fopen(filenameHCA,"rb")) == NULL){ - printf("Error: ファイルが開けませんでした。\n"); - return -1; - } - - // ヘッダチェック - memset(&header,0,sizeof(header)); - fread(&header,sizeof(header),1,fp); - if(!clHCA_CheckFile(&header,sizeof(header))){ - printf("Error: HCAファイルではありません。\n"); - fclose(fp);return -1; - } - - // ヘッダ解析 - clData_constructor(&d, &header, sizeof(header)); - clData_AddBit(&d, 32); - header.dataOffset=clData_CheckBit(&d, 16); - data=(unsigned char*) malloc(header.dataOffset); - if(!data){ - printf("Error: メモリ不足です。\n"); - fclose(fp);return -1; - } - fseek(fp,0,SEEK_SET); - fread(data,header.dataOffset,1,fp); - - size=header.dataOffset; - - clData_constructor(&d, data, size); - - // サイズチェック - if(size=sizeof(stHeader) && (clData_CheckBit(&d,32)&0x7F7F7F7F)==0x48434100){/*'HCA\0'*/ - clData_AddBit(&d,32); - _version=clData_GetBit(&d,16); - _dataOffset=clData_GetBit(&d,16); - printf("コーデック: HCA\n"); - printf("バージョン: %d.%d\n",_version>>8,_version&0xFF); - //if(size<_dataOffset)return -1; - if(clHCA_CheckSum(data,_dataOffset,0))printf("※ ヘッダが破損しています。改変してる場合もこの警告が出ます。\n"); - size-=(16+16+32)/8; - }else{ - printf("※ HCAチャンクがありません。再生に必要な情報です。\n"); - } - - // fmt - if(size>=sizeof(stFormat) && (clData_CheckBit(&d, 32)&0x7F7F7F7F)==0x666D7400){/*'fmt\0'*/ - clData_AddBit(&d,32); - _channelCount=clData_GetBit(&d,8); - _samplingRate=clData_GetBit(&d,24); - _blockCount=clData_GetBit(&d,32); - _fmt_r01=clData_GetBit(&d,16); - _fmt_r02=clData_GetBit(&d,16); - switch(_channelCount){ - case 1:printf("チャンネル数: モノラル (1チャンネル)\n");break; - case 2:printf("チャンネル数: ステレオ (2チャンネル)\n");break; - default:printf("チャンネル数: %dチャンネル\n",_channelCount);break; - } - if(!(_channelCount>=1&&_channelCount<=16)){ - printf("※ チャンネル数の範囲は1〜16です。\n"); - } - printf("サンプリングレート: %dHz\n",_samplingRate); - if(!(_samplingRate>=1&&_samplingRate<=0x7FFFFF)){ - printf("※ サンプリングレートの範囲は1〜8388607(0x7FFFFF)です。\n"); - } - printf("ブロック数: %d\n",_blockCount); - printf("先頭無音ブロック数: %d\n",(_fmt_r01-0x80)/0x400); - printf("末尾無音サンプル数?: %d\n",_fmt_r02); - size-=(16+16+32+24+8+32)/8; - }else{ - printf("※ fmtチャンクがありません。再生に必要な情報です。\n"); - } - - // comp - if(size>=sizeof(stCompress) && (clData_CheckBit(&d, 32)&0x7F7F7F7F)==0x636F6D70){/*'comp'*/ - clData_AddBit(&d,32); - _blockSize=clData_GetBit(&d,16); - _comp_r01=clData_GetBit(&d,8); - _comp_r02=clData_GetBit(&d,8); - _comp_r03=clData_GetBit(&d,8); - _comp_r04=clData_GetBit(&d,8); - _comp_r05=clData_GetBit(&d,8); - _comp_r06=clData_GetBit(&d,8); - _comp_r07=clData_GetBit(&d,8); - _comp_r08=clData_GetBit(&d,8); - clData_AddBit(&d,8+8); - printf("ビットレート: CBR (固定ビットレート)\n"); - printf("ブロックサイズ: 0x%04X\n",_blockSize); - if(!(_blockSize>=8&&_blockSize<=0xFFFF)){ - printf("※ ブロックサイズの範囲は8〜65535(0xFFFF)です。v1.3では0でVBRになるようになってましたが、v2.0から廃止されたようです。\n"); - } - printf("comp1: %d\n",_comp_r01); - printf("comp2: %d\n",_comp_r02); - if(!(_comp_r01>=0&&_comp_r01<=_comp_r02&&_comp_r02<=0x1F)){ - printf("※ comp1とcomp2の範囲は0<=comp1<=comp2<=31です。v2.0現在、comp1は1、comp2は15で固定されています。\n"); - } - printf("comp3: %d\n",_comp_r03); - if(!_comp_r03){ - printf("※ comp3は1以上の値です。\n"); - } - printf("comp4: %d\n",_comp_r04); - printf("comp5: %d\n",_comp_r05); - printf("comp6: %d\n",_comp_r06); - printf("comp7: %d\n",_comp_r07); - printf("comp8: %d\n",_comp_r08); - size-=(32+16+8*8)/8; - } - - // dec - else if(size>=sizeof(stDecode) && (clData_CheckBit(&d, 32)&0x7F7F7F7F)==0x64656300){/*'dec\0'*/ - unsigned char count1,count2,enableCount2; - clData_AddBit(&d, 32); - _blockSize=clData_GetBit(&d,16); - _comp_r01=clData_GetBit(&d,8); - _comp_r02=clData_GetBit(&d,8); - count1=clData_GetBit(&d,8); - count2=clData_GetBit(&d,8); - _comp_r03=clData_GetBit(&d,4); - _comp_r04=clData_GetBit(&d,4); - enableCount2=clData_GetBit(&d,8); - _comp_r05=count1+1; - _comp_r06=((enableCount2)?count2:count1)+1; - _comp_r07=_comp_r05-_comp_r06; - _comp_r08=0; - printf("ビットレート: CBR (固定ビットレート)\n"); - printf("ブロックサイズ: 0x%04X\n",_blockSize); - if(!(_blockSize>=8&&_blockSize<=0xFFFF)){ - printf("※ ブロックサイズの範囲は8〜65535(0xFFFF)です。v1.3では0でVBRになるようになってましたが、v2.0から廃止されたようです。\n"); - } - printf("dec1: %d\n",_comp_r01); - printf("dec2: %d\n",_comp_r02); - if(!(_comp_r01>=0&&_comp_r01<=_comp_r02&&_comp_r02<=0x1F)){ - printf("※ dec1とdec2の範囲は0<=dec1<=dec2<=31です。v2.0現在、dec1は1、dec2は15で固定されています。\n"); - } - printf("dec3: %d\n",_comp_r03); - if(!_comp_r03){ - printf("※ dec3は再生時に1以上の値に修正されます。\n"); - } - printf("dec4: %d\n",_comp_r04); - printf("dec5: %d\n",_comp_r05); - printf("dec6: %d\n",_comp_r06); - printf("dec7: %d\n",_comp_r07); - size-=(8+4+4+8+8+8+8+16+32)/8; - }else{ - printf("※ compチャンクまたはdecチャンクがありません。再生に必要な情報です。\n"); - } - - // vbr - if(size>=sizeof(stVBR) && (clData_CheckBit(&d,32)&0x7F7F7F7F)==0x76627200){/*'vbr\0'*/ - clData_AddBit(&d, 32); - _vbr_r01=clData_GetBit(&d,16); - _vbr_r02=clData_GetBit(&d,16); - printf("ビットレート: VBR (可変ビットレート) ※v2.0で廃止されています。\n"); - if(!(_blockSize==0)){ - printf("※ compまたはdecチャンクですでにCBRが指定されています。\n"); - } - printf("vbr1: %d\n",_vbr_r01); - if(!(_vbr_r01>=0&&_vbr_r01<=0x1FF)){ - printf("※ vbr1の範囲は0〜511(0x1FF)です。\n"); - } - printf("vbr2: %d\n",_vbr_r02); - size-=(16+16+32)/8; - }else{ - _vbr_r01=0; - _vbr_r02=0; - } - - // ath - if(size>=6 && (clData_CheckBit(&d,32)&0x7F7F7F7F)==0x61746800){/*'ath\0'*/ - clData_AddBit(&d,32); - _ath_type=clData_GetBit(&d,16); - printf("ATHタイプ:%d ※v2.0から廃止されています。\n",_ath_type); - size-=(16+32)/8; - }else{ - if(_version<0x200){ - printf("ATHタイプ:1 ※v2.0から廃止されています。\n"); - } - } - - // loop - if(size>=sizeof(stLoop) && (clData_CheckBit(&d,32)&0x7F7F7F7F)==0x6C6F6F70){/*'loop'*/ - clData_AddBit(&d, 32); - _loopStart=clData_GetBit(&d,32); - _loopEnd=clData_GetBit(&d,32); - _loop_r01=clData_GetBit(&d,16); - _loop_r02=clData_GetBit(&d,16); - printf("ループ開始ブロック: %d\n",_loopStart); - printf("ループ終了ブロック: %d\n",_loopEnd); - if(!(_loopStart>=0&&_loopStart<=_loopEnd&&_loopEnd<_blockCount)){ - printf("※ ループ開始ブロックとループ終了ブロックの範囲は、0<=ループ開始ブロック<=ループ終了ブロック<ブロック数 です。\n"); - } - printf("ループ情報1: %d\n",_loop_r01); - printf("ループ情報2: %d\n",_loop_r02); - size-=(16+16+32+32+32)/8; - } - - // ciph - if(size>=6 && (clData_CheckBit(&d, 32)&0x7F7F7F7F)==0x63697068){/*'ciph'*/ - clData_AddBit(&d,32); - _ciph_type=clData_GetBit(&d,16); - switch(_ciph_type){ - case 0:printf("暗号化タイプ: なし\n");break; - case 1:printf("暗号化タイプ: 鍵無し暗号化\n");break; - case 0x38:printf("暗号化タイプ: 鍵有り暗号化 ※正しい鍵を使わないと出力波形がおかしくなります。\n");break; - default:printf("暗号化タイプ: %d\n",_ciph_type);break; - } - if(!(_ciph_type==0||_ciph_type==1||_ciph_type==0x38)){ - printf("※ この暗号化タイプは、v2.0現在再生できません。\n"); - } - size-=6; - } - - // rva - if(size>=sizeof(stRVA) && (clData_CheckBit(&d,32)&0x7F7F7F7F)==0x72766100){/*'rva\0'*/ - union { unsigned int i; float f; } v; - clData_AddBit(&d,32); - v.i=clData_GetBit(&d,32); - _rva_volume=v.f; - printf("相対ボリューム調節: %g倍\n",_rva_volume); - size-=(32+32)/8; - } - - // comm - if(size>=5 && (clData_CheckBit(&d,32)&0x7F7F7F7F)==0x636F6D6D){/*'comm'*/ - int i; - clData_AddBit(&d,32); - _comm_len=clData_GetBit(&d,8); - _comm_comment=malloc(_comm_len+1); - for(i=0;i<_comm_len;++i)_comm_comment[i]=clData_GetBit(&d,8); - _comm_comment[i]='\0'; - printf("コメント: %s\n",_comm_comment); - free(_comm_comment); - } - - free(data); - - // 閉じる - fclose(fp); - - return 0; -} -#endif - -//-------------------------------------------------- -// デコードしてWAVEファイルに保存 -//-------------------------------------------------- -#if 0 -static int clHCA_DecodeToWavefile_Decode(void *fp1,void *fp2,unsigned int address,unsigned int count,void *data,void *modeFunction); - -static void clHCA_DecodeToWavefile_DecodeModeFloat(float f,void *fp){fwrite(&f,sizeof(f),1,(FILE *)fp);} -static void clHCA_DecodeToWavefile_DecodeMode8bit(float f,void *fp){int v=(int)(f*0x7F)+0x80;fwrite(&v,1,1,(FILE *)fp);} -static void clHCA_DecodeToWavefile_DecodeMode16bit(float f,void *fp){int v=(int)(f*0x7FFF);fwrite(&v,2,1,(FILE *)fp);} -static void clHCA_DecodeToWavefile_DecodeMode24bit(float f,void *fp){int v=(int)(f*0x7FFFFF);fwrite(&v,3,1,(FILE *)fp);} -static void clHCA_DecodeToWavefile_DecodeMode32bit(float f,void *fp){int v=(int)(f*0x7FFFFFFF);fwrite(&v,4,1,(FILE *)fp);} - -static int clHCA_DecodeToWavefile(clHCA *hca,const char *filenameHCA,const char *filenameWAV,float volume,int mode,int loop){ - FILE *fp1; - FILE *fp2; - stHeader header; - unsigned char *data1; - unsigned char *data2; - struct stWAVEHeader{ - char riff[4]; - unsigned int riffSize; - char wave[4]; - char fmt[4]; - unsigned int fmtSize; - unsigned short fmtType; - unsigned short fmtChannelCount; - unsigned int fmtSamplingRate; - unsigned int fmtSamplesPerSec; - unsigned short fmtSamplingSize; - unsigned short fmtBitCount; - }wavRiff={'R','I','F','F',0,'W','A','V','E','f','m','t',' ',ret_le32(0x10),0,0,0,0,0,0}; - struct stWAVEsmpl{ - char smpl[4]; - unsigned int smplSize; - unsigned int manufacturer; - unsigned int product; - unsigned int samplePeriod; - unsigned int MIDIUnityNote; - unsigned int MIDIPitchFraction; - unsigned int SMPTEFormat; - unsigned int SMPTEOffset; - unsigned int sampleLoops; - unsigned int samplerData; - unsigned int loop_Identifier; - unsigned int loop_Type; - unsigned int loop_Start; - unsigned int loop_End; - unsigned int loop_Fraction; - unsigned int loop_PlayCount; - }wavSmpl={'s','m','p','l',ret_le32(0x3C),0,0,0,ret_le32(0x3C),0,0,0,ret_le32(1),ret_le32(0x18),0,0,0,0,0,0}; - struct stWAVEnote{ - char note[4]; - unsigned int noteSize; - unsigned int dwName; - }wavNote={'n','o','t','e',0,0}; - struct stWAVEdata{ - char data[4]; - unsigned int dataSize; - }wavData={'d','a','t','a',0}; - - // チェック - if(!(filenameHCA&&filenameWAV&&(mode==0||mode==8||mode==16||mode==24||mode==32)&&loop>=0))return -1; - - // HCAファイルを開く - if((fp1 = fopen(filenameHCA,"rb")) == NULL)return -1; - - // ヘッダチェック - memset(&header,0,sizeof(header)); - fread(&header,sizeof(header),1,fp1); - if(!CheckFile(&header,sizeof(header))){fclose(fp1);return -1;} - - // ヘッダ解析 - header.dataOffset=get_be16(header.dataOffset); - data1=(unsigned char*) malloc(header.dataOffset); - if(!data1){fclose(fp1);return -1;} - fseek(fp1,0,SEEK_SET); - fread(data1,header.dataOffset,1,fp1); - if(clHCA_Decode(cl,data1,header.dataOffset,0) < 0){free(data1);fclose(fp1);return -1;} - - // WAVEファイルを開く - if((fp2 = fopen(filenameWAV,"wb")) == NULL){free(data1);fclose(fp1);return -1;} - - // WAVEヘッダを書き込み - wavRiff.fmtType=ret_le16((mode>0)?1:3); - wavRiff.fmtChannelCount=ret_le16(hca->_channelCount); - wavRiff.fmtBitCount=ret_le16((mode>0)?mode:32); - wavRiff.fmtSamplingRate=ret_le32(hca->_samplingRate); - wavRiff.fmtSamplingSize=ret_le16(wavRiff.fmtBitCount/8*wavRiff.fmtChannelCount); - wavRiff.fmtSamplesPerSec=ret_le32(wavRiff.fmtSamplingRate*wavRiff.fmtSamplingSize); - if(hca->_loopFlg){ - wavSmpl.samplePeriod=ret_le32((unsigned int)(1/(double)wavRiff.fmtSamplingRate*1000000000)); - wavSmpl.loop_Start=ret_le32(hca->_loopStart*0x80*8*wavRiff.fmtSamplingSize); - wavSmpl.loop_End=ret_le32(hca->_loopEnd*0x80*8*wavRiff.fmtSamplingSize); - wavSmpl.loop_PlayCount=ret_le32((hca->_loop_r01==0x80)?0:hca->_loop_r01); - }else if(loop){ - wavSmpl.loop_Start=0; - wavSmpl.loop_End=ret_le32(hca->_blockCount*0x80*8*wavRiff.fmtSamplingSize); - hca->_loopStart=0; - hca->_loopEnd=hca->_blockCount; - } - if(_comm_comment){ - unsigned int noteSize=4+hca->_comm_len+1; - if(noteSize&3)noteSize+=4-(noteSize&3); - waveNote.noteSize=ret_le32(noteSize); - } - wavData.dataSize=ret_le32(hca->_blockCount*0x80*8*wavRiff.fmtSamplingSize+(wavSmpl.loop_End-wavSmpl.loop_Start)*loop); - wavRiff.riffSize=ret_le32(0x1C+((hca->_loopFlg&&!loop)?sizeof(wavSmpl):0)+(hca->_comm_comment?8+wavNote.noteSize:0)+sizeof(wavData)+wavData.dataSize); - fwrite(&wavRiff,sizeof(wavRiff),1,fp2); - if(hca->_loopFlg&&!loop)fwrite(&wavSmpl,sizeof(wavSmpl),1,fp2); - if(hca->_comm_comment){ - int address=ftell(fp2); - fwrite(&wavNote,sizeof(wavNote),1,fp2); - fputs(hca->_comm_comment,fp2); - fseek(fp2,address+8+wavNote.noteSize,SEEK_SET); - } - fwrite(&wavData,sizeof(wavData),1,fp2); - - // 相対ボリュームを調節 - hca->_rva_volume*=volume; - - // デコード - void *modeFunction; - switch(mode){ - case 0:modeFunction=(void *)clHCA_DecodeToWavefile_DecodeModeFloat;break; - case 8:modeFunction=(void *)clHCA_DecodeToWavefile_DecodeMode8bit;break; - case 16:modeFunction=(void *)clHCA_DecodeToWavefile_DecodeMode16bit;break; - case 24:modeFunction=(void *)clHCA_DecodeToWavefile_DecodeMode24bit;break; - case 32:modeFunction=(void *)clHCA_DecodeToWavefile_DecodeMode32bit;break; - } - data2=(unsigned char*) malloc(_blockSize); - if(!data2){free(data1);fclose(fp2);fclose(fp1);return -1;} - if(!loop){ - if(clHCA_DecodeToWavefile_Decode(cl,fp1,fp2,_dataOffset,_blockCount,data2,modeFunction) < 0){free(data2);free(data1);fclose(fp2);fclose(fp1);return -1;} - }else{ - unsigned int loopBlockOffset=hca->_dataOffset+hca->_loopStart*hca->_blockSize; - unsigned int loopBlockCount=hca->_loopEnd-hca->_loopStart; - int i; - if(clHCA_DecodeToWavefile_Decode(cl,fp1,fp2,_dataOffset,_loopEnd,data2,modeFunction) < 0){free(data2);free(data1);fclose(fp2);fclose(fp1);return -1;} - for(i=1;i_blockSize,1,(FILE *)fp1); - if(clHCA_Decode(cl,data,hca->_blockSize,address) < 0)return -1; - for(i=0;i<8;i++){ - for(j=0;j<0x80;j++){ - for(k=0,m=hca->_channelCount;k_rva_volume; - if(f>1){f=1;}else if(f<-1){f=-1;} - ((void (*)(float,void *))modeFunction)(f,fp2); - } - } - } - } - return 0; -} -#endif - //-------------------------------------------------- // Decoder utilities //-------------------------------------------------- +#if 0 +static int clHCA_CheckFile(void *data, unsigned int size) { + return (data&&size>=4&&(get_be32(*(unsigned int *)data) & HCA_MASK) == 0x48434100);/*'HCA\0'*/ +} +#endif -int clHCA_isOurFile0(const void *data){ - clData d; - clData_constructor(&d, data, 8); - if((clData_CheckBit(&d,32)&0x7F7F7F7F)==0x48434100){/*'HCA\0'*/ - clData_AddBit(&d,32+16); - return clData_CheckBit(&d,16); - } - return -1; +int clHCA_isOurFile0(const void *data) { + clData br; + if (!data) + return -1; + + bitreader_init(&br, data, 8); + if ((bitreader_check(&br, 32) & HCA_MASK) == 0x48434100) {/*'HCA\0'*/ + bitreader_skip(&br, 32 + 16); + return bitreader_check(&br, 16); + } + return -1; } -int clHCA_isOurFile1(const void *data, unsigned int size){ - int minsize; - if (size<8)return -1; - minsize = clHCA_isOurFile0(data); - if (minsize < 0 || (unsigned int)minsize > size)return -1; - if (clHCA_CheckSum(data, minsize, 0))return -1; - return 0; +int clHCA_isOurFile1(const void *data, unsigned int size) { + int minsize; + if (!data || size < 8) + return -1; + minsize = clHCA_isOurFile0(data); + if (minsize < 0 || (unsigned int) minsize > size) + return -1; + if (crc16_checksum(data, minsize)) + return -1; + return 0; } -int clHCA_getInfo(clHCA *hca, clHCA_stInfo *info){ - if (!hca->_validFile)return -1; - info->version=hca->_version; - info->dataOffset=hca->_dataOffset; - info->samplingRate=hca->_samplingRate; - info->channelCount=hca->_channelCount; - info->blockSize=hca->_blockSize; - info->blockCount=hca->_blockCount; - info->loopEnabled=hca->_loopFlg; - info->loopStartBlock=hca->_loopStart; - info->loopEndBlock=hca->_loopEnd; - info->loopStartDelay=hca->_loop_r01; - info->loopEndPadding=hca->_loop_r02; - info->encoderDelay=hca->_fmt_r01; - info->encoderPadding=hca->_fmt_r02; - info->samplesPerBlock = 0x80 * 8; - info->comment=hca->_comm_comment; - return 0; +int clHCA_getInfo(clHCA *hca, clHCA_stInfo *info) { + if (!hca || !info || !hca->is_valid) + return -1; + + info->version = hca->version; + info->dataOffset = hca->header_size; + info->samplingRate = hca->sample_rate; + info->channelCount = hca->channels; + info->blockSize = hca->frame_size; + info->blockCount = hca->frame_count; + info->loopEnabled = hca->loop_flag; + info->loopStartBlock = hca->loop_start_frame; + info->loopEndBlock = hca->loop_end_frame; + info->loopStartDelay = hca->loop_start_delay; + info->loopEndPadding = hca->loop_end_padding; + info->encoderDelay = hca->encoder_delay; + info->encoderPadding = hca->encoder_padding; + info->samplesPerBlock = HCA_SAMPLES_PER_FRAME; + info->comment = hca->comment; + return 0; } -void clHCA_DecodeSamples16(clHCA *hca,signed short *samples){ - const float scale = 32768.0f; - float f; - signed int s; - int i, j; - unsigned int k, l; - //const float _rva_volume=hca->_rva_volume; - for(i=0;i<8;i++){ - for(j=0;j<0x80;j++){ - for(k=0,l=hca->_channelCount;k_channel[k].wave[i][j]/**_rva_volume*/; - if(f>1){f=1;}else if(f<-1){f=-1;} - s=(signed int)(f*scale); - if ((unsigned)(s+0x8000)&0xFFFF0000)s=(s>>31)^0x7FFF; - *samples++=(signed short)s; - } - } - } +void clHCA_DecodeSamples16(clHCA *hca, signed short *samples) { + const float scale = 32768.0f; + float f; + signed int s; + int i, j, k; + + for (i = 0; i < HCA_SUBFRAMES_PER_FRAME; i++) { + for (j = 0; j < HCA_SAMPLES_PER_SUBFRAME; j++) { + for (k = 0; k < hca->channels; k++) { + f = hca->channel[k].wave[i][j]; + //f = f * hca->rva_volume; /* rare, won't apply for now */ + if (f > 1) { + f = 1; + } else if (f < -1) { + f = -1; + } + s = (signed int) (f * scale); + if ((unsigned) (s + 0x8000) & 0xFFFF0000) + s = (s >> 31) ^ 0x7FFF; + *samples++ = (signed short) s; + } + } + } } + //-------------------------------------------------- // Allocation and creation //-------------------------------------------------- - -int clHCA_sizeof(){ - return sizeof(clHCA); +static void clHCA_constructor(clHCA *hca, unsigned int key_lower, unsigned int key_upper) { + memset(hca, 0, sizeof(*hca)); + hca->ciph_key_u = key_upper; + hca->ciph_key_l = key_lower; + hca->is_valid = 0; + hca->comment = 0; } -void clHCA_clear(clHCA *hca,unsigned int ciphKey1,unsigned int ciphKey2){ - clHCA_constructor(hca,ciphKey1,ciphKey2); +static void clHCA_destructor(clHCA *hca) { + free(hca->comment); + hca->comment = 0; } -void clHCA_done(clHCA *hca) -{ - clHCA_destructor(hca); +int clHCA_sizeof() { + return sizeof(clHCA); } -clHCA * clHCA_new(unsigned int ciphKey1, unsigned int ciphKey2){ - clHCA *hca = (clHCA *) malloc(clHCA_sizeof()); - if (hca){ - clHCA_constructor(hca,ciphKey1,ciphKey2); - } - return hca; +void clHCA_clear(clHCA *hca, unsigned int ciphKey1, unsigned int ciphKey2) { + clHCA_constructor(hca, ciphKey1, ciphKey2); } -void clHCA_delete(clHCA *hca){ - if (hca){ - clHCA_destructor(hca); - free(hca); - } +void clHCA_done(clHCA *hca) { + clHCA_destructor(hca); } +clHCA * clHCA_new(unsigned int ciphKey1, unsigned int ciphKey2) { + clHCA *hca = (clHCA *) malloc(clHCA_sizeof()); + if (hca) { + clHCA_constructor(hca, ciphKey1, ciphKey2); + } + return hca; +} + +void clHCA_delete(clHCA *hca) { + if (hca) { + clHCA_destructor(hca); + free(hca); + } +} + + //-------------------------------------------------- // ATH //-------------------------------------------------- -static void clATH_Init0(clATH *ath); -static void clATH_Init1(clATH *ath,unsigned int key); - -void clATH_constructor(clATH *ath){ - memset(ath,0,sizeof(*ath)); - clATH_Init0(ath); -} - -static int clATH_Init(clATH *ath,int type,unsigned int key){ - switch(type){ - case 0:clATH_Init0(ath);break; - case 1:clATH_Init1(ath,key);break; - default:return -1; - } - return 0; -} - -static const unsigned char * clATH_GetTable(clATH *ath){ - return ath->_table; -} - -void clATH_Init0(clATH *ath){ - memset(ath->_table,0,sizeof(ath->_table)); -} - -static const unsigned char clATH_list[]={ - 0x78,0x5F,0x56,0x51,0x4E,0x4C,0x4B,0x49,0x48,0x48,0x47,0x46,0x46,0x45,0x45,0x45, - 0x44,0x44,0x44,0x44,0x43,0x43,0x43,0x43,0x43,0x43,0x42,0x42,0x42,0x42,0x42,0x42, - 0x42,0x42,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x40,0x40,0x40,0x40, - 0x40,0x40,0x40,0x40,0x40,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F, - 0x3F,0x3F,0x3F,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D, - 0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B, - 0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B, - 0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C, - 0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3F, - 0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F, - 0x3F,0x3F,0x3F,0x3F,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40, - 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x41,0x41,0x41,0x41,0x41,0x41,0x41, - 0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41, - 0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42, - 0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x43,0x43,0x43, - 0x43,0x43,0x43,0x43,0x43,0x43,0x43,0x43,0x43,0x43,0x43,0x43,0x43,0x43,0x44,0x44, - 0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x45,0x45,0x45,0x45, - 0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x46, - 0x46,0x46,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x48,0x48,0x48,0x48, - 0x48,0x48,0x48,0x48,0x49,0x49,0x49,0x49,0x49,0x49,0x49,0x49,0x4A,0x4A,0x4A,0x4A, - 0x4A,0x4A,0x4A,0x4A,0x4B,0x4B,0x4B,0x4B,0x4B,0x4B,0x4B,0x4C,0x4C,0x4C,0x4C,0x4C, - 0x4C,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4E,0x4E,0x4E,0x4E,0x4E,0x4E,0x4F,0x4F,0x4F, - 0x4F,0x4F,0x4F,0x50,0x50,0x50,0x50,0x50,0x51,0x51,0x51,0x51,0x51,0x52,0x52,0x52, - 0x52,0x52,0x53,0x53,0x53,0x53,0x54,0x54,0x54,0x54,0x54,0x55,0x55,0x55,0x55,0x56, - 0x56,0x56,0x56,0x57,0x57,0x57,0x57,0x57,0x58,0x58,0x58,0x59,0x59,0x59,0x59,0x5A, - 0x5A,0x5A,0x5A,0x5B,0x5B,0x5B,0x5B,0x5C,0x5C,0x5C,0x5D,0x5D,0x5D,0x5D,0x5E,0x5E, - 0x5E,0x5F,0x5F,0x5F,0x60,0x60,0x60,0x61,0x61,0x61,0x61,0x62,0x62,0x62,0x63,0x63, - 0x63,0x64,0x64,0x64,0x65,0x65,0x66,0x66,0x66,0x67,0x67,0x67,0x68,0x68,0x68,0x69, - 0x69,0x6A,0x6A,0x6A,0x6B,0x6B,0x6B,0x6C,0x6C,0x6D,0x6D,0x6D,0x6E,0x6E,0x6F,0x6F, - 0x70,0x70,0x70,0x71,0x71,0x72,0x72,0x73,0x73,0x73,0x74,0x74,0x75,0x75,0x76,0x76, - 0x77,0x77,0x78,0x78,0x78,0x79,0x79,0x7A,0x7A,0x7B,0x7B,0x7C,0x7C,0x7D,0x7D,0x7E, - 0x7E,0x7F,0x7F,0x80,0x80,0x81,0x81,0x82,0x83,0x83,0x84,0x84,0x85,0x85,0x86,0x86, - 0x87,0x88,0x88,0x89,0x89,0x8A,0x8A,0x8B,0x8C,0x8C,0x8D,0x8D,0x8E,0x8F,0x8F,0x90, - 0x90,0x91,0x92,0x92,0x93,0x94,0x94,0x95,0x95,0x96,0x97,0x97,0x98,0x99,0x99,0x9A, - 0x9B,0x9B,0x9C,0x9D,0x9D,0x9E,0x9F,0xA0,0xA0,0xA1,0xA2,0xA2,0xA3,0xA4,0xA5,0xA5, - 0xA6,0xA7,0xA7,0xA8,0xA9,0xAA,0xAA,0xAB,0xAC,0xAD,0xAE,0xAE,0xAF,0xB0,0xB1,0xB1, - 0xB2,0xB3,0xB4,0xB5,0xB6,0xB6,0xB7,0xB8,0xB9,0xBA,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, - 0xC0,0xC1,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xC9,0xCA,0xCB,0xCC,0xCD, - 0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD, - 0xDE,0xDF,0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xED,0xEE, - 0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFF,0xFF, +/* Base ATH (Absolute Threshold of Hearing) curve (for 41856hz). + * May be a slight modification of the standard Painter & Spanias ATH curve formula. */ +static const unsigned char ath_base_curve[656] = { + 0x78,0x5F,0x56,0x51,0x4E,0x4C,0x4B,0x49,0x48,0x48,0x47,0x46,0x46,0x45,0x45,0x45, + 0x44,0x44,0x44,0x44,0x43,0x43,0x43,0x43,0x43,0x43,0x42,0x42,0x42,0x42,0x42,0x42, + 0x42,0x42,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x40,0x40,0x40,0x40, + 0x40,0x40,0x40,0x40,0x40,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F, + 0x3F,0x3F,0x3F,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D, + 0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B, + 0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B, + 0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C, + 0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,0x3D,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3E,0x3F, + 0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F, + 0x3F,0x3F,0x3F,0x3F,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40, + 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x41,0x41,0x41,0x41,0x41,0x41,0x41, + 0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41, + 0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42, + 0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x43,0x43,0x43, + 0x43,0x43,0x43,0x43,0x43,0x43,0x43,0x43,0x43,0x43,0x43,0x43,0x43,0x43,0x44,0x44, + 0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x45,0x45,0x45,0x45, + 0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x46, + 0x46,0x46,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x48,0x48,0x48,0x48, + 0x48,0x48,0x48,0x48,0x49,0x49,0x49,0x49,0x49,0x49,0x49,0x49,0x4A,0x4A,0x4A,0x4A, + 0x4A,0x4A,0x4A,0x4A,0x4B,0x4B,0x4B,0x4B,0x4B,0x4B,0x4B,0x4C,0x4C,0x4C,0x4C,0x4C, + 0x4C,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4E,0x4E,0x4E,0x4E,0x4E,0x4E,0x4F,0x4F,0x4F, + 0x4F,0x4F,0x4F,0x50,0x50,0x50,0x50,0x50,0x51,0x51,0x51,0x51,0x51,0x52,0x52,0x52, + 0x52,0x52,0x53,0x53,0x53,0x53,0x54,0x54,0x54,0x54,0x54,0x55,0x55,0x55,0x55,0x56, + 0x56,0x56,0x56,0x57,0x57,0x57,0x57,0x57,0x58,0x58,0x58,0x59,0x59,0x59,0x59,0x5A, + 0x5A,0x5A,0x5A,0x5B,0x5B,0x5B,0x5B,0x5C,0x5C,0x5C,0x5D,0x5D,0x5D,0x5D,0x5E,0x5E, + 0x5E,0x5F,0x5F,0x5F,0x60,0x60,0x60,0x61,0x61,0x61,0x61,0x62,0x62,0x62,0x63,0x63, + 0x63,0x64,0x64,0x64,0x65,0x65,0x66,0x66,0x66,0x67,0x67,0x67,0x68,0x68,0x68,0x69, + 0x69,0x6A,0x6A,0x6A,0x6B,0x6B,0x6B,0x6C,0x6C,0x6D,0x6D,0x6D,0x6E,0x6E,0x6F,0x6F, + 0x70,0x70,0x70,0x71,0x71,0x72,0x72,0x73,0x73,0x73,0x74,0x74,0x75,0x75,0x76,0x76, + 0x77,0x77,0x78,0x78,0x78,0x79,0x79,0x7A,0x7A,0x7B,0x7B,0x7C,0x7C,0x7D,0x7D,0x7E, + 0x7E,0x7F,0x7F,0x80,0x80,0x81,0x81,0x82,0x83,0x83,0x84,0x84,0x85,0x85,0x86,0x86, + 0x87,0x88,0x88,0x89,0x89,0x8A,0x8A,0x8B,0x8C,0x8C,0x8D,0x8D,0x8E,0x8F,0x8F,0x90, + 0x90,0x91,0x92,0x92,0x93,0x94,0x94,0x95,0x95,0x96,0x97,0x97,0x98,0x99,0x99,0x9A, + 0x9B,0x9B,0x9C,0x9D,0x9D,0x9E,0x9F,0xA0,0xA0,0xA1,0xA2,0xA2,0xA3,0xA4,0xA5,0xA5, + 0xA6,0xA7,0xA7,0xA8,0xA9,0xAA,0xAA,0xAB,0xAC,0xAD,0xAE,0xAE,0xAF,0xB0,0xB1,0xB1, + 0xB2,0xB3,0xB4,0xB5,0xB6,0xB6,0xB7,0xB8,0xB9,0xBA,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, + 0xC0,0xC1,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xC9,0xCA,0xCB,0xCC,0xCD, + 0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD, + 0xDE,0xDF,0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xED,0xEE, + 0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFF,0xFF, }; -void clATH_Init1(clATH *ath, unsigned int key){ - unsigned int i, v; - unsigned char *_table=ath->_table; - for(i=0,v=0;i<0x80;i++,v+=key){ - unsigned int index=v>>13; - if(index>=0x28E){ - memset(&_table[i],0xFF,0x80-i); - break; - } - _table[i]=clATH_list[index]; - } +static void ath_init0(unsigned char *ath_table) { + /* disable curve */ + memset(ath_table, 0, HCA_SAMPLES_PER_SUBFRAME); +} + +static void ath_init1(unsigned char *ath_curve, unsigned int sample_rate) { + unsigned int i, index; + unsigned int acc = 0; + + /* scale ATH curve depending on frequency */ + for (i = 0; i < HCA_SAMPLES_PER_SUBFRAME; i++, acc += sample_rate) { //todo add accumulator before to fix ATH + index = acc >> 13; + + if (index >= 654) { + memset(ath_curve+i, 0xFF, 0x80 - i); + break; + } + ath_curve[i] = ath_base_curve[index]; + } +} + +static int ath_init(unsigned char *ath_curve, int type, unsigned int sample_rate) { + switch (type) { + case 0: + ath_init0(ath_curve); + break; + case 1: + ath_init1(ath_curve, sample_rate); + break; + default: + return -1; + } + return 0; +} + + +//-------------------------------------------------- +// Encryption +//-------------------------------------------------- +static void cipher_decrypt(unsigned char *cipher_table, unsigned char *data, int size) { +#if HCA_DISABLE_OPTIMIZATIONS + unsigned int i; + for (i = 0; i < size; i++) { + data[i] = cipher_table[data[i]]; + } +#else + unsigned char *data_ = data; + for (data_ = (unsigned char *) data; size > 0; data_++, size--) { + *data_ = cipher_table[*data_]; + } +#endif +} + +static void cipher_init0(unsigned char *cipher_table) { + unsigned int i; + + /* no encryption */ + for (i = 0; i < 256; i++) { + cipher_table[i] = i; + } +} + +static void cipher_init1(unsigned char *cipher_table) { + const int mul = 13; + const int add = 11; + unsigned int i, v = 0; + + /* keyless encryption (unused?) */ + for (i = 1; i < 256 - 1; i++) { + v = (v * mul + add) & 0xFF; + if (v == 0 || v == 0xFF) + v = (v * mul + add) & 0xFF; + cipher_table[i] = v; + } + cipher_table[0] = 0; + cipher_table[0xFF] = 0xFF; +} + +static void cipher_init56_create_table(unsigned char *r, unsigned char key) { + const int mul = ((key & 1) << 3) | 5; + const int add = (key & 0xE) | 1; + unsigned int i; + + key >>= 4; + for (i = 0; i < 16; i++) { + key = (key * mul + add) & 0xF; + r[i] = key; + } +} + +static void cipher_init56(unsigned char *cipher_table, unsigned int keycode_lower, unsigned int keycode_upper) { + unsigned char kc[8]; + unsigned char seed[16]; + unsigned char base[256], base_r[16], base_c[16]; + unsigned int r, c; + + unsigned long long keycode = ((long long)keycode_upper << 32) | keycode_lower; + + /* 56bit keycode encryption (given as a uint64_t number, but upper 8b aren't used) */ + + /* keycode = keycode - 1 */ + if (keycode != 0) + keycode--; + + /* init keycode table */ + for (r = 0; r < (8-1); r++) { + kc[r] = keycode & 0xFF; + keycode = keycode >> 8; + } + + /* init seed table */ + seed[0x00] = kc[1]; + seed[0x01] = kc[1] ^ kc[6]; + seed[0x02] = kc[2] ^ kc[3]; + seed[0x03] = kc[2]; + seed[0x04] = kc[2] ^ kc[1]; + seed[0x05] = kc[3] ^ kc[4]; + seed[0x06] = kc[3]; + seed[0x07] = kc[3] ^ kc[2]; + seed[0x08] = kc[4] ^ kc[5]; + seed[0x09] = kc[4]; + seed[0x0A] = kc[4] ^ kc[3]; + seed[0x0B] = kc[5] ^ kc[6]; + seed[0x0C] = kc[5]; + seed[0x0D] = kc[5] ^ kc[4]; + seed[0x0E] = kc[6] ^ kc[1]; + seed[0x0F] = kc[6]; + + /* init base table */ + cipher_init56_create_table(base_r, kc[0]); + for (r = 0; r < 16; r++) { + unsigned char nb; + cipher_init56_create_table(base_c, seed[r]); + nb = base_r[r] << 4; + for (c = 0; c < 16; c++) { + base[r*16 + c] = nb | base_c[c]; /* combine nibbles */ + } + } + + /* final shuffle table */ + { + unsigned int i; + unsigned int x = 0; + unsigned int pos = 1; + + for (i = 0; i < 256; i++) { + x = (x + 17) & 0xFF; + if (base[x] != 0 && base[x] != 0xFF) + cipher_table[pos++] = base[x]; + } + cipher_table[0] = 0; + cipher_table[0xFF] = 0xFF; + } +} + +static int cipher_init(unsigned char *cipher_table, int type, unsigned int keycode_lower, unsigned int keycode_upper) { + if (!(keycode_upper | keycode_lower)) + type = 0; + + switch (type) { + case 0: + cipher_init0(cipher_table); + break; + case 1: + cipher_init1(cipher_table); + break; + case 56: + cipher_init56(cipher_table, keycode_lower, keycode_upper); + break; + default: + return -1; + } + return 0; } //-------------------------------------------------- -// 暗号化テーブル +// Parse //-------------------------------------------------- -static void clCipher_Init0(clCipher *cipher); -static void clCipher_Init1(clCipher *cipher); -static void clCipher_Init56(clCipher *cipher,unsigned int key1,unsigned int key2); - -void clCipher_constructor(clCipher *cipher){ - memset(cipher,0,sizeof(*cipher)); - clCipher_Init0(cipher); +static inline unsigned int header_ceil2(unsigned int a, unsigned int b) { + return (b > 0) ? (a / b + ((a % b) ? 1 : 0)) : 0; } -static int clCipher_Init(clCipher *cipher,int type,unsigned int key1,unsigned int key2){ - if(!(key1|key2))type=0; - switch(type){ - case 0:clCipher_Init0(cipher);break; - case 1:clCipher_Init1(cipher);break; - case 56:clCipher_Init56(cipher,key1,key2);break; - default:return -1; - } - return 0; -} -static void clCipher_Mask(clCipher *cipher,void *data,int size){ - unsigned char *_table=cipher->_table; - unsigned char *d; - for(d=(unsigned char *)data;size>0;d++,size--)*d=_table[*d]; -} +static int clHCA_DecodeHeader(clHCA *hca, void *data, unsigned int size) { + clData br; -void clCipher_Init0(clCipher *cipher){ - unsigned char *_table=cipher->_table; - int i; - for(i=0;i<0x100;i++)_table[i]=i; -} + if (!hca || !data ) + return -1; -void clCipher_Init1(clCipher *cipher){ - unsigned char *_table=cipher->_table; - int i, v; - for(i=1,v=0;i<0xFF;i++){ - v=(v*13+11)&0xFF; - if(v==0||v==0xFF)v=(v*13+11)&0xFF; - _table[i]=v; - } - _table[0]=0; - _table[0xFF]=0xFF; -} + hca->is_valid = 0; -static void clCipher_Init56_CreateTable(unsigned char *r,unsigned char key); + if (size < sizeof(stHeader)) + return -1; -void clCipher_Init56(clCipher *cipher,unsigned int key1,unsigned int key2){ - unsigned char *_table=cipher->_table; + bitreader_init(&br, data, size); - // テーブル1を生成 - unsigned char t1[8]; - unsigned char t2[0x10]; - unsigned char t3[0x100],t31[0x10],t32[0x10],*t; + /* read header chunks */ - int i, j, v; + /* HCA base header */ + if ((bitreader_check(&br, 32) & HCA_MASK) == 0x48434100) { /* "HCA\0" */ + bitreader_skip(&br, 32); + hca->version = bitreader_read(&br, 16); + hca->header_size = bitreader_read(&br, 16); - if(!key1)key2--; - key1--; - for(i=0;i<7;i++){ - t1[i]=key1; - key1=(key1>>8)|(key2<<24); - key2>>=8; - } +#if 0 // play unknown versions anyway (confirmed to exist: v1.1/v1.2/v1.3/v2.0) + if (hca->version != 0x0101 && + hca->version != 0x0102 && + hca->version != 0x0103 && + hca->version != 0x0200) + return -1; +#endif + if (size < hca->header_size) + return -1; - // テーブル2 - t2[0x00]=t1[1]; t2[0x01]=t1[1]^t1[6]; - t2[0x02]=t1[2]^t1[3]; t2[0x03]=t1[2]; - t2[0x04]=t1[2]^t1[1]; t2[0x05]=t1[3]^t1[4]; - t2[0x06]=t1[3]; t2[0x07]=t1[3]^t1[2]; - t2[0x08]=t1[4]^t1[5]; t2[0x09]=t1[4]; - t2[0x0A]=t1[4]^t1[3]; t2[0x0B]=t1[5]^t1[6]; - t2[0x0C]=t1[5]; t2[0x0D]=t1[5]^t1[4]; - t2[0x0E]=t1[6]^t1[1]; t2[0x0F]=t1[6]; + if (crc16_checksum(data,hca->header_size)) + return -1; - // テーブル3 - t=t3; - clCipher_Init56_CreateTable(t31,t1[0]); - for(i=0;i<0x10;i++){ - unsigned char v; - clCipher_Init56_CreateTable(t32,t2[i]); - v=t31[i]<<4; - for(j=0;j<0x10;j++){ - *(t++)=v|t32[j]; - } - } + size -= sizeof(stHeader); + } + else { + return -1; + } - // CIPHテーブル - t=&_table[1]; - for(i=0,v=0;i<0x100;i++){ - unsigned char a; - v=(v+0x11)&0xFF; - a=t3[v]; - if(a!=0&&a!=0xFF)*(t++)=a; - } - _table[0]=0; - _table[0xFF]=0xFF; + /* format info */ + if (size >= sizeof(stFormat) && (bitreader_check(&br, 32) & HCA_MASK) == 0x666D7400) { /* "fmt\0" */ + bitreader_skip(&br, 32); + hca->channels = bitreader_read(&br, 8); + hca->sample_rate = bitreader_read(&br, 24); + hca->frame_count = bitreader_read(&br, 32); + hca->encoder_delay = bitreader_read(&br, 16); + hca->encoder_padding = bitreader_read(&br, 16); -} + if (!(hca->channels >= 1 && hca->channels <= HCA_MAX_CHANNELS)) + return -1; -void clCipher_Init56_CreateTable(unsigned char *r,unsigned char key){ - int mul=((key&1)<<3)|5; - int add=(key&0xE)|1; - int i; - key>>=4; - for(i=0;i<0x10;i++){ - key=(key*mul+add)&0xF; - *(r++)=key; - } + if (hca->frame_count == 0) + return -1; + + if (!(hca->sample_rate >= 1 && hca->sample_rate <= 0x7FFFFF)) /* encoder max seems 48000 */ + return -1; + + size -= sizeof(stFormat); + } + else { + return -1; + } + + /* compression (v2.0) or decode (v1.x) info */ + if (size >= sizeof(stCompress) && (bitreader_check(&br, 32) & HCA_MASK) == 0x636F6D70) { /* "comp" */ + bitreader_skip(&br, 32); + hca->frame_size = bitreader_read(&br, 16); + hca->min_resolution = bitreader_read(&br, 8); + hca->max_resolution = bitreader_read(&br, 8); + hca->track_count = bitreader_read(&br, 8); + hca->channel_config = bitreader_read(&br, 8); + hca->total_band_count = bitreader_read(&br, 8); + hca->base_band_count = bitreader_read(&br, 8); + hca->stereo_band_count = bitreader_read(&br, 8); + hca->bands_per_hfr_group = bitreader_read(&br, 8); + hca->reserved1 = bitreader_read(&br, 8); + hca->reserved2 = bitreader_read(&br, 8); + + size -= sizeof(stCompress); + } + else if (size >= sizeof(stDecode) && (bitreader_check(&br, 32) & HCA_MASK) == 0x64656300) { /* "dec\0" */ + bitreader_skip(&br, 32); + hca->frame_size = bitreader_read(&br, 16); + hca->min_resolution = bitreader_read(&br, 8); + hca->max_resolution = bitreader_read(&br, 8); + hca->total_band_count = bitreader_read(&br, 8) + 1; + hca->base_band_count = bitreader_read(&br, 8) + 1; + hca->track_count = bitreader_read(&br, 4); + hca->channel_config = bitreader_read(&br, 4); + hca->stereo_type = bitreader_read(&br, 8); + + if (hca->stereo_type == 0) + hca->base_band_count = hca->total_band_count; + hca->stereo_band_count = hca->total_band_count - hca->base_band_count; + hca->bands_per_hfr_group = 0; + + size -= sizeof(stDecode); + } + else { + return -1; + } + + /* VBR (variable bit rate) info */ + if (size >= sizeof(stVBR) && (bitreader_check(&br, 32) & HCA_MASK) == 0x76627200) { /* "vbr\0" */ + bitreader_skip(&br, 32); + hca->vbr_max_frame_size = bitreader_read(&br, 16); + hca->vbr_noise_Level = bitreader_read(&br, 16); + + if (!(hca->frame_size == 0 && hca->vbr_max_frame_size > 8 && hca->vbr_max_frame_size <= 0x1FF)) + return -1; + + size -= sizeof(stVBR); + } + else { + /* removed in v2.0, probably unused in v1.x */ + hca->vbr_max_frame_size = 0; + hca->vbr_noise_Level = 0; + } + + /* ATH (Absolute Threshold of Hearing) info */ + if (size >= sizeof(stATH) && (bitreader_check(&br, 32) & HCA_MASK) == 0x61746800) { /* "ath\0" */ + bitreader_skip(&br, 32); + hca->ath_type = bitreader_read(&br, 16); + } + else { + /* removed? in v2.0, default in v1.x (maybe only ever used in v1.1) */ + hca->ath_type = (hca->version < 0x200) ? 1 : 0; + } + + /* loop info */ + if (size >= sizeof(stLoop) && (bitreader_check(&br, 32) & HCA_MASK) == 0x6C6F6F70) { /* "loop" */ + bitreader_skip(&br, 32); + hca->loop_start_frame = bitreader_read(&br, 32); + hca->loop_end_frame = bitreader_read(&br, 32); + hca->loop_start_delay = bitreader_read(&br, 16); + hca->loop_end_padding = bitreader_read(&br, 16); + + hca->loop_flag = 1; + + if (!(hca->loop_start_frame >= 0 && hca->loop_start_frame <= hca->loop_end_frame + && hca->loop_end_frame < hca->frame_count)) + return -1; + + size -= sizeof(stLoop); + } + else { + hca->loop_start_frame = 0; + hca->loop_end_frame = 0; + hca->loop_start_delay = 0; + hca->loop_end_padding = 0; + + hca->loop_flag = 0; + } + + /* cipher/encryption info */ + if (size >= sizeof(stCipher) && (bitreader_check(&br, 32) & HCA_MASK) == 0x63697068) { /* "ciph" */ + bitreader_skip(&br, 32); + hca->ciph_type = bitreader_read(&br, 16); + + if (!(hca->ciph_type == 0 || hca->ciph_type == 1 || hca->ciph_type == 56)) + return -1; + + size -= sizeof(stCipher); + } + else { + hca->ciph_type = 0; + } + + /* RVA (relative volume adjustment) info */ + if (size >= sizeof(stRVA) && (bitreader_check(&br, 32) & HCA_MASK) == 0x72766100) { /* "rva\0" */ + union { + unsigned int i; + float f; + } rva_volume_cast; + bitreader_skip(&br, 32); + rva_volume_cast.i = bitreader_read(&br, 32); + hca->rva_volume = rva_volume_cast.f; + + size -= sizeof(stRVA); + } else { + hca->rva_volume = 1; + } + + /* comment */ + if (size >= sizeof(stComment) && (bitreader_check(&br, 32) & HCA_MASK) == 0x636F6D6D) {/* "comm" */ + unsigned int i; + char *temp; + bitreader_skip(&br, 32); + hca->comment_len = bitreader_read(&br, 8); + + if (hca->comment_len > size) + return -1; + + temp = realloc(hca->comment, hca->comment_len + 1); + if (!temp) + return -1; + hca->comment = temp; + for (i = 0; i < hca->comment_len; ++i) + hca->comment[i] = bitreader_read(&br, 8); + hca->comment[i] = '\0'; /* should be null terminated but make sure */ + + size -= sizeof(stComment) + hca->comment_len; + } + else { + hca->comment_len = 0; + hca->comment = NULL; + } + + /* padding info */ + if (size >= sizeof(stPadding) && (bitreader_check(&br, 32) & HCA_MASK) == 0x70616400) { /* "pad\0" */ + size -= (size - 0x02); /* fills up to header_size, sans checksum */ + } + + /* fully read */ + if (size != 0x02) + return -1; + + + /* extra validations */ + if (!(hca->frame_size >= 0x08 && hca->frame_size <= 0xFFFF)) /* actual max seems 0x155*channels */ + return -1; /* theoretically can be 0 if VBR (not seen) */ + + if (!(hca->min_resolution == 1 && hca->max_resolution == 15)) + return -1; + + /* inits */ + if (hca->track_count == 0) + hca->track_count = 1; /* default to avoid division by zero */ + + if (ath_init(hca->ath_curve, hca->ath_type, hca->sample_rate) < 0) + return -1; + if (cipher_init(hca->cipher_table, hca->ciph_type, hca->ciph_key_l, hca->ciph_key_u) < 0) + return -1; + + hca->hfr_group_count = header_ceil2( + hca->total_band_count - hca->base_band_count - hca->stereo_band_count, + hca->bands_per_hfr_group); + + /* init channels */ + { + int channel_types[HCA_MAX_CHANNELS] = {0}; + unsigned int i, channels_per_track; + + channels_per_track = hca->channels / hca->track_count; + if (hca->stereo_band_count && channels_per_track > 1) { + int *ct = channel_types; + for (i = 0; i < hca->track_count; i++, ct += channels_per_track) { + switch (channels_per_track) { + case 2: + ct[0] = STEREO_PRIMARY; + ct[1] = STEREO_SECONDARY; + break; + case 3: + ct[0] = STEREO_PRIMARY; + ct[1] = STEREO_SECONDARY; + ct[2] = DISCRETE; + break; + case 4: + ct[0] = STEREO_PRIMARY; + ct[1] = 2; + if (hca->channel_config == 0) { + ct[2] = STEREO_PRIMARY; + ct[3] = STEREO_SECONDARY; + } else { + ct[2] = DISCRETE; + ct[3] = DISCRETE; + } + break; + case 5: + ct[0] = STEREO_PRIMARY; + ct[1] = STEREO_SECONDARY; + ct[2] = DISCRETE; + if (hca->channel_config <= 2) { + ct[3] = STEREO_PRIMARY; + ct[4] = STEREO_SECONDARY; + } else { + ct[3] = DISCRETE; + ct[4] = DISCRETE; + } + break; + case 6: + ct[0] = STEREO_PRIMARY; + ct[1] = STEREO_SECONDARY; + ct[2] = DISCRETE; + ct[3] = DISCRETE; + ct[4] = STEREO_PRIMARY; + ct[5] = STEREO_SECONDARY; + break; + case 7: + ct[0] = STEREO_PRIMARY; + ct[1] = STEREO_SECONDARY; + ct[2] = DISCRETE; + ct[3] = DISCRETE; + ct[4] = STEREO_PRIMARY; + ct[5] = STEREO_SECONDARY; + ct[6] = DISCRETE; + break; + case 8: + ct[0] = STEREO_PRIMARY; + ct[1] = STEREO_SECONDARY; + ct[2] = DISCRETE; + ct[3] = DISCRETE; + ct[4] = STEREO_PRIMARY; + ct[5] = STEREO_SECONDARY; + ct[6] = STEREO_PRIMARY; + ct[7] = STEREO_SECONDARY; + break; + } + } + } + + memset(hca->channel, 0, sizeof(hca->channel)); + for (i = 0; i < hca->channels; i++) { + hca->channel[i].type = channel_types[i]; + hca->channel[i].coded_scalefactor_count = (channel_types[i] != 2) ? + hca->base_band_count + hca->stereo_band_count : + hca->base_band_count; + hca->channel[i].hfr_scales = &hca->channel[i].scalefactors[hca->base_band_count + hca->stereo_band_count]; + } + } + + + hca->is_valid = 1; + + return 0; } //-------------------------------------------------- -// デコード +// Decode //-------------------------------------------------- -static void stChannel_Decode1(stChannel *ch,clData *data,unsigned int a,int b,const unsigned char *ath); -static void stChannel_Decode2(stChannel *ch,clData *data); -static void stChannel_Decode3(stChannel *ch,unsigned int a,unsigned int b,unsigned int c,unsigned int d); -static void stChannel_Decode4(stChannel *ch,int index,unsigned int a,unsigned int b,unsigned int c); -static void stChannel_Decode5(stChannel *ch,int index); +static void decode1_unpack_channel(stChannel *ch, clData *br, + unsigned int hfr_group_count, unsigned int packed_noise_level, const unsigned char *ath_curve); -int clHCA_Decode(clHCA *hca,void *data,unsigned int size,unsigned int address){ +static void decode2_dequantize_coefficients(stChannel *ch, clData *br); - // チェック - if(!(data))return -1; +static void decode3_reconstruct_high_frequency(stChannel *ch, + unsigned int hfr_group_count, unsigned int bands_per_hfr_group, + unsigned int stereo_band_count, unsigned int base_band_count, unsigned int total_band_count); - // ヘッダ - if(address==0){ - char r[0x10]; - unsigned int i, b; - clData d; +static void decode4_apply_intensity_stereo(stChannel *ch, int subframe, + unsigned int usable_band_count, unsigned int base_band_count, unsigned int stereo_band_count); - hca->_validFile = 0; +static void decoder5_run_imdct(stChannel *ch, int subframe); - clData_constructor(&d, data, size); - // サイズチェック - if(size_version=clData_GetBit(&d,16); - hca->_dataOffset=clData_GetBit(&d,16); - //if(!(_version<=0x200&&_version>0x101))return -1; // バージョンチェック(無効) - if(size_dataOffset)return -1; - //if(clHCA_CheckSum(hca,_dataOffset,0))return -1; // ヘッダの破損チェック(ヘッダ改変を有効にするため破損チェック無効) - size-=sizeof(stHeader); - }else{ - return -1; - } + if (!data || !hca || !hca->is_valid) + return -1; + if (size < hca->frame_size) + return -1; - // fmt - if(size>=sizeof(stFormat) && (clData_CheckBit(&d,32)&0x7F7F7F7F)==0x666D7400){/*'fmt\0'*/ - clData_AddBit(&d,32); - hca->_channelCount=clData_GetBit(&d,8); - hca->_samplingRate=clData_GetBit(&d,24); - hca->_blockCount=clData_GetBit(&d,32); - hca->_fmt_r01=clData_GetBit(&d,16); - hca->_fmt_r02=clData_GetBit(&d,16); - if(!(hca->_channelCount>=1&&hca->_channelCount<=16))return -1; - if(!(hca->_samplingRate>=1&&hca->_samplingRate<=0x7FFFFF))return -1; - size-=sizeof(stFormat); - }else{ - return -1; - } + bitreader_init(&br, data, hca->frame_size); - // comp - if(size>=sizeof(stCompress) && (clData_CheckBit(&d,32)&0x7F7F7F7F)==0x636F6D70){/*'comp'*/ - clData_AddBit(&d,32); - hca->_blockSize=clData_GetBit(&d,16); - hca->_comp_r01=clData_GetBit(&d,8); - hca->_comp_r02=clData_GetBit(&d,8); - hca->_comp_r03=clData_GetBit(&d,8); - hca->_comp_r04=clData_GetBit(&d,8); - hca->_comp_r05=clData_GetBit(&d,8); - hca->_comp_r06=clData_GetBit(&d,8); - hca->_comp_r07=clData_GetBit(&d,8); - hca->_comp_r08=clData_GetBit(&d,8); - clData_AddBit(&d,8+8); - if(!((hca->_blockSize>=8&&hca->_blockSize<=0xFFFF)||(hca->_blockSize==0)))return -1; - if(!(/*hca->_comp_r01>=0&&*/hca->_comp_r01<=hca->_comp_r02&&hca->_comp_r02<=0x1F))return -1; - size-=sizeof(stCompress); - } + /* test sync (not encrypted) */ + sync = bitreader_read(&br, 16); + if (sync != 0xFFFF) + return -1; - // dec - else if(size>=sizeof(stDecode) && (clData_CheckBit(&d,32)&0x7F7F7F7F)==0x64656300){/*'dec\0'*/ - unsigned char count1,count2,enableCount2; - clData_AddBit(&d,32); - hca->_blockSize=clData_GetBit(&d,16); - hca->_comp_r01=clData_GetBit(&d,8); - hca->_comp_r02=clData_GetBit(&d,8); - count1=clData_GetBit(&d,8); - count2=clData_GetBit(&d,8); - hca->_comp_r03=clData_GetBit(&d,4); - hca->_comp_r04=clData_GetBit(&d,4); - enableCount2=clData_GetBit(&d,8); - hca->_comp_r05=count1+1; - hca->_comp_r06=((enableCount2)?count2:count1)+1; - hca->_comp_r07=hca->_comp_r05-hca->_comp_r06; - hca->_comp_r08=0; - if(!((hca->_blockSize>=8&&hca->_blockSize<=0xFFFF)||(hca->_blockSize==0)))return -1; - if(!(/*hca->_comp_r01>=0&&*/hca->_comp_r01<=hca->_comp_r02&&hca->_comp_r02<=0x1F))return -1; - if(!hca->_comp_r03)hca->_comp_r03=1; - size-=sizeof(stDecode); - }else{ - return -1; - } + if (crc16_checksum(data, hca->frame_size)) + return -1; - // vbr - if(size>=sizeof(stVBR) && (clData_CheckBit(&d,32)&0x7F7F7F7F)==0x76627200){/*'vbr\0'*/ - clData_AddBit(&d,32); - hca->_vbr_r01=clData_GetBit(&d,16); - hca->_vbr_r02=clData_GetBit(&d,16); - if(!(hca->_blockSize==0&&/*hca->_vbr_r01>=0&&*/hca->_vbr_r01<=0x1FF))return -1; - }else{ - hca->_vbr_r01=0; - hca->_vbr_r02=0; - } + cipher_decrypt(hca->cipher_table, data, hca->frame_size); - // ath - if(size>=6 && (clData_CheckBit(&d,32)&0x7F7F7F7F)==0x61746800){/*'ath\0'*/ - clData_AddBit(&d,32); - hca->_ath_type=clData_GetBit(&d,16); - }else{ - hca->_ath_type=(hca->_version<0x200)?1:0;//v1.3ではデフォルト値が1になってたが、v2.0からATHテーブルが廃止されてるみたいなので0に - } - // loop - if(size>=sizeof(stLoop) && (clData_CheckBit(&d,32)&0x7F7F7F7F)==0x6C6F6F70){/*'loop'*/ - clData_AddBit(&d,32); - hca->_loopStart=clData_GetBit(&d,32); - hca->_loopEnd=clData_GetBit(&d,32); - hca->_loop_r01=clData_GetBit(&d,16); - hca->_loop_r02=clData_GetBit(&d,16); - hca->_loopFlg=1; - if(!(/*hca->_loopStart>=0&&*/hca->_loopStart<=hca->_loopEnd&&hca->_loopEnd_blockCount))return -1; - size-=sizeof(stLoop); - }else{ - hca->_loopStart=0; - hca->_loopEnd=0; - hca->_loop_r01=0; - hca->_loop_r02=0x400; - hca->_loopFlg=0; - } + /* unpack frame values */ + { + unsigned int frame_acceptable_noise_level = bitreader_read(&br, 9); + unsigned int frame_evaluation_boundary = bitreader_read(&br, 7); + unsigned int packed_noise_level = (frame_acceptable_noise_level << 8) - frame_evaluation_boundary; - // ciph - if(size>=6 && (clData_CheckBit(&d,32)&0x7F7F7F7F)==0x63697068){/*'ciph'*/ - clData_AddBit(&d,32); - hca->_ciph_type=clData_GetBit(&d,16); - if(!(hca->_ciph_type==0||hca->_ciph_type==1||hca->_ciph_type==0x38))return -1; - size-=6; - }else{ - hca->_ciph_type=0; - } + for (ch = 0; ch < hca->channels; ch++) { + decode1_unpack_channel(&hca->channel[ch], &br, + hca->hfr_group_count, packed_noise_level, hca->ath_curve); + } + } - // rva - if(size>=sizeof(stRVA) && (clData_CheckBit(&d,32)&0x7F7F7F7F)==0x72766100){/*'rva\0'*/ - union { unsigned int i; float f; } v; - clData_AddBit(&d,32); - v.i=clData_GetBit(&d,32); - hca->_rva_volume=v.f; - size-=sizeof(stRVA); - }else{ - hca->_rva_volume=1; - } + for (subframe = 0; subframe < HCA_SUBFRAMES_PER_FRAME; subframe++) { - // comm - if(size>=5 && (clData_CheckBit(&d,32)&0x7F7F7F7F)==0x636F6D6D){/*'comm'*/ - void * newmem; - unsigned int i; - clData_AddBit(&d,32); - hca->_comm_len=clData_GetBit(&d,8); - if(hca->_comm_len>size)return -1; - newmem=realloc(hca->_comm_comment,hca->_comm_len+1); - if(!newmem)return -1; - hca->_comm_comment=(char *)newmem; - for(i=0;i_comm_len;++i) - ((char *)newmem)[i]=clData_GetBit(&d,8); - ((char *)newmem)[i]='\0'; - size-=5+hca->_comm_len; - }else{ - hca->_comm_len=0; - hca->_comm_comment=NULL; - } + /* unpack channel data and get dequantized spectra */ + for (ch = 0; ch < hca->channels; ch++){ + decode2_dequantize_coefficients(&hca->channel[ch], &br); + } - // 初期化 - if(clATH_Init(&hca->_ath,hca->_ath_type,hca->_samplingRate) < 0)return -1; - if(clCipher_Init(&hca->_cipher,hca->_ciph_type,hca->_ciph_key1,hca->_ciph_key2) < 0)return -1; + /* restore missing bands from spectra 1 */ + for (ch = 0; ch < hca->channels; ch++) { + decode3_reconstruct_high_frequency(&hca->channel[ch], + hca->hfr_group_count, hca->bands_per_hfr_group, + hca->stereo_band_count, hca->base_band_count, hca->total_band_count); + } - // 値チェック(ヘッダの改変ミスによるエラーを回避するため) - if(!hca->_comp_r03)hca->_comp_r03=1;//0での除算を防ぐため + /* restore missing bands from spectra 2 */ + for (ch = 0; ch < hca->channels - 1; ch++) { + decode4_apply_intensity_stereo(&hca->channel[ch], subframe, + hca->total_band_count, hca->base_band_count, hca->stereo_band_count); + } - // デコード準備 - memset(hca->_channel,0,sizeof(hca->_channel)); + /* apply imdct */ + for (ch = 0; ch < hca->channels; ch++) { + decoder5_run_imdct(&hca->channel[ch], subframe); + } + } - if(!(hca->_comp_r01==1&&hca->_comp_r02==15))return -1; - - hca->_comp_r09=ceil2(hca->_comp_r05-(hca->_comp_r06+hca->_comp_r07),hca->_comp_r08); - - memset(r,0,sizeof(r)); - b=hca->_channelCount/hca->_comp_r03; - if(hca->_comp_r07&&b>1){ - char *c=r; - for(i=0;i_comp_r03;i++,c+=b){ - switch(b){ - case 2:c[0]=1;c[1]=2;break; - case 3:c[0]=1;c[1]=2;break; - case 4:c[0]=1;c[1]=2;if(hca->_comp_r04==0){c[2]=1;c[3]=2;}break; - case 5:c[0]=1;c[1]=2;if(hca->_comp_r04<=2){c[3]=1;c[4]=2;}break; - case 6:c[0]=1;c[1]=2;c[4]=1;c[5]=2;break; - case 7:c[0]=1;c[1]=2;c[4]=1;c[5]=2;break; - case 8:c[0]=1;c[1]=2;c[4]=1;c[5]=2;c[6]=1;c[7]=2;break; - } - } - } - for(i=0;i_channelCount;i++){ - hca->_channel[i].type=r[i]; - hca->_channel[i].value3=&hca->_channel[i].value[hca->_comp_r06+hca->_comp_r07]; - hca->_channel[i].count=hca->_comp_r06+((r[i]!=2)?hca->_comp_r07:0); - } - - hca->_validFile = 1; - } - - // ブロックデータ - else if(address>=hca->_dataOffset){ - clData d; - int magic; - unsigned int i, j; - if(!hca->_validFile)return -1; - if(size_blockSize)return -1; - if(clHCA_CheckSum(data,hca->_blockSize,0))return -1; - clCipher_Mask(&hca->_cipher,data,hca->_blockSize); - clData_constructor(&d,data,hca->_blockSize); - magic=clData_GetBit(&d,16);//0xFFFF固定 - if(magic==0xFFFF){ - const unsigned int _channelCount=hca->_channelCount; - int a=(clData_GetBit(&d,9)<<8)-clData_GetBit(&d,7); - for(i=0;i<_channelCount;i++)stChannel_Decode1(&hca->_channel[i],&d,hca->_comp_r09,a,clATH_GetTable(&hca->_ath)); - for(i=0;i<8;i++){ - for(j=0;j<_channelCount;j++)stChannel_Decode2(&hca->_channel[j],&d); - for(j=0;j<_channelCount;j++)stChannel_Decode3(&hca->_channel[j],hca->_comp_r09,hca->_comp_r08,hca->_comp_r07+hca->_comp_r06,hca->_comp_r05); - for(j=0;j<_channelCount-1;j++)stChannel_Decode4(&hca->_channel[j],i,hca->_comp_r05-hca->_comp_r06,hca->_comp_r06,hca->_comp_r07); - for(j=0;j<_channelCount;j++)stChannel_Decode5(&hca->_channel[j],i); - } - } - } - - return 0; + return 0; } //-------------------------------------------------- -// デコード第一段階 -// ベースデータの読み込み +// Decode 1st step //-------------------------------------------------- -static const unsigned char stChannel_Decode1_scalelist[]={ - // v2.0 - 0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0D,0x0D, - 0x0D,0x0D,0x0D,0x0D,0x0C,0x0C,0x0C,0x0C, - 0x0C,0x0C,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B, - 0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x09, - 0x09,0x09,0x09,0x09,0x09,0x08,0x08,0x08, - 0x08,0x08,0x08,0x07,0x06,0x06,0x05,0x04, - 0x04,0x04,0x03,0x03,0x03,0x02,0x02,0x02, - 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - // v1.3 - //0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0D,0x0D, - //0x0D,0x0D,0x0D,0x0D,0x0C,0x0C,0x0C,0x0C, - //0x0C,0x0C,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B, - //0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x09, - //0x09,0x09,0x09,0x09,0x09,0x08,0x08,0x08, - //0x08,0x08,0x08,0x07,0x06,0x06,0x05,0x04, - //0x04,0x04,0x03,0x03,0x03,0x02,0x02,0x02, - //0x02,0x01,0x01,0x01,0x01,0x01,0x01,0x01, -}; -static const unsigned int stChannel_Decode1_valueInt[]={ - 0x342A8D26,0x34633F89,0x3497657D,0x34C9B9BE,0x35066491,0x353311C4,0x356E9910,0x359EF532, - 0x35D3CCF1,0x360D1ADF,0x363C034A,0x367A83B3,0x36A6E595,0x36DE60F5,0x371426FF,0x3745672A, - 0x37838359,0x37AF3B79,0x37E97C38,0x381B8D3A,0x384F4319,0x388A14D5,0x38B7FBF0,0x38F5257D, - 0x3923520F,0x39599D16,0x3990FA4D,0x39C12C4D,0x3A00B1ED,0x3A2B7A3A,0x3A647B6D,0x3A9837F0, - 0x3ACAD226,0x3B071F62,0x3B340AAF,0x3B6FE4BA,0x3B9FD228,0x3BD4F35B,0x3C0DDF04,0x3C3D08A4, - 0x3C7BDFED,0x3CA7CD94,0x3CDF9613,0x3D14F4F0,0x3D467991,0x3D843A29,0x3DB02F0E,0x3DEAC0C7, - 0x3E1C6573,0x3E506334,0x3E8AD4C6,0x3EB8FBAF,0x3EF67A41,0x3F243516,0x3F5ACB94,0x3F91C3D3, - 0x3FC238D2,0x400164D2,0x402C6897,0x4065B907,0x40990B88,0x40CBEC15,0x4107DB35,0x413504F3, -}; -static const unsigned int stChannel_Decode1_scaleInt[]={ - 0x00000000,0x3F2AAAAB,0x3ECCCCCD,0x3E924925,0x3E638E39,0x3E3A2E8C,0x3E1D89D9,0x3E088889, - 0x3D842108,0x3D020821,0x3C810204,0x3C008081,0x3B804020,0x3B002008,0x3A801002,0x3A000801, -}; -static const float *stChannel_Decode1_valueFloat=(const float *)stChannel_Decode1_valueInt; -static const float *stChannel_Decode1_scaleFloat=(const float *)stChannel_Decode1_scaleInt; - -void stChannel_Decode1(stChannel *ch,clData *data,unsigned int a,int b,const unsigned char *ath){ - unsigned int i; - const unsigned int count=ch->count; - char *value=ch->value; - char *value2=ch->value2; - char *value3=ch->value3; - char *scale=ch->scale; - float *base=ch->base; - int v=clData_GetBit(data,3); - if(v>=6){ - for(i=0;i>1,v4; - value[0]=v1; - for(i=1;itype==2){ - v=clData_CheckBit(data,4);value2[0]=v; - if(v<15)for(i=0;i<8;i++)value2[i]=clData_GetBit(data,4); - }else{ - for(i=0;i>8)-((v*5)>>1)+1; - if(v<0)v=15; - else if(v>=0x39)v=1; - else v=stChannel_Decode1_scalelist[v]; - } - scale[i]=v; - } - memset(&scale[count],0,0x80-count); - for(i=0;icount; - const char *scale=ch->scale; - const float *base=ch->base; - float *block=ch->block; - for(i=0;i>1); - if(!v)clData_AddBit(data,-1); - f=(float)v; - } - block[i]=base[i]*f; - } - memset(&block[count],0,sizeof(float)*(0x80-count)); +/* scalefactor-to-scaling table, generated from sqrt(128) * (2^(53/128))^(scale_factor - 63) */ +static const unsigned int decode1_dequantizer_scaling_table_int[64] = { + 0x342A8D26,0x34633F89,0x3497657D,0x34C9B9BE,0x35066491,0x353311C4,0x356E9910,0x359EF532, + 0x35D3CCF1,0x360D1ADF,0x363C034A,0x367A83B3,0x36A6E595,0x36DE60F5,0x371426FF,0x3745672A, + 0x37838359,0x37AF3B79,0x37E97C38,0x381B8D3A,0x384F4319,0x388A14D5,0x38B7FBF0,0x38F5257D, + 0x3923520F,0x39599D16,0x3990FA4D,0x39C12C4D,0x3A00B1ED,0x3A2B7A3A,0x3A647B6D,0x3A9837F0, + 0x3ACAD226,0x3B071F62,0x3B340AAF,0x3B6FE4BA,0x3B9FD228,0x3BD4F35B,0x3C0DDF04,0x3C3D08A4, + 0x3C7BDFED,0x3CA7CD94,0x3CDF9613,0x3D14F4F0,0x3D467991,0x3D843A29,0x3DB02F0E,0x3DEAC0C7, + 0x3E1C6573,0x3E506334,0x3E8AD4C6,0x3EB8FBAF,0x3EF67A41,0x3F243516,0x3F5ACB94,0x3F91C3D3, + 0x3FC238D2,0x400164D2,0x402C6897,0x4065B907,0x40990B88,0x40CBEC15,0x4107DB35,0x413504F3, +}; +static const float *decode1_dequantizer_scaling_table = (const float *)decode1_dequantizer_scaling_table_int; + +static const unsigned int decode1_quantizer_step_size_int[16] = { + 0x00000000,0x3F2AAAAB,0x3ECCCCCD,0x3E924925,0x3E638E39,0x3E3A2E8C,0x3E1D89D9,0x3E088889, + 0x3D842108,0x3D020821,0x3C810204,0x3C008081,0x3B804020,0x3B002008,0x3A801002,0x3A000801, +}; +static const float *decode1_quantizer_step_size = (const float *)decode1_quantizer_step_size_int; + +static void decode1_unpack_channel(stChannel *ch, clData *br, + unsigned int hfr_group_count, unsigned int packed_noise_level, const unsigned char *ath_curve) { + unsigned int i; + const unsigned int csf_count = ch->coded_scalefactor_count; + + + /* read scalefactors */ + { + /* scale indexes to normalize dequantized coefficients */ + unsigned char scalefactor_delta_bits = bitreader_read(br, 3); + if (scalefactor_delta_bits >= 6) { + /* normal scalefactors */ + for (i = 0; i < csf_count; i++) { + ch->scalefactors[i] = bitreader_read(br, 6); + } + } + else if (scalefactor_delta_bits > 0) { + /* delta decode */ + unsigned char expected_delta = (1 << scalefactor_delta_bits) - 1; + unsigned char extra_delta = expected_delta >> 1; + unsigned char scalefactor_prev = bitreader_read(br, 6); + + ch->scalefactors[0] = scalefactor_prev; + for (i = 1; i < csf_count; i++) { + unsigned char delta = bitreader_read(br, scalefactor_delta_bits); + if (delta != expected_delta) { //??? may give negative escalefactors on wrong values??? + scalefactor_prev += delta - extra_delta; /* delta scalefactors */ + } else { + scalefactor_prev = bitreader_read(br, 6); + } + ch->scalefactors[i] = scalefactor_prev; + } + } + else { + /* no scalefactors */ + memset(ch->scalefactors, 0, 0x80); + } + } + + if (ch->type == STEREO_SECONDARY) { + /* read intensity */ + unsigned char intensity_value = bitreader_check(br, 4); + + ch->intensity[0] = intensity_value; + if (intensity_value < 15) { /* 15 may be an invalid value? */ + for (i = 0; i < HCA_SUBFRAMES_PER_FRAME; i++) { + ch->intensity[i] = bitreader_read(br, 4); + } + } + } + else { + /* read hfr scalefactors */ + for (i = 0; i < hfr_group_count; i++) { + ch->hfr_scales[i] = bitreader_read(br, 6); + } + } + + /* calculate resolutions */ + { + /* resolution determines the range of values per encoded spectra, + * using codebooks for lower resolutions during dequantization */ + for (i = 0; i < csf_count; i++) { + unsigned char new_resolution = 0; + unsigned char scalefactor = ch->scalefactors[i]; + if (scalefactor > 0) { + int noise_level = ath_curve[i] + ((packed_noise_level + i) >> 8); + int curve_position = noise_level - ((5 * scalefactor) >> 1) + 1; + + /* curve values can be simplified by clamping position to (0,58) and making + * scale_table[0] = 15, table[58] = 1 (like VGAudio does) */ + if (curve_position < 0) + new_resolution = 15; + else if (curve_position >= 57) + new_resolution = 1; + else + new_resolution = decode1_scale_to_resolution_curve[curve_position]; + } + ch->resolution[i] = new_resolution; + } + memset(&ch->resolution[csf_count], 0, 0x80 - csf_count); + } + + /* calculate gain */ + { + /* get actual scales to dequantize */ + for (i = 0; i < csf_count; i++) { + float scalefactor_scale = decode1_dequantizer_scaling_table[ ch->scalefactors[i] ]; + float resolution_scale = decode1_quantizer_step_size[ ch->resolution[i] ]; + ch->gain[i] = scalefactor_scale * resolution_scale; + } + } } //-------------------------------------------------- -// デコード第三段階 -// ブロックデータ修正その1 ※v2.0から追加 +// Decode 2nd step //-------------------------------------------------- -static const unsigned int stChannel_Decode3_listInt[2][0x40]={ - { - 0x00000000,0x00000000,0x32A0B051,0x32D61B5E,0x330EA43A,0x333E0F68,0x337D3E0C,0x33A8B6D5, - 0x33E0CCDF,0x3415C3FF,0x34478D75,0x3484F1F6,0x34B123F6,0x34EC0719,0x351D3EDA,0x355184DF, - 0x358B95C2,0x35B9FCD2,0x35F7D0DF,0x36251958,0x365BFBB8,0x36928E72,0x36C346CD,0x370218AF, - 0x372D583F,0x3766F85B,0x3799E046,0x37CD078C,0x3808980F,0x38360094,0x38728177,0x38A18FAF, - 0x38D744FD,0x390F6A81,0x393F179A,0x397E9E11,0x39A9A15B,0x39E2055B,0x3A16942D,0x3A48A2D8, - 0x3A85AAC3,0x3AB21A32,0x3AED4F30,0x3B1E196E,0x3B52A81E,0x3B8C57CA,0x3BBAFF5B,0x3BF9295A, - 0x3C25FED7,0x3C5D2D82,0x3C935A2B,0x3CC4563F,0x3D02CD87,0x3D2E4934,0x3D68396A,0x3D9AB62B, - 0x3DCE248C,0x3E0955EE,0x3E36FD92,0x3E73D290,0x3EA27043,0x3ED87039,0x3F1031DC,0x3F40213B, - },{ - 0x3F800000,0x3FAA8D26,0x3FE33F89,0x4017657D,0x4049B9BE,0x40866491,0x40B311C4,0x40EE9910, - 0x411EF532,0x4153CCF1,0x418D1ADF,0x41BC034A,0x41FA83B3,0x4226E595,0x425E60F5,0x429426FF, - 0x42C5672A,0x43038359,0x432F3B79,0x43697C38,0x439B8D3A,0x43CF4319,0x440A14D5,0x4437FBF0, - 0x4475257D,0x44A3520F,0x44D99D16,0x4510FA4D,0x45412C4D,0x4580B1ED,0x45AB7A3A,0x45E47B6D, - 0x461837F0,0x464AD226,0x46871F62,0x46B40AAF,0x46EFE4BA,0x471FD228,0x4754F35B,0x478DDF04, - 0x47BD08A4,0x47FBDFED,0x4827CD94,0x485F9613,0x4894F4F0,0x48C67991,0x49043A29,0x49302F0E, - 0x496AC0C7,0x499C6573,0x49D06334,0x4A0AD4C6,0x4A38FBAF,0x4A767A41,0x4AA43516,0x4ADACB94, - 0x4B11C3D3,0x4B4238D2,0x4B8164D2,0x4BAC6897,0x4BE5B907,0x4C190B88,0x4C4BEC15,0x00000000, - } +static const unsigned char decode2_quantized_spectrum_max_bits[16] = { + 0,2,3,3,4,4,4,4,5,6,7,8,9,10,11,12 +}; +static const unsigned char decode2_quantized_spectrum_bits[128] = { + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 1,1,2,2,0,0,0,0,0,0,0,0,0,0,0,0, + 2,2,2,2,2,2,3,3,0,0,0,0,0,0,0,0, + 2,2,3,3,3,3,3,3,0,0,0,0,0,0,0,0, + 3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4, + 3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4, + 3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4, + 3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4, +}; +static const float decode2_quantized_spectrum_value[128] = { + +0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0, + +0,+0,+1,-1,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0, + +0,+0,+1,+1,-1,-1,+2,-2,+0,+0,+0,+0,+0,+0,+0,+0, + +0,+0,+1,-1,+2,-2,+3,-3,+0,+0,+0,+0,+0,+0,+0,+0, + +0,+0,+1,+1,-1,-1,+2,+2,-2,-2,+3,+3,-3,-3,+4,-4, + +0,+0,+1,+1,-1,-1,+2,+2,-2,-2,+3,-3,+4,-4,+5,-5, + +0,+0,+1,+1,-1,-1,+2,-2,+3,-3,+4,-4,+5,-5,+6,-6, + +0,+0,+1,-1,+2,-2,+3,-3,+4,-4,+5,-5,+6,-6,+7,-7, }; -static const float *stChannel_Decode3_listFloat=(float *)stChannel_Decode3_listInt[1]; -void stChannel_Decode3(stChannel *ch,unsigned int a,unsigned int b,unsigned int c,unsigned int d){ - if(ch->type!=2&&b){ - unsigned int i, j, k, l; - const char *value=ch->value; - const char *value3=ch->value3; - float *block=ch->block; - for(i=0,k=c,l=c-1;icoded_scalefactor_count; + + + for (i = 0; i < csf_count; i++) { + float qc; + unsigned char resolution = ch->resolution[i]; + unsigned char bits = decode2_quantized_spectrum_max_bits[resolution]; + unsigned int code = bitreader_read(br, bits); + + /* read spectral coefficients */ + if (resolution < 8) { + /* use prefix codebooks for lower resolutions */ + code += resolution << 4; + bitreader_skip(br, decode2_quantized_spectrum_bits[code] - bits); + qc = decode2_quantized_spectrum_value[code]; + } + else { + /* parse values in sign-magnitude form (lowest bit = sign) */ + int signed_code = (1 - ((code & 1) << 1)) * (code >> 1); /* move sign */ + if (signed_code == 0) + bitreader_skip(br, -1); /* zero uses one less bit since it has no sign */ + qc = (float)signed_code; + } + + /* dequantize coef with gain */ + ch->spectra[i] = ch->gain[i] * qc; + } + + /* clean rest of spectra */ + memset(&ch->spectra[csf_count], 0, sizeof(float) * (0x80 - csf_count)); } //-------------------------------------------------- -// デコード第四段階 -// ブロックデータ修正その2 +// Decode 3rd step //-------------------------------------------------- -static const unsigned int stChannel_Decode4_listInt[]={ - // v2.0 - 0x40000000,0x3FEDB6DB,0x3FDB6DB7,0x3FC92492,0x3FB6DB6E,0x3FA49249,0x3F924925,0x3F800000, - 0x3F5B6DB7,0x3F36DB6E,0x3F124925,0x3EDB6DB7,0x3E924925,0x3E124925,0x00000000,0x00000000, - 0x00000000,0x32A0B051,0x32D61B5E,0x330EA43A,0x333E0F68,0x337D3E0C,0x33A8B6D5,0x33E0CCDF, - 0x3415C3FF,0x34478D75,0x3484F1F6,0x34B123F6,0x34EC0719,0x351D3EDA,0x355184DF,0x358B95C2, - 0x35B9FCD2,0x35F7D0DF,0x36251958,0x365BFBB8,0x36928E72,0x36C346CD,0x370218AF,0x372D583F, - 0x3766F85B,0x3799E046,0x37CD078C,0x3808980F,0x38360094,0x38728177,0x38A18FAF,0x38D744FD, - 0x390F6A81,0x393F179A,0x397E9E11,0x39A9A15B,0x39E2055B,0x3A16942D,0x3A48A2D8,0x3A85AAC3, - 0x3AB21A32,0x3AED4F30,0x3B1E196E,0x3B52A81E,0x3B8C57CA,0x3BBAFF5B,0x3BF9295A,0x3C25FED7, - //↓この2行要らない? - 0x3C5D2D82,0x3C935A2B,0x3CC4563F,0x3D02CD87,0x3D2E4934,0x3D68396A,0x3D9AB62B,0x3DCE248C, - 0x3E0955EE,0x3E36FD92,0x3E73D290,0x3EA27043,0x3ED87039,0x3F1031DC,0x3F40213B,0x00000000, - // v1.3 - //0x40000000,0x3FEDB6DB,0x3FDB6DB7,0x3FC92492,0x3FB6DB6E,0x3FA49249,0x3F924925,0x3F800000, - //0x3F5B6DB7,0x3F36DB6E,0x3F124925,0x3EDB6DB7,0x3E924925,0x3E124925,0x00000000,0x00000000, -}; +static const unsigned int decode3_scale_conversion_table_int[128] = { + 0x00000000,0x00000000,0x32A0B051,0x32D61B5E,0x330EA43A,0x333E0F68,0x337D3E0C,0x33A8B6D5, + 0x33E0CCDF,0x3415C3FF,0x34478D75,0x3484F1F6,0x34B123F6,0x34EC0719,0x351D3EDA,0x355184DF, + 0x358B95C2,0x35B9FCD2,0x35F7D0DF,0x36251958,0x365BFBB8,0x36928E72,0x36C346CD,0x370218AF, + 0x372D583F,0x3766F85B,0x3799E046,0x37CD078C,0x3808980F,0x38360094,0x38728177,0x38A18FAF, + 0x38D744FD,0x390F6A81,0x393F179A,0x397E9E11,0x39A9A15B,0x39E2055B,0x3A16942D,0x3A48A2D8, + 0x3A85AAC3,0x3AB21A32,0x3AED4F30,0x3B1E196E,0x3B52A81E,0x3B8C57CA,0x3BBAFF5B,0x3BF9295A, + 0x3C25FED7,0x3C5D2D82,0x3C935A2B,0x3CC4563F,0x3D02CD87,0x3D2E4934,0x3D68396A,0x3D9AB62B, + 0x3DCE248C,0x3E0955EE,0x3E36FD92,0x3E73D290,0x3EA27043,0x3ED87039,0x3F1031DC,0x3F40213B, -void stChannel_Decode4(stChannel *ch,int index,unsigned int a,unsigned int b,unsigned int c){ - if(ch->type==1&&c){ - float f1=((float *)stChannel_Decode4_listInt)[ch[1].value2[index]]; - float f2=f1-2.0f; - float *s=&ch->block[b]; - float *d=&ch[1].block[b]; - unsigned int i; - for(i=0;itype == STEREO_SECONDARY) + return; + if (bands_per_hfr_group == 0) /* not in v1.x */ + return; + + { + unsigned int group, i; + unsigned int start_band = stereo_band_count + base_band_count; + unsigned int highband = start_band; + unsigned int lowband = start_band - 1; + + for (group = 0; group < hfr_group_count; group++) { + for (i = 0; i < bands_per_hfr_group && highband < total_band_count; i++) { + unsigned int sc_index = ch->hfr_scales[group] - ch->scalefactors[lowband] + 64; + ch->spectra[highband] = decode3_scale_conversion_table[sc_index] * ch->spectra[lowband]; + highband++; + lowband--; + } + } + + ch->spectra[HCA_SAMPLES_PER_SUBFRAME - 1] = 0; /* last spectral coefficient should be 0 */ + } } //-------------------------------------------------- -// デコード第五段階 -// 波形データを生成 +// Decode 4th step //-------------------------------------------------- -static const unsigned int stChannel_Decode5_list1Int[7][0x40]={ - { - 0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75, - 0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75, - 0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75, - 0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75, - 0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75, - 0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75, - 0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75, - 0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75, - },{ - 0x3F7B14BE,0x3F54DB31,0x3F7B14BE,0x3F54DB31,0x3F7B14BE,0x3F54DB31,0x3F7B14BE,0x3F54DB31, - 0x3F7B14BE,0x3F54DB31,0x3F7B14BE,0x3F54DB31,0x3F7B14BE,0x3F54DB31,0x3F7B14BE,0x3F54DB31, - 0x3F7B14BE,0x3F54DB31,0x3F7B14BE,0x3F54DB31,0x3F7B14BE,0x3F54DB31,0x3F7B14BE,0x3F54DB31, - 0x3F7B14BE,0x3F54DB31,0x3F7B14BE,0x3F54DB31,0x3F7B14BE,0x3F54DB31,0x3F7B14BE,0x3F54DB31, - 0x3F7B14BE,0x3F54DB31,0x3F7B14BE,0x3F54DB31,0x3F7B14BE,0x3F54DB31,0x3F7B14BE,0x3F54DB31, - 0x3F7B14BE,0x3F54DB31,0x3F7B14BE,0x3F54DB31,0x3F7B14BE,0x3F54DB31,0x3F7B14BE,0x3F54DB31, - 0x3F7B14BE,0x3F54DB31,0x3F7B14BE,0x3F54DB31,0x3F7B14BE,0x3F54DB31,0x3F7B14BE,0x3F54DB31, - 0x3F7B14BE,0x3F54DB31,0x3F7B14BE,0x3F54DB31,0x3F7B14BE,0x3F54DB31,0x3F7B14BE,0x3F54DB31, - },{ - 0x3F7EC46D,0x3F74FA0B,0x3F61C598,0x3F45E403,0x3F7EC46D,0x3F74FA0B,0x3F61C598,0x3F45E403, - 0x3F7EC46D,0x3F74FA0B,0x3F61C598,0x3F45E403,0x3F7EC46D,0x3F74FA0B,0x3F61C598,0x3F45E403, - 0x3F7EC46D,0x3F74FA0B,0x3F61C598,0x3F45E403,0x3F7EC46D,0x3F74FA0B,0x3F61C598,0x3F45E403, - 0x3F7EC46D,0x3F74FA0B,0x3F61C598,0x3F45E403,0x3F7EC46D,0x3F74FA0B,0x3F61C598,0x3F45E403, - 0x3F7EC46D,0x3F74FA0B,0x3F61C598,0x3F45E403,0x3F7EC46D,0x3F74FA0B,0x3F61C598,0x3F45E403, - 0x3F7EC46D,0x3F74FA0B,0x3F61C598,0x3F45E403,0x3F7EC46D,0x3F74FA0B,0x3F61C598,0x3F45E403, - 0x3F7EC46D,0x3F74FA0B,0x3F61C598,0x3F45E403,0x3F7EC46D,0x3F74FA0B,0x3F61C598,0x3F45E403, - 0x3F7EC46D,0x3F74FA0B,0x3F61C598,0x3F45E403,0x3F7EC46D,0x3F74FA0B,0x3F61C598,0x3F45E403, - },{ - 0x3F7FB10F,0x3F7D3AAC,0x3F7853F8,0x3F710908,0x3F676BD8,0x3F5B941A,0x3F4D9F02,0x3F3DAEF9, - 0x3F7FB10F,0x3F7D3AAC,0x3F7853F8,0x3F710908,0x3F676BD8,0x3F5B941A,0x3F4D9F02,0x3F3DAEF9, - 0x3F7FB10F,0x3F7D3AAC,0x3F7853F8,0x3F710908,0x3F676BD8,0x3F5B941A,0x3F4D9F02,0x3F3DAEF9, - 0x3F7FB10F,0x3F7D3AAC,0x3F7853F8,0x3F710908,0x3F676BD8,0x3F5B941A,0x3F4D9F02,0x3F3DAEF9, - 0x3F7FB10F,0x3F7D3AAC,0x3F7853F8,0x3F710908,0x3F676BD8,0x3F5B941A,0x3F4D9F02,0x3F3DAEF9, - 0x3F7FB10F,0x3F7D3AAC,0x3F7853F8,0x3F710908,0x3F676BD8,0x3F5B941A,0x3F4D9F02,0x3F3DAEF9, - 0x3F7FB10F,0x3F7D3AAC,0x3F7853F8,0x3F710908,0x3F676BD8,0x3F5B941A,0x3F4D9F02,0x3F3DAEF9, - 0x3F7FB10F,0x3F7D3AAC,0x3F7853F8,0x3F710908,0x3F676BD8,0x3F5B941A,0x3F4D9F02,0x3F3DAEF9, - },{ - 0x3F7FEC43,0x3F7F4E6D,0x3F7E1324,0x3F7C3B28,0x3F79C79D,0x3F76BA07,0x3F731447,0x3F6ED89E, - 0x3F6A09A7,0x3F64AA59,0x3F5EBE05,0x3F584853,0x3F514D3D,0x3F49D112,0x3F41D870,0x3F396842, - 0x3F7FEC43,0x3F7F4E6D,0x3F7E1324,0x3F7C3B28,0x3F79C79D,0x3F76BA07,0x3F731447,0x3F6ED89E, - 0x3F6A09A7,0x3F64AA59,0x3F5EBE05,0x3F584853,0x3F514D3D,0x3F49D112,0x3F41D870,0x3F396842, - 0x3F7FEC43,0x3F7F4E6D,0x3F7E1324,0x3F7C3B28,0x3F79C79D,0x3F76BA07,0x3F731447,0x3F6ED89E, - 0x3F6A09A7,0x3F64AA59,0x3F5EBE05,0x3F584853,0x3F514D3D,0x3F49D112,0x3F41D870,0x3F396842, - 0x3F7FEC43,0x3F7F4E6D,0x3F7E1324,0x3F7C3B28,0x3F79C79D,0x3F76BA07,0x3F731447,0x3F6ED89E, - 0x3F6A09A7,0x3F64AA59,0x3F5EBE05,0x3F584853,0x3F514D3D,0x3F49D112,0x3F41D870,0x3F396842, - },{ - 0x3F7FFB11,0x3F7FD397,0x3F7F84AB,0x3F7F0E58,0x3F7E70B0,0x3F7DABCC,0x3F7CBFC9,0x3F7BACCD, - 0x3F7A7302,0x3F791298,0x3F778BC5,0x3F75DEC6,0x3F740BDD,0x3F721352,0x3F6FF573,0x3F6DB293, - 0x3F6B4B0C,0x3F68BF3C,0x3F660F88,0x3F633C5A,0x3F604621,0x3F5D2D53,0x3F59F26A,0x3F5695E5, - 0x3F531849,0x3F4F7A1F,0x3F4BBBF8,0x3F47DE65,0x3F43E200,0x3F3FC767,0x3F3B8F3B,0x3F373A23, - 0x3F7FFB11,0x3F7FD397,0x3F7F84AB,0x3F7F0E58,0x3F7E70B0,0x3F7DABCC,0x3F7CBFC9,0x3F7BACCD, - 0x3F7A7302,0x3F791298,0x3F778BC5,0x3F75DEC6,0x3F740BDD,0x3F721352,0x3F6FF573,0x3F6DB293, - 0x3F6B4B0C,0x3F68BF3C,0x3F660F88,0x3F633C5A,0x3F604621,0x3F5D2D53,0x3F59F26A,0x3F5695E5, - 0x3F531849,0x3F4F7A1F,0x3F4BBBF8,0x3F47DE65,0x3F43E200,0x3F3FC767,0x3F3B8F3B,0x3F373A23, - },{ - 0x3F7FFEC4,0x3F7FF4E6,0x3F7FE129,0x3F7FC38F,0x3F7F9C18,0x3F7F6AC7,0x3F7F2F9D,0x3F7EEA9D, - 0x3F7E9BC9,0x3F7E4323,0x3F7DE0B1,0x3F7D7474,0x3F7CFE73,0x3F7C7EB0,0x3F7BF531,0x3F7B61FC, - 0x3F7AC516,0x3F7A1E84,0x3F796E4E,0x3F78B47B,0x3F77F110,0x3F772417,0x3F764D97,0x3F756D97, - 0x3F748422,0x3F73913F,0x3F7294F8,0x3F718F57,0x3F708066,0x3F6F6830,0x3F6E46BE,0x3F6D1C1D, - 0x3F6BE858,0x3F6AAB7B,0x3F696591,0x3F6816A8,0x3F66BECC,0x3F655E0B,0x3F63F473,0x3F628210, - 0x3F6106F2,0x3F5F8327,0x3F5DF6BE,0x3F5C61C7,0x3F5AC450,0x3F591E6A,0x3F577026,0x3F55B993, - 0x3F53FAC3,0x3F5233C6,0x3F5064AF,0x3F4E8D90,0x3F4CAE79,0x3F4AC77F,0x3F48D8B3,0x3F46E22A, - 0x3F44E3F5,0x3F42DE29,0x3F40D0DA,0x3F3EBC1B,0x3F3CA003,0x3F3A7CA4,0x3F385216,0x3F36206C, - } +static const unsigned int decode4_intensity_ratio_table_int[80] = { + 0x40000000,0x3FEDB6DB,0x3FDB6DB7,0x3FC92492,0x3FB6DB6E,0x3FA49249,0x3F924925,0x3F800000, + 0x3F5B6DB7,0x3F36DB6E,0x3F124925,0x3EDB6DB7,0x3E924925,0x3E124925,0x00000000,0x00000000, + /* v2.0 seems to define indexes over 15, but intensity is packed in 4b thus unused */ + 0x00000000,0x32A0B051,0x32D61B5E,0x330EA43A,0x333E0F68,0x337D3E0C,0x33A8B6D5,0x33E0CCDF, + 0x3415C3FF,0x34478D75,0x3484F1F6,0x34B123F6,0x34EC0719,0x351D3EDA,0x355184DF,0x358B95C2, + 0x35B9FCD2,0x35F7D0DF,0x36251958,0x365BFBB8,0x36928E72,0x36C346CD,0x370218AF,0x372D583F, + 0x3766F85B,0x3799E046,0x37CD078C,0x3808980F,0x38360094,0x38728177,0x38A18FAF,0x38D744FD, + 0x390F6A81,0x393F179A,0x397E9E11,0x39A9A15B,0x39E2055B,0x3A16942D,0x3A48A2D8,0x3A85AAC3, + 0x3AB21A32,0x3AED4F30,0x3B1E196E,0x3B52A81E,0x3B8C57CA,0x3BBAFF5B,0x3BF9295A,0x3C25FED7, + 0x3C5D2D82,0x3C935A2B,0x3CC4563F,0x3D02CD87,0x3D2E4934,0x3D68396A,0x3D9AB62B,0x3DCE248C, + 0x3E0955EE,0x3E36FD92,0x3E73D290,0x3EA27043,0x3ED87039,0x3F1031DC,0x3F40213B,0x00000000, }; -static const unsigned int stChannel_Decode5_list2Int[7][0x40]={ - { - 0xBD0A8BD4,0x3D0A8BD4,0x3D0A8BD4,0xBD0A8BD4,0x3D0A8BD4,0xBD0A8BD4,0xBD0A8BD4,0x3D0A8BD4, - 0x3D0A8BD4,0xBD0A8BD4,0xBD0A8BD4,0x3D0A8BD4,0xBD0A8BD4,0x3D0A8BD4,0x3D0A8BD4,0xBD0A8BD4, - 0x3D0A8BD4,0xBD0A8BD4,0xBD0A8BD4,0x3D0A8BD4,0xBD0A8BD4,0x3D0A8BD4,0x3D0A8BD4,0xBD0A8BD4, - 0xBD0A8BD4,0x3D0A8BD4,0x3D0A8BD4,0xBD0A8BD4,0x3D0A8BD4,0xBD0A8BD4,0xBD0A8BD4,0x3D0A8BD4, - 0x3D0A8BD4,0xBD0A8BD4,0xBD0A8BD4,0x3D0A8BD4,0xBD0A8BD4,0x3D0A8BD4,0x3D0A8BD4,0xBD0A8BD4, - 0xBD0A8BD4,0x3D0A8BD4,0x3D0A8BD4,0xBD0A8BD4,0x3D0A8BD4,0xBD0A8BD4,0xBD0A8BD4,0x3D0A8BD4, - 0xBD0A8BD4,0x3D0A8BD4,0x3D0A8BD4,0xBD0A8BD4,0x3D0A8BD4,0xBD0A8BD4,0xBD0A8BD4,0x3D0A8BD4, - 0x3D0A8BD4,0xBD0A8BD4,0xBD0A8BD4,0x3D0A8BD4,0xBD0A8BD4,0x3D0A8BD4,0x3D0A8BD4,0xBD0A8BD4, - },{ - 0xBE47C5C2,0xBF0E39DA,0x3E47C5C2,0x3F0E39DA,0x3E47C5C2,0x3F0E39DA,0xBE47C5C2,0xBF0E39DA, - 0x3E47C5C2,0x3F0E39DA,0xBE47C5C2,0xBF0E39DA,0xBE47C5C2,0xBF0E39DA,0x3E47C5C2,0x3F0E39DA, - 0x3E47C5C2,0x3F0E39DA,0xBE47C5C2,0xBF0E39DA,0xBE47C5C2,0xBF0E39DA,0x3E47C5C2,0x3F0E39DA, - 0xBE47C5C2,0xBF0E39DA,0x3E47C5C2,0x3F0E39DA,0x3E47C5C2,0x3F0E39DA,0xBE47C5C2,0xBF0E39DA, - 0x3E47C5C2,0x3F0E39DA,0xBE47C5C2,0xBF0E39DA,0xBE47C5C2,0xBF0E39DA,0x3E47C5C2,0x3F0E39DA, - 0xBE47C5C2,0xBF0E39DA,0x3E47C5C2,0x3F0E39DA,0x3E47C5C2,0x3F0E39DA,0xBE47C5C2,0xBF0E39DA, - 0xBE47C5C2,0xBF0E39DA,0x3E47C5C2,0x3F0E39DA,0x3E47C5C2,0x3F0E39DA,0xBE47C5C2,0xBF0E39DA, - 0x3E47C5C2,0x3F0E39DA,0xBE47C5C2,0xBF0E39DA,0xBE47C5C2,0xBF0E39DA,0x3E47C5C2,0x3F0E39DA, - },{ - 0xBDC8BD36,0xBE94A031,0xBEF15AEA,0xBF226799,0x3DC8BD36,0x3E94A031,0x3EF15AEA,0x3F226799, - 0x3DC8BD36,0x3E94A031,0x3EF15AEA,0x3F226799,0xBDC8BD36,0xBE94A031,0xBEF15AEA,0xBF226799, - 0x3DC8BD36,0x3E94A031,0x3EF15AEA,0x3F226799,0xBDC8BD36,0xBE94A031,0xBEF15AEA,0xBF226799, - 0xBDC8BD36,0xBE94A031,0xBEF15AEA,0xBF226799,0x3DC8BD36,0x3E94A031,0x3EF15AEA,0x3F226799, - 0x3DC8BD36,0x3E94A031,0x3EF15AEA,0x3F226799,0xBDC8BD36,0xBE94A031,0xBEF15AEA,0xBF226799, - 0xBDC8BD36,0xBE94A031,0xBEF15AEA,0xBF226799,0x3DC8BD36,0x3E94A031,0x3EF15AEA,0x3F226799, - 0xBDC8BD36,0xBE94A031,0xBEF15AEA,0xBF226799,0x3DC8BD36,0x3E94A031,0x3EF15AEA,0x3F226799, - 0x3DC8BD36,0x3E94A031,0x3EF15AEA,0x3F226799,0xBDC8BD36,0xBE94A031,0xBEF15AEA,0xBF226799, - },{ - 0xBD48FB30,0xBE164083,0xBE78CFCC,0xBEAC7CD4,0xBEDAE880,0xBF039C3D,0xBF187FC0,0xBF2BEB4A, - 0x3D48FB30,0x3E164083,0x3E78CFCC,0x3EAC7CD4,0x3EDAE880,0x3F039C3D,0x3F187FC0,0x3F2BEB4A, - 0x3D48FB30,0x3E164083,0x3E78CFCC,0x3EAC7CD4,0x3EDAE880,0x3F039C3D,0x3F187FC0,0x3F2BEB4A, - 0xBD48FB30,0xBE164083,0xBE78CFCC,0xBEAC7CD4,0xBEDAE880,0xBF039C3D,0xBF187FC0,0xBF2BEB4A, - 0x3D48FB30,0x3E164083,0x3E78CFCC,0x3EAC7CD4,0x3EDAE880,0x3F039C3D,0x3F187FC0,0x3F2BEB4A, - 0xBD48FB30,0xBE164083,0xBE78CFCC,0xBEAC7CD4,0xBEDAE880,0xBF039C3D,0xBF187FC0,0xBF2BEB4A, - 0xBD48FB30,0xBE164083,0xBE78CFCC,0xBEAC7CD4,0xBEDAE880,0xBF039C3D,0xBF187FC0,0xBF2BEB4A, - 0x3D48FB30,0x3E164083,0x3E78CFCC,0x3EAC7CD4,0x3EDAE880,0x3F039C3D,0x3F187FC0,0x3F2BEB4A, - },{ - 0xBCC90AB0,0xBD96A905,0xBDFAB273,0xBE2F10A2,0xBE605C13,0xBE888E93,0xBEA09AE5,0xBEB8442A, - 0xBECF7BCA,0xBEE63375,0xBEFC5D27,0xBF08F59B,0xBF13682A,0xBF1D7FD1,0xBF273656,0xBF3085BB, - 0x3CC90AB0,0x3D96A905,0x3DFAB273,0x3E2F10A2,0x3E605C13,0x3E888E93,0x3EA09AE5,0x3EB8442A, - 0x3ECF7BCA,0x3EE63375,0x3EFC5D27,0x3F08F59B,0x3F13682A,0x3F1D7FD1,0x3F273656,0x3F3085BB, - 0x3CC90AB0,0x3D96A905,0x3DFAB273,0x3E2F10A2,0x3E605C13,0x3E888E93,0x3EA09AE5,0x3EB8442A, - 0x3ECF7BCA,0x3EE63375,0x3EFC5D27,0x3F08F59B,0x3F13682A,0x3F1D7FD1,0x3F273656,0x3F3085BB, - 0xBCC90AB0,0xBD96A905,0xBDFAB273,0xBE2F10A2,0xBE605C13,0xBE888E93,0xBEA09AE5,0xBEB8442A, - 0xBECF7BCA,0xBEE63375,0xBEFC5D27,0xBF08F59B,0xBF13682A,0xBF1D7FD1,0xBF273656,0xBF3085BB, - },{ - 0xBC490E90,0xBD16C32C,0xBD7B2B74,0xBDAFB680,0xBDE1BC2E,0xBE09CF86,0xBE22ABB6,0xBE3B6ECF, - 0xBE541501,0xBE6C9A7F,0xBE827DC0,0xBE8E9A22,0xBE9AA086,0xBEA68F12,0xBEB263EF,0xBEBE1D4A, - 0xBEC9B953,0xBED53641,0xBEE0924F,0xBEEBCBBB,0xBEF6E0CB,0xBF00E7E4,0xBF064B82,0xBF0B9A6B, - 0xBF10D3CD,0xBF15F6D9,0xBF1B02C6,0xBF1FF6CB,0xBF24D225,0xBF299415,0xBF2E3BDE,0xBF32C8C9, - 0x3C490E90,0x3D16C32C,0x3D7B2B74,0x3DAFB680,0x3DE1BC2E,0x3E09CF86,0x3E22ABB6,0x3E3B6ECF, - 0x3E541501,0x3E6C9A7F,0x3E827DC0,0x3E8E9A22,0x3E9AA086,0x3EA68F12,0x3EB263EF,0x3EBE1D4A, - 0x3EC9B953,0x3ED53641,0x3EE0924F,0x3EEBCBBB,0x3EF6E0CB,0x3F00E7E4,0x3F064B82,0x3F0B9A6B, - 0x3F10D3CD,0x3F15F6D9,0x3F1B02C6,0x3F1FF6CB,0x3F24D225,0x3F299415,0x3F2E3BDE,0x3F32C8C9, - },{ - 0xBBC90F88,0xBC96C9B6,0xBCFB49BA,0xBD2FE007,0xBD621469,0xBD8A200A,0xBDA3308C,0xBDBC3AC3, - 0xBDD53DB9,0xBDEE3876,0xBE039502,0xBE1008B7,0xBE1C76DE,0xBE28DEFC,0xBE354098,0xBE419B37, - 0xBE4DEE60,0xBE5A3997,0xBE667C66,0xBE72B651,0xBE7EE6E1,0xBE8586CE,0xBE8B9507,0xBE919DDD, - 0xBE97A117,0xBE9D9E78,0xBEA395C5,0xBEA986C4,0xBEAF713A,0xBEB554EC,0xBEBB31A0,0xBEC1071E, - 0xBEC6D529,0xBECC9B8B,0xBED25A09,0xBED8106B,0xBEDDBE79,0xBEE363FA,0xBEE900B7,0xBEEE9479, - 0xBEF41F07,0xBEF9A02D,0xBEFF17B2,0xBF0242B1,0xBF04F484,0xBF07A136,0xBF0A48AD,0xBF0CEAD0, - 0xBF0F8784,0xBF121EB0,0xBF14B039,0xBF173C07,0xBF19C200,0xBF1C420C,0xBF1EBC12,0xBF212FF9, - 0xBF239DA9,0xBF26050A,0xBF286605,0xBF2AC082,0xBF2D1469,0xBF2F61A5,0xBF31A81D,0xBF33E7BC, - } -}; -static const unsigned int stChannel_Decode5_list3Int[2][0x40]={ - { - 0x3A3504F0,0x3B0183B8,0x3B70C538,0x3BBB9268,0x3C04A809,0x3C308200,0x3C61284C,0x3C8B3F17, - 0x3CA83992,0x3CC77FBD,0x3CE91110,0x3D0677CD,0x3D198FC4,0x3D2DD35C,0x3D434643,0x3D59ECC1, - 0x3D71CBA8,0x3D85741E,0x3D92A413,0x3DA078B4,0x3DAEF522,0x3DBE1C9E,0x3DCDF27B,0x3DDE7A1D, - 0x3DEFB6ED,0x3E00D62B,0x3E0A2EDA,0x3E13E72A,0x3E1E00B1,0x3E287CF2,0x3E335D55,0x3E3EA321, - 0x3E4A4F75,0x3E56633F,0x3E62DF37,0x3E6FC3D1,0x3E7D1138,0x3E8563A2,0x3E8C72B7,0x3E93B561, - 0x3E9B2AEF,0x3EA2D26F,0x3EAAAAAB,0x3EB2B222,0x3EBAE706,0x3EC34737,0x3ECBD03D,0x3ED47F46, - 0x3EDD5128,0x3EE6425C,0x3EEF4EFF,0x3EF872D7,0x3F00D4A9,0x3F0576CA,0x3F0A1D3B,0x3F0EC548, - 0x3F136C25,0x3F180EF2,0x3F1CAAC2,0x3F213CA2,0x3F25C1A5,0x3F2A36E7,0x3F2E9998,0x3F32E705, - },{ - 0xBF371C9E,0xBF3B37FE,0xBF3F36F2,0xBF431780,0xBF46D7E6,0xBF4A76A4,0xBF4DF27C,0xBF514A6F, - 0xBF547DC5,0xBF578C03,0xBF5A74EE,0xBF5D3887,0xBF5FD707,0xBF6250DA,0xBF64A699,0xBF66D908, - 0xBF68E90E,0xBF6AD7B1,0xBF6CA611,0xBF6E5562,0xBF6FE6E7,0xBF715BEF,0xBF72B5D1,0xBF73F5E6, - 0xBF751D89,0xBF762E13,0xBF7728D7,0xBF780F20,0xBF78E234,0xBF79A34C,0xBF7A5397,0xBF7AF439, - 0xBF7B8648,0xBF7C0ACE,0xBF7C82C8,0xBF7CEF26,0xBF7D50CB,0xBF7DA88E,0xBF7DF737,0xBF7E3D86, - 0xBF7E7C2A,0xBF7EB3CC,0xBF7EE507,0xBF7F106C,0xBF7F3683,0xBF7F57CA,0xBF7F74B6,0xBF7F8DB6, - 0xBF7FA32E,0xBF7FB57B,0xBF7FC4F6,0xBF7FD1ED,0xBF7FDCAD,0xBF7FE579,0xBF7FEC90,0xBF7FF22E, - 0xBF7FF688,0xBF7FF9D0,0xBF7FFC32,0xBF7FFDDA,0xBF7FFEED,0xBF7FFF8F,0xBF7FFFDF,0xBF7FFFFC, - } +static const float *decode4_intensity_ratio_table = (const float *)decode4_intensity_ratio_table_int; + +static void decode4_apply_intensity_stereo(stChannel *ch_pair, int subframe, + unsigned int total_band_count, unsigned int base_band_count, unsigned int stereo_band_count) { + if (ch_pair[0].type != STEREO_PRIMARY) + return; + if (stereo_band_count == 0) + return; + + { + float ratio_l = decode4_intensity_ratio_table[ ch_pair[1].intensity[subframe] ]; + float ratio_r = ratio_l - 2.0f; +#if HCA_DISABLE_OPTIMIZATIONS + float *sp_l = ch_pair[0].spectra; + float *sp_r = ch_pair[1].spectra; + unsigned int band; + + for (band = base_band_count; band < total_band_count; band++) { + sp_r[band] = sp_l[band] * ratio_r; + sp_l[band] = sp_l[band] * ratio_l; + } +#else + float *sp0 = &ch_pair[0].spectra[base_band_count]; + float *sp1 = &ch_pair[1].spectra[base_band_count]; + unsigned int i; + unsigned int max_band = total_band_count - base_band_count; + + for (i = 0; i < max_band; i++) { + *sp1 = (*sp0) * ratio_r; + *sp0 = (*sp0) * ratio_l; + sp1++; + sp0++; + } +#endif + } +} + +//-------------------------------------------------- +// Decode 5th step +//-------------------------------------------------- +static const unsigned int decode5_sin_tables_int[7][64] = { + { + 0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75, + 0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75, + 0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75, + 0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75, + 0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75, + 0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75, + 0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75, + 0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75,0x3DA73D75, + },{ + 0x3F7B14BE,0x3F54DB31,0x3F7B14BE,0x3F54DB31,0x3F7B14BE,0x3F54DB31,0x3F7B14BE,0x3F54DB31, + 0x3F7B14BE,0x3F54DB31,0x3F7B14BE,0x3F54DB31,0x3F7B14BE,0x3F54DB31,0x3F7B14BE,0x3F54DB31, + 0x3F7B14BE,0x3F54DB31,0x3F7B14BE,0x3F54DB31,0x3F7B14BE,0x3F54DB31,0x3F7B14BE,0x3F54DB31, + 0x3F7B14BE,0x3F54DB31,0x3F7B14BE,0x3F54DB31,0x3F7B14BE,0x3F54DB31,0x3F7B14BE,0x3F54DB31, + 0x3F7B14BE,0x3F54DB31,0x3F7B14BE,0x3F54DB31,0x3F7B14BE,0x3F54DB31,0x3F7B14BE,0x3F54DB31, + 0x3F7B14BE,0x3F54DB31,0x3F7B14BE,0x3F54DB31,0x3F7B14BE,0x3F54DB31,0x3F7B14BE,0x3F54DB31, + 0x3F7B14BE,0x3F54DB31,0x3F7B14BE,0x3F54DB31,0x3F7B14BE,0x3F54DB31,0x3F7B14BE,0x3F54DB31, + 0x3F7B14BE,0x3F54DB31,0x3F7B14BE,0x3F54DB31,0x3F7B14BE,0x3F54DB31,0x3F7B14BE,0x3F54DB31, + },{ + 0x3F7EC46D,0x3F74FA0B,0x3F61C598,0x3F45E403,0x3F7EC46D,0x3F74FA0B,0x3F61C598,0x3F45E403, + 0x3F7EC46D,0x3F74FA0B,0x3F61C598,0x3F45E403,0x3F7EC46D,0x3F74FA0B,0x3F61C598,0x3F45E403, + 0x3F7EC46D,0x3F74FA0B,0x3F61C598,0x3F45E403,0x3F7EC46D,0x3F74FA0B,0x3F61C598,0x3F45E403, + 0x3F7EC46D,0x3F74FA0B,0x3F61C598,0x3F45E403,0x3F7EC46D,0x3F74FA0B,0x3F61C598,0x3F45E403, + 0x3F7EC46D,0x3F74FA0B,0x3F61C598,0x3F45E403,0x3F7EC46D,0x3F74FA0B,0x3F61C598,0x3F45E403, + 0x3F7EC46D,0x3F74FA0B,0x3F61C598,0x3F45E403,0x3F7EC46D,0x3F74FA0B,0x3F61C598,0x3F45E403, + 0x3F7EC46D,0x3F74FA0B,0x3F61C598,0x3F45E403,0x3F7EC46D,0x3F74FA0B,0x3F61C598,0x3F45E403, + 0x3F7EC46D,0x3F74FA0B,0x3F61C598,0x3F45E403,0x3F7EC46D,0x3F74FA0B,0x3F61C598,0x3F45E403, + },{ + 0x3F7FB10F,0x3F7D3AAC,0x3F7853F8,0x3F710908,0x3F676BD8,0x3F5B941A,0x3F4D9F02,0x3F3DAEF9, + 0x3F7FB10F,0x3F7D3AAC,0x3F7853F8,0x3F710908,0x3F676BD8,0x3F5B941A,0x3F4D9F02,0x3F3DAEF9, + 0x3F7FB10F,0x3F7D3AAC,0x3F7853F8,0x3F710908,0x3F676BD8,0x3F5B941A,0x3F4D9F02,0x3F3DAEF9, + 0x3F7FB10F,0x3F7D3AAC,0x3F7853F8,0x3F710908,0x3F676BD8,0x3F5B941A,0x3F4D9F02,0x3F3DAEF9, + 0x3F7FB10F,0x3F7D3AAC,0x3F7853F8,0x3F710908,0x3F676BD8,0x3F5B941A,0x3F4D9F02,0x3F3DAEF9, + 0x3F7FB10F,0x3F7D3AAC,0x3F7853F8,0x3F710908,0x3F676BD8,0x3F5B941A,0x3F4D9F02,0x3F3DAEF9, + 0x3F7FB10F,0x3F7D3AAC,0x3F7853F8,0x3F710908,0x3F676BD8,0x3F5B941A,0x3F4D9F02,0x3F3DAEF9, + 0x3F7FB10F,0x3F7D3AAC,0x3F7853F8,0x3F710908,0x3F676BD8,0x3F5B941A,0x3F4D9F02,0x3F3DAEF9, + },{ + 0x3F7FEC43,0x3F7F4E6D,0x3F7E1324,0x3F7C3B28,0x3F79C79D,0x3F76BA07,0x3F731447,0x3F6ED89E, + 0x3F6A09A7,0x3F64AA59,0x3F5EBE05,0x3F584853,0x3F514D3D,0x3F49D112,0x3F41D870,0x3F396842, + 0x3F7FEC43,0x3F7F4E6D,0x3F7E1324,0x3F7C3B28,0x3F79C79D,0x3F76BA07,0x3F731447,0x3F6ED89E, + 0x3F6A09A7,0x3F64AA59,0x3F5EBE05,0x3F584853,0x3F514D3D,0x3F49D112,0x3F41D870,0x3F396842, + 0x3F7FEC43,0x3F7F4E6D,0x3F7E1324,0x3F7C3B28,0x3F79C79D,0x3F76BA07,0x3F731447,0x3F6ED89E, + 0x3F6A09A7,0x3F64AA59,0x3F5EBE05,0x3F584853,0x3F514D3D,0x3F49D112,0x3F41D870,0x3F396842, + 0x3F7FEC43,0x3F7F4E6D,0x3F7E1324,0x3F7C3B28,0x3F79C79D,0x3F76BA07,0x3F731447,0x3F6ED89E, + 0x3F6A09A7,0x3F64AA59,0x3F5EBE05,0x3F584853,0x3F514D3D,0x3F49D112,0x3F41D870,0x3F396842, + },{ + 0x3F7FFB11,0x3F7FD397,0x3F7F84AB,0x3F7F0E58,0x3F7E70B0,0x3F7DABCC,0x3F7CBFC9,0x3F7BACCD, + 0x3F7A7302,0x3F791298,0x3F778BC5,0x3F75DEC6,0x3F740BDD,0x3F721352,0x3F6FF573,0x3F6DB293, + 0x3F6B4B0C,0x3F68BF3C,0x3F660F88,0x3F633C5A,0x3F604621,0x3F5D2D53,0x3F59F26A,0x3F5695E5, + 0x3F531849,0x3F4F7A1F,0x3F4BBBF8,0x3F47DE65,0x3F43E200,0x3F3FC767,0x3F3B8F3B,0x3F373A23, + 0x3F7FFB11,0x3F7FD397,0x3F7F84AB,0x3F7F0E58,0x3F7E70B0,0x3F7DABCC,0x3F7CBFC9,0x3F7BACCD, + 0x3F7A7302,0x3F791298,0x3F778BC5,0x3F75DEC6,0x3F740BDD,0x3F721352,0x3F6FF573,0x3F6DB293, + 0x3F6B4B0C,0x3F68BF3C,0x3F660F88,0x3F633C5A,0x3F604621,0x3F5D2D53,0x3F59F26A,0x3F5695E5, + 0x3F531849,0x3F4F7A1F,0x3F4BBBF8,0x3F47DE65,0x3F43E200,0x3F3FC767,0x3F3B8F3B,0x3F373A23, + },{ + 0x3F7FFEC4,0x3F7FF4E6,0x3F7FE129,0x3F7FC38F,0x3F7F9C18,0x3F7F6AC7,0x3F7F2F9D,0x3F7EEA9D, + 0x3F7E9BC9,0x3F7E4323,0x3F7DE0B1,0x3F7D7474,0x3F7CFE73,0x3F7C7EB0,0x3F7BF531,0x3F7B61FC, + 0x3F7AC516,0x3F7A1E84,0x3F796E4E,0x3F78B47B,0x3F77F110,0x3F772417,0x3F764D97,0x3F756D97, + 0x3F748422,0x3F73913F,0x3F7294F8,0x3F718F57,0x3F708066,0x3F6F6830,0x3F6E46BE,0x3F6D1C1D, + 0x3F6BE858,0x3F6AAB7B,0x3F696591,0x3F6816A8,0x3F66BECC,0x3F655E0B,0x3F63F473,0x3F628210, + 0x3F6106F2,0x3F5F8327,0x3F5DF6BE,0x3F5C61C7,0x3F5AC450,0x3F591E6A,0x3F577026,0x3F55B993, + 0x3F53FAC3,0x3F5233C6,0x3F5064AF,0x3F4E8D90,0x3F4CAE79,0x3F4AC77F,0x3F48D8B3,0x3F46E22A, + 0x3F44E3F5,0x3F42DE29,0x3F40D0DA,0x3F3EBC1B,0x3F3CA003,0x3F3A7CA4,0x3F385216,0x3F36206C, + } }; -void stChannel_Decode5(stChannel *ch,int index){ - const float *s, *s1, *s2; - float *d; - unsigned int i, count1, count2, j, k; - s=ch->block;d=ch->wav1; - for(i=0,count1=1,count2=0x40;i<7;i++,count1<<=1,count2>>=1){ - float *d1=d; - float *d2=&d[count2]; - float *w; - for(j=0;jwav1;d=ch->block; - for(i=0,count1=0x40,count2=1;i<7;i++,count1>>=1,count2<<=1){ - const float *list1Float=(const float *)stChannel_Decode5_list1Int[i]; - const float *list2Float=(const float *)stChannel_Decode5_list2Int[i]; - float *d1, *d2, *w; - s1=s; - s2=&s1[count2]; - d1=d; - d2=&d1[count2*2-1]; - for(j=0;jwav2; - for(i=0;i<0x80;i++)*(d++)=*(s++); - s=(const float *)stChannel_Decode5_list3Int;d=ch->wave[index]; - s1=&ch->wav2[0x40];s2=ch->wav3; - for(i=0;i<0x40;i++)*(d++)=*(s1++)**(s++)+*(s2++); - for(i=0;i<0x40;i++)*(d++)=*(s++)**(--s1)-*(s2++); - s1=&ch->wav2[0x40-1];d=ch->wav3; - for(i=0;i<0x40;i++)*(d++)=*(s1--)**(--s); - for(i=0;i<0x40;i++)*(d++)=*(--s)**(++s1); +static const unsigned int decode5_cos_tables_int[7][64]={ + { + 0xBD0A8BD4,0x3D0A8BD4,0x3D0A8BD4,0xBD0A8BD4,0x3D0A8BD4,0xBD0A8BD4,0xBD0A8BD4,0x3D0A8BD4, + 0x3D0A8BD4,0xBD0A8BD4,0xBD0A8BD4,0x3D0A8BD4,0xBD0A8BD4,0x3D0A8BD4,0x3D0A8BD4,0xBD0A8BD4, + 0x3D0A8BD4,0xBD0A8BD4,0xBD0A8BD4,0x3D0A8BD4,0xBD0A8BD4,0x3D0A8BD4,0x3D0A8BD4,0xBD0A8BD4, + 0xBD0A8BD4,0x3D0A8BD4,0x3D0A8BD4,0xBD0A8BD4,0x3D0A8BD4,0xBD0A8BD4,0xBD0A8BD4,0x3D0A8BD4, + 0x3D0A8BD4,0xBD0A8BD4,0xBD0A8BD4,0x3D0A8BD4,0xBD0A8BD4,0x3D0A8BD4,0x3D0A8BD4,0xBD0A8BD4, + 0xBD0A8BD4,0x3D0A8BD4,0x3D0A8BD4,0xBD0A8BD4,0x3D0A8BD4,0xBD0A8BD4,0xBD0A8BD4,0x3D0A8BD4, + 0xBD0A8BD4,0x3D0A8BD4,0x3D0A8BD4,0xBD0A8BD4,0x3D0A8BD4,0xBD0A8BD4,0xBD0A8BD4,0x3D0A8BD4, + 0x3D0A8BD4,0xBD0A8BD4,0xBD0A8BD4,0x3D0A8BD4,0xBD0A8BD4,0x3D0A8BD4,0x3D0A8BD4,0xBD0A8BD4, + },{ + 0xBE47C5C2,0xBF0E39DA,0x3E47C5C2,0x3F0E39DA,0x3E47C5C2,0x3F0E39DA,0xBE47C5C2,0xBF0E39DA, + 0x3E47C5C2,0x3F0E39DA,0xBE47C5C2,0xBF0E39DA,0xBE47C5C2,0xBF0E39DA,0x3E47C5C2,0x3F0E39DA, + 0x3E47C5C2,0x3F0E39DA,0xBE47C5C2,0xBF0E39DA,0xBE47C5C2,0xBF0E39DA,0x3E47C5C2,0x3F0E39DA, + 0xBE47C5C2,0xBF0E39DA,0x3E47C5C2,0x3F0E39DA,0x3E47C5C2,0x3F0E39DA,0xBE47C5C2,0xBF0E39DA, + 0x3E47C5C2,0x3F0E39DA,0xBE47C5C2,0xBF0E39DA,0xBE47C5C2,0xBF0E39DA,0x3E47C5C2,0x3F0E39DA, + 0xBE47C5C2,0xBF0E39DA,0x3E47C5C2,0x3F0E39DA,0x3E47C5C2,0x3F0E39DA,0xBE47C5C2,0xBF0E39DA, + 0xBE47C5C2,0xBF0E39DA,0x3E47C5C2,0x3F0E39DA,0x3E47C5C2,0x3F0E39DA,0xBE47C5C2,0xBF0E39DA, + 0x3E47C5C2,0x3F0E39DA,0xBE47C5C2,0xBF0E39DA,0xBE47C5C2,0xBF0E39DA,0x3E47C5C2,0x3F0E39DA, + },{ + 0xBDC8BD36,0xBE94A031,0xBEF15AEA,0xBF226799,0x3DC8BD36,0x3E94A031,0x3EF15AEA,0x3F226799, + 0x3DC8BD36,0x3E94A031,0x3EF15AEA,0x3F226799,0xBDC8BD36,0xBE94A031,0xBEF15AEA,0xBF226799, + 0x3DC8BD36,0x3E94A031,0x3EF15AEA,0x3F226799,0xBDC8BD36,0xBE94A031,0xBEF15AEA,0xBF226799, + 0xBDC8BD36,0xBE94A031,0xBEF15AEA,0xBF226799,0x3DC8BD36,0x3E94A031,0x3EF15AEA,0x3F226799, + 0x3DC8BD36,0x3E94A031,0x3EF15AEA,0x3F226799,0xBDC8BD36,0xBE94A031,0xBEF15AEA,0xBF226799, + 0xBDC8BD36,0xBE94A031,0xBEF15AEA,0xBF226799,0x3DC8BD36,0x3E94A031,0x3EF15AEA,0x3F226799, + 0xBDC8BD36,0xBE94A031,0xBEF15AEA,0xBF226799,0x3DC8BD36,0x3E94A031,0x3EF15AEA,0x3F226799, + 0x3DC8BD36,0x3E94A031,0x3EF15AEA,0x3F226799,0xBDC8BD36,0xBE94A031,0xBEF15AEA,0xBF226799, + },{ + 0xBD48FB30,0xBE164083,0xBE78CFCC,0xBEAC7CD4,0xBEDAE880,0xBF039C3D,0xBF187FC0,0xBF2BEB4A, + 0x3D48FB30,0x3E164083,0x3E78CFCC,0x3EAC7CD4,0x3EDAE880,0x3F039C3D,0x3F187FC0,0x3F2BEB4A, + 0x3D48FB30,0x3E164083,0x3E78CFCC,0x3EAC7CD4,0x3EDAE880,0x3F039C3D,0x3F187FC0,0x3F2BEB4A, + 0xBD48FB30,0xBE164083,0xBE78CFCC,0xBEAC7CD4,0xBEDAE880,0xBF039C3D,0xBF187FC0,0xBF2BEB4A, + 0x3D48FB30,0x3E164083,0x3E78CFCC,0x3EAC7CD4,0x3EDAE880,0x3F039C3D,0x3F187FC0,0x3F2BEB4A, + 0xBD48FB30,0xBE164083,0xBE78CFCC,0xBEAC7CD4,0xBEDAE880,0xBF039C3D,0xBF187FC0,0xBF2BEB4A, + 0xBD48FB30,0xBE164083,0xBE78CFCC,0xBEAC7CD4,0xBEDAE880,0xBF039C3D,0xBF187FC0,0xBF2BEB4A, + 0x3D48FB30,0x3E164083,0x3E78CFCC,0x3EAC7CD4,0x3EDAE880,0x3F039C3D,0x3F187FC0,0x3F2BEB4A, + },{ + 0xBCC90AB0,0xBD96A905,0xBDFAB273,0xBE2F10A2,0xBE605C13,0xBE888E93,0xBEA09AE5,0xBEB8442A, + 0xBECF7BCA,0xBEE63375,0xBEFC5D27,0xBF08F59B,0xBF13682A,0xBF1D7FD1,0xBF273656,0xBF3085BB, + 0x3CC90AB0,0x3D96A905,0x3DFAB273,0x3E2F10A2,0x3E605C13,0x3E888E93,0x3EA09AE5,0x3EB8442A, + 0x3ECF7BCA,0x3EE63375,0x3EFC5D27,0x3F08F59B,0x3F13682A,0x3F1D7FD1,0x3F273656,0x3F3085BB, + 0x3CC90AB0,0x3D96A905,0x3DFAB273,0x3E2F10A2,0x3E605C13,0x3E888E93,0x3EA09AE5,0x3EB8442A, + 0x3ECF7BCA,0x3EE63375,0x3EFC5D27,0x3F08F59B,0x3F13682A,0x3F1D7FD1,0x3F273656,0x3F3085BB, + 0xBCC90AB0,0xBD96A905,0xBDFAB273,0xBE2F10A2,0xBE605C13,0xBE888E93,0xBEA09AE5,0xBEB8442A, + 0xBECF7BCA,0xBEE63375,0xBEFC5D27,0xBF08F59B,0xBF13682A,0xBF1D7FD1,0xBF273656,0xBF3085BB, + },{ + 0xBC490E90,0xBD16C32C,0xBD7B2B74,0xBDAFB680,0xBDE1BC2E,0xBE09CF86,0xBE22ABB6,0xBE3B6ECF, + 0xBE541501,0xBE6C9A7F,0xBE827DC0,0xBE8E9A22,0xBE9AA086,0xBEA68F12,0xBEB263EF,0xBEBE1D4A, + 0xBEC9B953,0xBED53641,0xBEE0924F,0xBEEBCBBB,0xBEF6E0CB,0xBF00E7E4,0xBF064B82,0xBF0B9A6B, + 0xBF10D3CD,0xBF15F6D9,0xBF1B02C6,0xBF1FF6CB,0xBF24D225,0xBF299415,0xBF2E3BDE,0xBF32C8C9, + 0x3C490E90,0x3D16C32C,0x3D7B2B74,0x3DAFB680,0x3DE1BC2E,0x3E09CF86,0x3E22ABB6,0x3E3B6ECF, + 0x3E541501,0x3E6C9A7F,0x3E827DC0,0x3E8E9A22,0x3E9AA086,0x3EA68F12,0x3EB263EF,0x3EBE1D4A, + 0x3EC9B953,0x3ED53641,0x3EE0924F,0x3EEBCBBB,0x3EF6E0CB,0x3F00E7E4,0x3F064B82,0x3F0B9A6B, + 0x3F10D3CD,0x3F15F6D9,0x3F1B02C6,0x3F1FF6CB,0x3F24D225,0x3F299415,0x3F2E3BDE,0x3F32C8C9, + },{ + 0xBBC90F88,0xBC96C9B6,0xBCFB49BA,0xBD2FE007,0xBD621469,0xBD8A200A,0xBDA3308C,0xBDBC3AC3, + 0xBDD53DB9,0xBDEE3876,0xBE039502,0xBE1008B7,0xBE1C76DE,0xBE28DEFC,0xBE354098,0xBE419B37, + 0xBE4DEE60,0xBE5A3997,0xBE667C66,0xBE72B651,0xBE7EE6E1,0xBE8586CE,0xBE8B9507,0xBE919DDD, + 0xBE97A117,0xBE9D9E78,0xBEA395C5,0xBEA986C4,0xBEAF713A,0xBEB554EC,0xBEBB31A0,0xBEC1071E, + 0xBEC6D529,0xBECC9B8B,0xBED25A09,0xBED8106B,0xBEDDBE79,0xBEE363FA,0xBEE900B7,0xBEEE9479, + 0xBEF41F07,0xBEF9A02D,0xBEFF17B2,0xBF0242B1,0xBF04F484,0xBF07A136,0xBF0A48AD,0xBF0CEAD0, + 0xBF0F8784,0xBF121EB0,0xBF14B039,0xBF173C07,0xBF19C200,0xBF1C420C,0xBF1EBC12,0xBF212FF9, + 0xBF239DA9,0xBF26050A,0xBF286605,0xBF2AC082,0xBF2D1469,0xBF2F61A5,0xBF31A81D,0xBF33E7BC, + } +}; + +/* HCA window function, close to a KBD window with an alpha of around 3.82 (similar to AAC/Vorbis) */ +static const unsigned int decode5_imdct_window_int[128] = { + 0x3A3504F0,0x3B0183B8,0x3B70C538,0x3BBB9268,0x3C04A809,0x3C308200,0x3C61284C,0x3C8B3F17, + 0x3CA83992,0x3CC77FBD,0x3CE91110,0x3D0677CD,0x3D198FC4,0x3D2DD35C,0x3D434643,0x3D59ECC1, + 0x3D71CBA8,0x3D85741E,0x3D92A413,0x3DA078B4,0x3DAEF522,0x3DBE1C9E,0x3DCDF27B,0x3DDE7A1D, + 0x3DEFB6ED,0x3E00D62B,0x3E0A2EDA,0x3E13E72A,0x3E1E00B1,0x3E287CF2,0x3E335D55,0x3E3EA321, + 0x3E4A4F75,0x3E56633F,0x3E62DF37,0x3E6FC3D1,0x3E7D1138,0x3E8563A2,0x3E8C72B7,0x3E93B561, + 0x3E9B2AEF,0x3EA2D26F,0x3EAAAAAB,0x3EB2B222,0x3EBAE706,0x3EC34737,0x3ECBD03D,0x3ED47F46, + 0x3EDD5128,0x3EE6425C,0x3EEF4EFF,0x3EF872D7,0x3F00D4A9,0x3F0576CA,0x3F0A1D3B,0x3F0EC548, + 0x3F136C25,0x3F180EF2,0x3F1CAAC2,0x3F213CA2,0x3F25C1A5,0x3F2A36E7,0x3F2E9998,0x3F32E705, + + 0xBF371C9E,0xBF3B37FE,0xBF3F36F2,0xBF431780,0xBF46D7E6,0xBF4A76A4,0xBF4DF27C,0xBF514A6F, + 0xBF547DC5,0xBF578C03,0xBF5A74EE,0xBF5D3887,0xBF5FD707,0xBF6250DA,0xBF64A699,0xBF66D908, + 0xBF68E90E,0xBF6AD7B1,0xBF6CA611,0xBF6E5562,0xBF6FE6E7,0xBF715BEF,0xBF72B5D1,0xBF73F5E6, + 0xBF751D89,0xBF762E13,0xBF7728D7,0xBF780F20,0xBF78E234,0xBF79A34C,0xBF7A5397,0xBF7AF439, + 0xBF7B8648,0xBF7C0ACE,0xBF7C82C8,0xBF7CEF26,0xBF7D50CB,0xBF7DA88E,0xBF7DF737,0xBF7E3D86, + 0xBF7E7C2A,0xBF7EB3CC,0xBF7EE507,0xBF7F106C,0xBF7F3683,0xBF7F57CA,0xBF7F74B6,0xBF7F8DB6, + 0xBF7FA32E,0xBF7FB57B,0xBF7FC4F6,0xBF7FD1ED,0xBF7FDCAD,0xBF7FE579,0xBF7FEC90,0xBF7FF22E, + 0xBF7FF688,0xBF7FF9D0,0xBF7FFC32,0xBF7FFDDA,0xBF7FFEED,0xBF7FFF8F,0xBF7FFFDF,0xBF7FFFFC, +}; +static const float *decode5_imdct_window = (const float *)decode5_imdct_window_int; + +static void decoder5_run_imdct(stChannel *ch, int subframe) { + const static int size = HCA_SAMPLES_PER_SUBFRAME; + const static int half = HCA_SAMPLES_PER_SUBFRAME / 2; + const static int mdct_bits = HCA_MDCT_BITS; + + + /* apply DCT-IV to dequantized spectra */ + { + unsigned int i, j, k; + unsigned int count1a, count2a, count1b, count2b; + const float *temp1a, *temp1b; + float *temp2a, *temp2b; + + /* this is all too crafty for me to simplify, see VGAudio (Mdct.Dct4) */ + + temp1a = ch->spectra; + temp2a = ch->temp; + count1a = 1; + count2a = half; + for (i = 0; i < mdct_bits; i++) { + float *swap; + float *d1 = &temp2a[0]; + float *d2 = &temp2a[count2a]; + + for (j = 0; j < count1a; j++) { + for (k = 0; k < count2a; k++) { + float a = *(temp1a++); + float b = *(temp1a++); + *(d1++) = b + a; + *(d2++) = a - b; + } + d1 += count2a; + d2 += count2a; + } + swap = (float*) temp1a - HCA_SAMPLES_PER_SUBFRAME; /* move spectra/temp to beginning */ + temp1a = temp2a; + temp2a = swap; + + count1a = count1a << 1; + count2a = count2a >> 1; + } + + temp1b = ch->temp; + temp2b = ch->spectra; + count1b = half; + count2b = 1; + for (i = 0; i < mdct_bits; i++) { + const float *sin_table = (const float *) decode5_sin_tables_int[i]; + const float *cos_table = (const float *) decode5_cos_tables_int[i]; + float *swap; + float *d1 = temp2b; + float *d2 = &temp2b[count2b * 2 - 1]; + const float *s1 = &temp1b[0]; + const float *s2 = &temp1b[count2b]; + + for (j = 0; j < count1b; j++) { + for (k = 0; k < count2b; k++) { + float a = *(s1++); + float b = *(s2++); + float sin = *(sin_table++); + float cos = *(cos_table++); + *(d1++) = a * sin - b * cos; + *(d2--) = a * cos + b * sin; + } + s1 += count2b; + s2 += count2b; + d1 += count2b; + d2 += count2b * 3; + } + swap = (float*) temp1b; + temp1b = temp2b; + temp2b = swap; + + count1b = count1b >> 1; + count2b = count2b << 1; + } + + /* copy dct */ + /* (with the above optimization spectra is already modified, so this is redundant) */ + { +#if HCA_DISABLE_OPTIMIZATIONS + for (i = 0; i < size; i++) { + ch->dct[i] = ch->spectra[i]; + } +#else + float *dct = ch->dct; + const float *spectra = ch->spectra; + + for (i = 0; i < size; i++) { + *(dct++) = *(spectra++); + } +#endif + } + } + + /* update output/imdct */ + { + unsigned int i; + +#if HCA_DISABLE_OPTIMIZATIONS + /* over-optimized IMDCT (see below for standard function), slightly faster (saves ~3 secs when decoding ~150 files) */ + for (i = 0; i < half; i++) { + ch->wave[subframe][i] = decode5_imdct_window[i] * ch->dct[i + half] + ch->imdct_previous[i]; + ch->wave[subframe][i + half] = decode5_imdct_window[i + half] * ch->dct[size - 1 - i] - ch->imdct_previous[i + half]; + ch->imdct_previous[i] = decode5_imdct_window[size - 1 - i] * ch->dct[half - i - 1]; + ch->imdct_previous[i + half] = decode5_imdct_window[half - i - 1] * ch->dct[i]; + } +#else + const float *imdct_window = decode5_imdct_window; + const float *dct; + float *imdct_previous; + float *wave = ch->wave[subframe]; + + dct = &ch->dct[half]; + imdct_previous = ch->imdct_previous; + for (i = 0; i < half; i++) { + *(wave++) = *(dct++) * *(imdct_window++) + *(imdct_previous++); + } + for (i = 0; i < half; i++) { + *(wave++) = *(imdct_window++) * *(--dct) - *(imdct_previous++); + } + /* implicit: imdct_window pointer is now at end */ + dct = &ch->dct[half - 1]; + imdct_previous = ch->imdct_previous; + for (i = 0; i < half; i++) { + *(imdct_previous++) = *(--imdct_window) * *(dct--); + } + for (i = 0; i < half; i++) { + *(imdct_previous++) = *(--imdct_window) * *(++dct) ; + } +#endif + } +} + +//-------------------------------------------------- +// Main decode +//-------------------------------------------------- +int clHCA_Decode(clHCA *hca, void *data, unsigned int size, unsigned int address) { + if (!hca) + return -1; + + if (address == 0) { + return clHCA_DecodeHeader(hca, data, size); + } + else if (address >= hca->header_size) { + return clHCA_DecodeFrame(hca, data, size); + } + + return 0; }