Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions Example/SwiftySoundExample/ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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) {
Expand Down
21 changes: 14 additions & 7 deletions Sources/Sound.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -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..<playersPerSound {
Expand Down Expand Up @@ -222,10 +227,11 @@ open class Sound {
/// - file: Sound file name.
/// - fileExtension: Sound file extension.
/// - 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(file: String, fileExtension: String? = nil, numberOfLoops: Int = 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
}
Expand All @@ -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
Expand Down
12 changes: 12 additions & 0 deletions Tests/SwiftySoundTests/SwiftySoundTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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") {
Expand Down