返回

苹果系统如何将Mic采集的PCM转为AAC?

IOS

iOS系统Mic采集PCM转AAC技术解析

我们提供两种方法来完成PCM到AAC的转换。

AudioQueue方法

AudioQueue是一种高效的音频处理库,可处理实时音频数据。您可以使用AudioQueue来获取PCM数据并将其转换为AAC数据。

  1. 初始化AudioQueue

    AudioQueueRef queue;
    AudioQueueNewInput(&format, MyAQInputCallback, (__bridge void *)self, NULL, kCFRunLoopCommonModes, 0, &queue);
    
  2. 启动AudioQueue

    AudioQueueStart(queue, NULL);
    
  3. AudioQueue回调函数

    void MyAQInputCallback(
        void *inUserData,
        AudioQueueRef inAQ,
        AudioQueueBufferRef inBuffer,
        const AudioTimeStamp *inStartTime,
        UInt32 inNumPackets,
        const AudioStreamPacketDescription *inPacketDesc
    ) {
        // 处理PCM数据并将其转换为AAC数据
        // 将AAC数据发送到网络或存储到文件中
    }
    

AudioUnit方法

AudioUnit是一种更灵活的音频处理库,可用于创建自定义音频处理链。您可以使用AudioUnit来创建PCM到AAC转换器。

  1. 创建AudioUnit

    AudioComponentDescription desc;
    desc.componentType = kAudioUnitType_Converter;
    desc.componentSubType = kAudioUnitSubType_AACEncoder;
    desc.componentManufacturer = kAudioUnitManufacturer_Apple;
    AudioComponent comp = AudioComponentFindNext(NULL, &desc);
    AudioUnit au;
    AudioComponentInstanceNew(comp, &au);
    
  2. 配置AudioUnit

    AudioStreamBasicDescription format;
    format.mSampleRate = 44100;
    format.mFormatID = kAudioFormatLinearPCM;
    format.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked;
    format.mBytesPerPacket = 2;
    format.mFramesPerPacket = 1;
    format.mBytesPerFrame = 2;
    format.mChannelsPerFrame = 1;
    format.mBitsPerChannel = 16;
    AudioUnitSetProperty(au, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &format, sizeof(format));
    format.mFormatID = kAudioFormatMPEG4AAC;
    AudioUnitSetProperty(au, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 0, &format, sizeof(format));
    
  3. 初始化AudioUnit

    AudioUnitInitialize(au);
    
  4. 处理PCM数据并将其转换为AAC数据

    UInt32 numPackets = inBuffer->mAudioDataByteSize / format.mBytesPerPacket;
    AudioBufferList bufList;
    bufList.mNumberBuffers = 1;
    bufList.mBuffers[0].mNumberChannels = 1;
    bufList.mBuffers[0].mDataByteSize = inBuffer->mAudioDataByteSize;
    bufList.mBuffers[0].mData = inBuffer->mAudioData;
    AudioUnitRender(au, &bufList, &numPackets);
    
  5. 释放AudioUnit

    AudioUnitUninitialize(au);
    AudioComponentInstanceDispose(au);