mirror of
https://github.com/ndarilek/tts-rs.git
synced 2024-11-25 13:29:38 +00:00
FFI: Implement tts_speak()
The tts_speak() function has an additional parameter that, if not NULL, will be filled with a pointer to an UtteranceId. If this is specified, the caller must also call tts_free_utterance() to deallocate the UtteranceId when they're done with it.
This commit is contained in:
parent
c0f9250099
commit
98bfc10d41
52
src/ffi.rs
52
src/ffi.rs
|
@ -1,11 +1,11 @@
|
||||||
use libc::c_char;
|
use libc::c_char;
|
||||||
use std::{
|
use std::{
|
||||||
cell::RefCell,
|
cell::RefCell,
|
||||||
ffi::{CString, NulError},
|
ffi::{CStr, CString, NulError},
|
||||||
ptr,
|
ptr,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{Backends, Features, TTS};
|
use crate::{Backends, Features, UtteranceId, TTS};
|
||||||
|
|
||||||
thread_local! {
|
thread_local! {
|
||||||
/// Stores the last reported error, so it can be retrieved at will from C
|
/// Stores the last reported error, so it can be retrieved at will from C
|
||||||
|
@ -19,7 +19,7 @@ fn set_last_error<E: Into<Vec<u8>>>(err: E) -> Result<(), NulError> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the last reported error as a const C string (const char*)
|
/// Get the last reported error as a const C string.
|
||||||
/// This string will be valid until at least the next call to `tts_get_error`.
|
/// This string will be valid until at least the next call to `tts_get_error`.
|
||||||
/// It is never called internally by the library.
|
/// It is never called internally by the library.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
@ -84,3 +84,49 @@ pub extern "C" fn tts_free(tts: *mut TTS) {
|
||||||
pub extern "C" fn tts_supported_features(tts: *mut TTS) -> Features {
|
pub extern "C" fn tts_supported_features(tts: *mut TTS) -> Features {
|
||||||
unsafe { tts.as_ref().unwrap().supported_features() }
|
unsafe { tts.as_ref().unwrap().supported_features() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Speaks the specified text, optionally interrupting current speech.
|
||||||
|
/// If `utterance` is not NULL, , fills it with a pointer to the returned UtteranceId (or NULL if
|
||||||
|
/// the backend doesn't provide one).
|
||||||
|
/// Returns true on success, false on error or if `tts` is NULL.
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn tts_speak(
|
||||||
|
tts: *mut TTS,
|
||||||
|
text: *const c_char,
|
||||||
|
interrupt: bool,
|
||||||
|
utterance: *mut *mut UtteranceId,
|
||||||
|
) -> bool {
|
||||||
|
if tts.is_null() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
unsafe {
|
||||||
|
let text = CStr::from_ptr(text).to_string_lossy().into_owned();
|
||||||
|
match tts.as_mut().unwrap().speak(text, interrupt) {
|
||||||
|
Ok(u) => {
|
||||||
|
if !utterance.is_null() {
|
||||||
|
*utterance = match u {
|
||||||
|
Some(u) => Box::into_raw(Box::new(u)),
|
||||||
|
None => ptr::null_mut(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
set_last_error(e.to_string()).unwrap();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Free the memory associated with an `UtteranceId`.
|
||||||
|
/// Does nothing if `utterance` is NULL.
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn tts_free_utterance(utterance: *mut UtteranceId) {
|
||||||
|
if utterance.is_null() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
unsafe {
|
||||||
|
Box::from_raw(utterance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user