IPA notation AVSpeechSynthesizer is not working?

I am attempting to utilize alternative pronunciation utilizing the IPA notation for AVSpeechSynthesizer on macOS (Big Sur 11.4). The attributed string is being ignored and so the functionality is not working. I tried this on iOS simulator and it works properly.

The India English voice pronounces the word "shame" as shy-em, so I applied the correct pronunciation but no change was heard. I then substituted the pronunciation for a completely different word but there was no change.

Is there something else that must be done to make this work?

AVSpeechSynthesisIPANotationAttribute

Attributed String: It's a '{ }shame{ AVSpeechSynthesisIPANotationAttribute = "\U0283\U02c8e\U0361\U026am"; }' it didn't work out.{ } Target Range: {8, 5} Target String: shame, Substitution: ʃˈe͡ɪm

Attributed String: It's a '{ }shame{ AVSpeechSynthesisIPANotationAttribute = "\U0283\U02c8e\U0361\U026am"; }' it didn't work out.{ } Target Range: {8, 5} Target String: shame, Substitution: ʃˈe͡ɪm

Attributed String: It's a '{ }shame{ AVSpeechSynthesisIPANotationAttribute = "t\U0259.\U02c8me\U0361\U026a.do\U0361\U028a"; }' it didn't work out.{ } Target Range: {8, 5} Target String: shame, Substitution: tə.ˈme͡ɪ.do͡ʊ

Attributed String: It's a '{ }shame{ AVSpeechSynthesisIPANotationAttribute = "t\U0259.\U02c8me\U0361\U026a.do\U0361\U028a"; }' it didn't work out.{ } Target Range: {8, 5} Target String: shame, Substitution: tə.ˈme͡ɪ.do͡ʊ

class SpeakerTest: NSObject, AVSpeechSynthesizerDelegate {
    let synth = AVSpeechSynthesizer()

    func speakIPA_Substitution(subst: String,  voice: AVSpeechSynthesisVoice)
    {
        let text         = "It's a 'shame' it didn't work out."
        let mutAttrStr   = NSMutableAttributedString(string: text)
        let range        = NSString(string: text).range(of: "shame")
        let pronounceKey = NSAttributedString.Key(rawValue: AVSpeechSynthesisIPANotationAttribute)
        mutAttrStr.setAttributes([pronounceKey: subst], range: range)
        let utterance    = AVSpeechUtterance(attributedString: mutAttrStr)
        utterance.voice  = voice
        utterance.postUtteranceDelay = 1.0
        let swiftRange = Range(range, in: text)!
        print("Attributed String: \(mutAttrStr)")
        print("Target Range: \(range)")
        print("Target String: \(text[swiftRange]), Substitution: \(subst)\n")
        synth.speak(utterance)
    }

    func customPronunciation()
    {
        let shame        = "ʃˈe͡ɪm"         // substitute correct pronunciation
        let tomato       = "tə.ˈme͡ɪ.do͡ʊ"   // completely different word pronunciation
        let britishVoice = AVSpeechSynthesisVoice(language: "en-GB")!
        let indiaVoice   = AVSpeechSynthesisVoice(language: "en-IN")!
        speakIPA_Substitution(subst: shame, voice: britishVoice)  // already correct, no substitute needed
        // pronounced incorrectly and ignoring the corrected pronunciation from IPA Notation
        speakIPA_Substitution(subst: shame,  voice: indiaVoice)   // ignores substitution
        speakIPA_Substitution(subst: tomato, voice: britishVoice) // ignores substitution
        speakIPA_Substitution(subst: tomato, voice: indiaVoice)   // ignores substitution
    }
}

  • I just learned that "en-IN" is not a language choice on Catalina. Substituting "en-US" will achieve the same outcome, though the voice will be US English let indiaVoice = AVSpeechSynthesisVoice(language: "en-US")!

  • What would be a good workaround \ alternative? I moved my code and workflow from NSSpeechSynthesizer to AVSpeechSynthesizer for the sole benefit of applying\using a pronunciation dictionary, so whatever I can do in the interim, I will gladly consider to make this work.

Add a Comment

Replies

It may be that something else needs to be done on macOS but because this works in the simulator, I filed a bug report. Jul 9, 2021 at 2:27 PM – FB9298976

  • You'll be happy to know that feedback not found so apple is ignoring this issue apparently.

Add a Comment