summaryrefslogtreecommitdiff
path: root/cros_alsa/src/elem.rs
diff options
context:
space:
mode:
Diffstat (limited to 'cros_alsa/src/elem.rs')
-rw-r--r--cros_alsa/src/elem.rs204
1 files changed, 0 insertions, 204 deletions
diff --git a/cros_alsa/src/elem.rs b/cros_alsa/src/elem.rs
deleted file mode 100644
index 08fe8b62..00000000
--- a/cros_alsa/src/elem.rs
+++ /dev/null
@@ -1,204 +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.
-
-//! This module provides different implementations of `Elem` that use the alsa-lib control interface
-//! API to read and write alsa control elements.
-//!
-//! The `Elem::type()` returns the type of value that a control element can interact with,
-//! and it is one of integer, integer64, boolean, enumerators, bytes or IEC958 structure.
-//! The `Elem::size()` returns the number of values it reads from or writes to the hardware
-//! at a time.
-//! The `Elem::load(..)` and `Elem::save(..)` are used by `ControlOps` trait to read and write
-//! the underlying mixer control.
-//!
-//! Users should use the provided implementations of `Elem` to define the associated type in
-//! their owner encapsulation of `Control`.
-
-use std::default::Default;
-use std::error;
-use std::fmt;
-
-use libc::{c_long, c_uint};
-use remain::sorted;
-
-use crate::control_primitive::{self, snd_strerror, Ctl, ElemId, ElemType, ElemValue};
-
-/// The Result type of cros-alsa::elem.
-pub type Result<T> = std::result::Result<T, Error>;
-
-#[sorted]
-#[derive(Debug)]
-/// Possible errors that can occur in cros-alsa::elem.
-pub enum Error {
- /// Failed to call AlsaControlAPI.
- AlsaControlAPI(control_primitive::Error),
- /// Failed to call `snd_ctl_elem_read()`.
- ElemReadFailed(i32),
- /// Failed to call `snd_ctl_elem_write()`.
- ElemWriteFailed(i32),
-}
-
-impl error::Error for Error {}
-
-impl From<control_primitive::Error> for Error {
- fn from(err: control_primitive::Error) -> Error {
- Error::AlsaControlAPI(err)
- }
-}
-
-impl fmt::Display for Error {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- use Error::*;
- match self {
- AlsaControlAPI(e) => write!(f, "{}", e),
- ElemReadFailed(e) => write!(f, "snd_ctl_elem_read failed: {}", snd_strerror(*e)?),
- ElemWriteFailed(e) => write!(f, "snd_ctl_elem_write failed: {}", snd_strerror(*e)?),
- }
- }
-}
-
-// Uses a recursive macro to generate implementation for [bool; n] and [i32; n], n = 1 to 128.
-// The `$t:ident $($ts:ident)*` part matches and removes one token at a time. It's used for
-// counting recursive steps.
-macro_rules! impl_for_array {
- {$n:expr, $type:ty, $t:ident $($ts:ident)*} => {
- impl Elem for [$type; $n] {
- type T = Self;
- /// Reads [$type; $n] data from the mixer control.
- ///
- /// # Errors
- ///
- /// * If it fails to call `snd_ctl_elem_read()`.
- fn load(handle: &mut Ctl, id: &ElemId) -> Result<Self::T>
- {
- let mut elem = ElemValue::new(id)?;
- // Safe because self.handle.as_mut_ptr() is a valid *mut snd_ctl_t and
- // elem.as_mut_ptr() is also a valid *mut snd_ctl_elem_value_t.
- let rc = unsafe { alsa_sys::snd_ctl_elem_read(handle.as_mut_ptr(), elem.as_mut_ptr()) };
- if rc < 0 {
- return Err(Error::ElemReadFailed(rc));
- }
- let mut ret = [Default::default(); $n];
- for i in 0..$n {
- // Safe because elem.as_ptr() is a valid snd_ctl_elem_value_t* and i is guaranteed to be
- // within a valid range.
- ret[i] = unsafe { <$type>::elem_value_get(&elem, i) };
- }
- Ok(ret)
- }
-
- /// Updates [$type; $n] data to the mixer control.
- ///
- /// # Results
- ///
- /// * `changed` - false on success.
- /// - true on success when value was changed.
- ///
- /// # Errors
- ///
- /// * If it fails to call `snd_ctl_elem_write()`.
- fn save(handle: &mut Ctl, id: &ElemId, val: Self::T) -> Result<bool> {
- let mut elem = ElemValue::new(id)?;
- for i in 0..$n {
- // Safe because elem.as_mut_ptr() is a valid snd_ctl_elem_value_t* and i is guaranteed to be
- // within a valid range.
- unsafe { <$type>::elem_value_set(&mut elem, i, val[i]) };
- }
- // Safe because self.handle.as_mut_ptr() is a valid *mut snd_ctl_t and
- // elem.as_mut_ptr() is also a valid *mut snd_ctl_elem_value_t.
- let rc = unsafe { alsa_sys::snd_ctl_elem_write(handle.as_mut_ptr(), elem.as_mut_ptr()) };
- if rc < 0 {
- return Err(Error::ElemWriteFailed(rc));
- }
- Ok(rc > 0)
- }
-
- /// Gets the data type itself can read and write.
- fn elem_type() -> ElemType {
- <$type>::elem_type()
- }
-
- /// Gets the number of value entries itself can read and write.
- fn size() -> usize {
- $n
- }
- }
- impl_for_array!{($n - 1), $type, $($ts)*}
- };
- {$n:expr, $type:ty,} => {};
-}
-
-// Implements `Elem` for [i32; n] where n = 1 to 128.
-impl_for_array! {128, i32,
-T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T
-T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T
-T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T
-T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T
-}
-
-// Implements `Elem` for [bool; n] where n = 1 to 128.
-impl_for_array! {128, bool,
-T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T
-T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T
-T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T
-T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T
-}
-
-impl CtlElemValue for bool {
- type T = bool;
- /// Gets a bool from the ElemValue.
- unsafe fn elem_value_get(elem: &ElemValue, idx: usize) -> bool {
- alsa_sys::snd_ctl_elem_value_get_boolean(elem.as_ptr(), idx as c_uint) != 0
- }
- /// Sets a bool to the ElemValue.
- unsafe fn elem_value_set(elem: &mut ElemValue, idx: usize, val: bool) {
- alsa_sys::snd_ctl_elem_value_set_boolean(elem.as_mut_ptr(), idx as c_uint, val as c_long);
- }
- /// Returns ElemType::Boolean.
- fn elem_type() -> ElemType {
- ElemType::Boolean
- }
-}
-
-impl CtlElemValue for i32 {
- type T = i32;
- /// Gets an i32 from the ElemValue.
- unsafe fn elem_value_get(elem: &ElemValue, idx: usize) -> i32 {
- alsa_sys::snd_ctl_elem_value_get_integer(elem.as_ptr(), idx as c_uint) as i32
- }
- /// Sets an i32 to the ElemValue.
- unsafe fn elem_value_set(elem: &mut ElemValue, idx: usize, val: i32) {
- alsa_sys::snd_ctl_elem_value_set_integer(elem.as_mut_ptr(), idx as c_uint, val as c_long);
- }
- /// Returns ElemType::Integer.
- fn elem_type() -> ElemType {
- ElemType::Integer
- }
-}
-
-/// All primitive types of a control element should implement `CtlElemValue` trait.
-trait CtlElemValue {
- /// The primitive type of a control element.
- type T;
- /// Gets the value from the ElemValue.
- unsafe fn elem_value_get(value: &ElemValue, idx: usize) -> Self::T;
- /// Sets the value to the ElemValue.
- unsafe fn elem_value_set(value: &mut ElemValue, id: usize, val: Self::T);
- /// Gets the data type itself can read and write.
- fn elem_type() -> ElemType;
-}
-
-/// Use `Elem` trait to access the underlying control element through the given `Ctl` and `ElemId`.
-pub trait Elem: Sized {
- /// The data type of a control element.
- type T;
- /// Reads the value from the mixer control.
- fn load(handle: &mut Ctl, id: &ElemId) -> Result<Self::T>;
- /// Saves the value to the mixer control.
- fn save(handle: &mut Ctl, id: &ElemId, val: Self::T) -> Result<bool>;
- /// Gets the data type itself can read and write.
- fn elem_type() -> ElemType;
- /// Gets the number of value entries itself can read and write.
- fn size() -> usize;
-}