2013-07-28 60 views
1

我试图播放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

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

+0

谢谢你的回答!我已经尝试将效果单元格式设置为32位浮点(尝试'kAudioFormatFlagsNativeFloatPacked')。得到同样的错误 - 这次初始化图形(设置格式工作)。试图在效果和输出之间插入另一个转换器,以改变为16位样本,得到相同的结果。 –

+0

您是否将连接到效果单元的单位的范围设置为相同的格式(32位浮点数)? – hotpaw2

+0

是的,我做了,现在是这样的:8K样本 - >转换 - > 32位样本 - >效果 - >另一个转换 - > 16位 - >远程io,请参阅修改后的代码。 –