Search code examples
swiftavfoundationcore-audioavaudioengine

AVAudioSinkNode Giving No Signal


Context: I'm trying to make a real-time audio chat.

I've been playing around with AVAudioSinkNode all week so I can record audio, however for some reason whenever I try it, the audioBufferList is always filled with zeros. Right now I'm testing it in Swift Playground. Here is my code:

let engine = AVAudioEngine()

let sinkNode = AVAudioSinkNode { (timestep, frames, audioBufferList) -> OSStatus in
    let ptr = audioBufferList.pointee.mBuffers.mData?.assumingMemoryBound(to: Float.self)
    var monoSamples = [Float]()
    monoSamples.append(contentsOf: UnsafeBufferPointer(start: ptr, count: Int(frames)))
    for frame in 0..<frames {
      print("sink: " + String(monoSamples[Int(frame)]))
    }
    return noErr
}

engine.attach(sinkNode)

engine.connect(engine.inputNode, to: sinkNode, format: nil)

do {
    try engine.start()
    CFRunLoopRunInMode(.defaultMode, CFTimeInterval(duration), false)
    engine.stop()
} catch {
    print("Could not start engine: \(error)")
}

Then this is the resulting output:

...
sink: 0.0
sink: 0.0
sink: 0.0
sink: 0.0
sink: 0.0
sink: 0.0
sink: 0.0
sink: 0.0
sink: 0.0
sink: 0.0
sink: 0.0
sink: 0.0
sink: 0.0
sink: 0.0
sink: 0.0
sink: 0.0
sink: 0.0
sink: 0.0
sink: 0.0
sink: 0.0
sink: 0.0
sink: 0.0
sink: 0.0
sink: 0.0
Program ended with exit code: 0

I've looked around at some questions that were similar, but few seem to be having my issue. I've looked into using taps but from what I've seen those aren't great for real-time applications like mine.

Could anyone point me in the right direction?


Solution

  • After playing with your example I can confirm it works as expected. However, that was initially not the case because I had my Dante Virtual Soundcard selected as system-wide audio input.

    After setting the audio input to microphone the numbers started to reflect an actual audio signal.

    So, try set your audio input to something you know for sure produces audio.

    EDIT

    As we found out another way this can fail is when the permissions for using the microphone are not set for XCode. These can be set using System Preferences -> Security & Privacy -> Microphone -> XCode