swift on macOS: AVAudioPlayer stops immediately

Hi all,

I'm making my first macOS (not iOS) project in Swift.

In my main AppDelegate.swift I instantiate a class called PlaySound and then call startSound()

The class called PlaySound.swift plays an mp3. However, I hear no sound unless I put a sleep() soon after I call myPlayer.play() in either class file. I thought I was losing reference to the class instantiation, but I am able to call a test print function as you see and that works.

Does anyone know why the audio is stopping?

thanks for any help -Bill


import Cocoa
@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
    func applicationDidFinishLaunching(_ aNotification: Notification) {
        let myPlaySound = PlaySound()
        myPlaySound.startSound()
        myPlaySound.testPrint()
    }

    func applicationWillTerminate(_ aNotification: Notification) {
    
    }
}


PlaySound class below...

import Foundation
import AVKit
class PlaySound {
  
    var soundFile="crickets"
    var myPlayer = AVAudioPlayer()
    func startSound(){
            do{
                myPlayer = try AVAudioPlayer(contentsOf: URL.init(fileURLWithPath: Bundle.main.path(forResource: soundFile, ofType: "mp3")!))
         
                myPlayer.numberOfLoops = -1
                myPlayer.prepareToPlay()
               
                myPlayer.volume = 0
               
                myPlayer.play()
               
                myPlayer.setVolume(1, fadeDuration: 2)
                print("should hear something")
                print(myPlayer.volume)
            }
            catch{
                print(error)
            }
    }
    func fadeOutSound(){
        myPlayer.setVolume(0, fadeDuration: 10)
        myPlayer.stop()
    }
    func testPrint()  {
        print("yes this works")
    }
  
}//end class
Accepted Answer

>>I thought I was losing reference to the class instantiation,


That thought was correct.


>> but I am able to call a test print function as you see and that works.


Because the reference hasn't been "lost" quite yet. In your code:


func applicationDidFinishLaunching(_ aNotification: Notification) {
        let myPlaySound = PlaySound()
        myPlaySound.startSound()
        myPlaySound.testPrint()
    }


You create a locally-scoped variable, "myPlaySound", containing a reference to a PlaySound object. The only owning reference to the object is that variable, so when the variable goes away, at the end of the function scope (at line 5), the object is deallocated. Note that this is after the testPrint function is called, but before playback has had a chance to start. The result is that you see your print output, but hear nothing.


You need a persistent reference to the PlaySound object to keep it alive. For example, you could make "myPlaySound" an instance variable of the app delegate.

Thanks very much! That did it.

swift on macOS: AVAudioPlayer stops immediately
 
 
Q