AVAudioPlayer 爆裂声和爆裂声
Posted
技术标签:
【中文标题】AVAudioPlayer 爆裂声和爆裂声【英文标题】:AVAudioPlayer crackles and pops 【发布时间】:2017-12-07 03:40:16 【问题描述】:我有一个类似西蒙的记忆游戏,播放一系列音调,用户尝试重复这些音调。问题是我不时听到可怕的噼啪声。它可能是在几个音符或多达二十个音符之后。声音都是两秒长的 wav 文件。我循环播放十个播放器,这样所有声音都不会被剪裁。 (我尝试了多达 50 个,但没有任何帮助。)我还尝试实现 audioPlayerDidFinishPlaying
,以便在声音完成后停止播放器,但这也无济于事。最后,我添加了prepareToPlay()
- 遗憾的是,没有区别。
一个可能相关也可能不相关的有趣问题是,在大约 15 个音符的序列之后,音频停止一起工作。应用继续正常运行,但没有任何声音。
这是代码的音频部分:
func playSound(_ soundID: Int)
var soundName = ""
switch soundID
case 0:
soundName = "beep1"
case 1:
soundName = "beep2"
case 2:
soundName = "beep3"
case 3:
soundName = "beep4"
case 4:
soundName = "swish3"
default:
soundName = "clank"
guard let url = Bundle.main.url(forResource: soundName, withExtension: "wav") else return
do
buttonSound.insert(try AVAudioPlayer(contentsOf: url, fileTypeHint: AVFileType.wav.rawValue), at: playerIndex)
buttonSound[playerIndex].prepareToPlay()
buttonSound[playerIndex].delegate = self
if playerIndex < 10
buttonSound[playerIndex].play()
playerIndex += 1
else
buttonSound[playerIndex].play()
playerIndex = 0
catch
// error
func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool)
if flag
player.stop()
/******** 更新*********/
根据我遇到的一个过时的示例,我将 AVAudioPlayer 创建移到了它自己的类中……某处。它解决了15音后完全切断音频的问题,但是裂纹和爆裂声仍然存在!我还尝试重新录制声音,但没有成功。
这是根据需要创建 AVAudioPlayers 的类:
import UIKit
import AVFoundation
private var players: [AVAudioPlayer] = []
class AVAudioPlayerPool: NSObject
class func playerWithURL(url: URL) -> AVAudioPlayer?
let availablePlayers = players.filter (player) -> Bool in
return player.isPlaying == false && player.url == url
if let playerToUse = availablePlayers.first
playerToUse.prepareToPlay()
return playerToUse
do
let newPlayer = try AVAudioPlayer(contentsOf: url, fileTypeHint: AVFileType.wav.rawValue)
players.append(newPlayer)
newPlayer.prepareToPlay()
return newPlayer
catch
return nil
播放声音很简单:
func playSound(_ soundID: Int)
var soundName = ""
switch soundID
case 0:
soundName = "tt1"
case 1:
soundName = "tt2"
case 2:
soundName = "tt3"
case 3:
soundName = "tt4"
case 4:
soundName = "swish3"
default:
soundName = "clank"
guard let url = Bundle.main.url(forResource: soundName, withExtension: "wav") else return
let player = AVAudioPlayerPool.playerWithURL(url: url)
player?.play()
如果有人有任何想法 - 即使只是下一步,您也可以尝试......
【问题讨论】:
如何在后台队列中播放文件?主线程可能正忙于处理您的游戏,这可能会导致您遇到爆裂声 我尝试将其移出主线程 - 仍然很脆。不过谢谢你的建议。 你用过 OALSimpleAudio 吗? github.com/kstenerud/ObjectAL-for-iPhone我在我当前的游戏项目中使用它,它有很多不同的声音。它是一个 Objective-C 代码,但使用桥接头很容易添加到 swift 项目中。如果您需要帮助,请告诉我 @Woof,我很欣赏这个建议,但是,这只是一个简单的学习项目。我真的很想弄清楚 AVAudioPlayer。如果这是一个实际项目,我会在几周前继续前进。谢谢! 【参考方案1】:在我看来,您的主要问题是声音加载是在应该播放声音本身的同一函数内完成的。从概念上讲是错误的,为了能够尽可能快地播放声音,您应该在“播放”功能之外一劳永逸地加载所有声音。该功能应该只是播放,仅此而已。
【讨论】:
这是有道理的。我仍在试图弄清楚如何将动态播放器创建与播放功能分开。但我正在努力…… 尽管这个答案很好,但它不是问题的解决方案。我为每个声音创建了单独的音频播放器,在 VC 中初始化。调用从游戏场景中播放声音的方法仍会导致“描述的爆裂声/噼啪声”【参考方案2】:我们刚刚在团队中遇到了问题。在我们的案例中,只有应用程序在连接了调试器的设备上运行时才能重现失真的声音错误。一旦我们将应用程序从调试器中分离出来,裂纹就会消失。 看起来问题首先出现在新的 Xcode 9.2 (9C40b) 中。
【讨论】:
这很有趣,如果它解决了我的问题会很棒。当我改进播放器创建过程时,失真从模拟器中消失了。不幸的是,它仍在设备上,无论是否连接。 我遇到了完全相同的问题。我已经将声音创建和播放方法实现到我在游戏场景中创建和实例化的单独类中。每次我调用一个方法来播放声音时,我都会听到这种爆裂声和爆裂声。我尝试了很多不同的声音,但问题仍然存在。还尝试删除运行模式中的调试,但没有运气! 分离调试器也解决了这里的问题。谢谢。但是有没有办法在附加调试器时修复它?【参考方案3】:经过数小时的实验,我要说问题是由我选择的声音引起的 - 一种带有混响的大而空心的方波合成器声音。我首先尝试降低可能有帮助的水平思维。接下来我尝试了各种不同的声音,但一切都噼啪作响。我认为这与我分配球员的方式有关。一旦我解决了播放器问题,我就没有想过要回去再尝试不同的声音。直到,我做到了......而且它有效!
【讨论】:
以上是关于AVAudioPlayer 爆裂声和爆裂声的主要内容,如果未能解决你的问题,请参考以下文章