audio unit pcm 錄製

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);

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章