Post

Replies

Boosts

Views

Activity

Change Mic output format in AVAudioEngine
I need to get the microphone output in a certain format that isn't equal to the hw format. To do this, I'm creating a AVAudioMixerNode which will have that format as it's output. However, I never receive any buffers when installing the tap on the mixer node. I thought the inputNode would flow upstream? Am I doing something wrong? Note that I'm not using AudioUnits or AudioQueues because I need to do some frequency filtering on the actual audio stream and thought this was the easiest way to do it.Here's the code:mixerNode = [[AVAudioMixerNode alloc]init]; //Attach node [theEngine attachNode:mixerNode]; //Then connect inputNode (mic) to mixer node [theEngine connect:theEngine.inputNode to:mixerNode format:[theEngine.inputNode outputFormatForBus:0]]; [theEngine startAndReturnError:&theError]; //Now set up the real audio format i want AudioStreamBasicDescription audioFormat; audioFormat.mSampleRate = 8000; audioFormat.mChannelsPerFrame = numberOfChannels; audioFormat.mFormatID = kAudioFormatLinearPCM; audioFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger; audioFormat.mBitsPerChannel = 16; audioFormat.mBytesPerPacket = audioFormat.mBytesPerFrame = (audioFormat.mBitsPerChannel / 8) * audioFormat.mChannelsPerFrame; audioFormat.mFramesPerPacket = 1; //Now install the tap on the mixer so we get the correct format [mixerNode installTapOnBus:0 bufferSize:4096 format:[[AVAudioFormat alloc]initWithStreamDescription:&audioFormat] block:^(AVAudioPCMBuffer * _Nonnull buffer, AVAudioTime * _Nonnull when) { NSLog(@"got buff"); }];
2
0
1.5k
Dec ’15
AudioUnit conversion/effects with RenderCallback
I am trying to use AudioUnits to take the Mic input, convert it to a different sample rate, and filter the any frequencies above 4000 hz. To do this, I try to have the following connection:RemoteIO -> Convert to Effects formats -> Filter frequencies using kAudioUnitSubType_LowPassFilter -> Convert to final formatI will then take the output and send it as a network stream over RTP. Because of this, I want to use the RenderCallback. My confusion is what do I set the callback on and what do I call AudioUnitRender on? From what I can tell, I have to set the callback on the RemoteIO unit. But then, do I call AudioUnitRender on that RemoteIO unit or do I call it on one of the other units? When I call it on other units, I get errors. When I call it on the RemoteIO unit, I do get audio but it's not clear to me if anything is getting filtered or not.Here is my code://This is the component for the Mic input AudioComponentDescription desc; desc.componentType = kAudioUnitType_Output; desc.componentSubType = kAudioUnitSubType_RemoteIO; desc.componentManufacturer = kAudioUnitManufacturer_Apple; desc.componentFlags = 0; desc.componentFlagsMask = 0; AudioComponent inputComponent = AudioComponentFindNext(NULL, &desc); CheckError(AudioComponentInstanceNew(inputComponent, &theAudioUnit), "Instance AU"); UInt32 flag = 1; CheckError(AudioUnitSetProperty(theAudioUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, 1, &flag, 1), "EnableIO"); //This is the final audio format I will use AudioStreamBasicDescription audioFormat; audioFormat.mSampleRate = 8000; //Need a sample rate of 8000 audioFormat.mChannelsPerFrame = numberOfChannels; audioFormat.mFormatID = kAudioFormatLinearPCM; audioFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger; audioFormat.mBitsPerChannel = 16; audioFormat.mBytesPerPacket = audioFormat.mBytesPerFrame = (audioFormat.mBitsPerChannel / 8) * audioFormat.mChannelsPerFrame; audioFormat.mFramesPerPacket = 1; //Here is the effect filter for frequencies above 4000 AudioComponentDescription lowPass; lowPass.componentType = kAudioUnitType_Effect; lowPass.componentSubType = kAudioUnitSubType_LowPassFilter; lowPass.componentManufacturer = kAudioUnitManufacturer_Apple; lowPass.componentFlags = 0; lowPass.componentFlagsMask = 0; //This is the converter from Mic input to effect format AudioComponentDescription converter; converter.componentType = kAudioUnitType_FormatConverter; converter.componentSubType = kAudioUnitSubType_AUConverter; converter.componentManufacturer = kAudioUnitManufacturer_Apple; converter.componentFlags = 0; converter.componentFlagsMask = 0; AudioComponent converterComponent = AudioComponentFindNext(nil, &converter); CheckError(AudioComponentInstanceNew(converterComponent, &converterUnit), "Converter inst"); AudioComponent effectComponent = AudioComponentFindNext(nil, &lowPass); CheckError(AudioComponentInstanceNew(effectComponent, &lowPassUnit), "Effect Inst"); //Here is the audio format from the Mic AudioStreamBasicDescription theFormat; memset (&theFormat, 0, sizeof (theFormat)); UInt32 sizeofDesc = sizeof(AudioStreamBasicDescription); CheckError(AudioUnitGetProperty(theAudioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &theFormat, &sizeofDesc), "Get IO Format"); //Now I set it as the input for the converter CheckError(AudioUnitSetProperty(converterUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &theFormat, sizeof(AudioStreamBasicDescription)), "Set Converter In fomrat"); //Here is the audio format from the Effect AudioStreamBasicDescription effectFormat; memset(&effectFormat, 0, sizeof(effectFormat)); CheckError(AudioUnitGetProperty(lowPassUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &effectFormat,&sizeofDesc), "Get Lowpass Format"); //Now i set that as the output for the converter CheckError(AudioUnitSetProperty(converterUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 0, &effectFormat, sizeof(AudioStreamBasicDescription)), "Set cConverter out format"); AudioUnitConnection connection; connection.sourceAudioUnit = theAudioUnit; connection.sourceOutputNumber = 1; connection.destInputNumber = 0; //Here I connect the Mic input to the converter CheckError(AudioUnitSetProperty(converterUnit, kAudioUnitProperty_MakeConnection, kAudioUnitScope_Input, 0, &connection, sizeof(AudioUnitConnection)), "Make Conn audio to convert"); AudioUnitConnection lowPassConnection; lowPassConnection.sourceAudioUnit = converterUnit; lowPassConnection.sourceOutputNumber = 0; lowPassConnection.destInputNumber = 0; //Here I connect the converter to the Effect filter CheckError(AudioUnitSetProperty(lowPassUnit, kAudioUnitProperty_MakeConnection, kAudioUnitScope_Input, 0, &lowPassConnection, sizeof(AudioUnitConnection)), "Make Conn conv to low pass"); //Here I set the Frequency cutoff Float32 lowPassFreq = 3999; CheckError(AudioUnitSetParameter(lowPassUnit, kLowPassParam_CutoffFrequency, kAudioUnitScope_Global, 0, lowPassFreq, sizeof(Float32)), "Set Low Pass freq"); //Here will be the converter from the Filter to the final output format I need AudioComponentDescription outConverter; outConverter.componentType = kAudioUnitType_FormatConverter; outConverter.componentSubType = kAudioUnitSubType_AUConverter; outConverter.componentManufacturer = kAudioUnitManufacturer_Apple; outConverter.componentFlags = 0; outConverter.componentFlagsMask = 0; AudioComponent outConverterComponent = AudioComponentFindNext(nil, &outConverter); CheckError(AudioComponentInstanceNew(outConverterComponent, &outConverterUnit), "Out Converter inst"); //Set the input of this to be the Effect format CheckError(AudioUnitSetProperty(outConverterUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &effectFormat, sizeof(AudioStreamBasicDescription)), "Out Convreter set input format"); //Set the output of this to be the final audio format I need CheckError(AudioUnitSetProperty(outConverterUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 0, &audioFormat, sizeof(AudioStreamBasicDescription)), "Out Converter output format"); AudioUnitConnection outConnection; outConnection.sourceAudioUnit = lowPassUnit; outConnection.sourceOutputNumber = 0; outConnection.destInputNumber = 0; //Set the connection between effect and converter CheckError(AudioUnitSetProperty(outConverterUnit, kAudioUnitProperty_MakeConnection, kAudioUnitScope_Input, 0, &outConnection, sizeof(AudioUnitConnection)), "Make connection out conv to low pass"); //Initialize everything AudioUnitInitialize(theAudioUnit); AudioUnitInitialize(converterUnit); AudioUnitInitialize(lowPassUnit); AudioUnitInitialize(outConverterUnit); AURenderCallbackStruct callbackStruct; callbackStruct.inputProc = recordingCallback; callbackStruct.inputProcRefCon = (__bridge void * _Nullable)(self); //I need a render callback, so I set it on the Mic input CheckError(AudioUnitSetProperty(theAudioUnit, kAudioOutputUnitProperty_SetInputCallback, kAudioUnitScope_Global, 1, &callbackStruct, sizeof(AURenderCallbackStruct)), "Set input callback"); //And start the Mic input CheckError(AudioOutputUnitStart(theAudioUnit), "Out converter start");And here is the Render Callback: AudioBufferList bufferList; bufferList.mNumberBuffers = 1; bufferList.mBuffers[0].mData = NULL; NSLog(@"Number frames: %u, bus nubmer: %u", (unsigned int)inBusNumber, (unsigned int)inNumberFrames); //This is where I'm confused. What should the unit be here? Is it the audio unit? Converter unit? OSStatus status = AudioUnitRender(theAudioUnit, ioActionFlags, inTimeStamp, 1, inNumberFrames, &bufferList);
1
0
2.0k
Jan ’16
Xcode builds are getting blocked when you have a large amount of dependencies
I was working with some Apple Engineers today but we ran out of time in the session. They asked that I post the feedback number with some information: FB7763992. We were trying to figure out why I was having slow incremental compilation. In our testing, we found 1.4gb of .d files - the Apple Engineer believed the processing of these files slowed down the Xcode build process.
1
0
1k
Jun ’20