ios AudioUnit 播放 pcm 数据

来源:互联网 发布:淘宝防排查软件 编辑:程序博客网 时间:2024/05/22 15:43

ios AudioUnit 播放 pcm 数据

由于公司要做音频播放,配合ffmpeg,把音乐解码承pcm裸数据,然后通过ios AudioUnit播放。

1,如下所示结构图



需求不需要录制这块,但是网上普遍都是录制跟播放再一起的,根据相关文档总结一下代码

2, AudioUnit 初始化 AudioSession

- (void)initAudioSession {    NSError *error;    AVAudioSession *audioSession = [AVAudioSession sharedInstance];        [audioSession setCategory:AVAudioSessionCategoryPlayback error:&error];    [audioSession setPreferredSampleRate:44100 error:&error];    [audioSession setPreferredInputNumberOfChannels:1 error:&error];    [audioSession setPreferredIOBufferDuration:0.022 error:&error];}

3,  AudioUnit 初始化buf

- (void)initBuffer {    UInt32 flag = 0;    AudioUnitSetProperty(audioUnit,                         kAudioUnitProperty_ShouldAllocateBuffer,                         kAudioUnitScope_Output,                         INPUT_BUS,                         &flag,                         sizeof(flag));}

4,AudioUnit 初始化组件

- (void)initAudioComponent {    AudioComponentDescription audioDesc;    audioDesc.componentType = kAudioUnitType_Output;    audioDesc.componentSubType = kAudioUnitSubType_RemoteIO;    audioDesc.componentManufacturer = kAudioUnitManufacturer_Apple;    audioDesc.componentFlags = 0;    audioDesc.componentFlagsMask = 0;        AudioComponent inputComponent = AudioComponentFindNext(NULL, &audioDesc);    AudioComponentInstanceNew(inputComponent, &audioUnit);    UInt32 flag = 1;    AudioUnitSetProperty(audioUnit,                             kAudioOutputUnitProperty_EnableIO,                             kAudioUnitScope_Output,                             OUTPUT_BUS,                             &flag,                             sizeof(flag));}

5, AudioUnit 格式信息

- (void)initFormat {    int channel = 1;    AudioStreamBasicDescription audioFormat;    audioFormat.mSampleRate = 44100;    audioFormat.mFormatID = kAudioFormatLinearPCM;    audioFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;    audioFormat.mFramesPerPacket = 1;    audioFormat.mChannelsPerFrame = 1 << channel;    audioFormat.mBitsPerChannel = 16;    audioFormat.mBytesPerPacket = 2 <<  channel;    audioFormat.mBytesPerFrame = 2 << channel;    AudioUnitSetProperty(audioUnit,                         kAudioUnitProperty_StreamFormat,                         kAudioUnitScope_Input,                         OUTPUT_BUS,                         &audioFormat,                         sizeof(audioFormat));}

6,AudioUnit 注册回到函数

- (void)initFormat {    int channel = 1;    AudioStreamBasicDescription audioFormat;    audioFormat.mSampleRate = 44100;    audioFormat.mFormatID = kAudioFormatLinearPCM;    audioFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;    audioFormat.mFramesPerPacket = 1;    audioFormat.mChannelsPerFrame = 1 << channel;    audioFormat.mBitsPerChannel = 16;    audioFormat.mBytesPerPacket = 2 <<  channel;    audioFormat.mBytesPerFrame = 2 << channel;    AudioUnitSetProperty(audioUnit,                         kAudioUnitProperty_StreamFormat,                         kAudioUnitScope_Input,                         OUTPUT_BUS,                         &audioFormat,                         sizeof(audioFormat));}

7, 定义回调函数

static OSStatus PlayCallback(void *inRefCon,                            AudioUnitRenderActionFlags *ioActionFlags,                            const AudioTimeStamp *inTimeStamp,                            UInt32 inBusNumber,                            UInt32 inNumberFrames,                            AudioBufferList *ioData) {    memset(ioData->mBuffers[0].mData, 0, ioData->mBuffers[0].mDataByteSize);    //add 增加回调把数据更改 by chenglong     AudioUnitRender(audioUnit, ioActionFlags, inTimeStamp, 1, inNumberFrames, ioData);        return noErr;}

8,开启播放

- (void)startPlayer {    AudioOutputUnitStart(audioUnit);    NSLog(@"Start");}

9,结束播放

- (void)stopPlayer {    AudioOutputUnitStop(audioUnit);    NSLog(@"Stop");}


原创粉丝点击