ds_transcriber/
config.rs

1//! Initialises recording device and audio stream's silence level
2use anyhow::{anyhow, Result};
3use cpal::{
4    traits::{DeviceTrait, HostTrait},
5    Device, SampleRate, SupportedStreamConfig,
6};
7use log::error;
8
9const SAMPLE_RATE: u32 = 16000;
10
11///
12/// # Input device configuration
13/// Gets data ready to begin recording
14
15pub(crate) struct StreamConfig {
16    device: Device,
17    config: SupportedStreamConfig,
18    silence_level: i32,
19}
20
21#[cfg(test)]
22mod tests {
23    use crate::config::get_config;
24    use cpal::traits::HostTrait;
25
26    #[test]
27    fn supported_device() {
28        let host = cpal::default_host();
29        let device = host.default_input_device().expect("no input device found");
30        assert_eq!(1, get_config(&device).unwrap().channels());
31    }
32}
33
34impl StreamConfig {
35    /// Creates a new stream configuration:
36    pub fn new(silence_level: i32) -> Result<Self> {
37        let device = get_default_device()?;
38        match get_config(&device) {
39            Ok(config) => Ok(StreamConfig {
40                config,
41                device,
42                silence_level,
43            }),
44            Err(e) => {
45                error!("{}", e);
46                Err(anyhow!(e))
47            }
48        }
49    }
50
51    /// Returns the device in use:
52    pub fn device(&self) -> &Device {
53        &self.device
54    }
55
56    /// Returns SupportedStreamConfig (.config() returns the configuration we use on our stream)
57    pub fn supported_config(&self) -> &SupportedStreamConfig {
58        &self.config
59    }
60
61    /// Returns the silence level
62    pub fn silence_level(&self) -> i32 {
63        self.silence_level
64    }
65}
66
67///Returns the configuration of the mono channel
68fn get_config(device: &Device) -> Result<SupportedStreamConfig> {
69    let mut config = device.default_input_config()?;
70    if config.channels() != 1 {
71        let mut supported_configs_range = device.supported_input_configs()?;
72        config = match supported_configs_range.next() {
73            Some(conf) => {
74                conf.with_sample_rate(SampleRate(SAMPLE_RATE)) //16K from deepspeech
75            }
76            None => config,
77        };
78    }
79    Ok(config)
80}
81fn get_default_device() -> Result<Device> {
82    let host = cpal::default_host();
83    match host.default_input_device() {
84        Some(device) => Ok(device),
85        None => Err(anyhow!("no input device found")),
86    }
87}