IOS Audio Unit에서 PCM 데이터 재생

3489 단어

예제 코드: XBVoiceTool


단계:


1. AVAudioSession 설정 2.오디오 유닛 초기화 3.출력 흐름 형식 설정 4.콜백 설정 5.콜백에서 데이터 제공
AVAudioSession 설정
    // session
    NSError *error = nil;
    AVAudioSession* session = [AVAudioSession sharedInstance];
    [session setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker error:&error];
    [session setActive:YES error:nil];

audioUnit 초기화
    // audioUnit
    AudioComponentDescription outputDesc;
    outputDesc.componentType = kAudioUnitType_Output;
    outputDesc.componentSubType = kAudioUnitSubType_VoiceProcessingIO;
    outputDesc.componentManufacturer = kAudioUnitManufacturer_Apple;
    outputDesc.componentFlags = 0;
    outputDesc.componentFlagsMask = 0;
    AudioComponent outputComponent = AudioComponentFindNext(NULL, &outputDesc);
    AudioComponentInstanceNew(outputComponent, &audioUnit);

출력 흐름 형식 설정
    // 
    int mFramesPerPacket = 1;
    int mBytesPerFrame = channel * bit / 8;
    
    AudioStreamBasicDescription streamDesc;
    streamDesc.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsNonInterleaved;
    streamDesc.mFormatID = kAudioFormatLinearPCM;
    streamDesc.mSampleRate = rate;
    streamDesc.mFramesPerPacket = mFramesPerPacket;
    streamDesc.mChannelsPerFrame = channel;
    streamDesc.mBitsPerChannel = bit;
    streamDesc.mBytesPerFrame = mBytesPerFrame;
    streamDesc.mBytesPerPacket = mBytesPerFrame * mFramesPerPacket;
    
    OSStatus status = AudioUnitSetProperty(audioUnit,
                                           kAudioUnitProperty_StreamFormat,
                                           kAudioUnitScope_Input,
                                           kOutputBus,
                                           &streamDesc,
                                           sizeof(streamDesc));
    CheckError(status, "SetProperty StreamFormat failure");

콜백 설정
    // 
    AURenderCallbackStruct outputCallBackStruct;
    outputCallBackStruct.inputProc = outputCallBackFun;
    outputCallBackStruct.inputProcRefCon = (__bridge void * _Nullable)(self);
    status = AudioUnitSetProperty(audioUnit,
                                  kAudioUnitProperty_SetRenderCallback,
                                  kAudioUnitScope_Input,
                                  kOutputBus,
                                  &outputCallBackStruct,
                                  sizeof(outputCallBackStruct));
    CheckError(status, "SetProperty EnableIO failure");

콜백에서 데이터 제공
여기 플레이어에 설치된bl_input 리셋에서 데이터 제공
static OSStatus outputCallBackFun(    void *                            inRefCon,
                    AudioUnitRenderActionFlags *    ioActionFlags,
                    const AudioTimeStamp *            inTimeStamp,
                    UInt32                            inBusNumber,
                    UInt32                            inNumberFrames,
                    AudioBufferList * __nullable    ioData)
{
    memset(ioData->mBuffers[0].mData, 0, ioData->mBuffers[0].mDataByteSize);
//    memset(ioData->mBuffers[1].mData, 0, ioData->mBuffers[1].mDataByteSize);
    
    XBAudioUnitPlayer *player = (__bridge XBAudioUnitPlayer *)(inRefCon);
    if (player.bl_input)
    {
        player.bl_input(ioData);
    }
    return noErr;
}

좋은 웹페이지 즐겨찾기