-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathclHCA.h
285 lines (254 loc) · 7 KB
/
clHCA.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
#pragma once
//--------------------------------------------------
// インクルード
//--------------------------------------------------
#include <stdio.h>
#include <stdint.h>
#ifdef __GNUC__
#define ATTRPACK __attribute__((packed, ms_struct))
#define FUNCHOT __attribute__((hot))
#else
#define ATTRPACK
#define FUNCHOT
#endif
#ifdef _MSC_VER
#define PACKED( __Declaration__ )\
__pragma( pack(push, 1) ) \
__Declaration__ \
__pragma( pack(pop) )
#else
#define PACKED(x) x
#endif
#if (UINTPTR_MAX == UINT64_MAX)
typedef double fm_t;
#else
typedef float fm_t;
#endif
//--------------------------------------------------
// HCA(High Compression Audio)クラス
//--------------------------------------------------
class clHCA
{
public:
clHCA(uint32_t ciphKey1, uint32_t ciphKey2);
// チェック
static bool CheckFile(void* data);
// デコード
bool Decode(const char* filename, const char* filenameWAV, float volume = 1);
bool Decode(FILE* fp, void* data, size_t size);
bool Decode2(FILE* fp, FILE* fpHCA, size_t size);
bool Decode(FILE * fp, void * data, size_t size, uint32_t address, FILE * fp_hca);
bool Decode(void* fp, void* data, size_t size, uint32_t address) FUNCHOT;
private:
PACKED(
// ファイル情報
struct stHeader
{
uint32_t signature; // 'HCA'|0x00808080
uint8_t version; // バージョン(1)
uint8_t revision; // リビジョン(3)
uint16_t dataOffset; // データオフセット
} ATTRPACK;
)
static_assert(sizeof(stHeader) == 8, "stHeader size is not correct");
// フォーマット情報
PACKED(
struct stFormat
{
uint32_t fmt; // 'fmt'|0x00808080
uint32_t channelCount : 8; // チャンネル数 1~16
uint32_t samplingRate : 24; // サンプリングレート 1~0x7FFFFF
uint32_t blockCount; // ブロック数
uint16_t r14; // 不明(0xC80)
uint16_t r16; // 不明(0x226)
} ATTRPACK;
)
static_assert(sizeof(stFormat) == 16, "stFormat size is not correct");
// デコード情報
PACKED(
struct stDecode
{
uint32_t dec; // 'dec'|0x00808080
uint16_t blockSize; // ブロックサイズ(CBRのときに有効?) 8~0xFFFF、0のときはVBR
uint8_t r1E; // 不明(1) 0以上
uint8_t r1F; // 不明(15) r1E~0x1F
uint8_t count1; // type0とtype1のcount
uint8_t count2; // type2のcount
uint8_t r22; // 不明(0)
uint8_t r23; // 不明(0)
} ATTRPACK;
)
static_assert(sizeof(stDecode) == 12, "stDecode size is not correct");
PACKED(
struct stComp
{
uint32_t comp; // 'comp'|0x00808080
uint16_t blockSize;
uint8_t v8; //r1E (same as dec)
uint8_t v7; //r1F (same as dec)
uint8_t count1;
uint8_t count2;
uint8_t v9; //unknown
uint8_t v10;
uint8_t v11;
uint8_t v12;
uint8_t unk00[2];
} ATTRPACK;
)
static_assert(sizeof(stComp) == 16, "stComp size is not correct");
// 可変ビットレート情報
PACKED(
struct stVBR
{
uint32_t vbr; // 'vbr'|0x00808080
uint16_t r04; // 不明 0~0x1FF
uint16_t r06; // 不明
} ATTRPACK;
)
static_assert(sizeof(stVBR) == 8, "stVBR size is not correct");
// ATHテーブル情報
PACKED(
struct stATH
{
uint32_t ath; // 'ath'|0x00808080
uint16_t type; // テーブルの種類(0:全て0 1:テーブル1)
} ATTRPACK;
)
static_assert(sizeof(stATH) == 6, "stATH size is not correct");
// ループ情報
PACKED(
struct stLoop
{
uint32_t loop; // 'loop'|0x80808080
uint32_t loopStart; // ループ開始ブロックインデックス 0以上
uint32_t loopEnd; // ループ終了ブロックインデックス 0以上 loopStart~stFormat::blockCount-1
uint16_t r0C; // 不明(0x80)
uint16_t r0E; // 不明(0x226)
} ATTRPACK;
)
static_assert(sizeof(stLoop) == 16, "stLoop size is not correct");
// CIPHテーブル情報(ブロックデータの暗号化テーブル情報)
PACKED(
struct stCIPH
{
uint32_t ciph; // 'ciph'|0x80808080
uint16_t type; // テーブルの種類(0:暗号化なし 1:テーブル1 56:テーブル2)
} ATTRPACK;
)
static_assert(sizeof(stCIPH) == 6, "stCIPH size is not correct");
// 相対ボリューム調節情報
PACKED(
struct stRVA
{
uint32_t rva; // 'rva'|0x00808080
float volume; // ボリューム
} ATTRPACK;
)
static_assert(sizeof(stRVA) == 8, "stRVA size is not correct");
// コメント情報
PACKED(
struct stComment
{
uint32_t comm; // 'comm'|0x80808080
uint8_t r04; // 不明 文字列の長さ?
// char 文字列[];
} ATTRPACK;
)
static_assert(sizeof(stComment) == 5, "stComment size is not correct");
// パディング?
PACKED(
struct stPAD
{
uint32_t pad; // 'pad'|0x00808080
// ※サイズ不明
} ATTRPACK;
)
static_assert(sizeof(stPAD) == 4, "stPAD size is not correct");
uint32_t _version;
uint32_t _revision;
uint32_t _dataOffset;
uint32_t _channelCount;
uint32_t _samplingRate;
uint32_t _blockCount;
uint32_t _fmt_r14;
uint32_t _fmt_r16;
uint32_t _blockSize;
uint32_t _dec_r1E;
uint32_t _dec_r1F;
uint32_t _dec_count1;
uint32_t _dec_count2;
uint32_t _dec_r22;
uint32_t _dec_r23;
uint32_t _vbr_r04;
uint32_t _vbr_r06;
uint32_t _ath_type;
uint32_t _loopStart;
uint32_t _loopEnd;
uint32_t _loop_r0C;
uint32_t _loop_r0E;
uint32_t _ciph_type;
float _rva_volume;
class clATH
{
public:
clATH();
bool Init(int32_t type, uint32_t key);
uint8_t* GetTable(void);
private:
uint8_t _table[0x80];
void Init0(void);
void Init1(uint32_t key);
} _ath;
class clCIPH
{
public:
clCIPH();
bool Init(int32_t type, uint32_t key1, uint32_t key2);
void Mask(void* data, int32_t size) FUNCHOT;
private:
uint8_t _table[0x100];
void Init0(void);
void Init1(void);
void Init56(uint32_t key1, uint32_t key2);
void Init56_CreateTable(uint8_t* table, uint8_t key);
} _ciph;
class clData
{
public:
clData(void* data, int32_t size);
int32_t CheckBit(int32_t bitSize) FUNCHOT;
int32_t GetBit(int32_t bitSize) FUNCHOT;
void AddBit(int32_t bitSize) FUNCHOT;
private:
uint8_t* _data;
int32_t _size;
int32_t _bit;
};
bool InitDecode(int32_t channelCount, int32_t a, int32_t b, int32_t count1, int32_t count2, int32_t e, int32_t f);
void Decode(clData* data);
struct stChannel
{
fm_t wave[8][0x80];
fm_t base[0x80];
fm_t block[0x80];
fm_t wav1[0x80];
fm_t wav2[0x80];
fm_t wav3[0x80];
uint8_t value[0x80];
uint8_t scale[0x80];
uint8_t value2[8];
int32_t type;
int32_t count;
void Decode1(clData* data) FUNCHOT;
void Decode2(int32_t a, int32_t b, uint8_t* ath) FUNCHOT;
void Decode3(void) FUNCHOT;
void Decode4(clData* data) FUNCHOT;
void Decode5(int32_t index) FUNCHOT;
void Decode6(void) FUNCHOT;
void Decode7(void) FUNCHOT;
void Decode8(int32_t index) FUNCHOT;
} _channel[0x10];
uint32_t _ciph_key1;
uint32_t _ciph_key2;
static uint16_t CheckSum(void* data, int32_t size, uint16_t sum = 0);
};