如何使用效果音频装置?

时间:2013-07-28 15:45:12

标签: ios core-audio audiounit

我正在尝试播放8000hz样本并通过效果传递它们。
我的目标是提高音量(示例代码不会这样做,) 我想我需要一个效果音频单元,链接到远程音频单元 我还读到效果单元对它可以处理的格式非常严格,主要需要44.1khz样本,浮点和32位样本(。
所以,我添加了一个转换器单元 此外,因为我想(不确定)iOS无法播放32位样本(感谢@ hotpaw2!) - 我添加了另一个转换回16位。 问题是,我在初始化音频图时总是得到错误-10868 我没有最后一个转换单元也能得到它 如果我将转换单元连接到输出(无效果单元),一切正常(8k样本播放就好了) 发生了什么事?

    /* Must use play & record category, for reasons beyond the scope of this question */
    [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionDuckOthers | AVAudioSessionCategoryOptionDefaultToSpeaker | AVAudioSessionCategoryOptionAllowBluetooth error:nil];
    NSError* err = nil;
    if (![[AVAudioSession sharedInstance] setPreferredSampleRate:44100 error:&err]){
        NSLog(@"%@",err);
    }
    AudioUnit effect,convert,output,oconvert;
    AUNode neffect,nconvert,noutput,noconvert;
    AUGraph graph;
    AudioComponentDescription deffect,dconvert,doutput;
    AudioStreamBasicDescription in_format,out_format,effect_format;
    // Formats
    memset(&in_format,0,sizeof(in_format));
    memset(&out_format, 0, sizeof(out_format));
    memset(&effect_format, 0, sizeof(effect_format));
    in_format.mSampleRate = 8000;
    in_format.mChannelsPerFrame = 1;
    in_format.mFormatID = kAudioFormatLinearPCM;
    in_format.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked;
    in_format.mBitsPerChannel = 16;
    in_format.mFramesPerPacket = 1;
    in_format.mBytesPerFrame = in_format.mChannelsPerFrame * (in_format.mBitsPerChannel / 8);
    in_format.mBytesPerPacket = in_format.mBytesPerFrame * in_format.mFramesPerPacket;
    out_format.mSampleRate = 44100;
    out_format.mChannelsPerFrame = 1;
    out_format.mFormatID = kAudioFormatLinearPCM;
    out_format.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked;
    out_format.mBitsPerChannel = 16;
    out_format.mFramesPerPacket = 1;
    out_format.mBytesPerFrame = out_format.mChannelsPerFrame * (out_format.mBitsPerChannel / 8);
    out_format.mBytesPerPacket = out_format.mBytesPerFrame * out_format.mFramesPerPacket;
    effect_format.mSampleRate = 44100;
    effect_format.mChannelsPerFrame = 1;
    effect_format.mFormatID = kAudioFormatLinearPCM;
    effect_format.mFormatFlags = kAudioFormatFlagsNativeFloatPacked;
    effect_format.mBitsPerChannel = 32;
    effect_format.mFramesPerPacket = 1;
    effect_format.mBytesPerFrame = effect_format.mChannelsPerFrame * (effect_format.mBitsPerChannel / 8);
    effect_format.mBytesPerPacket = effect_format.mBytesPerFrame * effect_format.mFramesPerPacket;

    // Descriptions
    memset(&doutput, 0, sizeof(doutput));
    memset(&deffect, 0, sizeof(deffect));
    memset(&dconvert, 0, sizeof(dconvert));
    doutput.componentType = kAudioUnitType_Output;
    doutput.componentSubType = kAudioUnitSubType_RemoteIO;
    doutput.componentManufacturer = deffect.componentManufacturer = dconvert.componentManufacturer = kAudioUnitManufacturer_Apple;
    dconvert.componentType = kAudioUnitType_FormatConverter;
    dconvert.componentSubType = kAudioUnitSubType_AUConverter;
    deffect.componentType = kAudioUnitType_Effect;
    deffect.componentSubType = kAudioUnitSubType_DynamicsProcessor;
    // Create graph
    SdCheck(NewAUGraph(&graph));

    // Create nodes;
    SdCheck(AUGraphAddNode(graph, &deffect, &neffect));
    SdCheck(AUGraphAddNode(graph, &doutput, &noutput));
    SdCheck(AUGraphAddNode(graph, &dconvert, &nconvert));
    SdCheck(AUGraphAddNode(graph, &dconvert, &noconvert));
    // Open graph
    SdCheck(AUGraphOpen(graph));
    // Get units
    SdCheck(AUGraphNodeInfo(graph, neffect,NULL, &effect));
    SdCheck(AUGraphNodeInfo(graph, noutput,NULL, &output));
    SdCheck(AUGraphNodeInfo(graph, nconvert,NULL, &convert));
    SdCheck(AUGraphNodeInfo(graph, noconvert,NULL, &oconvert));
    // Set formats
    SdCheck(AudioUnitSetProperty (output,
                                  kAudioUnitProperty_StreamFormat,
                                  kAudioUnitScope_Input,
                                  0,
                                  &out_format,
                                  sizeof(out_format)));
    SdCheck(AudioUnitSetProperty (convert,
                                  kAudioUnitProperty_StreamFormat,
                                  kAudioUnitScope_Input,
                                  0,
                                  &effect_format,
                                  sizeof(effect_format)));
    SdCheck(AudioUnitSetProperty (convert,
                                  kAudioUnitProperty_StreamFormat,
                                  kAudioUnitScope_Output,
                                  0,
                                  &in_format,
                                  sizeof(in_format)));
    SdCheck(AudioUnitSetProperty (effect,
                                  kAudioUnitProperty_StreamFormat,
                                  kAudioUnitScope_Input,
                                  0,
                                  &effect_format,
                                  sizeof(effect_format)));
    SdCheck(AudioUnitSetProperty (effect,
                                  kAudioUnitProperty_StreamFormat,
                                  kAudioUnitScope_Output,
                                  0,
                                  &effect_format,
                                  sizeof(effect_format)));
    SdCheck(AudioUnitSetProperty (oconvert,
                                  kAudioUnitProperty_StreamFormat,
                                  kAudioUnitScope_Input,
                                  0,
                                  &out_format,
                                  sizeof(out_format)));
    SdCheck(AudioUnitSetProperty (oconvert,
                                  kAudioUnitProperty_StreamFormat,
                                  kAudioUnitScope_Output,
                                  0,
                                  &effect_format,
                                  sizeof(effect_format)));

    // Connect nodes
    SdCheck(AUGraphConnectNodeInput(graph, nconvert, 0, neffect, 0));
    SdCheck(AUGraphConnectNodeInput(graph, neffect, 0, noconvert, 0));
    SdCheck(AUGraphConnectNodeInput(graph, noconvert, 0, noutput, 0));
    // Set render callback
    AURenderCallbackStruct input;
    memset(&input, 0, sizeof(input));
    input.inputProc = SdInputProc;
    input.inputProcRefCon = (__bridge void*)self;
    SdCheck(AUGraphSetNodeInputCallback(graph, nconvert, 0, &input));
    // Initialize graph
    /*** The following fails with error -10868 (unsupported format) ***/
    SdCheck(AUGraphInitialize(graph));

1 个答案:

答案 0 :(得分:1)

iOS上的大多数效果音频单元要求在其输入和输出连接上使用32位浮点格式。您的示例代码尝试使用16位整数I / O配置效果单元,这将无效。