diff options
Diffstat (limited to 'cras/client/cras-sys/src/lib.rs')
-rw-r--r-- | cras/client/cras-sys/src/lib.rs | 657 |
1 files changed, 0 insertions, 657 deletions
diff --git a/cras/client/cras-sys/src/lib.rs b/cras/client/cras-sys/src/lib.rs deleted file mode 100644 index 2b3d21e0..00000000 --- a/cras/client/cras-sys/src/lib.rs +++ /dev/null @@ -1,657 +0,0 @@ -// Copyright 2019 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. -extern crate audio_streams; -extern crate data_model; - -use std::cmp::min; -use std::convert::{TryFrom, TryInto}; -use std::error; -use std::fmt; -use std::iter::FromIterator; -use std::os::raw::c_char; -use std::str::FromStr; -use std::time::Duration; - -#[allow(dead_code)] -#[allow(non_upper_case_globals)] -#[allow(non_camel_case_types)] -#[allow(non_snake_case)] -pub mod gen; -use gen::{ - _snd_pcm_format, audio_dev_debug_info, audio_message, audio_stream_debug_info, - cras_audio_format_packed, cras_iodev_info, cras_ionode_info, cras_ionode_info__bindgen_ty_1, - cras_timespec, snd_pcm_format_t, CRAS_AUDIO_MESSAGE_ID, CRAS_CHANNEL, CRAS_CLIENT_TYPE, - CRAS_NODE_TYPE, CRAS_STREAM_DIRECTION, CRAS_STREAM_EFFECT, CRAS_STREAM_TYPE, -}; - -use audio_streams::{SampleFormat, StreamDirection, StreamEffect}; - -unsafe impl data_model::DataInit for gen::audio_message {} -unsafe impl data_model::DataInit for gen::audio_debug_info {} -unsafe impl data_model::DataInit for gen::audio_dev_debug_info {} -unsafe impl data_model::DataInit for gen::audio_stream_debug_info {} -unsafe impl data_model::DataInit for gen::cras_client_connected {} -unsafe impl data_model::DataInit for gen::cras_client_stream_connected {} -unsafe impl data_model::DataInit for gen::cras_connect_message {} -unsafe impl data_model::DataInit for gen::cras_disconnect_stream_message {} -unsafe impl data_model::DataInit for gen::cras_dump_audio_thread {} -unsafe impl data_model::DataInit for gen::cras_iodev_info {} -unsafe impl data_model::DataInit for gen::cras_ionode_info {} -unsafe impl data_model::DataInit for gen::cras_server_state {} -unsafe impl data_model::DataInit for gen::cras_set_system_mute {} -unsafe impl data_model::DataInit for gen::cras_set_system_volume {} - -/// An enumeration of errors that can occur when converting the packed C -/// structs into Rust-style structs. -#[derive(Debug)] -pub enum Error { - InvalidChannel(i8), - InvalidClientType(u32), - InvalidClientTypeStr, - InvalidStreamType(u32), -} - -impl error::Error for Error {} - -impl fmt::Display for Error { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - use Error::*; - match self { - InvalidChannel(c) => write!( - f, - "Channel value {} is not within valid range [0, {})", - c, - CRAS_CHANNEL::CRAS_CH_MAX as u32 - ), - InvalidClientType(t) => write!( - f, - "Client type {} is not within valid range [0, {})", - t, - CRAS_CLIENT_TYPE::CRAS_CLIENT_TYPE_SERVER_STREAM as u32 + 1 - ), - InvalidClientTypeStr => write!(f, "Invalid client type string"), - InvalidStreamType(t) => write!( - f, - "Stream type {} is not within valid range [0, {})", - t, - CRAS_STREAM_TYPE::CRAS_STREAM_NUM_TYPES as u32 - ), - } - } -} - -impl cras_audio_format_packed { - /// Initializes `cras_audio_format_packed` from input parameters. - /// Field `channel_layout` will be assigned with default channel layout defined in - /// `Self::default_channel_layout`. - /// - /// # Arguments - /// * `format` - Format in used. - /// * `rate` - Rate in used. - /// * `num_channels` - Number of channels in used. - /// * `direction` - Stream direction enumeration. - /// - /// # Returns - /// Structure `cras_audio_format_packed` - pub fn new( - format: _snd_pcm_format, - rate: u32, - num_channels: usize, - direction: CRAS_STREAM_DIRECTION, - ) -> Self { - Self { - format: format as i32, - frame_rate: rate, - num_channels: num_channels as u32, - channel_layout: Self::default_channel_layout(num_channels, direction), - } - } - - /// Generates default channel layout by given number of channels and stream direction. - /// ``` - /// use cras_sys::gen::{ - /// _snd_pcm_format, - /// cras_audio_format_packed, - /// CRAS_STREAM_DIRECTION::* - /// }; - /// let test_one = | num_channels, direction, expected_results | { - /// let default_channel_fmt = cras_audio_format_packed::new( - /// _snd_pcm_format::SND_PCM_FORMAT_S16, - /// 48000, - /// num_channels, - /// direction - /// ); - /// assert_eq!(default_channel_fmt.channel_layout, expected_results); - /// }; - /// test_one(2, CRAS_STREAM_OUTPUT, [0, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1]); - /// test_one(4, CRAS_STREAM_OUTPUT, [0, 1, 2, 3, -1, -1, -1, -1, -1, -1, -1]); - /// test_one(6, CRAS_STREAM_OUTPUT, [0, 1, 4, 5, 2, 3, -1, -1, -1, -1, -1]); - /// test_one(2, CRAS_STREAM_INPUT, [0, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1]); - /// test_one(4, CRAS_STREAM_INPUT, [0, 1, 2, 3, -1, -1, -1, -1, -1, -1, -1]); - /// test_one(6, CRAS_STREAM_INPUT, [0, 1, 2, 3, 4, 5, -1, -1, -1, -1, -1]); - /// ``` - fn default_channel_layout( - num_channels: usize, - direction: CRAS_STREAM_DIRECTION, - ) -> [i8; CRAS_CHANNEL::CRAS_CH_MAX as usize] { - use {CRAS_CHANNEL::*, CRAS_STREAM_DIRECTION::*}; - - let mut channel_layout = [-1; CRAS_CH_MAX as usize]; - match (num_channels, direction) { - (6, CRAS_STREAM_OUTPUT) => { - [ - CRAS_CH_FL, - CRAS_CH_FR, - CRAS_CH_FC, - CRAS_CH_LFE, - CRAS_CH_RL, - CRAS_CH_RR, - ] - .iter() - .enumerate() - .for_each(|(idx, &channel)| channel_layout[channel as usize] = idx as i8); - } - _ => { - for (i, channel) in channel_layout - .iter_mut() - .enumerate() - .take(min(num_channels, CRAS_CH_MAX as usize)) - { - *channel = i as i8; - } - } - } - channel_layout - } -} - -impl Default for audio_message { - fn default() -> Self { - Self { - error: 0, - frames: 0, - id: CRAS_AUDIO_MESSAGE_ID::NUM_AUDIO_MESSAGES, - } - } -} - -impl Default for cras_iodev_info { - fn default() -> Self { - Self { - idx: 0, - name: [0; 64usize], - stable_id: 0, - max_supported_channels: 0, - } - } -} - -#[derive(Debug)] -pub struct CrasIodevInfo { - pub index: u32, - pub name: String, -} - -fn cstring_to_string(cstring: &[c_char]) -> String { - let null_idx = match cstring.iter().enumerate().find(|(_, &c)| c == 0) { - Some((i, _)) => i, - None => return "".to_owned(), - }; - - let ptr = cstring.as_ptr() as *const u8; - let slice = unsafe { core::slice::from_raw_parts(ptr, null_idx) }; - String::from_utf8_lossy(slice).to_string() -} - -impl From<cras_iodev_info> for CrasIodevInfo { - fn from(info: cras_iodev_info) -> Self { - Self { - index: info.idx, - name: cstring_to_string(&info.name), - } - } -} - -impl Default for cras_ionode_info { - fn default() -> Self { - Self { - iodev_idx: 0, - ionode_idx: 0, - plugged: 0, - active: 0, - plugged_time: cras_ionode_info__bindgen_ty_1 { - tv_sec: 0, - tv_usec: 0, - }, - volume: 0, - ui_gain_scaler: 0.0, - capture_gain: 0, - left_right_swapped: 0, - type_enum: 0, - stable_id: 0, - type_: [0; 32usize], - name: [0; 64usize], - active_hotword_model: [0; 16usize], - } - } -} - -impl From<u32> for CRAS_NODE_TYPE { - fn from(node_type: u32) -> CRAS_NODE_TYPE { - use CRAS_NODE_TYPE::*; - match node_type { - 0 => CRAS_NODE_TYPE_INTERNAL_SPEAKER, - 1 => CRAS_NODE_TYPE_HEADPHONE, - 2 => CRAS_NODE_TYPE_HDMI, - 3 => CRAS_NODE_TYPE_HAPTIC, - 4 => CRAS_NODE_TYPE_LINEOUT, - 5 => CRAS_NODE_TYPE_MIC, - 6 => CRAS_NODE_TYPE_HOTWORD, - 7 => CRAS_NODE_TYPE_POST_MIX_PRE_DSP, - 8 => CRAS_NODE_TYPE_POST_DSP, - 9 => CRAS_NODE_TYPE_USB, - 10 => CRAS_NODE_TYPE_BLUETOOTH, - _ => CRAS_NODE_TYPE_UNKNOWN, - } - } -} - -#[derive(Debug)] -pub struct CrasIonodeInfo { - pub name: String, - pub iodev_index: u32, - pub ionode_index: u32, - pub stable_id: u32, - pub plugged: bool, - pub active: bool, - pub node_type: CRAS_NODE_TYPE, - pub type_name: String, - pub volume: u32, - pub capture_gain: i32, - pub plugged_time: cras_timespec, -} - -impl From<cras_ionode_info> for CrasIonodeInfo { - fn from(info: cras_ionode_info) -> Self { - Self { - name: cstring_to_string(&info.name), - iodev_index: info.iodev_idx, - ionode_index: info.ionode_idx, - stable_id: info.stable_id, - plugged: info.plugged != 0, - active: info.active != 0, - node_type: CRAS_NODE_TYPE::from(info.type_enum), - type_name: cstring_to_string(&info.type_), - volume: info.volume, - capture_gain: info.capture_gain, - plugged_time: cras_timespec { - tv_sec: info.plugged_time.tv_sec, - tv_nsec: info.plugged_time.tv_usec * 1000, - }, - } - } -} - -impl From<u32> for CRAS_STREAM_DIRECTION { - fn from(node_type: u32) -> CRAS_STREAM_DIRECTION { - use CRAS_STREAM_DIRECTION::*; - match node_type { - 0 => CRAS_STREAM_OUTPUT, - 1 => CRAS_STREAM_INPUT, - 2 => CRAS_STREAM_UNDEFINED, - 3 => CRAS_STREAM_POST_MIX_PRE_DSP, - _ => CRAS_STREAM_UNDEFINED, - } - } -} - -impl Default for audio_dev_debug_info { - fn default() -> Self { - Self { - dev_name: [0; 64], - buffer_size: 0, - min_buffer_level: 0, - min_cb_level: 0, - max_cb_level: 0, - frame_rate: 0, - num_channels: 0, - est_rate_ratio: 0.0, - direction: 0, - num_underruns: 0, - num_severe_underruns: 0, - highest_hw_level: 0, - runtime_sec: 0, - runtime_nsec: 0, - longest_wake_sec: 0, - longest_wake_nsec: 0, - software_gain_scaler: 0.0, - } - } -} - -/// A rust-style representation of the server's packed audio_dev_debug_info -/// struct. -#[derive(Debug)] -pub struct AudioDevDebugInfo { - pub dev_name: String, - pub buffer_size: u32, - pub min_buffer_level: u32, - pub min_cb_level: u32, - pub max_cb_level: u32, - pub frame_rate: u32, - pub num_channels: u32, - pub est_rate_ratio: f64, - pub direction: CRAS_STREAM_DIRECTION, - pub num_underruns: u32, - pub num_severe_underruns: u32, - pub highest_hw_level: u32, - pub runtime: Duration, - pub longest_wake: Duration, - pub software_gain_scaler: f64, -} - -impl From<audio_dev_debug_info> for AudioDevDebugInfo { - fn from(info: audio_dev_debug_info) -> Self { - Self { - dev_name: cstring_to_string(&info.dev_name), - buffer_size: info.buffer_size, - min_buffer_level: info.min_buffer_level, - min_cb_level: info.min_cb_level, - max_cb_level: info.max_cb_level, - frame_rate: info.frame_rate, - num_channels: info.num_channels, - est_rate_ratio: info.est_rate_ratio, - direction: CRAS_STREAM_DIRECTION::from(u32::from(info.direction)), - num_underruns: info.num_underruns, - num_severe_underruns: info.num_severe_underruns, - highest_hw_level: info.highest_hw_level, - runtime: Duration::new(info.runtime_sec.into(), info.runtime_nsec), - longest_wake: Duration::new(info.longest_wake_sec.into(), info.longest_wake_nsec), - software_gain_scaler: info.software_gain_scaler, - } - } -} - -impl fmt::Display for AudioDevDebugInfo { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - writeln!(f, "Device: {}", self.dev_name)?; - writeln!(f, " Direction: {:?}", self.direction)?; - writeln!(f, " Buffer size: {}", self.buffer_size)?; - writeln!(f, " Minimum buffer level: {}", self.min_buffer_level)?; - writeln!(f, " Minimum callback level: {}", self.min_cb_level)?; - writeln!(f, " Max callback level: {}", self.max_cb_level)?; - writeln!(f, " Frame rate: {}", self.frame_rate)?; - writeln!(f, " Number of channels: {}", self.num_channels)?; - writeln!(f, " Estimated rate ratio: {:.2}", self.est_rate_ratio)?; - writeln!(f, " Underrun count: {}", self.num_underruns)?; - writeln!(f, " Severe underrun count: {}", self.num_severe_underruns)?; - writeln!(f, " Highest hardware level: {}", self.highest_hw_level)?; - writeln!(f, " Runtime: {:?}", self.runtime)?; - writeln!(f, " Longest wake: {:?}", self.longest_wake)?; - writeln!(f, " Software gain scaler: {}", self.software_gain_scaler)?; - Ok(()) - } -} - -impl TryFrom<u32> for CRAS_STREAM_TYPE { - type Error = Error; - fn try_from(stream_type: u32) -> Result<Self, Self::Error> { - use CRAS_STREAM_TYPE::*; - match stream_type { - 0 => Ok(CRAS_STREAM_TYPE_DEFAULT), - 1 => Ok(CRAS_STREAM_TYPE_MULTIMEDIA), - 2 => Ok(CRAS_STREAM_TYPE_VOICE_COMMUNICATION), - 3 => Ok(CRAS_STREAM_TYPE_SPEECH_RECOGNITION), - 4 => Ok(CRAS_STREAM_TYPE_PRO_AUDIO), - 5 => Ok(CRAS_STREAM_TYPE_ACCESSIBILITY), - _ => Err(Error::InvalidStreamType(stream_type)), - } - } -} - -impl TryFrom<u32> for CRAS_CLIENT_TYPE { - type Error = Error; - fn try_from(client_type: u32) -> Result<Self, Self::Error> { - use CRAS_CLIENT_TYPE::*; - match client_type { - 0 => Ok(CRAS_CLIENT_TYPE_UNKNOWN), - 1 => Ok(CRAS_CLIENT_TYPE_LEGACY), - 2 => Ok(CRAS_CLIENT_TYPE_TEST), - 3 => Ok(CRAS_CLIENT_TYPE_PCM), - 4 => Ok(CRAS_CLIENT_TYPE_CHROME), - 5 => Ok(CRAS_CLIENT_TYPE_ARC), - 6 => Ok(CRAS_CLIENT_TYPE_CROSVM), - 7 => Ok(CRAS_CLIENT_TYPE_SERVER_STREAM), - 8 => Ok(CRAS_CLIENT_TYPE_LACROS), - _ => Err(Error::InvalidClientType(client_type)), - } - } -} - -impl FromStr for CRAS_CLIENT_TYPE { - type Err = Error; - fn from_str(s: &str) -> std::result::Result<Self, Self::Err> { - use CRAS_CLIENT_TYPE::*; - match s { - "crosvm" => Ok(CRAS_CLIENT_TYPE_CROSVM), - "arcvm" => Ok(CRAS_CLIENT_TYPE_ARCVM), - _ => Err(Error::InvalidClientTypeStr), - } - } -} - -impl Default for audio_stream_debug_info { - fn default() -> Self { - Self { - stream_id: 0, - dev_idx: 0, - direction: 0, - stream_type: 0, - client_type: 0, - buffer_frames: 0, - cb_threshold: 0, - effects: 0, - flags: 0, - frame_rate: 0, - num_channels: 0, - longest_fetch_sec: 0, - longest_fetch_nsec: 0, - num_missed_cb: 0, - num_overruns: 0, - is_pinned: 0, - pinned_dev_idx: 0, - runtime_sec: 0, - runtime_nsec: 0, - stream_volume: 0.0, - channel_layout: [0; 11], - } - } -} - -impl TryFrom<i8> for CRAS_CHANNEL { - type Error = Error; - fn try_from(channel: i8) -> Result<Self, Self::Error> { - use CRAS_CHANNEL::*; - match channel { - 0 => Ok(CRAS_CH_FL), - 1 => Ok(CRAS_CH_FR), - 2 => Ok(CRAS_CH_RL), - 3 => Ok(CRAS_CH_RR), - 4 => Ok(CRAS_CH_FC), - 5 => Ok(CRAS_CH_LFE), - 6 => Ok(CRAS_CH_SL), - 7 => Ok(CRAS_CH_SR), - 8 => Ok(CRAS_CH_RC), - 9 => Ok(CRAS_CH_FLC), - 10 => Ok(CRAS_CH_FRC), - _ => Err(Error::InvalidChannel(channel)), - } - } -} - -/// A rust-style representation of the server's packed audio_stream_debug_info -/// struct. -#[derive(Debug)] -pub struct AudioStreamDebugInfo { - pub stream_id: u64, - pub dev_idx: u32, - pub direction: CRAS_STREAM_DIRECTION, - pub stream_type: CRAS_STREAM_TYPE, - pub client_type: CRAS_CLIENT_TYPE, - pub buffer_frames: u32, - pub cb_threshold: u32, - pub effects: u64, - pub flags: u32, - pub frame_rate: u32, - pub num_channels: u32, - pub longest_fetch: Duration, - pub num_missed_cb: u32, - pub num_overruns: u32, - pub is_pinned: bool, - pub pinned_dev_idx: u32, - pub runtime: Duration, - pub stream_volume: f64, - pub channel_layout: Vec<CRAS_CHANNEL>, -} - -impl TryFrom<audio_stream_debug_info> for AudioStreamDebugInfo { - type Error = Error; - fn try_from(info: audio_stream_debug_info) -> Result<Self, Self::Error> { - let channel_layout = info - .channel_layout - .iter() - .cloned() - .take_while(|&c| c != -1) - .map(TryInto::try_into) - .collect::<Result<Vec<_>, _>>()?; - Ok(Self { - stream_id: info.stream_id, - dev_idx: info.dev_idx, - direction: info.direction.into(), - stream_type: info.stream_type.try_into()?, - client_type: info.client_type.try_into()?, - buffer_frames: info.buffer_frames, - cb_threshold: info.cb_threshold, - effects: info.effects, - flags: info.flags, - frame_rate: info.frame_rate, - num_channels: info.num_channels, - longest_fetch: Duration::new(info.longest_fetch_sec.into(), info.longest_fetch_nsec), - num_missed_cb: info.num_missed_cb, - num_overruns: info.num_overruns, - is_pinned: info.is_pinned != 0, - pinned_dev_idx: info.pinned_dev_idx, - runtime: Duration::new(info.runtime_sec.into(), info.runtime_nsec), - stream_volume: info.stream_volume, - channel_layout, - }) - } -} - -impl fmt::Display for AudioStreamDebugInfo { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - writeln!( - f, - "Stream: {}, Device index: {}", - self.stream_id, self.dev_idx - )?; - writeln!(f, " Direction: {:?}", self.direction)?; - writeln!(f, " Stream type: {:?}", self.stream_type)?; - writeln!(f, " Client type: {:?}", self.client_type)?; - writeln!(f, " Buffer frames: {}", self.buffer_frames)?; - writeln!(f, " Callback threshold: {}", self.cb_threshold)?; - writeln!(f, " Effects: {:#x}", self.effects)?; - writeln!(f, " Frame rate: {}", self.frame_rate)?; - writeln!(f, " Number of channels: {}", self.num_channels)?; - writeln!(f, " Longest fetch: {:?}", self.longest_fetch)?; - writeln!(f, " Overrun count: {}", self.num_overruns)?; - writeln!(f, " Pinned: {}", self.is_pinned)?; - writeln!(f, " Pinned device index: {}", self.pinned_dev_idx)?; - writeln!(f, " Missed callbacks: {}", self.num_missed_cb)?; - match self.direction { - CRAS_STREAM_DIRECTION::CRAS_STREAM_OUTPUT => { - writeln!(f, " Volume: {:.2}", self.stream_volume)? - } - CRAS_STREAM_DIRECTION::CRAS_STREAM_INPUT => { - writeln!(f, " Gain: {:.2}", self.stream_volume)? - } - _ => (), - }; - writeln!(f, " Runtime: {:?}", self.runtime)?; - write!(f, " Channel map:")?; - for channel in &self.channel_layout { - write!(f, " {:?}", channel)?; - } - writeln!(f)?; - Ok(()) - } -} - -/// A rust-style representation of the server's audio debug info. -pub struct AudioDebugInfo { - pub devices: Vec<AudioDevDebugInfo>, - pub streams: Vec<AudioStreamDebugInfo>, -} - -impl AudioDebugInfo { - pub fn new(devices: Vec<AudioDevDebugInfo>, streams: Vec<AudioStreamDebugInfo>) -> Self { - Self { devices, streams } - } -} - -impl Into<u64> for CRAS_STREAM_EFFECT { - fn into(self) -> u64 { - u64::from(self.0) - } -} - -impl CRAS_STREAM_EFFECT { - pub fn empty() -> Self { - CRAS_STREAM_EFFECT(0) - } -} - -impl From<StreamDirection> for CRAS_STREAM_DIRECTION { - /// Convert an audio_streams StreamDirection into the corresponding CRAS_STREAM_DIRECTION. - fn from(direction: StreamDirection) -> Self { - match direction { - StreamDirection::Playback => CRAS_STREAM_DIRECTION::CRAS_STREAM_OUTPUT, - StreamDirection::Capture => CRAS_STREAM_DIRECTION::CRAS_STREAM_INPUT, - } - } -} - -impl From<StreamEffect> for CRAS_STREAM_EFFECT { - /// Convert an audio_streams StreamEffect into the corresponding CRAS_STREAM_EFFECT. - fn from(effect: StreamEffect) -> Self { - match effect { - StreamEffect::NoEffect => CRAS_STREAM_EFFECT::empty(), - StreamEffect::EchoCancellation => CRAS_STREAM_EFFECT::APM_ECHO_CANCELLATION, - } - } -} - -impl<'a> FromIterator<&'a StreamEffect> for CRAS_STREAM_EFFECT { - fn from_iter<I>(iter: I) -> Self - where - I: IntoIterator<Item = &'a StreamEffect>, - { - iter.into_iter().fold( - CRAS_STREAM_EFFECT::empty(), - |cras_effect, &stream_effect| cras_effect | stream_effect.into(), - ) - } -} - -/// Convert an audio_streams SampleFormat into the corresponding pcm_format. -impl From<SampleFormat> for snd_pcm_format_t { - fn from(format: SampleFormat) -> Self { - match format { - SampleFormat::U8 => snd_pcm_format_t::SND_PCM_FORMAT_U8, - SampleFormat::S16LE => snd_pcm_format_t::SND_PCM_FORMAT_S16_LE, - SampleFormat::S24LE => snd_pcm_format_t::SND_PCM_FORMAT_S24_LE, - SampleFormat::S32LE => snd_pcm_format_t::SND_PCM_FORMAT_S32_LE, - } - } -} |