Skip to main content

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}