How to use “kAudioUnitSubType_VoiceProcessingIO” subtype of core audio API in mac os?

倾然丶 夕夏残阳落幕 提交于 2019-11-29 04:51:50

I discovered a few things enabling this IO unit.

  1. Stream format is really picky. It has to be
    • LinearPCM
    • FlagsCononical
    • 32 bits per channel
    • (I did 1 channel but it might work with more)-
    • sample rate 44100 (might work with others might not)
  2. You don't set EnableIO on it. IO is enabled by default and that property is not writable.
  3. Set stream format before initialization.

As with other core audio work, you just need to check the error status of every single function call, determine what the errors are and make little changes at each step until you finally get it to work.

I had two different kAudioUnitProperty_StreamFormat setup based on the number of the channels.

size_t bytesPerSample = sizeof (AudioUnitSampleType);
stereoStreamFormat.mFormatID          = kAudioFormatLinearPCM;
stereoStreamFormat.mFormatFlags       = kAudioFormatFlagsAudioUnitCanonical;
stereoStreamFormat.mBytesPerPacket    = bytesPerSample;
stereoStreamFormat.mFramesPerPacket   = 1;
stereoStreamFormat.mBytesPerFrame     = bytesPerSample;
stereoStreamFormat.mChannelsPerFrame  = 2;
stereoStreamFormat.mBitsPerChannel    = 8 * bytesPerSample;
stereoStreamFormat.mSampleRate        = graphSampleRate;

and

size_t bytesPerSample = sizeof (AudioUnitSampleType);
monoStreamFormat.mFormatID          = kAudioFormatLinearPCM;
monoStreamFormat.mFormatFlags       = kAudioFormatFlagsAudioUnitCanonical;
monoStreamFormat.mBytesPerPacket    = bytesPerSample;
monoStreamFormat.mFramesPerPacket   = 1;
monoStreamFormat.mBytesPerFrame     = bytesPerSample;
monoStreamFormat.mChannelsPerFrame  = 1;                  // 1 indicates mono
monoStreamFormat.mBitsPerChannel    = 8 * bytesPerSample;
monoStreamFormat.mSampleRate        = graphSampleRate;

with this audio stream formats when using the I/O unit as a kAudioUnitSubType_VoiceProcessingIO

AudioComponentDescription iOUnitDescription;
iOUnitDescription.componentType = kAudioUnitType_Output;
iOUnitDescription.componentSubType = kAudioUnitSubType_VoiceProcessingIO;
iOUnitDescription.componentManufacturer = kAudioUnitManufacturer_Apple;
iOUnitDescription.componentFlags = 0;
iOUnitDescription.componentFlagsMask = 0;

I can clearly see a interruption in the audio output, as the buffer size was smaller than the one from this AudioUnit.

Switching back to the kAudioUnitSubType_RemoteIO

iOUnitDescription.componentSubType = kAudioUnitSubType_RemoteIO;

That interruption disappear.

I'm processing audio input from microphone and applying some real time calculations on the audio buffers.

In the methods the graphSampleRate is the AVSession sample rate

graphSampleRate = [AVAudioSession sharedInstance] sampleRate];

and maybe here I'm wrong.

At the end the configuration parameters values are the following:

The stereo stream format:

Sample Rate:              44100
Format ID:                 lpcm
Format Flags:              3116
Bytes per Packet:             4
Frames per Packet:            1
Bytes per Frame:              4
Channels per Frame:           2
Bits per Channel:            32

The mono stream format:

Sample Rate:              44100
Format ID:                 lpcm
Format Flags:              3116
Bytes per Packet:             4
Frames per Packet:            1
Bytes per Frame:              4
Channels per Frame:           1
Bits per Channel:            32
Roozbeh Zabihollahi

Thanks to SO post here I realized I should have used this flag:

audioFormat.mFormatFlags        = kAudioFormatFlagsCanonical;
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!