• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2020 The Chromium OS Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 use std::error;
6 use std::fmt;
7 
8 use remain::sorted;
9 
10 use crate::control::{self, Control};
11 use crate::control_primitive;
12 use crate::control_primitive::{Ctl, ElemId, ElemIface};
13 use crate::control_tlv::{self, ControlTLV};
14 
15 pub type Result<T> = std::result::Result<T, Error>;
16 
17 #[sorted]
18 #[derive(Debug)]
19 /// Possible errors that can occur in cros-alsa::card.
20 pub enum Error {
21     /// Failed to call AlsaControlAPI.
22     AlsaControlAPI(control_primitive::Error),
23     /// Error occurs in Control.
24     Control(control::Error),
25     /// Error occurs in ControlTLV.
26     ControlTLV(control_tlv::Error),
27 }
28 
29 impl error::Error for Error {}
30 
31 impl From<control::Error> for Error {
from(err: control::Error) -> Error32     fn from(err: control::Error) -> Error {
33         Error::Control(err)
34     }
35 }
36 
37 impl From<control_tlv::Error> for Error {
from(err: control_tlv::Error) -> Error38     fn from(err: control_tlv::Error) -> Error {
39         Error::ControlTLV(err)
40     }
41 }
42 
43 impl From<control_primitive::Error> for Error {
from(err: control_primitive::Error) -> Error44     fn from(err: control_primitive::Error) -> Error {
45         Error::AlsaControlAPI(err)
46     }
47 }
48 
49 impl fmt::Display for Error {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result50     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
51         use Error::*;
52         match self {
53             AlsaControlAPI(e) => write!(f, "{}", e),
54             Control(e) => write!(f, "{}", e),
55             ControlTLV(e) => write!(f, "{}", e),
56         }
57     }
58 }
59 
60 /// `Card` represents a sound card.
61 #[derive(Debug)]
62 pub struct Card {
63     handle: Ctl,
64     name: String,
65 }
66 
67 impl Card {
68     /// Creates a `Card`.
69     ///
70     /// # Arguments
71     ///
72     /// * `card_name` - The sound card name, ex: sofcmlmax98390d.
73     ///
74     /// # Errors
75     ///
76     /// * If card_name is an invalid CString.
77     /// * If snd_ctl_open() fails.
new(card_name: &str) -> Result<Self>78     pub fn new(card_name: &str) -> Result<Self> {
79         let handle = Ctl::new(&format!("hw:{}", card_name))?;
80         Ok(Card {
81             name: card_name.to_owned(),
82             handle,
83         })
84     }
85 
86     /// Gets sound card name.
name(&self) -> &str87     pub fn name(&self) -> &str {
88         &self.name
89     }
90 
91     /// Creates a `Control` from control name.
92     ///
93     /// # Errors
94     ///
95     /// * If control name is an invalid CString.
96     /// * If control does not exist.
97     /// * If `Control` elem_type() mismatches the type of underlying mixer control.
98     /// * If `Control` size() mismatches the number of value entries of underlying mixer control.
control_by_name<'a, T: 'a>(&'a mut self, control_name: &str) -> Result<T> where T: Control<'a>,99     pub fn control_by_name<'a, T: 'a>(&'a mut self, control_name: &str) -> Result<T>
100     where
101         T: Control<'a>,
102     {
103         let id = ElemId::new(ElemIface::Mixer, control_name)?;
104         Ok(T::from(&mut self.handle, id)?)
105     }
106 
107     /// Creates a `ControlTLV` from control name.
108     ///
109     /// # Errors
110     ///
111     /// * If control name is an invalid CString.
112     /// * If control does not exist.
control_tlv_by_name<'a>(&'a mut self, control_name: &str) -> Result<ControlTLV<'a>>113     pub fn control_tlv_by_name<'a>(&'a mut self, control_name: &str) -> Result<ControlTLV<'a>> {
114         let id = ElemId::new(ElemIface::Mixer, control_name)?;
115         Ok(ControlTLV::new(&mut self.handle, id)?)
116     }
117 }
118