audio unit pcm 录制/混音
程序员文章站
2022-07-14 08:00:18
...
OI UIint 实现录制播放
1.描述音频元件(kAudioUnitType_Output/kAudioUnitSubType_RemoteIO /kAudioUnitManufacturerApple)。
2.使用 AudioComponentFindNext(NULL, &descriptionOfAudioComponent) 获得 AudioComponent。AudioComponent有点像生产 Audio Unit 的工厂。
3.使用 AudioComponentInstanceNew(ourComponent, &audioUnit) 获得 Audio Unit 实例。
4.使用 AudioUnitSetProperty函数为录制和回放开启IO。
5.使用 AudioStreamBasicDescription 结构体描述音频格式,并使用AudioUnitSetProperty进行设置。
6.使用 AudioUnitSetProperty 设置音频录制与放播的回调函数。
7.分配缓冲区。
8.初始化 Audio Unit。
9.启动 Audio Unit。
//第一步 创建unit 描述
AudioComponentDescription outputDescription = {0};
outputDescription.componentType = kAudioUnitType_Output;
outputDescription.componentSubType = kAudioUnitSubType_RemoteIO;
outputDescription.componentManufacturer = kAudioUnitManufacturer_Apple;
outputDescription.componentFlags = 0;
outputDescription.componentFlagsMask = 0;
//第二步 用AudioComponentFindNext 获得 AudioComponent
AudioComponent comp = AudioComponentFindNext(NULL, &outputDescription);
//第三步 使用 AudioComponentInstanceNew(ourComponent, &audioUnit) 获得 Audio Unit 实例。
status = AudioComponentInstanceNew(comp, &audioUnit);
//第四步 使用 AudioUnitSetProperty函数为录制和回放开启IO。(设置uint 为 IOUnit)
//4.1 设置unit element 1 (输入元素) kInputBus = 1
UInt32 flag = 1;
status = AudioUnitSetProperty(audioUnit,
kAudioOutputUnitProperty_EnableIO,
kAudioUnitScope_Input,
kInputBus,
&flag,
sizeof(flag));
checkStatus(status);
//4.2 设置unit elementt 0(输出元素) kOutputBus = 0
UInt32 flag2 = 0;// 1 是开启 0是关闭
status = AudioUnitSetProperty(audioUnit,
kAudioOutputUnitProperty_EnableIO,
kAudioUnitScope_Output,
kOutputBus,
&flag2,
sizeof(flag2));
checkStatus(status);
//第5步 使用 AudioStreamBasicDescription 结构体描述音频格式,并使用AudioUnitSetProperty进行设置。
AudioStreamBasicDescription audioFormat;
audioFormat.mSampleRate = 44100.00; //每秒钟采样的次数
audioFormat.mFormatID = kAudioFormatLinearPCM;
audioFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
audioFormat.mFramesPerPacket = 1;//每个包有多少帧
audioFormat.mChannelsPerFrame = 1;//单声道
audioFormat.mBitsPerChannel = 16;//mBitsPerChannel是数据大小,即采样位深,
audioFormat.mBytesPerPacket = 2;//每一包有多少字节
audioFormat.mBytesPerFrame = 2;//每一帧有多少字节
//采样率SampleRate: 每秒钟采样的次数
//帧frame:每一次采样的数据对应一帧
//声道数mChannelsPerFrame:人的两个耳朵对统一音源的感受不同带来距离定位,多声道也是为了立体感,每个声道有单独的采样数据,所以多一个声道就多一批的数据。
//从上至下是一个包含关系:每秒有SampleRate次采样, 44100
//每次采样一个frame, 1
//每个frame有mChannelsPerFrame个样本, 1
//每个样本有mBitsPerChannel这么多数据 16
//5.1 给uint 设置采样的数据格式
status = AudioUnitSetProperty(audioUnit,
kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Output,
kInputBus,
&audioFormat,
sizeof(audioFormat));
checkStatus(status);
status = AudioUnitSetProperty(audioUnit,
kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Input,
kOutputBus,
&audioFormat,
sizeof(audioFormat));
checkStatus(status);
//第6步 设置Unit 的callback 函数
// 设置声音采集后的回调调函数。当microphone(麦克风)采集到数据时就是调用回调函数传入数据。
AURenderCallbackStruct callbackStruct;
callbackStruct.inputProc = recordingCallback;
callbackStruct.inputProcRefCon = (__bridge void * _Nullable)(self);
status = AudioUnitSetProperty(audioUnit,
kAudioOutputUnitProperty_SetInputCallback,
kAudioUnitScope_Global,
kInputBus,//1
&callbackStruct,
sizeof(callbackStruct));
checkStatus(status);
// 设置声音输出回调函数。当speaker(扬声器)需要数据时就会调用回调函数去获取数据。它是 "拉" 数据的概念。
callbackStruct.inputProc = playbackCallback;
callbackStruct.inputProcRefCon = (__bridge void * _Nullable)(self);
status = AudioUnitSetProperty(audioUnit,
kAudioUnitProperty_SetRenderCallback,
kAudioUnitScope_Global,
kOutputBus,//0
&callbackStruct,
sizeof(callbackStruct));
checkStatus(status);
混音部分
上一篇: c
下一篇: htmlunit模拟sso登陆
推荐阅读