2

My Morse code translator will not output the sound as it should. I have tested the speakers and my methods without this function and it works flawlessly, but it is not in context with the rest of the program. The compiler gives me no errors and the playground does not crash, it just doesn't play sound. Volume and ringer is at full.

func speakTheCode(message: String) {
    var speaker = AVAudioPlayer()
    let longBeep = #fileLiteral(resourceName: "beep_long.mp3")
    let shortBeep = #fileLiteral(resourceName: "beep_short.mp3")
    let dash = "-"
    let dot = "."
    for character in message.characters {
        if character == dash[dash.startIndex] {
                speaker = try! AVAudioPlayer(contentsOf: longBeep)
                speaker.prepareToPlay()
            print("-")
        }
        else if character == dot[dot.startIndex] {
                speaker = try! AVAudioPlayer(contentsOf: shortBeep)
                speaker.prepareToPlay()
                print(".")
        }
        speaker.play()
    }
}

I've been messing around with the code for hours now and nothing is working. What (if anything) am I doing wrong?

Matt
  • 21
  • 2

2 Answers2

0

There seems to some playgrounds issues with playing audio. See this thread:

Playing a sound in a Swift Playground

However, I was able to make some changes to your code and get it to work. Here's my code:

class Morse:NSObject, AVAudioPlayerDelegate {
    private var message = ""
    private var dotSound:AVAudioPlayer!
    private var dashSound:AVAudioPlayer!
    private let dash = Character("-")
    private let dot = Character(".")
    private var index:String.Index!

    init(message:String) {
        super.init()
        do {
            if let url = Bundle.main.url(forResource:"beep_short", withExtension:"mp3") {
                self.dotSound = try AVAudioPlayer(contentsOf:url)
                self.dotSound.delegate = self
                self.dotSound.prepareToPlay()
            }
        } catch {
            NSLog("Error loading dot audio!")
        }
        do {
            if let url = Bundle.main.url(forResource:"beep_long", withExtension:"mp3") {
                self.dashSound = try AVAudioPlayer(contentsOf:url)
                self.dashSound.delegate = self
                self.dashSound.prepareToPlay()
            }
        } catch {
            NSLog("Error loading dash audio!")
        }
        self.message = message
        self.index = message.startIndex
    }

    func playCharacter() {
        let character = message.characters[index]
        NSLog("Character: \(character)")
        if character == dash {
            dashSound.play()
        } else if character == dot {
            dotSound.play()
        }
    }

    func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
        NSLog("Finished playing")
        if index != message.endIndex {
            self.index = message.index(after:index)
            playCharacter()
        }
    }
}

let m = Morse(message:"...---")
m.playCharacter()

PlaygroundPage.current.needsIndefiniteExecution = true

I had to enable indefinite execution to get the code to execute at all. Also, I had some issues with the second audio file loading but I didn't investigate further to see if it was an issue with my test file or something else since it mostly worked.

Community
  • 1
  • 1
Fahim
  • 3,466
  • 1
  • 12
  • 18
-1

@Fahim still it is showing error

class Morse:NSObject, AVAudioPlayerDelegate { private var message = "" private var dotSound:AVAudioPlayer! private var dashSound:AVAudioPlayer! private let dash = Character("-") private let dot = Character(".") private var index:String.Index!

init(message:String) {
    super.init()
    do {
        if let url = Bundle.main.url(forResource:"beep_short", withExtension:"mp3") {
            self.dotSound = try AVAudioPlayer(contentsOf:url)
            self.dotSound.delegate = self
            self.dotSound.prepareToPlay()
        }
    } catch {
        NSLog("Error loading dot audio!")
    }
    do {
        if let url = Bundle.main.url(forResource:"beep_long", withExtension:"mp3") {
            self.dashSound = try AVAudioPlayer(contentsOf:url)
            self.dashSound.delegate = self
            self.dashSound.prepareToPlay()
        }
    } catch {
        NSLog("Error loading dash audio!")
    }
    self.message = message
    self.index = message.startIndex
}

func playCharacter() {
    let character = message.characters[index]
    NSLog("Character: \(character)")
    if character == dash {
        dashSound.play()
    } else if character == dot {
        dotSound.play()
    }
}

func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
    NSLog("Finished playing")
    if index != message.endIndex {
        self.index = message.index(after:index)
        playCharacter()
    }
}

}

let m = Morse(message:"...---") m.playCharacter()

PlaygroundPage.current.needsIndefiniteExecution = true

  • It's confusing when you post comments as an official answer. This "answer" of yours should be a comment to Fahim's answer and you should edit your question to show this updated code. – Michael Dautermann Mar 30 '17 at 10:34