|
1 | 1 | use crate::audio::{SampleFormat, SpeechResult}; |
2 | 2 | use crate::metadata::{BrailleBackendMetadata, SpeechSynthesizerMetadata, Voice}; |
3 | | -use std::ffi::{c_char, c_uchar, c_uint, CString}; |
| 3 | +use crate::{initialize, list_voices}; |
| 4 | +use std::ffi::{c_char, c_uchar, c_uint, CStr, CString}; |
4 | 5 | pub type WhisprsSampleFormat = SampleFormat; |
5 | 6 | #[repr(C)] |
6 | 7 | pub struct WhisprsSpeechResult { |
@@ -114,3 +115,45 @@ impl Drop for WhisprsVoice { |
114 | 115 | } |
115 | 116 | } |
116 | 117 | } |
| 118 | +unsafe fn optional_c_string_to_rust(string: &*const c_char) -> Option<&str> { |
| 119 | + if string.is_null() { |
| 120 | + None |
| 121 | + } else { |
| 122 | + Some(CStr::from_ptr(*string).to_str().unwrap()) |
| 123 | + } |
| 124 | +} |
| 125 | +#[unsafe(no_mangle)] |
| 126 | +pub unsafe extern "C" fn whisprs_initialize() { |
| 127 | + initialize().unwrap(); |
| 128 | +} |
| 129 | +#[unsafe(no_mangle)] |
| 130 | +pub unsafe extern "C" fn whisprs_list_voices( |
| 131 | + synthesizer: *const c_char, |
| 132 | + name: *const c_char, |
| 133 | + language: *const c_char, |
| 134 | + needs_audio_data: bool, |
| 135 | + voices_ptr: *mut *mut *mut WhisprsVoice, |
| 136 | + voices_len: *mut usize, |
| 137 | +) { |
| 138 | + let synthesizer = optional_c_string_to_rust(&synthesizer); |
| 139 | + let name = optional_c_string_to_rust(&name); |
| 140 | + let language = optional_c_string_to_rust(&language); |
| 141 | + let voices: Vec<*mut WhisprsVoice> = list_voices(synthesizer, name, language, needs_audio_data) |
| 142 | + .unwrap() |
| 143 | + .into_iter() |
| 144 | + .map(|voice| Box::into_raw(Box::new(voice.into()))) |
| 145 | + .collect(); |
| 146 | + *voices_len = voices.len(); |
| 147 | + let mut voices = voices.into_boxed_slice(); |
| 148 | + *voices_ptr = voices.as_mut_ptr(); |
| 149 | + std::mem::forget(voices); |
| 150 | +} |
| 151 | +#[unsafe(no_mangle)] |
| 152 | +pub unsafe extern "C" fn whisprs_free_voice_list( |
| 153 | + voices: *mut *mut WhisprsVoice, |
| 154 | + voices_len: usize, |
| 155 | +) { |
| 156 | + let voices = std::slice::from_raw_parts_mut(voices, voices_len); |
| 157 | + let voices = Box::from_raw(std::ptr::from_mut::<[*mut WhisprsVoice]>(voices)); |
| 158 | + let _voices: Vec<Box<WhisprsVoice>> = voices.iter().map(|ptr| Box::from_raw(*ptr)).collect(); |
| 159 | +} |
0 commit comments