Simple Low-Latency Audio Playback in iOS Swift

Play sound effect without latency

Apple recommends AVAudioPlayer for playback of audio data unless you require very low I/O latency.

So you might want to try another approach.

In one of my apps I play countdown sounds by creating a system sound ID from my wav file. Try this in your class:

import UIKit
import AudioToolbox

class ViewController: UIViewController {
var sound: SystemSoundID = 0

override func viewDidLoad() {
super.viewDidLoad()

var hornSound = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("horn", ofType: "mp3")!)

AudioServicesCreateSystemSoundID(hornSound!, &self.sound)
}

@IBAction func playSound(sender: UIButton) {
AudioServicesPlaySystemSound(self.sound)
}

...
}

iOS objective C low-latency audio playback like SoundPool

You should be able to create several AVAudioPlayers and call prepareToPlay on them, but personally I like to use AVAssetReader to keep a buffer of LPCM audio ready to play at a moment's notice.

Using AVAudioEngine to schedule sounds for low-latency metronome

I was able to make a buffer containing sound from file and silence of required length. Hope this will help:

// audioFile here – an instance of AVAudioFile initialized with wav-file
func tickBuffer(forBpm bpm: Int) -> AVAudioPCMBuffer {
audioFile.framePosition = 0 // position in file from where to read, required if you're read several times from one AVAudioFile
let periodLength = AVAudioFrameCount(audioFile.processingFormat.sampleRate * 60 / Double(bpm)) // tick's length for given bpm (sound length + silence length)
let buffer = AVAudioPCMBuffer(PCMFormat: audioFile.processingFormat, frameCapacity: periodLength)
try! audioFile.readIntoBuffer(buffer) // sorry for forcing try
buffer.frameLength = periodLength // key to success. This will append silcence to sound
return buffer
}

// player – instance of AVAudioPlayerNode within your AVAudioEngine
func startLoop() {
player.stop()
let buffer = tickBuffer(forBpm: bpm)
player.scheduleBuffer(buffer, atTime: nil, options: .Loops, completionHandler: nil)
player.play()
}


Related Topics



Leave a reply



Submit