0

I am trying to run a simple oscillator using the new AVAudioSourceNode Apple introduced in the latest release. The code is excerpt from the example code Apple released, available here.

However, whenever I run this in a Swift playground, the callback is fired but no sound is emitted. When I move this code to an iOS app, it works fine. Any idea what's happening? AFAIK other audio nodes work well in Playgrounds, so I'm not sure why this specific one fails. See code below. Ran using Xcode 11 and macOS 10.15.

import AVFoundation
import PlaygroundSupport

let audioEngine = AVAudioEngine()
let mainMixerNode = audioEngine.mainMixerNode
let outputNode = audioEngine.outputNode
let format = outputNode.inputFormat(forBus: 0)
let incrementAmount = 1.0 / Float(format.sampleRate)
var time: Float = 0.0

func sineWave(time: Float) -> Float {
    return sin(2.0 * Float.pi * 440.0 * time)
}

let sourceNode = AVAudioSourceNode { (_, _, frameCount, audioBufferList) -> OSStatus in
    let bufferListPointer = UnsafeMutableAudioBufferListPointer(audioBufferList)
    for frameIndex in 0..<Int(frameCount) {
        let sample = sineWave(time: time)

        time += incrementAmount

        for buffer in bufferListPointer {
            let buf: UnsafeMutableBufferPointer<Float> = UnsafeMutableBufferPointer(buffer)
            buf[frameIndex] = sample
        }
    }
    return noErr
}

audioEngine.attach(sourceNode)

audioEngine.connect(sourceNode, to: mainMixerNode, format: format)
audioEngine.connect(mainMixerNode, to: outputNode, format: nil)

mainMixerNode.outputVolume = 0.5

audioEngine.prepare()
do {
    try audioEngine.start()
} catch {
    print(error.localizedDescription)
}

PlaygroundPage.current.needsIndefiniteExecution = true
nevos
  • 907
  • 1
  • 10
  • 22

1 Answers1

0

It seems that Playground printing really ruins the performance of real time processing blocks. I had the same problem and then I moved the AVAudioSourceNode code to a different .swift file in the Sources folder, as suggested here

papadoo1
  • 1
  • 1