# eSpeak NG bindings for Rust ![Crates.io](https://img.shields.io/crates/v/espeakng-sys?style=flat) FFI bindings to the C library eSpeak NG for Rust Current eSpeak NG version: 1.51 ## Dependencies - [eSpeak NG](https://github.com/espeak-ng/espeak-ng/blob/master/docs/building.md) ## Example This example shows how you can convert a &str to a Vec ```rs #![allow(non_upper_case_globals)] use espeakng_sys::*; use std::os::raw::{c_char, c_short, c_int}; use std::ffi::{c_void, CString}; use std::cell::Cell; use lazy_static::lazy_static; use std::sync::{Mutex, MutexGuard}; /// The name of the voice to use const VOICE_NAME: &str = "English"; /// The length in mS of sound buffers passed to the SynthCallback function. const BUFF_LEN: i32 = 500; /// Options to set for espeak-ng const OPTIONS: i32 = 0; lazy_static! { /// The complete audio provided by the callback static ref AUDIO_RETURN: Mutex>> = Mutex::new(Cell::new(Vec::default())); /// Audio buffer for use in the callback static ref AUDIO_BUFFER: Mutex>> = Mutex::new(Cell::new(Vec::default())); } /// Spoken speech pub struct Spoken { /// The audio data pub wav: Vec, /// The sample rate of the audio pub sample_rate: i32 } /// Perform Text-To-Speech pub fn speak(text: &str) -> Spoken { let output: espeak_AUDIO_OUTPUT = espeak_AUDIO_OUTPUT_AUDIO_OUTPUT_RETRIEVAL; AUDIO_RETURN.plock().set(Vec::default()); AUDIO_BUFFER.plock().set(Vec::default()); // The directory which contains the espeak-ng-data directory, or NULL for the default location. let path: *const c_char = std::ptr::null(); let voice_name_cstr = CString::new(VOICE_NAME).expect("Failed to convert &str to CString"); let voice_name = voice_name_cstr.as_ptr(); // Returns: sample rate in Hz, or -1 (EE_INTERNAL_ERROR). let sample_rate = unsafe { espeak_Initialize(output, BUFF_LEN, path, OPTIONS) }; unsafe { espeak_SetVoiceByName(voice_name as *const c_char); espeak_SetSynthCallback(Some(synth_callback)) } let text_cstr = CString::new(text).expect("Failed to convert &str to CString"); let position = 0u32; let position_type: espeak_POSITION_TYPE = 0; let end_position = 0u32; let flags = espeakCHARS_AUTO; let identifier = std::ptr::null_mut(); let user_data = std::ptr::null_mut(); unsafe { espeak_Synth(text_cstr.as_ptr() as *const c_void, BUFF_LEN as size_t, position, position_type, end_position, flags, identifier, user_data); } // Wait for the speaking to complete match unsafe { espeak_Synchronize() } { espeak_ERROR_EE_OK => {}, espeak_ERROR_EE_INTERNAL_ERROR => { todo!() } _ => unreachable!() } let result = AUDIO_RETURN.plock().take(); Spoken { wav: result, sample_rate } } /// int SynthCallback(short *wav, int numsamples, espeak_EVENT *events); /// /// wav: is the speech sound data which has been produced. /// NULL indicates that the synthesis has been completed. /// /// numsamples: is the number of entries in wav. This number may vary, may be less than /// the value implied by the buflength parameter given in espeak_Initialize, and may /// sometimes be zero (which does NOT indicate end of synthesis). /// /// events: an array of espeak_EVENT items which indicate word and sentence events, and /// also the occurance if and