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