Posts

Post not yet marked as solved
0 Replies
497 Views
Setting AVSpeechSynthesizer.delegate = self breaks french hyphenated words. e.g. “parlez-vous” will be pronounced “parlez”, "attendez-vous" will be pronounced "attendez", "est-ce que'il est la?" will be pronounced "est que'il est la?" "Puis-je vous voir demain?" will be pronounced "Puis vous voir demain?" If you listen you can tell that the second word is silent ... like there seems to be the correct space left for it. I have sent feedback FB 11968008 to Apple. No problem in the simulator - this is a device only problem occuring on these devices. iPhone 11 iOS 16.2, iPhone 8 iOS 16.1.2, iPad Air2 iOS 15.7.2, Xcode 14.2 Any thoughts? Example code: import SwiftUI import Speech struct ContentView: View { var synth = SpeechSynthesizer() @State var isDelegateSet = true var sentences: [String] = [ "Parlez-vous ", "attendez-vous ", "est-ce qu'il est la?", "Puis-je vous voir demain?" ] var body: some View { VStack { List { ForEach(sentences.indices, id: \.self) { index in Button(sentences[index]) { synth.toggleAVSpeechSynthesizerDelegate(isDelegateSet: isDelegateSet) synth.speak(string: sentences[index]) } } Toggle("toggle AVSpeechSynthesizer delegate", isOn: $isDelegateSet) Text(isDelegateSet ? "AVSpeechSynthesizer.delegate = self \nSpeech is INCORRECT " : "AVSpeechSynthesizer.delegate = nil \nSpeech is correct") .padding() } } } } class SpeechSynthesizer: NSObject, ObservableObject, AVSpeechSynthesizerDelegate { var synthesizer = AVSpeechSynthesizer() var utterance = AVSpeechUtterance(string: "") override init() { super.init() synthesizer.delegate = self } func speak(string: String) { synthesizer.stopSpeaking(at: .immediate) utterance = AVSpeechUtterance(string: string) utterance.voice = AVSpeechSynthesisVoice(language: "fr-FR") synthesizer.speak(utterance) } func toggleAVSpeechSynthesizerDelegate(isDelegateSet: Bool) { if isDelegateSet { synthesizer.delegate = self } else { synthesizer.delegate = nil } } func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, willSpeakRangeOfSpeechString characterRange: NSRange, utterance: AVSpeechUtterance) { // if synthesizer.delegate = self , phrases are spoken incorrectly. !! // if synthesizer.delegate = nil , phrases are spoken correctly as delegates are not called. !! } }
Posted
by boop.
Last updated
.
Post not yet marked as solved
0 Replies
572 Views
Problem: AVSpeechSynthesiser sometimes describes words rather than just speaking them as a real person would. When speaking in English AVSpeechSynthesiser pronounces the word "A" on its own as "Capital A", while the phrase "A little test" is pronounced correctly. A workaround of lowercasing the speech string - so "A" becomes "a" fixes this specific example. (I'm not yet sure if lowercasing sentences could affect pronunciation badly in some instances.) A more serious example: When speaking French the word "allé" on its own is pronounced by AVSpeechSynthesiser as "allé - e accent aigu" (accent aigu = acute accent). And here the problem exists even when the word is part of a sentence! With "Je suis allé au cinéma" (I went to the cinema) AVSpeechSynthesiser says "Je suis allé e accent aigu au cinéma" which is clearly wrong and unhelpful. Is there a way to fix this?
Posted
by boop.
Last updated
.
Post not yet marked as solved
0 Replies
1k Views
I have a problem in my SpriteKit game where audio using playSoundFileNamed(_ soundFile:, waitForCompletion:) will not play after the app is interrupted by a phone call. (I also use SKAudioNodes in my app which aren't affected but I really really really want to be able to use the SKAction playSoundFileNamed as well.)Here's the gameScene.swift file from a stripped down SpriteKit game template which reproduces the problem. You just need to add an audio file to the project and call it "note"I've attached the code that should reside in appDelegate to a toggle on/off button to simulate the phone call interruption.That code 1) Stops AudioEngine then deactivates AVAudioSession - (normally in applicationWillResignActive) ... and 2) Activates AVAudioSession then Starts AudioEngine - (normally in applicationDidBecomeActive)The error:AVAudioSession.mm:1079:-[AVAudioSession setActive:withOptions:error:]: Deactivating an audio session that has running I/O. All I/O should be stopped or paused prior to deactivating the audio session.This occurs when attempting to deactivate the audio session but only after a sound has been played at least once. to reproduce:1) Run the app 2) toggle the engine off and on a few times. No error will occur. 3) Tap the playSoundFileNamed button 1 or more times to play the sound. 4) Wait for sound to stop 5) Wait some more to be sure6) Tap Toggle Audio Engine button to stop the audioEngine and deactivate session - the error occurs.7) Toggle the engine on and of a few times to see session activated, session deactivated, session activated printed in debug area - i.e. no errors reported.8) Now with session active and engine running, playSoundFileNamed button will not play the sound anymore.What am I doing wrong?p.s. I also tried self.removeAllActions() before deactivating but it didn't help.import SpriteKit import AVFoundation class GameScene: SKScene { var toggleAudioButton: SKLabelNode? var playSoundFileButton: SKLabelNode? var engineIsRunning = true override func didMove(to view: SKView) { toggleAudioButton = SKLabelNode(text: "toggle Audio Engine") toggleAudioButton?.position = CGPoint(x:20, y:100) toggleAudioButton?.name = "toggleAudioEngine" toggleAudioButton?.fontSize = 80 addChild(toggleAudioButton!) playSoundFileButton = SKLabelNode(text: "playSoundFileNamed") playSoundFileButton?.position = CGPoint(x: (toggleAudioButton?.frame.midX)!, y: (toggleAudioButton?.frame.midY)!-240) playSoundFileButton?.name = "playSoundFileNamed" playSoundFileButton?.fontSize = 80 addChild(playSoundFileButton!) } override func touchesBegan(_ touches: Set, with event: UIEvent?) { if let touch = touches.first { let location = touch.location(in: self) let nodes = self.nodes(at: location) for spriteNode in nodes { if spriteNode.name == "toggleAudioEngine" { if engineIsRunning { // 1 stop engine, 2 deactivate session scene?.audioEngine.stop() // 1 toggleAudioButton!.text = "engine is paused" engineIsRunning = !engineIsRunning do{ // this is the line that fails when hit anytime after the playSoundFileButton has played a sound try AVAudioSession.sharedInstance().setActive(false) // 2 print("session deactivated") } catch{ print("DEACTIVATE SESSION FAILED") } } else { // 1 activate session/ 2 start engine do{ try AVAudioSession.sharedInstance().setActive(true) // 1 print("session activated") } catch{ print("couldn't setActive = true") } do { try scene?.audioEngine.start() // 2 toggleAudioButton!.text = "engine is running" engineIsRunning = !engineIsRunning } catch { // } } } if spriteNode.name == "playSoundFileNamed" { self.run(SKAction.playSoundFileNamed("note", waitForCompletion: false)) } } } } }
Posted
by boop.
Last updated
.