-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathlib.rs
More file actions
197 lines (172 loc) · 5.34 KB
/
Copy pathlib.rs
File metadata and controls
197 lines (172 loc) · 5.34 KB
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
pub mod audio;
pub mod billing_collector;
mod billing_context;
mod conversation;
mod duration;
pub mod language;
mod protocol;
mod registry;
mod segment;
pub mod service;
pub mod speech_gate;
use std::time;
use anyhow::{Context, Result, bail};
use tokio::sync::mpsc::{self, UnboundedReceiver, UnboundedSender, unbounded_channel};
pub use billing_context::BillingContext;
pub use conversation::*;
pub use duration::Duration;
pub use protocol::*;
pub use registry::*;
pub use segment::*;
pub use service::Service;
/// A unidirectional audio message. Useful for implementing an audio transfer channel.
#[derive(Debug)]
pub enum AudioMsg {
Frame(AudioFrame),
Clear,
}
#[derive(Debug)]
pub struct AudioMsgConsumer {
receiver: UnboundedReceiver<AudioMsg>,
}
impl AudioMsgConsumer {
/// Consumes an audio message. If none is available, waits until there is one.
/// Returns None if the channel is closed.
pub async fn consume(&mut self) -> Option<AudioMsg> {
self.receiver.recv().await
}
/// Tries to consume an audio message without waiting.
/// Returns None if no message is available or if the channel is closed.
pub fn try_consume(&mut self) -> Option<AudioMsg> {
self.receiver.try_recv().ok()
}
}
#[derive(Debug)]
pub struct AudioMsgProducer {
format: AudioFormat,
sender: UnboundedSender<AudioMsg>,
}
impl AudioMsgProducer {
/// Sends raw audio samples
pub fn send_samples(&self, samples: Vec<i16>) -> Result<()> {
self.send_frame(AudioFrame {
format: self.format,
samples,
})
}
/// Sends an audio frame.
pub fn send_frame(&self, frame: AudioFrame) -> Result<()> {
if frame.format != self.format {
bail!(
"Audio frame format mismatch (expected: {:?}, received: {:?})",
self.format,
frame.format
);
}
Ok(self.sender.send(AudioMsg::Frame(frame))?)
}
/// Sends a clear message to remove all pending frames in the channel.
pub fn clear(&self) -> Result<()> {
Ok(self.sender.send(AudioMsg::Clear)?)
}
pub fn format(&self) -> AudioFormat {
self.format
}
}
/// TODO: Actually support AudioMsg::Clear to clear all the pending frames in the channel.
pub fn audio_msg_channel(format: AudioFormat) -> (AudioMsgProducer, AudioMsgConsumer) {
let (sender, receiver) = unbounded_channel();
(
AudioMsgProducer { format, sender },
AudioMsgConsumer { receiver },
)
}
#[derive(Debug)]
pub struct AudioConsumer {
pub format: AudioFormat,
pub receiver: mpsc::UnboundedReceiver<Vec<i16>>,
}
impl AudioConsumer {
/// Consumes an audio frame. If none is available, waits until there is one.
pub async fn consume(&mut self) -> Option<AudioFrame> {
self.receiver.recv().await.map(|samples| AudioFrame {
format: self.format,
samples,
})
}
}
// TODO: This might be overengineered, we probably are fine with `Sender<AudioFrame>` and
// `Receiver<AudioFrame>` without checking the format for which I guess the receiver is actually
// responsible, _and_ it might even okay for the receiver to receive different audio formats, e.g. in
// low QoS situations?
#[derive(Debug)]
pub struct AudioProducer {
pub format: AudioFormat,
pub sender: mpsc::UnboundedSender<Vec<i16>>,
}
impl AudioProducer {
pub fn produce(&self, frame: AudioFrame) -> Result<()> {
if frame.format != self.format {
bail!(
"Audio frame format mismatch (expected: {:?}, received: {:?})",
self.format,
frame.format
);
}
self.sender.send(frame.samples).context("Sending samples")?;
Ok(())
}
}
/// Create a unidirectional audio channel.
pub fn audio_channel(format: AudioFormat) -> (AudioProducer, AudioConsumer) {
let (producer, consumer) = mpsc::unbounded_channel();
(
AudioProducer {
format,
sender: producer,
},
AudioConsumer {
format,
receiver: consumer,
},
)
}
#[derive(Debug, Clone)]
pub struct AudioFrame {
pub format: AudioFormat,
pub samples: Vec<i16>,
}
impl AudioFrame {
pub fn from_le_bytes(format: AudioFormat, bytes: &[u8]) -> Self {
let samples = audio::from_le_bytes(bytes);
Self { format, samples }
}
pub fn to_le_bytes(&self) -> Vec<u8> {
audio::to_le_bytes(&self.samples)
}
pub fn duration(&self) -> time::Duration {
self.format.duration(self.samples.len())
}
pub fn into_mono(self) -> AudioFrame {
let format = self.format;
if format.channels == 1 {
return self;
}
let samples_per_channel = self.samples.len() / format.channels as usize;
let mut mono_samples = vec![0; samples_per_channel];
let channels_i32 = format.channels as i32;
(0..samples_per_channel).for_each(|i| {
mono_samples[i] = ((0..format.channels)
.map(|j| self.samples[i + j as usize * samples_per_channel] as i32)
.sum::<i32>()
/ channels_i32) as i16;
});
AudioFrame {
format: AudioFormat {
channels: 1,
sample_rate: format.sample_rate,
},
samples: mono_samples,
}
}
}