1 /* _______ ____ __ ___ ___
2 * \ _ \ \ / \ / \ \ / / ' ' '
3 * | | \ \ | | || | \/ | . .
4 * | | | | | | || ||\ /| |
5 * | | | | | | || || \/ | | ' ' '
6 * | | | | | | || || | | . .
7 * | |_/ / \ \__// || | |
8 * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque
9 * / \
10 * / . \
11 * readamf.c - Code to read a DSMI AMF module from / / \ \
12 * an open file. | < / \_
13 * | \/ /\ /
14 * By Chris Moeller. \_ / > /
15 * | \ / /
16 * | ' /
17 * \__/
18 */
19
20 #include <stdlib.h>
21 #include <string.h>
22 #include <math.h>
23
24 #include "dumb.h"
25 #include "internal/it.h"
26
27
28
it_amf_process_track(IT_ENTRY * entry_table,unsigned char * track,int rows,int channels)29 static void it_amf_process_track( IT_ENTRY *entry_table, unsigned char *track, int rows, int channels )
30 {
31 int last_instrument = 0;
32 int tracksize = track[ 0 ] + ( track[ 1 ] << 8 ) + ( track[ 2 ] << 16 );
33 track += 3;
34 while ( tracksize-- ) {
35 unsigned int row = track[ 0 ];
36 unsigned int command = track[ 1 ];
37 unsigned int argument = track[ 2 ];
38 IT_ENTRY * entry = entry_table + row * channels;
39 if ( row >= ( unsigned int ) rows ) break;
40 if ( command < 0x7F ) {
41 entry->mask |= IT_ENTRY_NOTE | IT_ENTRY_INSTRUMENT | IT_ENTRY_VOLPAN;
42 entry->note = command;
43 if ( ! entry->instrument ) entry->instrument = last_instrument;
44 entry->volpan = argument;
45 }
46 else if ( command == 0x7F ) {
47 signed char row_delta = ( signed char ) argument;
48 int row_source = ( int ) row + ( int ) row_delta;
49 if ( row_source >= 0 && row_source < ( int ) rows ) {
50 *entry = entry_table[ row_source * channels ];
51 }
52 }
53 else if ( command == 0x80 ) {
54 entry->mask |= IT_ENTRY_INSTRUMENT;
55 last_instrument = argument + 1;
56 entry->instrument = last_instrument;
57 }
58 else if ( command == 0x83 ) {
59 entry->mask |= IT_ENTRY_VOLPAN;
60 entry->volpan = argument;
61 }
62 else {
63 unsigned int effect = command & 0x7F;
64 unsigned int effectvalue = argument;
65 switch (effect) {
66 case 0x01: effect = IT_SET_SPEED; break;
67
68 case 0x02: effect = IT_VOLUME_SLIDE;
69 case 0x0A: if ( effect == 0x0A ) effect = IT_VOLSLIDE_TONEPORTA;
70 case 0x0B: if ( effect == 0x0B ) effect = IT_VOLSLIDE_VIBRATO;
71 if ( effectvalue & 0x80 ) effectvalue = ( -( signed char ) effectvalue ) & 0x0F;
72 else effectvalue = ( effectvalue & 0x0F ) << 4;
73 break;
74
75 case 0x04:
76 if ( effectvalue & 0x80 ) {
77 effect = IT_PORTAMENTO_UP;
78 effectvalue = ( -( signed char ) effectvalue ) & 0x7F;
79 }
80 else {
81 effect = IT_PORTAMENTO_DOWN;
82 }
83 break;
84
85 case 0x06: effect = IT_TONE_PORTAMENTO; break;
86
87 case 0x07: effect = IT_TREMOR; break;
88
89 case 0x08: effect = IT_ARPEGGIO; break;
90
91 case 0x09: effect = IT_VIBRATO; break;
92
93 case 0x0C: effect = IT_BREAK_TO_ROW; break;
94
95 case 0x0D: effect = IT_JUMP_TO_ORDER; break;
96
97 case 0x0F: effect = IT_RETRIGGER_NOTE; break;
98
99 case 0x10: effect = IT_SET_SAMPLE_OFFSET; break;
100
101 case 0x11:
102 if ( effectvalue ) {
103 effect = IT_VOLUME_SLIDE;
104 if ( effectvalue & 0x80 )
105 effectvalue = 0xF0 | ( ( -( signed char ) effectvalue ) & 0x0F );
106 else
107 effectvalue = 0x0F | ( ( effectvalue & 0x0F ) << 4 );
108 }
109 else
110 effect = 0;
111 break;
112
113 case 0x12:
114 case 0x16:
115 if ( effectvalue ) {
116 int mask = ( effect == 0x16 ) ? 0xE0 : 0xF0;
117 effect = ( effectvalue & 0x80 ) ? IT_PORTAMENTO_UP : IT_PORTAMENTO_DOWN;
118 if ( effectvalue & 0x80 )
119 effectvalue = mask | ( ( -( signed char ) effectvalue ) & 0x0F );
120 else
121 effectvalue = mask | ( effectvalue & 0x0F );
122 }
123 else
124 effect = 0;
125 break;
126
127 case 0x13:
128 effect = IT_S;
129 effectvalue = EFFECT_VALUE( IT_S_NOTE_DELAY, effectvalue & 0x0F );
130 break;
131
132 case 0x14:
133 effect = IT_S;
134 effectvalue = EFFECT_VALUE( IT_S_DELAYED_NOTE_CUT, effectvalue & 0x0F );
135 break;
136
137 case 0x15: effect = IT_SET_SONG_TEMPO; break;
138
139 case 0x17:
140 effectvalue = ( effectvalue + 64 ) & 0x7F;
141 if ( entry->mask & IT_ENTRY_EFFECT ) {
142 if ( !( entry->mask & IT_ENTRY_VOLPAN ) ) {
143 entry->mask |= IT_ENTRY_VOLPAN;
144 entry->volpan = ( effectvalue / 2 ) + 128;
145 }
146 effect = 0;
147 }
148 else {
149 effect = IT_SET_PANNING;
150 }
151 break;
152
153 default: effect = effectvalue = 0;
154 }
155 if ( effect ) {
156 entry->mask |= IT_ENTRY_EFFECT;
157 entry->effect = effect;
158 entry->effectvalue = effectvalue;
159 }
160 }
161 track += 3;
162 }
163 }
164
it_amf_process_pattern(IT_PATTERN * pattern,IT_ENTRY * entry_table,int rows,int channels)165 static int it_amf_process_pattern( IT_PATTERN *pattern, IT_ENTRY *entry_table, int rows, int channels )
166 {
167 int i, j;
168 int n_entries = rows;
169 IT_ENTRY * entry;
170
171 pattern->n_rows = rows;
172
173 for ( i = 0, j = channels * rows; i < j; i++ ) {
174 if ( entry_table[ i ].mask ) {
175 n_entries++;
176 }
177 }
178
179 pattern->n_entries = n_entries;
180
181 pattern->entry = entry = malloc( n_entries * sizeof( IT_ENTRY ) );
182 if ( !entry ) {
183 return -1;
184 }
185
186 for ( i = 0; i < rows; i++ ) {
187 for ( j = 0; j < channels; j++ ) {
188 if ( entry_table[ i * channels + j ].mask ) {
189 *entry = entry_table[ i * channels + j ];
190 entry->channel = j;
191 entry++;
192 }
193 }
194 IT_SET_END_ROW( entry );
195 entry++;
196 }
197
198 return 0;
199 }
200
it_amf_read_sample_header(IT_SAMPLE * sample,DUMBFILE * f,int * offset,int ver)201 static int it_amf_read_sample_header( IT_SAMPLE *sample, DUMBFILE *f, int * offset, int ver )
202 {
203 int exists;
204
205 exists = dumbfile_getc( f );
206
207 dumbfile_getnc( (char *) sample->name, 32, f );
208 sample->name[32] = 0;
209
210 dumbfile_getnc( (char *) sample->filename, 13, f );
211 sample->filename[13] = 0;
212
213 *offset = (int)dumbfile_igetl( f );
214 sample->length = dumbfile_igetl( f );
215 sample->C5_speed = dumbfile_igetw( f );
216 sample->default_volume = dumbfile_getc( f );
217 sample->global_volume = 64;
218 if ( sample->default_volume > 64 ) sample->default_volume = 64;
219
220 if ( ver >= 11 ) {
221 sample->loop_start = dumbfile_igetl( f );
222 sample->loop_end = dumbfile_igetl( f );
223 } else {
224 sample->loop_start = dumbfile_igetw( f );
225 sample->loop_end = sample->length;
226 }
227
228 if ( sample->length <= 0 ) {
229 sample->flags = 0;
230 return 0;
231 }
232
233 sample->flags = exists == 1 ? IT_SAMPLE_EXISTS : 0;
234
235 sample->default_pan = 0;
236 sample->finetune = 0;
237
238 if ( sample->loop_end > sample->loop_start + 2 && sample->loop_end <= sample->length )
239 sample->flags |= IT_SAMPLE_LOOP;
240
241 sample->vibrato_speed = 0;
242 sample->vibrato_depth = 0;
243 sample->vibrato_rate = 0;
244 sample->vibrato_waveform = 0; // do we have to set _all_ these?
245 sample->max_resampling_quality = -1;
246
247 return dumbfile_error(f);
248 }
249
250
251
it_amf_read_sample_data(IT_SAMPLE * sample,DUMBFILE * f)252 static int it_amf_read_sample_data( IT_SAMPLE *sample, DUMBFILE *f )
253 {
254 int i, read_length = 0;
255
256 sample->data = malloc( sample->length );
257
258 if ( !sample->data )
259 return -1;
260
261 if ( sample->length )
262 read_length = (int)dumbfile_getnc( sample->data, sample->length, f );
263
264 for ( i = 0; i < read_length; i++ ) {
265 ( ( signed char * ) sample->data )[ i ] ^= 0x80;
266 }
267
268 for ( i = read_length; i < sample->length; i++ ) {
269 ( ( signed char * ) sample->data )[ i ] = 0;
270 }
271
272 return 0; /* Sometimes the last sample is truncated :( */
273 }
274
it_amf_load_sigdata(DUMBFILE * f,int * version)275 static DUMB_IT_SIGDATA *it_amf_load_sigdata(DUMBFILE *f, int * version)
276 {
277 DUMB_IT_SIGDATA *sigdata;
278 int i, j, ver, ntracks, realntracks, nchannels;
279
280 int maxsampleseekpos = 0;
281 int sampleseekpos[256];
282
283 unsigned short *orderstotracks;
284 unsigned short *trackmap;
285 unsigned int tracksize[256];
286
287 unsigned char **track;
288
289 static const char sig[] = "AMF";
290
291 char signature [3];
292
293 if ( dumbfile_getnc( signature, 3, f ) != 3 ||
294 memcmp( signature, sig, 3 ) ) {
295 return NULL;
296 }
297
298 *version = ver = dumbfile_getc( f );
299 if ( ver < 10 || ver > 14) {
300 return NULL;
301 }
302
303 sigdata = malloc(sizeof(*sigdata));
304 if (!sigdata) {
305 return NULL;
306 }
307
308 dumbfile_getnc( (char *) sigdata->name, 32, f );
309 sigdata->name[ 32 ] = 0;
310 sigdata->n_samples = dumbfile_getc( f );
311 sigdata->n_orders = dumbfile_getc( f );
312 ntracks = dumbfile_igetw( f );
313 nchannels = dumbfile_getc( f );
314
315 if ( dumbfile_error( f ) ||
316 sigdata->n_samples < 1 || sigdata->n_samples > 255 ||
317 sigdata->n_orders < 1 || sigdata->n_orders > 255 ||
318 ! ntracks ||
319 nchannels < 1 || nchannels > 32 ) {
320 free( sigdata );
321 return NULL;
322 }
323
324 sigdata->n_pchannels = nchannels;
325
326 memset( sigdata->channel_volume, 64, DUMB_IT_N_CHANNELS );
327
328 if ( ver >= 11 ) {
329 int nchannels = ( ver >= 13 ) ? 32 : 16;
330 for ( i = 0; i < nchannels; i++ ) {
331 signed char panpos = dumbfile_getc( f );
332 int pan = ( panpos + 64 ) / 2;
333 if ( pan < 0 ) pan = 0;
334 else if ( pan > 64 ) pan = IT_SURROUND;
335 sigdata->channel_pan[ i ] = pan;
336 }
337 }
338 else {
339 int sep = 32 * dumb_it_default_panning_separation / 100;
340 for ( i = 0; i < 16; i++ ) {
341 sigdata->channel_pan[ i ] = ( dumbfile_getc( f ) & 1 ) ? 32 - sep : 32 + sep;
342 }
343 }
344
345 sigdata->tempo = 125;
346 sigdata->speed = 6;
347 if ( ver >= 13 ) {
348 i = dumbfile_getc( f );
349 if ( i >= 32 ) sigdata->tempo = i;
350 i = dumbfile_getc( f );
351 if ( i <= 32 ) sigdata->speed = i;
352 }
353
354 sigdata->order = malloc( sigdata->n_orders );
355 if ( !sigdata->order ) {
356 free( sigdata );
357 return NULL;
358 }
359
360 orderstotracks = malloc( sigdata->n_orders * nchannels * sizeof( unsigned short ) );
361 if ( !orderstotracks ) {
362 free( sigdata->order );
363 free( sigdata );
364 return NULL;
365 }
366
367 for ( i = 0; i < sigdata->n_orders; i++ ) {
368 sigdata->order[ i ] = i;
369 tracksize[ i ] = 64;
370 if ( ver >= 14 ) {
371 tracksize[ i ] = dumbfile_igetw( f );
372 }
373 for ( j = 0; j < nchannels; j++ ) {
374 orderstotracks[ i * nchannels + j ] = dumbfile_igetw( f );
375 }
376 }
377
378 if ( dumbfile_error( f ) ) {
379 free( orderstotracks );
380 free( sigdata->order );
381 free( sigdata );
382 return NULL;
383 }
384
385 sigdata->sample = malloc( sigdata->n_samples * sizeof( *sigdata->sample ) );
386 if ( !sigdata->sample ) {
387 free( orderstotracks );
388 free( sigdata->order );
389 free( sigdata );
390 return NULL;
391 }
392
393 sigdata->restart_position = 0;
394
395 sigdata->song_message = NULL;
396 sigdata->instrument = NULL;
397 sigdata->pattern = NULL;
398 sigdata->midi = NULL;
399 sigdata->checkpoint = NULL;
400
401 sigdata->n_instruments = 0;
402
403 for ( i = 0; i < sigdata->n_samples; ++i )
404 sigdata->sample[i].data = NULL;
405
406 for ( i = 0; i < sigdata->n_samples; ++i ) {
407 int offset;
408 if ( it_amf_read_sample_header( &sigdata->sample[i], f, &offset, ver ) ) {
409 goto error_ott;
410 }
411 sampleseekpos[ i ] = offset;
412 if ( offset > maxsampleseekpos ) maxsampleseekpos = offset;
413 }
414
415 sigdata->n_patterns = sigdata->n_orders;
416
417 sigdata->pattern = malloc( sigdata->n_patterns * sizeof( *sigdata->pattern ) );
418 if ( !sigdata->pattern ) {
419 goto error_ott;
420 }
421 for (i = 0; i < sigdata->n_patterns; ++i)
422 sigdata->pattern[i].entry = NULL;
423
424 trackmap = malloc( ntracks * sizeof( unsigned short ) );
425 if ( !trackmap ) {
426 goto error_ott;
427 }
428
429 if ( dumbfile_getnc( ( char * ) trackmap, ntracks * sizeof( unsigned short ), f ) != (long)(ntracks * sizeof( unsigned short )) ) {
430 goto error_tm;
431 }
432
433 realntracks = 0;
434
435 for ( i = 0; i < ntracks; i++ ) {
436 if ( trackmap[ i ] > realntracks ) realntracks = trackmap[ i ];
437 }
438
439 track = calloc( realntracks, sizeof( unsigned char * ) );
440 if ( !track ) {
441 goto error_tm;
442 }
443
444 for ( i = 0; i < realntracks; i++ ) {
445 int tracksize = dumbfile_igetw( f );
446 tracksize += dumbfile_getc( f ) << 16;
447 track[ i ] = malloc( tracksize * 3 + 3 );
448 if ( !track[ i ] ) {
449 goto error_all;
450 }
451 track[ i ][ 0 ] = tracksize & 255;
452 track[ i ][ 1 ] = ( tracksize >> 8 ) & 255;
453 track[ i ][ 2 ] = ( tracksize >> 16 ) & 255;
454 if ( dumbfile_getnc( (char *) track[ i ] + 3, tracksize * 3, f ) != tracksize * 3 ) {
455 goto error_all;
456 }
457 }
458
459 for ( i = 1; i <= maxsampleseekpos; i++ ) {
460 for ( j = 0; j < sigdata->n_samples; j++ ) {
461 if ( sampleseekpos[ j ] == i ) {
462 if ( it_amf_read_sample_data( &sigdata->sample[ j ], f ) ) {
463 goto error_all;
464 }
465 break;
466 }
467 }
468 }
469
470 /* Process tracks into patterns */
471 for ( i = 0; i < sigdata->n_patterns; i++ ) {
472 IT_ENTRY * entry_table = calloc( tracksize[ i ] * nchannels, sizeof( IT_ENTRY ) );
473 if ( !entry_table ) {
474 goto error_all;
475 }
476 for ( j = 0; j < nchannels; j++ ) {
477 int ntrack = orderstotracks[ i * nchannels + j ];
478 if ( ntrack && ntrack <= ntracks ) {
479 int realtrack = trackmap[ ntrack - 1 ];
480 if ( realtrack ) {
481 realtrack--;
482 if ( realtrack < realntracks && track[ realtrack ] ) {
483 it_amf_process_track( entry_table + j, track[ realtrack ], tracksize[ i ], nchannels );
484 }
485 }
486 }
487 }
488 if ( it_amf_process_pattern( &sigdata->pattern[ i ], entry_table, tracksize[ i ], nchannels ) ) {
489 free( entry_table );
490 goto error_all;
491 }
492 free( entry_table );
493 }
494
495 /* Now let's initialise the remaining variables, and we're done! */
496 sigdata->flags = IT_OLD_EFFECTS | IT_COMPATIBLE_GXX | IT_STEREO | IT_WAS_AN_S3M;
497
498 sigdata->global_volume = 128;
499 sigdata->mixing_volume = 48;
500 sigdata->pan_separation = 128;
501
502 _dumb_it_fix_invalid_orders(sigdata);
503
504 for ( i = 0; i < realntracks; i++ ) {
505 if ( track[ i ] ) {
506 free( track[ i ] );
507 }
508 }
509 free( track );
510 free( trackmap );
511 free( orderstotracks );
512
513 return sigdata;
514
515 error_all:
516 for ( i = 0; i < realntracks; i++ ) {
517 if ( track[ i ] ) {
518 free( track[ i ] );
519 }
520 }
521 free( track );
522 error_tm:
523 free( trackmap );
524 error_ott:
525 free( orderstotracks );
526 _dumb_it_unload_sigdata( sigdata );
527 return NULL;
528 }
529
530
531
dumb_read_amf_quick(DUMBFILE * f)532 DUH *dumb_read_amf_quick(DUMBFILE *f)
533 {
534 sigdata_t *sigdata;
535
536 DUH_SIGTYPE_DESC *descptr = &_dumb_sigtype_it;
537
538 int version;
539
540 sigdata = it_amf_load_sigdata(f, &version);
541
542 if (!sigdata)
543 return NULL;
544
545 {
546 const char *tag[2][2];
547 char ver_string[14];
548 tag[0][0] = "TITLE";
549 tag[0][1] = (const char *)(((DUMB_IT_SIGDATA *)sigdata)->name);
550 tag[1][0] = "FORMAT";
551 memcpy( ver_string, "DSMI AMF v", 10 );
552 ver_string[10] = '0' + version / 10;
553 ver_string[11] = '.';
554 ver_string[12] = '0' + version % 10;
555 ver_string[13] = 0;
556 tag[1][1] = ver_string;
557 return make_duh(-1, 2, (const char *const (*)[2])tag, 1, &descptr, &sigdata);
558 }
559 }
560