1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
//! # espeak-ng-rs
//!
//! A pure-Rust port of [eSpeak NG](https://github.com/espeak-ng/espeak-ng)
//! text-to-speech.
//!
//! The crate can be used as a **drop-in replacement** for the C library
//! (`libespeak-ng`) from Rust code. The mapping is:
//!
//! | C function | Rust equivalent |
//! |---|---|
//! | `espeak_ng_Initialize()` | [`EspeakNg::new()`] |
//! | `espeak_ng_SetVoiceByName()` | [`EspeakNg::set_voice()`] |
//! | `espeak_ng_SetParameter()` | [`EspeakNg::set_parameter()`] |
//! | `espeak_ng_Synthesize()` | [`EspeakNg::synth()`] |
//! | `espeak_TextToPhonemes()` | [`EspeakNg::text_to_phonemes()`] |
//! | `espeak_ng_GetSampleRate()` | [`EspeakNg::sample_rate()`] |
//! | `espeak_ng_Terminate()` | `drop(engine)` |
//!
//! ## Quick start
//!
//! ```rust,no_run
//! use espeak_ng::EspeakNg;
//!
//! // Initialise (equivalent to espeak_ng_Initialize + espeak_ng_SetVoiceByName)
//! let engine = EspeakNg::new("en")?;
//!
//! // Text → IPA phonemes
//! let ipa = engine.text_to_phonemes("hello world")?;
//! assert_eq!(ipa, "hɛlˈəʊ wˈɜːld");
//!
//! // Text → 22 050 Hz PCM
//! let (samples, rate) = engine.synth("hello world")?;
//! assert_eq!(rate, 22050);
//! # Ok::<(), espeak_ng::Error>(())
//! ```
//!
//! ## Convenience functions
//!
//! For one-shot calls that don't need a persistent engine:
//!
//! ```rust,no_run
//! // Text → IPA string
//! let ipa = espeak_ng::text_to_ipa("en", "hello world")?;
//!
//! // Text → PCM samples + sample rate
//! let (samples, rate) = espeak_ng::text_to_pcm("en", "hello")?;
//! # Ok::<(), espeak_ng::Error>(())
//! ```
//!
//! ## Module overview
//!
//! | Module | Purpose |
//! |---|---|
//! | (crate root) | [`EspeakNg`] engine, convenience functions |
//! | [`encoding`] | UTF-8 / ISO-8859-* / KOI8-R / ISCII decode |
//! | [`phoneme`] | Binary phoneme table loader and IPA scanner |
//! | [`dictionary`] | Dictionary lookup and rule-based translation |
//! | [`translate`] | Full text → phoneme code → IPA pipeline |
//! | [`synthesize`] | Harmonic formant synthesizer → PCM |
//! | [`oracle`] | C library FFI (feature = `c-oracle`) |
// ---------------------------------------------------------------------------
// Modules
// ---------------------------------------------------------------------------
pub use ipa_table;
/// C library oracle for comparison testing and benchmarking.
///
/// Only compiled when the `c-oracle` feature is active.
/// Links `libespeak-ng` via FFI and exposes the original C functions
/// alongside equivalent Rust implementations for A/B comparison.
// ---------------------------------------------------------------------------
// Bundled data (feature = "bundled-data")
// ---------------------------------------------------------------------------
/// Install all bundled eSpeak NG data files into `dest_dir`.
///
/// Only available when the `bundled-data` Cargo feature is enabled. The
/// three data sub-crates (`espeak-ng-data-phonemes`, `espeak-ng-data-dict-ru`,
/// `espeak-ng-data-dicts`) embed every data file at compile time; this
/// function extracts them to a user-supplied directory so the engine can
/// read them.
///
/// The call is **idempotent** — running it multiple times on the same
/// directory is safe (files are simply overwritten).
///
/// # Example
///
/// ```rust,no_run
/// # #[cfg(feature = "bundled-data")]
/// # {
/// use std::path::PathBuf;
///
/// let data_dir = PathBuf::from("/tmp/my-espeak-data");
/// std::fs::create_dir_all(&data_dir).unwrap();
/// espeak_ng::install_bundled_data(&data_dir).unwrap();
///
/// let engine = espeak_ng::EspeakNg::with_data_dir(&data_dir, "en").unwrap();
/// let ipa = engine.text_to_phonemes("hello world").unwrap();
/// # }
/// ```
///
/// # Errors
/// Returns an [`std::io::Error`] if a directory cannot be created or a
/// file cannot be written.
pub use ;
// ---------------------------------------------------------------------------
// Re-exports – top-level public API
// ---------------------------------------------------------------------------
pub use ;
/// Text encoding enum and decoder.
///
/// Re-exported from [`encoding`] for convenience.
pub use ;
/// Phoneme data types.
///
/// Re-exported from [`phoneme`] for convenience.
pub use ;
/// Text translator.
///
/// Re-exported from [`translate`] for convenience.
pub use ;
/// Synthesizer and voice parameters.
///
/// Re-exported from [`synthesize`] for convenience.
pub use ;
/// Main TTS engine — drop-in replacement for the C library session.
///
/// Re-exported from [`engine`] for convenience.
pub use ;
// ---------------------------------------------------------------------------
// Convenience functions
// ---------------------------------------------------------------------------
/// Convert text to an IPA phoneme string.
///
/// One-shot convenience wrapper around [`EspeakNg::text_to_phonemes`].
/// Equivalent to running:
///
/// ```shell
/// espeak-ng -v <lang> -q --ipa "<text>"
/// ```
///
/// Uses the default espeak-ng data directory (`/usr/share/espeak-ng-data`
/// or the `ESPEAK_DATA_PATH` environment variable).
///
/// # Errors
/// - [`Error::VoiceNotFound`] — the language data files are missing.
/// - [`Error::InvalidData`] — the dictionary or phoneme tables are corrupt.
///
/// # Example
/// ```rust,no_run
/// // English
/// assert_eq!(espeak_ng::text_to_ipa("en", "hello world")?, "hɛlˈəʊ wˈɜːld");
/// assert_eq!(espeak_ng::text_to_ipa("en", "42")?, "fˈɔːti tˈuː");
/// assert_eq!(espeak_ng::text_to_ipa("en", "walked")?, "wˈɔːkt");
///
/// // German
/// assert_eq!(espeak_ng::text_to_ipa("de", "schön")?, "ʃˈøːn");
///
/// // French
/// assert_eq!(espeak_ng::text_to_ipa("fr", "bonjour")?, "bɔ̃ʒˈuːɹ");
/// # Ok::<(), espeak_ng::Error>(())
/// ```
/// Synthesize text to raw 16-bit PCM audio at 22 050 Hz (mono).
///
/// One-shot convenience wrapper around [`EspeakNg::synth`].
/// Uses the real espeak-ng binary acoustic data (phondata / phonindex /
/// phontab) for authentic eSpeak NG sound quality.
///
/// Returns `(samples, sample_rate)` where `sample_rate` is always 22 050 Hz.
///
/// # Errors
/// - [`Error::VoiceNotFound`] — the phoneme data files are missing.
/// - [`Error::InvalidData`] — the phondata binary is corrupt.
///
/// # Example
/// ```rust,no_run
/// let (samples, rate) = espeak_ng::text_to_pcm("en", "hello world")?;
/// assert_eq!(rate, 22050);
/// assert!(!samples.is_empty());
/// # Ok::<(), espeak_ng::Error>(())
/// ```