本文介绍了iOS Swift中简单的低延迟音频播放的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是iOS的初学者,我正在尝试使用Swift设计一个鼓组应用程序。我用一个按钮设计了一个视图并编写了下面的代码,但它有一些问题:

I'm a beginner in iOS and I'm trying to design a drum set app with Swift. I designed a view with a single button and wrote the code below, but it has some problems:


  1. 当我触摸时,有些声音会丢失按钮很快就像一个鼓声。

  2. 仍然在'鼓声'中,每次触摸按钮时声音都会中断,而不是让样本播放直到结束。例如,钹卷很糟糕。即使我再次触摸按钮,我也希望听到每个样本完全响起。

  3. 触摸和声音之间存在延迟。我知道 AVAudioPlayer 不是低延迟音频的最佳选择,但作为初学者,很难学习 OpenAL AudioUnit 没有 Swift 中的代码示例或教程。问题类似于:。

  1. Some sounds are lost when I touch the button quickly like a drum roll.
  2. Still in a 'drum roll', the sound is interrupted every time the button is touched, instead of letting the sample play till its ending. It's awful in cymbal roll, for instance. I'd like to hear every sample sounding completely, even if I touch the button again.
  3. There is a latency between the touch and the sound. I know that AVAudioPlayer is not the best choice for low-latency audio, but as a beginner, it's hard to learn OpenAL, AudioUnit without code samples or tutorials in Swift. The problem is similar to this: 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单例上发现了一个非常简单的解决方案(在应用程序启动时自动实例化):

If you need extremely low latency, I discovered a very simple solution available on the AVAudioSession singleton (which is instantiated automatically when an app launches):

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

First, get a reference to your app's AVAudioSession singleton using this class method:

(来自):

声明SWIFT

class func sharedInstance() - > AVAudioSession

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

Then, attempt to set the preferred IO buffer duration to something very short ( such as .002) using this instance method:

宣言SWIFT

func setPreferredIOBufferDuration(_ duration:NSTimeInterval)抛出

参数

持续时间音频I / O缓冲区你想要
使用的持续时间,以秒为单位。

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

outError 输入时,指向一个错误对象。如果发生错误
,则指针将设置为描述
错误的NSError对象。如果您不想要错误信息,请传入零。返回值
如果请求成功,则为true,否则为false。

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.

讨论

这方法请求更改I / O缓冲区持续时间。要确定
更改是否生效,请使用IOBufferDuration属性。
有关详细信息,请参阅。

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)抛出方法,取决于函数没有返回错误, 其他因素我还不完全清楚关于。另外 - 在我的测试中 - 我发现如果你将这个值设置为一个非常低的值,那么值(或接近它的值)确实会被设置,但是当播放文件时(例如使用AVAudioPlayerNode)声音不会玩了。没有错误,只是没有声音。这显然是个问题。我还没有发现如何测试这个问题,除非注意到在实际设备上测试时听不到声音。我会调查一下。但就目前而言,我建议将首选持续时间设置为不小于.002或.0015。 .0015的值似乎适用于我正在测试的iPad Air(型号A1474)。虽然低至.0012似乎在我的iPhone 6S上运行良好。


Keep in mind the note directly above- whether the IOBufferDuration property is actually set to the value passed into the func setPrefferedIOBufferDuration(_ duration: NSTimeInterval) throws method, depends on the function not returning an error, and other factors that I am not completely clear about. Also- in my testing- I discovered that if you set this value to an extremely low value, the value (or something close to it) does indeed get set, but when playing a file (for instance using the AVAudioPlayerNode) the sound will not be played. No error, just no sound. This is obviously a problem. And I haven't discovered how to test for this issue, except by noticing a lack of sound hitting my ear while testing on an actual device. I'll look into it. But for now, I would recommend setting the preferred duration to no less than .002 or .0015. The value of .0015 seems to work for the iPad Air (Model A1474) I am testing on. While as low as .0012 seems to work well on my iPhone 6S.

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

And another thing to consider from a CPU overhead standpoint is the format of the audio file. Uncompressed formats will have a very low CPU overhead when played. Apple recommends that for the highest quality and lowest overhead you should use CAF files. For compressed files and the lowest overhead you should use IMA4 compression:

(来自):

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

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

You can convert to IMA4 using afconvert as well:

/ usr / bin / afconvert -f AIFC -d ima4 [file]

这篇关于iOS Swift中简单的低延迟音频播放的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-23 00:43