Well this doesn’t really replicate any Xojo Syntax, but it is a Sound function that took me a few days to find all the pieces to. I had one that worked (it was much longer and more complicated), but it failed in iOS13 with a hard crash. This one works.
NOTE: this does block the UI while the tone is sounding, which for my current use is fine, but I will probably thread it in a later version
import Foundation
import AVFoundation
fileprivate var audioEngine : AVAudioEngine = AVAudioEngine()
func beep() {
playTONE(freq:500,dur:0.15)
}
func playTONE(freq:Double,dur:Double) {
let wait = dur * 1000000.0
var player : AVAudioPlayerNode?
var mixer : AVAudioMixerNode
var buffer : AVAudioPCMBuffer
player = AVAudioPlayerNode()
mixer = audioEngine.mainMixerNode;
buffer = AVAudioPCMBuffer(pcmFormat: player!.outputFormat(forBus:0), frameCapacity: 100)!
buffer.frameLength = 100
// generate sine wave.
let sr:Float = Float(mixer.outputFormat(forBus:0).sampleRate)
let n_channels = Int(mixer.outputFormat(forBus:0).channelCount)
var i : Int = 0
let f1 : Float = (Float(freq*2)*Float.pi)/sr
while i < Int(buffer.frameLength) {
buffer.floatChannelData?.pointee[i] = sinf(f1*Float(i)) * 0.5
i+=n_channels
}
// setup audio engine
audioEngine.attach(player!)
audioEngine.connect(player!, to: mixer, format: player!.outputFormat(forBus: 0))
audioEngine.prepare()
try! audioEngine.start()
// play player and buffer
player!.scheduleBuffer(buffer, at: nil, options: .loops, completionHandler: nil)
player!.play()
usleep(useconds_t(wait))
player!.stop()
}