Note that there are some explanatory texts on larger screens.

plurals
  1. POHow do I use an effect audio unit?
    primarykey
    data
    text
    <p>I'm trying to play 8000hz samples and pass them through an effect. <br/>I aim to boost the audio volume (sample code doesn't do it, <i>yet</i>).<br/> I figured I needed an effect audio unit, chained to the remote audio unit.<br/> I also read about the effect unit being very strict with the format it can handle, mainly requiring 44.1khz samples, floating point and 32 bit samples (.<br/> So, I added a convertor unit.<br/> Also, since I figure (not sure though) iOS can't play 32 bit samples (thanks @hotpaw2 !) - I added another conversion back to 16 bits. The problem is, I always get error -10868 while initializing the audio graph.<br/> I get it without the last conversion unit as well.<br/> If I connect the convert unit to the output (no effect unit), everything works fine (8k samples play just fine).<br/> What's going on?</p> <pre><code> /* Must use play &amp; 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:&amp;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(&amp;in_format,0,sizeof(in_format)); memset(&amp;out_format, 0, sizeof(out_format)); memset(&amp;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(&amp;doutput, 0, sizeof(doutput)); memset(&amp;deffect, 0, sizeof(deffect)); memset(&amp;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(&amp;graph)); // Create nodes; SdCheck(AUGraphAddNode(graph, &amp;deffect, &amp;neffect)); SdCheck(AUGraphAddNode(graph, &amp;doutput, &amp;noutput)); SdCheck(AUGraphAddNode(graph, &amp;dconvert, &amp;nconvert)); SdCheck(AUGraphAddNode(graph, &amp;dconvert, &amp;noconvert)); // Open graph SdCheck(AUGraphOpen(graph)); // Get units SdCheck(AUGraphNodeInfo(graph, neffect,NULL, &amp;effect)); SdCheck(AUGraphNodeInfo(graph, noutput,NULL, &amp;output)); SdCheck(AUGraphNodeInfo(graph, nconvert,NULL, &amp;convert)); SdCheck(AUGraphNodeInfo(graph, noconvert,NULL, &amp;oconvert)); // Set formats SdCheck(AudioUnitSetProperty (output, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &amp;out_format, sizeof(out_format))); SdCheck(AudioUnitSetProperty (convert, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &amp;effect_format, sizeof(effect_format))); SdCheck(AudioUnitSetProperty (convert, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 0, &amp;in_format, sizeof(in_format))); SdCheck(AudioUnitSetProperty (effect, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &amp;effect_format, sizeof(effect_format))); SdCheck(AudioUnitSetProperty (effect, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 0, &amp;effect_format, sizeof(effect_format))); SdCheck(AudioUnitSetProperty (oconvert, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &amp;out_format, sizeof(out_format))); SdCheck(AudioUnitSetProperty (oconvert, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 0, &amp;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(&amp;input, 0, sizeof(input)); input.inputProc = SdInputProc; input.inputProcRefCon = (__bridge void*)self; SdCheck(AUGraphSetNodeInputCallback(graph, nconvert, 0, &amp;input)); // Initialize graph /*** The following fails with error -10868 (unsupported format) ***/ SdCheck(AUGraphInitialize(graph)); </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload