ft2_load_aiff.c (14799B)
1 /* Apple AIFF sample loader 2 ** 3 ** Note: Vol/loop sanitation is done in the last stage 4 ** of sample loading, so you don't need to do that here. 5 ** Do NOT close the file handle! 6 */ 7 8 #include <stdio.h> 9 #include <stdint.h> 10 #include <stdbool.h> 11 #include <math.h> 12 #include "../ft2_header.h" 13 #include "../ft2_audio.h" 14 #include "../ft2_sample_ed.h" 15 #include "../ft2_sysreqs.h" 16 #include "../ft2_sample_loader.h" 17 18 static double getAIFFSampleRate(uint8_t *in); 19 static bool aiffIsStereo(FILE *f); // only ran on files that are confirmed to be AIFFs 20 21 bool loadAIFF(FILE *f, uint32_t filesize) 22 { 23 char compType[4]; 24 int8_t *audioDataS8; 25 uint8_t sampleRateBytes[10], *audioDataU8; 26 int16_t *audioDataS16, smp16; 27 uint16_t numChannels, bitDepth; 28 int32_t *audioDataS32; 29 uint32_t i, blockName, blockSize; 30 uint32_t offset, len32; 31 sample_t *s = &tmpSmp; 32 33 fseek(f, 8, SEEK_SET); 34 fread(compType, 1, 4, f); 35 rewind(f); 36 37 if (filesize < 12) 38 { 39 loaderMsgBox("Error loading sample: The sample is not supported or is invalid!"); 40 return false; 41 } 42 43 uint32_t commPtr = 0, commLen = 0; 44 uint32_t ssndPtr = 0, ssndLen = 0; 45 46 fseek(f, 12, SEEK_SET); 47 while (!feof(f) && (uint32_t)ftell(f) < filesize-12) 48 { 49 fread(&blockName, 4, 1, f); if (feof(f)) break; 50 fread(&blockSize, 4, 1, f); if (feof(f)) break; 51 52 blockName = SWAP32(blockName); 53 blockSize = SWAP32(blockSize); 54 55 switch (blockName) 56 { 57 case 0x434F4D4D: // "COMM" 58 { 59 commPtr = ftell(f); 60 commLen = blockSize; 61 } 62 break; 63 64 case 0x53534E44: // "SSND" 65 { 66 ssndPtr = ftell(f); 67 ssndLen = blockSize; 68 } 69 break; 70 71 default: break; 72 } 73 74 fseek(f, blockSize + (blockSize & 1), SEEK_CUR); 75 } 76 77 if (commPtr == 0 || commLen < 18 || ssndPtr == 0) 78 { 79 loaderMsgBox("Error loading sample: The sample is not supported or is invalid!"); 80 return false; 81 } 82 83 // kludge for strange AIFFs 84 if (ssndLen == 0) 85 ssndLen = filesize - ssndPtr; 86 87 if (ssndPtr+ssndLen > (uint32_t)filesize) 88 ssndLen = filesize - ssndPtr; 89 90 fseek(f, commPtr, SEEK_SET); 91 fread(&numChannels, 2, 1, f); numChannels = SWAP16(numChannels); 92 fseek(f, 4, SEEK_CUR); 93 fread(&bitDepth, 2, 1, f); bitDepth = SWAP16(bitDepth); 94 fread(sampleRateBytes, 1, 10, f); 95 96 if (numChannels != 1 && numChannels != 2) 97 { 98 loaderMsgBox("Error loading sample: Unsupported amounts of channels!"); 99 return false; 100 } 101 102 // read compression type (if present) 103 bool signedSample = true; 104 bool floatSample = false; 105 if (commLen > 18) 106 { 107 fread(&compType, 1, 4, f); 108 109 if (!memcmp(compType, "raw ", 4)) 110 { 111 signedSample = false; 112 } 113 else if (!memcmp(compType, "FL32", 4) || !memcmp(compType, "fl32", 4) || !memcmp(compType, "FL64", 4) || !memcmp(compType, "fl64", 4)) 114 { 115 floatSample = true; 116 } 117 else 118 { 119 loaderMsgBox("Error loading sample: Unsupported AIFF type!"); 120 return false; 121 } 122 } 123 124 if (bitDepth != 8 && bitDepth != 16 && bitDepth != 24 && bitDepth != 32 && 125 !(floatSample && bitDepth == 64) && !(floatSample && bitDepth == 32)) 126 { 127 loaderMsgBox("Error loading sample: Unsupported AIFF type!"); 128 return false; 129 } 130 131 double dSampleRate = getAIFFSampleRate(sampleRateBytes); 132 133 // sample data chunk 134 135 fseek(f, ssndPtr, SEEK_SET); 136 137 fread(&offset, 4, 1, f); 138 if (offset > 0) 139 { 140 loaderMsgBox("Error loading sample: The sample is not supported or is invalid!"); 141 return false; 142 } 143 144 fseek(f, 4, SEEK_CUR); 145 146 ssndLen -= 8; // don't include offset and blockSize datas 147 148 uint32_t sampleLength = ssndLen; 149 150 int16_t stereoSampleLoadMode = -1; 151 if (aiffIsStereo(f)) 152 stereoSampleLoadMode = loaderSysReq(4, "System request", "This is a stereo sample...", NULL); 153 154 // read sample data 155 156 if (!floatSample && bitDepth == 8) // 8-BIT INTEGER SAMPLE 157 { 158 if (!allocateSmpData(s, sampleLength, false)) 159 { 160 loaderMsgBox("Not enough memory!"); 161 return false; 162 } 163 164 if (fread(s->dataPtr, sampleLength, 1, f) != 1) 165 { 166 loaderMsgBox("General I/O error during loading! Is the file in use?"); 167 return false; 168 } 169 170 audioDataS8 = (int8_t *)s->dataPtr; 171 if (!signedSample) 172 { 173 for (i = 0; i < sampleLength; i++) 174 audioDataS8[i] ^= 0x80; 175 } 176 177 // stereo conversion 178 if (numChannels == 2) 179 { 180 sampleLength /= 2; 181 182 switch (stereoSampleLoadMode) 183 { 184 case STEREO_SAMPLE_READ_LEFT: 185 { 186 for (i = 1; i < sampleLength; i++) 187 audioDataS8[i] = audioDataS8[(i * 2) + 0]; 188 } 189 break; 190 191 case STEREO_SAMPLE_READ_RIGHT: 192 { 193 len32 = sampleLength - 1; 194 for (i = 0; i < len32; i++) 195 audioDataS8[i] = audioDataS8[(i * 2) + 1]; 196 197 audioDataS8[i] = 0; 198 } 199 break; 200 201 default: 202 case STEREO_SAMPLE_CONVERT: 203 { 204 len32 = sampleLength - 1; 205 for (i = 0; i < len32; i++) 206 { 207 smp16 = (audioDataS8[(i * 2) + 0] + audioDataS8[(i * 2) + 1]) >> 1; 208 audioDataS8[i] = (int8_t)smp16; 209 } 210 211 audioDataS8[i] = 0; 212 } 213 break; 214 } 215 } 216 } 217 else if (!floatSample && bitDepth == 16) // 16-BIT INTEGER SAMPLE 218 { 219 sampleLength /= sizeof (int16_t); 220 if (!allocateSmpData(s, sampleLength * sizeof (int16_t), false)) 221 { 222 loaderMsgBox("Not enough memory!"); 223 return false; 224 } 225 226 if (fread(s->dataPtr, sampleLength, sizeof (int16_t), f) != sizeof (int16_t)) 227 { 228 loaderMsgBox("General I/O error during loading! Is the file in use?"); 229 return false; 230 } 231 232 // change endianness 233 audioDataS16 = (int16_t *)s->dataPtr; 234 for (i = 0; i < sampleLength; i++) 235 audioDataS16[i] = SWAP16(audioDataS16[i]); 236 237 // stereo conversion 238 if (numChannels == 2) 239 { 240 sampleLength /= 2; 241 242 switch (stereoSampleLoadMode) 243 { 244 case STEREO_SAMPLE_READ_LEFT: 245 { 246 for (i = 1; i < sampleLength; i++) 247 audioDataS16[i] = audioDataS16[(i * 2) + 0]; 248 } 249 break; 250 251 case STEREO_SAMPLE_READ_RIGHT: 252 { 253 len32 = sampleLength - 1; 254 for (i = 0; i < len32; i++) 255 audioDataS16[i] = audioDataS16[(i * 2) + 1]; 256 257 audioDataS16[i] = 0; 258 } 259 break; 260 261 default: 262 case STEREO_SAMPLE_CONVERT: 263 { 264 len32 = sampleLength - 1; 265 for (i = 0; i < len32; i++) 266 { 267 int32_t smp32 = (audioDataS16[(i * 2) + 0] + audioDataS16[(i * 2) + 1]) >> 1; 268 audioDataS16[i] = (int16_t)smp32; 269 } 270 271 audioDataS16[i] = 0; 272 } 273 break; 274 } 275 } 276 277 s->flags |= SAMPLE_16BIT; 278 } 279 else if (!floatSample && bitDepth == 24) // 24-BIT INTEGER SAMPLE 280 { 281 sampleLength /= 3; 282 if (!allocateSmpData(s, sampleLength * sizeof (int32_t), false)) 283 { 284 loaderMsgBox("Not enough memory!"); 285 return false; 286 } 287 288 if (fread(&s->dataPtr[sampleLength], sampleLength, 3, f) != 3) 289 { 290 loaderMsgBox("General I/O error during loading! Is the file in use?"); 291 return false; 292 } 293 294 audioDataS32 = (int32_t *)s->dataPtr; 295 296 // convert to 32-bit 297 audioDataU8 = (uint8_t *)s->dataPtr + sampleLength; 298 for (i = 0; i < sampleLength; i++) 299 { 300 audioDataS32[i] = (audioDataU8[0] << 24) | (audioDataU8[1] << 16) | (audioDataU8[2] << 8); 301 audioDataU8 += 3; 302 } 303 304 // stereo conversion 305 if (numChannels == 2) 306 { 307 sampleLength /= 2; 308 309 switch (stereoSampleLoadMode) 310 { 311 case STEREO_SAMPLE_READ_LEFT: 312 { 313 for (i = 1; i < sampleLength; i++) 314 audioDataS32[i] = audioDataS32[(i * 2) + 0]; 315 } 316 break; 317 318 case STEREO_SAMPLE_READ_RIGHT: 319 { 320 len32 = sampleLength - 1; 321 for (i = 0; i < len32; i++) 322 audioDataS32[i] = audioDataS32[(i * 2) + 1]; 323 324 audioDataS32[i] = 0; 325 } 326 break; 327 328 default: 329 case STEREO_SAMPLE_CONVERT: 330 { 331 len32 = sampleLength - 1; 332 for (i = 0; i < len32; i++) 333 { 334 int64_t smp64 = audioDataS32[(i * 2) + 0]; 335 smp64 += audioDataS32[(i * 2) + 1]; 336 smp64 >>= 1; 337 338 audioDataS32[i] = (int32_t)smp64; 339 } 340 341 audioDataS32[i] = 0; 342 } 343 break; 344 } 345 } 346 347 normalizeSigned32Bit(audioDataS32, sampleLength); 348 349 audioDataS16 = (int16_t *)s->dataPtr; 350 for (i = 0; i < sampleLength; i++) 351 audioDataS16[i] = audioDataS32[i] >> 16; 352 353 s->flags |= SAMPLE_16BIT; 354 } 355 else if (!floatSample && bitDepth == 32) // 32-BIT INTEGER SAMPLE 356 { 357 sampleLength /= sizeof (int32_t); 358 if (!allocateSmpData(s, sampleLength * sizeof (int32_t), false)) 359 { 360 loaderMsgBox("Not enough memory!"); 361 return false; 362 } 363 364 if (fread(s->dataPtr, sampleLength, sizeof (int32_t), f) != sizeof (int32_t)) 365 { 366 loaderMsgBox("General I/O error during loading! Is the file in use?"); 367 return false; 368 } 369 370 // change endianness 371 audioDataS32 = (int32_t *)s->dataPtr; 372 for (i = 0; i < sampleLength; i++) 373 audioDataS32[i] = SWAP32(audioDataS32[i]); 374 375 // stereo conversion 376 if (numChannels == 2) 377 { 378 sampleLength /= 2; 379 380 switch (stereoSampleLoadMode) 381 { 382 case STEREO_SAMPLE_READ_LEFT: 383 { 384 for (i = 1; i < sampleLength; i++) 385 audioDataS32[i] = audioDataS32[(i * 2) + 0]; 386 } 387 break; 388 389 case STEREO_SAMPLE_READ_RIGHT: 390 { 391 len32 = sampleLength - 1; 392 for (i = 0; i < len32; i++) 393 audioDataS32[i] = audioDataS32[(i * 2) + 1]; 394 395 audioDataS32[i] = 0; 396 } 397 break; 398 399 default: 400 case STEREO_SAMPLE_CONVERT: 401 { 402 len32 = sampleLength - 1; 403 for (i = 0; i < len32; i++) 404 { 405 int64_t smp64 = audioDataS32[(i * 2) + 0]; 406 smp64 += audioDataS32[(i * 2) + 1]; 407 smp64 >>= 1; 408 409 audioDataS32[i] = (int32_t)smp64; 410 } 411 412 audioDataS32[i] = 0; 413 } 414 break; 415 } 416 } 417 418 normalizeSigned32Bit(audioDataS32, sampleLength); 419 420 audioDataS16 = (int16_t *)s->dataPtr; 421 for (i = 0; i < sampleLength; i++) 422 audioDataS16[i] = audioDataS32[i] >> 16; 423 424 s->flags |= SAMPLE_16BIT; 425 } 426 else if (floatSample && bitDepth == 32) // 32-BIT FLOAT SAMPLE 427 { 428 sampleLength /= sizeof (float); 429 if (!allocateSmpData(s, sampleLength * sizeof (float), false)) 430 { 431 loaderMsgBox("Not enough memory!"); 432 return false; 433 } 434 435 if (fread(s->dataPtr, sampleLength, sizeof (float), f) != sizeof (float)) 436 { 437 loaderMsgBox("General I/O error during loading! Is the file in use?"); 438 return false; 439 } 440 441 // change endianness 442 audioDataS32 = (int32_t *)s->dataPtr; 443 for (i = 0; i < sampleLength; i++) 444 audioDataS32[i] = SWAP32(audioDataS32[i]); 445 446 float *fAudioDataFloat = (float *)s->dataPtr; 447 448 // stereo conversion 449 if (numChannels == 2) 450 { 451 sampleLength /= 2; 452 switch (stereoSampleLoadMode) 453 { 454 case STEREO_SAMPLE_READ_LEFT: 455 { 456 // remove right channel data 457 for (i = 1; i < sampleLength; i++) 458 fAudioDataFloat[i] = fAudioDataFloat[(i * 2) + 0]; 459 } 460 break; 461 462 case STEREO_SAMPLE_READ_RIGHT: 463 { 464 // remove left channel data 465 len32 = sampleLength - 1; 466 for (i = 0; i < len32; i++) 467 fAudioDataFloat[i] = fAudioDataFloat[(i * 2) + 1]; 468 469 fAudioDataFloat[i] = 0.0f; 470 } 471 break; 472 473 default: 474 case STEREO_SAMPLE_CONVERT: 475 { 476 // mix stereo to mono 477 len32 = sampleLength - 1; 478 for (i = 0; i < len32; i++) 479 fAudioDataFloat[i] = (fAudioDataFloat[(i * 2) + 0] + fAudioDataFloat[(i * 2) + 1]) * 0.5f; 480 481 fAudioDataFloat[i] = 0.0f; 482 } 483 break; 484 } 485 } 486 487 normalize32BitFloatToSigned16Bit(fAudioDataFloat, sampleLength); 488 489 int16_t *ptr16 = (int16_t *)s->dataPtr; 490 for (i = 0; i < sampleLength; i++) 491 { 492 const int32_t smp32 = (const int32_t)fAudioDataFloat[i]; 493 ptr16[i] = (int16_t)smp32; 494 } 495 496 s->flags |= SAMPLE_16BIT; 497 } 498 else if (floatSample && bitDepth == 64) // 64-BIT FLOAT SAMPLE 499 { 500 sampleLength /= sizeof (double); 501 if (!allocateSmpData(s, sampleLength * sizeof (double), false)) 502 { 503 loaderMsgBox("Not enough memory!"); 504 return false; 505 } 506 507 if (fread(s->dataPtr, sampleLength, sizeof (double), f) != sizeof (double)) 508 { 509 loaderMsgBox("General I/O error during loading! Is the file in use?"); 510 return false; 511 } 512 513 // change endianness 514 int64_t *audioDataS64 = (int64_t *)s->dataPtr; 515 for (i = 0; i < sampleLength; i++) 516 audioDataS64[i] = SWAP64(audioDataS64[i]); 517 518 double *dAudioDataDouble = (double *)s->dataPtr; 519 520 // stereo conversion 521 if (numChannels == 2) 522 { 523 sampleLength /= 2; 524 switch (stereoSampleLoadMode) 525 { 526 case STEREO_SAMPLE_READ_LEFT: 527 { 528 // remove right channel data 529 for (i = 1; i < sampleLength; i++) 530 dAudioDataDouble[i] = dAudioDataDouble[(i * 2) + 0]; 531 } 532 break; 533 534 case STEREO_SAMPLE_READ_RIGHT: 535 { 536 // remove left channel data 537 len32 = sampleLength - 1; 538 for (i = 0; i < len32; i++) 539 dAudioDataDouble[i] = dAudioDataDouble[(i * 2) + 1]; 540 541 dAudioDataDouble[i] = 0.0; 542 } 543 break; 544 545 default: 546 case STEREO_SAMPLE_CONVERT: 547 { 548 // mix stereo to mono 549 len32 = sampleLength - 1; 550 for (i = 0; i < len32; i++) 551 dAudioDataDouble[i] = (dAudioDataDouble[(i * 2) + 0] + dAudioDataDouble[(i * 2) + 1]) * 0.5; 552 553 dAudioDataDouble[i] = 0.0; 554 } 555 break; 556 } 557 } 558 559 normalize64BitFloatToSigned16Bit(dAudioDataDouble, sampleLength); 560 561 int16_t *ptr16 = (int16_t *)s->dataPtr; 562 for (i = 0; i < sampleLength; i++) 563 { 564 const int32_t smp32 = (const int32_t)dAudioDataDouble[i]; 565 ptr16[i] = (int16_t)smp32; 566 } 567 568 s->flags |= SAMPLE_16BIT; 569 } 570 571 if (sampleLength > MAX_SAMPLE_LEN) 572 sampleLength = MAX_SAMPLE_LEN; 573 574 bool sample16Bit = !!(s->flags & SAMPLE_16BIT); 575 reallocateSmpData(s, sampleLength, sample16Bit); // readjust memory needed 576 577 s->length = sampleLength; 578 s->volume = 64; 579 s->panning = 128; 580 581 setSampleC4Hz(s, dSampleRate); 582 583 return true; 584 } 585 586 static double getAIFFSampleRate(uint8_t *in) 587 { 588 /* 80-bit IEEE-754 to unsigned double-precision float. 589 ** Sign bit is ignored. 590 */ 591 592 #define EXP_BIAS 16383 593 594 const uint16_t exp15 = ((in[0] & 0x7F) << 8) | in[1]; 595 const uint64_t mantissaBits = *(uint64_t *)&in[2]; 596 const uint64_t mantissa63 = SWAP64(mantissaBits) & INT64_MAX; 597 598 double dExp = exp15 - EXP_BIAS; 599 double dMantissa = mantissa63 / (INT64_MAX+1.0); 600 601 return (1.0 + dMantissa) * exp2(dExp); 602 } 603 604 static bool aiffIsStereo(FILE *f) // only ran on files that are confirmed to be AIFFs 605 { 606 uint16_t numChannels; 607 uint32_t chunkID, chunkSize; 608 609 uint32_t oldPos = ftell(f); 610 611 fseek(f, 0, SEEK_END); 612 int32_t filesize = ftell(f); 613 614 if (filesize < 12) 615 { 616 fseek(f, oldPos, SEEK_SET); 617 return false; 618 } 619 620 fseek(f, 12, SEEK_SET); 621 622 uint32_t commPtr = 0; 623 uint32_t commLen = 0; 624 625 int32_t bytesRead = 0; 626 while (!feof(f) && bytesRead < filesize-12) 627 { 628 fread(&chunkID, 4, 1, f); chunkID = SWAP32(chunkID); if (feof(f)) break; 629 fread(&chunkSize, 4, 1, f); chunkSize = SWAP32(chunkSize); if (feof(f)) break; 630 631 int32_t endOfChunk = (ftell(f) + chunkSize) + (chunkSize & 1); 632 switch (chunkID) 633 { 634 case 0x434F4D4D: // "COMM" 635 { 636 commPtr = ftell(f); 637 commLen = chunkSize; 638 } 639 break; 640 641 default: break; 642 } 643 644 bytesRead += (chunkSize + (chunkSize & 1)); 645 fseek(f, endOfChunk, SEEK_SET); 646 } 647 648 if (commPtr == 0 || commLen < 2) 649 { 650 fseek(f, oldPos, SEEK_SET); 651 return false; 652 } 653 654 fseek(f, commPtr, SEEK_SET); 655 fread(&numChannels, 2, 1, f); numChannels = SWAP16(numChannels); 656 fseek(f, oldPos, SEEK_SET); 657 658 return (numChannels == 2); 659 }