3

I need to record an audio signal from a microfone sampled with 16,000Hz. I am using AVAudioEngine and Swift:

let input = audioEngine.inputNode
let mixer = AVAudioMixerNode()
audioEngine.attach(mixer)

let format = AVAudioFormat(commonFormat: AVAudioCommonFormat.pcmFormatInt16, sampleRate: 16000.0, channels: 1, interleaved: false)

audioEngine.connect(input, to: mixer, format: input.inputFormat(forBus: 0))            

mixer.installTap(onBus: 0, bufferSize: 2048, format: format) {
            (buffer: AVAudioPCMBuffer!, time: AVAudioTime!) -> Void in ... }

Unfortunately the app crashes with this error:

central] 54: ERROR: [0x3b281e40] >avae> AVAudioNode.mm:751: AUSetFormat: error -10868 *** Terminating app due to uncaught exception 'com.apple.coreaudio.avfaudio', reason: 'error -10868'

What am I doing wrong?

My idea was to use a mixer node to downsample from 44100 Hz to 16000Hz.

Is there a better solution than using a mixer?

EDIT:

Using AVAudioCommonFormat.pcmFormatFloat32 instead of AVAudioCommonFormat.pcmFormatInt16 works better. It does not lead to error messages or app crashes and on my iPhone 5 it even receives the correct sound signal. However, in the Xcode simulator (iPhone 7 / iPhone X) I only receive 0 as samples. I tested Siri in the simulator with the microphone and it works, so the microphone is not broken. What could be the problem?

Simon Hessner
  • 1,439
  • 1
  • 15
  • 39

1 Answers1

1

The only thing I found that worked to change the sampling rate was

AVAudioSettings.sharedInstance().setPreferredSampleRate(...)

Unfortunately, there is no guarantee that you will get the sample rate that you want, although it seems like 8000, 12000, 16000, 22050, 44100 all worked.

The following did NOT work:

  1. Setting the my custom format in a tap off engine.inputNode. (Exception)
  2. Adding a mixer with my custom format and tapping that. (Exception)
  3. Adding a mixer, connecting it with the inputNode's format, connecting the mixer to the main mixer with my custom format, then removing the input of the outputNode so as not to send the audio to the speaker and get instant feedback. (Worked, but got all zeros)
  4. Not using my custom format at all in the AVAudioEngine, and using AVAudioConverter to convert from the hardware rate in my tap. (Length of the buffer was not set, no way to tell if results were correct)

This was with iOS 12.3.1.

prewett
  • 1,438
  • 12
  • 18
  • Identical to https://stackoverflow.com/questions/39595444/avaudioengine-downsample-issue/57104029#57104029 – matt Aug 14 '19 at 09:23