AudioUnit的播放音频文件

本文详细介绍了如何使用AudioUnit播放PCM和MP3音频文件。对于PCM文件,需初始化AudioUnit并设置PCM流描述及回调接口。播放MP3则需额外将MP3转换为LPCM,涉及初始化、设置转换对象及在rendercallback中完成转换。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这一段研究了一下如果用 AudioUnit 播放音频文件。其中播放mp3和播放pcm是不一样的。下面分别介绍一下,当做总结

1. 播放 PCM文件

1)初始化
AudioUnit的初始化比较啰嗦,而且方法比较多。这里采用一种比较简单的。

  AudioComponentDescription outputUinitDesc; //定义AudioUnit描述,下面是设置 unit 的类型。
    memset(&outputUinitDesc, 0, sizeof(AudioComponentDescription));
    outputUinitDesc.componentType = kAudioUnitType_Output;//输出类型
    outputUinitDesc.componentSubType = kAudioUnitSubType_RemoteIO;
    outputUinitDesc.componentManufacturer = kAudioUnitManufacturer_Apple;
    outputUinitDesc.componentFlags = 0;
    outputUinitDesc.componentFlagsMask = 0;
    AudioComponent outComponent = AudioComponentFindNext(NULL, &outputUinitDesc);
    OSStatus status = AudioComponentInstanceNew(outComponent, &_outAudioUinit);  

接下来要设置一下AudioUnit的属性,都是通过AudioUnitSetProperty这个接口来设置

  AudioStreamBasicDescription pcmStreamDesc = PCMStreamDescription();
    AudioUnitSetProperty(_outAudioUinit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &pcmStreamDesc, sizeof(pcmStreamDesc));  

这段代码是用来设置 pcm 文件的格式,包括采样率,位深等等。

接着设置回调接口,在这个接口中用来把解析来的数据填入到相应的数据结构中,为 AudioUnit 来播放

AURenderCallbackStruct callBackStruct;
    callBackStruct.inputProc = BXAURenderCallback;//回调函数
    callBackStruct.inputProcRefCon = (__bridge void * _Nullable)(self);
    AudioUnitSetProperty(_outAudioUinit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, 0, &callBackStruct, sizeof(AURenderCallbackStruct));//回调函数和 AudioUnit 的关联

回调函数定义如下

OSStatus  BXAURenderCallback(void *inRefCon,AudioUnitRenderActionFlags *    ioActionFlags,const AudioTimeStamp *inTimeStamp,UInt32    inBusNumber,UInt32 inNumberFrames, AudioBufferList * __nullable ioData)

初始化 AudioUnit

 OSStatus result = AudioUnitInitialize(_outAudioUinit);
    NSLog(@"result %d", result);

貌似不写这个函数也行

开始播放

 OSStatus status = AudioOutputUnitStart(_outAudioUinit);
        assert(status == noErr);

2.播放mp3

播放 MP3比播放pcm多了个步骤就是要把mp3转换成LPCM,AudioUnit才能播放。

首先初始化的步骤都一样,设置了播放的回调函数以后,还要设置一下converter使用的 bufferList

AudioBufferList *renderBufferList;
 UInt32 bufferSize = 4096*4;
    renderBufferSize = bufferSize;
    renderBufferList = (AudioBufferList*)calloc(1, sizeof(UInt32)+sizeof(AudioBuffer));
    renderBufferList->mNumberBuffers = 1;
    renderBufferList->mBuffers[0].mData = calloc(1, bufferSize);
    renderBufferList->mBuffers[0].mDataByteSize = bufferSize;
    renderBufferList->mBuffers[0].mNumberChannels = 2;

调用接口设置转换对象和音频的格式

extern OSStatus
AudioConverterNew(      const AudioStreamBasicDescription * inSourceFormat,//被转换的音频格式
                        const AudioStreamBasicDescription * inDestinationFormat,//转换后的音频格式
                        AudioConverterRef __nullable * __nonnull outAudioConverter);

然后在output的render callback中,使用Converter 把mp3的数据转换成LPCM的数据

extern OSStatus
AudioConverterFillComplexBuffer(    AudioConverterRef                   inAudioConverter,//AudioConverter的指针
                                    AudioConverterComplexInputDataProc  inInputDataProc,//提供输入数据的callback的回调函数,从这个回调函数中获得数据,并填满自定义的AudioBufferList
                                    void * __nullable                   inInputDataProcUserData,//自定义的类
                                    UInt32 *                            ioOutputDataPacketSize,//如果为输入参数,则是定义的formate中数据的大小。输出参数,转换后的数据的大小
                                    AudioBufferList *                   outOutputData,//转换后的数据
                                    AudioStreamPacketDescription * __nullable outPacketDescription);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值