use std::ffi::{CStr, CString};
use std::os::raw::{c_char, c_int, c_void};
#[link(name = "espeak-ng")]
extern "C" {
fn espeak_Initialize(
output: c_int,
buflength: c_int,
path: *const c_char,
options: c_int,
) -> c_int;
fn espeak_SetVoiceByName(name: *const c_char) -> c_int;
fn espeak_TextToPhonemes(
textptr: *const *const c_void,
textmode: c_int,
phonememode: c_int,
) -> *const c_char;
fn espeak_Terminate() -> c_int;
}
#[allow(dead_code)]
const AUDIO_OUTPUT_SYNCHRONOUS: c_int = 0x01;
const AUDIO_OUTPUT_RETRIEVAL: c_int = 0x02;
const ESPEAK_PHONEMES_IPA: c_int = 0x02;
const ESPEAK_CHARS_UTF8: c_int = 1;
pub fn test_espeak() -> Result<(), Box<dyn std::error::Error>> {
println!("Testing espeak-ng FFI for G2P conversion");
unsafe {
let init_result = espeak_Initialize(AUDIO_OUTPUT_RETRIEVAL, 0, std::ptr::null(), 0);
if init_result < 0 {
return Err("Failed to initialize espeak-ng".into());
}
let voice_name = CString::new("en")?;
espeak_SetVoiceByName(voice_name.as_ptr());
let test_words = vec!["hello", "world", "a", "i", "I", "the", "cat", "apple"];
for word in test_words {
println!("\nTesting word: '{}'", word);
let c_text = CString::new(word)?;
let mut text_ptr = c_text.as_ptr() as *const c_void;
let phonemes_ptr =
espeak_TextToPhonemes(&mut text_ptr, ESPEAK_CHARS_UTF8, ESPEAK_PHONEMES_IPA);
if !phonemes_ptr.is_null() {
let phonemes = CStr::from_ptr(phonemes_ptr).to_string_lossy();
println!(" IPA: {}", phonemes);
} else {
println!(" Failed to get phonemes");
}
}
espeak_Terminate();
}
Ok(())
}