Mercurial > otakunoraifu
annotate music2/koedec.cc @ 66:d112357a0ec1
Fix a bug with savegames introduced with changeset c7bcc0ec2267.
Warning: savegames created since c7bcc0ec2267 are probably corrupted,
you may have to start the game over.
If you chose not to do so, you should replace all occurrences of 'TextWindow' by 'TextImplWindow',
and 'Text Window' by 'TextImpl Window' in your save files.
author | Thibaut Girka <thib@sitedethib.com> |
---|---|
date | Sat, 11 Dec 2010 18:36:20 +0100 |
parents | 4416cfac86ae |
children |
rev | line source |
---|---|
0 | 1 /* |
2 * Copyright (c) 2004-2006 Kazunori "jagarl" Ueno | |
3 * All rights reserved. | |
4 * | |
5 * Redistribution and use in source and binary forms, with or without | |
6 * modification, are permitted provided that the following conditions | |
7 * are met: | |
8 * 1. Redistributions of source code must retain the above copyright | |
9 * notice, this list of conditions and the following disclaimer. | |
10 * 2. Redistributions in binary form must reproduce the above copyright | |
11 * notice, this list of conditions and the following disclaimer in the | |
12 * documentation and/or other materials provided with the distribution. | |
13 * 3. The name of the author may not be used to endorse or promote products | |
14 * derived from this software without specific prior written permission. | |
15 * | |
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | |
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | |
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | |
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
26 */ | |
27 | |
52 | 28 #include <stdio.h> |
29 #include <stdlib.h> | |
30 #include <string.h> | |
0 | 31 #include <vector> |
32 #include <list> | |
33 #include <algorithm> | |
52 | 34 #include "music.h" |
35 #include "system/file.h" | |
36 #include "system/file_impl.h" | |
0 | 37 |
38 using namespace std; | |
39 | |
40 /********************************************* | |
41 ** | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
53
diff
changeset
|
42 ** FindKoe -- RealLiveの音声アーカイブ処理 |
0 | 43 ** |
44 */ | |
45 | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
53
diff
changeset
|
46 /* 声ファイルのアーカイブ用のキャッシュ */ |
0 | 47 #define koe_cache_size 7 |
48 struct AvgKoeTable { | |
49 int koe_num; | |
50 int length; | |
51 int offset; | |
52 AvgKoeTable(int _num, int _len, int _off) : | |
53 koe_num(_num), length(_len), offset(_off) {} | |
54 bool operator <(int number) const { | |
55 return koe_num < number; | |
56 } | |
57 bool operator <(const AvgKoeTable& to) const { | |
58 return koe_num < to.koe_num; | |
59 } | |
60 bool operator ==(const AvgKoeTable& to) const { | |
61 return koe_num == to.koe_num; | |
62 } | |
63 bool operator ==(const int to) const { | |
64 return koe_num == to; | |
65 } | |
66 }; | |
52 | 67 |
0 | 68 struct AvgKoeHead { |
69 FILE* stream; | |
70 int file_number; | |
71 int rate; | |
72 KoeType type; | |
73 vector<AvgKoeTable> table; | |
74 AvgKoeHead(FILE* stream, int file_number, KoeType type); | |
75 AvgKoeHead(const AvgKoeHead& from); | |
76 ~AvgKoeHead(); | |
77 AvgKoeTable* Find(int koe_num); | |
78 bool operator !=(int num) const { return file_number != num; } | |
79 bool operator ==(int num) const { return file_number == num; } | |
80 }; | |
52 | 81 |
0 | 82 struct AvgKoeCache { |
83 list<AvgKoeHead> cache; | |
84 AvgKoeInfo Find(int file_number, int index); | |
85 }; | |
52 | 86 |
0 | 87 static AvgKoeCache koe_cache; |
88 | |
89 AvgKoeInfo FindKoe(int file_number, int index) { | |
90 return koe_cache.Find(file_number, index); | |
52 | 91 } |
45
53a311ea8289
Patched an old patch of mine (OGG koe files handling)... It's a bit less ugly, and it works with tremor!
thib
parents:
43
diff
changeset
|
92 |
0 | 93 AvgKoeInfo AvgKoeCache::Find(int file_number, int index) { |
94 AvgKoeInfo info; | |
52 | 95 info.stream = NULL; |
96 info.length = 0; | |
97 info.offset = 0; | |
0 | 98 |
53
ddbcbd000206
* MuSys, AyuSysConfig, FileSearcher (former FILESEARCHER) and KeyHolder (former KEYHOLDER) are now singletons
thib
parents:
52
diff
changeset
|
99 FileSearcher* file_searcher = FileSearcher::GetInstance(); |
ddbcbd000206
* MuSys, AyuSysConfig, FileSearcher (former FILESEARCHER) and KeyHolder (former KEYHOLDER) are now singletons
thib
parents:
52
diff
changeset
|
100 |
0 | 101 list<AvgKoeHead>::iterator it; |
102 it = find(cache.begin(), cache.end(), file_number); | |
103 if (it == cache.end()) { | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
53
diff
changeset
|
104 /* 新たに head を作る */ |
0 | 105 char fname[100]; |
106 KoeType type = koe_unknown; | |
107 sprintf(fname, "z%03d.koe", file_number); | |
53
ddbcbd000206
* MuSys, AyuSysConfig, FileSearcher (former FILESEARCHER) and KeyHolder (former KEYHOLDER) are now singletons
thib
parents:
52
diff
changeset
|
108 ARCINFO* arcinfo = file_searcher->Find(FileSearcher::KOE,fname,".koe"); |
52 | 109 if (arcinfo == NULL) { |
0 | 110 type = koe_nwk; |
111 sprintf(fname, "z%04d.nwk", file_number); | |
53
ddbcbd000206
* MuSys, AyuSysConfig, FileSearcher (former FILESEARCHER) and KeyHolder (former KEYHOLDER) are now singletons
thib
parents:
52
diff
changeset
|
112 arcinfo = file_searcher->Find(FileSearcher::KOE,fname,".nwk"); |
0 | 113 } |
52 | 114 if (arcinfo == NULL) { |
0 | 115 type = koe_ovk; |
116 sprintf(fname, "z%04d.ovk", file_number); | |
53
ddbcbd000206
* MuSys, AyuSysConfig, FileSearcher (former FILESEARCHER) and KeyHolder (former KEYHOLDER) are now singletons
thib
parents:
52
diff
changeset
|
117 arcinfo = file_searcher->Find(FileSearcher::KOE,fname,".ovk"); |
0 | 118 } |
24 | 119 #if HAVE_LIBVORBISFILE || HAVE_LIBVORBISIDEC |
52 | 120 if (arcinfo == NULL) { |
45
53a311ea8289
Patched an old patch of mine (OGG koe files handling)... It's a bit less ugly, and it works with tremor!
thib
parents:
43
diff
changeset
|
121 //FIXME: OMG that's ugly, improve it as soon as you can! |
53
ddbcbd000206
* MuSys, AyuSysConfig, FileSearcher (former FILESEARCHER) and KeyHolder (former KEYHOLDER) are now singletons
thib
parents:
52
diff
changeset
|
122 DIRFILE* koedir = (DIRFILE*) file_searcher->MakeARCFILE((FileSearcher::ARCTYPE)0, "koe"); |
2
422f3cb3614b
Enabled voice playing with "%04d/%04d%05d.ogg" format. Don't use a cache for this
thib
parents:
0
diff
changeset
|
123 sprintf(fname, "%04d", file_number); |
50 | 124 char* dirname = koedir->SearchFile(fname); |
125 delete koedir; | |
126 koedir = new DIRFILE(dirname); | |
127 delete[] dirname; | |
2
422f3cb3614b
Enabled voice playing with "%04d/%04d%05d.ogg" format. Don't use a cache for this
thib
parents:
0
diff
changeset
|
128 sprintf(fname, "z%04d%05d.ogg", file_number, index); |
422f3cb3614b
Enabled voice playing with "%04d/%04d%05d.ogg" format. Don't use a cache for this
thib
parents:
0
diff
changeset
|
129 arcinfo = koedir->Find(fname, ".ogg"); |
422f3cb3614b
Enabled voice playing with "%04d/%04d%05d.ogg" format. Don't use a cache for this
thib
parents:
0
diff
changeset
|
130 delete koedir; |
45
53a311ea8289
Patched an old patch of mine (OGG koe files handling)... It's a bit less ugly, and it works with tremor!
thib
parents:
43
diff
changeset
|
131 |
52 | 132 if (arcinfo == NULL) return info; |
45
53a311ea8289
Patched an old patch of mine (OGG koe files handling)... It's a bit less ugly, and it works with tremor!
thib
parents:
43
diff
changeset
|
133 FILE* stream = arcinfo->OpenFile(&info.length); |
50 | 134 delete arcinfo; |
2
422f3cb3614b
Enabled voice playing with "%04d/%04d%05d.ogg" format. Don't use a cache for this
thib
parents:
0
diff
changeset
|
135 info.type = koe_ogg; |
422f3cb3614b
Enabled voice playing with "%04d/%04d%05d.ogg" format. Don't use a cache for this
thib
parents:
0
diff
changeset
|
136 info.stream = stream; |
422f3cb3614b
Enabled voice playing with "%04d/%04d%05d.ogg" format. Don't use a cache for this
thib
parents:
0
diff
changeset
|
137 return info; |
422f3cb3614b
Enabled voice playing with "%04d/%04d%05d.ogg" format. Don't use a cache for this
thib
parents:
0
diff
changeset
|
138 } |
24 | 139 #endif |
52 | 140 if (arcinfo == NULL) return info; |
0 | 141 FILE* stream = arcinfo->OpenFile(); |
142 delete arcinfo; | |
52 | 143 if (stream == NULL) return info; |
0 | 144 cache.push_front(AvgKoeHead(stream, file_number, type)); |
145 if (cache.size() >= koe_cache_size) cache.pop_back(); | |
146 it = cache.begin(); | |
147 } | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
53
diff
changeset
|
148 if (it->file_number != file_number) return info; // 番号がおかしい |
0 | 149 AvgKoeTable* table = it->Find(index); |
52 | 150 //FIXME: table == NULL ? |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
53
diff
changeset
|
151 if (table == 0) return info; // index が見付からない |
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
53
diff
changeset
|
152 // info を作成する |
0 | 153 info.length = table->length; |
154 info.offset = table->offset; | |
155 info.rate = it->rate; | |
156 info.type = it->type; | |
157 int new_fd = dup(fileno(it->stream)); | |
52 | 158 if (new_fd == -1) info.stream = NULL; |
0 | 159 else info.stream = fdopen(new_fd, "rb"); |
160 return info; | |
161 } | |
162 | |
163 AvgKoeHead::AvgKoeHead(const AvgKoeHead& from) { | |
164 if (from.stream) { | |
165 int new_fd = dup(fileno(from.stream)); | |
52 | 166 if (new_fd == -1) stream = NULL; |
0 | 167 else stream = fdopen(new_fd, "rb"); |
168 } | |
169 file_number = from.file_number; | |
170 rate = from.rate; | |
171 table = from.table; | |
172 type = from.type; | |
173 } | |
2
422f3cb3614b
Enabled voice playing with "%04d/%04d%05d.ogg" format. Don't use a cache for this
thib
parents:
0
diff
changeset
|
174 |
0 | 175 AvgKoeHead::AvgKoeHead(FILE* _s, int _file_number, KoeType _type) { |
176 char head[0x20]; | |
177 stream = _s; file_number = _file_number; | |
43
01aa5ddf7dc8
A lot of very minor improvements (deleted some unused variables, and other things like that...)
thib
parents:
24
diff
changeset
|
178 //int offset = ftell(stream); |
0 | 179 rate = 22050; |
180 type = _type; | |
52 | 181 if (stream == NULL) return; |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
53
diff
changeset
|
182 /* header 読み込み */ |
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
53
diff
changeset
|
183 if (type == koe_nwk) { // 新しい形式 : .nwk file |
0 | 184 rate = 44100; |
185 fread(head, 4, 1, stream); | |
186 int table_len = read_little_endian_int(head); | |
187 table.reserve(table_len); | |
188 int i; | |
189 for (i=0; i<table_len; i++) { | |
190 fread(head, 12, 1, stream); | |
191 int sz = read_little_endian_int(head); | |
192 int off = read_little_endian_int(head+4); | |
193 int cnt = read_little_endian_int(head+8); | |
194 table.push_back(AvgKoeTable(cnt, sz, off)); | |
195 } | |
196 } else if (type == koe_ovk) { // Little Busters! : .ovk file | |
197 rate = 44100; | |
198 fread(head, 4, 1, stream); | |
199 int table_len = read_little_endian_int(head); | |
200 table.reserve(table_len); | |
201 int i; | |
202 for (i=0; i<table_len; i++) { | |
203 fread(head, 16, 1, stream); | |
204 int sz = read_little_endian_int(head); | |
205 int off = read_little_endian_int(head+4); | |
206 int cnt = read_little_endian_int(head+8); | |
207 table.push_back(AvgKoeTable(cnt, sz, off)); | |
208 } | |
209 } else { // .koe file | |
210 fread(head, 0x20, 1, stream); | |
211 if (strncmp(head, "KOEPAC", 7) != 0) { // invalid header | |
52 | 212 stream = NULL; |
0 | 213 return; |
214 } | |
215 int table_len = read_little_endian_int(head+0x10); | |
216 rate = read_little_endian_int(head+0x18); | |
217 if (rate == 0) rate = 22050; | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
53
diff
changeset
|
218 /* table 読み込み */ |
0 | 219 table.reserve(table_len); |
220 char* buf = new char[table_len*8]; | |
221 fread(buf, table_len, 8, stream); | |
222 int i; for (i=0; i<table_len; i++) { | |
223 int cnt = read_little_endian_short(buf+i*8); | |
224 int sz = read_little_endian_short(buf+i*8+2); | |
225 int off = read_little_endian_int(buf+i*8+4); | |
226 table.push_back(AvgKoeTable(cnt, sz, off)); | |
227 } | |
228 } | |
229 sort(table.begin(), table.end()); | |
230 } | |
231 | |
232 AvgKoeHead::~AvgKoeHead(void) { | |
233 if (stream) fclose(stream); | |
52 | 234 stream = NULL; |
0 | 235 } |
52 | 236 |
0 | 237 AvgKoeTable* AvgKoeHead::Find(int koe_num) { |
52 | 238 if (table.empty()) return NULL; |
0 | 239 vector<AvgKoeTable>::iterator it; |
240 it = lower_bound(table.begin(), table.end(), koe_num); | |
52 | 241 if (it == table.end() || it->koe_num != koe_num) return NULL; |
0 | 242 return &table[it-table.begin()]; |
243 } | |
244 | |
245 /********************************************* | |
246 ** | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
53
diff
changeset
|
247 ** MakeWavHeader : koe ファイルに wave header を付ける |
0 | 248 ** |
249 */ | |
250 | |
251 static unsigned char orig_header[0x2c] = { | |
252 0x52, 0x49, 0x46, 0x46, /* +00 "RIFF" */ | |
253 0x00, 0x00, 0x00, 0x00, /* +04 file size - 8 */ | |
254 0x57, 0x41, 0x56, 0x45, 0x66, 0x6d, 0x74, 0x20, /* +08 "WAVEfmt " */ | |
255 0x10, 0x00, 0x00, 0x00, /* +10 fmt size */ | |
256 0x01, 0x00, /* +14 wFormatTag */ | |
257 0x02, 0x00, /* +16 Channels */ | |
258 0x44, 0xac, 0x00, 0x00, /* +18 rate */ | |
259 0x10, 0xb1, 0x02, 0x00, /* +1c BytesPerSec = rate * BlockAlign */ | |
260 0x04, 0x00, /* +20 BlockAlign = channels*BytesPerSample */ | |
261 0x10, 0x00, /* +22 BitsPerSample */ | |
262 0x64, 0x61, 0x74, 0x61, /* +24 "data" */ | |
263 0x00, 0x00, 0x00, 0x00 /* +28 filesize - 0x2c */ | |
264 }; | |
265 | |
266 const char* MakeWavHeader(int rate, int ch, int bps, int size) { | |
267 static char header[0x2c]; | |
268 memcpy(header, (const char*)orig_header, 0x2c); | |
269 write_little_endian_int(header+0x04, size-8); | |
270 write_little_endian_int(header+0x28, size-0x2c); | |
271 write_little_endian_int(header+0x18, rate); | |
272 write_little_endian_int(header+0x1c, rate*ch*bps); | |
273 header[0x16] = ch; | |
274 header[0x20] = ch*bps; | |
275 header[0x22] = bps*8; | |
276 return header; | |
277 } | |
278 | |
279 /********************************************* | |
280 ** | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
53
diff
changeset
|
281 ** decode_koe -- 音声データ展開 |
0 | 282 ** |
283 */ | |
284 | |
285 extern char* decode_koe(AvgKoeInfo info, int* len); | |
286 | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
53
diff
changeset
|
287 /* 8bit -> 16bit への変換テーブル。本来は signed short だが |
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
53
diff
changeset
|
288 ** とりあえず unsigned で扱っている |
0 | 289 */ |
290 | |
291 unsigned short koe_8bit_trans_tbl[256] = { | |
292 0x8000,0x81ff,0x83f9,0x85ef,0x87e1,0x89cf,0x8bb9,0x8d9f, | |
293 0x8f81,0x915f,0x9339,0x950f,0x96e1,0x98af,0x9a79,0x9c3f, | |
294 0x9e01,0x9fbf,0xa179,0xa32f,0xa4e1,0xa68f,0xa839,0xa9df, | |
295 0xab81,0xad1f,0xaeb9,0xb04f,0xb1e1,0xb36f,0xb4f9,0xb67f, | |
296 0xb801,0xb97f,0xbaf9,0xbc6f,0xbde1,0xbf4f,0xc0b9,0xc21f, | |
297 0xc381,0xc4df,0xc639,0xc78f,0xc8e1,0xca2f,0xcb79,0xccbf, | |
298 0xce01,0xcf3f,0xd079,0xd1af,0xd2e1,0xd40f,0xd539,0xd65f, | |
299 0xd781,0xd89f,0xd9b9,0xdacf,0xdbe1,0xdcef,0xddf9,0xdeff, | |
300 0xe001,0xe0ff,0xe1f9,0xe2ef,0xe3e1,0xe4cf,0xe5b9,0xe69f, | |
301 0xe781,0xe85f,0xe939,0xea0f,0xeae1,0xebaf,0xec79,0xed3f, | |
302 0xee01,0xeebf,0xef79,0xf02f,0xf0e1,0xf18f,0xf239,0xf2df, | |
303 0xf381,0xf41f,0xf4b9,0xf54f,0xf5e1,0xf66f,0xf6f9,0xf77f, | |
304 0xf801,0xf87f,0xf8f9,0xf96f,0xf9e1,0xfa4f,0xfab9,0xfb1f, | |
305 0xfb81,0xfbdf,0xfc39,0xfc8f,0xfce1,0xfd2f,0xfd79,0xfdbf, | |
306 0xfe01,0xfe3f,0xfe79,0xfeaf,0xfee1,0xff0f,0xff39,0xff5f, | |
307 0xff81,0xff9f,0xffb9,0xffcf,0xffe1,0xffef,0xfff9,0xffff, | |
308 0x0000,0x0001,0x0007,0x0011,0x001f,0x0031,0x0047,0x0061, | |
309 0x007f,0x00a1,0x00c7,0x00f1,0x011f,0x0151,0x0187,0x01c1, | |
310 0x01ff,0x0241,0x0287,0x02d1,0x031f,0x0371,0x03c7,0x0421, | |
311 0x047f,0x04e1,0x0547,0x05b1,0x061f,0x0691,0x0707,0x0781, | |
312 0x07ff,0x0881,0x0907,0x0991,0x0a1f,0x0ab1,0x0b47,0x0be1, | |
313 0x0c7f,0x0d21,0x0dc7,0x0e71,0x0f1f,0x0fd1,0x1087,0x1141, | |
314 0x11ff,0x12c1,0x1387,0x1451,0x151f,0x15f1,0x16c7,0x17a1, | |
315 0x187f,0x1961,0x1a47,0x1b31,0x1c1f,0x1d11,0x1e07,0x1f01, | |
316 0x1fff,0x2101,0x2207,0x2311,0x241f,0x2531,0x2647,0x2761, | |
317 0x287f,0x29a1,0x2ac7,0x2bf1,0x2d1f,0x2e51,0x2f87,0x30c1, | |
318 0x31ff,0x3341,0x3487,0x35d1,0x371f,0x3871,0x39c7,0x3b21, | |
319 0x3c7f,0x3de1,0x3f47,0x40b1,0x421f,0x4391,0x4507,0x4681, | |
320 0x47ff,0x4981,0x4b07,0x4c91,0x4e1f,0x4fb1,0x5147,0x52e1, | |
321 0x547f,0x5621,0x57c7,0x5971,0x5b1f,0x5cd1,0x5e87,0x6041, | |
322 0x61ff,0x63c1,0x6587,0x6751,0x691f,0x6af1,0x6cc7,0x6ea1, | |
323 0x707f,0x7261,0x7447,0x7631,0x781f,0x7a11,0x7c07,0x7fff | |
324 }; | |
325 | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
53
diff
changeset
|
326 /* ADPCM・・・じゃないらしい。ただのDPCMのナめたテーブル。 |
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
53
diff
changeset
|
327 ** 自動生成すりゃいいんだけど256byteだったら |
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
53
diff
changeset
|
328 ** テーブルでも問題ないでしょ |
0 | 329 */ |
330 | |
331 char koe_ad_trans_tbl[256] = { | |
332 0x00,0xff,0x01,0xfe,0x02,0xfd,0x03,0xfc,0x04,0xfb,0x05,0xfa,0x06,0xf9,0x07,0xf8, | |
333 0x08,0xf7,0x09,0xf6,0x0a,0xf5,0x0b,0xf4,0x0c,0xf3,0x0d,0xf2,0x0e,0xf1,0x0f,0xf0, | |
334 0x10,0xef,0x11,0xee,0x12,0xed,0x13,0xec,0x14,0xeb,0x15,0xea,0x16,0xe9,0x17,0xe8, | |
335 0x18,0xe7,0x19,0xe6,0x1a,0xe5,0x1b,0xe4,0x1c,0xe3,0x1d,0xe2,0x1e,0xe1,0x1f,0xe0, | |
336 0x20,0xdf,0x21,0xde,0x22,0xdd,0x23,0xdc,0x24,0xdb,0x25,0xda,0x26,0xd9,0x27,0xd8, | |
337 0x28,0xd7,0x29,0xd6,0x2a,0xd5,0x2b,0xd4,0x2c,0xd3,0x2d,0xd2,0x2e,0xd1,0x2f,0xd0, | |
338 0x30,0xcf,0x31,0xce,0x32,0xcd,0x33,0xcc,0x34,0xcb,0x35,0xca,0x36,0xc9,0x37,0xc8, | |
339 0x38,0xc7,0x39,0xc6,0x3a,0xc5,0x3b,0xc4,0x3c,0xc3,0x3d,0xc2,0x3e,0xc1,0x3f,0xc0, | |
340 0x40,0xbf,0x41,0xbe,0x42,0xbd,0x43,0xbc,0x44,0xbb,0x45,0xba,0x46,0xb9,0x47,0xb8, | |
341 0x48,0xb7,0x49,0xb6,0x4a,0xb5,0x4b,0xb4,0x4c,0xb3,0x4d,0xb2,0x4e,0xb1,0x4f,0xb0, | |
342 0x50,0xaf,0x51,0xae,0x52,0xad,0x53,0xac,0x54,0xab,0x55,0xaa,0x56,0xa9,0x57,0xa8, | |
343 0x58,0xa7,0x59,0xa6,0x5a,0xa5,0x5b,0xa4,0x5c,0xa3,0x5d,0xa2,0x5e,0xa1,0x5f,0xa0, | |
344 0x60,0x9f,0x61,0x9e,0x62,0x9d,0x63,0x9c,0x64,0x9b,0x65,0x9a,0x66,0x99,0x67,0x98, | |
345 0x68,0x97,0x69,0x96,0x6a,0x95,0x6b,0x94,0x6c,0x93,0x6d,0x92,0x6e,0x91,0x6f,0x90, | |
346 0x70,0x8f,0x71,0x8e,0x72,0x8d,0x73,0x8c,0x74,0x8b,0x75,0x8a,0x76,0x89,0x77,0x88, | |
347 0x78,0x87,0x79,0x86,0x7a,0x85,0x7b,0x84,0x7c,0x83,0x7d,0x82,0x7e,0x81,0x7f,0x80 | |
348 }; | |
349 | |
350 extern int is_koe_ogg(char* head); | |
351 extern char* decode_koe_ogg(AvgKoeInfo info, int* dest_len); | |
352 | |
353 char* decode_koe(AvgKoeInfo info, int* dest_len) { | |
52 | 354 char buf[1024]; |
355 char* table; | |
0 | 356 unsigned char* src_orig, *src; |
357 unsigned short* dest_orig, *dest; | |
52 | 358 int all_len, i, j; |
0 | 359 if (info.stream == NULL) { |
360 return NULL; | |
361 } | |
52 | 362 fseek(info.stream, info.offset, SEEK_SET); |
0 | 363 if (info.type == koe_nwk) { |
364 return decode_koe_nwa(info, dest_len); | |
365 } | |
366 fread(buf, 1, 0x20, info.stream); | |
367 if (is_koe_ogg(buf)) { | |
52 | 368 fseek(info.stream, -20, SEEK_CUR); |
0 | 369 return decode_koe_ogg(info, dest_len); |
370 } | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
53
diff
changeset
|
371 /* avg32 の声データ展開 */ |
0 | 372 table = (char*)malloc(info.length*2); |
52 | 373 fseek(info.stream, info.offset, SEEK_SET); |
0 | 374 fread(table, 2, info.length, info.stream); |
375 | |
376 all_len = 0; | |
52 | 377 for (i=0; i < info.length; i++) |
0 | 378 all_len += read_little_endian_short(table + i*2); |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
53
diff
changeset
|
379 /* データ読み込み */ |
0 | 380 src_orig = (unsigned char*) malloc(all_len); |
381 dest_orig = (unsigned short*)malloc(info.length * 0x1000 + 0x2c); | |
382 if (src_orig == NULL || dest_orig == NULL) return NULL; | |
383 src = src_orig; | |
384 fread(src, 1, all_len, info.stream); | |
385 *dest_len = info.length * 0x400 * 4; | |
386 const char* header = MakeWavHeader(info.rate, 2, 2, *dest_len); | |
387 memcpy(dest_orig, header, 0x2c); | |
388 dest = dest_orig + 0x2c; | |
389 /* memset(dest_data, 0, table_len * 0x1000); */ | |
390 | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
53
diff
changeset
|
391 /* 展開 */ |
0 | 392 for (i=0; i<info.length; i++) { |
393 int slen = read_little_endian_short(table+i*2); | |
394 if (slen == 0) { // do nothing | |
395 memset(dest, 0, 0x1000); | |
396 dest += 0x800; src += 0; | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
53
diff
changeset
|
397 } else if (slen == 0x400) { // table 変換 |
0 | 398 for (j=0; j<0x400; j++) { |
399 write_little_endian_short((char*)(dest+0), koe_8bit_trans_tbl[*src]); | |
400 write_little_endian_short((char*)(dest+1), koe_8bit_trans_tbl[*src]); | |
401 dest += 2; src++; | |
402 } | |
403 } else { // DPCM | |
404 char d = 0; short o2; | |
405 int k,j; for (j=0, k=0; j<slen && k < 0x800; j++) { | |
406 unsigned char s = src[j]; | |
407 if ( (s+1) & 0x0f) { | |
408 d -= koe_ad_trans_tbl[s & 0x0f]; | |
409 } else { | |
410 unsigned char s2; | |
411 s >>= 4; s &= 0x0f; s2 = s; | |
412 s = src[++j]; s2 |= (s<<4) & 0xf0; | |
413 d -= koe_ad_trans_tbl[s2]; | |
414 } | |
415 o2 = koe_8bit_trans_tbl[ (unsigned char)d]; | |
416 write_little_endian_short((char*)(dest+k), o2); | |
417 write_little_endian_short((char*)(dest+k+1), o2); | |
418 k+=2; | |
419 s >>= 4; | |
420 if ((s+1) & 0x0f) { | |
421 d -= koe_ad_trans_tbl[s & 0x0f]; | |
422 } else { | |
423 d -= koe_ad_trans_tbl[ src[++j] ]; | |
424 } | |
425 o2 = koe_8bit_trans_tbl[ (unsigned char)d]; | |
426 write_little_endian_short((char*)(dest+k), o2); | |
427 write_little_endian_short((char*)(dest+k+1), o2); | |
428 k+=2; | |
429 } | |
430 dest += 0x800; src += slen; | |
431 } | |
432 } | |
433 free( (void*) table); | |
434 free( (void*) src_orig); | |
435 return (char*)dest_orig; | |
436 } | |
437 | |
438 |