У меня есть Simon-подобная игра памяти, в которой воспроизводится последовательность тонов, и пользователь пытается повторить тоны. Проблема в том, что время от времени я получаю ужасный, потрескивающий звук. Это может быть только после нескольких нот или целых двадцать. Звуки - это все файлы 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()
}
Если у кого-то есть мысли - даже если это просто следующий шаг, вы можете попробовать...