novel_tts/queue/queue_input.rs
1//! TTS队列输入端模块
2//!
3//! 该模块定义了TTS队列的输入端,允许向队列中添加音频片段。
4//! 输入端使用线程安全的结构,可以在多个线程中使用。
5
6use rodio::Source;
7use std::sync::{Mutex, atomic::AtomicBool};
8use tokio::sync::mpsc::Receiver;
9
10/// TTS队列输入端
11///
12/// 用于向TTS队列中添加音频片段。该结构是线程安全的,可以跨线程使用。
13///
14/// # 泛型参数
15/// * `T` - 音频源类型,必须实现Source、Send和Clone trait
16pub struct TTSQueueInput<T>
17where
18 T: Source + Send + Clone,
19{
20 /// 存储音频片段的向量,每个片段可以附带一个信号发送器
21 /// 使用Mutex保证线程安全
22 pub sounds: Mutex<Vec<(T, super::Signal)>>,
23
24 /// 标记队列是否已完成(不再添加新的音频片段)
25 /// 使用AtomicBool保证原子操作
26 pub is_finished: AtomicBool,
27}
28
29impl<T> TTSQueueInput<T>
30where
31 T: Source + Send + Clone,
32{
33 /// 向队列末尾添加一个音频片段
34 ///
35 /// # 参数
36 /// * `source` - 要添加的音频源
37 pub fn append(&self, source: T) {
38 // 锁定sounds向量并添加新的音频片段
39 // 信号发送器为None,表示不关心播放状态
40 self.sounds.lock().unwrap().push((source, None));
41 }
42
43 /// 向队列末尾添加一个带信号通知的音频片段
44 ///
45 /// 返回一个接收器,用于接收该音频片段的播放状态通知:
46 /// - false: 音频片段开始播放
47 /// - true: 音频片段播放完成
48 ///
49 /// # 参数
50 /// * `source` - 要添加的音频源
51 ///
52 /// # 返回值
53 /// * `Receiver<bool>` - 用于接收播放状态通知的接收器
54 pub fn append_with_signal(&self, source: T) -> Receiver<bool> {
55 // 创建一个容量为1的通道,用于发送播放状态信号
56 let (tx, rx) = tokio::sync::mpsc::channel(1);
57
58 // 锁定sounds向量并添加新的音频片段及信号发送器
59 self.sounds.lock().unwrap().push((source, Some(tx)));
60
61 rx
62 }
63
64 /// 设置队列完成状态
65 ///
66 /// 当设置为true时,表示不会再有新的音频片段添加到队列中
67 ///
68 /// # 参数
69 /// * `is_finished` - 完成状态标志
70 pub fn set_is_finished(&self, is_finished: bool) {
71 // 使用Release内存序存储完成状态
72 self.is_finished
73 .store(is_finished, std::sync::atomic::Ordering::Release);
74 }
75
76 /// 检查队列是否已完成
77 ///
78 /// # 返回值
79 /// * `bool` - 如果队列已完成返回true,否则返回false
80 pub fn is_finished(&self) -> bool {
81 // 使用Acquire内存序加载完成状态
82 self.is_finished.load(std::sync::atomic::Ordering::Acquire)
83 }
84}