| 58 | | |
|---|
| 59 | | static int sample_rates[] = {48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 6000, 5512, 4000}; |
|---|
| 60 | | for (int sample_index = 0; sample_index < 12; sample_index ++) |
|---|
| 61 | | { |
|---|
| 62 | | for (int channels = 1; channels <= 6; channels++) { |
|---|
| 63 | | // This decoder only takes an A/52 or AC-3 stream as it's input |
|---|
| 64 | | CAStreamBasicDescription theInputFormat1(sample_rates[sample_index], kAudioFormatAC3, 0, 256*6, 0, channels, 0, 0); |
|---|
| 65 | | AddInputFormat(theInputFormat1); |
|---|
| 66 | | CAStreamBasicDescription theInputFormat2(sample_rates[sample_index], kAudioFormatAVIAC3, 0, 256*6, 0, channels, 0, 0); |
|---|
| 67 | | AddInputFormat(theInputFormat2); |
|---|
| 68 | | |
|---|
| 69 | | // Output 16-Bit Ints |
|---|
| 70 | | CAStreamBasicDescription theOutputFormat1(sample_rates[sample_index], kAudioFormatLinearPCM, 0, 1, 0, channels, 16, kIntPCMOutFormatFlag); |
|---|
| 71 | | AddOutputFormat(theOutputFormat1); |
|---|
| 72 | | |
|---|
| 73 | | // And 32-Bit |
|---|
| 74 | | CAStreamBasicDescription theOutputFormat2(sample_rates[sample_index], kAudioFormatLinearPCM, 0, 1, 0, channels, 32, kIntPCMOutFormatFlag); |
|---|
| 75 | | AddOutputFormat(theOutputFormat2); |
|---|
| 76 | | |
|---|
| 77 | | // And floats |
|---|
| 78 | | CAStreamBasicDescription theOutputFormat3(sample_rates[sample_index], kAudioFormatLinearPCM, 0, 1, 0, channels, 32, kFloatPCMOutFormatFlag); |
|---|
| 79 | | AddOutputFormat(theOutputFormat3); |
|---|
| 80 | | } |
|---|
| 81 | | } |
|---|
| 82 | | |
|---|
| 83 | | total_bytes = 0; |
|---|
| 84 | | total_frames = 0; |
|---|
| 85 | | decoder_state = NULL; |
|---|
| 86 | | firstInput = true; |
|---|
| 87 | | |
|---|
| 88 | | remainingBytesFromLastFrame = 0; |
|---|
| 89 | | beginningOfIncompleteHeaderSize = 0; |
|---|
| | 97 | CFTypeRef pass = CFPreferencesCopyAppValue(CFSTR("attemptPassthrough"), CFSTR("com.cod3r.a52codec")); |
|---|
| | 98 | if(pass != NULL) |
|---|
| | 99 | { |
|---|
| | 100 | CFTypeID type = CFGetTypeID(pass); |
|---|
| | 101 | if(type == CFStringGetTypeID()) |
|---|
| | 102 | passthrough = CFStringGetIntValue((CFStringRef)pass); |
|---|
| | 103 | else if(type == CFNumberGetTypeID()) |
|---|
| | 104 | CFNumberGetValue((CFNumberRef)pass, kCFNumberIntType, &passthrough); |
|---|
| | 105 | else |
|---|
| | 106 | passthrough = 0; |
|---|
| | 107 | CFRelease(pass); |
|---|
| | 108 | } |
|---|
| | 109 | else |
|---|
| | 110 | passthrough = 0; |
|---|
| | 111 | |
|---|
| | 112 | if(passthrough) |
|---|
| | 113 | { |
|---|
| | 114 | //begin our passthrough hack |
|---|
| | 115 | static int sample_rates[] = {48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 6000, 5512, 4000}; |
|---|
| | 116 | for (int sample_index = 0; sample_index < 12; sample_index ++) |
|---|
| | 117 | { |
|---|
| | 118 | for (int channels = 1; channels <= 2; channels++) { |
|---|
| | 119 | CAStreamBasicDescription theOutputFormat(sample_rates[sample_index], kAudioFormatLinearPCM, 0, 1, 0, channels, 16, kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked); |
|---|
| | 120 | AddOutputFormat(theOutputFormat); |
|---|
| | 121 | // This decoder only takes an A/52 or AC-3 stream as it's input |
|---|
| | 122 | CAStreamBasicDescription theInputFormat1(sample_rates[sample_index], kAudioFormatAC3, 0, 256*6, 0, channels, 0, 0); |
|---|
| | 123 | AddInputFormat(theInputFormat1); |
|---|
| | 124 | CAStreamBasicDescription theInputFormat2(sample_rates[sample_index], kAudioFormatAVIAC3, 0, 256*6, 0, channels, 0, 0); |
|---|
| | 125 | AddInputFormat(theInputFormat2); |
|---|
| | 126 | } |
|---|
| | 127 | } |
|---|
| | 128 | |
|---|
| | 129 | } |
|---|
| | 130 | else |
|---|
| | 131 | { |
|---|
| | 132 | static int sample_rates[] = {48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 6000, 5512, 4000}; |
|---|
| | 133 | for (int sample_index = 0; sample_index < 12; sample_index ++) |
|---|
| | 134 | { |
|---|
| | 135 | for (int channels = 1; channels <= 6; channels++) { |
|---|
| | 136 | // This decoder only takes an A/52 or AC-3 stream as it's input |
|---|
| | 137 | CAStreamBasicDescription theInputFormat1(sample_rates[sample_index], kAudioFormatAC3, 0, 256*6, 0, channels, 0, 0); |
|---|
| | 138 | AddInputFormat(theInputFormat1); |
|---|
| | 139 | CAStreamBasicDescription theInputFormat2(sample_rates[sample_index], kAudioFormatAVIAC3, 0, 256*6, 0, channels, 0, 0); |
|---|
| | 140 | AddInputFormat(theInputFormat2); |
|---|
| | 141 | |
|---|
| | 142 | // Output 16-Bit Ints |
|---|
| | 143 | CAStreamBasicDescription theOutputFormat1(sample_rates[sample_index], kAudioFormatLinearPCM, 0, 1, 0, channels, 16, kIntPCMOutFormatFlag); |
|---|
| | 144 | AddOutputFormat(theOutputFormat1); |
|---|
| | 145 | |
|---|
| | 146 | // And 32-Bit |
|---|
| | 147 | CAStreamBasicDescription theOutputFormat2(sample_rates[sample_index], kAudioFormatLinearPCM, 0, 1, 0, channels, 32, kIntPCMOutFormatFlag); |
|---|
| | 148 | AddOutputFormat(theOutputFormat2); |
|---|
| | 149 | |
|---|
| | 150 | // And floats |
|---|
| | 151 | CAStreamBasicDescription theOutputFormat3(sample_rates[sample_index], kAudioFormatLinearPCM, 0, 1, 0, channels, 32, kFloatPCMOutFormatFlag); |
|---|
| | 152 | AddOutputFormat(theOutputFormat3); |
|---|
| | 153 | } |
|---|
| | 154 | } |
|---|
| | 155 | } |
|---|
| | 156 | |
|---|
| | 157 | total_bytes = 0; |
|---|
| | 158 | total_frames = 0; |
|---|
| | 159 | decoder_state = NULL; |
|---|
| | 160 | firstInput = true; |
|---|
| | 161 | |
|---|
| | 162 | remainingBytesFromLastFrame = 0; |
|---|
| | 163 | beginningOfIncompleteHeaderSize = 0; |
|---|
| | 164 | |
|---|
| 478 | | switch(mOutputFormat.mChannelsPerFrame) { |
|---|
| 479 | | case 1: |
|---|
| 480 | | // Just mono |
|---|
| 481 | | a52_flags = A52_MONO | A52_ADJUST_LEVEL; |
|---|
| 482 | | break; |
|---|
| 483 | | |
|---|
| 484 | | case 2: |
|---|
| 485 | | // All we really need is stereophonic, baby |
|---|
| 486 | | if(useStereoOverDolby) |
|---|
| 487 | | a52_flags = A52_STEREO | A52_ADJUST_LEVEL; |
|---|
| 488 | | else |
|---|
| 489 | | a52_flags = A52_DOLBY | A52_ADJUST_LEVEL; |
|---|
| 490 | | break; |
|---|
| 491 | | |
|---|
| 492 | | case 5: |
|---|
| 493 | | // Try to get 5.0 channels |
|---|
| 494 | | a52_flags = A52_3F2R | A52_ADJUST_LEVEL; |
|---|
| 495 | | break; |
|---|
| 496 | | |
|---|
| 497 | | case 6: |
|---|
| 498 | | // Try to get 5.1 channels |
|---|
| 499 | | a52_flags = A52_3F2R | A52_LFE | A52_ADJUST_LEVEL; |
|---|
| 500 | | break; |
|---|
| 501 | | |
|---|
| 502 | | default: |
|---|
| 503 | | fprintf(stderr, "ACShepA52Decoder::ProduceOutputPackets: Unknown output channel amount\n"); |
|---|
| 504 | | break; |
|---|
| 505 | | } |
|---|
| 506 | | |
|---|
| 507 | | readLength = bytes_to_read; |
|---|
| 508 | | input_data = GetBytes(readLength); |
|---|
| 509 | | a52_frame(decoder_state, input_data, &a52_flags, &level, bias); |
|---|
| 510 | | a52_dynrng(decoder_state, dynrng_call, &dynamicRangeCompression); |
|---|
| 511 | | |
|---|
| 512 | | // Cycle through the blocks, and actually do stuff |
|---|
| 513 | | for (int j = 0; j < 6; j++) { |
|---|
| 514 | | a52_block(decoder_state); |
|---|
| 515 | | output_samples = a52_samples(decoder_state); |
|---|
| 516 | | |
|---|
| 517 | | // Need to know what kind of output data to process |
|---|
| 518 | | if (mOutputFormat.mFormatFlags == kIntPCMOutFormatFlag) { |
|---|
| 519 | | if (mOutputFormat.mBitsPerChannel == 16) { |
|---|
| 520 | | output_offset += Process16BitSignedInts(outOutputData, output_offset, output_samples, a52_flags); |
|---|
| | 514 | if(passthrough) |
|---|
| | 515 | { |
|---|
| | 516 | static const uint8_t p_sync_le[6] = { 0x72, 0xF8, 0x1F, 0x4E, 0x01, 0x00 }; |
|---|
| | 517 | |
|---|
| | 518 | uint8_t *myOutputData = (uint8_t *)(outOutputData); |
|---|
| | 519 | |
|---|
| | 520 | myOutputData += output_offset * output_sample_size; //output_offset is in 16-bit ints |
|---|
| | 521 | |
|---|
| | 522 | memset(myOutputData, 0, 2 * 2 * 256 * 6); |
|---|
| | 523 | memcpy(myOutputData, p_sync_le, 6); |
|---|
| | 524 | input_data = GetBytes(bytes_to_read); |
|---|
| | 525 | myOutputData[5] = input_data[5] & 0x7; |
|---|
| | 526 | myOutputData[6] = (bytes_to_read << 4) & 0xff; |
|---|
| | 527 | myOutputData[7] = (bytes_to_read >> 4) & 0xff; |
|---|
| | 528 | unsigned int i; |
|---|
| | 529 | for(i=0; i<bytes_to_read; i+=2) |
|---|
| | 530 | { |
|---|
| | 531 | myOutputData[i+8] = input_data[i+1]; |
|---|
| | 532 | myOutputData[i+9] = input_data[i]; |
|---|
| | 533 | } |
|---|
| | 534 | output_offset += mOutputFormat.mChannelsPerFrame * 256 * 6; //Our framed hack |
|---|
| | 535 | } |
|---|
| | 536 | else |
|---|
| | 537 | { |
|---|
| | 538 | switch(mOutputFormat.mChannelsPerFrame) { |
|---|
| | 539 | case 1: |
|---|
| | 540 | // Just mono |
|---|
| | 541 | a52_flags = A52_MONO | A52_ADJUST_LEVEL; |
|---|
| | 542 | break; |
|---|
| | 543 | |
|---|
| | 544 | case 2: |
|---|
| | 545 | // All we really need is stereophonic, baby |
|---|
| | 546 | if(useStereoOverDolby) |
|---|
| | 547 | a52_flags = A52_STEREO | A52_ADJUST_LEVEL; |
|---|
| | 548 | else |
|---|
| | 549 | a52_flags = A52_DOLBY | A52_ADJUST_LEVEL; |
|---|
| | 550 | break; |
|---|
| | 551 | |
|---|
| | 552 | case 5: |
|---|
| | 553 | // Try to get 5.0 channels |
|---|
| | 554 | a52_flags = A52_3F2R | A52_ADJUST_LEVEL; |
|---|
| | 555 | break; |
|---|
| | 556 | |
|---|
| | 557 | case 6: |
|---|
| | 558 | // Try to get 5.1 channels |
|---|
| | 559 | a52_flags = A52_3F2R | A52_LFE | A52_ADJUST_LEVEL; |
|---|
| | 560 | break; |
|---|
| | 561 | |
|---|
| | 562 | default: |
|---|
| | 563 | fprintf(stderr, "ACShepA52Decoder::ProduceOutputPackets: Unknown output channel amount\n"); |
|---|
| | 564 | break; |
|---|
| | 565 | } |
|---|
| | 566 | |
|---|
| | 567 | readLength = bytes_to_read; |
|---|
| | 568 | input_data = GetBytes(readLength); |
|---|
| | 569 | a52_frame(decoder_state, input_data, &a52_flags, &level, bias); |
|---|
| | 570 | a52_dynrng(decoder_state, dynrng_call, &dynamicRangeCompression); |
|---|
| | 571 | |
|---|
| | 572 | // Cycle through the blocks, and actually do stuff |
|---|
| | 573 | for (int j = 0; j < 6; j++) { |
|---|
| | 574 | a52_block(decoder_state); |
|---|
| | 575 | output_samples = a52_samples(decoder_state); |
|---|
| | 576 | |
|---|
| | 577 | // Need to know what kind of output data to process |
|---|
| | 578 | if (mOutputFormat.mFormatFlags == kIntPCMOutFormatFlag) { |
|---|
| | 579 | if (mOutputFormat.mBitsPerChannel == 16) { |
|---|
| | 580 | output_offset += Process16BitSignedInts(outOutputData, output_offset, output_samples, a52_flags); |
|---|
| | 581 | } else { |
|---|
| | 582 | output_offset += Process32BitSignedInts(outOutputData, output_offset, output_samples, a52_flags); |
|---|
| | 583 | } |
|---|