2017-03-22 16 views
5

का उपयोग कर पीसीएम को एएसी संपीड़ित फ्रेम को डीकोड करने के लिए कैसे करें, मैं अपने आवेदन में एसआईपी कॉल को कार्यान्वित करना चाहता हूं, और पहली समस्या, जिसे मुझे हल करने की आवश्यकता है, एडीटीएस हेडर के साथ संकुचित एएसी प्रारूप से ऑडियो को रैखिक पीसीएम में परिवर्तित कर रहा है।ऑडियो कनवर्टरफिल कॉम्प्लेक्सबफर आईओएस

मेरा इनपुट डेटा विभिन्न फ्रेम नाम के साथ एडीटीएस फ्रेम का एनएसएआरएआरई है। प्रत्येक फ्रेम टाइप एनएसएमयूटेबलडेटा है। प्रत्येक फ्रेम एक ही प्रारूप और नमूना दर का है, केवल अंतर फ्रेम फ्रेम है।

मैंने this issue के लिए इगोर रोटारू द्वारा सुझाए गए नमूना कोड को लागू करने का प्रयास किया, लेकिन यह काम नहीं कर सकता।

अब मेरा कोड इस तरह दिखता है।

- (void)configureAudioConverter { 
    AudioStreamBasicDescription inFormat; 
    memset(&inFormat, 0, sizeof(inFormat)); 
    inputFormat.mBitsPerChannel = 0; 
    inputFormat.mBytesPerFrame = 0; 
    inputFormat.mBytesPerPacket = 0; 
    inputFormat.mChannelsPerFrame = 1; 
    inputFormat.mFormatFlags = kMPEG4Object_AAC_LC; 
    inputFormat.mFormatID = kAudioFormatMPEG4AAC; 
    inputFormat.mFramesPerPacket = 1024; 
    inputFormat.mReserved = 0; 
    inputFormat.mSampleRate = 22050; 

    AudioStreamBasicDescription outputFormat; 
    memset(&outputFormat, 0, sizeof(outputFormat)); 
    outputFormat.mSampleRate  = inputFormat.mSampleRate; 
    outputFormat.mFormatID   = kAudioFormatLinearPCM; 
    outputFormat.mFormatFlags  = kLinearPCMFormatFlagIsSignedInteger; 
    outputFormat.mBytesPerPacket = 2; 
    outputFormat.mFramesPerPacket = 1; 
    outputFormat.mBytesPerFrame = 2; 
    outputFormat.mChannelsPerFrame = 1; 
    outputFormat.mBitsPerChannel = 16; 
    outputFormat.mReserved   = 0; 

    AudioClassDescription *description = [self 
             getAudioClassDescriptionWithType:kAudioFormatMPEG4AAC 
             fromManufacturer:kAppleSoftwareAudioCodecManufacturer]; 

    OSStatus status = AudioConverterNewSpecific(&inputFormat, &outputFormat, 1, description, &_audioConverter); 

    if (status != 0) { 
     printf("setup converter error, status: %i\n", (int)status); 
    } 
} 

उसके बाद मैं कॉलबैक फ़ंक्शन लिखा है:: सबसे पहले, मैं AudioConverter कॉन्फ़िगर

struct MyUserData { 
    UInt32 mChannels; 
    UInt32 mDataSize; 
    const void* mData; 
    AudioStreamPacketDescription mPacket; 
}; 

OSStatus inInputDataProc(AudioConverterRef inAudioConverter, 
         UInt32 *ioNumberDataPackets, 
         AudioBufferList *ioData, 
         AudioStreamPacketDescription **outDataPacketDescription, 
         void *inUserData) 
{ 
    struct MyUserData* userData = (struct MyUserData*)(inUserData); 

    if (!userData->mDataSize) { 
     *ioNumberDataPackets = 0; 
     return kNoMoreDataError; 
    } 

    if (outDataPacketDescription) { 
     userData->mPacket.mStartOffset = 0; 
     userData->mPacket.mVariableFramesInPacket = 0; 
     userData->mPacket.mDataByteSize = userData->mDataSize; 
     *outDataPacketDescription = &userData->mPacket; 
    } 

    ioData->mBuffers[0].mNumberChannels = userData->mChannels; 
    ioData->mBuffers[0].mDataByteSize = userData->mDataSize; 
    ioData->mBuffers[0].mData = (void *)userData->mData; 

    // No more data to provide following this run. 
    userData->mDataSize = 0; 

    return noErr; 
} 

और डिकोडिंग फ्रेम के लिए मेरी समारोह इस तरह दिखता है:

- (void)startDecodingAudio { 
    if (!_converterConfigured){ 
     return; 
    } 

    while (true){ 
     if ([self hasFramesToDecode]){ 
      struct MyUserData userData = {1, (UInt32)_decoderBuffer[_currPosInDecoderBuf].length, _decoderBuffer[_currPosInDecoderBuf].bytes}; 

      uint8_t *buffer = (uint8_t *)malloc(128 * sizeof(short int)); 
      AudioBufferList decBuffer; 
      decBuffer.mNumberBuffers = 1; 
      decBuffer.mBuffers[0].mNumberChannels = 1; 
      decBuffer.mBuffers[0].mDataByteSize = 128 * sizeof(short int); 
      decBuffer.mBuffers[0].mData = buffer; 

      UInt32 numFrames = 128; 

      AudioStreamPacketDescription outPacketDescription; 
      memset(&outPacketDescription, 0, sizeof(AudioStreamPacketDescription)); 
      outPacketDescription.mDataByteSize = 128; 
      outPacketDescription.mStartOffset = 0; 
      outPacketDescription.mVariableFramesInPacket = 0; 

      OSStatus status = AudioConverterFillComplexBuffer(_audioConverter, 
                   inInputDataProc, 
                   &userData, 
                   &numFrames, 
                   &decBuffer, 
                   &outPacketDescription); 

      NSError *error = nil; 

      if (status == kNoMoreDataError) { 
       NSLog(@"%u bytes decoded", (unsigned int)decBuffer.mBuffers[0].mDataByteSize); 
       [_decodedData appendData:[NSData dataWithBytes:decBuffer.mBuffers[0].mData length:decBuffer.mBuffers[0].mDataByteSize]]; 
       _currPosInDecoderBuf += 1; 
      } else { 
       error = [NSError errorWithDomain:NSOSStatusErrorDomain code:status userInfo:nil]; 
      } 
     } else { 
      break; 
     } 
    } 
} 

हर बार , ऑडियो कनवर्टरफिल कॉम्प्लेक्सबफर रिटर्न स्टेटस 1852797029 जो ऐप्पल एपीआई के अनुसार है, kAudioCodecIllegalOperationError। अगर किसी को ऐसे प्रारूपों में परिवर्तित करने में सफलता मिली है, तो कृपया कुछ उदाहरण या सलाह साझा करें।

+0

क्या आपने अपनी समस्या का समाधान किया है? – vladiqtx

+0

@VladislavRudskoy हाँ, नीचे मेरा जवाब देखें। –

उत्तर

4

अंत में, मैंने स्ट्रीमिंगकिट लाइब्रेरी के साथ अपने बाइट्स को डीकोड किया (मूल रिपोजिरी here पाया जा सकता है)।

संबंधित मुद्दे