From 0fb6c62d838ee2b07c8c1df64fa5e4f2f4161b7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Caddet?= Date: Fri, 4 Sep 2020 15:48:56 +0200 Subject: [PATCH] fix some parameters types and implement set_voice We have an ilegal hardware instruction in backend::av_foundation::voices::AVSpeechSynthesisVoice::new(identifier) when sending voiceWithIdentifier. Is it because the runLoop is not runing when it's called? --- examples/hello_world.rs | 14 ++++++++++++++ src/backends/appkit.rs | 2 +- src/backends/av_foundation.rs | 2 +- src/backends/av_foundation/voices.rs | 11 +++++++---- src/lib.rs | 6 +++--- 5 files changed, 26 insertions(+), 9 deletions(-) diff --git a/examples/hello_world.rs b/examples/hello_world.rs index e95c53c..f3e054e 100644 --- a/examples/hello_world.rs +++ b/examples/hello_world.rs @@ -47,6 +47,20 @@ fn main() -> Result<(), Error> { tts.speak("This is normal volume.", false)?; tts.set_volume(original_volume)?; } + let Features { voices, .. } = tts.supported_features(); + if voices { + let original_voice = tts.voice()?; + let voices_list = tts.list_voices(); + println!("Available voices:\n==="); + for v in voices_list.iter() { + println!("{}",v); + tts.set_voice(v)?; + println!("voice set"); + println!("{}", tts.voice()?); + tts.speak(v,false)?; + } + tts.set_voice(original_voice)?; + } tts.speak("Goodbye.", false)?; let mut _input = String::new(); #[cfg(target_os = "macos")] diff --git a/src/backends/appkit.rs b/src/backends/appkit.rs index 164cf53..dd8caa3 100644 --- a/src/backends/appkit.rs +++ b/src/backends/appkit.rs @@ -204,7 +204,7 @@ impl Backend for AppKit { unimplemented!() } - fn set_voice(&mut self, voice: String) -> Result<(),Error> { + fn set_voice(&mut self, voice: &str) -> Result<(),Error> { unimplemented!() } } diff --git a/src/backends/av_foundation.rs b/src/backends/av_foundation.rs index c51988a..b5bfd32 100644 --- a/src/backends/av_foundation.rs +++ b/src/backends/av_foundation.rs @@ -150,7 +150,7 @@ impl Backend for AvFoundation { AVSpeechSynthesisVoice::list().iter().map(|v| {v.identifier()}).collect() } - fn set_voice(&mut self, voice: String) -> Result<(),Error> { + fn set_voice(&mut self, voice: &str) -> Result<(),Error> { self.voice = AVSpeechSynthesisVoice::new(voice); Ok(()) } diff --git a/src/backends/av_foundation/voices.rs b/src/backends/av_foundation/voices.rs index a23c14a..1f5b1d5 100644 --- a/src/backends/av_foundation/voices.rs +++ b/src/backends/av_foundation/voices.rs @@ -2,16 +2,19 @@ use objc::runtime::*; use objc::*; use core_foundation::array::CFArray; +use cocoa_foundation::foundation::NSString; +use cocoa_foundation::base::{nil,id}; use core_foundation::string::CFString; #[derive(Copy,Clone)] pub struct AVSpeechSynthesisVoice(*const Object); impl AVSpeechSynthesisVoice { - pub fn new(identifier: String) -> Self { - let i: CFString = CFString::from(identifier.as_str()); - let voice: *const Object = unsafe{msg_send![class!(AVSpeechSynthesisVoice).metaclass(), voiceWithIdentifier: i]}; - AVSpeechSynthesisVoice{0: voice} + pub fn new(identifier: &str) -> Self { + unsafe{ + let i: id = NSString::alloc(nil).init_str(identifier); + msg_send![class!(AVSpeechSynthesisVoice), voiceWithIdentifier:i] + } } pub fn default() -> Self { diff --git a/src/lib.rs b/src/lib.rs index 61a47ae..daebd23 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -102,7 +102,7 @@ pub trait Backend { fn is_speaking(&self) -> Result; fn voice(&self) -> Result; fn list_voices(&self) -> Vec; - fn set_voice(&mut self, voice: String) -> Result<(),Error>; + fn set_voice(&mut self, voice: &str) -> Result<(),Error>; } pub struct TTS(Box); @@ -399,13 +399,13 @@ impl TTS { /** * Set speaking voice. */ - pub fn set_voice(&mut self, voice: String) -> Result<(),Error> { + pub fn set_voice>(&mut self, voice: S) -> Result<(),Error> { let Features { voices: voices_feature, .. } = self.0.supported_features(); if voices_feature { - self.0.set_voice(voice) + self.0.set_voice(voice.into().as_str()) } else { Err(Error::UnsupportedFeature) }