| | 478 | |
|---|
| | 479 | // Output order of liba52: LFE, left, center, right, left surround, right surround. |
|---|
| | 480 | // Channels missing are skipped |
|---|
| | 481 | // Supposed input to CoreAudio is: left, right, center, LFE, left surround, right surround |
|---|
| | 482 | |
|---|
| | 483 | void getChannelMap(int a52_flags, int chanMap[6]) |
|---|
| | 484 | { |
|---|
| | 485 | int defaultMap[] = {0, 1, 2, 3, 4, 5}; |
|---|
| | 486 | int frontChan = 0; |
|---|
| | 487 | int lfe = a52_flags & A52_LFE ? 1 : 0; |
|---|
| | 488 | |
|---|
| | 489 | memcpy(chanMap, defaultMap, sizeof(defaultMap)); |
|---|
| | 490 | switch (a52_flags & A52_CHANNEL_MASK) { |
|---|
| | 491 | case A52_STEREO: |
|---|
| | 492 | case A52_DOLBY: |
|---|
| | 493 | case A52_2F1R: |
|---|
| | 494 | case A52_2F2R: |
|---|
| | 495 | chanMap[1] = lfe + 1; |
|---|
| | 496 | frontChan = 1; |
|---|
| | 497 | |
|---|
| | 498 | case A52_CHANNEL: |
|---|
| | 499 | case A52_CHANNEL1: |
|---|
| | 500 | case A52_CHANNEL2: |
|---|
| | 501 | case A52_MONO: |
|---|
| | 502 | chanMap[0] = lfe; |
|---|
| | 503 | frontChan++; |
|---|
| | 504 | break; |
|---|
| | 505 | |
|---|
| | 506 | case A52_3F: |
|---|
| | 507 | case A52_3F1R: |
|---|
| | 508 | case A52_3F2R: |
|---|
| | 509 | chanMap[0] = lfe; |
|---|
| | 510 | chanMap[1] = lfe + 2; |
|---|
| | 511 | chanMap[2] = lfe + 1; |
|---|
| | 512 | frontChan = 3; |
|---|
| | 513 | break; |
|---|
| | 514 | |
|---|
| | 515 | default: |
|---|
| | 516 | break; |
|---|
| | 517 | } |
|---|
| | 518 | if(lfe) |
|---|
| | 519 | chanMap[frontChan] = 0; |
|---|
| | 520 | } |
|---|
| | 521 | |
|---|
| | 522 | template <class outPtr, class inPtr> |
|---|
| | 523 | UInt32 InterleaveSamples(void *output_data_untyped, UInt32 output_data_offset, sample_t *output_samples, int a52_flags) { |
|---|
| | 524 | inPtr *cast_samples; |
|---|
| | 525 | outPtr *output_data = (outPtr *)output_data_untyped; |
|---|
| | 526 | |
|---|
| | 527 | cast_samples = (inPtr *)output_samples; |
|---|
| | 528 | |
|---|
| | 529 | int chans = ChannelCount(a52_flags); |
|---|
| | 530 | |
|---|
| | 531 | // each element is the liba52 channel number of the CA channel number of the index |
|---|
| | 532 | int chanMap[6]; |
|---|
| | 533 | getChannelMap(a52_flags, chanMap); |
|---|
| | 534 | |
|---|
| | 535 | for (int i = 0; i < 256; i++) { |
|---|
| | 536 | for (int j = 0; j < chans; j++) { |
|---|
| | 537 | output_data[chans*i + output_data_offset + j] = cast_samples[i + 256*chanMap[j]]; |
|---|
| | 538 | } |
|---|
| | 539 | } |
|---|
| | 540 | |
|---|
| | 541 | return chans * 256; // Number of 'UInt16' we processed |
|---|
| | 542 | } |
|---|
| | 543 | |
|---|
| 695 | | } |
|---|
| 696 | | |
|---|
| 697 | | |
|---|
| 698 | | // Output order of liba52: LFE, left, center, right, left surround, right surround. |
|---|
| 699 | | // Channels missing are skipped |
|---|
| 700 | | // Supposed input to CoreAudio is: left, right, center, LFE, left surround, right surround |
|---|
| 701 | | |
|---|
| 702 | | UInt32 ACShepA52Decoder::Process16BitSignedInts(void *output_data_untyped, UInt32 output_data_offset, sample_t *output_samples, int a52_flags) { |
|---|
| 703 | | SInt32 *cast_samples; |
|---|
| 704 | | SInt16 *output_data = (SInt16 *)output_data_untyped; |
|---|
| 705 | | |
|---|
| 706 | | cast_samples = (SInt32 *)output_samples; |
|---|
| 707 | | |
|---|
| 708 | | // Weird things... |
|---|
| 709 | | // As far as I can see, we take a float, cast it to an UInt32, then copy it to a UInt16 |
|---|
| 710 | | // The trick being: level = 1 and bias = 384 |
|---|
| 711 | | |
|---|
| 712 | | // It is 256 samples |
|---|
| 713 | | |
|---|
| 714 | | // ME.f is using 16-bit |
|---|
| 715 | | |
|---|
| 716 | | switch(a52_flags & A52_CHANNEL_MASK) { |
|---|
| 717 | | |
|---|
| 718 | | // 5 Channel |
|---|
| 719 | | case A52_3F2R: |
|---|
| 720 | | |
|---|
| 721 | | // With LFE |
|---|
| 722 | | if (a52_flags & A52_LFE) { |
|---|
| 723 | | //fprintf(stderr, "ACShepA52Decoder::Process16BitSignedInts: Running 5.1\n"); |
|---|
| 724 | | |
|---|
| 725 | | for (int k = 0; k < 256; k++) { |
|---|
| 726 | | output_data[6*k + output_data_offset + 3] = cast_samples[k + 256*0]; // LFE chan |
|---|
| 727 | | output_data[6*k + output_data_offset + 0] = cast_samples[k + 256*1]; // left chan |
|---|
| 728 | | output_data[6*k + output_data_offset + 2] = cast_samples[k + 256*2]; // center chan |
|---|
| 729 | | output_data[6*k + output_data_offset + 1] = cast_samples[k + 256*3]; // right chan |
|---|
| 730 | | output_data[6*k + output_data_offset + 4] = cast_samples[k + 256*4]; // left surround chan |
|---|
| 731 | | output_data[6*k + output_data_offset + 5] = cast_samples[k + 256*5]; // right surround chan |
|---|
| 732 | | } |
|---|
| 733 | | |
|---|
| 734 | | return 6 * 256; // Number of 'UInt16' we processed |
|---|
| 735 | | |
|---|
| 736 | | } else { |
|---|
| 737 | | //fprintf(stderr, "ACShepA52Decoder::Process16BitSignedInts: Running 5.0\n"); |
|---|
| 738 | | for (int k = 0; k < 256; k++) { |
|---|
| 739 | | output_data[5*k + output_data_offset + 0] = cast_samples[k + 256*0]; // left chan |
|---|
| 740 | | output_data[5*k + output_data_offset + 2] = cast_samples[k + 256*1]; // center chan |
|---|
| 741 | | output_data[5*k + output_data_offset + 1] = cast_samples[k + 256*2]; // right chan |
|---|
| 742 | | output_data[5*k + output_data_offset + 3] = cast_samples[k + 256*3]; // left surround chan |
|---|
| 743 | | output_data[5*k + output_data_offset + 4] = cast_samples[k + 256*4]; // right surround chan |
|---|
| 744 | | } |
|---|
| 745 | | |
|---|
| 746 | | return 5 * 256; // Number of 'UInt16' we processed |
|---|
| 747 | | } |
|---|
| 748 | | break; |
|---|
| 749 | | |
|---|
| 750 | | // Stereo |
|---|
| 751 | | case A52_STEREO: |
|---|
| 752 | | case A52_DOLBY: |
|---|
| 753 | | //fprintf(stderr, "ACShepA52Decoder::Process16BitSignedInts: Running stereo\n"); |
|---|
| 754 | | |
|---|
| 755 | | for (int k = 0; k < 256; k++) { |
|---|
| 756 | | output_data[2*k + output_data_offset] = cast_samples[k]; // left chan |
|---|
| 757 | | output_data[2*k + output_data_offset + 1] = cast_samples[k + 256]; // right chan |
|---|
| 758 | | } |
|---|
| 759 | | |
|---|
| 760 | | return 2 * 256; // Number of 'UInt16' we processed |
|---|
| 761 | | |
|---|
| 762 | | break; |
|---|
| 763 | | |
|---|
| 764 | | // Mono |
|---|
| 765 | | case A52_MONO: |
|---|
| 766 | | //fprintf(stderr, "ACShepA52Decoder::Process16BitSignedInts: Running mono\n"); |
|---|
| 767 | | |
|---|
| 768 | | for (int k = 0; k < 256; k++) { |
|---|
| 769 | | output_data[k + output_data_offset] = cast_samples[k]; // mono chan |
|---|
| 770 | | } |
|---|
| 771 | | |
|---|
| 772 | | return 256; // Number of 'UInt16' we processed |
|---|
| 773 | | |
|---|
| 774 | | break; |
|---|
| 775 | | |
|---|
| 776 | | default: |
|---|
| 777 | | fprintf(stderr, "ACShepA52Decoder::Process16BitSignedInts: Failed to match output channels\n"); |
|---|
| 778 | | } |
|---|
| 779 | | |
|---|
| 780 | | return 0; |
|---|
| 781 | | } |
|---|
| 782 | | |
|---|
| 783 | | // Output order of liba52: LFE, left, center, right, left surround, right surround. |
|---|
| 784 | | // Channels missing are skipped |
|---|
| 785 | | // Supposed input to CoreAudio is: left, right, center, LFE, left surround, right surround |
|---|
| 786 | | |
|---|
| 787 | | UInt32 ACShepA52Decoder::Process32BitSignedInts(void *output_data_untyped, UInt32 output_data_offset, sample_t *output_samples, int a52_flags) { |
|---|
| 788 | | SInt32 *output_data = (SInt32 *)output_data_untyped; |
|---|
| 789 | | |
|---|
| 790 | | //fprintf(stderr, "ACShepA52Decoder::Process32BitSignedInts: Flags are: 0x%08X\n", a52_flags); |
|---|
| 791 | | |
|---|
| 792 | | // PlayAudioFileLite uses SInt32 |
|---|
| 793 | | |
|---|
| 794 | | switch(a52_flags & A52_CHANNEL_MASK) { |
|---|
| 795 | | |
|---|
| 796 | | // 5 Channel |
|---|
| 797 | | case A52_3F2R: |
|---|
| 798 | | |
|---|
| 799 | | // With LFE |
|---|
| 800 | | if (a52_flags & A52_LFE) { |
|---|
| 801 | | //fprintf(stderr, "ACShepA52Decoder::Process32BitSignedInts: Running 5.1\n"); |
|---|
| 802 | | |
|---|
| 803 | | for (int k = 0; k < 256; k++) { |
|---|
| 804 | | output_data[6*k + output_data_offset + 3] = (SInt32)output_samples[k + 256*0]; // LFE chan |
|---|
| 805 | | output_data[6*k + output_data_offset + 0] = (SInt32)output_samples[k + 256*1]; // left chan |
|---|
| 806 | | output_data[6*k + output_data_offset + 2] = (SInt32)output_samples[k + 256*2]; // center chan |
|---|
| 807 | | output_data[6*k + output_data_offset + 1] = (SInt32)output_samples[k + 256*3]; // right chan |
|---|
| 808 | | output_data[6*k + output_data_offset + 4] = (SInt32)output_samples[k + 256*4]; // left surround chan |
|---|
| 809 | | output_data[6*k + output_data_offset + 5] = (SInt32)output_samples[k + 256*5]; // right surround chan |
|---|
| 810 | | } |
|---|
| 811 | | |
|---|
| 812 | | return 6 * 256; // Number of 'UInt32' we processed |
|---|
| 813 | | } else { |
|---|
| 814 | | //fprintf(stderr, "ACShepA52Decoder::Process32BitSignedInts: Running 5.0\n"); |
|---|
| 815 | | for (int k = 0; k < 256; k++) { |
|---|
| 816 | | output_data[5*k + output_data_offset + 0] = (SInt32)output_samples[k + 256*0]; // left chan |
|---|
| 817 | | output_data[5*k + output_data_offset + 2] = (SInt32)output_samples[k + 256*1]; // center chan |
|---|
| 818 | | output_data[5*k + output_data_offset + 1] = (SInt32)output_samples[k + 256*2]; // right chan |
|---|
| 819 | | output_data[5*k + output_data_offset + 3] = (SInt32)output_samples[k + 256*3]; // left surround chan |
|---|
| 820 | | output_data[5*k + output_data_offset + 4] = (SInt32)output_samples[k + 256*4]; // right surround chan |
|---|
| 821 | | } |
|---|
| 822 | | |
|---|
| 823 | | return 5 * 256; // Number of 'UInt32' we processed |
|---|
| 824 | | } |
|---|
| 825 | | break; |
|---|
| 826 | | |
|---|
| 827 | | // Stereo |
|---|
| 828 | | case A52_STEREO: |
|---|
| 829 | | case A52_DOLBY: |
|---|
| 830 | | //fprintf(stderr, "ACShepA52Decoder::Process32BitSignedInts: Running stereo\n"); |
|---|
| 831 | | |
|---|
| 832 | | for (int k = 0; k < 256; k++) { |
|---|
| 833 | | output_data[2*k + output_data_offset] = (SInt32)output_samples[k]; // left chan |
|---|
| 834 | | output_data[2*k + output_data_offset + 1] = (SInt32)output_samples[k + 256]; // right chan |
|---|
| 835 | | } |
|---|
| 836 | | |
|---|
| 837 | | return 2 * 256; // Number of 'UInt32' we processed |
|---|
| 838 | | break; |
|---|
| 839 | | |
|---|
| 840 | | // Mono |
|---|
| 841 | | case A52_MONO: |
|---|
| 842 | | //fprintf(stderr, "ACShepA52Decoder::Process32BitSignedInts: Running mono\n"); |
|---|
| 843 | | |
|---|
| 844 | | for (int k = 0; k < 256; k++) { |
|---|
| 845 | | output_data[k + output_data_offset] = (SInt32)output_samples[k]; // moon chan |
|---|
| 846 | | } |
|---|
| 847 | | |
|---|
| 848 | | return 256; // Number of 'UInt32' we processed |
|---|
| 849 | | break; |
|---|
| 850 | | |
|---|
| 851 | | default: |
|---|
| 852 | | |
|---|
| 853 | | fprintf(stderr, "ACShepA52Decoder::Process32BitSignedInts: Failed to match output channels\n"); |
|---|
| 854 | | } |
|---|
| 855 | | |
|---|
| 856 | | return 0; |
|---|
| 857 | | } |
|---|
| 858 | | |
|---|
| 859 | | |
|---|
| 860 | | UInt32 ACShepA52Decoder::ProcessFloats(void *output_data_untyped, UInt32 output_data_offset, sample_t *output_samples, int a52_flags) { |
|---|
| 861 | | float *output_data = (float *)output_data_untyped; |
|---|
| 862 | | |
|---|
| 863 | | |
|---|
| 864 | | switch(a52_flags & A52_CHANNEL_MASK) { |
|---|
| 865 | | |
|---|
| 866 | | // 5 Channel |
|---|
| 867 | | case A52_3F2R: |
|---|
| 868 | | |
|---|
| 869 | | // With LFE |
|---|
| 870 | | if (a52_flags & A52_LFE) { |
|---|
| 871 | | //fprintf(stderr, "ACShepA52Decoder::ProcessFloats: Running 5.1\n"); |
|---|
| 872 | | |
|---|
| 873 | | for (int k = 0; k < 256; k++) { |
|---|
| 874 | | output_data[6*k + output_data_offset + 3] = output_samples[k + 256*0]; // LFE chan |
|---|
| 875 | | output_data[6*k + output_data_offset + 0] = output_samples[k + 256*1]; // left chan |
|---|
| 876 | | output_data[6*k + output_data_offset + 2] = output_samples[k + 256*2]; // center chan |
|---|
| 877 | | output_data[6*k + output_data_offset + 1] = output_samples[k + 256*3]; // right chan |
|---|
| 878 | | output_data[6*k + output_data_offset + 4] = output_samples[k + 256*4]; // left surround chan |
|---|
| 879 | | output_data[6*k + output_data_offset + 5] = output_samples[k + 256*5]; // right surround chan |
|---|
| 880 | | } |
|---|
| 881 | | |
|---|
| 882 | | return 6 * 256; // Number of 'float' we processed |
|---|
| 883 | | } else { |
|---|
| 884 | | //fprintf(stderr, "ACShepA52Decoder::ProcessFloats: Running 5.0\n"); |
|---|
| 885 | | for (int k = 0; k < 256; k++) { |
|---|
| 886 | | output_data[5*k + output_data_offset + 0] = output_samples[k + 256*0]; // left chan |
|---|
| 887 | | output_data[5*k + output_data_offset + 2] = output_samples[k + 256*1]; // center chan |
|---|
| 888 | | output_data[5*k + output_data_offset + 1] = output_samples[k + 256*2]; // right chan |
|---|
| 889 | | output_data[5*k + output_data_offset + 3] = output_samples[k + 256*3]; // left surround chan |
|---|
| 890 | | output_data[5*k + output_data_offset + 4] = output_samples[k + 256*4]; // right surround chan |
|---|
| 891 | | } |
|---|
| 892 | | |
|---|
| 893 | | return 5 * 256; // Number of 'UInt32' we processed |
|---|
| 894 | | } |
|---|
| 895 | | |
|---|
| 896 | | break; |
|---|
| 897 | | |
|---|
| 898 | | // Stereo |
|---|
| 899 | | case A52_STEREO: |
|---|
| 900 | | case A52_DOLBY: |
|---|
| 901 | | //fprintf(stderr, "ACShepA52Decoder::ProcessFloats: Running stereo\n"); |
|---|
| 902 | | |
|---|
| 903 | | for (int k = 0; k < 256; k++) { |
|---|
| 904 | | output_data[2*k + output_data_offset] = output_samples[k]; // left chan |
|---|
| 905 | | output_data[2*k + output_data_offset + 1] = output_samples[k + 256]; // right chan |
|---|
| 906 | | } |
|---|
| 907 | | |
|---|
| 908 | | return 2 * 256; // Number of 'float' we processed |
|---|
| 909 | | break; |
|---|
| 910 | | |
|---|
| 911 | | // Mono |
|---|
| 912 | | case A52_MONO: |
|---|
| 913 | | //fprintf(stderr, "ACShepA52Decoder::ProcessFloats: Running mono\n"); |
|---|
| 914 | | |
|---|
| 915 | | for (int k = 0; k < 256; k++) { |
|---|
| 916 | | output_data[k + output_data_offset] = output_samples[k]; // mono chan |
|---|
| 917 | | } |
|---|
| 918 | | |
|---|
| 919 | | return 256; // Number of 'float' we processed |
|---|
| 920 | | break; |
|---|
| 921 | | |
|---|
| 922 | | default: |
|---|
| 923 | | fprintf(stderr, "ACShepA52Decoder::ProcessFloats: Failed to match output channels\n"); |
|---|
| 924 | | } |
|---|
| 925 | | return 0; |
|---|