diff --git a/Example/SwiftySoundExample/ViewController.swift b/Example/SwiftySoundExample/ViewController.swift index 6f306d0..ff05ee6 100644 --- a/Example/SwiftySoundExample/ViewController.swift +++ b/Example/SwiftySoundExample/ViewController.swift @@ -28,7 +28,7 @@ class ViewController: UIViewController, UITextFieldDelegate { super.viewDidLoad() switchSoundEnabled.isOn = Sound.enabled if let dogUrl = Bundle.main.url(forResource: "dog", withExtension: "wav") { - dogSound = Sound(url: dogUrl) + dogSound = Sound(url: dogUrl, playersPerSound: 1) } if let pianoUrl = Bundle.main.url(forResource: "piano", withExtension: "wav") { backgroundSound = Sound(url: pianoUrl) @@ -46,11 +46,15 @@ class ViewController: UIViewController, UITextFieldDelegate { // MARK: - Actions @IBAction func buttonDogClicked(_ sender: Any) { - Sound.play(file: "dog", fileExtension: "wav", numberOfLoops: numberOfLoops()) + let numberOfLoops = self.numberOfLoops() + let numberOfPlayers = max(numberOfLoops + 1, 1) + Sound.play(file: "dog", fileExtension: "wav", numberOfLoops: numberOfLoops, numberOfPlayers: numberOfPlayers) } @IBAction func buttonCatClicked(_ sender: Any) { - Sound.play(file: "cat", fileExtension: "wav", numberOfLoops: numberOfLoops()) + let numberOfLoops = self.numberOfLoops() + let numberOfPlayers = max(numberOfLoops + 1, 1) + Sound.play(file: "cat", fileExtension: "wav", numberOfLoops: numberOfLoops, numberOfPlayers: numberOfPlayers) } @IBAction func buttonDogWithVolumeClicked(_ sender: Any) { diff --git a/Sources/Sound.swift b/Sources/Sound.swift index a470a1e..b368c2d 100644 --- a/Sources/Sound.swift +++ b/Sources/Sound.swift @@ -74,6 +74,9 @@ open class Sound { } } + /// Number of AVAudioPlayer instances created for the sound + public var playersPerSound: Int { players.count } + #if os(iOS) || os(tvOS) /// Sound session. The default value is the shared `AVAudioSession` session. public static var session: Session = AVAudioSession.sharedInstance() @@ -120,12 +123,14 @@ open class Sound { /// Create a sound object. /// - /// - Parameter url: Sound file URL. - public init?(url: URL) { + /// - Parameters: + /// - url: Sound file URL. + /// - numberOfPlayers: Number of AVAudioPlayer instances for sound. + public init?(url: URL, numberOfPlayers: Int? = nil) { #if os(iOS) || os(tvOS) _ = Sound.category #endif - let playersPerSound = max(Sound.playersPerSound, 1) + let playersPerSound = max(numberOfPlayers ?? Sound.playersPerSound, 1) var myPlayers: [Player] = [] myPlayers.reserveCapacity(playersPerSound) for _ in 0.. Bool { + @discardableResult public static func play(file: String, fileExtension: String? = nil, numberOfLoops: Int = 0, numberOfPlayers: Int? = nil) -> Bool { if let url = url(for: file, fileExtension: fileExtension) { - return play(url: url, numberOfLoops: numberOfLoops) + return play(url: url, numberOfLoops: numberOfLoops, numberOfPlayers: numberOfPlayers) } return false } @@ -235,14 +241,15 @@ open class Sound { /// - Parameters: /// - url: Sound file URL. /// - numberOfLoops: Number of loops. Specify a negative number for an infinite loop. Default value of 0 means that the sound will be played once. + /// - numberOfPlayers: Number of AVAudioPlayer instances for sound. /// - Returns: If the sound was played successfully the return value will be true. It will be false if sounds are disabled or if system could not play the sound. - @discardableResult public static func play(url: URL, numberOfLoops: Int = 0) -> Bool { + @discardableResult public static func play(url: URL, numberOfLoops: Int = 0, numberOfPlayers: Int? = nil) -> Bool { if !Sound.enabled { return false } var sound = sounds[url] if sound == nil { - sound = Sound(url: url) + sound = Sound(url: url, numberOfPlayers: numberOfPlayers) sounds[url] = sound } return sound?.play(numberOfLoops: numberOfLoops) ?? false diff --git a/Tests/SwiftySoundTests/SwiftySoundTests.swift b/Tests/SwiftySoundTests/SwiftySoundTests.swift index c6aac4d..2586ad2 100644 --- a/Tests/SwiftySoundTests/SwiftySoundTests.swift +++ b/Tests/SwiftySoundTests/SwiftySoundTests.swift @@ -109,6 +109,18 @@ class SwiftySoundTests: XCTestCase { XCTAssertEqual(Sound.playersPerSound, 5) } + func testPlayersPerSpecificSound() { + if let url = bundle.url(forResource: "dog", withExtension: "wav") { + + guard let sound = Sound(url: url, numberOfPlayers: 3) else { + XCTFail() + return + } + + XCTAssertEqual(sound.playersPerSound, 3) + } + } + // MARK: Playback func testCreatingInstance() { if let url = bundle.url(forResource: "dog", withExtension: "wav") {