summaryrefslogtreecommitdiff
path: root/cros_alsa/src/control.rs
diff options
context:
space:
mode:
Diffstat (limited to 'cros_alsa/src/control.rs')
-rw-r--r--cros_alsa/src/control.rs297
1 files changed, 0 insertions, 297 deletions
diff --git a/cros_alsa/src/control.rs b/cros_alsa/src/control.rs
deleted file mode 100644
index 2bc90256..00000000
--- a/cros_alsa/src/control.rs
+++ /dev/null
@@ -1,297 +0,0 @@
-// Copyright 2020 The Chromium OS Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-//! `control` module is meant to provide easier to use and more type safe abstractions
-//! for various alsa mixer controls.
-//!
-//! Each mixer control should implement the `Control` trait to allow itself to be created by `Card`.
-//! Each mixer control could hold `Ctl` as handle and `ElemID` as id and use `#[derive(ControlOps)]` macro
-//! to generate default load / save implementations of the `ControlOps` trait which allows itself to read and
-//! write the underlying hardware.
-//!
-//! # Examples
-//! This is an example of how to define a `SwitchControl`.
-//!
-//! ```
-//! use std::error::Error;
-//!
-//! use cros_alsa::{Ctl, ElemId, Control, ControlError, ControlOps};
-//! use cros_alsa::elem::Elem;
-//!
-//! type Result<T> = std::result::Result<T, ControlError>;
-//!
-//! #[derive(ControlOps)]
-//! pub struct SwitchControl<'a> {
-//! // Must hold `Ctl` as handle and `ElemID` as id to use `#[derive(ControlOps)]`.
-//! handle: &'a mut Ctl,
-//! id: ElemId,
-//! }
-//!
-//! impl<'a> Control<'a> for SwitchControl <'a> {
-//! type Item = [bool; 1];
-//!
-//! fn new(handle: &'a mut Ctl, id: ElemId) -> Self {
-//! Self {
-//! handle,
-//! id,
-//! }
-//! }
-//! }
-//!
-//! impl<'a> SwitchControl<'a> {
-//! /// Reads the state of a switch type mix control.
-//! pub fn state(&mut self) -> Result<bool> {
-//! // Uses ControlOps::load() to read the mixer control.
-//! let v = self.load()?;
-//! Ok(v[0])
-//! }
-//!
-//! /// Updates the control state to true.
-//! pub fn on(&mut self) -> Result<()> {
-//! // Uses ControlOps::save() to write the mixer control.
-//! self.save([true])?;
-//! Ok(())
-//! }
-//! }
-//!
-//! ```
-
-use std::error;
-use std::fmt;
-
-use cros_alsa_derive::ControlOps;
-use remain::sorted;
-
-use crate::control_primitive::{self, Ctl, ElemId, ElemInfo, ElemType};
-use crate::elem::{self, Elem};
-
-/// The Result type of cros-alsa::control.
-pub type Result<T> = std::result::Result<T, Error>;
-
-#[sorted]
-#[derive(Debug)]
-/// Possible errors that can occur in cros-alsa::control.
-pub enum Error {
- /// Failed to call AlsaControlAPI.
- AlsaControlAPI(control_primitive::Error),
- /// Error occurs in Elem.
- Elem(elem::Error),
- /// Elem::size() does not match the element count of the mixer control.
- MismatchElemCount(String, usize, usize),
- /// Elem::elem_type() does not match the data type of the mixer control.
- MismatchElemType(String, ElemType, ElemType),
-}
-
-impl error::Error for Error {}
-
-impl From<control_primitive::Error> for Error {
- fn from(err: control_primitive::Error) -> Error {
- Error::AlsaControlAPI(err)
- }
-}
-
-impl From<elem::Error> for Error {
- fn from(err: elem::Error) -> Error {
- Error::Elem(err)
- }
-}
-
-impl fmt::Display for Error {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- use Error::*;
- match self {
- AlsaControlAPI(e) => write!(f, "{}", e),
- Elem(e) => write!(f, "{}", e),
- MismatchElemCount(name, count, elem_count) => write!(
- f,
- "invalid `Control::size()` of {}: expect: {}, get: {}",
- name, count, elem_count
- ),
- MismatchElemType(name, t, elem_type) => write!(
- f,
- "invalid `Control::elem_type()` of {}: expect: {}, get: {}",
- name, t, elem_type
- ),
- }
- }
-}
-
-/// Each mixer control should implement the `Control` trait to allow itself to be created by `Card`.
-pub trait Control<'a>: Sized + 'a {
- /// The data type of the mixer control.
- /// Use `ElemType::load()` and `ElemType::save()` to read or write the mixer control.
- type Item: Elem;
-
- /// Called by `Self::from(handle: &'a mut Ctl, id: ElemId)` to create a `Control`.
- fn new(handle: &'a mut Ctl, id: ElemId) -> Self;
- /// Called by `Card` to create a `Control`.
- fn from(handle: &'a mut Ctl, id: ElemId) -> Result<Self> {
- let info = ElemInfo::new(handle, &id)?;
- if info.elem_type()? != Self::elem_type() {
- return Err(Error::MismatchElemType(
- id.name()?.to_owned(),
- info.elem_type()?,
- Self::elem_type(),
- ));
- }
-
- if info.count() != Self::size() {
- return Err(Error::MismatchElemCount(
- id.name()?.to_owned(),
- info.count(),
- Self::size(),
- ));
- }
-
- Ok(Self::new(handle, id))
- }
- /// Called by `Self::from(handle: &'a mut Ctl, id: ElemId)` to validate the data type of a
- /// `Control`.
- fn elem_type() -> ElemType {
- Self::Item::elem_type()
- }
- /// Called by `Self::from(handle: &'a mut Ctl, id: ElemId)` to validate the number of value
- /// entries of a `Control`.
- fn size() -> usize {
- Self::Item::size()
- }
-}
-
-/// Each mixer control could implement the `ControlOps` trait to allow itself to read and
-/// write the underlying hardware`. Users could hold `Ctl` and `ElemID` as `handle` and `id`
-/// in their control structure and use `#[derive(ControlOps)]` macro to generate default
-/// load / save implementations.
-pub trait ControlOps<'a>: Control<'a> {
- /// Reads the values of the mixer control.
- fn load(&mut self) -> Result<<Self as Control<'a>>::Item>;
- /// Saves the values to the mixer control.
- fn save(&mut self, val: <Self as Control<'a>>::Item) -> Result<bool>;
-}
-
-/// `Control` that reads and writes a single integer value entry.
-/// Since this crate is the `cros_alsa` crate, we replace the `cros_alsa`
-/// path to `crate` in derive macros by `cros_alsa` attribute.
-#[derive(ControlOps)]
-#[cros_alsa(path = "crate")]
-pub struct IntControl<'a> {
- handle: &'a mut Ctl,
- id: ElemId,
-}
-
-impl<'a> IntControl<'a> {
- /// Gets an i32 value from the mixer control.
- ///
- /// # Errors
- ///
- /// * If it fails to read from the control.
- pub fn get(&mut self) -> Result<i32> {
- let val = self.load()?;
- Ok(val[0])
- }
-
- /// Updates an i32 value to the mixer control.
- ///
- /// # Errors
- ///
- /// * If it fails to write to the control.
- pub fn set(&mut self, val: i32) -> Result<()> {
- self.save([val])?;
- Ok(())
- }
-}
-
-impl<'a> Control<'a> for IntControl<'a> {
- type Item = [i32; 1];
- fn new(handle: &'a mut Ctl, id: ElemId) -> Self {
- Self { handle, id }
- }
-}
-
-/// Stereo Volume Mixer Control
-/// Since this crate is the `cros_alsa` crate, we replace the `cros_alsa`
-/// path to `crate` in derive macros by `cros_alsa` attribute.
-#[derive(ControlOps)]
-#[cros_alsa(path = "crate")]
-pub struct StereoVolumeControl<'a> {
- handle: &'a mut Ctl,
- id: ElemId,
-}
-
-impl<'a> StereoVolumeControl<'a> {
- /// Reads the left and right volume.
- ///
- /// # Errors
- ///
- /// * If it fails to read from the control.
- pub fn volume(&mut self) -> Result<(i32, i32)> {
- let val = self.load()?;
- Ok((val[0], val[1]))
- }
-
- /// Updates the left and right volume.
- ///
- /// # Errors
- ///
- /// * If it fails to write to the control.
- pub fn set_volume(&mut self, left: i32, right: i32) -> Result<()> {
- self.save([left, right])?;
- Ok(())
- }
-}
-
-impl<'a> Control<'a> for StereoVolumeControl<'a> {
- type Item = [i32; 2];
- fn new(handle: &'a mut Ctl, id: ElemId) -> Self {
- Self { handle, id }
- }
-}
-
-/// `Control` that reads and writes a single boolean value entry.
-/// Since this crate is the `cros_alsa` crate, we replace the `cros_alsa`
-/// path to `crate` in derive macros by `cros_alsa` attribute.
-#[derive(ControlOps)]
-#[cros_alsa(path = "crate")]
-pub struct SwitchControl<'a> {
- handle: &'a mut Ctl,
- id: ElemId,
-}
-
-impl<'a> SwitchControl<'a> {
- /// Reads the state of a switch type mix control.
- ///
- /// # Errors
- ///
- /// * If it fails to read from the control.
- pub fn state(&mut self) -> Result<bool> {
- let v = self.load()?;
- Ok(v[0])
- }
-
- /// Updates the control state to true.
- ///
- /// # Errors
- ///
- /// * If it fails to write to the control.
- pub fn on(&mut self) -> Result<()> {
- self.save([true])?;
- Ok(())
- }
-
- /// Updates the control state to false.
- ///
- /// # Errors
- ///
- /// * If it fails to write to the control.
- pub fn off(&mut self) -> Result<()> {
- self.save([false])?;
- Ok(())
- }
-}
-
-impl<'a> Control<'a> for SwitchControl<'a> {
- type Item = [bool; 1];
- fn new(handle: &'a mut Ctl, id: ElemId) -> Self {
- Self { handle, id }
- }
-}