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?
This commit is contained in:
François Caddet 2020-09-04 15:48:56 +02:00
parent 6ed94686f3
commit 0fb6c62d83
5 changed files with 26 additions and 9 deletions

View File

@ -47,6 +47,20 @@ fn main() -> Result<(), Error> {
tts.speak("This is normal volume.", false)?; tts.speak("This is normal volume.", false)?;
tts.set_volume(original_volume)?; 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)?; tts.speak("Goodbye.", false)?;
let mut _input = String::new(); let mut _input = String::new();
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]

View File

@ -204,7 +204,7 @@ impl Backend for AppKit {
unimplemented!() unimplemented!()
} }
fn set_voice(&mut self, voice: String) -> Result<(),Error> { fn set_voice(&mut self, voice: &str) -> Result<(),Error> {
unimplemented!() unimplemented!()
} }
} }

View File

@ -150,7 +150,7 @@ impl Backend for AvFoundation {
AVSpeechSynthesisVoice::list().iter().map(|v| {v.identifier()}).collect() 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); self.voice = AVSpeechSynthesisVoice::new(voice);
Ok(()) Ok(())
} }

View File

@ -2,16 +2,19 @@
use objc::runtime::*; use objc::runtime::*;
use objc::*; use objc::*;
use core_foundation::array::CFArray; use core_foundation::array::CFArray;
use cocoa_foundation::foundation::NSString;
use cocoa_foundation::base::{nil,id};
use core_foundation::string::CFString; use core_foundation::string::CFString;
#[derive(Copy,Clone)] #[derive(Copy,Clone)]
pub struct AVSpeechSynthesisVoice(*const Object); pub struct AVSpeechSynthesisVoice(*const Object);
impl AVSpeechSynthesisVoice { impl AVSpeechSynthesisVoice {
pub fn new(identifier: String) -> Self { pub fn new(identifier: &str) -> Self {
let i: CFString = CFString::from(identifier.as_str()); unsafe{
let voice: *const Object = unsafe{msg_send![class!(AVSpeechSynthesisVoice).metaclass(), voiceWithIdentifier: i]}; let i: id = NSString::alloc(nil).init_str(identifier);
AVSpeechSynthesisVoice{0: voice} msg_send![class!(AVSpeechSynthesisVoice), voiceWithIdentifier:i]
}
} }
pub fn default() -> Self { pub fn default() -> Self {

View File

@ -102,7 +102,7 @@ pub trait Backend {
fn is_speaking(&self) -> Result<bool, Error>; fn is_speaking(&self) -> Result<bool, Error>;
fn voice(&self) -> Result<String, Error>; fn voice(&self) -> Result<String, Error>;
fn list_voices(&self) -> Vec<String>; fn list_voices(&self) -> Vec<String>;
fn set_voice(&mut self, voice: String) -> Result<(),Error>; fn set_voice(&mut self, voice: &str) -> Result<(),Error>;
} }
pub struct TTS(Box<dyn Backend>); pub struct TTS(Box<dyn Backend>);
@ -399,13 +399,13 @@ impl TTS {
/** /**
* Set speaking voice. * Set speaking voice.
*/ */
pub fn set_voice(&mut self, voice: String) -> Result<(),Error> { pub fn set_voice<S: Into<String>>(&mut self, voice: S) -> Result<(),Error> {
let Features { let Features {
voices: voices_feature, voices: voices_feature,
.. ..
} = self.0.supported_features(); } = self.0.supported_features();
if voices_feature { if voices_feature {
self.0.set_voice(voice) self.0.set_voice(voice.into().as_str())
} else { } else {
Err(Error::UnsupportedFeature) Err(Error::UnsupportedFeature)
} }