1 /*  _______         ____    __         ___    ___
2  * \    _  \       \    /  \  /       \   \  /   /       '   '  '
3  *  |  | \  \       |  |    ||         |   \/   |         .      .
4  *  |  |  |  |      |  |    ||         ||\  /|  |
5  *  |  |  |  |      |  |    ||         || \/ |  |         '  '  '
6  *  |  |  |  |      |  |    ||         ||    |  |         .      .
7  *  |  |_/  /        \  \__//          ||    |  |
8  * /_______/ynamic    \____/niversal  /__\  /____\usic   /|  .  . ibliotheque
9  *                                                      /  \
10  *                                                     / .  \
11  * readam.c - Code to read a RIFF AM module           / / \  \
12  *             from a parsed RIFF structure.         | <  /   \_
13  *                                                   |  \/ /\   /
14  * By Chris Moeller.                                  \_  /  > /
15  *                                                      | \ / /
16  *                                                      |  ' /
17  *                                                       \__/
18  */
19 
20 #include <stdlib.h>
21 #include <string.h>
22 
23 #include "dumb.h"
24 #include "internal/it.h"
25 #include "internal/riff.h"
26 
27 static int it_riff_am_process_sample( IT_SAMPLE * sample, DUMBFILE * f, int len, int ver )
28 {
29 	int header_length;
30 	int default_pan;
31 	int default_volume;
32 	int flags;
33 	int length;
34 	int length_bytes;
35 	int loop_start;
36 	int loop_end;
37     int sample_rate;
38 
39     int32 start = dumbfile_pos( f );
40 
41 	if ( ver == 0 )
42     {
43 		if ( len < 0x38 )
44 			return -1;
45 
46 		header_length = 0x38;
47 
48         dumbfile_getnc( (char *) sample->name, 28, f );
49 		sample->name[ 28 ] = 0;
50 
51         default_pan = dumbfile_getc( f );
52         default_volume = dumbfile_getc( f );
53         flags = dumbfile_igetw( f );
54         length = dumbfile_igetl( f );
55         loop_start = dumbfile_igetl( f );
56         loop_end = dumbfile_igetl( f );
57         sample_rate = dumbfile_igetl( f );
58 	}
59 	else
60 	{
61 		if (len < 4) return -1;
62 
63         header_length = dumbfile_igetl( f );
64 		if ( header_length < 0x40 )
65 			return -1;
66 		if ( header_length + 4 > len )
67 			return -1;
68 
69         start += 4;
70 		len -= 4;
71 
72         dumbfile_getnc( (char *) sample->name, 32, f );
73 
74         default_pan = dumbfile_igetw( f );
75         default_volume = dumbfile_igetw( f );
76         flags = dumbfile_igetw( f );
77         dumbfile_skip( f, 2 );
78         length = dumbfile_igetl( f );
79         loop_start = dumbfile_igetl( f );
80         loop_end = dumbfile_igetl( f );
81         sample_rate = dumbfile_igetl( f );
82 
83 		if ( default_pan > 0x7FFF || default_volume > 0x7FFF )
84 			return -1;
85 
86 		default_pan = default_pan * 64 / 32767;
87 		default_volume = default_volume * 64 / 32767;
88 	}
89 
90 	if ( ! length ) {
91 		sample->flags &= ~IT_SAMPLE_EXISTS;
92 		return 0;
93 	}
94 
95 	if ( flags & ~( 0x8000 | 0x80 | 0x20 | 0x10 | 0x08 | 0x04 ) )
96 		return -1;
97 
98 	length_bytes = length << ( ( flags & 0x04 ) >> 2 );
99 
100 	if ( length_bytes + header_length > len )
101 		return -1;
102 
103 	sample->flags = 0;
104 
105 	if ( flags & 0x80 ) sample->flags |= IT_SAMPLE_EXISTS;
106 	if ( flags & 0x04 ) sample->flags |= IT_SAMPLE_16BIT;
107 
108 	sample->length = length;
109 	sample->loop_start = loop_start;
110 	sample->loop_end = loop_end;
111 	sample->C5_speed = sample_rate;
112 	sample->default_volume = default_volume;
113 	sample->default_pan = default_pan | ( ( flags & 0x20 ) << 2 );
114 	sample->filename[0] = 0;
115 	sample->global_volume = 64;
116 	sample->vibrato_speed = 0;
117 	sample->vibrato_depth = 0;
118 	sample->vibrato_rate = 0;
119 	sample->vibrato_waveform = IT_VIBRATO_SINE;
120 	sample->finetune = 0;
121 	sample->max_resampling_quality = -1;
122 
123 	if ( flags & 0x08 )
124 	{
125 		if (((unsigned int)sample->loop_end <= (unsigned int)sample->length) &&
126 			((unsigned int)sample->loop_start < (unsigned int)sample->loop_end))
127 		{
128 			sample->length = sample->loop_end;
129 			sample->flags |= IT_SAMPLE_LOOP;
130 			if ( flags & 0x10 ) sample->flags |= IT_SAMPLE_PINGPONG_LOOP;
131 		}
132 	}
133 
134 	length_bytes = sample->length << ( ( flags & 0x04 ) >> 2 );
135 
136 	sample->data = malloc( length_bytes );
137 	if ( ! sample->data )
138 		return -1;
139 
140     if ( dumbfile_seek( f, start + header_length, DFS_SEEK_SET ) )
141         return -1;
142 
143     dumbfile_getnc( sample->data, length_bytes, f );
144 
145 	return 0;
146 }
147 
148 static int it_riff_am_process_pattern( IT_PATTERN * pattern, DUMBFILE * f, int len, int ver )
149 {
150     int nrows, row;
151     long start, end;
152 	unsigned flags;
153     int p, q, r;
154 	IT_ENTRY * entry;
155 
156     nrows = dumbfile_getc( f ) + 1;
157 
158 	pattern->n_rows = nrows;
159 
160 	len -= 1;
161 
162 	pattern->n_entries = 0;
163 
164 	row = 0;
165 
166     start = dumbfile_pos( f );
167     end = start + len;
168 
169     while ( (row < nrows) && !dumbfile_error( f ) && (dumbfile_pos( f ) < end) ) {
170         p = dumbfile_getc( f );
171         if ( ! p ) {
172 			++ row;
173 			continue;
174 		}
175 
176         flags = p & 0xE0;
177 
178         if (flags) {
179 			++ pattern->n_entries;
180             if (flags & 0x80) dumbfile_skip( f, 2 );
181             if (flags & 0x40) dumbfile_skip( f, 2 );
182             if (flags & 0x20) dumbfile_skip( f, 1 );
183 		}
184 	}
185 
186 	if ( ! pattern->n_entries ) return 0;
187 
188 	pattern->n_entries += nrows;
189 
190 	pattern->entry = malloc( pattern->n_entries * sizeof( * pattern->entry ) );
191 	if ( ! pattern->entry ) return -1;
192 
193 	entry = pattern->entry;
194 
195 	row = 0;
196 
197     dumbfile_seek( f, start, DFS_SEEK_SET );
198 
199     while ( ( row < nrows ) && !dumbfile_error( f ) && ( dumbfile_pos( f ) < end ) )
200 	{
201         p = dumbfile_getc( f );
202 
203         if ( ! p )
204 		{
205 			IT_SET_END_ROW( entry );
206 			++ entry;
207 			++ row;
208 			continue;
209 		}
210 
211         flags = p;
212 		entry->channel = flags & 0x1F;
213 		entry->mask = 0;
214 
215 		if (flags & 0xE0)
216 		{
217 			if ( flags & 0x80 )
218 			{
219                 q = dumbfile_getc( f );
220                 r = dumbfile_getc( f );
221                 _dumb_it_xm_convert_effect( r, q, entry, 0 );
222 			}
223 
224 			if ( flags & 0x40 )
225 			{
226                 q = dumbfile_getc( f );
227                 r = dumbfile_getc( f );
228                 if ( q )
229 				{
230 					entry->mask |= IT_ENTRY_INSTRUMENT;
231                     entry->instrument = q;
232 				}
233                 if ( r )
234 				{
235 					entry->mask |= IT_ENTRY_NOTE;
236                     entry->note = r - 1;
237 				}
238 			}
239 
240 			if ( flags & 0x20 )
241 			{
242                 q = dumbfile_getc( f );
243 				entry->mask |= IT_ENTRY_VOLPAN;
244                 if ( ver == 0 ) entry->volpan = q;
245                 else entry->volpan = q * 64 / 127;
246 			}
247 
248 			if (entry->mask) entry++;
249 		}
250 	}
251 
252 	while ( row < nrows )
253 	{
254 		IT_SET_END_ROW( entry );
255 		++ entry;
256 		++ row;
257 	}
258 
259 	pattern->n_entries = (int)(entry - pattern->entry);
260 	if ( ! pattern->n_entries ) return -1;
261 
262 	return 0;
263 }
264 
265 static DUMB_IT_SIGDATA *it_riff_amff_load_sigdata( DUMBFILE * f, struct riff * stream )
266 {
267 	DUMB_IT_SIGDATA *sigdata;
268 
269     int n, o, p, found;
270 
271 	if ( ! stream ) goto error;
272 
273 	if ( stream->type != DUMB_ID( 'A', 'M', 'F', 'F' ) ) goto error;
274 
275 	sigdata = malloc( sizeof( *sigdata ) );
276 	if ( ! sigdata ) goto error;
277 
278 	sigdata->n_patterns = 0;
279 	sigdata->n_samples = 0;
280 	sigdata->name[0] = 0;
281 
282 	found = 0;
283 
284 	for ( n = 0; (unsigned)n < stream->chunk_count; ++n )
285 	{
286 		struct riff_chunk * c = stream->chunks + n;
287 		switch( c->type )
288 		{
289 		case DUMB_ID( 'M', 'A', 'I', 'N' ):
290 			/* initialization data */
291 			if ( ( found & 1 ) || ( c->size < 0x48 ) ) goto error_sd;
292 			found |= 1;
293 			break;
294 
295 		case DUMB_ID( 'O', 'R', 'D', 'R' ):
296 			if ( ( found & 2 ) || ( c->size < 1 ) ) goto error_sd;
297 			found |= 2;
298 			break;
299 
300         case DUMB_ID( 'P', 'A', 'T', 'T' ):
301             if ( dumbfile_seek( f, c->offset, DFS_SEEK_SET ) ) goto error_sd;
302             o = dumbfile_getc( f );
303             if ( o >= sigdata->n_patterns ) sigdata->n_patterns = o + 1;
304             o = dumbfile_igetl( f );
305             if ( (unsigned)o + 5 > c->size ) goto error_sd;
306 			break;
307 
308 		case DUMB_ID( 'I', 'N', 'S', 'T' ):
309 			{
310 				if ( c->size < 0xE1 ) goto error_sd;
311                 if ( dumbfile_seek( f, c->offset + 1, DFS_SEEK_SET ) ) goto error_sd;
312                 o = dumbfile_getc( f );
313                 if ( o >= sigdata->n_samples ) sigdata->n_samples = o + 1;
314                 if ( c->size >= 0x121 )
315                 {
316                     if ( dumbfile_seek( f, c->offset + 0xE1, DFS_SEEK_SET ) ) goto error_sd;
317                     if ( dumbfile_mgetl( f ) == DUMB_ID('S','A','M','P') )
318                     {
319                         unsigned size = dumbfile_igetl( f );
320                         if ( size + 0xE1 + 8 > c->size ) goto error_sd;
321                     }
322 				}
323 			}
324 			break;
325 		}
326 	}
327 
328 	if ( found != 3 || !sigdata->n_samples || !sigdata->n_patterns ) goto error_sd;
329 
330 	if ( sigdata->n_samples > 255 || sigdata->n_patterns > 255 ) goto error_sd;
331 
332 	sigdata->song_message = NULL;
333 	sigdata->order = NULL;
334 	sigdata->instrument = NULL;
335 	sigdata->sample = NULL;
336 	sigdata->pattern = NULL;
337 	sigdata->midi = NULL;
338 	sigdata->checkpoint = NULL;
339 
340 	sigdata->mixing_volume = 48;
341 	sigdata->pan_separation = 128;
342 
343 	sigdata->n_instruments = 0;
344 	sigdata->n_orders = 0;
345 	sigdata->restart_position = 0;
346 
347 	memset(sigdata->channel_volume, 64, DUMB_IT_N_CHANNELS);
348 
349 	for (n = 0; n < DUMB_IT_N_CHANNELS; n += 4) {
350 		int sep = 32 * dumb_it_default_panning_separation / 100;
351 		sigdata->channel_pan[n  ] = 32 - sep;
352 		sigdata->channel_pan[n+1] = 32 + sep;
353 		sigdata->channel_pan[n+2] = 32 + sep;
354 		sigdata->channel_pan[n+3] = 32 - sep;
355 	}
356 
357     for ( n = 0; (unsigned)n < stream->chunk_count; ++n )
358 	{
359 		struct riff_chunk * c = stream->chunks + n;
360 		switch ( c->type )
361 		{
362 		case DUMB_ID( 'M', 'A', 'I', 'N' ):
363             if ( dumbfile_seek( f, c->offset, DFS_SEEK_SET ) ) goto error_usd;
364             dumbfile_getnc( (char *) sigdata->name, 64, f );
365 			sigdata->name[ 64 ] = 0;
366 			sigdata->flags = IT_STEREO | IT_OLD_EFFECTS | IT_COMPATIBLE_GXX | IT_WAS_AN_S3M;
367             o = dumbfile_getc( f );
368             if ( ! ( o & 1 ) ) sigdata->flags |= IT_LINEAR_SLIDES;
369             if ( ( o & ~3 ) || ! ( o & 2 ) ) goto error_usd; // unknown flags
370             sigdata->n_pchannels = dumbfile_getc( f );
371             sigdata->speed = dumbfile_getc( f );
372             sigdata->tempo = dumbfile_getc( f );
373 
374             dumbfile_skip( f, 4 );
375 
376             sigdata->global_volume = dumbfile_getc( f );
377 
378             if ( c->size < 0x48 + (unsigned)sigdata->n_pchannels ) goto error_usd;
379 
380 			for ( o = 0; o < sigdata->n_pchannels; ++o )
381 			{
382                 p = dumbfile_getc( f );
383                 sigdata->channel_pan[ o ] = p;
384                 if ( p >= 128 )
385 				{
386 					sigdata->channel_volume[ o ] = 0;
387 				}
388 			}
389 			break;
390 		}
391 	}
392 
393 	sigdata->pattern = malloc( sigdata->n_patterns * sizeof( *sigdata->pattern ) );
394 	if ( ! sigdata->pattern ) goto error_usd;
395 	for ( n = 0; n < sigdata->n_patterns; ++n )
396 		sigdata->pattern[ n ].entry = NULL;
397 
398 	sigdata->sample = malloc( sigdata->n_samples * sizeof( *sigdata->sample ) );
399 	if ( ! sigdata->sample ) goto error_usd;
400 	for ( n = 0; n < sigdata->n_samples; ++n )
401 	{
402 		IT_SAMPLE * sample = sigdata->sample + n;
403 		sample->data = NULL;
404 		sample->flags = 0;
405 		sample->name[ 0 ] = 0;
406 	}
407 
408     for ( n = 0; (unsigned)n < stream->chunk_count; ++n )
409 	{
410 		struct riff_chunk * c = stream->chunks + n;
411 		switch ( c->type )
412 		{
413 		case DUMB_ID( 'O', 'R', 'D', 'R' ):
414             if ( dumbfile_seek( f, c->offset, DFS_SEEK_SET ) ) goto error_usd;
415             sigdata->n_orders = dumbfile_getc( f ) + 1;
416             if ( (unsigned)sigdata->n_orders + 1 > c->size ) goto error_usd;
417 			sigdata->order = malloc( sigdata->n_orders );
418 			if ( ! sigdata->order ) goto error_usd;
419             dumbfile_getnc( (char *) sigdata->order, sigdata->n_orders, f );
420 			break;
421 
422 		case DUMB_ID( 'P', 'A', 'T', 'T' ):
423             if ( dumbfile_seek( f, c->offset, DFS_SEEK_SET ) ) goto error_usd;
424             o = dumbfile_getc( f );
425             p = dumbfile_igetl( f );
426             if ( it_riff_am_process_pattern( sigdata->pattern + o, f, p, 0 ) ) goto error_usd;
427 			break;
428 
429 		case DUMB_ID( 'I', 'N', 'S', 'T' ):
430 			{
431 				IT_SAMPLE * sample;
432                 if ( dumbfile_seek( f, c->offset + 1, DFS_SEEK_SET ) ) goto error_usd;
433                 sample = sigdata->sample + dumbfile_getc( f );
434                 if ( c->size >= 0x121 )
435                 {
436                     if ( dumbfile_seek( f, c->offset + 0xE1, DFS_SEEK_SET ) ) goto error_usd;
437                     if ( dumbfile_mgetl( f ) == DUMB_ID('S','A','M','P') )
438                     {
439                         unsigned size = dumbfile_igetl( f );
440                         if ( it_riff_am_process_sample( sample, f, size, 0 ) ) goto error_usd;
441                         break;
442                     }
443 				}
444                 dumbfile_seek( f, c->offset + 2, DFS_SEEK_SET );
445                 dumbfile_getnc( (char *) sample->name, 28, f );
446                 sample->name[ 28 ] = 0;
447             }
448 			break;
449 		}
450 	}
451 
452 	_dumb_it_fix_invalid_orders( sigdata );
453 
454 	return sigdata;
455 
456 error_usd:
457 	_dumb_it_unload_sigdata( sigdata );
458 	goto error;
459 error_sd:
460 	free( sigdata );
461 error:
462 	return NULL;
463 }
464 
465 static DUMB_IT_SIGDATA *it_riff_am_load_sigdata( DUMBFILE * f, struct riff * stream )
466 {
467 	DUMB_IT_SIGDATA *sigdata;
468 
469 	int n, o, p, found;
470 
471     if ( ! f || ! stream ) goto error;
472 
473 	if ( stream->type != DUMB_ID( 'A', 'M', ' ', ' ' ) ) goto error;
474 
475 	sigdata = malloc(sizeof(*sigdata));
476 	if ( ! sigdata ) goto error;
477 
478 	sigdata->n_patterns = 0;
479 	sigdata->n_samples = 0;
480 	sigdata->name[0] = 0;
481 
482 	found = 0;
483 
484     for ( n = 0; (unsigned)n < stream->chunk_count; ++n )
485 	{
486 		struct riff_chunk * c = stream->chunks + n;
487 		switch( c->type )
488 		{
489 		case DUMB_ID( 'I' ,'N' ,'I' ,'T' ):
490 			/* initialization data */
491 			if ( ( found & 1 ) || ( c->size < 0x48 ) ) goto error_sd;
492 			found |= 1;
493 			break;
494 
495 		case DUMB_ID( 'O', 'R', 'D', 'R' ):
496 			if ( ( found & 2 ) || ( c->size < 1 ) ) goto error_sd;
497 			found |= 2;
498 			break;
499 
500 		case DUMB_ID( 'P', 'A', 'T', 'T' ):
501             if ( dumbfile_seek( f, c->offset, DFS_SEEK_SET ) ) goto error_sd;
502             o = dumbfile_getc( f );
503             if ( o >= sigdata->n_patterns ) sigdata->n_patterns = o + 1;
504             o = dumbfile_igetl( f );
505             if ( (unsigned)o + 5 > c->size ) goto error_sd;
506 			break;
507 
508 		case DUMB_ID( 'R', 'I', 'F', 'F' ):
509 			{
510                 struct riff * str = c->nested;
511 				switch ( str->type )
512 				{
513 				case DUMB_ID( 'A', 'I', ' ', ' ' ):
514                     for ( o = 0; (unsigned)o < str->chunk_count; ++o )
515 					{
516 						struct riff_chunk * chk = str->chunks + o;
517 						switch( chk->type )
518 						{
519 						case DUMB_ID( 'I', 'N', 'S', 'T' ):
520 							{
521 								struct riff * temp;
522 								unsigned size;
523 								unsigned sample_found;
524                                 if ( dumbfile_seek( f, chk->offset, DFS_SEEK_SET ) ) goto error_sd;
525                                 size = dumbfile_igetl( f );
526 								if ( size < 0x142 ) goto error_sd;
527 								sample_found = 0;
528                                 dumbfile_skip( f, 1 );
529                                 p = dumbfile_getc( f );
530                                 if ( p >= sigdata->n_samples ) sigdata->n_samples = p + 1;
531                                 temp = riff_parse( f, chk->offset + 4 + size, chk->size - size - 4, 1 );
532 								if ( temp )
533 								{
534 									if ( temp->type == DUMB_ID( 'A', 'S', ' ', ' ' ) )
535 									{
536                                         for ( p = 0; (unsigned)p < temp->chunk_count; ++p )
537 										{
538 											if ( temp->chunks[ p ].type == DUMB_ID( 'S', 'A', 'M', 'P' ) )
539 											{
540 												if ( sample_found )
541 												{
542 													riff_free( temp );
543                                                     goto error_sd;
544 												}
545 												sample_found = 1;
546 											}
547 										}
548 									}
549 									riff_free( temp );
550 								}
551 							}
552 						}
553 					}
554 				}
555 			}
556 			break;
557 		}
558 	}
559 
560 	if ( found != 3 || !sigdata->n_samples || !sigdata->n_patterns ) goto error_sd;
561 
562 	if ( sigdata->n_samples > 255 || sigdata->n_patterns > 255 ) goto error_sd;
563 
564 	sigdata->song_message = NULL;
565 	sigdata->order = NULL;
566 	sigdata->instrument = NULL;
567 	sigdata->sample = NULL;
568 	sigdata->pattern = NULL;
569 	sigdata->midi = NULL;
570 	sigdata->checkpoint = NULL;
571 
572 	sigdata->mixing_volume = 48;
573 	sigdata->pan_separation = 128;
574 
575 	sigdata->n_instruments = 0;
576 	sigdata->n_orders = 0;
577 	sigdata->restart_position = 0;
578 
579 	memset(sigdata->channel_volume, 64, DUMB_IT_N_CHANNELS);
580 
581 	for (n = 0; n < DUMB_IT_N_CHANNELS; n += 4) {
582 		int sep = 32 * dumb_it_default_panning_separation / 100;
583 		sigdata->channel_pan[n  ] = 32 - sep;
584 		sigdata->channel_pan[n+1] = 32 + sep;
585 		sigdata->channel_pan[n+2] = 32 + sep;
586 		sigdata->channel_pan[n+3] = 32 - sep;
587 	}
588 
589     for ( n = 0; (unsigned)n < stream->chunk_count; ++n )
590 	{
591 		struct riff_chunk * c = stream->chunks + n;
592 		switch ( c->type )
593 		{
594 		case DUMB_ID( 'I', 'N', 'I', 'T' ):
595             if ( dumbfile_seek( f, c->offset, DFS_SEEK_SET ) ) goto error_usd;
596             dumbfile_getnc( (char *) sigdata->name, 64, f );
597 			sigdata->name[ 64 ] = 0;
598 			sigdata->flags = IT_STEREO | IT_OLD_EFFECTS | IT_COMPATIBLE_GXX | IT_WAS_AN_S3M;
599             o = dumbfile_getc( f );
600             if ( ! ( o & 1 ) ) sigdata->flags |= IT_LINEAR_SLIDES;
601             if ( ( o & ~3 ) || ! ( o & 2 ) ) goto error_usd; // unknown flags
602             sigdata->n_pchannels = dumbfile_getc( f );
603             sigdata->speed = dumbfile_getc( f );
604             sigdata->tempo = dumbfile_getc( f );
605 
606             dumbfile_skip( f, 4 );
607 
608             sigdata->global_volume = dumbfile_getc( f );
609 
610             if ( c->size < 0x48 + (unsigned)sigdata->n_pchannels ) goto error_usd;
611 
612 			for ( o = 0; o < sigdata->n_pchannels; ++o )
613 			{
614                 p = dumbfile_getc( f );
615                 if ( p <= 128 )
616 				{
617                     sigdata->channel_pan[ o ] = p / 2;
618 				}
619 				else
620 				{
621 					sigdata->channel_volume[ o ] = 0;
622 				}
623 			}
624 			break;
625 		}
626 	}
627 
628 	sigdata->pattern = malloc( sigdata->n_patterns * sizeof( *sigdata->pattern ) );
629 	if ( ! sigdata->pattern ) goto error_usd;
630 	for ( n = 0; n < sigdata->n_patterns; ++n )
631 		sigdata->pattern[ n ].entry = NULL;
632 
633 	sigdata->sample = malloc( sigdata->n_samples * sizeof( *sigdata->sample ) );
634 	if ( ! sigdata->sample ) goto error_usd;
635 	for ( n = 0; n < sigdata->n_samples; ++n )
636 	{
637 		IT_SAMPLE * sample = sigdata->sample + n;
638 		sample->data = NULL;
639 		sample->flags = 0;
640 		sample->name[ 0 ] = 0;
641 	}
642 
643     for ( n = 0; (unsigned)n < stream->chunk_count; ++n )
644 	{
645 		struct riff_chunk * c = stream->chunks + n;
646 		switch ( c->type )
647 		{
648 		case DUMB_ID( 'O', 'R', 'D', 'R' ):
649             if ( dumbfile_seek( f, c->offset, DFS_SEEK_SET ) ) goto error_usd;
650             sigdata->n_orders = dumbfile_getc( f ) + 1;
651             if ( (unsigned)sigdata->n_orders + 1 > c->size ) goto error_usd;
652 			sigdata->order = malloc( sigdata->n_orders );
653 			if ( ! sigdata->order ) goto error_usd;
654             dumbfile_getnc( (char *) sigdata->order, sigdata->n_orders, f );
655 			break;
656 
657 		case DUMB_ID( 'P', 'A', 'T', 'T' ):
658             if ( dumbfile_seek( f, c->offset, DFS_SEEK_SET ) ) goto error_usd;
659             o = dumbfile_getc( f );
660             p = dumbfile_igetl( f );
661             if ( it_riff_am_process_pattern( sigdata->pattern + o, f, p, 1 ) ) goto error_usd;
662 			break;
663 
664 		case DUMB_ID( 'R', 'I', 'F', 'F' ):
665 			{
666                 struct riff * str = c->nested;
667 				switch ( str->type )
668 				{
669 				case DUMB_ID('A', 'I', ' ', ' '):
670                     for ( o = 0; (unsigned)o < str->chunk_count; ++o )
671 					{
672 						struct riff_chunk * chk = str->chunks + o;
673 						switch( chk->type )
674 						{
675 						case DUMB_ID( 'I', 'N', 'S', 'T' ):
676 							{
677 								struct riff * temp;
678 								unsigned size;
679 								unsigned sample_found;
680 								IT_SAMPLE * sample;
681                                 if ( dumbfile_seek( f, chk->offset, DFS_SEEK_SET ) ) goto error_usd;
682                                 size = dumbfile_igetl( f );
683                                 dumbfile_skip( f, 1 );
684                                 p = dumbfile_getc( f );
685                                 temp = riff_parse( f, chk->offset + 4 + size, chk->size - size - 4, 1 );
686 								sample_found = 0;
687                                 sample = sigdata->sample + p;
688 								if ( temp )
689 								{
690 									if ( temp->type == DUMB_ID( 'A', 'S', ' ', ' ' ) )
691 									{
692                                         for ( p = 0; (unsigned)p < temp->chunk_count; ++p )
693 										{
694 											struct riff_chunk * c = temp->chunks + p;
695 											if ( c->type == DUMB_ID( 'S', 'A', 'M', 'P' ) )
696 											{
697 												if ( sample_found )
698 												{
699 													riff_free( temp );
700 													goto error_usd;
701 												}
702                                                 {
703                                                     riff_free( temp );
704                                                     goto error_usd;
705                                                 }
706                                                 if ( it_riff_am_process_sample( sample, f, c->size, 1 ) )
707 												{
708 													riff_free( temp );
709 													goto error_usd;
710 												}
711 												sample_found = 1;
712 											}
713 										}
714 									}
715 									riff_free( temp );
716 								}
717 								if ( ! sample_found )
718 								{
719                                     dumbfile_seek( f, chk->offset + 6, DFS_SEEK_SET );
720                                     dumbfile_getnc( (char *) sample->name, 32, f );
721 									sample->name[ 32 ] = 0;
722 								}
723 							}
724 						}
725 					}
726 				}
727 			}
728 			break;
729 		}
730 	}
731 
732 	_dumb_it_fix_invalid_orders( sigdata );
733 
734 	return sigdata;
735 
736 error_usd:
737 	_dumb_it_unload_sigdata( sigdata );
738 	goto error;
739 error_sd:
740 	free( sigdata );
741 error:
742 	return NULL;
743 }
744 
745 DUH *dumb_read_riff_amff( DUMBFILE * f, struct riff * stream )
746 {
747 	sigdata_t *sigdata;
748 	long length;
749 
750 	DUH_SIGTYPE_DESC *descptr = &_dumb_sigtype_it;
751 
752     sigdata = it_riff_amff_load_sigdata( f, stream );
753 
754 	if (!sigdata)
755 		return NULL;
756 
757 	length = 0;/*_dumb_it_build_checkpoints(sigdata, 0);*/
758 
759 	{
760 		const char *tag[2][2];
761 		tag[0][0] = "TITLE";
762         tag[0][1] = (const char *)(((DUMB_IT_SIGDATA *)sigdata)->name);
763 		tag[1][0] = "FORMAT";
764 		tag[1][1] = "RIFF AMFF";
765 		return make_duh( length, 2, ( const char * const (*) [ 2 ] ) tag, 1, & descptr, & sigdata );
766 	}
767 }
768 
769 DUH *dumb_read_riff_am( DUMBFILE * f, struct riff * stream )
770 {
771 	sigdata_t *sigdata;
772 
773 	DUH_SIGTYPE_DESC *descptr = &_dumb_sigtype_it;
774 
775     sigdata = it_riff_am_load_sigdata( f, stream );
776 
777 	if (!sigdata)
778 		return NULL;
779 
780 	{
781 		const char *tag[2][2];
782 		tag[0][0] = "TITLE";
783         tag[0][1] = (const char *)(((DUMB_IT_SIGDATA *)sigdata)->name);
784 		tag[1][0] = "FORMAT";
785 		tag[1][1] = "RIFF AM";
786 		return make_duh( -1, 2, ( const char * const (*) [ 2 ] ) tag, 1, & descptr, & sigdata );
787 	}
788 }
789