1use std::sync::Arc;
15
16use windows::{
17 core::HSTRING, Media::SpeechSynthesis::SpeechSynthesizer, Storage::Streams::DataReader,
18};
19
20#[derive(Clone, Debug)]
21pub struct Sapi5TtsSynthesizer {
22 synth: Arc<SpeechSynthesizer>,
23}
24
25impl Sapi5TtsSynthesizer {
26 pub fn new() -> Self {
30 let synth = SpeechSynthesizer::new().expect("Can't create the speech synthesizer.");
32 Self {
33 synth: synth.into(),
34 }
35 }
36
37 pub fn set_speed(&self, speed: f64) {
44 let options = self.synth.Options().unwrap();
45 options
46 .SetSpeakingRate(speed)
47 .expect("Can't set the speed value.");
48 }
49
50 pub fn set_pitch(&self, pitch: f64) {
52 let options = self.synth.Options().unwrap();
53 options
54 .SetAudioPitch(pitch)
55 .expect("Can't set the pitch value.");
56 }
57
58 pub fn set_volume(&self, volume: f64) {
60 let options = self.synth.Options().unwrap();
61 options
62 .SetAudioVolume(volume)
63 .expect("Can't set the volume value.");
64 }
65
66 pub fn get_voice_list(&self) -> Vec<(String, String)> {
70 let mut v: Vec<(String, String)> = vec![];
71 for x in SpeechSynthesizer::AllVoices().unwrap() {
72 v.push((
73 x.Id().unwrap().to_string(),
74 x.DisplayName().unwrap().to_string(),
75 ))
76 }
77 v
78 }
79
80 pub fn set_voice(&self, voice: String) {
85 for x in SpeechSynthesizer::AllVoices().unwrap() {
86 if x.Id().unwrap().to_string() == voice {
87 self.synth.SetVoice(&x).unwrap_or(());
88 return;
89 }
90 }
91 }
92
93 pub fn synth(&self, text: &str, recv: impl Fn(Vec<u8>) -> bool) -> Option<[u8; 44]> {
99 let Ok(stream) = self.synth.SynthesizeTextToStreamAsync(&HSTRING::from(text)) else {
100 return None;
101 };
102 let Ok(stream) = stream.get() else {
103 return None;
104 };
105
106 let Ok(size) = stream.Size() else {
107 return None;
108 };
109 let Ok(reader) = DataReader::CreateDataReader(&stream) else {
110 return None;
111 };
112 let _ = reader.LoadAsync(size as u32);
113
114 let mut head: [u8; 44] = [0; 44];
116 reader.ReadBytes(&mut head).unwrap();
117 let mut last_len = size as u32 - 44;
118 let mut buffer: [u8; 3200] = [0; 3200];
119 loop {
120 if reader.ReadBytes(&mut buffer).is_err() {
121 break;
122 }
123 match reader.UnconsumedBufferLength() {
124 Ok(len) if last_len != len => {
125 if !recv(buffer[0..(last_len - len) as usize].to_vec()) {
126 break;
127 }
128 last_len = len;
129 }
130 _ => continue,
131 }
132 }
133 Some(head)
134 }
135}
136
137#[cfg(test)]
138mod test_tts {
139 use crate::tts::Sapi5TtsSynthesizer;
140
141 #[test]
142 fn main() {
143 let synth = Sapi5TtsSynthesizer::new();
144 let (tx, rx) = std::sync::mpsc::channel();
145 synth.synth("你好呀,我们是一群追求梦想的人。", move |data| {
146 for i in data {
147 let _ = tx.send(i);
148 }
149 true
150 }).unwrap();
151 let v = rx.iter().collect::<Vec<_>>();
152 dbg!(v.len());
153 }
154}