Playing a Sound in a Swift Playground

Play musical notes in Swift Playground

You have to enable the asynchronous mode for the Playground.

Add this at the top (Xcode 7, Swift 2):

import XCPlayground
XCPlaygroundPage.currentPage.needsIndefiniteExecution = true

and your sequence will play.

The same for Xcode 8 (Swift 3):

import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true

Creating and playing a sound in swift

Here's a bit of code I've got added to FlappySwift that works:

import SpriteKit
import AVFoundation

class GameScene: SKScene {

// Grab the path, make sure to add it to your project!
var coinSound = NSURL(fileURLWithPath: Bundle.main.path(forResource: "coin", ofType: "wav")!)
var audioPlayer = AVAudioPlayer()

// Initial setup
override func didMoveToView(view: SKView) {
audioPlayer = AVAudioPlayer(contentsOfURL: coinSound, error: nil)
audioPlayer.prepareToPlay()
}

// Trigger the sound effect when the player grabs the coin
func didBeginContact(contact: SKPhysicsContact!) {
audioPlayer.play()
}

}

Swift NSSound plays silently?

NSSound plays its sound asynchronously. By default, a playground exits immediately after executing the its code, so the process terminates before the sound has had a chance to play.

Here's a quick and dirty way to keep the playground alive indefinitely so that you can hear the sound play.

import Cocoa
import XCPlayground

if let sound = NSSound(named:"Hero") {
XCPlaygroundPage.currentPage.needsIndefiniteExecution = true
sound.play()
}

How to call function when song finished in a Swift Playground

Set your winPlayer delegate as,

winPlayer?.delegate = self

and implement the method

func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
if flag == true {
// song finished successfully here
}
}

where you will place the delegate is up to you.

SingletonMusicPlayer playing overitself

I think you ran into a form of readers-writers problem here by attempting to simultaneously manipulate instance variables on your singleton from different threads. I don't know what your desired music player behavior is if it's being called from multiple threads at once, but for me one easy improvement would be to give your MusicPlayerManager singleton it's own DispatchQueue, where multiple overlapping requests can be handled sequentially.

You could define one like this:

let concurrentQueue = DispatchQueue(label: "com.stackoverflow.gamma", attributes: .concurrent)

And then wrap the code inside the playNotes function like this:

func playNotes(notes: [UInt8]) {
self.concurrentQueue.async(flags: .barrier) {
...
}
}


Related Topics



Leave a reply



Submit