gpt4 book ai didi

ios - iOS Swift 中简单的低延迟音频播放

转载 作者:搜寻专家 更新时间:2023-10-31 08:23:02 25 4
gpt4 key购买 nike

我是 iOS 的初学者,我正在尝试使用 Swift 设计一个架子鼓应用。我设计了一个只有一个按钮的 View 并写了下面的代码,但是它有一些问题:

  1. 当我像击鼓一样快速触摸按钮时,一些声音会丢失。
  2. 仍然是“鼓声”,每次触摸按钮时声音都会中断,而不是让样本一直播放到结束。例如,它在铙钹卷中很糟糕。我想听到每个样本的完整声音,即使我再次触摸按钮也是如此。
  3. 触摸和声音之间存在延迟。我知道AVAudioPlayer不是低延迟音频的最佳选择,但作为初学者,没有代码很难学习OpenALAudioUnit Swift 中的示例或教程。问题类似于:Which framework should I use to play an audio file (WAV, MP3, AIFF) in iOS with low latency? .

代码:

override func viewDidLoad() {
super.viewDidLoad()

// Enable multiple touch for the button
for v in view.subviews {
if v.isKindOfClass(UIButton) {
v.multipleTouchEnabled = true
}
}

// Init audio
audioURL = NSBundle.mainBundle().URLForResource("snareDrum", withExtension: "wav")!
do {
player = try AVAudioPlayer(contentsOfURL: audioURL)
player?.prepareToPlay()
} catch {
print("AVAudioPlayer Error")
}
}

override func viewDidDisappear(animated: Bool) {
super.viewDidDisappear(animated)

player?.stop()
player = nil
}

@IBAction func playSound(sender: UIButton) {
player?.currentTime = 0
player?.play()
}

最佳答案

如果您需要极低的延迟,我在 AVAudioSession 单例(应用启动时自动实例化)上发现了一个非常简单的解决方案:

首先,使用此类方法获取对您应用的 AVAudioSession 单例的引用:

(来自 AVAudioSession Class Reference):

Getting the Shared Audio Session

Declaration SWIFT

class func sharedInstance() -> AVAudioSession

然后,尝试将首选 IO 缓冲持续时间设置为非常合适的值 使用此实例方法的短(例如 .002):

Sets the preferred audio I/O buffer duration, in seconds.

Declaration SWIFT

func setPreferredIOBufferDuration(_ duration: NSTimeInterval) throws

Parameters

duration The audio I/O buffer duration, in seconds, that you want to use.

outError On input, a pointer to an error object. If an error occurs, the pointer is set to an NSError object that describes the error. If you do not want error information, pass in nil. Return Value true if a request was successfully made, or false otherwise.

Discussion

This method requests a change to the I/O buffer duration. To determine whether the change takes effect, use the IOBufferDuration property. For details see Configuring the Audio Session.


请记住上面的注释 - IOBufferDuration 属性是否实际上设置为传递给 func setPrefferedIOBufferDuration(_ duration: NSTimeInterval) throws 的值 方法,取决于函数不返回错误, 其他我不完全清楚的因素。另外——在我的测试中——我发现如果你将这个值设置为一个极低的值,这个值(或接近它的值)确实会被设置,但是当播放一个文件(例如使用 AVAudioPlayerNode)时,声音不会被播放。没有错误,只是没有声音。这显然是个问题。而且我还没有发现如何测试这个问题,除了在实际设备上测试时注意到没有声音进入我的耳朵。我会调查一下。但就目前而言,我建议将首选持续时间设置为不少于 .002 或 .0015。 .0015 的值似乎适用于我正在测试的 iPad Air(型号 A1474)。虽然低至 .0012 似乎在我的 iPhone 6S 上运行良好。

从 CPU 开销的角度来看,另一件需要考虑的事情是音频文件的格式。播放未压缩格式时,CPU 开销非常低。 Apple 建议您应使用 CAF 文件以获得最高质量和最低开销。对于压缩文件和最低开销,您应该使用 IMA4 压缩:

(来自 iOS Multimedia Programming Guide):

Preferred Audio Formats in iOS For uncompressed (highest quality) audio, use 16-bit, little endian, linear PCM audio data packaged in a CAF file. You can convert an audio file to this format in Mac OS X using the afconvert command-line tool, as shown here:

/usr/bin/afconvert -f caff -d LEI16 {INPUT} {OUTPUT}

For less memory usage when you need to play multiple sounds simultaneously, use IMA4 (IMA/ADPCM) compression. This reduces file size but entails minimal CPU impact during decompression. As with linear PCM data, package IMA4 data in a CAF file.

您也可以使用 afconvert 转换为 IMA4:

/usr/bin/afconvert -f AIFC -d ima4 [文件]

关于ios - iOS Swift 中简单的低延迟音频播放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34680007/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com