Changeset 38

Show
Ignore:
Timestamp:
04/04/07 10:37:45 (2 years ago)
Author:
gbooker
Message:

AC3 Passthrough support, if enabled. Needs some proper support from perian and application as well. Works on ATV if you set it up right.

Also, fixed some stupid variable mistakes for prefs.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/A52/ACShepA52Decoder.cpp

    r37 r38  
    5656        kFloatPCMOutFormatFlag = kLinearPCMFormatFlagIsFloat             | kLinearPCMFormatFlagIsPacked; 
    5757#endif 
    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; 
    9058         
    9159        CFPreferencesAppSynchronize(CFSTR("com.cod3r.a52codec")); 
     
    11583        if(stereo != NULL) 
    11684        { 
    117                 CFTypeID type = CFGetTypeID(dynRange); 
     85                CFTypeID type = CFGetTypeID(stereo); 
    11886                if(type == CFStringGetTypeID()) 
    119                         useStereoOverDolby = CFStringGetIntValue((CFStringRef)dynRange); 
     87                        useStereoOverDolby = CFStringGetIntValue((CFStringRef)stereo); 
    12088                else if(type == CFNumberGetTypeID()) 
    121                         CFNumberGetValue((CFNumberRef)dynRange, kCFNumberIntType, &useStereoOverDolby); 
     89                        CFNumberGetValue((CFNumberRef)stereo, kCFNumberIntType, &useStereoOverDolby); 
    12290                else 
    12391                        useStereoOverDolby = 0; 
     
    12795                useStereoOverDolby = 0; 
    12896         
     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                 
    129165        //fprintf(stderr, "ACShepA52Decoder::Constructor: Number of input formats supported: %lu\n", GetNumberSupportedInputFormats()); 
    130166        //fprintf(stderr, "ACShepA52Decoder::Constructor: Number of output formats supported: %lu\n", GetNumberSupportedOutputFormats()); 
     
    476512                // Now ready to do a bit of processing... 
    477513                 
    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                                        } 
    521584                                } else { 
    522                                         output_offset += Process32BitSignedInts(outOutputData, output_offset, output_samples, a52_flags); 
     585                                        output_offset += ProcessFloats(outOutputData, output_offset, output_samples, a52_flags); 
    523586                                } 
    524                         } else { 
    525                                 output_offset += ProcessFloats(outOutputData, output_offset, output_samples, a52_flags); 
    526                         } 
    527                  
     587                         
     588                        } 
    528589                } 
    529590                 
  • trunk/A52/ACShepA52Decoder.h

    r26 r38  
    8282        bool    useStereoOverDolby; 
    8383        double  dynamicRangeCompression; 
     84        bool    passthrough; 
    8485}; 
    8586 
  • trunk/A52Codec.xcodeproj/project.pbxproj

    r36 r38  
    183183                65CB364E066A1FA900A75A43 /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = /System/Library/Frameworks/CoreAudio.framework; sourceTree = "<absolute>"; }; 
    184184                F50815870A2161180092BF70 /* XCAResources.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; path = XCAResources.r; sourceTree = "<group>"; }; 
    185                 F50B7AB50AAB69C600065C78 /* Preferences.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Preferences.app; sourceTree = BUILT_PRODUCTS_DIR; }; 
     185                F50B7AB50AAB69C600065C78 /* A52Preferences.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = A52Preferences.app; sourceTree = BUILT_PRODUCTS_DIR; }; 
    186186                F50B7AB70AAB69C700065C78 /* Preferences-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = "Preferences-Info.plist"; sourceTree = "<group>"; }; 
    187187                F50B7AC40AAB6E3F00065C78 /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = English.lproj/A52CodecPreferences.nib; sourceTree = "<group>"; }; 
     
    366366                                F5BDACAD0A20A00000FF4884 /* A52Codec.component */, 
    367367                                F5525DF70A3BF78A00F36B86 /* AC3MovieImport.component */, 
    368                                 F50B7AB50AAB69C600065C78 /* Preferences.app */, 
     368                                F50B7AB50AAB69C600065C78 /* A52Preferences.app */, 
    369369                        ); 
    370370                        name = Products; 
     
    499499                        name = A52Preferences; 
    500500                        productName = Preferences; 
    501                         productReference = F50B7AB50AAB69C600065C78 /* Preferences.app */; 
     501                        productReference = F50B7AB50AAB69C600065C78 /* A52Preferences.app */; 
    502502                        productType = "com.apple.product-type.application"; 
    503503                };