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
|
use cpal::traits::{DeviceTrait, HostTrait, StreamTrait};
use cpal::{InputCallbackInfo, Sample, SampleFormat, SampleRate, StreamConfig};
use log::*;
use tokio::sync::watch;
use crate::audio::SAMPLE_RATE;
use crate::error::{AudioError, AudioStream};
use crate::state::StatePhase;
pub fn callback<T: Sample>(
mut input_sender: futures_channel::mpsc::Sender<f32>,
input_volume_receiver: watch::Receiver<f32>,
phase_watcher: watch::Receiver<StatePhase>,
) -> impl FnMut(&[T], &InputCallbackInfo) + Send + 'static {
move |data: &[T], _info: &InputCallbackInfo| {
if !matches!(&*phase_watcher.borrow(), StatePhase::Connected(_)) {
return;
}
let input_volume = *input_volume_receiver.borrow();
for sample in data.iter().map(|e| e.to_f32()).map(|e| e * input_volume) {
if let Err(_e) = input_sender.try_send(sample) {
warn!("Error sending audio: {}", _e);
}
}
}
}
pub trait AudioInputDevice {
fn play(&self) -> Result<(), AudioError>;
fn pause(&self) -> Result<(), AudioError>;
fn set_volume(&self, volume: f32);
fn sample_receiver(&mut self) -> futures_channel::mpsc::Receiver<f32>;
fn num_channels(&self) -> usize;
}
pub struct DefaultAudioInputDevice {
stream: cpal::Stream,
sample_receiver: Option<futures_channel::mpsc::Receiver<f32>>,
volume_sender: watch::Sender<f32>,
channels: u16,
}
impl DefaultAudioInputDevice {
pub fn new(
input_volume: f32,
phase_watcher: watch::Receiver<StatePhase>,
) -> Result<Self, AudioError> {
let sample_rate = SampleRate(SAMPLE_RATE);
let host = cpal::default_host();
let input_device = host
.default_input_device()
.ok_or(AudioError::NoDevice(AudioStream::Input))?;
let input_supported_config = input_device
.supported_input_configs()
.map_err(|e| AudioError::NoConfigs(AudioStream::Input, e))?
.find_map(|c| {
if c.min_sample_rate() <= sample_rate && c.max_sample_rate() >= sample_rate {
Some(c)
} else {
None
}
})
.ok_or(AudioError::NoSupportedConfig(AudioStream::Input))?
.with_sample_rate(sample_rate);
let input_supported_sample_format = input_supported_config.sample_format();
let input_config: StreamConfig = input_supported_config.into();
let err_fn = |err| error!("An error occurred on the output audio stream: {}", err);
let (sample_sender, sample_receiver) = futures_channel::mpsc::channel(1_000_000);
let (volume_sender, input_volume_receiver) = watch::channel::<f32>(input_volume);
let input_stream = match input_supported_sample_format {
SampleFormat::F32 => input_device.build_input_stream(
&input_config,
callback::<f32>(sample_sender, input_volume_receiver, phase_watcher),
err_fn,
),
SampleFormat::I16 => input_device.build_input_stream(
&input_config,
callback::<i16>(sample_sender, input_volume_receiver, phase_watcher),
err_fn,
),
SampleFormat::U16 => input_device.build_input_stream(
&input_config,
callback::<u16>(sample_sender, input_volume_receiver, phase_watcher),
err_fn,
),
}
.map_err(|e| AudioError::InvalidStream(AudioStream::Input, e))?;
let res = Self {
stream: input_stream,
sample_receiver: Some(sample_receiver),
volume_sender,
channels: input_config.channels,
};
Ok(res)
}
}
impl AudioInputDevice for DefaultAudioInputDevice {
fn play(&self) -> Result<(), AudioError> {
self.stream
.play()
.map_err(|e| AudioError::InputPlayError(e))
}
fn pause(&self) -> Result<(), AudioError> {
self.stream
.pause()
.map_err(|e| AudioError::InputPauseError(e))
}
fn set_volume(&self, volume: f32) {
self.volume_sender.send(volume).unwrap();
}
fn sample_receiver(&mut self) -> futures_channel::mpsc::Receiver<f32> {
let ret = self.sample_receiver.take();
ret.unwrap()
}
fn num_channels(&self) -> usize {
self.channels as usize
}
}
|