comparison Plugins/Input/adplug/core/cff.cpp @ 359:8df427a314a8 trunk

[svn] Adlib synthesizer (AdPlug) support.
author chainsaw
date Fri, 30 Dec 2005 16:31:39 -0800
parents
children c71e2ef2dcf4
comparison
equal deleted inserted replaced
358:70075730e187 359:8df427a314a8
1 /*
2 AdPlug - Replayer for many OPL2/OPL3 audio file formats.
3 Copyright (C) 1999 - 2002 Simon Peter <dn.tlp@gmx.net>, et al.
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19 cff.cpp - BoomTracker loader by Riven the Mage <riven@ok.ru>
20 */
21 /*
22 NOTE: Conversion of slides is not 100% accurate. Original volume slides
23 have effect on carrier volume only. Also, original arpeggio, frequency & volume
24 slides use previous effect data instead of current.
25 */
26
27 #include <stdlib.h>
28
29 #include "cff.h"
30
31 /* -------- Public Methods -------------------------------- */
32
33 CPlayer *CcffLoader::factory(Copl *newopl)
34 {
35 return new CcffLoader(newopl);
36 }
37
38 bool CcffLoader::load(const std::string &filename, const CFileProvider &fp)
39 {
40 binistream *f = fp.open(filename); if(!f) return false;
41 const unsigned char conv_inst[11] = { 2,1,10,9,4,3,6,5,0,8,7 };
42 const unsigned short conv_note[12] = { 0x16B, 0x181, 0x198, 0x1B0, 0x1CA, 0x1E5, 0x202, 0x220, 0x241, 0x263, 0x287, 0x2AE };
43
44 int i,j,k,t=0;
45
46 // '<CUD-FM-File>' - signed ?
47 f->readString(header.id, 16);
48 header.version = f->readInt(1); header.size = f->readInt(2);
49 header.packed = f->readInt(1); f->readString((char *)header.reserved, 12);
50 if (memcmp(header.id,"<CUD-FM-File>""\x1A\xDE\xE0",16))
51 { fp.close(f); return false; }
52
53 unsigned char *module = new unsigned char [0x10000];
54
55 // packed ?
56 if (header.packed)
57 {
58 cff_unpacker *unpacker = new cff_unpacker;
59
60 unsigned char *packed_module = new unsigned char [header.size + 4];
61
62 memset(packed_module,0,header.size + 4);
63
64 f->readString((char *)packed_module, header.size);
65 fp.close(f);
66
67 if (!unpacker->unpack(packed_module,module))
68 {
69 delete unpacker;
70 delete packed_module;
71 delete module;
72 return false;
73 }
74
75 delete unpacker;
76 delete packed_module;
77
78 if (memcmp(&module[0x5E1],"CUD-FM-File - SEND A POSTCARD -",31))
79 {
80 delete module;
81 return false;
82 }
83 }
84 else
85 {
86 f->readString((char *)module, header.size);
87 fp.close(f);
88 }
89
90 // init CmodPlayer
91 realloc_instruments(47);
92 realloc_order(64);
93 realloc_patterns(36,64,9);
94 init_notetable(conv_note);
95 init_trackord();
96
97 // load instruments
98 for (i=0;i<47;i++)
99 {
100 memcpy(&instruments[i],&module[i*32],sizeof(cff_instrument));
101
102 for (j=0;j<11;j++)
103 inst[i].data[conv_inst[j]] = instruments[i].data[j];
104
105 instruments[i].name[20] = 0;
106 }
107
108 // number of patterns
109 nop = module[0x5E0];
110
111 // load title & author
112 memcpy(song_title,&module[0x614],20);
113 memcpy(song_author,&module[0x600],20);
114
115 // load order
116 memcpy(order,&module[0x628],64);
117
118 // load tracks
119 for (i=0;i<nop;i++)
120 {
121 unsigned char old_event_byte2[9];
122
123 memset(old_event_byte2,0,9);
124
125 for (j=0;j<9;j++)
126 {
127 for (k=0;k<64;k++)
128 {
129 cff_event *event = (cff_event *)&module[0x669 + ((i*64+k)*9+j)*3];
130
131 // convert note
132 if (event->byte0 == 0x6D)
133 tracks[t][k].note = 127;
134 else
135 if (event->byte0)
136 tracks[t][k].note = event->byte0;
137
138 if (event->byte2)
139 old_event_byte2[j] = event->byte2;
140
141 // convert effect
142 switch (event->byte1)
143 {
144 case 'I': // set instrument
145 tracks[t][k].inst = event->byte2 + 1;
146 tracks[t][k].param1 = tracks[t][k].param2 = 0;
147 break;
148
149 case 'H': // set tempo
150 tracks[t][k].command = 7;
151 if (event->byte2 < 16)
152 {
153 tracks[t][k].param1 = 0x07;
154 tracks[t][k].param2 = 0x0D;
155 }
156 break;
157
158 case 'A': // set speed
159 tracks[t][k].command = 19;
160 tracks[t][k].param1 = event->byte2 >> 4;
161 tracks[t][k].param2 = event->byte2 & 15;
162 break;
163
164 case 'L': // pattern break
165 tracks[t][k].command = 13;
166 tracks[t][k].param1 = event->byte2 >> 4;
167 tracks[t][k].param2 = event->byte2 & 15;
168 break;
169
170 case 'K': // order jump
171 tracks[t][k].command = 11;
172 tracks[t][k].param1 = event->byte2 >> 4;
173 tracks[t][k].param2 = event->byte2 & 15;
174 break;
175
176 case 'M': // set vibrato/tremolo
177 tracks[t][k].command = 27;
178 tracks[t][k].param1 = event->byte2 >> 4;
179 tracks[t][k].param2 = event->byte2 & 15;
180 break;
181
182 case 'C': // set modulator volume
183 tracks[t][k].command = 21;
184 tracks[t][k].param1 = (0x3F - event->byte2) >> 4;
185 tracks[t][k].param2 = (0x3F - event->byte2) & 15;
186 break;
187
188 case 'G': // set carrier volume
189 tracks[t][k].command = 22;
190 tracks[t][k].param1 = (0x3F - event->byte2) >> 4;
191 tracks[t][k].param2 = (0x3F - event->byte2) & 15;
192 break;
193
194 case 'B': // set carrier waveform
195 tracks[t][k].command = 25;
196 tracks[t][k].param1 = event->byte2;
197 tracks[t][k].param2 = 0x0F;
198 break;
199
200 case 'E': // fine frequency slide down
201 tracks[t][k].command = 24;
202 tracks[t][k].param1 = old_event_byte2[j] >> 4;
203 tracks[t][k].param2 = old_event_byte2[j] & 15;
204 break;
205
206 case 'F': // fine frequency slide up
207 tracks[t][k].command = 23;
208 tracks[t][k].param1 = old_event_byte2[j] >> 4;
209 tracks[t][k].param2 = old_event_byte2[j] & 15;
210 break;
211
212 case 'D': // fine volume slide
213 tracks[t][k].command = 14;
214 if (old_event_byte2[j] & 15)
215 {
216 // slide down
217 tracks[t][k].param1 = 5;
218 tracks[t][k].param2 = old_event_byte2[j] & 15;
219 }
220 else
221 {
222 // slide up
223 tracks[t][k].param1 = 4;
224 tracks[t][k].param2 = old_event_byte2[j] >> 4;
225 }
226 break;
227
228 case 'J': // arpeggio
229 tracks[t][k].param1 = old_event_byte2[j] >> 4;
230 tracks[t][k].param2 = old_event_byte2[j] & 15;
231 break;
232 }
233 }
234
235 t++;
236 }
237 }
238
239 delete [] module;
240
241 // order loop
242 restartpos = 0;
243
244 // order length
245 for (i=0;i<64;i++)
246 {
247 if (order[i] >= 0x80)
248 {
249 length = i;
250 break;
251 }
252 }
253
254 // default tempo
255 bpm = 0x7D;
256
257 rewind(0);
258
259 return true;
260 }
261
262 void CcffLoader::rewind(int subsong)
263 {
264 CmodPlayer::rewind(subsong);
265
266 // default instruments
267 for (int i=0;i<9;i++)
268 {
269 channel[i].inst = i;
270
271 channel[i].vol1 = 63 - (inst[i].data[10] & 63);
272 channel[i].vol2 = 63 - (inst[i].data[9] & 63);
273 }
274 }
275
276 std::string CcffLoader::gettype()
277 {
278 if (header.packed)
279 return std::string("BoomTracker 4, packed");
280 else
281 return std::string("BoomTracker 4");
282 }
283
284 std::string CcffLoader::gettitle()
285 {
286 return std::string(song_title,20);
287 }
288
289 std::string CcffLoader::getauthor()
290 {
291 return std::string(song_author,20);
292 }
293
294 std::string CcffLoader::getinstrument(unsigned int n)
295 {
296 return std::string(instruments[n].name);
297 }
298
299 unsigned int CcffLoader::getinstruments()
300 {
301 return 47;
302 }
303
304 /* -------- Private Methods ------------------------------- */
305
306 #ifdef _WIN32
307 #pragma warning(disable:4244)
308 #pragma warning(disable:4018)
309 #endif
310
311 /*
312 Lempel-Ziv-Tyr ;-)
313 */
314 long CcffLoader::cff_unpacker::unpack(unsigned char *ibuf, unsigned char *obuf)
315 {
316 if (memcmp(ibuf,"YsComp""\x07""CUD1997""\x1A\x04",16))
317 return 0;
318
319 input = ibuf + 16;
320 output = obuf;
321
322 output_length = 0;
323
324 heap = (unsigned char *)malloc(0x10000);
325 dictionary = (unsigned char **)malloc(sizeof(unsigned char *)*0x8000);
326
327 memset(heap,0,0x10000);
328 memset(dictionary,0,0x8000);
329
330 cleanup();
331 startup();
332
333 // LZW
334 while (1)
335 {
336 new_code = get_code();
337
338 // 0x00: end of data
339 if (new_code == 0)
340 break;
341
342 // 0x01: end of block
343 if (new_code == 1)
344 {
345 cleanup();
346 startup();
347
348 continue;
349 }
350
351 // 0x02: expand code length
352 if (new_code == 2)
353 {
354 code_length++;
355
356 continue;
357 }
358
359 // 0x03: RLE
360 if (new_code == 3)
361 {
362 unsigned char old_code_length = code_length;
363
364 code_length = 2;
365
366 unsigned char repeat_length = get_code() + 1;
367
368 code_length = 4 << get_code();
369
370 unsigned long repeat_counter = get_code();
371
372 for (unsigned int i=0;i<repeat_counter*repeat_length;i++)
373 output[output_length++] = output[output_length - repeat_length];
374
375 code_length = old_code_length;
376
377 startup();
378
379 continue;
380 }
381
382 if (new_code >= (0x104 + dictionary_length))
383 {
384 // dictionary <- old.code.string + old.code.char
385 the_string[++the_string[0]] = the_string[1];
386 }
387 else
388 {
389 // dictionary <- old.code.string + new.code.char
390 unsigned char temp_string[256];
391
392 translate_code(new_code,temp_string);
393
394 the_string[++the_string[0]] = temp_string[1];
395 }
396
397 expand_dictionary(the_string);
398
399 // output <- new.code.string
400 translate_code(new_code,the_string);
401
402 for (int i=0;i<the_string[0];i++)
403 output[output_length++] = the_string[i+1];
404
405 old_code = new_code;
406 }
407
408 free(heap);
409 free(dictionary);
410
411 return output_length;
412 }
413
414 unsigned long CcffLoader::cff_unpacker::get_code()
415 {
416 unsigned long code;
417
418 while (bits_left < code_length)
419 {
420 bits_buffer |= ((*input++) << bits_left);
421 bits_left += 8;
422 }
423
424 code = bits_buffer & ((1 << code_length) - 1);
425
426 bits_buffer >>= code_length;
427 bits_left -= code_length;
428
429 return code;
430 }
431
432 void CcffLoader::cff_unpacker::translate_code(unsigned long code, unsigned char *string)
433 {
434 unsigned char translated_string[256];
435
436 if (code >= 0x104)
437 {
438 memcpy(translated_string,dictionary[code - 0x104],(*(dictionary[code - 0x104])) + 1);
439 }
440 else
441 {
442 translated_string[0] = 1;
443 translated_string[1] = (code - 4) & 0xFF;
444 }
445
446 memcpy(string,translated_string,256);
447 }
448
449 void CcffLoader::cff_unpacker::cleanup()
450 {
451 code_length = 9;
452
453 bits_buffer = 0;
454 bits_left = 0;
455
456 heap_length = 0;
457 dictionary_length = 0;
458 }
459
460 void CcffLoader::cff_unpacker::startup()
461 {
462 old_code = get_code();
463
464 translate_code(old_code,the_string);
465
466 for (int i=0;i<the_string[0];i++)
467 output[output_length++] = the_string[i+1];
468 }
469
470 void CcffLoader::cff_unpacker::expand_dictionary(unsigned char *string)
471 {
472 if (string[0] >= 0xF0)
473 return;
474
475 memcpy(&heap[heap_length],string,string[0] + 1);
476
477 dictionary[dictionary_length] = &heap[heap_length];
478
479 dictionary_length++;
480
481 heap_length += (string[0] + 1);
482 }
483
484 #ifdef _WIN32
485 #pragma warning(default:4244)
486 #pragma warning(default:4018)
487 #endif