Tadej Slemenšek
Tadej Slemenšek

Reputation: 112

audioEngine.start() throws exception when called



Problem
I'm trying to record microphone data using AVAudioEngine. This is my setup:

First I create singleton session, set sessions category and activate it:

let audioSession = AVAudioSession.sharedInstance()
    
do {
    try audioSession.setCategory(.record)
    try audioSession.setActive(true)
} catch {
    ...
}

After that I create input format for bus 0, connect input and output nodes and install tap on input node (I also tried to tap output node):

let inputFormat = self.audioEngine.inputNode.inputFormat(forBus: 0)
self.audioEngine.connect(self.audioEngine.inputNode, to: self.audioEngine.outputNode, format: inputFormat)
self.audioEngine.outputNode.installTap(onBus: 0, bufferSize: bufferSize, format: inputFormat) { (buffer, time) in
    let theLength = Int(buffer.frameLength)
    var samplesAsDoubles:[Double] = []
    
    for i in 0 ..< theLength
    {
        let theSample = Double((buffer.floatChannelData?.pointee[i])!)
        samplesAsDoubles.append( theSample )
    }
    ...
}

All of the above is in one function. I also have another function called startRecording which contains the following:

do {
    try audioEngine.start()
} catch {
    ...
}

I have also verified microphone permissions are granted.

start method fails and this is the response:

The operation couldn’t be completed. (com.apple.coreaudio.avfaudio error -10875.)


Questions
Based on documentation there are three possible causes:

I don't believe it's the session one, because I set it up via documentation.

If the driver fails, how would I detect that and handle it?

If graph is setup incorrectly, where did I mess it up?

Upvotes: 2

Views: 640

Answers (1)

Rob Napier
Rob Napier

Reputation: 299265

If you want to record the microphone, attach the tap to the inputNode, not the outputNode. Taps observe the output of a node. There is no "output" of the outputNode. It's the sink.

If you need to install a tap "immediately before the outputNode" (which might not be the input node in a more complicated graph), you can insert a mixer between the input(s) and the output and attach the tap to the mixer.

Also, make sure you really want to connect the input node to the output node here. There's no need to do that unless you want to playback audio live. You can just attach a tap to the input node without building any more of the graph if you just want to record the microphone. (This also might be causing part of your problem, since you set your category to .record, i.e. no playback. I don't know that wiring something to the output in that case causes an exception, but it definitely doesn't make sense.)

Upvotes: 2

Related Questions