Playing beep sound using AVAudioEngine in SwiftUI

241 views Asked by At

I am new to SWift and have tried to play beep sound with fixed frequency, say 600Hz. That's it. Any suggestion is welcome.

Here is an example using AVFoundation I tried, but it plays no sound. I suspect many places but have no clues. (1) initialzing player (2) prepared buffer wrongly (3) misused optional type and doing wrapping wrongly (4) the code is okay but it does not play on simulator (5) and surprising many other possibilities Can you kindly help me?

import SwiftUI
import AVFoundation

struct BeepPlayer: View {
    var body: some View {
        Button(action: playBeep) {
            Text("Play 600Hz Beep")
        }
    }
    
    func playBeep() {
        let engine = AVAudioEngine()
        let player = AVAudioPlayerNode()
        var mixer = engine.mainMixerNode
        engine.attach(player)
        var buffer = createBeepBuffer()
        player.scheduleBuffer(buffer, at: nil, options: .loops, completionHandler: nil)
        engine.connect(player, to: mixer, format: mixer.outputFormat(forBus: 0))
        
        
        do {
            try engine.start()
            player.play()
            
        } catch {
            print("Error: \(error)")
        }
        player.stop()
    }
    
    func createBeepBuffer() -> AVAudioPCMBuffer {
        let sampleRate: Double = 44100
        let frequency: Float = 600
        let duration: Double = 1
        let frames = AVAudioFrameCount(44100 * duration)
        let buffer = AVAudioPCMBuffer(pcmFormat: AVAudioFormat(standardFormatWithSampleRate: sampleRate, channels: 2)!, frameCapacity: frames)
        buffer?.frameLength = frames
        
        let amplitude: Float = 0.5
        let increment = 2 * Float.pi * frequency / Float(sampleRate)
        var currentPhase: Float = 0
        
        for i in 0..<Int(frames) {
            buffer?.floatChannelData?[0][i] = sin(currentPhase) * amplitude
            buffer?.floatChannelData?[1][i] = sin(currentPhase) * amplitude
            currentPhase += increment
        }
        
        return buffer!
    }
}
0

There are 0 answers