mirror of https://github.com/ndarilek/tts-rs.git
Implement callbacks on AVFoundation.
This commit is contained in:
parent
bd57075d53
commit
251fb8d8c1
|
@ -6,13 +6,14 @@ use cocoa_foundation::base::{id, nil};
|
||||||
use cocoa_foundation::foundation::NSString;
|
use cocoa_foundation::foundation::NSString;
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use log::{info, trace};
|
use log::{info, trace};
|
||||||
use objc::runtime::*;
|
use objc::runtime::{Object, Sel};
|
||||||
use objc::*;
|
use objc::{class, declare::ClassDecl, msg_send, sel, sel_impl};
|
||||||
|
|
||||||
use crate::{Backend, BackendId, Error, Features, UtteranceId};
|
use crate::{Backend, BackendId, Error, Features, UtteranceId, CALLBACKS};
|
||||||
|
|
||||||
pub(crate) struct AvFoundation {
|
pub(crate) struct AvFoundation {
|
||||||
id: BackendId,
|
id: BackendId,
|
||||||
|
delegate: *mut Object,
|
||||||
synth: *mut Object,
|
synth: *mut Object,
|
||||||
rate: f32,
|
rate: f32,
|
||||||
volume: f32,
|
volume: f32,
|
||||||
|
@ -26,11 +27,71 @@ lazy_static! {
|
||||||
impl AvFoundation {
|
impl AvFoundation {
|
||||||
pub(crate) fn new() -> Self {
|
pub(crate) fn new() -> Self {
|
||||||
info!("Initializing AVFoundation backend");
|
info!("Initializing AVFoundation backend");
|
||||||
|
let mut decl = ClassDecl::new("MyNSSpeechSynthesizerDelegate", class!(NSObject)).unwrap();
|
||||||
|
decl.add_ivar::<u64>("backend_id");
|
||||||
|
|
||||||
|
extern "C" fn speech_synthesizer_did_start_speech_utterance(
|
||||||
|
this: &Object,
|
||||||
|
_: Sel,
|
||||||
|
synth: *const Object,
|
||||||
|
utterance: id,
|
||||||
|
) {
|
||||||
|
unsafe {
|
||||||
|
let backend_id: u64 = *this.get_ivar("backend_id");
|
||||||
|
let backend_id = BackendId::AvFoundation(backend_id);
|
||||||
|
let callbacks = CALLBACKS.lock().unwrap();
|
||||||
|
let callbacks = callbacks.get(&backend_id).unwrap();
|
||||||
|
if let Some(callback) = callbacks.utterance_begin {
|
||||||
|
let utterance_id = UtteranceId::AvFoundation(utterance);
|
||||||
|
callback(utterance_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" fn speech_synthesizer_did_finish_speech_utterance(
|
||||||
|
this: &Object,
|
||||||
|
_: Sel,
|
||||||
|
synth: *const Object,
|
||||||
|
utterance: id,
|
||||||
|
) {
|
||||||
|
unsafe {
|
||||||
|
let backend_id: u64 = *this.get_ivar("backend_id");
|
||||||
|
let backend_id = BackendId::AvFoundation(backend_id);
|
||||||
|
let callbacks = CALLBACKS.lock().unwrap();
|
||||||
|
let callbacks = callbacks.get(&backend_id).unwrap();
|
||||||
|
if let Some(callback) = callbacks.utterance_end {
|
||||||
|
let utterance_id = UtteranceId::AvFoundation(utterance);
|
||||||
|
callback(utterance_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
decl.add_method(
|
||||||
|
sel!(speechSynthesizer:didStartSpeechUtterance:),
|
||||||
|
speech_synthesizer_did_start_speech_utterance
|
||||||
|
as extern "C" fn(&Object, Sel, *const Object, id) -> (),
|
||||||
|
);
|
||||||
|
decl.add_method(
|
||||||
|
sel!(speechSynthesizer:didFinishSpeechUtterance:),
|
||||||
|
speech_synthesizer_did_finish_speech_utterance
|
||||||
|
as extern "C" fn(&Object, Sel, *const Object, id) -> (),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let delegate_class = decl.register();
|
||||||
|
let delegate_obj: *mut Object = unsafe { msg_send![delegate_class, new] };
|
||||||
let mut backend_id = NEXT_BACKEND_ID.lock().unwrap();
|
let mut backend_id = NEXT_BACKEND_ID.lock().unwrap();
|
||||||
let rv = unsafe {
|
let rv = unsafe {
|
||||||
let synth: *mut Object = msg_send![class!(AVSpeechSynthesizer), new];
|
let synth: *mut Object = msg_send![class!(AVSpeechSynthesizer), new];
|
||||||
|
delegate_obj
|
||||||
|
.as_mut()
|
||||||
|
.unwrap()
|
||||||
|
.set_ivar("backend_id", *backend_id);
|
||||||
|
let _: () = msg_send![synth, setDelegate: delegate_obj];
|
||||||
AvFoundation {
|
AvFoundation {
|
||||||
id: BackendId::AvFoundation(*backend_id),
|
id: BackendId::AvFoundation(*backend_id),
|
||||||
|
delegate: delegate_obj,
|
||||||
synth: synth,
|
synth: synth,
|
||||||
rate: 0.5,
|
rate: 0.5,
|
||||||
volume: 1.,
|
volume: 1.,
|
||||||
|
@ -157,6 +218,7 @@ impl Backend for AvFoundation {
|
||||||
impl Drop for AvFoundation {
|
impl Drop for AvFoundation {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
let _: Object = msg_send![self.delegate, release];
|
||||||
let _: Object = msg_send![self.synth, release];
|
let _: Object = msg_send![self.synth, release];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue