AudioUnit请教

发布于 2021-11-29 01:28:36 字数 28160 浏览 853 评论 1

@xikan 你好,想跟你请教个问题:

typedef struct MyAUGraphStruct{

    AUGraph graph;

    AudioUnit remoteIOUnit;

} MyAUGraphStruct;


#define BUFFER_COUNT 15


MyAUGraphStruct myStruct;


AudioBuffer recordedBuffers[BUFFER_COUNT];//Used to save audio data

int         currentBufferPointer;//Pointer to the current buffer

int         callbackCount;


static void CheckError(OSStatus error, const char *operation)

{

    if (error == noErr) return;

    char errorString[20];

    // See if it appears to be a 4-char-code

    *(UInt32 *)(errorString + 1) = CFSwapInt32HostToBig(error);

    if (isprint(errorString[1]) && isprint(errorString[2]) &&

        isprint(errorString[3]) && isprint(errorString[4])) {

        errorString[0] = errorString[5] = ''';

        errorString[6] = '';

    } else

        // No, format it as an integer

        sprintf(errorString, "%d", (int)error);

    fprintf(stderr, "Error: %s (%s)n", operation, errorString);

    

    exit(1);

}


OSStatus InputCallback(void *inRefCon,

                       AudioUnitRenderActionFlags *ioActionFlags,

                       const AudioTimeStamp *inTimeStamp,

                       UInt32 inBusNumber,

                       UInt32 inNumberFrames,

                       AudioBufferList *ioData){

    //TODO: implement this function

    MyAUGraphStruct* myStruct = (MyAUGraphStruct*)inRefCon;

    

//    Get samples from input bus(bus 1)

    CheckError(AudioUnitRender(myStruct->remoteIOUnit,

                               ioActionFlags,

                               inTimeStamp,

                               1,

                               inNumberFrames,

                               ioData),

               "AudioUnitRender failed");

    

    //save audio to ring buffer and load from ring buffer

    AudioBuffer buffer = ioData->mBuffers[0];

    recordedBuffers[currentBufferPointer].mNumberChannels = buffer.mNumberChannels;

    recordedBuffers[currentBufferPointer].mDataByteSize = buffer.mDataByteSize;

    free(recordedBuffers[currentBufferPointer].mData);

    recordedBuffers[currentBufferPointer].mData = malloc(sizeof(SInt16)*buffer.mDataByteSize);

    memcpy(recordedBuffers[currentBufferPointer].mData,

           buffer.mData,

           buffer.mDataByteSize);

    currentBufferPointer = (currentBufferPointer+1)%BUFFER_COUNT;

    

    if (callbackCount>=BUFFER_COUNT) {

        memcpy(buffer.mData,

               recordedBuffers[currentBufferPointer].mData,

               buffer.mDataByteSize);

    }

    NSLog(@"%d",buffer.mDataByteSize);


    NSLog(@"%d",buffer.mData);

    callbackCount++;

    return noErr;

}


@implementation HZAuidoUnit

@synthesize streamFormat;

- (void)initUnit{

    currentBufferPointer = 0;

    callbackCount = 0;

    

    [self setupSession];

    

    [self createAUGraph:&myStruct];

    

    [self setupRemoteIOUnit:&myStruct];

    

    [self startGraph:myStruct.graph];

    

}


-(void)openOrCloseEchoCancellation{

    UInt32 echoCancellation = 1;

    UInt32 size = sizeof(echoCancellation);

    CheckError(AudioUnitGetProperty(myStruct.remoteIOUnit,

                                    kAUVoiceIOProperty_BypassVoiceProcessing,

                                    kAudioUnitScope_Global,

                                    0,

                                    &echoCancellation,

                                    &size),

               "kAUVoiceIOProperty_BypassVoiceProcessing failed");

    

}


-(void)startGraph:(AUGraph)graph{

    CheckError(AUGraphInitialize(graph),

               "AUGraphInitialize failed");

    

    CheckError(AUGraphStart(graph),

               "AUGraphStart failed");

}


-(void)setupRemoteIOUnit:(MyAUGraphStruct*)myStruct{

    //Open input of the bus 1(input mic)

    UInt32 enableFlag = 1;

    CheckError(AudioUnitSetProperty(myStruct->remoteIOUnit,

                                    kAudioOutputUnitProperty_EnableIO,

                                    kAudioUnitScope_Input,

                                    1,

                                    &enableFlag,

                                    sizeof(enableFlag)),

               "Open input of bus 1 failed");

    

//    Open output of bus 0(output speaker)

    CheckError(AudioUnitSetProperty(myStruct->remoteIOUnit,

                                    kAudioOutputUnitProperty_EnableIO,

                                    kAudioUnitScope_Output,

                                    0,

                                    &enableFlag,

                                    sizeof(enableFlag)),

               "Open output of bus 0 failed");

    

    //Set up stream format for input and output

    streamFormat.mFormatID = kAudioFormatLinearPCM;

    streamFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;

    streamFormat.mSampleRate = 8000.00;

    streamFormat.mFramesPerPacket = 1;

    streamFormat.mBytesPerFrame = 2 ;

    streamFormat.mBytesPerPacket = 2;

    streamFormat.mBitsPerChannel = 16;

    streamFormat.mChannelsPerFrame = 1;

    

    

    CheckError(AudioUnitSetProperty(myStruct->remoteIOUnit,

                                    kAudioUnitProperty_StreamFormat,

                                    kAudioUnitScope_Input,

                                    0,

                                    &streamFormat,

                                    sizeof(streamFormat)),

               "kAudioUnitProperty_StreamFormat of bus 0 failed");

    

    CheckError(AudioUnitSetProperty(myStruct->remoteIOUnit,

                                    kAudioUnitProperty_StreamFormat,

                                    kAudioUnitScope_Output,

                                    1,

                                    &streamFormat,

                                    sizeof(streamFormat)),

               "kAudioUnitProperty_StreamFormat of bus 1 failed");

    

    //Set up input callback

    AURenderCallbackStruct input;

    input.inputProc = InputCallback;

    input.inputProcRefCon = myStruct;

    CheckError(AudioUnitSetProperty(myStruct->remoteIOUnit,

                                    kAudioUnitProperty_SetRenderCallback,

                                    kAudioUnitScope_Global,

                                    0,//input mic

                                    &input,

                                    sizeof(input)),

               "kAudioUnitProperty_SetRenderCallback failed");

}


-(void)createAUGraph:(MyAUGraphStruct*)myStruct{

    //Create graph

    CheckError(NewAUGraph(&myStruct->graph),

               "NewAUGraph failed");

    

    //Create nodes and add to the graph

    //Set up a RemoteIO for synchronously playback

    AudioComponentDescription inputcd = {0};

    inputcd.componentType = kAudioUnitType_Output;

    //inputcd.componentSubType = kAudioUnitSubType_RemoteIO;

    //we can access the system's echo cancellation by using kAudioUnitSubType_VoiceProcessingIO subtype

    inputcd.componentSubType = kAudioUnitSubType_VoiceProcessingIO;

    inputcd.componentManufacturer = kAudioUnitManufacturer_Apple;

    inputcd.componentFlags = 0;

    inputcd.componentFlagsMask = 0;

    

    AUNode remoteIONode;

    //Add node to the graph

    CheckError(AUGraphAddNode(myStruct->graph,

                              &inputcd,

                              &remoteIONode),

               "AUGraphAddNode failed");

    

    //Open the graph

    CheckError(AUGraphOpen(myStruct->graph),

               "AUGraphOpen failed");

    

    //Get reference to the node

    CheckError(AUGraphNodeInfo(myStruct->graph,

                               remoteIONode,

                               &inputcd,

                               &myStruct->remoteIOUnit),

               "AUGraphNodeInfo failed");

}


-(void)createRemoteIONodeToGraph:(AUGraph*)graph{

    

}


-(void)setupSession{

    AVAudioSession* session = [AVAudioSession sharedInstance];

    [session setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];

    [session overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker error:nil];

    [session setActive:YES error:nil];

}


本来是44100的采样率 改为8000 报错,请教

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

灵芸 2021-11-29 08:34:09

感激不尽

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文