diff options
Diffstat (limited to 'cras/client')
28 files changed, 0 insertions, 10117 deletions
diff --git a/cras/client/cras-sys/.gitignore b/cras/client/cras-sys/.gitignore deleted file mode 100644 index fa8d85ac..00000000 --- a/cras/client/cras-sys/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -Cargo.lock -target diff --git a/cras/client/cras-sys/.rustfmt.toml b/cras/client/cras-sys/.rustfmt.toml deleted file mode 100644 index a2db3012..00000000 --- a/cras/client/cras-sys/.rustfmt.toml +++ /dev/null @@ -1,2 +0,0 @@ -use_field_init_shorthand = true -use_try_shorthand = true diff --git a/cras/client/cras-sys/Android.bp b/cras/client/cras-sys/Android.bp deleted file mode 100644 index d6482b2e..00000000 --- a/cras/client/cras-sys/Android.bp +++ /dev/null @@ -1,62 +0,0 @@ -// This file is generated by cargo2android.py --run --device --test --global_defaults=crosvm_defaults --dependencies. - -package { - // See: http://go/android-license-faq - // A large-scale-change added 'default_applicable_licenses' to import - // all of the 'license_kinds' from "external_adhd_license" - // to get the below license kinds: - // SPDX-license-identifier-BSD - default_applicable_licenses: ["external_adhd_license"], -} - -rust_defaults { - name: "cras-sys_defaults", - defaults: ["crosvm_defaults"], - crate_name: "cras_sys", - srcs: ["src/lib.rs"], - test_suites: ["general-tests"], - auto_gen_config: true, - edition: "2015", - rustlibs: [ - "libaudio_streams", - "libdata_model", - ], -} - -rust_test_host { - name: "cras-sys_host_test_src_lib", - defaults: ["cras-sys_defaults"], -} - -rust_test { - name: "cras-sys_device_test_src_lib", - defaults: ["cras-sys_defaults"], -} - -rust_library { - name: "libcras_sys", - defaults: ["crosvm_defaults"], - host_supported: true, - crate_name: "cras_sys", - srcs: ["src/lib.rs"], - edition: "2015", - rustlibs: [ - "libaudio_streams", - "libdata_model", - ], -} - -// dependent_library ["feature_list"] -// ../../../../crosvm/assertions/src/lib.rs -// ../../../../crosvm/data_model/src/lib.rs -// ../../../../crosvm/sync/src/lib.rs -// ../../../../crosvm/sys_util/poll_token_derive/poll_token_derive.rs -// ../../../../crosvm/sys_util/src/lib.rs -// ../../../../crosvm/syscall_defines/src/lib.rs -// ../../../../crosvm/tempfile/src/lib.rs -// ../../../audio_streams/src/audio_streams.rs -// libc-0.2.76 "default,std" -// proc-macro2-1.0.19 "default,proc-macro" -// quote-1.0.7 "default,proc-macro" -// syn-1.0.39 "clone-impls,default,derive,parsing,printing,proc-macro,quote" -// unicode-xid-0.2.1 "default" diff --git a/cras/client/cras-sys/Cargo.toml b/cras/client/cras-sys/Cargo.toml deleted file mode 100644 index 1ac1857a..00000000 --- a/cras/client/cras-sys/Cargo.toml +++ /dev/null @@ -1,8 +0,0 @@ -[package] -name = "cras-sys" -version = "0.1.0" -authors = ["The Chromium OS Authors"] - -[dependencies] -audio_streams = { path = "../../../audio_streams" } # provided by ebuild -data_model = { path = "../../../../crosvm/data_model" } # provided by ebuild diff --git a/cras/client/cras-sys/generator/.gitignore b/cras/client/cras-sys/generator/.gitignore deleted file mode 100644 index 0e8b881c..00000000 --- a/cras/client/cras-sys/generator/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -*.h -Cargo.lock diff --git a/cras/client/cras-sys/generator/Cargo.toml b/cras/client/cras-sys/generator/Cargo.toml deleted file mode 100644 index 87c826e2..00000000 --- a/cras/client/cras-sys/generator/Cargo.toml +++ /dev/null @@ -1,7 +0,0 @@ -[package] -name = "generator" -version = "0.1.0" -authors = ["paulhsia <paulhsia@chromium.org>"] - -[dependencies] -bindgen = "0.43.0" diff --git a/cras/client/cras-sys/generator/README.md b/cras/client/cras-sys/generator/README.md deleted file mode 100644 index 0ca99062..00000000 --- a/cras/client/cras-sys/generator/README.md +++ /dev/null @@ -1,3 +0,0 @@ -1. Use `cargo run` to generate rust bindings at `lib_gen.rs` - -2. Copy `lib_gen.rs` to `cras-sys/src/gen.rs diff --git a/cras/client/cras-sys/generator/src/main.rs b/cras/client/cras-sys/generator/src/main.rs deleted file mode 100644 index e562691d..00000000 --- a/cras/client/cras-sys/generator/src/main.rs +++ /dev/null @@ -1,159 +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 bindgen; - -use bindgen::builder; - -use std::fs::{self, File}; -use std::io::Write; -use std::path::Path; -use std::str; - -fn copy_headers(src_dir: &Path, dst_dir: &Path) -> Result<(), String> { - if dst_dir.is_file() { - fs::remove_file(&dst_dir).or_else(|e| { - Err(format!( - "failed to remove existing file at {:?}: {}", - dst_dir, e - )) - })?; - } - - if !dst_dir.is_dir() { - fs::create_dir(&dst_dir).or_else(|e| { - Err(format!( - "failed to create destination directory: {:?}: {}", - dst_dir, e - )) - })?; - } - - let header_files = vec![ - "cras_audio_format.h", - "cras_iodev_info.h", - "cras_messages.h", - "cras_shm.h", - "cras_types.h", - "cras_util.h", - "packet_status_logger.h", - ]; - - for header in &header_files { - let src = src_dir.join(&header); - let dst = dst_dir.join(&header); - fs::copy(&src, &dst).or_else(|e| { - Err(format!( - "failed to copy header file {:?} to {:?}: {}", - src, dst, e - )) - })?; - } - Ok(()) -} - -/* - * If we use both `packed` and `align(4)` for a struct, bindgen will generate - * it as an opaque struct. - * - * `cras_server_state` is created from C with `packed` and `aligned(4)` and - * shared through a shared memory area. - * - * Structs with `packed` and `align(4)` have the same memory layout as those - * with `packed` except for some extra alignment bytes at the end. - * - * Therefore, using only `packed` for `cras_server_state` from Rust side is safe. - * - * This function modifies `cras_server_state` from - * `__attribute__ ((packed, aligned(4)))` to `__attribute__ ((packed))` - */ -fn modify_server_state_attributes(dir: &Path) -> Result<(), String> { - let cras_types_path = dir.join("cras_types.h"); - let bytes = fs::read(&cras_types_path) - .or_else(|e| Err(format!("failed to read {:?}: {}", cras_types_path, e)))?; - - let old = str::from_utf8(&bytes).or_else(|e| { - Err(format!( - "failed to parse {:?} as utf8: {}", - cras_types_path, e - )) - })?; - - let new = old.replacen( - "struct __attribute__((packed, aligned(4))) cras_server_state {", - "struct __attribute__((packed)) cras_server_state {", - 1, - ); - - if new.len() >= old.len() { - return Err("failed to remove 'aligned(4)' from cras_server_state".to_string()); - } - - fs::write(&cras_types_path, new).or_else(|e| { - Err(format!( - "failed to write updated contents to {:?}: {}", - cras_types_path, e - )) - })?; - - Ok(()) -} - -fn gen() -> String { - let name = "cras_gen"; - let bindings = builder() - .header("c_headers/cras_messages.h") - .header("c_headers/cras_types.h") - .header("c_headers/cras_audio_format.h") - .header("c_headers/cras_shm.h") - .whitelist_type("cras_.*") - .whitelist_var("cras_.*") - .whitelist_type("CRAS_.*") - .whitelist_var("CRAS_.*") - .whitelist_type("audio_message") - .whitelist_var("MAX_DEBUG_.*") - .rustified_enum("CRAS_.*") - .rustified_enum("_snd_pcm_.*") - .bitfield_enum("CRAS_STREAM_EFFECT") - .generate() - .expect(format!("Unable to generate {} code", name).as_str()); - - bindings.to_string() -} - -fn write_output(output_path: &Path, output: String) -> std::io::Result<()> { - let header = b"// 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. - -/* - * generated from files in cras/src/common in adhd: - * cras_audio_format.h - * cras_iodev_info.h - * cras_messages.h - * cras_shm.h - * cras_types.h - * cras_util.h - * packet_status_logger.h - */ - -#![allow(clippy::unreadable_literal)] -#![allow(clippy::cognitive_complexity)] -"; - - let mut output_file = File::create(output_path)?; - output_file.write_all(header)?; - output_file.write_all(output.as_bytes())?; - Ok(()) -} - -fn main() { - let src_header_dir = Path::new("../../../src/common"); - let dst_header_dir = Path::new("./c_headers"); - - copy_headers(src_header_dir, dst_header_dir).expect("failed to copy C headers"); - modify_server_state_attributes(dst_header_dir) - .expect("failed to modify cras_server_state's attributes"); - let generated_code = gen(); - write_output(Path::new("lib_gen.rs"), generated_code).expect("failed to write generated code"); -} diff --git a/cras/client/cras-sys/src/gen.rs b/cras/client/cras-sys/src/gen.rs deleted file mode 100644 index 6fb4cdf8..00000000 --- a/cras/client/cras-sys/src/gen.rs +++ /dev/null @@ -1,5004 +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. - -/* - * generated from files in cras/src/common in adhd: - * cras_audio_format.h - * cras_iodev_info.h - * cras_messages.h - * cras_shm.h - * cras_types.h - * cras_util.h - * packet_status_logger.h - */ - -#![allow(clippy::unreadable_literal)] -#![allow(clippy::cognitive_complexity)] -/* automatically generated by rust-bindgen */ - -pub const CRAS_IODEV_NAME_BUFFER_SIZE: u32 = 64; -pub const CRAS_NODE_TYPE_BUFFER_SIZE: u32 = 32; -pub const CRAS_NODE_MIC_POS_BUFFER_SIZE: u32 = 128; -pub const CRAS_NODE_NAME_BUFFER_SIZE: u32 = 64; -pub const CRAS_NODE_HOTWORD_MODEL_BUFFER_SIZE: u32 = 16; -pub const CRAS_MAX_IODEVS: u32 = 20; -pub const CRAS_MAX_IONODES: u32 = 20; -pub const CRAS_MAX_ATTACHED_CLIENTS: u32 = 20; -pub const CRAS_MAX_AUDIO_THREAD_SNAPSHOTS: u32 = 10; -pub const CRAS_MAX_HOTWORD_MODEL_NAME_SIZE: u32 = 12; -pub const MAX_DEBUG_DEVS: u32 = 4; -pub const MAX_DEBUG_STREAMS: u32 = 8; -pub const CRAS_BT_EVENT_LOG_SIZE: u32 = 1024; -pub const CRAS_SERVER_STATE_VERSION: u32 = 2; -pub const CRAS_PROTO_VER: u32 = 7; -pub const CRAS_SERV_MAX_MSG_SIZE: u32 = 256; -pub const CRAS_CLIENT_MAX_MSG_SIZE: u32 = 256; -pub const CRAS_MAX_HOTWORD_MODELS: u32 = 243; -pub const CRAS_MAX_REMIX_CHANNELS: u32 = 8; -pub const CRAS_MAX_TEST_DATA_LEN: u32 = 224; -pub const CRAS_AEC_DUMP_FILE_NAME_LEN: u32 = 128; -pub const CRAS_NUM_SHM_BUFFERS: u32 = 2; -pub const CRAS_SHM_BUFFERS_MASK: u32 = 1; -pub type __int8_t = ::std::os::raw::c_schar; -pub type __uint8_t = ::std::os::raw::c_uchar; -pub type __int32_t = ::std::os::raw::c_int; -pub type __uint32_t = ::std::os::raw::c_uint; -pub type __int64_t = ::std::os::raw::c_long; -pub type __uint64_t = ::std::os::raw::c_ulong; -pub type __time_t = ::std::os::raw::c_long; -pub type __syscall_slong_t = ::std::os::raw::c_long; -#[repr(C, packed)] -#[derive(Copy, Clone)] -pub struct cras_iodev_info { - pub idx: u32, - pub name: [::std::os::raw::c_char; 64usize], - pub stable_id: u32, - pub max_supported_channels: u32, -} -#[test] -fn bindgen_test_layout_cras_iodev_info() { - assert_eq!( - ::std::mem::size_of::<cras_iodev_info>(), - 76usize, - concat!("Size of: ", stringify!(cras_iodev_info)) - ); - assert_eq!( - ::std::mem::align_of::<cras_iodev_info>(), - 1usize, - concat!("Alignment of ", stringify!(cras_iodev_info)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_iodev_info>())).idx as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(cras_iodev_info), - "::", - stringify!(idx) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_iodev_info>())).name as *const _ as usize }, - 4usize, - concat!( - "Offset of field: ", - stringify!(cras_iodev_info), - "::", - stringify!(name) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_iodev_info>())).stable_id as *const _ as usize }, - 68usize, - concat!( - "Offset of field: ", - stringify!(cras_iodev_info), - "::", - stringify!(stable_id) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_iodev_info>())).max_supported_channels as *const _ as usize - }, - 72usize, - concat!( - "Offset of field: ", - stringify!(cras_iodev_info), - "::", - stringify!(max_supported_channels) - ) - ); -} -#[repr(C, packed)] -#[derive(Copy, Clone)] -pub struct cras_ionode_info { - pub iodev_idx: u32, - pub ionode_idx: u32, - pub plugged: i32, - pub active: i32, - pub plugged_time: cras_ionode_info__bindgen_ty_1, - pub volume: u32, - pub capture_gain: i32, - pub ui_gain_scaler: f32, - pub left_right_swapped: i32, - pub type_enum: u32, - pub stable_id: u32, - pub type_: [::std::os::raw::c_char; 32usize], - pub name: [::std::os::raw::c_char; 64usize], - pub active_hotword_model: [::std::os::raw::c_char; 16usize], -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct cras_ionode_info__bindgen_ty_1 { - pub tv_sec: i64, - pub tv_usec: i64, -} -#[test] -fn bindgen_test_layout_cras_ionode_info__bindgen_ty_1() { - assert_eq!( - ::std::mem::size_of::<cras_ionode_info__bindgen_ty_1>(), - 16usize, - concat!("Size of: ", stringify!(cras_ionode_info__bindgen_ty_1)) - ); - assert_eq!( - ::std::mem::align_of::<cras_ionode_info__bindgen_ty_1>(), - 8usize, - concat!("Alignment of ", stringify!(cras_ionode_info__bindgen_ty_1)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_ionode_info__bindgen_ty_1>())).tv_sec as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(cras_ionode_info__bindgen_ty_1), - "::", - stringify!(tv_sec) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_ionode_info__bindgen_ty_1>())).tv_usec as *const _ as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(cras_ionode_info__bindgen_ty_1), - "::", - stringify!(tv_usec) - ) - ); -} -#[test] -fn bindgen_test_layout_cras_ionode_info() { - assert_eq!( - ::std::mem::size_of::<cras_ionode_info>(), - 168usize, - concat!("Size of: ", stringify!(cras_ionode_info)) - ); - assert_eq!( - ::std::mem::align_of::<cras_ionode_info>(), - 1usize, - concat!("Alignment of ", stringify!(cras_ionode_info)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_ionode_info>())).iodev_idx as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(cras_ionode_info), - "::", - stringify!(iodev_idx) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_ionode_info>())).ionode_idx as *const _ as usize }, - 4usize, - concat!( - "Offset of field: ", - stringify!(cras_ionode_info), - "::", - stringify!(ionode_idx) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_ionode_info>())).plugged as *const _ as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(cras_ionode_info), - "::", - stringify!(plugged) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_ionode_info>())).active as *const _ as usize }, - 12usize, - concat!( - "Offset of field: ", - stringify!(cras_ionode_info), - "::", - stringify!(active) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_ionode_info>())).plugged_time as *const _ as usize }, - 16usize, - concat!( - "Offset of field: ", - stringify!(cras_ionode_info), - "::", - stringify!(plugged_time) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_ionode_info>())).volume as *const _ as usize }, - 32usize, - concat!( - "Offset of field: ", - stringify!(cras_ionode_info), - "::", - stringify!(volume) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_ionode_info>())).capture_gain as *const _ as usize }, - 36usize, - concat!( - "Offset of field: ", - stringify!(cras_ionode_info), - "::", - stringify!(capture_gain) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_ionode_info>())).ui_gain_scaler as *const _ as usize }, - 40usize, - concat!( - "Offset of field: ", - stringify!(cras_ionode_info), - "::", - stringify!(ui_gain_scaler) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_ionode_info>())).left_right_swapped as *const _ as usize - }, - 44usize, - concat!( - "Offset of field: ", - stringify!(cras_ionode_info), - "::", - stringify!(left_right_swapped) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_ionode_info>())).type_enum as *const _ as usize }, - 48usize, - concat!( - "Offset of field: ", - stringify!(cras_ionode_info), - "::", - stringify!(type_enum) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_ionode_info>())).stable_id as *const _ as usize }, - 52usize, - concat!( - "Offset of field: ", - stringify!(cras_ionode_info), - "::", - stringify!(stable_id) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_ionode_info>())).type_ as *const _ as usize }, - 56usize, - concat!( - "Offset of field: ", - stringify!(cras_ionode_info), - "::", - stringify!(type_) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_ionode_info>())).name as *const _ as usize }, - 88usize, - concat!( - "Offset of field: ", - stringify!(cras_ionode_info), - "::", - stringify!(name) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_ionode_info>())).active_hotword_model as *const _ as usize - }, - 152usize, - concat!( - "Offset of field: ", - stringify!(cras_ionode_info), - "::", - stringify!(active_hotword_model) - ) - ); -} -pub const ionode_attr_IONODE_ATTR_PLUGGED: ionode_attr = 0; -pub const ionode_attr_IONODE_ATTR_VOLUME: ionode_attr = 1; -pub const ionode_attr_IONODE_ATTR_CAPTURE_GAIN: ionode_attr = 2; -pub const ionode_attr_IONODE_ATTR_SWAP_LEFT_RIGHT: ionode_attr = 3; -pub type ionode_attr = u32; -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct timespec { - pub tv_sec: __time_t, - pub tv_nsec: __syscall_slong_t, -} -#[test] -fn bindgen_test_layout_timespec() { - assert_eq!( - ::std::mem::size_of::<timespec>(), - 16usize, - concat!("Size of: ", stringify!(timespec)) - ); - assert_eq!( - ::std::mem::align_of::<timespec>(), - 8usize, - concat!("Alignment of ", stringify!(timespec)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<timespec>())).tv_sec as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(timespec), - "::", - stringify!(tv_sec) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<timespec>())).tv_nsec as *const _ as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(timespec), - "::", - stringify!(tv_nsec) - ) - ); -} -impl _snd_pcm_format { - pub const SND_PCM_FORMAT_LAST: _snd_pcm_format = _snd_pcm_format::SND_PCM_FORMAT_DSD_U32_BE; -} -impl _snd_pcm_format { - pub const SND_PCM_FORMAT_S16: _snd_pcm_format = _snd_pcm_format::SND_PCM_FORMAT_S16_LE; -} -impl _snd_pcm_format { - pub const SND_PCM_FORMAT_U16: _snd_pcm_format = _snd_pcm_format::SND_PCM_FORMAT_U16_LE; -} -impl _snd_pcm_format { - pub const SND_PCM_FORMAT_S24: _snd_pcm_format = _snd_pcm_format::SND_PCM_FORMAT_S24_LE; -} -impl _snd_pcm_format { - pub const SND_PCM_FORMAT_U24: _snd_pcm_format = _snd_pcm_format::SND_PCM_FORMAT_U24_LE; -} -impl _snd_pcm_format { - pub const SND_PCM_FORMAT_S32: _snd_pcm_format = _snd_pcm_format::SND_PCM_FORMAT_S32_LE; -} -impl _snd_pcm_format { - pub const SND_PCM_FORMAT_U32: _snd_pcm_format = _snd_pcm_format::SND_PCM_FORMAT_U32_LE; -} -impl _snd_pcm_format { - pub const SND_PCM_FORMAT_FLOAT: _snd_pcm_format = _snd_pcm_format::SND_PCM_FORMAT_FLOAT_LE; -} -impl _snd_pcm_format { - pub const SND_PCM_FORMAT_FLOAT64: _snd_pcm_format = _snd_pcm_format::SND_PCM_FORMAT_FLOAT64_LE; -} -impl _snd_pcm_format { - pub const SND_PCM_FORMAT_IEC958_SUBFRAME: _snd_pcm_format = - _snd_pcm_format::SND_PCM_FORMAT_IEC958_SUBFRAME_LE; -} -impl _snd_pcm_format { - pub const SND_PCM_FORMAT_S20: _snd_pcm_format = _snd_pcm_format::SND_PCM_FORMAT_S20_LE; -} -impl _snd_pcm_format { - pub const SND_PCM_FORMAT_U20: _snd_pcm_format = _snd_pcm_format::SND_PCM_FORMAT_U20_LE; -} -#[repr(i32)] -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] -pub enum _snd_pcm_format { - SND_PCM_FORMAT_UNKNOWN = -1, - SND_PCM_FORMAT_S8 = 0, - SND_PCM_FORMAT_U8 = 1, - SND_PCM_FORMAT_S16_LE = 2, - SND_PCM_FORMAT_S16_BE = 3, - SND_PCM_FORMAT_U16_LE = 4, - SND_PCM_FORMAT_U16_BE = 5, - SND_PCM_FORMAT_S24_LE = 6, - SND_PCM_FORMAT_S24_BE = 7, - SND_PCM_FORMAT_U24_LE = 8, - SND_PCM_FORMAT_U24_BE = 9, - SND_PCM_FORMAT_S32_LE = 10, - SND_PCM_FORMAT_S32_BE = 11, - SND_PCM_FORMAT_U32_LE = 12, - SND_PCM_FORMAT_U32_BE = 13, - SND_PCM_FORMAT_FLOAT_LE = 14, - SND_PCM_FORMAT_FLOAT_BE = 15, - SND_PCM_FORMAT_FLOAT64_LE = 16, - SND_PCM_FORMAT_FLOAT64_BE = 17, - SND_PCM_FORMAT_IEC958_SUBFRAME_LE = 18, - SND_PCM_FORMAT_IEC958_SUBFRAME_BE = 19, - SND_PCM_FORMAT_MU_LAW = 20, - SND_PCM_FORMAT_A_LAW = 21, - SND_PCM_FORMAT_IMA_ADPCM = 22, - SND_PCM_FORMAT_MPEG = 23, - SND_PCM_FORMAT_GSM = 24, - SND_PCM_FORMAT_S20_LE = 25, - SND_PCM_FORMAT_S20_BE = 26, - SND_PCM_FORMAT_U20_LE = 27, - SND_PCM_FORMAT_U20_BE = 28, - SND_PCM_FORMAT_SPECIAL = 31, - SND_PCM_FORMAT_S24_3LE = 32, - SND_PCM_FORMAT_S24_3BE = 33, - SND_PCM_FORMAT_U24_3LE = 34, - SND_PCM_FORMAT_U24_3BE = 35, - SND_PCM_FORMAT_S20_3LE = 36, - SND_PCM_FORMAT_S20_3BE = 37, - SND_PCM_FORMAT_U20_3LE = 38, - SND_PCM_FORMAT_U20_3BE = 39, - SND_PCM_FORMAT_S18_3LE = 40, - SND_PCM_FORMAT_S18_3BE = 41, - SND_PCM_FORMAT_U18_3LE = 42, - SND_PCM_FORMAT_U18_3BE = 43, - SND_PCM_FORMAT_G723_24 = 44, - SND_PCM_FORMAT_G723_24_1B = 45, - SND_PCM_FORMAT_G723_40 = 46, - SND_PCM_FORMAT_G723_40_1B = 47, - SND_PCM_FORMAT_DSD_U8 = 48, - SND_PCM_FORMAT_DSD_U16_LE = 49, - SND_PCM_FORMAT_DSD_U32_LE = 50, - SND_PCM_FORMAT_DSD_U16_BE = 51, - SND_PCM_FORMAT_DSD_U32_BE = 52, -} -pub use self::_snd_pcm_format as snd_pcm_format_t; -#[repr(u32)] -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] -pub enum CRAS_CHANNEL { - CRAS_CH_FL = 0, - CRAS_CH_FR = 1, - CRAS_CH_RL = 2, - CRAS_CH_RR = 3, - CRAS_CH_FC = 4, - CRAS_CH_LFE = 5, - CRAS_CH_SL = 6, - CRAS_CH_SR = 7, - CRAS_CH_RC = 8, - CRAS_CH_FLC = 9, - CRAS_CH_FRC = 10, - CRAS_CH_MAX = 11, -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct cras_audio_format { - pub format: snd_pcm_format_t, - pub frame_rate: usize, - pub num_channels: usize, - pub channel_layout: [i8; 11usize], -} -#[test] -fn bindgen_test_layout_cras_audio_format() { - assert_eq!( - ::std::mem::size_of::<cras_audio_format>(), - 40usize, - concat!("Size of: ", stringify!(cras_audio_format)) - ); - assert_eq!( - ::std::mem::align_of::<cras_audio_format>(), - 8usize, - concat!("Alignment of ", stringify!(cras_audio_format)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_audio_format>())).format as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(cras_audio_format), - "::", - stringify!(format) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_audio_format>())).frame_rate as *const _ as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(cras_audio_format), - "::", - stringify!(frame_rate) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_audio_format>())).num_channels as *const _ as usize }, - 16usize, - concat!( - "Offset of field: ", - stringify!(cras_audio_format), - "::", - stringify!(num_channels) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_audio_format>())).channel_layout as *const _ as usize - }, - 24usize, - concat!( - "Offset of field: ", - stringify!(cras_audio_format), - "::", - stringify!(channel_layout) - ) - ); -} -#[repr(C, packed)] -#[derive(Debug, Copy, Clone)] -pub struct cras_audio_format_packed { - pub format: i32, - pub frame_rate: u32, - pub num_channels: u32, - pub channel_layout: [i8; 11usize], -} -#[test] -fn bindgen_test_layout_cras_audio_format_packed() { - assert_eq!( - ::std::mem::size_of::<cras_audio_format_packed>(), - 23usize, - concat!("Size of: ", stringify!(cras_audio_format_packed)) - ); - assert_eq!( - ::std::mem::align_of::<cras_audio_format_packed>(), - 1usize, - concat!("Alignment of ", stringify!(cras_audio_format_packed)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_audio_format_packed>())).format as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(cras_audio_format_packed), - "::", - stringify!(format) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_audio_format_packed>())).frame_rate as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(cras_audio_format_packed), - "::", - stringify!(frame_rate) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_audio_format_packed>())).num_channels as *const _ as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(cras_audio_format_packed), - "::", - stringify!(num_channels) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_audio_format_packed>())).channel_layout as *const _ as usize - }, - 12usize, - concat!( - "Offset of field: ", - stringify!(cras_audio_format_packed), - "::", - stringify!(channel_layout) - ) - ); -} -#[repr(C)] -#[derive(Copy, Clone)] -pub struct packet_status_logger { - pub data: [u8; 64usize], - pub size: ::std::os::raw::c_int, - pub wp: ::std::os::raw::c_int, - pub num_wraps: ::std::os::raw::c_int, - pub ts: timespec, -} -#[test] -fn bindgen_test_layout_packet_status_logger() { - assert_eq!( - ::std::mem::size_of::<packet_status_logger>(), - 96usize, - concat!("Size of: ", stringify!(packet_status_logger)) - ); - assert_eq!( - ::std::mem::align_of::<packet_status_logger>(), - 8usize, - concat!("Alignment of ", stringify!(packet_status_logger)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<packet_status_logger>())).data as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(packet_status_logger), - "::", - stringify!(data) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<packet_status_logger>())).size as *const _ as usize }, - 64usize, - concat!( - "Offset of field: ", - stringify!(packet_status_logger), - "::", - stringify!(size) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<packet_status_logger>())).wp as *const _ as usize }, - 68usize, - concat!( - "Offset of field: ", - stringify!(packet_status_logger), - "::", - stringify!(wp) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<packet_status_logger>())).num_wraps as *const _ as usize }, - 72usize, - concat!( - "Offset of field: ", - stringify!(packet_status_logger), - "::", - stringify!(num_wraps) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<packet_status_logger>())).ts as *const _ as usize }, - 80usize, - concat!( - "Offset of field: ", - stringify!(packet_status_logger), - "::", - stringify!(ts) - ) - ); -} -#[repr(C, packed)] -#[derive(Debug, Copy, Clone)] -pub struct cras_timespec { - pub tv_sec: i64, - pub tv_nsec: i64, -} -#[test] -fn bindgen_test_layout_cras_timespec() { - assert_eq!( - ::std::mem::size_of::<cras_timespec>(), - 16usize, - concat!("Size of: ", stringify!(cras_timespec)) - ); - assert_eq!( - ::std::mem::align_of::<cras_timespec>(), - 1usize, - concat!("Alignment of ", stringify!(cras_timespec)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_timespec>())).tv_sec as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(cras_timespec), - "::", - stringify!(tv_sec) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_timespec>())).tv_nsec as *const _ as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(cras_timespec), - "::", - stringify!(tv_nsec) - ) - ); -} -#[repr(u32)] -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] -pub enum CRAS_SPECIAL_DEVICE { - NO_DEVICE = 0, - SILENT_RECORD_DEVICE = 1, - SILENT_PLAYBACK_DEVICE = 2, - SILENT_HOTWORD_DEVICE = 3, - MAX_SPECIAL_DEVICE_IDX = 4, -} -pub const TEST_IODEV_TYPE_TEST_IODEV_HOTWORD: TEST_IODEV_TYPE = 0; -pub type TEST_IODEV_TYPE = u32; -#[repr(u32)] -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] -pub enum CRAS_TEST_IODEV_CMD { - TEST_IODEV_CMD_HOTWORD_TRIGGER = 0, -} -#[repr(u32)] -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] -pub enum CRAS_CONNECTION_TYPE { - CRAS_CONTROL = 0, - CRAS_PLAYBACK = 1, - CRAS_CAPTURE = 2, - CRAS_VMS_LEGACY = 3, - CRAS_VMS_UNIFIED = 4, - CRAS_PLUGIN_PLAYBACK = 5, - CRAS_PLUGIN_UNIFIED = 6, - CRAS_NUM_CONN_TYPE = 7, -} -#[repr(u32)] -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] -pub enum CRAS_STREAM_DIRECTION { - CRAS_STREAM_OUTPUT = 0, - CRAS_STREAM_INPUT = 1, - CRAS_STREAM_UNDEFINED = 2, - CRAS_STREAM_POST_MIX_PRE_DSP = 3, - CRAS_NUM_DIRECTIONS = 4, -} -#[repr(u32)] -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] -pub enum CRAS_INPUT_STREAM_FLAG { - BULK_AUDIO_OK = 1, - USE_DEV_TIMING = 2, - HOTWORD_STREAM = 3, - TRIGGER_ONLY = 4, - SERVER_ONLY = 8, -} -#[repr(u32)] -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] -pub enum CRAS_LOOPBACK_TYPE { - LOOPBACK_POST_MIX_PRE_DSP = 0, - LOOPBACK_POST_DSP = 1, - LOOPBACK_NUM_TYPES = 2, -} -#[repr(u32)] -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] -pub enum CRAS_STREAM_TYPE { - CRAS_STREAM_TYPE_DEFAULT = 0, - CRAS_STREAM_TYPE_MULTIMEDIA = 1, - CRAS_STREAM_TYPE_VOICE_COMMUNICATION = 2, - CRAS_STREAM_TYPE_SPEECH_RECOGNITION = 3, - CRAS_STREAM_TYPE_PRO_AUDIO = 4, - CRAS_STREAM_TYPE_ACCESSIBILITY = 5, - CRAS_STREAM_NUM_TYPES = 6, -} -#[repr(u32)] -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] -pub enum CRAS_CLIENT_TYPE { - CRAS_CLIENT_TYPE_UNKNOWN = 0, - CRAS_CLIENT_TYPE_LEGACY = 1, - CRAS_CLIENT_TYPE_TEST = 2, - CRAS_CLIENT_TYPE_PCM = 3, - CRAS_CLIENT_TYPE_CHROME = 4, - CRAS_CLIENT_TYPE_ARC = 5, - CRAS_CLIENT_TYPE_CROSVM = 6, - CRAS_CLIENT_TYPE_SERVER_STREAM = 7, - CRAS_CLIENT_TYPE_LACROS = 8, - CRAS_CLIENT_TYPE_PLUGIN = 9, - CRAS_CLIENT_TYPE_ARCVM = 10, - CRAS_NUM_CLIENT_TYPE = 11, -} -impl CRAS_STREAM_EFFECT { - pub const APM_ECHO_CANCELLATION: CRAS_STREAM_EFFECT = CRAS_STREAM_EFFECT(1); -} -impl CRAS_STREAM_EFFECT { - pub const APM_NOISE_SUPRESSION: CRAS_STREAM_EFFECT = CRAS_STREAM_EFFECT(2); -} -impl CRAS_STREAM_EFFECT { - pub const APM_GAIN_CONTROL: CRAS_STREAM_EFFECT = CRAS_STREAM_EFFECT(4); -} -impl CRAS_STREAM_EFFECT { - pub const APM_VOICE_DETECTION: CRAS_STREAM_EFFECT = CRAS_STREAM_EFFECT(8); -} -impl ::std::ops::BitOr<CRAS_STREAM_EFFECT> for CRAS_STREAM_EFFECT { - type Output = Self; - #[inline] - fn bitor(self, other: Self) -> Self { - CRAS_STREAM_EFFECT(self.0 | other.0) - } -} -impl ::std::ops::BitOrAssign for CRAS_STREAM_EFFECT { - #[inline] - fn bitor_assign(&mut self, rhs: CRAS_STREAM_EFFECT) { - self.0 |= rhs.0; - } -} -impl ::std::ops::BitAnd<CRAS_STREAM_EFFECT> for CRAS_STREAM_EFFECT { - type Output = Self; - #[inline] - fn bitand(self, other: Self) -> Self { - CRAS_STREAM_EFFECT(self.0 & other.0) - } -} -impl ::std::ops::BitAndAssign for CRAS_STREAM_EFFECT { - #[inline] - fn bitand_assign(&mut self, rhs: CRAS_STREAM_EFFECT) { - self.0 &= rhs.0; - } -} -#[repr(C)] -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] -pub struct CRAS_STREAM_EFFECT(pub u32); -#[repr(C, packed)] -#[derive(Debug, Copy, Clone)] -pub struct cras_attached_client_info { - pub id: u32, - pub pid: i32, - pub uid: u32, - pub gid: u32, -} -#[test] -fn bindgen_test_layout_cras_attached_client_info() { - assert_eq!( - ::std::mem::size_of::<cras_attached_client_info>(), - 16usize, - concat!("Size of: ", stringify!(cras_attached_client_info)) - ); - assert_eq!( - ::std::mem::align_of::<cras_attached_client_info>(), - 1usize, - concat!("Alignment of ", stringify!(cras_attached_client_info)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_attached_client_info>())).id as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(cras_attached_client_info), - "::", - stringify!(id) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_attached_client_info>())).pid as *const _ as usize }, - 4usize, - concat!( - "Offset of field: ", - stringify!(cras_attached_client_info), - "::", - stringify!(pid) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_attached_client_info>())).uid as *const _ as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(cras_attached_client_info), - "::", - stringify!(uid) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_attached_client_info>())).gid as *const _ as usize }, - 12usize, - concat!( - "Offset of field: ", - stringify!(cras_attached_client_info), - "::", - stringify!(gid) - ) - ); -} -pub type cras_node_id_t = u64; -#[repr(u32)] -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] -pub enum CRAS_BT_LOG_EVENTS { - BT_ADAPTER_ADDED = 0, - BT_ADAPTER_REMOVED = 1, - BT_AUDIO_GATEWAY_INIT = 2, - BT_AUDIO_GATEWAY_START = 3, - BT_AVAILABLE_CODECS = 4, - BT_A2DP_CONFIGURED = 5, - BT_A2DP_START = 6, - BT_A2DP_SUSPENDED = 7, - BT_CODEC_SELECTION = 8, - BT_DEV_CONNECTED = 9, - BT_DEV_DISCONNECTED = 10, - BT_DEV_CONN_WATCH_CB = 11, - BT_DEV_SUSPEND_CB = 12, - BT_HFP_NEW_CONNECTION = 13, - BT_HFP_REQUEST_DISCONNECT = 14, - BT_HFP_SUPPORTED_FEATURES = 15, - BT_HFP_HF_INDICATOR = 16, - BT_HFP_SET_SPEAKER_GAIN = 17, - BT_HFP_UPDATE_SPEAKER_GAIN = 18, - BT_HSP_NEW_CONNECTION = 19, - BT_HSP_REQUEST_DISCONNECT = 20, - BT_NEW_AUDIO_PROFILE_AFTER_CONNECT = 21, - BT_RESET = 22, - BT_SCO_CONNECT = 23, - BT_TRANSPORT_ACQUIRE = 24, - BT_TRANSPORT_RELEASE = 25, - BT_TRANSPORT_SET_VOLUME = 26, - BT_TRANSPORT_UPDATE_VOLUME = 27, -} -#[repr(C, packed)] -#[derive(Debug, Copy, Clone)] -pub struct audio_thread_event { - pub tag_sec: u32, - pub nsec: u32, - pub data1: u32, - pub data2: u32, - pub data3: u32, -} -#[test] -fn bindgen_test_layout_audio_thread_event() { - assert_eq!( - ::std::mem::size_of::<audio_thread_event>(), - 20usize, - concat!("Size of: ", stringify!(audio_thread_event)) - ); - assert_eq!( - ::std::mem::align_of::<audio_thread_event>(), - 1usize, - concat!("Alignment of ", stringify!(audio_thread_event)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<audio_thread_event>())).tag_sec as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(audio_thread_event), - "::", - stringify!(tag_sec) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<audio_thread_event>())).nsec as *const _ as usize }, - 4usize, - concat!( - "Offset of field: ", - stringify!(audio_thread_event), - "::", - stringify!(nsec) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<audio_thread_event>())).data1 as *const _ as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(audio_thread_event), - "::", - stringify!(data1) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<audio_thread_event>())).data2 as *const _ as usize }, - 12usize, - concat!( - "Offset of field: ", - stringify!(audio_thread_event), - "::", - stringify!(data2) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<audio_thread_event>())).data3 as *const _ as usize }, - 16usize, - concat!( - "Offset of field: ", - stringify!(audio_thread_event), - "::", - stringify!(data3) - ) - ); -} -#[repr(C, packed)] -#[derive(Copy, Clone)] -pub struct audio_thread_event_log { - pub write_pos: u64, - pub sync_write_pos: u64, - pub len: u32, - pub log: [audio_thread_event; 6144usize], -} -#[test] -fn bindgen_test_layout_audio_thread_event_log() { - assert_eq!( - ::std::mem::size_of::<audio_thread_event_log>(), - 122900usize, - concat!("Size of: ", stringify!(audio_thread_event_log)) - ); - assert_eq!( - ::std::mem::align_of::<audio_thread_event_log>(), - 1usize, - concat!("Alignment of ", stringify!(audio_thread_event_log)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<audio_thread_event_log>())).write_pos as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(audio_thread_event_log), - "::", - stringify!(write_pos) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<audio_thread_event_log>())).sync_write_pos as *const _ as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(audio_thread_event_log), - "::", - stringify!(sync_write_pos) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<audio_thread_event_log>())).len as *const _ as usize }, - 16usize, - concat!( - "Offset of field: ", - stringify!(audio_thread_event_log), - "::", - stringify!(len) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<audio_thread_event_log>())).log as *const _ as usize }, - 20usize, - concat!( - "Offset of field: ", - stringify!(audio_thread_event_log), - "::", - stringify!(log) - ) - ); -} -#[repr(C, packed)] -#[derive(Copy, Clone)] -pub struct audio_dev_debug_info { - pub dev_name: [::std::os::raw::c_char; 64usize], - 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: u8, - pub num_underruns: u32, - pub num_severe_underruns: u32, - pub highest_hw_level: u32, - pub runtime_sec: u32, - pub runtime_nsec: u32, - pub longest_wake_sec: u32, - pub longest_wake_nsec: u32, - pub software_gain_scaler: f64, -} -#[test] -fn bindgen_test_layout_audio_dev_debug_info() { - assert_eq!( - ::std::mem::size_of::<audio_dev_debug_info>(), - 133usize, - concat!("Size of: ", stringify!(audio_dev_debug_info)) - ); - assert_eq!( - ::std::mem::align_of::<audio_dev_debug_info>(), - 1usize, - concat!("Alignment of ", stringify!(audio_dev_debug_info)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<audio_dev_debug_info>())).dev_name as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(audio_dev_debug_info), - "::", - stringify!(dev_name) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<audio_dev_debug_info>())).buffer_size as *const _ as usize - }, - 64usize, - concat!( - "Offset of field: ", - stringify!(audio_dev_debug_info), - "::", - stringify!(buffer_size) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<audio_dev_debug_info>())).min_buffer_level as *const _ as usize - }, - 68usize, - concat!( - "Offset of field: ", - stringify!(audio_dev_debug_info), - "::", - stringify!(min_buffer_level) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<audio_dev_debug_info>())).min_cb_level as *const _ as usize - }, - 72usize, - concat!( - "Offset of field: ", - stringify!(audio_dev_debug_info), - "::", - stringify!(min_cb_level) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<audio_dev_debug_info>())).max_cb_level as *const _ as usize - }, - 76usize, - concat!( - "Offset of field: ", - stringify!(audio_dev_debug_info), - "::", - stringify!(max_cb_level) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<audio_dev_debug_info>())).frame_rate as *const _ as usize }, - 80usize, - concat!( - "Offset of field: ", - stringify!(audio_dev_debug_info), - "::", - stringify!(frame_rate) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<audio_dev_debug_info>())).num_channels as *const _ as usize - }, - 84usize, - concat!( - "Offset of field: ", - stringify!(audio_dev_debug_info), - "::", - stringify!(num_channels) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<audio_dev_debug_info>())).est_rate_ratio as *const _ as usize - }, - 88usize, - concat!( - "Offset of field: ", - stringify!(audio_dev_debug_info), - "::", - stringify!(est_rate_ratio) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<audio_dev_debug_info>())).direction as *const _ as usize }, - 96usize, - concat!( - "Offset of field: ", - stringify!(audio_dev_debug_info), - "::", - stringify!(direction) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<audio_dev_debug_info>())).num_underruns as *const _ as usize - }, - 97usize, - concat!( - "Offset of field: ", - stringify!(audio_dev_debug_info), - "::", - stringify!(num_underruns) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<audio_dev_debug_info>())).num_severe_underruns as *const _ - as usize - }, - 101usize, - concat!( - "Offset of field: ", - stringify!(audio_dev_debug_info), - "::", - stringify!(num_severe_underruns) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<audio_dev_debug_info>())).highest_hw_level as *const _ as usize - }, - 105usize, - concat!( - "Offset of field: ", - stringify!(audio_dev_debug_info), - "::", - stringify!(highest_hw_level) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<audio_dev_debug_info>())).runtime_sec as *const _ as usize - }, - 109usize, - concat!( - "Offset of field: ", - stringify!(audio_dev_debug_info), - "::", - stringify!(runtime_sec) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<audio_dev_debug_info>())).runtime_nsec as *const _ as usize - }, - 113usize, - concat!( - "Offset of field: ", - stringify!(audio_dev_debug_info), - "::", - stringify!(runtime_nsec) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<audio_dev_debug_info>())).longest_wake_sec as *const _ as usize - }, - 117usize, - concat!( - "Offset of field: ", - stringify!(audio_dev_debug_info), - "::", - stringify!(longest_wake_sec) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<audio_dev_debug_info>())).longest_wake_nsec as *const _ as usize - }, - 121usize, - concat!( - "Offset of field: ", - stringify!(audio_dev_debug_info), - "::", - stringify!(longest_wake_nsec) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<audio_dev_debug_info>())).software_gain_scaler as *const _ - as usize - }, - 125usize, - concat!( - "Offset of field: ", - stringify!(audio_dev_debug_info), - "::", - stringify!(software_gain_scaler) - ) - ); -} -#[repr(C, packed)] -#[derive(Debug, Copy, Clone)] -pub struct audio_stream_debug_info { - pub stream_id: u64, - pub dev_idx: u32, - pub direction: u32, - pub stream_type: u32, - pub client_type: u32, - 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_sec: u32, - pub longest_fetch_nsec: u32, - pub num_missed_cb: u32, - pub num_overruns: u32, - pub is_pinned: u32, - pub pinned_dev_idx: u32, - pub runtime_sec: u32, - pub runtime_nsec: u32, - pub stream_volume: f64, - pub channel_layout: [i8; 11usize], -} -#[test] -fn bindgen_test_layout_audio_stream_debug_info() { - assert_eq!( - ::std::mem::size_of::<audio_stream_debug_info>(), - 103usize, - concat!("Size of: ", stringify!(audio_stream_debug_info)) - ); - assert_eq!( - ::std::mem::align_of::<audio_stream_debug_info>(), - 1usize, - concat!("Alignment of ", stringify!(audio_stream_debug_info)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<audio_stream_debug_info>())).stream_id as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(audio_stream_debug_info), - "::", - stringify!(stream_id) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<audio_stream_debug_info>())).dev_idx as *const _ as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(audio_stream_debug_info), - "::", - stringify!(dev_idx) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<audio_stream_debug_info>())).direction as *const _ as usize - }, - 12usize, - concat!( - "Offset of field: ", - stringify!(audio_stream_debug_info), - "::", - stringify!(direction) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<audio_stream_debug_info>())).stream_type as *const _ as usize - }, - 16usize, - concat!( - "Offset of field: ", - stringify!(audio_stream_debug_info), - "::", - stringify!(stream_type) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<audio_stream_debug_info>())).client_type as *const _ as usize - }, - 20usize, - concat!( - "Offset of field: ", - stringify!(audio_stream_debug_info), - "::", - stringify!(client_type) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<audio_stream_debug_info>())).buffer_frames as *const _ as usize - }, - 24usize, - concat!( - "Offset of field: ", - stringify!(audio_stream_debug_info), - "::", - stringify!(buffer_frames) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<audio_stream_debug_info>())).cb_threshold as *const _ as usize - }, - 28usize, - concat!( - "Offset of field: ", - stringify!(audio_stream_debug_info), - "::", - stringify!(cb_threshold) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<audio_stream_debug_info>())).effects as *const _ as usize }, - 32usize, - concat!( - "Offset of field: ", - stringify!(audio_stream_debug_info), - "::", - stringify!(effects) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<audio_stream_debug_info>())).flags as *const _ as usize }, - 40usize, - concat!( - "Offset of field: ", - stringify!(audio_stream_debug_info), - "::", - stringify!(flags) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<audio_stream_debug_info>())).frame_rate as *const _ as usize - }, - 44usize, - concat!( - "Offset of field: ", - stringify!(audio_stream_debug_info), - "::", - stringify!(frame_rate) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<audio_stream_debug_info>())).num_channels as *const _ as usize - }, - 48usize, - concat!( - "Offset of field: ", - stringify!(audio_stream_debug_info), - "::", - stringify!(num_channels) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<audio_stream_debug_info>())).longest_fetch_sec as *const _ - as usize - }, - 52usize, - concat!( - "Offset of field: ", - stringify!(audio_stream_debug_info), - "::", - stringify!(longest_fetch_sec) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<audio_stream_debug_info>())).longest_fetch_nsec as *const _ - as usize - }, - 56usize, - concat!( - "Offset of field: ", - stringify!(audio_stream_debug_info), - "::", - stringify!(longest_fetch_nsec) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<audio_stream_debug_info>())).num_missed_cb as *const _ as usize - }, - 60usize, - concat!( - "Offset of field: ", - stringify!(audio_stream_debug_info), - "::", - stringify!(num_missed_cb) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<audio_stream_debug_info>())).num_overruns as *const _ as usize - }, - 64usize, - concat!( - "Offset of field: ", - stringify!(audio_stream_debug_info), - "::", - stringify!(num_overruns) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<audio_stream_debug_info>())).is_pinned as *const _ as usize - }, - 68usize, - concat!( - "Offset of field: ", - stringify!(audio_stream_debug_info), - "::", - stringify!(is_pinned) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<audio_stream_debug_info>())).pinned_dev_idx as *const _ as usize - }, - 72usize, - concat!( - "Offset of field: ", - stringify!(audio_stream_debug_info), - "::", - stringify!(pinned_dev_idx) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<audio_stream_debug_info>())).runtime_sec as *const _ as usize - }, - 76usize, - concat!( - "Offset of field: ", - stringify!(audio_stream_debug_info), - "::", - stringify!(runtime_sec) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<audio_stream_debug_info>())).runtime_nsec as *const _ as usize - }, - 80usize, - concat!( - "Offset of field: ", - stringify!(audio_stream_debug_info), - "::", - stringify!(runtime_nsec) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<audio_stream_debug_info>())).stream_volume as *const _ as usize - }, - 84usize, - concat!( - "Offset of field: ", - stringify!(audio_stream_debug_info), - "::", - stringify!(stream_volume) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<audio_stream_debug_info>())).channel_layout as *const _ as usize - }, - 92usize, - concat!( - "Offset of field: ", - stringify!(audio_stream_debug_info), - "::", - stringify!(channel_layout) - ) - ); -} -#[repr(C, packed)] -#[derive(Copy, Clone)] -pub struct audio_debug_info { - pub num_streams: u32, - pub num_devs: u32, - pub devs: [audio_dev_debug_info; 4usize], - pub streams: [audio_stream_debug_info; 8usize], - pub log: audio_thread_event_log, -} -#[test] -fn bindgen_test_layout_audio_debug_info() { - assert_eq!( - ::std::mem::size_of::<audio_debug_info>(), - 124264usize, - concat!("Size of: ", stringify!(audio_debug_info)) - ); - assert_eq!( - ::std::mem::align_of::<audio_debug_info>(), - 1usize, - concat!("Alignment of ", stringify!(audio_debug_info)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<audio_debug_info>())).num_streams as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(audio_debug_info), - "::", - stringify!(num_streams) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<audio_debug_info>())).num_devs as *const _ as usize }, - 4usize, - concat!( - "Offset of field: ", - stringify!(audio_debug_info), - "::", - stringify!(num_devs) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<audio_debug_info>())).devs as *const _ as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(audio_debug_info), - "::", - stringify!(devs) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<audio_debug_info>())).streams as *const _ as usize }, - 540usize, - concat!( - "Offset of field: ", - stringify!(audio_debug_info), - "::", - stringify!(streams) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<audio_debug_info>())).log as *const _ as usize }, - 1364usize, - concat!( - "Offset of field: ", - stringify!(audio_debug_info), - "::", - stringify!(log) - ) - ); -} -#[repr(C, packed)] -#[derive(Debug, Copy, Clone)] -pub struct main_thread_event { - pub tag_sec: u32, - pub nsec: u32, - pub data1: u32, - pub data2: u32, - pub data3: u32, -} -#[test] -fn bindgen_test_layout_main_thread_event() { - assert_eq!( - ::std::mem::size_of::<main_thread_event>(), - 20usize, - concat!("Size of: ", stringify!(main_thread_event)) - ); - assert_eq!( - ::std::mem::align_of::<main_thread_event>(), - 1usize, - concat!("Alignment of ", stringify!(main_thread_event)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<main_thread_event>())).tag_sec as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(main_thread_event), - "::", - stringify!(tag_sec) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<main_thread_event>())).nsec as *const _ as usize }, - 4usize, - concat!( - "Offset of field: ", - stringify!(main_thread_event), - "::", - stringify!(nsec) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<main_thread_event>())).data1 as *const _ as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(main_thread_event), - "::", - stringify!(data1) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<main_thread_event>())).data2 as *const _ as usize }, - 12usize, - concat!( - "Offset of field: ", - stringify!(main_thread_event), - "::", - stringify!(data2) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<main_thread_event>())).data3 as *const _ as usize }, - 16usize, - concat!( - "Offset of field: ", - stringify!(main_thread_event), - "::", - stringify!(data3) - ) - ); -} -#[repr(C, packed)] -#[derive(Copy, Clone)] -pub struct main_thread_event_log { - pub write_pos: u32, - pub len: u32, - pub log: [main_thread_event; 1024usize], -} -#[test] -fn bindgen_test_layout_main_thread_event_log() { - assert_eq!( - ::std::mem::size_of::<main_thread_event_log>(), - 20488usize, - concat!("Size of: ", stringify!(main_thread_event_log)) - ); - assert_eq!( - ::std::mem::align_of::<main_thread_event_log>(), - 1usize, - concat!("Alignment of ", stringify!(main_thread_event_log)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<main_thread_event_log>())).write_pos as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(main_thread_event_log), - "::", - stringify!(write_pos) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<main_thread_event_log>())).len as *const _ as usize }, - 4usize, - concat!( - "Offset of field: ", - stringify!(main_thread_event_log), - "::", - stringify!(len) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<main_thread_event_log>())).log as *const _ as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(main_thread_event_log), - "::", - stringify!(log) - ) - ); -} -#[repr(C, packed)] -#[derive(Copy, Clone)] -pub struct main_thread_debug_info { - pub main_log: main_thread_event_log, -} -#[test] -fn bindgen_test_layout_main_thread_debug_info() { - assert_eq!( - ::std::mem::size_of::<main_thread_debug_info>(), - 20488usize, - concat!("Size of: ", stringify!(main_thread_debug_info)) - ); - assert_eq!( - ::std::mem::align_of::<main_thread_debug_info>(), - 1usize, - concat!("Alignment of ", stringify!(main_thread_debug_info)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<main_thread_debug_info>())).main_log as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(main_thread_debug_info), - "::", - stringify!(main_log) - ) - ); -} -#[repr(C, packed)] -#[derive(Debug, Copy, Clone)] -pub struct cras_bt_event { - pub tag_sec: u32, - pub nsec: u32, - pub data1: u32, - pub data2: u32, -} -#[test] -fn bindgen_test_layout_cras_bt_event() { - assert_eq!( - ::std::mem::size_of::<cras_bt_event>(), - 16usize, - concat!("Size of: ", stringify!(cras_bt_event)) - ); - assert_eq!( - ::std::mem::align_of::<cras_bt_event>(), - 1usize, - concat!("Alignment of ", stringify!(cras_bt_event)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_bt_event>())).tag_sec as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(cras_bt_event), - "::", - stringify!(tag_sec) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_bt_event>())).nsec as *const _ as usize }, - 4usize, - concat!( - "Offset of field: ", - stringify!(cras_bt_event), - "::", - stringify!(nsec) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_bt_event>())).data1 as *const _ as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(cras_bt_event), - "::", - stringify!(data1) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_bt_event>())).data2 as *const _ as usize }, - 12usize, - concat!( - "Offset of field: ", - stringify!(cras_bt_event), - "::", - stringify!(data2) - ) - ); -} -#[repr(C, packed)] -#[derive(Copy, Clone)] -pub struct cras_bt_event_log { - pub write_pos: u32, - pub len: u32, - pub log: [cras_bt_event; 1024usize], -} -#[test] -fn bindgen_test_layout_cras_bt_event_log() { - assert_eq!( - ::std::mem::size_of::<cras_bt_event_log>(), - 16392usize, - concat!("Size of: ", stringify!(cras_bt_event_log)) - ); - assert_eq!( - ::std::mem::align_of::<cras_bt_event_log>(), - 1usize, - concat!("Alignment of ", stringify!(cras_bt_event_log)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_bt_event_log>())).write_pos as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(cras_bt_event_log), - "::", - stringify!(write_pos) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_bt_event_log>())).len as *const _ as usize }, - 4usize, - concat!( - "Offset of field: ", - stringify!(cras_bt_event_log), - "::", - stringify!(len) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_bt_event_log>())).log as *const _ as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(cras_bt_event_log), - "::", - stringify!(log) - ) - ); -} -#[repr(C, packed)] -#[derive(Copy, Clone)] -pub struct cras_bt_debug_info { - pub bt_log: cras_bt_event_log, - pub wbs_logger: packet_status_logger, -} -#[test] -fn bindgen_test_layout_cras_bt_debug_info() { - assert_eq!( - ::std::mem::size_of::<cras_bt_debug_info>(), - 16488usize, - concat!("Size of: ", stringify!(cras_bt_debug_info)) - ); - assert_eq!( - ::std::mem::align_of::<cras_bt_debug_info>(), - 1usize, - concat!("Alignment of ", stringify!(cras_bt_debug_info)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_bt_debug_info>())).bt_log as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(cras_bt_debug_info), - "::", - stringify!(bt_log) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_bt_debug_info>())).wbs_logger as *const _ as usize }, - 16392usize, - concat!( - "Offset of field: ", - stringify!(cras_bt_debug_info), - "::", - stringify!(wbs_logger) - ) - ); -} -#[repr(u32)] -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] -pub enum CRAS_AUDIO_THREAD_EVENT_TYPE { - AUDIO_THREAD_EVENT_A2DP_OVERRUN = 0, - AUDIO_THREAD_EVENT_A2DP_THROTTLE = 1, - AUDIO_THREAD_EVENT_BUSYLOOP = 2, - AUDIO_THREAD_EVENT_DEBUG = 3, - AUDIO_THREAD_EVENT_SEVERE_UNDERRUN = 4, - AUDIO_THREAD_EVENT_UNDERRUN = 5, - AUDIO_THREAD_EVENT_DROP_SAMPLES = 6, - AUDIO_THREAD_EVENT_DEV_OVERRUN = 7, - AUDIO_THREAD_EVENT_TYPE_COUNT = 8, -} -#[repr(C, packed)] -#[derive(Copy, Clone)] -pub struct cras_audio_thread_snapshot { - pub timestamp: timespec, - pub event_type: CRAS_AUDIO_THREAD_EVENT_TYPE, - pub audio_debug_info: audio_debug_info, -} -#[test] -fn bindgen_test_layout_cras_audio_thread_snapshot() { - assert_eq!( - ::std::mem::size_of::<cras_audio_thread_snapshot>(), - 124284usize, - concat!("Size of: ", stringify!(cras_audio_thread_snapshot)) - ); - assert_eq!( - ::std::mem::align_of::<cras_audio_thread_snapshot>(), - 1usize, - concat!("Alignment of ", stringify!(cras_audio_thread_snapshot)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_audio_thread_snapshot>())).timestamp as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(cras_audio_thread_snapshot), - "::", - stringify!(timestamp) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_audio_thread_snapshot>())).event_type as *const _ as usize - }, - 16usize, - concat!( - "Offset of field: ", - stringify!(cras_audio_thread_snapshot), - "::", - stringify!(event_type) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_audio_thread_snapshot>())).audio_debug_info as *const _ - as usize - }, - 20usize, - concat!( - "Offset of field: ", - stringify!(cras_audio_thread_snapshot), - "::", - stringify!(audio_debug_info) - ) - ); -} -#[repr(C, packed)] -#[derive(Copy, Clone)] -pub struct cras_audio_thread_snapshot_buffer { - pub snapshots: [cras_audio_thread_snapshot; 10usize], - pub pos: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_cras_audio_thread_snapshot_buffer() { - assert_eq!( - ::std::mem::size_of::<cras_audio_thread_snapshot_buffer>(), - 1242844usize, - concat!("Size of: ", stringify!(cras_audio_thread_snapshot_buffer)) - ); - assert_eq!( - ::std::mem::align_of::<cras_audio_thread_snapshot_buffer>(), - 1usize, - concat!( - "Alignment of ", - stringify!(cras_audio_thread_snapshot_buffer) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_audio_thread_snapshot_buffer>())).snapshots as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(cras_audio_thread_snapshot_buffer), - "::", - stringify!(snapshots) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_audio_thread_snapshot_buffer>())).pos as *const _ as usize - }, - 1242840usize, - concat!( - "Offset of field: ", - stringify!(cras_audio_thread_snapshot_buffer), - "::", - stringify!(pos) - ) - ); -} -#[repr(C, packed)] -#[derive(Copy, Clone)] -pub struct cras_server_state { - pub state_version: u32, - pub volume: u32, - pub min_volume_dBFS: i32, - pub max_volume_dBFS: i32, - pub mute: i32, - pub user_mute: i32, - pub mute_locked: i32, - pub suspended: i32, - pub capture_gain: i32, - pub capture_mute: i32, - pub capture_mute_locked: i32, - pub num_streams_attached: u32, - pub num_output_devs: u32, - pub num_input_devs: u32, - pub output_devs: [cras_iodev_info; 20usize], - pub input_devs: [cras_iodev_info; 20usize], - pub num_output_nodes: u32, - pub num_input_nodes: u32, - pub output_nodes: [cras_ionode_info; 20usize], - pub input_nodes: [cras_ionode_info; 20usize], - pub num_attached_clients: u32, - pub client_info: [cras_attached_client_info; 20usize], - pub update_count: u32, - pub num_active_streams: [u32; 4usize], - pub last_active_stream_time: cras_timespec, - pub audio_debug_info: audio_debug_info, - pub default_output_buffer_size: i32, - pub non_empty_status: i32, - pub aec_supported: i32, - pub aec_group_id: i32, - pub snapshot_buffer: cras_audio_thread_snapshot_buffer, - pub bt_debug_info: cras_bt_debug_info, - pub bt_wbs_enabled: i32, - pub deprioritize_bt_wbs_mic: i32, - pub main_thread_debug_info: main_thread_debug_info, - pub num_input_streams_with_permission: [u32; 11usize], - pub noise_cancellation_enabled: i32, - pub hotword_pause_at_suspend: i32, -} -#[test] -fn bindgen_test_layout_cras_server_state() { - assert_eq!( - ::std::mem::size_of::<cras_server_state>(), - 1414344usize, - concat!("Size of: ", stringify!(cras_server_state)) - ); - assert_eq!( - ::std::mem::align_of::<cras_server_state>(), - 1usize, - concat!("Alignment of ", stringify!(cras_server_state)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_server_state>())).state_version as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(cras_server_state), - "::", - stringify!(state_version) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_server_state>())).volume as *const _ as usize }, - 4usize, - concat!( - "Offset of field: ", - stringify!(cras_server_state), - "::", - stringify!(volume) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_server_state>())).min_volume_dBFS as *const _ as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(cras_server_state), - "::", - stringify!(min_volume_dBFS) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_server_state>())).max_volume_dBFS as *const _ as usize - }, - 12usize, - concat!( - "Offset of field: ", - stringify!(cras_server_state), - "::", - stringify!(max_volume_dBFS) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_server_state>())).mute as *const _ as usize }, - 16usize, - concat!( - "Offset of field: ", - stringify!(cras_server_state), - "::", - stringify!(mute) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_server_state>())).user_mute as *const _ as usize }, - 20usize, - concat!( - "Offset of field: ", - stringify!(cras_server_state), - "::", - stringify!(user_mute) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_server_state>())).mute_locked as *const _ as usize }, - 24usize, - concat!( - "Offset of field: ", - stringify!(cras_server_state), - "::", - stringify!(mute_locked) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_server_state>())).suspended as *const _ as usize }, - 28usize, - concat!( - "Offset of field: ", - stringify!(cras_server_state), - "::", - stringify!(suspended) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_server_state>())).capture_gain as *const _ as usize }, - 32usize, - concat!( - "Offset of field: ", - stringify!(cras_server_state), - "::", - stringify!(capture_gain) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_server_state>())).capture_mute as *const _ as usize }, - 36usize, - concat!( - "Offset of field: ", - stringify!(cras_server_state), - "::", - stringify!(capture_mute) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_server_state>())).capture_mute_locked as *const _ as usize - }, - 40usize, - concat!( - "Offset of field: ", - stringify!(cras_server_state), - "::", - stringify!(capture_mute_locked) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_server_state>())).num_streams_attached as *const _ as usize - }, - 44usize, - concat!( - "Offset of field: ", - stringify!(cras_server_state), - "::", - stringify!(num_streams_attached) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_server_state>())).num_output_devs as *const _ as usize - }, - 48usize, - concat!( - "Offset of field: ", - stringify!(cras_server_state), - "::", - stringify!(num_output_devs) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_server_state>())).num_input_devs as *const _ as usize - }, - 52usize, - concat!( - "Offset of field: ", - stringify!(cras_server_state), - "::", - stringify!(num_input_devs) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_server_state>())).output_devs as *const _ as usize }, - 56usize, - concat!( - "Offset of field: ", - stringify!(cras_server_state), - "::", - stringify!(output_devs) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_server_state>())).input_devs as *const _ as usize }, - 1576usize, - concat!( - "Offset of field: ", - stringify!(cras_server_state), - "::", - stringify!(input_devs) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_server_state>())).num_output_nodes as *const _ as usize - }, - 3096usize, - concat!( - "Offset of field: ", - stringify!(cras_server_state), - "::", - stringify!(num_output_nodes) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_server_state>())).num_input_nodes as *const _ as usize - }, - 3100usize, - concat!( - "Offset of field: ", - stringify!(cras_server_state), - "::", - stringify!(num_input_nodes) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_server_state>())).output_nodes as *const _ as usize }, - 3104usize, - concat!( - "Offset of field: ", - stringify!(cras_server_state), - "::", - stringify!(output_nodes) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_server_state>())).input_nodes as *const _ as usize }, - 6464usize, - concat!( - "Offset of field: ", - stringify!(cras_server_state), - "::", - stringify!(input_nodes) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_server_state>())).num_attached_clients as *const _ as usize - }, - 9824usize, - concat!( - "Offset of field: ", - stringify!(cras_server_state), - "::", - stringify!(num_attached_clients) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_server_state>())).client_info as *const _ as usize }, - 9828usize, - concat!( - "Offset of field: ", - stringify!(cras_server_state), - "::", - stringify!(client_info) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_server_state>())).update_count as *const _ as usize }, - 10148usize, - concat!( - "Offset of field: ", - stringify!(cras_server_state), - "::", - stringify!(update_count) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_server_state>())).num_active_streams as *const _ as usize - }, - 10152usize, - concat!( - "Offset of field: ", - stringify!(cras_server_state), - "::", - stringify!(num_active_streams) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_server_state>())).last_active_stream_time as *const _ - as usize - }, - 10168usize, - concat!( - "Offset of field: ", - stringify!(cras_server_state), - "::", - stringify!(last_active_stream_time) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_server_state>())).audio_debug_info as *const _ as usize - }, - 10184usize, - concat!( - "Offset of field: ", - stringify!(cras_server_state), - "::", - stringify!(audio_debug_info) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_server_state>())).default_output_buffer_size as *const _ - as usize - }, - 134448usize, - concat!( - "Offset of field: ", - stringify!(cras_server_state), - "::", - stringify!(default_output_buffer_size) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_server_state>())).non_empty_status as *const _ as usize - }, - 134452usize, - concat!( - "Offset of field: ", - stringify!(cras_server_state), - "::", - stringify!(non_empty_status) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_server_state>())).aec_supported as *const _ as usize }, - 134456usize, - concat!( - "Offset of field: ", - stringify!(cras_server_state), - "::", - stringify!(aec_supported) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_server_state>())).aec_group_id as *const _ as usize }, - 134460usize, - concat!( - "Offset of field: ", - stringify!(cras_server_state), - "::", - stringify!(aec_group_id) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_server_state>())).snapshot_buffer as *const _ as usize - }, - 134464usize, - concat!( - "Offset of field: ", - stringify!(cras_server_state), - "::", - stringify!(snapshot_buffer) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_server_state>())).bt_debug_info as *const _ as usize }, - 1377308usize, - concat!( - "Offset of field: ", - stringify!(cras_server_state), - "::", - stringify!(bt_debug_info) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_server_state>())).bt_wbs_enabled as *const _ as usize - }, - 1393796usize, - concat!( - "Offset of field: ", - stringify!(cras_server_state), - "::", - stringify!(bt_wbs_enabled) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_server_state>())).deprioritize_bt_wbs_mic as *const _ - as usize - }, - 1393800usize, - concat!( - "Offset of field: ", - stringify!(cras_server_state), - "::", - stringify!(deprioritize_bt_wbs_mic) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_server_state>())).main_thread_debug_info as *const _ - as usize - }, - 1393804usize, - concat!( - "Offset of field: ", - stringify!(cras_server_state), - "::", - stringify!(main_thread_debug_info) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_server_state>())).num_input_streams_with_permission - as *const _ as usize - }, - 1414292usize, - concat!( - "Offset of field: ", - stringify!(cras_server_state), - "::", - stringify!(num_input_streams_with_permission) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_server_state>())).noise_cancellation_enabled as *const _ - as usize - }, - 1414336usize, - concat!( - "Offset of field: ", - stringify!(cras_server_state), - "::", - stringify!(noise_cancellation_enabled) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_server_state>())).hotword_pause_at_suspend as *const _ - as usize - }, - 1414340usize, - concat!( - "Offset of field: ", - stringify!(cras_server_state), - "::", - stringify!(hotword_pause_at_suspend) - ) - ); -} -pub const cras_notify_device_action_CRAS_DEVICE_ACTION_ADD: cras_notify_device_action = 0; -pub const cras_notify_device_action_CRAS_DEVICE_ACTION_REMOVE: cras_notify_device_action = 1; -pub const cras_notify_device_action_CRAS_DEVICE_ACTION_CHANGE: cras_notify_device_action = 2; -pub type cras_notify_device_action = u32; -#[repr(u32)] -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] -pub enum CRAS_ALSA_CARD_TYPE { - ALSA_CARD_TYPE_INTERNAL = 0, - ALSA_CARD_TYPE_USB = 1, -} -#[repr(C, packed)] -#[derive(Copy, Clone)] -pub struct cras_alsa_card_info { - pub card_type: CRAS_ALSA_CARD_TYPE, - pub card_index: u32, - pub usb_vendor_id: u32, - pub usb_product_id: u32, - pub usb_serial_number: [::std::os::raw::c_char; 64usize], - pub usb_desc_checksum: u32, -} -#[test] -fn bindgen_test_layout_cras_alsa_card_info() { - assert_eq!( - ::std::mem::size_of::<cras_alsa_card_info>(), - 84usize, - concat!("Size of: ", stringify!(cras_alsa_card_info)) - ); - assert_eq!( - ::std::mem::align_of::<cras_alsa_card_info>(), - 1usize, - concat!("Alignment of ", stringify!(cras_alsa_card_info)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_alsa_card_info>())).card_type as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(cras_alsa_card_info), - "::", - stringify!(card_type) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_alsa_card_info>())).card_index as *const _ as usize }, - 4usize, - concat!( - "Offset of field: ", - stringify!(cras_alsa_card_info), - "::", - stringify!(card_index) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_alsa_card_info>())).usb_vendor_id as *const _ as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(cras_alsa_card_info), - "::", - stringify!(usb_vendor_id) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_alsa_card_info>())).usb_product_id as *const _ as usize - }, - 12usize, - concat!( - "Offset of field: ", - stringify!(cras_alsa_card_info), - "::", - stringify!(usb_product_id) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_alsa_card_info>())).usb_serial_number as *const _ as usize - }, - 16usize, - concat!( - "Offset of field: ", - stringify!(cras_alsa_card_info), - "::", - stringify!(usb_serial_number) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_alsa_card_info>())).usb_desc_checksum as *const _ as usize - }, - 80usize, - concat!( - "Offset of field: ", - stringify!(cras_alsa_card_info), - "::", - stringify!(usb_desc_checksum) - ) - ); -} -pub type cras_stream_id_t = u32; -#[repr(u32)] -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] -pub enum CRAS_NODE_TYPE { - CRAS_NODE_TYPE_INTERNAL_SPEAKER = 0, - CRAS_NODE_TYPE_HEADPHONE = 1, - CRAS_NODE_TYPE_HDMI = 2, - CRAS_NODE_TYPE_HAPTIC = 3, - CRAS_NODE_TYPE_LINEOUT = 4, - CRAS_NODE_TYPE_MIC = 5, - CRAS_NODE_TYPE_HOTWORD = 6, - CRAS_NODE_TYPE_POST_MIX_PRE_DSP = 7, - CRAS_NODE_TYPE_POST_DSP = 8, - CRAS_NODE_TYPE_BLUETOOTH_NB_MIC = 9, - CRAS_NODE_TYPE_USB = 10, - CRAS_NODE_TYPE_BLUETOOTH = 11, - CRAS_NODE_TYPE_FALLBACK_NORMAL = 12, - CRAS_NODE_TYPE_FALLBACK_ABNORMAL = 13, - CRAS_NODE_TYPE_UNKNOWN = 14, - CRAS_NODE_TYPE_ECHO_REFERENCE = 15, - CRAS_NODE_TYPE_ALSA_LOOPBACK = 16, -} -#[repr(u32)] -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] -pub enum CRAS_NODE_POSITION { - NODE_POSITION_EXTERNAL = 0, - NODE_POSITION_INTERNAL = 1, - NODE_POSITION_FRONT = 2, - NODE_POSITION_REAR = 3, - NODE_POSITION_KEYBOARD = 4, -} -#[repr(u32)] -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] -pub enum CRAS_SERVER_MESSAGE_ID { - CRAS_SERVER_CONNECT_STREAM = 0, - CRAS_SERVER_DISCONNECT_STREAM = 1, - CRAS_SERVER_SWITCH_STREAM_TYPE_IODEV = 2, - CRAS_SERVER_SET_SYSTEM_VOLUME = 3, - CRAS_SERVER_SET_SYSTEM_MUTE = 4, - CRAS_SERVER_SET_USER_MUTE = 5, - CRAS_SERVER_SET_SYSTEM_MUTE_LOCKED = 6, - CRAS_SERVER_SET_SYSTEM_CAPTURE_GAIN = 7, - CRAS_SERVER_SET_SYSTEM_CAPTURE_MUTE = 8, - CRAS_SERVER_SET_SYSTEM_CAPTURE_MUTE_LOCKED = 9, - CRAS_SERVER_SET_NODE_ATTR = 10, - CRAS_SERVER_SELECT_NODE = 11, - CRAS_SERVER_RELOAD_DSP = 12, - CRAS_SERVER_DUMP_DSP_INFO = 13, - CRAS_SERVER_DUMP_AUDIO_THREAD = 14, - CRAS_SERVER_DUMP_SNAPSHOTS = 15, - CRAS_SERVER_ADD_ACTIVE_NODE = 16, - CRAS_SERVER_RM_ACTIVE_NODE = 17, - CRAS_SERVER_ADD_TEST_DEV = 18, - CRAS_SERVER_TEST_DEV_COMMAND = 19, - CRAS_SERVER_SUSPEND = 20, - CRAS_SERVER_RESUME = 21, - CRAS_CONFIG_GLOBAL_REMIX = 22, - CRAS_SERVER_GET_HOTWORD_MODELS = 23, - CRAS_SERVER_SET_HOTWORD_MODEL = 24, - CRAS_SERVER_REGISTER_NOTIFICATION = 25, - CRAS_SERVER_SET_AEC_DUMP = 26, - CRAS_SERVER_RELOAD_AEC_CONFIG = 27, - CRAS_SERVER_DUMP_BT = 28, - CRAS_SERVER_SET_BT_WBS_ENABLED = 29, - CRAS_SERVER_GET_ATLOG_FD = 30, - CRAS_SERVER_DUMP_MAIN = 31, -} -#[repr(u32)] -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] -pub enum CRAS_CLIENT_MESSAGE_ID { - CRAS_CLIENT_CONNECTED = 0, - CRAS_CLIENT_STREAM_CONNECTED = 1, - CRAS_CLIENT_AUDIO_DEBUG_INFO_READY = 2, - CRAS_CLIENT_GET_HOTWORD_MODELS_READY = 3, - CRAS_CLIENT_OUTPUT_VOLUME_CHANGED = 4, - CRAS_CLIENT_OUTPUT_MUTE_CHANGED = 5, - CRAS_CLIENT_CAPTURE_GAIN_CHANGED = 6, - CRAS_CLIENT_CAPTURE_MUTE_CHANGED = 7, - CRAS_CLIENT_NODES_CHANGED = 8, - CRAS_CLIENT_ACTIVE_NODE_CHANGED = 9, - CRAS_CLIENT_OUTPUT_NODE_VOLUME_CHANGED = 10, - CRAS_CLIENT_NODE_LEFT_RIGHT_SWAPPED_CHANGED = 11, - CRAS_CLIENT_INPUT_NODE_GAIN_CHANGED = 12, - CRAS_CLIENT_NUM_ACTIVE_STREAMS_CHANGED = 13, - CRAS_CLIENT_ATLOG_FD_READY = 14, -} -#[repr(C, packed)] -#[derive(Debug, Copy, Clone)] -pub struct cras_server_message { - pub length: u32, - pub id: CRAS_SERVER_MESSAGE_ID, -} -#[test] -fn bindgen_test_layout_cras_server_message() { - assert_eq!( - ::std::mem::size_of::<cras_server_message>(), - 8usize, - concat!("Size of: ", stringify!(cras_server_message)) - ); - assert_eq!( - ::std::mem::align_of::<cras_server_message>(), - 1usize, - concat!("Alignment of ", stringify!(cras_server_message)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_server_message>())).length as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(cras_server_message), - "::", - stringify!(length) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_server_message>())).id as *const _ as usize }, - 4usize, - concat!( - "Offset of field: ", - stringify!(cras_server_message), - "::", - stringify!(id) - ) - ); -} -#[repr(C, packed)] -#[derive(Debug, Copy, Clone)] -pub struct cras_client_message { - pub length: u32, - pub id: CRAS_CLIENT_MESSAGE_ID, -} -#[test] -fn bindgen_test_layout_cras_client_message() { - assert_eq!( - ::std::mem::size_of::<cras_client_message>(), - 8usize, - concat!("Size of: ", stringify!(cras_client_message)) - ); - assert_eq!( - ::std::mem::align_of::<cras_client_message>(), - 1usize, - concat!("Alignment of ", stringify!(cras_client_message)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_client_message>())).length as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(cras_client_message), - "::", - stringify!(length) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_client_message>())).id as *const _ as usize }, - 4usize, - concat!( - "Offset of field: ", - stringify!(cras_client_message), - "::", - stringify!(id) - ) - ); -} -#[repr(C, packed)] -#[derive(Debug, Copy, Clone)] -pub struct cras_connect_message { - pub header: cras_server_message, - pub proto_version: u32, - pub direction: CRAS_STREAM_DIRECTION, - pub stream_id: cras_stream_id_t, - pub stream_type: CRAS_STREAM_TYPE, - pub buffer_frames: u32, - pub cb_threshold: u32, - pub flags: u32, - pub format: cras_audio_format_packed, - pub dev_idx: u32, - pub effects: u64, - pub client_type: CRAS_CLIENT_TYPE, - pub client_shm_size: u64, - pub buffer_offsets: [u64; 2usize], -} -#[test] -fn bindgen_test_layout_cras_connect_message() { - assert_eq!( - ::std::mem::size_of::<cras_connect_message>(), - 99usize, - concat!("Size of: ", stringify!(cras_connect_message)) - ); - assert_eq!( - ::std::mem::align_of::<cras_connect_message>(), - 1usize, - concat!("Alignment of ", stringify!(cras_connect_message)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_connect_message>())).header as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(cras_connect_message), - "::", - stringify!(header) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_connect_message>())).proto_version as *const _ as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(cras_connect_message), - "::", - stringify!(proto_version) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_connect_message>())).direction as *const _ as usize }, - 12usize, - concat!( - "Offset of field: ", - stringify!(cras_connect_message), - "::", - stringify!(direction) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_connect_message>())).stream_id as *const _ as usize }, - 16usize, - concat!( - "Offset of field: ", - stringify!(cras_connect_message), - "::", - stringify!(stream_id) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_connect_message>())).stream_type as *const _ as usize - }, - 20usize, - concat!( - "Offset of field: ", - stringify!(cras_connect_message), - "::", - stringify!(stream_type) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_connect_message>())).buffer_frames as *const _ as usize - }, - 24usize, - concat!( - "Offset of field: ", - stringify!(cras_connect_message), - "::", - stringify!(buffer_frames) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_connect_message>())).cb_threshold as *const _ as usize - }, - 28usize, - concat!( - "Offset of field: ", - stringify!(cras_connect_message), - "::", - stringify!(cb_threshold) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_connect_message>())).flags as *const _ as usize }, - 32usize, - concat!( - "Offset of field: ", - stringify!(cras_connect_message), - "::", - stringify!(flags) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_connect_message>())).format as *const _ as usize }, - 36usize, - concat!( - "Offset of field: ", - stringify!(cras_connect_message), - "::", - stringify!(format) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_connect_message>())).dev_idx as *const _ as usize }, - 59usize, - concat!( - "Offset of field: ", - stringify!(cras_connect_message), - "::", - stringify!(dev_idx) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_connect_message>())).effects as *const _ as usize }, - 63usize, - concat!( - "Offset of field: ", - stringify!(cras_connect_message), - "::", - stringify!(effects) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_connect_message>())).client_type as *const _ as usize - }, - 71usize, - concat!( - "Offset of field: ", - stringify!(cras_connect_message), - "::", - stringify!(client_type) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_connect_message>())).client_shm_size as *const _ as usize - }, - 75usize, - concat!( - "Offset of field: ", - stringify!(cras_connect_message), - "::", - stringify!(client_shm_size) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_connect_message>())).buffer_offsets as *const _ as usize - }, - 83usize, - concat!( - "Offset of field: ", - stringify!(cras_connect_message), - "::", - stringify!(buffer_offsets) - ) - ); -} -#[repr(C, packed)] -#[derive(Debug, Copy, Clone)] -pub struct cras_disconnect_stream_message { - pub header: cras_server_message, - pub stream_id: cras_stream_id_t, -} -#[test] -fn bindgen_test_layout_cras_disconnect_stream_message() { - assert_eq!( - ::std::mem::size_of::<cras_disconnect_stream_message>(), - 12usize, - concat!("Size of: ", stringify!(cras_disconnect_stream_message)) - ); - assert_eq!( - ::std::mem::align_of::<cras_disconnect_stream_message>(), - 1usize, - concat!("Alignment of ", stringify!(cras_disconnect_stream_message)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_disconnect_stream_message>())).header as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(cras_disconnect_stream_message), - "::", - stringify!(header) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_disconnect_stream_message>())).stream_id as *const _ - as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(cras_disconnect_stream_message), - "::", - stringify!(stream_id) - ) - ); -} -#[repr(C, packed)] -#[derive(Debug, Copy, Clone)] -pub struct cras_switch_stream_type_iodev { - pub header: cras_server_message, - pub stream_type: CRAS_STREAM_TYPE, - pub iodev_idx: u32, -} -#[test] -fn bindgen_test_layout_cras_switch_stream_type_iodev() { - assert_eq!( - ::std::mem::size_of::<cras_switch_stream_type_iodev>(), - 16usize, - concat!("Size of: ", stringify!(cras_switch_stream_type_iodev)) - ); - assert_eq!( - ::std::mem::align_of::<cras_switch_stream_type_iodev>(), - 1usize, - concat!("Alignment of ", stringify!(cras_switch_stream_type_iodev)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_switch_stream_type_iodev>())).header as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(cras_switch_stream_type_iodev), - "::", - stringify!(header) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_switch_stream_type_iodev>())).stream_type as *const _ - as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(cras_switch_stream_type_iodev), - "::", - stringify!(stream_type) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_switch_stream_type_iodev>())).iodev_idx as *const _ as usize - }, - 12usize, - concat!( - "Offset of field: ", - stringify!(cras_switch_stream_type_iodev), - "::", - stringify!(iodev_idx) - ) - ); -} -#[repr(C, packed)] -#[derive(Debug, Copy, Clone)] -pub struct cras_set_system_volume { - pub header: cras_server_message, - pub volume: u32, -} -#[test] -fn bindgen_test_layout_cras_set_system_volume() { - assert_eq!( - ::std::mem::size_of::<cras_set_system_volume>(), - 12usize, - concat!("Size of: ", stringify!(cras_set_system_volume)) - ); - assert_eq!( - ::std::mem::align_of::<cras_set_system_volume>(), - 1usize, - concat!("Alignment of ", stringify!(cras_set_system_volume)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_set_system_volume>())).header as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(cras_set_system_volume), - "::", - stringify!(header) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_set_system_volume>())).volume as *const _ as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(cras_set_system_volume), - "::", - stringify!(volume) - ) - ); -} -#[repr(C, packed)] -#[derive(Debug, Copy, Clone)] -pub struct cras_set_system_mute { - pub header: cras_server_message, - pub mute: i32, -} -#[test] -fn bindgen_test_layout_cras_set_system_mute() { - assert_eq!( - ::std::mem::size_of::<cras_set_system_mute>(), - 12usize, - concat!("Size of: ", stringify!(cras_set_system_mute)) - ); - assert_eq!( - ::std::mem::align_of::<cras_set_system_mute>(), - 1usize, - concat!("Alignment of ", stringify!(cras_set_system_mute)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_set_system_mute>())).header as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(cras_set_system_mute), - "::", - stringify!(header) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_set_system_mute>())).mute as *const _ as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(cras_set_system_mute), - "::", - stringify!(mute) - ) - ); -} -#[repr(C, packed)] -#[derive(Debug, Copy, Clone)] -pub struct cras_set_node_attr { - pub header: cras_server_message, - pub node_id: cras_node_id_t, - pub attr: ionode_attr, - pub value: i32, -} -#[test] -fn bindgen_test_layout_cras_set_node_attr() { - assert_eq!( - ::std::mem::size_of::<cras_set_node_attr>(), - 24usize, - concat!("Size of: ", stringify!(cras_set_node_attr)) - ); - assert_eq!( - ::std::mem::align_of::<cras_set_node_attr>(), - 1usize, - concat!("Alignment of ", stringify!(cras_set_node_attr)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_set_node_attr>())).header as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(cras_set_node_attr), - "::", - stringify!(header) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_set_node_attr>())).node_id as *const _ as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(cras_set_node_attr), - "::", - stringify!(node_id) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_set_node_attr>())).attr as *const _ as usize }, - 16usize, - concat!( - "Offset of field: ", - stringify!(cras_set_node_attr), - "::", - stringify!(attr) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_set_node_attr>())).value as *const _ as usize }, - 20usize, - concat!( - "Offset of field: ", - stringify!(cras_set_node_attr), - "::", - stringify!(value) - ) - ); -} -#[repr(C, packed)] -#[derive(Debug, Copy, Clone)] -pub struct cras_select_node { - pub header: cras_server_message, - pub direction: CRAS_STREAM_DIRECTION, - pub node_id: cras_node_id_t, -} -#[test] -fn bindgen_test_layout_cras_select_node() { - assert_eq!( - ::std::mem::size_of::<cras_select_node>(), - 20usize, - concat!("Size of: ", stringify!(cras_select_node)) - ); - assert_eq!( - ::std::mem::align_of::<cras_select_node>(), - 1usize, - concat!("Alignment of ", stringify!(cras_select_node)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_select_node>())).header as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(cras_select_node), - "::", - stringify!(header) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_select_node>())).direction as *const _ as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(cras_select_node), - "::", - stringify!(direction) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_select_node>())).node_id as *const _ as usize }, - 12usize, - concat!( - "Offset of field: ", - stringify!(cras_select_node), - "::", - stringify!(node_id) - ) - ); -} -#[repr(C, packed)] -#[derive(Debug, Copy, Clone)] -pub struct cras_add_active_node { - pub header: cras_server_message, - pub direction: CRAS_STREAM_DIRECTION, - pub node_id: cras_node_id_t, -} -#[test] -fn bindgen_test_layout_cras_add_active_node() { - assert_eq!( - ::std::mem::size_of::<cras_add_active_node>(), - 20usize, - concat!("Size of: ", stringify!(cras_add_active_node)) - ); - assert_eq!( - ::std::mem::align_of::<cras_add_active_node>(), - 1usize, - concat!("Alignment of ", stringify!(cras_add_active_node)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_add_active_node>())).header as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(cras_add_active_node), - "::", - stringify!(header) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_add_active_node>())).direction as *const _ as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(cras_add_active_node), - "::", - stringify!(direction) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_add_active_node>())).node_id as *const _ as usize }, - 12usize, - concat!( - "Offset of field: ", - stringify!(cras_add_active_node), - "::", - stringify!(node_id) - ) - ); -} -#[repr(C, packed)] -#[derive(Debug, Copy, Clone)] -pub struct cras_rm_active_node { - pub header: cras_server_message, - pub direction: CRAS_STREAM_DIRECTION, - pub node_id: cras_node_id_t, -} -#[test] -fn bindgen_test_layout_cras_rm_active_node() { - assert_eq!( - ::std::mem::size_of::<cras_rm_active_node>(), - 20usize, - concat!("Size of: ", stringify!(cras_rm_active_node)) - ); - assert_eq!( - ::std::mem::align_of::<cras_rm_active_node>(), - 1usize, - concat!("Alignment of ", stringify!(cras_rm_active_node)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_rm_active_node>())).header as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(cras_rm_active_node), - "::", - stringify!(header) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_rm_active_node>())).direction as *const _ as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(cras_rm_active_node), - "::", - stringify!(direction) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_rm_active_node>())).node_id as *const _ as usize }, - 12usize, - concat!( - "Offset of field: ", - stringify!(cras_rm_active_node), - "::", - stringify!(node_id) - ) - ); -} -#[repr(C, packed)] -#[derive(Debug, Copy, Clone)] -pub struct cras_reload_dsp { - pub header: cras_server_message, -} -#[test] -fn bindgen_test_layout_cras_reload_dsp() { - assert_eq!( - ::std::mem::size_of::<cras_reload_dsp>(), - 8usize, - concat!("Size of: ", stringify!(cras_reload_dsp)) - ); - assert_eq!( - ::std::mem::align_of::<cras_reload_dsp>(), - 1usize, - concat!("Alignment of ", stringify!(cras_reload_dsp)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_reload_dsp>())).header as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(cras_reload_dsp), - "::", - stringify!(header) - ) - ); -} -#[repr(C, packed)] -#[derive(Debug, Copy, Clone)] -pub struct cras_dump_dsp_info { - pub header: cras_server_message, -} -#[test] -fn bindgen_test_layout_cras_dump_dsp_info() { - assert_eq!( - ::std::mem::size_of::<cras_dump_dsp_info>(), - 8usize, - concat!("Size of: ", stringify!(cras_dump_dsp_info)) - ); - assert_eq!( - ::std::mem::align_of::<cras_dump_dsp_info>(), - 1usize, - concat!("Alignment of ", stringify!(cras_dump_dsp_info)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_dump_dsp_info>())).header as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(cras_dump_dsp_info), - "::", - stringify!(header) - ) - ); -} -#[repr(C, packed)] -#[derive(Debug, Copy, Clone)] -pub struct cras_dump_audio_thread { - pub header: cras_server_message, -} -#[test] -fn bindgen_test_layout_cras_dump_audio_thread() { - assert_eq!( - ::std::mem::size_of::<cras_dump_audio_thread>(), - 8usize, - concat!("Size of: ", stringify!(cras_dump_audio_thread)) - ); - assert_eq!( - ::std::mem::align_of::<cras_dump_audio_thread>(), - 1usize, - concat!("Alignment of ", stringify!(cras_dump_audio_thread)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_dump_audio_thread>())).header as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(cras_dump_audio_thread), - "::", - stringify!(header) - ) - ); -} -#[repr(C, packed)] -#[derive(Debug, Copy, Clone)] -pub struct cras_get_atlog_fd { - pub header: cras_server_message, -} -#[test] -fn bindgen_test_layout_cras_get_atlog_fd() { - assert_eq!( - ::std::mem::size_of::<cras_get_atlog_fd>(), - 8usize, - concat!("Size of: ", stringify!(cras_get_atlog_fd)) - ); - assert_eq!( - ::std::mem::align_of::<cras_get_atlog_fd>(), - 1usize, - concat!("Alignment of ", stringify!(cras_get_atlog_fd)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_get_atlog_fd>())).header as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(cras_get_atlog_fd), - "::", - stringify!(header) - ) - ); -} -#[repr(C, packed)] -#[derive(Debug, Copy, Clone)] -pub struct cras_dump_main { - pub header: cras_server_message, -} -#[test] -fn bindgen_test_layout_cras_dump_main() { - assert_eq!( - ::std::mem::size_of::<cras_dump_main>(), - 8usize, - concat!("Size of: ", stringify!(cras_dump_main)) - ); - assert_eq!( - ::std::mem::align_of::<cras_dump_main>(), - 1usize, - concat!("Alignment of ", stringify!(cras_dump_main)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_dump_main>())).header as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(cras_dump_main), - "::", - stringify!(header) - ) - ); -} -#[repr(C, packed)] -#[derive(Debug, Copy, Clone)] -pub struct cras_dump_bt { - pub header: cras_server_message, -} -#[test] -fn bindgen_test_layout_cras_dump_bt() { - assert_eq!( - ::std::mem::size_of::<cras_dump_bt>(), - 8usize, - concat!("Size of: ", stringify!(cras_dump_bt)) - ); - assert_eq!( - ::std::mem::align_of::<cras_dump_bt>(), - 1usize, - concat!("Alignment of ", stringify!(cras_dump_bt)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_dump_bt>())).header as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(cras_dump_bt), - "::", - stringify!(header) - ) - ); -} -#[repr(C, packed)] -#[derive(Debug, Copy, Clone)] -pub struct cras_dump_snapshots { - pub header: cras_server_message, -} -#[test] -fn bindgen_test_layout_cras_dump_snapshots() { - assert_eq!( - ::std::mem::size_of::<cras_dump_snapshots>(), - 8usize, - concat!("Size of: ", stringify!(cras_dump_snapshots)) - ); - assert_eq!( - ::std::mem::align_of::<cras_dump_snapshots>(), - 1usize, - concat!("Alignment of ", stringify!(cras_dump_snapshots)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_dump_snapshots>())).header as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(cras_dump_snapshots), - "::", - stringify!(header) - ) - ); -} -#[repr(C, packed)] -#[derive(Debug, Copy, Clone)] -pub struct cras_add_test_dev { - pub header: cras_server_message, - pub type_: TEST_IODEV_TYPE, -} -#[test] -fn bindgen_test_layout_cras_add_test_dev() { - assert_eq!( - ::std::mem::size_of::<cras_add_test_dev>(), - 12usize, - concat!("Size of: ", stringify!(cras_add_test_dev)) - ); - assert_eq!( - ::std::mem::align_of::<cras_add_test_dev>(), - 1usize, - concat!("Alignment of ", stringify!(cras_add_test_dev)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_add_test_dev>())).header as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(cras_add_test_dev), - "::", - stringify!(header) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_add_test_dev>())).type_ as *const _ as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(cras_add_test_dev), - "::", - stringify!(type_) - ) - ); -} -#[repr(C, packed)] -#[derive(Copy, Clone)] -pub struct cras_test_dev_command { - pub header: cras_server_message, - pub command: ::std::os::raw::c_uint, - pub iodev_idx: ::std::os::raw::c_uint, - pub data_len: ::std::os::raw::c_uint, - pub data: [u8; 224usize], -} -#[test] -fn bindgen_test_layout_cras_test_dev_command() { - assert_eq!( - ::std::mem::size_of::<cras_test_dev_command>(), - 244usize, - concat!("Size of: ", stringify!(cras_test_dev_command)) - ); - assert_eq!( - ::std::mem::align_of::<cras_test_dev_command>(), - 1usize, - concat!("Alignment of ", stringify!(cras_test_dev_command)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_test_dev_command>())).header as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(cras_test_dev_command), - "::", - stringify!(header) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_test_dev_command>())).command as *const _ as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(cras_test_dev_command), - "::", - stringify!(command) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_test_dev_command>())).iodev_idx as *const _ as usize }, - 12usize, - concat!( - "Offset of field: ", - stringify!(cras_test_dev_command), - "::", - stringify!(iodev_idx) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_test_dev_command>())).data_len as *const _ as usize }, - 16usize, - concat!( - "Offset of field: ", - stringify!(cras_test_dev_command), - "::", - stringify!(data_len) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_test_dev_command>())).data as *const _ as usize }, - 20usize, - concat!( - "Offset of field: ", - stringify!(cras_test_dev_command), - "::", - stringify!(data) - ) - ); -} -#[repr(C, packed)] -#[derive(Copy, Clone)] -pub struct cras_config_global_remix { - pub header: cras_server_message, - pub num_channels: ::std::os::raw::c_uint, - pub coefficient: [f32; 64usize], -} -#[test] -fn bindgen_test_layout_cras_config_global_remix() { - assert_eq!( - ::std::mem::size_of::<cras_config_global_remix>(), - 268usize, - concat!("Size of: ", stringify!(cras_config_global_remix)) - ); - assert_eq!( - ::std::mem::align_of::<cras_config_global_remix>(), - 1usize, - concat!("Alignment of ", stringify!(cras_config_global_remix)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_config_global_remix>())).header as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(cras_config_global_remix), - "::", - stringify!(header) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_config_global_remix>())).num_channels as *const _ as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(cras_config_global_remix), - "::", - stringify!(num_channels) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_config_global_remix>())).coefficient as *const _ as usize - }, - 12usize, - concat!( - "Offset of field: ", - stringify!(cras_config_global_remix), - "::", - stringify!(coefficient) - ) - ); -} -#[repr(C, packed)] -#[derive(Debug, Copy, Clone)] -pub struct cras_get_hotword_models { - pub header: cras_server_message, - pub node_id: cras_node_id_t, -} -#[test] -fn bindgen_test_layout_cras_get_hotword_models() { - assert_eq!( - ::std::mem::size_of::<cras_get_hotword_models>(), - 16usize, - concat!("Size of: ", stringify!(cras_get_hotword_models)) - ); - assert_eq!( - ::std::mem::align_of::<cras_get_hotword_models>(), - 1usize, - concat!("Alignment of ", stringify!(cras_get_hotword_models)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_get_hotword_models>())).header as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(cras_get_hotword_models), - "::", - stringify!(header) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_get_hotword_models>())).node_id as *const _ as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(cras_get_hotword_models), - "::", - stringify!(node_id) - ) - ); -} -#[repr(C, packed)] -#[derive(Debug, Copy, Clone)] -pub struct cras_set_hotword_model { - pub header: cras_server_message, - pub node_id: cras_node_id_t, - pub model_name: [::std::os::raw::c_char; 12usize], -} -#[test] -fn bindgen_test_layout_cras_set_hotword_model() { - assert_eq!( - ::std::mem::size_of::<cras_set_hotword_model>(), - 28usize, - concat!("Size of: ", stringify!(cras_set_hotword_model)) - ); - assert_eq!( - ::std::mem::align_of::<cras_set_hotword_model>(), - 1usize, - concat!("Alignment of ", stringify!(cras_set_hotword_model)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_set_hotword_model>())).header as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(cras_set_hotword_model), - "::", - stringify!(header) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_set_hotword_model>())).node_id as *const _ as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(cras_set_hotword_model), - "::", - stringify!(node_id) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_set_hotword_model>())).model_name as *const _ as usize - }, - 16usize, - concat!( - "Offset of field: ", - stringify!(cras_set_hotword_model), - "::", - stringify!(model_name) - ) - ); -} -#[repr(C, packed)] -#[derive(Debug, Copy, Clone)] -pub struct cras_set_aec_dump { - pub header: cras_server_message, - pub stream_id: cras_stream_id_t, - pub start: ::std::os::raw::c_uint, -} -#[test] -fn bindgen_test_layout_cras_set_aec_dump() { - assert_eq!( - ::std::mem::size_of::<cras_set_aec_dump>(), - 16usize, - concat!("Size of: ", stringify!(cras_set_aec_dump)) - ); - assert_eq!( - ::std::mem::align_of::<cras_set_aec_dump>(), - 1usize, - concat!("Alignment of ", stringify!(cras_set_aec_dump)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_set_aec_dump>())).header as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(cras_set_aec_dump), - "::", - stringify!(header) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_set_aec_dump>())).stream_id as *const _ as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(cras_set_aec_dump), - "::", - stringify!(stream_id) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_set_aec_dump>())).start as *const _ as usize }, - 12usize, - concat!( - "Offset of field: ", - stringify!(cras_set_aec_dump), - "::", - stringify!(start) - ) - ); -} -#[repr(C, packed)] -#[derive(Debug, Copy, Clone)] -pub struct cras_reload_aec_config { - pub header: cras_server_message, -} -#[test] -fn bindgen_test_layout_cras_reload_aec_config() { - assert_eq!( - ::std::mem::size_of::<cras_reload_aec_config>(), - 8usize, - concat!("Size of: ", stringify!(cras_reload_aec_config)) - ); - assert_eq!( - ::std::mem::align_of::<cras_reload_aec_config>(), - 1usize, - concat!("Alignment of ", stringify!(cras_reload_aec_config)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_reload_aec_config>())).header as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(cras_reload_aec_config), - "::", - stringify!(header) - ) - ); -} -#[repr(C, packed)] -#[derive(Debug, Copy, Clone)] -pub struct cras_set_bt_wbs_enabled { - pub header: cras_server_message, - pub enabled: ::std::os::raw::c_uint, -} -#[test] -fn bindgen_test_layout_cras_set_bt_wbs_enabled() { - assert_eq!( - ::std::mem::size_of::<cras_set_bt_wbs_enabled>(), - 12usize, - concat!("Size of: ", stringify!(cras_set_bt_wbs_enabled)) - ); - assert_eq!( - ::std::mem::align_of::<cras_set_bt_wbs_enabled>(), - 1usize, - concat!("Alignment of ", stringify!(cras_set_bt_wbs_enabled)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_set_bt_wbs_enabled>())).header as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(cras_set_bt_wbs_enabled), - "::", - stringify!(header) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_set_bt_wbs_enabled>())).enabled as *const _ as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(cras_set_bt_wbs_enabled), - "::", - stringify!(enabled) - ) - ); -} -#[repr(C, packed)] -#[derive(Debug, Copy, Clone)] -pub struct cras_register_notification { - pub header: cras_server_message, - pub msg_id: u32, - pub do_register: ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_cras_register_notification() { - assert_eq!( - ::std::mem::size_of::<cras_register_notification>(), - 16usize, - concat!("Size of: ", stringify!(cras_register_notification)) - ); - assert_eq!( - ::std::mem::align_of::<cras_register_notification>(), - 1usize, - concat!("Alignment of ", stringify!(cras_register_notification)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_register_notification>())).header as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(cras_register_notification), - "::", - stringify!(header) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_register_notification>())).msg_id as *const _ as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(cras_register_notification), - "::", - stringify!(msg_id) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_register_notification>())).do_register as *const _ as usize - }, - 12usize, - concat!( - "Offset of field: ", - stringify!(cras_register_notification), - "::", - stringify!(do_register) - ) - ); -} -#[repr(C, packed)] -#[derive(Debug, Copy, Clone)] -pub struct cras_client_connected { - pub header: cras_client_message, - pub client_id: u32, -} -#[test] -fn bindgen_test_layout_cras_client_connected() { - assert_eq!( - ::std::mem::size_of::<cras_client_connected>(), - 12usize, - concat!("Size of: ", stringify!(cras_client_connected)) - ); - assert_eq!( - ::std::mem::align_of::<cras_client_connected>(), - 1usize, - concat!("Alignment of ", stringify!(cras_client_connected)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_client_connected>())).header as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(cras_client_connected), - "::", - stringify!(header) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_client_connected>())).client_id as *const _ as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(cras_client_connected), - "::", - stringify!(client_id) - ) - ); -} -#[repr(C, packed)] -#[derive(Debug, Copy, Clone)] -pub struct cras_client_stream_connected { - pub header: cras_client_message, - pub err: i32, - pub stream_id: cras_stream_id_t, - pub format: cras_audio_format_packed, - pub samples_shm_size: u32, - pub effects: u64, -} -#[test] -fn bindgen_test_layout_cras_client_stream_connected() { - assert_eq!( - ::std::mem::size_of::<cras_client_stream_connected>(), - 51usize, - concat!("Size of: ", stringify!(cras_client_stream_connected)) - ); - assert_eq!( - ::std::mem::align_of::<cras_client_stream_connected>(), - 1usize, - concat!("Alignment of ", stringify!(cras_client_stream_connected)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_client_stream_connected>())).header as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(cras_client_stream_connected), - "::", - stringify!(header) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_client_stream_connected>())).err as *const _ as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(cras_client_stream_connected), - "::", - stringify!(err) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_client_stream_connected>())).stream_id as *const _ as usize - }, - 12usize, - concat!( - "Offset of field: ", - stringify!(cras_client_stream_connected), - "::", - stringify!(stream_id) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_client_stream_connected>())).format as *const _ as usize - }, - 16usize, - concat!( - "Offset of field: ", - stringify!(cras_client_stream_connected), - "::", - stringify!(format) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_client_stream_connected>())).samples_shm_size as *const _ - as usize - }, - 39usize, - concat!( - "Offset of field: ", - stringify!(cras_client_stream_connected), - "::", - stringify!(samples_shm_size) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_client_stream_connected>())).effects as *const _ as usize - }, - 43usize, - concat!( - "Offset of field: ", - stringify!(cras_client_stream_connected), - "::", - stringify!(effects) - ) - ); -} -#[repr(C, packed)] -#[derive(Debug, Copy, Clone)] -pub struct cras_client_audio_debug_info_ready { - pub header: cras_client_message, -} -#[test] -fn bindgen_test_layout_cras_client_audio_debug_info_ready() { - assert_eq!( - ::std::mem::size_of::<cras_client_audio_debug_info_ready>(), - 8usize, - concat!("Size of: ", stringify!(cras_client_audio_debug_info_ready)) - ); - assert_eq!( - ::std::mem::align_of::<cras_client_audio_debug_info_ready>(), - 1usize, - concat!( - "Alignment of ", - stringify!(cras_client_audio_debug_info_ready) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_client_audio_debug_info_ready>())).header as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(cras_client_audio_debug_info_ready), - "::", - stringify!(header) - ) - ); -} -#[repr(C, packed)] -#[derive(Debug, Copy, Clone)] -pub struct cras_client_atlog_fd_ready { - pub header: cras_client_message, -} -#[test] -fn bindgen_test_layout_cras_client_atlog_fd_ready() { - assert_eq!( - ::std::mem::size_of::<cras_client_atlog_fd_ready>(), - 8usize, - concat!("Size of: ", stringify!(cras_client_atlog_fd_ready)) - ); - assert_eq!( - ::std::mem::align_of::<cras_client_atlog_fd_ready>(), - 1usize, - concat!("Alignment of ", stringify!(cras_client_atlog_fd_ready)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_client_atlog_fd_ready>())).header as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(cras_client_atlog_fd_ready), - "::", - stringify!(header) - ) - ); -} -#[repr(C, packed)] -#[derive(Copy, Clone)] -pub struct cras_client_get_hotword_models_ready { - pub header: cras_client_message, - pub hotword_models_size: i32, - pub hotword_models: [u8; 244usize], -} -#[test] -fn bindgen_test_layout_cras_client_get_hotword_models_ready() { - assert_eq!( - ::std::mem::size_of::<cras_client_get_hotword_models_ready>(), - 256usize, - concat!( - "Size of: ", - stringify!(cras_client_get_hotword_models_ready) - ) - ); - assert_eq!( - ::std::mem::align_of::<cras_client_get_hotword_models_ready>(), - 1usize, - concat!( - "Alignment of ", - stringify!(cras_client_get_hotword_models_ready) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_client_get_hotword_models_ready>())).header as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(cras_client_get_hotword_models_ready), - "::", - stringify!(header) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_client_get_hotword_models_ready>())).hotword_models_size - as *const _ as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(cras_client_get_hotword_models_ready), - "::", - stringify!(hotword_models_size) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_client_get_hotword_models_ready>())).hotword_models - as *const _ as usize - }, - 12usize, - concat!( - "Offset of field: ", - stringify!(cras_client_get_hotword_models_ready), - "::", - stringify!(hotword_models) - ) - ); -} -#[repr(C, packed)] -#[derive(Debug, Copy, Clone)] -pub struct cras_client_volume_changed { - pub header: cras_client_message, - pub volume: i32, -} -#[test] -fn bindgen_test_layout_cras_client_volume_changed() { - assert_eq!( - ::std::mem::size_of::<cras_client_volume_changed>(), - 12usize, - concat!("Size of: ", stringify!(cras_client_volume_changed)) - ); - assert_eq!( - ::std::mem::align_of::<cras_client_volume_changed>(), - 1usize, - concat!("Alignment of ", stringify!(cras_client_volume_changed)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_client_volume_changed>())).header as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(cras_client_volume_changed), - "::", - stringify!(header) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_client_volume_changed>())).volume as *const _ as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(cras_client_volume_changed), - "::", - stringify!(volume) - ) - ); -} -#[repr(C, packed)] -#[derive(Debug, Copy, Clone)] -pub struct cras_client_mute_changed { - pub header: cras_client_message, - pub muted: i32, - pub user_muted: i32, - pub mute_locked: i32, -} -#[test] -fn bindgen_test_layout_cras_client_mute_changed() { - assert_eq!( - ::std::mem::size_of::<cras_client_mute_changed>(), - 20usize, - concat!("Size of: ", stringify!(cras_client_mute_changed)) - ); - assert_eq!( - ::std::mem::align_of::<cras_client_mute_changed>(), - 1usize, - concat!("Alignment of ", stringify!(cras_client_mute_changed)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_client_mute_changed>())).header as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(cras_client_mute_changed), - "::", - stringify!(header) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_client_mute_changed>())).muted as *const _ as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(cras_client_mute_changed), - "::", - stringify!(muted) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_client_mute_changed>())).user_muted as *const _ as usize - }, - 12usize, - concat!( - "Offset of field: ", - stringify!(cras_client_mute_changed), - "::", - stringify!(user_muted) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_client_mute_changed>())).mute_locked as *const _ as usize - }, - 16usize, - concat!( - "Offset of field: ", - stringify!(cras_client_mute_changed), - "::", - stringify!(mute_locked) - ) - ); -} -#[repr(C, packed)] -#[derive(Debug, Copy, Clone)] -pub struct cras_client_nodes_changed { - pub header: cras_client_message, -} -#[test] -fn bindgen_test_layout_cras_client_nodes_changed() { - assert_eq!( - ::std::mem::size_of::<cras_client_nodes_changed>(), - 8usize, - concat!("Size of: ", stringify!(cras_client_nodes_changed)) - ); - assert_eq!( - ::std::mem::align_of::<cras_client_nodes_changed>(), - 1usize, - concat!("Alignment of ", stringify!(cras_client_nodes_changed)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_client_nodes_changed>())).header as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(cras_client_nodes_changed), - "::", - stringify!(header) - ) - ); -} -#[repr(C, packed)] -#[derive(Debug, Copy, Clone)] -pub struct cras_client_active_node_changed { - pub header: cras_client_message, - pub direction: u32, - pub node_id: cras_node_id_t, -} -#[test] -fn bindgen_test_layout_cras_client_active_node_changed() { - assert_eq!( - ::std::mem::size_of::<cras_client_active_node_changed>(), - 20usize, - concat!("Size of: ", stringify!(cras_client_active_node_changed)) - ); - assert_eq!( - ::std::mem::align_of::<cras_client_active_node_changed>(), - 1usize, - concat!("Alignment of ", stringify!(cras_client_active_node_changed)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_client_active_node_changed>())).header as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(cras_client_active_node_changed), - "::", - stringify!(header) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_client_active_node_changed>())).direction as *const _ - as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(cras_client_active_node_changed), - "::", - stringify!(direction) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_client_active_node_changed>())).node_id as *const _ as usize - }, - 12usize, - concat!( - "Offset of field: ", - stringify!(cras_client_active_node_changed), - "::", - stringify!(node_id) - ) - ); -} -#[repr(C, packed)] -#[derive(Debug, Copy, Clone)] -pub struct cras_client_node_value_changed { - pub header: cras_client_message, - pub node_id: cras_node_id_t, - pub value: i32, -} -#[test] -fn bindgen_test_layout_cras_client_node_value_changed() { - assert_eq!( - ::std::mem::size_of::<cras_client_node_value_changed>(), - 20usize, - concat!("Size of: ", stringify!(cras_client_node_value_changed)) - ); - assert_eq!( - ::std::mem::align_of::<cras_client_node_value_changed>(), - 1usize, - concat!("Alignment of ", stringify!(cras_client_node_value_changed)) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_client_node_value_changed>())).header as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(cras_client_node_value_changed), - "::", - stringify!(header) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_client_node_value_changed>())).node_id as *const _ as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(cras_client_node_value_changed), - "::", - stringify!(node_id) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_client_node_value_changed>())).value as *const _ as usize - }, - 16usize, - concat!( - "Offset of field: ", - stringify!(cras_client_node_value_changed), - "::", - stringify!(value) - ) - ); -} -#[repr(C, packed)] -#[derive(Debug, Copy, Clone)] -pub struct cras_client_num_active_streams_changed { - pub header: cras_client_message, - pub direction: u32, - pub num_active_streams: u32, -} -#[test] -fn bindgen_test_layout_cras_client_num_active_streams_changed() { - assert_eq!( - ::std::mem::size_of::<cras_client_num_active_streams_changed>(), - 16usize, - concat!( - "Size of: ", - stringify!(cras_client_num_active_streams_changed) - ) - ); - assert_eq!( - ::std::mem::align_of::<cras_client_num_active_streams_changed>(), - 1usize, - concat!( - "Alignment of ", - stringify!(cras_client_num_active_streams_changed) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_client_num_active_streams_changed>())).header as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(cras_client_num_active_streams_changed), - "::", - stringify!(header) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_client_num_active_streams_changed>())).direction as *const _ - as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(cras_client_num_active_streams_changed), - "::", - stringify!(direction) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_client_num_active_streams_changed>())).num_active_streams - as *const _ as usize - }, - 12usize, - concat!( - "Offset of field: ", - stringify!(cras_client_num_active_streams_changed), - "::", - stringify!(num_active_streams) - ) - ); -} -#[repr(u32)] -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] -pub enum CRAS_AUDIO_MESSAGE_ID { - AUDIO_MESSAGE_REQUEST_DATA = 0, - AUDIO_MESSAGE_DATA_READY = 1, - AUDIO_MESSAGE_DATA_CAPTURED = 2, - NUM_AUDIO_MESSAGES = 3, -} -#[repr(C, packed)] -#[derive(Debug, Copy, Clone)] -pub struct audio_message { - pub id: CRAS_AUDIO_MESSAGE_ID, - pub error: i32, - pub frames: u32, -} -#[test] -fn bindgen_test_layout_audio_message() { - assert_eq!( - ::std::mem::size_of::<audio_message>(), - 12usize, - concat!("Size of: ", stringify!(audio_message)) - ); - assert_eq!( - ::std::mem::align_of::<audio_message>(), - 1usize, - concat!("Alignment of ", stringify!(audio_message)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<audio_message>())).id as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(audio_message), - "::", - stringify!(id) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<audio_message>())).error as *const _ as usize }, - 4usize, - concat!( - "Offset of field: ", - stringify!(audio_message), - "::", - stringify!(error) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<audio_message>())).frames as *const _ as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(audio_message), - "::", - stringify!(frames) - ) - ); -} -#[repr(C, packed)] -#[derive(Debug, Copy, Clone)] -pub struct cras_audio_shm_config { - pub used_size: u32, - pub frame_bytes: u32, -} -#[test] -fn bindgen_test_layout_cras_audio_shm_config() { - assert_eq!( - ::std::mem::size_of::<cras_audio_shm_config>(), - 8usize, - concat!("Size of: ", stringify!(cras_audio_shm_config)) - ); - assert_eq!( - ::std::mem::align_of::<cras_audio_shm_config>(), - 1usize, - concat!("Alignment of ", stringify!(cras_audio_shm_config)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_audio_shm_config>())).used_size as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(cras_audio_shm_config), - "::", - stringify!(used_size) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_audio_shm_config>())).frame_bytes as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(cras_audio_shm_config), - "::", - stringify!(frame_bytes) - ) - ); -} -#[repr(C, packed)] -#[derive(Debug, Copy, Clone)] -pub struct cras_audio_shm_header { - pub config: cras_audio_shm_config, - pub read_buf_idx: u32, - pub write_buf_idx: u32, - pub read_offset: [u32; 2usize], - pub write_offset: [u32; 2usize], - pub write_in_progress: [i32; 2usize], - pub volume_scaler: f32, - pub mute: i32, - pub callback_pending: i32, - pub num_overruns: u32, - pub ts: cras_timespec, - pub buffer_offset: [u64; 2usize], -} -#[test] -fn bindgen_test_layout_cras_audio_shm_header() { - assert_eq!( - ::std::mem::size_of::<cras_audio_shm_header>(), - 88usize, - concat!("Size of: ", stringify!(cras_audio_shm_header)) - ); - assert_eq!( - ::std::mem::align_of::<cras_audio_shm_header>(), - 1usize, - concat!("Alignment of ", stringify!(cras_audio_shm_header)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_audio_shm_header>())).config as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(cras_audio_shm_header), - "::", - stringify!(config) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_audio_shm_header>())).read_buf_idx as *const _ as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(cras_audio_shm_header), - "::", - stringify!(read_buf_idx) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_audio_shm_header>())).write_buf_idx as *const _ as usize - }, - 12usize, - concat!( - "Offset of field: ", - stringify!(cras_audio_shm_header), - "::", - stringify!(write_buf_idx) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_audio_shm_header>())).read_offset as *const _ as usize - }, - 16usize, - concat!( - "Offset of field: ", - stringify!(cras_audio_shm_header), - "::", - stringify!(read_offset) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_audio_shm_header>())).write_offset as *const _ as usize - }, - 24usize, - concat!( - "Offset of field: ", - stringify!(cras_audio_shm_header), - "::", - stringify!(write_offset) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_audio_shm_header>())).write_in_progress as *const _ as usize - }, - 32usize, - concat!( - "Offset of field: ", - stringify!(cras_audio_shm_header), - "::", - stringify!(write_in_progress) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_audio_shm_header>())).volume_scaler as *const _ as usize - }, - 40usize, - concat!( - "Offset of field: ", - stringify!(cras_audio_shm_header), - "::", - stringify!(volume_scaler) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_audio_shm_header>())).mute as *const _ as usize }, - 44usize, - concat!( - "Offset of field: ", - stringify!(cras_audio_shm_header), - "::", - stringify!(mute) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_audio_shm_header>())).callback_pending as *const _ as usize - }, - 48usize, - concat!( - "Offset of field: ", - stringify!(cras_audio_shm_header), - "::", - stringify!(callback_pending) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_audio_shm_header>())).num_overruns as *const _ as usize - }, - 52usize, - concat!( - "Offset of field: ", - stringify!(cras_audio_shm_header), - "::", - stringify!(num_overruns) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_audio_shm_header>())).ts as *const _ as usize }, - 56usize, - concat!( - "Offset of field: ", - stringify!(cras_audio_shm_header), - "::", - stringify!(ts) - ) - ); - assert_eq!( - unsafe { - &(*(::std::ptr::null::<cras_audio_shm_header>())).buffer_offset as *const _ as usize - }, - 72usize, - concat!( - "Offset of field: ", - stringify!(cras_audio_shm_header), - "::", - stringify!(buffer_offset) - ) - ); -} -#[repr(C)] -#[derive(Copy, Clone)] -pub struct cras_shm_info { - pub fd: ::std::os::raw::c_int, - pub name: [::std::os::raw::c_char; 255usize], - pub length: usize, -} -#[test] -fn bindgen_test_layout_cras_shm_info() { - assert_eq!( - ::std::mem::size_of::<cras_shm_info>(), - 272usize, - concat!("Size of: ", stringify!(cras_shm_info)) - ); - assert_eq!( - ::std::mem::align_of::<cras_shm_info>(), - 8usize, - concat!("Alignment of ", stringify!(cras_shm_info)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_shm_info>())).fd as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(cras_shm_info), - "::", - stringify!(fd) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_shm_info>())).name as *const _ as usize }, - 4usize, - concat!( - "Offset of field: ", - stringify!(cras_shm_info), - "::", - stringify!(name) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_shm_info>())).length as *const _ as usize }, - 264usize, - concat!( - "Offset of field: ", - stringify!(cras_shm_info), - "::", - stringify!(length) - ) - ); -} -#[repr(C)] -#[derive(Copy, Clone)] -pub struct cras_audio_shm { - pub config: cras_audio_shm_config, - pub header_info: cras_shm_info, - pub header: *mut cras_audio_shm_header, - pub samples_info: cras_shm_info, - pub samples: *mut u8, -} -#[test] -fn bindgen_test_layout_cras_audio_shm() { - assert_eq!( - ::std::mem::size_of::<cras_audio_shm>(), - 568usize, - concat!("Size of: ", stringify!(cras_audio_shm)) - ); - assert_eq!( - ::std::mem::align_of::<cras_audio_shm>(), - 8usize, - concat!("Alignment of ", stringify!(cras_audio_shm)) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_audio_shm>())).config as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(cras_audio_shm), - "::", - stringify!(config) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_audio_shm>())).header_info as *const _ as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(cras_audio_shm), - "::", - stringify!(header_info) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_audio_shm>())).header as *const _ as usize }, - 280usize, - concat!( - "Offset of field: ", - stringify!(cras_audio_shm), - "::", - stringify!(header) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_audio_shm>())).samples_info as *const _ as usize }, - 288usize, - concat!( - "Offset of field: ", - stringify!(cras_audio_shm), - "::", - stringify!(samples_info) - ) - ); - assert_eq!( - unsafe { &(*(::std::ptr::null::<cras_audio_shm>())).samples as *const _ as usize }, - 560usize, - concat!( - "Offset of field: ", - stringify!(cras_audio_shm), - "::", - stringify!(samples) - ) - ); -} 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, - } - } -} diff --git a/cras/client/cras_tests/.gitignore b/cras/client/cras_tests/.gitignore deleted file mode 100644 index 302b31de..00000000 --- a/cras/client/cras_tests/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -target/ -.*.rustfmt diff --git a/cras/client/cras_tests/.rustfmt.toml b/cras/client/cras_tests/.rustfmt.toml deleted file mode 100644 index a2db3012..00000000 --- a/cras/client/cras_tests/.rustfmt.toml +++ /dev/null @@ -1,2 +0,0 @@ -use_field_init_shorthand = true -use_try_shorthand = true diff --git a/cras/client/cras_tests/Cargo.toml b/cras/client/cras_tests/Cargo.toml deleted file mode 100644 index 108fe6c4..00000000 --- a/cras/client/cras_tests/Cargo.toml +++ /dev/null @@ -1,17 +0,0 @@ -[package] -name = "cras_tests" -version = "0.1.0" -authors = ["The Chromium OS Authors"] -edition = "2018" - -[dependencies] -audio_streams = { path = "../../../audio_streams" } # provided by ebuild -getopts = "0.2.18" -hound = "3.4.0" -libcras = { path = "../libcras" } # provided by ebuild -sys_util = { path = "../../../../crosvm/sys_util" } # provided by ebuild - -[profile.release] -lto = true -panic = 'abort' -overflow-checks = true diff --git a/cras/client/cras_tests/src/arguments.rs b/cras/client/cras_tests/src/arguments.rs deleted file mode 100644 index 59e9ec26..00000000 --- a/cras/client/cras_tests/src/arguments.rs +++ /dev/null @@ -1,462 +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. -use std::error; -use std::fmt; -use std::path::PathBuf; - -use audio_streams::SampleFormat; -use getopts::{self, Matches, Options}; - -#[derive(Debug)] -pub enum Error { - GetOpts(getopts::Fail), - InvalidArgument(String, String, String), - InvalidFiletype(String), - MissingArgument(String), - MissingCommand, - MissingFilename, - UnknownCommand(String), -} - -impl error::Error for Error {} - -impl fmt::Display for Error { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - use Error::*; - match self { - GetOpts(e) => write!(f, "Getopts Error: {}", e), - InvalidArgument(flag, value, error_msg) => { - write!(f, "Invalid {} argument '{}': {}", flag, value, error_msg) - } - InvalidFiletype(extension) => write!( - f, - "Invalid file extension '{}'. Supported types are 'wav' and 'raw'", - extension - ), - MissingArgument(subcommand) => write!(f, "Missing argument for {}", subcommand), - MissingCommand => write!(f, "A command must be provided"), - MissingFilename => write!(f, "A file name must be provided"), - UnknownCommand(s) => write!(f, "Unknown command '{}'", s), - } - } -} - -type Result<T> = std::result::Result<T, Error>; - -/// The different types of commands that can be given to cras_tests. -/// Any options for those commands are passed as parameters to the enum values. -#[derive(Debug, PartialEq)] -pub enum Command { - Capture(AudioOptions), - Playback(AudioOptions), - Control(ControlCommand), -} - -impl Command { - pub fn parse<T: AsRef<str>>(args: &[T]) -> Result<Option<Self>> { - let program_name = args.get(0).map(|s| s.as_ref()).unwrap_or("cras_tests"); - let remaining_args = args.get(2..).unwrap_or(&[]); - match args.get(1).map(|s| s.as_ref()) { - None => { - show_usage(program_name); - Err(Error::MissingCommand) - } - Some("help") => { - show_usage(program_name); - Ok(None) - } - Some("capture") => Ok( - AudioOptions::parse(program_name, "capture", remaining_args)?.map(Command::Capture), - ), - Some("playback") => Ok( - AudioOptions::parse(program_name, "playback", remaining_args)? - .map(Command::Playback), - ), - Some("control") => { - Ok(ControlCommand::parse(program_name, remaining_args)?.map(Command::Control)) - } - Some(s) => { - show_usage(program_name); - Err(Error::UnknownCommand(s.to_string())) - } - } - } -} - -#[derive(Debug, PartialEq)] -pub enum FileType { - Raw, - Wav, -} - -impl fmt::Display for FileType { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - FileType::Raw => write!(f, "raw data"), - FileType::Wav => write!(f, "WAVE"), - } - } -} - -fn show_usage(program_name: &str) { - eprintln!("Usage: {} [command] <command args>", program_name); - eprintln!("\nCommands:\n"); - eprintln!("capture - Capture to a file from CRAS"); - eprintln!("playback - Playback to CRAS from a file"); - eprintln!("control - Get and set server settings"); - eprintln!("\nhelp - Print help message"); -} - -fn show_audio_command_usage(program_name: &str, command: &str, opts: &Options) { - let brief = format!("Usage: {} {} [options] [filename]", program_name, command); - eprint!("{}", opts.usage(&brief)); -} - -/// The possible command line options that can be passed to the 'playback' and -/// 'capture' commands. Optional values will be `Some(_)` only if a value was -/// explicitly provided by the user. -/// -/// This struct will be passed to `playback()` and `capture()`. -#[derive(Debug, PartialEq)] -pub enum LoopbackType { - PreDsp, - PostDsp, -} - -#[derive(Debug, PartialEq)] -pub struct AudioOptions { - pub file_name: PathBuf, - pub loopback_type: Option<LoopbackType>, - pub file_type: FileType, - pub buffer_size: Option<usize>, - pub num_channels: Option<usize>, - pub format: Option<SampleFormat>, - pub frame_rate: Option<u32>, -} - -fn get_u32_param(matches: &Matches, option_name: &str) -> Result<Option<u32>> { - matches.opt_get::<u32>(option_name).map_err(|e| { - let argument = matches.opt_str(option_name).unwrap_or_default(); - Error::InvalidArgument(option_name.to_string(), argument, e.to_string()) - }) -} - -fn get_usize_param(matches: &Matches, option_name: &str) -> Result<Option<usize>> { - matches.opt_get::<usize>(option_name).map_err(|e| { - let argument = matches.opt_str(option_name).unwrap_or_default(); - Error::InvalidArgument(option_name.to_string(), argument, e.to_string()) - }) -} - -impl AudioOptions { - fn parse<T: AsRef<str>>( - program_name: &str, - command_name: &str, - args: &[T], - ) -> Result<Option<Self>> { - let mut opts = Options::new(); - opts.optopt("b", "buffer_size", "Buffer size in frames", "SIZE") - .optopt("c", "channels", "Number of channels", "NUM") - .optopt( - "f", - "format", - "Sample format (U8, S16_LE, S24_LE, or S32_LE)", - "FORMAT", - ) - .optopt("r", "rate", "Audio frame rate (Hz)", "RATE") - .optflag("h", "help", "Print help message"); - - if command_name == "capture" { - opts.optopt( - "", - "loopback", - "Capture from loopback device ('pre_dsp' or 'post_dsp')", - "DEVICE", - ); - } - - let args = args.iter().map(|s| s.as_ref()); - let matches = match opts.parse(args) { - Ok(m) => m, - Err(e) => { - show_audio_command_usage(program_name, command_name, &opts); - return Err(Error::GetOpts(e)); - } - }; - if matches.opt_present("h") { - show_audio_command_usage(program_name, command_name, &opts); - return Ok(None); - } - - let loopback_type = if matches.opt_defined("loopback") { - match matches.opt_str("loopback").as_deref() { - Some("pre_dsp") => Some(LoopbackType::PreDsp), - Some("post_dsp") => Some(LoopbackType::PostDsp), - Some(s) => { - return Err(Error::InvalidArgument( - "loopback".to_string(), - s.to_string(), - "Loopback type must be 'pre_dsp' or 'post_dsp'".to_string(), - )) - } - None => None, - } - } else { - None - }; - - let file_name = match matches.free.get(0) { - None => { - show_audio_command_usage(program_name, command_name, &opts); - return Err(Error::MissingFilename); - } - Some(file_name) => PathBuf::from(file_name), - }; - - let extension = file_name - .extension() - .map(|s| s.to_string_lossy().into_owned()); - let file_type = match extension.as_deref() { - Some("wav") | Some("wave") => FileType::Wav, - Some("raw") | None => FileType::Raw, - Some(extension) => return Err(Error::InvalidFiletype(extension.to_string())), - }; - - let buffer_size = get_usize_param(&matches, "buffer_size")?; - let num_channels = get_usize_param(&matches, "channels")?; - let frame_rate = get_u32_param(&matches, "rate")?; - let format = match matches.opt_str("format").as_deref() { - Some("U8") => Some(SampleFormat::U8), - Some("S16_LE") => Some(SampleFormat::S16LE), - Some("S24_LE") => Some(SampleFormat::S24LE), - Some("S32_LE") => Some(SampleFormat::S32LE), - Some(s) => { - show_audio_command_usage(program_name, command_name, &opts); - return Err(Error::InvalidArgument( - "format".to_string(), - s.to_string(), - "Format must be 'U8', 'S16_LE', 'S24_LE', or 'S32_LE'".to_string(), - )); - } - None => None, - }; - - Ok(Some(AudioOptions { - loopback_type, - file_name, - file_type, - buffer_size, - num_channels, - format, - frame_rate, - })) - } -} - -fn show_control_command_usage(program_name: &str) { - eprintln!("Usage: {} control [command] <command args>", program_name); - eprintln!(""); - eprintln!("Commands:"); - let commands = [ - ("help", "", "Print help message"), - ("", "", ""), - ("get_volume", "", "Get the system volume (0 - 100)"), - ( - "set_volume", - "VOLUME", - "Set the system volume to VOLUME (0 - 100)", - ), - ("get_mute", "", "Get the system mute state (true or false)"), - ( - "set_mute", - "MUTE", - "Set the system mute state to MUTE (true or false)", - ), - ("", "", ""), - ("list_output_devices", "", "Print list of output devices"), - ("list_input_devices", "", "Print list of input devices"), - ("list_output_nodes", "", "Print list of output nodes"), - ("list_input_nodes", "", "Print list of input nodes"), - ( - "dump_audio_debug_info", - "", - "Print stream info, device info, and audio thread log.", - ), - ]; - for command in &commands { - let command_string = format!("{} {}", command.0, command.1); - eprintln!("\t{: <23} {}", command_string, command.2); - } -} - -#[derive(Debug, PartialEq)] -pub enum ControlCommand { - GetSystemVolume, - SetSystemVolume(u32), - GetSystemMute, - SetSystemMute(bool), - ListOutputDevices, - ListInputDevices, - ListOutputNodes, - ListInputNodes, - DumpAudioDebugInfo, -} - -impl ControlCommand { - fn parse<T: AsRef<str>>(program_name: &str, args: &[T]) -> Result<Option<Self>> { - let mut args = args.iter().map(|s| s.as_ref()); - match args.next() { - Some("help") => { - show_control_command_usage(program_name); - Ok(None) - } - Some("get_volume") => Ok(Some(ControlCommand::GetSystemVolume)), - Some("set_volume") => { - let volume_str = args - .next() - .ok_or_else(|| Error::MissingArgument("set_volume".to_string()))?; - - let volume = volume_str.parse::<u32>().map_err(|e| { - Error::InvalidArgument( - "set_volume".to_string(), - volume_str.to_string(), - e.to_string(), - ) - })?; - - Ok(Some(ControlCommand::SetSystemVolume(volume))) - } - Some("get_mute") => Ok(Some(ControlCommand::GetSystemMute)), - Some("set_mute") => { - let mute_str = args - .next() - .ok_or_else(|| Error::MissingArgument("set_mute".to_string()))?; - - let mute = mute_str.parse::<bool>().map_err(|e| { - Error::InvalidArgument( - "set_mute".to_string(), - mute_str.to_string(), - e.to_string(), - ) - })?; - Ok(Some(ControlCommand::SetSystemMute(mute))) - } - Some("list_output_devices") => Ok(Some(ControlCommand::ListOutputDevices)), - Some("list_input_devices") => Ok(Some(ControlCommand::ListInputDevices)), - Some("list_output_nodes") => Ok(Some(ControlCommand::ListOutputNodes)), - Some("list_input_nodes") => Ok(Some(ControlCommand::ListInputNodes)), - Some("dump_audio_debug_info") => Ok(Some(ControlCommand::DumpAudioDebugInfo)), - Some(s) => { - show_control_command_usage(program_name); - Err(Error::UnknownCommand(s.to_string())) - } - None => { - show_control_command_usage(program_name); - Err(Error::MissingCommand) - } - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn parse_command() { - let command = Command::parse(&["cras_tests", "playback", "output.wav"]) - .unwrap() - .unwrap(); - assert_eq!( - command, - Command::Playback(AudioOptions { - file_name: PathBuf::from("output.wav"), - loopback_type: None, - file_type: FileType::Wav, - frame_rate: None, - num_channels: None, - format: None, - buffer_size: None, - }) - ); - let command = Command::parse(&["cras_tests", "capture", "input.raw"]) - .unwrap() - .unwrap(); - assert_eq!( - command, - Command::Capture(AudioOptions { - file_name: PathBuf::from("input.raw"), - loopback_type: None, - file_type: FileType::Raw, - frame_rate: None, - num_channels: None, - format: None, - buffer_size: None, - }) - ); - - let command = Command::parse(&[ - "cras_tests", - "playback", - "-r", - "44100", - "output.wave", - "-c", - "2", - ]) - .unwrap() - .unwrap(); - assert_eq!( - command, - Command::Playback(AudioOptions { - file_name: PathBuf::from("output.wave"), - loopback_type: None, - file_type: FileType::Wav, - frame_rate: Some(44100), - num_channels: Some(2), - format: None, - buffer_size: None, - }) - ); - - let command = - Command::parse(&["cras_tests", "playback", "-r", "44100", "output", "-c", "2"]) - .unwrap() - .unwrap(); - assert_eq!( - command, - Command::Playback(AudioOptions { - file_name: PathBuf::from("output"), - loopback_type: None, - file_type: FileType::Raw, - frame_rate: Some(44100), - num_channels: Some(2), - format: None, - buffer_size: None, - }) - ); - - assert!(Command::parse(&["cras_tests"]).is_err()); - assert!(Command::parse(&["cras_tests", "capture"]).is_err()); - assert!(Command::parse(&["cras_tests", "capture", "input.mp3"]).is_err()); - assert!(Command::parse(&["cras_tests", "capture", "input.ogg"]).is_err()); - assert!(Command::parse(&["cras_tests", "capture", "input.flac"]).is_err()); - assert!(Command::parse(&["cras_tests", "playback"]).is_err()); - assert!(Command::parse(&["cras_tests", "loopback"]).is_err()); - assert!(Command::parse(&["cras_tests", "loopback", "file.ogg"]).is_err()); - assert!(Command::parse(&["cras_tests", "filename.wav"]).is_err()); - assert!(Command::parse(&["cras_tests", "filename.wav", "capture"]).is_err()); - assert!(Command::parse(&["cras_tests", "help"]).is_ok()); - assert!(Command::parse(&[ - "cras_tests", - "-c", - "2", - "playback", - "output.wav", - "-r", - "44100" - ]) - .is_err()); - } -} diff --git a/cras/client/cras_tests/src/audio.rs b/cras/client/cras_tests/src/audio.rs deleted file mode 100644 index 23018fd7..00000000 --- a/cras/client/cras_tests/src/audio.rs +++ /dev/null @@ -1,414 +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. - -use std::error; -use std::fmt; -use std::fs::File; -use std::io::{self, BufReader, BufWriter, Read, Write}; -use std::os::raw::c_int; -use std::path::Path; -use std::sync::atomic::{AtomicBool, Ordering}; - -use audio_streams::{SampleFormat, StreamSource}; -use hound::{WavReader, WavSpec, WavWriter}; -use libcras::{BoxError, CrasClient, CrasNodeType}; -use sys_util::{register_signal_handler, set_rt_prio_limit, set_rt_round_robin}; - -use crate::arguments::{AudioOptions, FileType, LoopbackType}; - -#[derive(Debug)] -pub enum Error { - CreateStream(BoxError), - FetchStream(BoxError), - FloatingPointSamples, - InvalidWavFile(hound::Error), - Io(io::Error), - Libcras(libcras::Error), - NoLoopbackNode(CrasNodeType), - OpenFile(hound::Error), - SampleBits(u16), - SysUtil(sys_util::Error), -} - -impl error::Error for Error {} - -impl fmt::Display for Error { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - use Error::*; - match self { - CreateStream(e) => write!(f, "Failed to create stream: {}", e), - FetchStream(e) => write!(f, "Failed to fetch buffer from stream: {}", e), - FloatingPointSamples => write!(f, "Floating point audio samples are not supported"), - InvalidWavFile(e) => write!(f, "Could not open file as WAV file: {}", e), - Io(e) => write!(f, "IO Error: {}", e), - Libcras(e) => write!(f, "Libcras Error: {}", e), - NoLoopbackNode(typ) => write!(f, "No loopback node found with type {:?}", typ), - OpenFile(e) => write!(f, "Could not open WAV file for writing: {}", e), - SampleBits(bits) => write!( - f, - "Sample size {} is not supported, only 8, 16, 24, and 32 bit samples are supported", - bits - ), - SysUtil(e) => write!(f, "SysUtil Error: {}", e), - } - } -} - -type Result<T> = std::result::Result<T, Error>; - -static INTERRUPTED: AtomicBool = AtomicBool::new(false); - -extern "C" fn sigint_handler(_: c_int) { - // Check if we've already received one SIGINT. If we have, the program may - // be misbehaving and not terminating, so to be safe we'll forcefully exit. - if INTERRUPTED.load(Ordering::Acquire) { - std::process::exit(1); - } - INTERRUPTED.store(true, Ordering::Release); -} - -fn add_sigint_handler() -> Result<()> { - const SIGINT: c_int = 2; - let result = unsafe { register_signal_handler(SIGINT, sigint_handler) }; - result.map_err(Error::SysUtil) -} - -fn set_priority_to_realtime() { - const AUDIO_THREAD_RTPRIO: u16 = 10; - if set_rt_prio_limit(AUDIO_THREAD_RTPRIO as u64).is_err() - || set_rt_round_robin(AUDIO_THREAD_RTPRIO as i32).is_err() - { - println!("Attempt to use real-time priority failed, running with default scheduler."); - } -} - -fn channel_string(num_channels: usize) -> String { - match num_channels { - 1 => "Mono".to_string(), - 2 => "Stereo".to_string(), - _ => format!("{} Channels", num_channels), - } -} - -struct WavSource { - wav_reader: WavReader<BufReader<File>>, - format: SampleFormat, - num_channels: usize, - frame_rate: u32, -} - -impl WavSource { - fn try_new(opts: &AudioOptions) -> Result<Self> { - let wav_reader = WavReader::open(&opts.file_name).map_err(Error::InvalidWavFile)?; - let spec = wav_reader.spec(); - if spec.sample_format == hound::SampleFormat::Float { - return Err(Error::FloatingPointSamples); - } - - let format = match spec.bits_per_sample { - 8 => SampleFormat::U8, - 16 => SampleFormat::S16LE, - 24 => SampleFormat::S24LE, - 32 => SampleFormat::S32LE, - s => return Err(Error::SampleBits(s)), - }; - if opts.format.is_some() && Some(format) != opts.format { - eprintln!("Warning: format changed to {:?}", format); - } - - let num_channels = spec.channels as usize; - if opts.num_channels.is_some() && Some(num_channels) != opts.num_channels { - eprintln!("Warning: number of channels changed to {}", num_channels); - } - - let frame_rate = spec.sample_rate; - if opts.frame_rate.is_some() && Some(frame_rate) != opts.frame_rate { - eprintln!("Warning: frame rate changed to {}", frame_rate); - } - - Ok(Self { - wav_reader, - format, - num_channels, - frame_rate, - }) - } - - fn format(&self) -> SampleFormat { - self.format - } - - fn num_channels(&self) -> usize { - self.num_channels - } - - fn frame_rate(&self) -> u32 { - self.frame_rate - } -} - -impl Read for WavSource { - fn read(&mut self, mut buf: &mut [u8]) -> io::Result<usize> { - let frame_size = self.format.sample_bytes() * self.num_channels; - let read_len = buf.len() - buf.len() % frame_size; - let num_samples = read_len / self.format.sample_bytes(); - let samples = self.wav_reader.samples::<i32>(); - let mut read = 0; - for s in samples.take(num_samples) { - match s { - Ok(sample) => { - let result = match self.format { - SampleFormat::U8 => buf.write_all(&((sample + 128) as u8).to_le_bytes()), - SampleFormat::S16LE => buf.write_all(&(sample as i16).to_le_bytes()), - SampleFormat::S24LE | SampleFormat::S32LE => { - buf.write_all(&sample.to_le_bytes()) - } - }; - - match result { - Ok(()) => read += self.format.sample_bytes(), - Err(_) => return Ok(read), - }; - } - Err(_) => return Ok(read), - }; - } - Ok(read) - } -} - -pub fn playback(opts: AudioOptions) -> Result<()> { - let num_channels; - let frame_rate; - let format; - let mut sample_source: Box<dyn Read> = match opts.file_type { - FileType::Wav => { - let wav_source = WavSource::try_new(&opts)?; - num_channels = wav_source.num_channels(); - frame_rate = wav_source.frame_rate(); - format = wav_source.format(); - Box::new(wav_source) - } - FileType::Raw => { - num_channels = opts.num_channels.unwrap_or(2); - frame_rate = opts.frame_rate.unwrap_or(48000); - format = opts.format.unwrap_or(SampleFormat::S16LE); - Box::new(BufReader::new( - File::open(&opts.file_name).map_err(Error::Io)?, - )) - } - }; - - println!( - "Playing {} '{}' : {}, Rate {} Hz, {}", - opts.file_type, - opts.file_name.display(), - format, - frame_rate, - channel_string(num_channels) - ); - - let mut cras_client = CrasClient::new().map_err(Error::Libcras)?; - let (_control, mut stream) = cras_client - .new_playback_stream( - num_channels, - format, - frame_rate, - opts.buffer_size.unwrap_or(256), - ) - .map_err(Error::CreateStream)?; - set_priority_to_realtime(); - - add_sigint_handler()?; - while !INTERRUPTED.load(Ordering::Acquire) { - let mut buffer = stream.next_playback_buffer().map_err(Error::FetchStream)?; - - let frame_size = num_channels * format.sample_bytes(); - let frames = buffer.frame_capacity(); - - let mut chunk = (&mut sample_source).take((frames * frame_size) as u64); - let transferred = io::copy(&mut chunk, &mut buffer).map_err(Error::Io)?; - if transferred == 0 { - break; - } - } - // Stream and client should gracefully be closed out of this scope - - Ok(()) -} - -struct WavSink { - wav_writer: WavWriter<BufWriter<File>>, - format: SampleFormat, -} - -impl WavSink { - fn try_new<P: AsRef<Path>>( - path: P, - num_channels: usize, - format: SampleFormat, - frame_rate: u32, - ) -> Result<Self> { - let spec = WavSpec { - channels: num_channels as u16, - sample_rate: frame_rate, - bits_per_sample: (format.sample_bytes() * 8) as u16, - sample_format: hound::SampleFormat::Int, - }; - let wav_writer = WavWriter::create(path, spec).map_err(Error::OpenFile)?; - Ok(Self { wav_writer, format }) - } -} - -impl Write for WavSink { - fn write(&mut self, samples: &[u8]) -> io::Result<usize> { - let sample_bytes = self.format.sample_bytes(); - if samples.len() % sample_bytes != 0 { - return Err(io::Error::new( - io::ErrorKind::InvalidInput, - format!( - "u8 samples vector of length {} cannot be interpreted as {:?} samples", - samples.len(), - self.format - ), - )); - } - let num_samples = samples.len() / sample_bytes; - match self.format { - SampleFormat::U8 => { - for sample in samples { - self.wav_writer.write_sample(*sample as i8).map_err(|e| { - io::Error::new( - io::ErrorKind::Other, - format!("Failed to write sample: {}", e), - ) - })?; - } - } - SampleFormat::S16LE => { - // hound offers an optimized i16 writer, so special case here. - let mut writer = self.wav_writer.get_i16_writer(num_samples as u32); - for i in 0..num_samples { - let sample = i16::from_le_bytes([ - samples[sample_bytes * i], - samples[sample_bytes * i + 1], - ]); - writer.write_sample(sample); - } - // I16Writer buffers internally and must be explicitly flushed to write - // samples to the backing writer. Flush is not called automatically - // on drop. - // The flush method only writes data from the i16_writer to the underlying - // WavWriter, it does not actually guarantee a flush to disk. - writer.flush().map_err(|e| { - io::Error::new( - io::ErrorKind::Other, - format!("Failed to flush SampleWriter: {}", e), - ) - })?; - } - SampleFormat::S24LE | SampleFormat::S32LE => { - for i in 0..num_samples { - let mut sample = i32::from_le_bytes([ - samples[sample_bytes * i], - samples[sample_bytes * i + 1], - samples[sample_bytes * i + 2], - samples[sample_bytes * i + 3], - ]); - - // Upsample to 32 bit since CRAS doesn't support S24_3LE. - // Our wav encoder/decoder, hound, does have support for - // S24_LE, but it hasn't released a new version since the - // support was added. If getting that support is an issue, - // push upstream to cut a new a release. - if self.format == SampleFormat::S24LE { - sample <<= 8; - } - - self.wav_writer.write_sample(sample).map_err(|e| { - io::Error::new( - io::ErrorKind::Other, - format!("Failed to write sample: {}", e), - ) - })?; - } - } - } - - Ok(samples.len()) - } - - fn flush(&mut self) -> io::Result<()> { - self.wav_writer.flush().map_err(|e| { - io::Error::new( - io::ErrorKind::Other, - format!("Failed to flush WavWriter: {}", e), - ) - }) - } -} - -pub fn capture(opts: AudioOptions) -> Result<()> { - let num_channels = opts.num_channels.unwrap_or(2); - let format = opts.format.unwrap_or(SampleFormat::S16LE); - let frame_rate = opts.frame_rate.unwrap_or(48000); - let buffer_size = opts.buffer_size.unwrap_or(256); - - let mut sample_sink: Box<dyn Write> = match opts.file_type { - FileType::Raw => Box::new(BufWriter::new( - File::create(&opts.file_name).map_err(Error::Io)?, - )), - FileType::Wav => Box::new(WavSink::try_new( - &opts.file_name, - num_channels, - format, - frame_rate, - )?), - }; - - println!( - "Recording {} '{}' : {}, Rate {} Hz, {}", - opts.file_type, - opts.file_name.display(), - format, - frame_rate, - channel_string(num_channels) - ); - - let mut cras_client = CrasClient::new().map_err(Error::Libcras)?; - cras_client.enable_cras_capture(); - let (_control, mut stream) = match opts.loopback_type { - Some(loopback_type) => { - let node_type = match loopback_type { - LoopbackType::PreDsp => CrasNodeType::CRAS_NODE_TYPE_POST_MIX_PRE_DSP, - LoopbackType::PostDsp => CrasNodeType::CRAS_NODE_TYPE_POST_DSP, - }; - - let loopback_node = cras_client - .input_nodes() - .find(|node| node.node_type == node_type) - .ok_or(Error::NoLoopbackNode(node_type))?; - - cras_client - .new_pinned_capture_stream( - loopback_node.iodev_index, - num_channels, - format, - frame_rate, - buffer_size, - ) - .map_err(Error::CreateStream)? - } - None => cras_client - .new_capture_stream(num_channels, format, frame_rate, buffer_size) - .map_err(Error::CreateStream)?, - }; - set_priority_to_realtime(); - add_sigint_handler()?; - while !INTERRUPTED.load(Ordering::Acquire) { - let mut buf = stream.next_capture_buffer().map_err(Error::FetchStream)?; - io::copy(&mut buf, &mut sample_sink).map_err(Error::Io)?; - } - Ok(()) -} diff --git a/cras/client/cras_tests/src/control.rs b/cras/client/cras_tests/src/control.rs deleted file mode 100644 index 3a98ec98..00000000 --- a/cras/client/cras_tests/src/control.rs +++ /dev/null @@ -1,106 +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. - -use std::error; -use std::fmt; - -use libcras::{AudioDebugInfo, CrasClient, CrasIonodeInfo}; - -use crate::arguments::ControlCommand; - -/// An enumeration of errors that can occur when running `ControlCommand` using -/// the `control()` function. -#[derive(Debug)] -pub enum Error { - Libcras(libcras::Error), -} - -impl error::Error for Error {} - -impl fmt::Display for Error { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - use Error::*; - match self { - Libcras(e) => write!(f, "Libcras Error: {}", e), - } - } -} - -type Result<T> = std::result::Result<T, Error>; - -fn print_nodes(nodes: impl Iterator<Item = CrasIonodeInfo>) { - println!( - "{: <13}{: <7}{: <6}{: <10}{: <13}{: <20} {: <10}", - "Stable ID", "ID", "Vol", "Plugged", "Time", "Type", "Name" - ); - for node in nodes { - let id = format!("{}:{}", node.iodev_index, node.ionode_index); - let stable_id = format!("({:08x})", node.stable_id); - let plugged_time = node.plugged_time.tv_sec; - let active = if node.active { "*" } else { " " }; - println!( - "{: <13}{: <7}{: <6}{: <10}{: <13}{: <20}{}{: <10}", - stable_id, - id, - node.volume, - node.plugged, - plugged_time, - node.type_name, - active, - node.name - ); - } -} - -fn print_audio_debug_info(info: &AudioDebugInfo) { - println!("Audio Debug Stats:"); - println!("-------------devices------------"); - for device in &info.devices { - println!("{}", device); - println!(); - } - - println!("-------------stream_dump------------"); - for stream in &info.streams { - println!("{}", stream); - println!(); - } -} - -/// Connect to CRAS and run the given `ControlCommand`. -pub fn control(command: ControlCommand) -> Result<()> { - use ControlCommand::*; - let mut cras_client = CrasClient::new().map_err(Error::Libcras)?; - match command { - GetSystemVolume => println!("{}", cras_client.get_system_volume()), - SetSystemVolume(volume) => { - cras_client - .set_system_volume(volume) - .map_err(Error::Libcras)?; - } - GetSystemMute => println!("{}", cras_client.get_system_mute()), - SetSystemMute(mute) => { - cras_client.set_system_mute(mute).map_err(Error::Libcras)?; - } - ListOutputDevices => { - println!("{: <5}{: <10}", "ID", "Name"); - for dev in cras_client.output_devices() { - println!("{: <5}{: <10}", dev.index, dev.name); - } - } - ListInputDevices => { - println!("{: <5}{: <10}", "ID", "Name"); - for dev in cras_client.input_devices() { - println!("{: <5}{: <10}", dev.index, dev.name); - } - } - ListOutputNodes => print_nodes(cras_client.output_nodes()), - ListInputNodes => print_nodes(cras_client.input_nodes()), - DumpAudioDebugInfo => { - let debug_info = cras_client.get_audio_debug_info().map_err(Error::Libcras)?; - print_audio_debug_info(&debug_info); - } - }; - Ok(()) -} diff --git a/cras/client/cras_tests/src/main.rs b/cras/client/cras_tests/src/main.rs deleted file mode 100644 index 50ffd090..00000000 --- a/cras/client/cras_tests/src/main.rs +++ /dev/null @@ -1,58 +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. - -mod arguments; -mod audio; -mod control; - -use std::error; -use std::fmt; - -use crate::arguments::Command; -use crate::audio::{capture, playback}; -use crate::control::control; - -#[derive(Debug)] -pub enum Error { - Audio(audio::Error), - ParseArgs(arguments::Error), - Control(control::Error), -} - -impl error::Error for Error {} - -impl fmt::Display for Error { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - use Error::*; - match self { - Audio(e) => e.fmt(f), - ParseArgs(e) => write!(f, "Failed to parse arguments: {}", e), - Control(e) => e.fmt(f), - } - } -} - -type Result<T> = std::result::Result<T, Error>; - -fn run() -> Result<()> { - let args: Vec<String> = std::env::args().collect(); - let command = match Command::parse(&args).map_err(Error::ParseArgs)? { - None => return Ok(()), - Some(v) => v, - }; - - match command { - Command::Capture(audio_opts) => capture(audio_opts).map_err(Error::Audio), - Command::Control(command) => control(command).map_err(Error::Control), - Command::Playback(audio_opts) => playback(audio_opts).map_err(Error::Audio), - } -} - -fn main() { - // Use run() instead of returning a Result from main() so that we can print - // errors using Display instead of Debug. - if let Err(e) = run() { - eprintln!("{}", e); - } -} diff --git a/cras/client/libcras/.gitignore b/cras/client/libcras/.gitignore deleted file mode 100644 index fa8d85ac..00000000 --- a/cras/client/libcras/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -Cargo.lock -target diff --git a/cras/client/libcras/.rustfmt.toml b/cras/client/libcras/.rustfmt.toml deleted file mode 100644 index a2db3012..00000000 --- a/cras/client/libcras/.rustfmt.toml +++ /dev/null @@ -1,2 +0,0 @@ -use_field_init_shorthand = true -use_try_shorthand = true diff --git a/cras/client/libcras/Android.bp b/cras/client/libcras/Android.bp deleted file mode 100644 index aecb27a2..00000000 --- a/cras/client/libcras/Android.bp +++ /dev/null @@ -1,69 +0,0 @@ -// This file is generated by cargo2android.py --run --device --test --global_defaults=crosvm_defaults --dependencies. - -package { - // See: http://go/android-license-faq - // A large-scale-change added 'default_applicable_licenses' to import - // all of the 'license_kinds' from "external_adhd_license" - // to get the below license kinds: - // SPDX-license-identifier-BSD - default_applicable_licenses: ["external_adhd_license"], -} - -rust_defaults { - name: "libcras_defaults", - defaults: ["crosvm_defaults"], - crate_name: "libcras", - srcs: ["src/libcras.rs"], - test_suites: ["general-tests"], - auto_gen_config: true, - edition: "2018", - rustlibs: [ - "libaudio_streams", - "libcras_sys", - "libdata_model", - "liblibc", - "libsys_util", - ], -} - -rust_test_host { - name: "libcras_host_test_src_libcras", - defaults: ["libcras_defaults"], -} - -rust_test { - name: "libcras_device_test_src_libcras", - defaults: ["libcras_defaults"], -} - -rust_library { - name: "liblibcras", - defaults: ["crosvm_defaults"], - host_supported: true, - crate_name: "libcras", - srcs: ["src/libcras.rs"], - edition: "2018", - rustlibs: [ - "libaudio_streams", - "libcras_sys", - "libdata_model", - "liblibc", - "libsys_util", - ], -} - -// dependent_library ["feature_list"] -// ../../../../crosvm/assertions/src/lib.rs -// ../../../../crosvm/data_model/src/lib.rs -// ../../../../crosvm/sync/src/lib.rs -// ../../../../crosvm/sys_util/poll_token_derive/poll_token_derive.rs -// ../../../../crosvm/sys_util/src/lib.rs -// ../../../../crosvm/syscall_defines/src/lib.rs -// ../../../../crosvm/tempfile/src/lib.rs -// ../../../audio_streams/src/audio_streams.rs -// ../cras-sys/src/lib.rs -// libc-0.2.76 "default,std" -// proc-macro2-1.0.19 "default,proc-macro" -// quote-1.0.7 "default,proc-macro" -// syn-1.0.39 "clone-impls,default,derive,parsing,printing,proc-macro,quote" -// unicode-xid-0.2.1 "default" diff --git a/cras/client/libcras/Cargo.toml b/cras/client/libcras/Cargo.toml deleted file mode 100644 index b52a2612..00000000 --- a/cras/client/libcras/Cargo.toml +++ /dev/null @@ -1,15 +0,0 @@ -[package] -name = "libcras" -version = "0.1.0" -authors = ["The Chromium OS Authors"] -edition = "2018" - -[lib] -path = "src/libcras.rs" - -[dependencies] -audio_streams = { path = "../../../audio_streams" } # provided by ebuild -libc = "*" -cras-sys = { path = "../cras-sys" } # provided by ebuild -data_model = { path = "../../../../crosvm/data_model" } # provided by ebuild -sys_util = { path = "../../../../crosvm/sys_util" } # provided by ebuild diff --git a/cras/client/libcras/src/audio_socket.rs b/cras/client/libcras/src/audio_socket.rs deleted file mode 100644 index ac56144c..00000000 --- a/cras/client/libcras/src/audio_socket.rs +++ /dev/null @@ -1,316 +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. -use std::io; -use std::io::{Read, Write}; -use std::mem; -use std::os::unix::{ - io::{AsRawFd, RawFd}, - net::UnixStream, -}; -use std::time::Duration; - -use cras_sys::gen::{audio_message, CRAS_AUDIO_MESSAGE_ID}; -use data_model::DataInit; -use sys_util::{PollContext, PollToken}; - -/// A structure for interacting with the CRAS server audio thread through a `UnixStream::pair`. -pub struct AudioSocket { - socket: UnixStream, -} - -/// Audio message results which are exchanged by `CrasStream` and CRAS audio server. -/// through an audio socket. -#[allow(dead_code)] -#[derive(Debug)] -pub enum AudioMessage { - /// * `id` - Audio message id, which is a `enum CRAS_AUDIO_MESSAGE_ID`. - /// * `frames` - A `u32` indicating the read or written frame count. - Success { - id: CRAS_AUDIO_MESSAGE_ID, - frames: u32, - }, - /// * `error` - Error code when a error occurs. - Error(i32), -} - -/// Converts AudioMessage to raw audio_message for CRAS audio server. -impl Into<audio_message> for AudioMessage { - fn into(self) -> audio_message { - match self { - AudioMessage::Success { id, frames } => audio_message { - id, - error: 0, - frames, - }, - AudioMessage::Error(error) => audio_message { - id: CRAS_AUDIO_MESSAGE_ID::AUDIO_MESSAGE_REQUEST_DATA, - error, - frames: 0, - }, - } - } -} - -/// Converts AudioMessage from raw audio_message from CRAS audio server. -impl From<audio_message> for AudioMessage { - fn from(message: audio_message) -> Self { - match message.error { - 0 => AudioMessage::Success { - id: message.id as CRAS_AUDIO_MESSAGE_ID, - frames: message.frames, - }, - error => AudioMessage::Error(error), - } - } -} - -impl AudioSocket { - /// Creates `AudioSocket` from a `UnixStream`. - /// - /// # Arguments - /// `socket` - A `UnixStream`. - pub fn new(socket: UnixStream) -> Self { - AudioSocket { socket } - } - - fn read_from_socket<T>(&mut self) -> io::Result<T> - where - T: Sized + DataInit + Default, - { - let mut message: T = Default::default(); - let rc = self.socket.read(message.as_mut_slice())?; - if rc == mem::size_of::<T>() { - Ok(message) - } else { - Err(io::Error::new(io::ErrorKind::Other, "Read truncated data.")) - } - } - - /// Blocks reading an `audio message`. - /// - /// # Returns - /// `AudioMessage` - AudioMessage enum. - /// - /// # Errors - /// Returns io::Error if error occurs. - pub fn read_audio_message(&mut self) -> io::Result<AudioMessage> { - match self.read_audio_message_with_timeout(None)? { - None => Err(io::Error::new(io::ErrorKind::Other, "Unexpected exit")), - Some(message) => Ok(message), - } - } - - /// Blocks waiting for an `audio message` until `timeout` occurs. If `timeout` - /// is None, blocks indefinitely. - /// - /// # Returns - /// Some(AudioMessage) - AudioMessage enum if we receive a message before timeout. - /// None - If the timeout expires. - /// - /// # Errors - /// Returns io::Error if error occurs. - pub fn read_audio_message_with_timeout( - &mut self, - timeout: Option<Duration>, - ) -> io::Result<Option<AudioMessage>> { - #[derive(PollToken)] - enum Token { - AudioMsg, - } - let poll_ctx: PollContext<Token> = - match PollContext::new().and_then(|pc| pc.add(self, Token::AudioMsg).and(Ok(pc))) { - Ok(pc) => pc, - Err(e) => { - return Err(io::Error::new( - io::ErrorKind::Other, - format!("Failed to create PollContext: {}", e), - )); - } - }; - let events = { - let result = match timeout { - None => poll_ctx.wait(), - Some(duration) => poll_ctx.wait_timeout(duration), - }; - match result { - Ok(v) => v, - Err(e) => { - return Err(io::Error::new( - io::ErrorKind::Other, - format!("Failed to poll: {:?}", e), - )); - } - } - }; - - // Check the first readable message - let tokens: Vec<Token> = events.iter_readable().map(|e| e.token()).collect(); - match tokens.get(0) { - None => Ok(None), - Some(&Token::AudioMsg) => { - let raw_msg: audio_message = self.read_from_socket()?; - Ok(Some(AudioMessage::from(raw_msg))) - } - } - } - - /// Sends raw audio message with given AudioMessage enum. - /// - /// # Arguments - /// * `msg` - enum AudioMessage, which could be `Success` with message id - /// and frames or `Error` with error code. - /// - /// # Errors - /// Returns error if `libc::write` fails. - fn send_audio_message(&mut self, msg: AudioMessage) -> io::Result<()> { - let msg: audio_message = msg.into(); - let rc = self.socket.write(msg.as_slice())?; - if rc < mem::size_of::<audio_message>() { - Err(io::Error::new(io::ErrorKind::Other, "Sent truncated data.")) - } else { - Ok(()) - } - } - - /// Sends the data ready message with written frame count. - /// - /// # Arguments - /// * `frames` - An `u32` indicating the written frame count. - pub fn data_ready(&mut self, frames: u32) -> io::Result<()> { - self.send_audio_message(AudioMessage::Success { - id: CRAS_AUDIO_MESSAGE_ID::AUDIO_MESSAGE_DATA_READY, - frames, - }) - } - - /// Sends the capture ready message with read frame count. - /// - /// # Arguments - /// - /// * `frames` - An `u32` indicating the number of read frames. - pub fn capture_ready(&mut self, frames: u32) -> io::Result<()> { - self.send_audio_message(AudioMessage::Success { - id: CRAS_AUDIO_MESSAGE_ID::AUDIO_MESSAGE_DATA_CAPTURED, - frames, - }) - } -} - -impl AsRawFd for AudioSocket { - fn as_raw_fd(&self) -> RawFd { - self.socket.as_raw_fd() - } -} - -#[cfg(test)] -mod tests { - use super::*; - - // PartialEq for comparing AudioMessage in tests - impl PartialEq for AudioMessage { - fn eq(&self, other: &Self) -> bool { - match (self, other) { - ( - AudioMessage::Success { id, frames }, - AudioMessage::Success { - id: other_id, - frames: other_frames, - }, - ) => id == other_id && frames == other_frames, - (AudioMessage::Error(err), AudioMessage::Error(other_err)) => err == other_err, - _ => false, - } - } - } - - fn init_audio_socket_pair() -> (AudioSocket, AudioSocket) { - let (sock1, sock2) = UnixStream::pair().unwrap(); - let sender = AudioSocket::new(sock1); - let receiver = AudioSocket::new(sock2); - (sender, receiver) - } - - #[test] - fn audio_socket_send_and_recv_audio_message() { - let (mut sender, mut receiver) = init_audio_socket_pair(); - let message_succ = AudioMessage::Success { - id: CRAS_AUDIO_MESSAGE_ID::AUDIO_MESSAGE_REQUEST_DATA, - frames: 0, - }; - sender.send_audio_message(message_succ).unwrap(); - let res = receiver.read_audio_message().unwrap(); - assert_eq!( - res, - AudioMessage::Success { - id: CRAS_AUDIO_MESSAGE_ID::AUDIO_MESSAGE_REQUEST_DATA, - frames: 0 - } - ); - - let message_err = AudioMessage::Error(123); - sender.send_audio_message(message_err).unwrap(); - let res = receiver.read_audio_message().unwrap(); - assert_eq!(res, AudioMessage::Error(123)); - } - - #[test] - fn audio_socket_data_ready_send_and_recv() { - let (sock1, sock2) = UnixStream::pair().unwrap(); - let mut audio_socket_send = AudioSocket::new(sock1); - let mut audio_socket_recv = AudioSocket::new(sock2); - audio_socket_send.data_ready(256).unwrap(); - - // Test receiving by using raw audio_message since CRAS audio server use this. - let audio_msg: audio_message = audio_socket_recv.read_from_socket().unwrap(); - let ref_audio_msg = audio_message { - id: CRAS_AUDIO_MESSAGE_ID::AUDIO_MESSAGE_DATA_READY, - error: 0, - frames: 256, - }; - // Use brace to copy unaligned data locally - assert_eq!({ audio_msg.id }, { ref_audio_msg.id }); - assert_eq!({ audio_msg.error }, { ref_audio_msg.error }); - assert_eq!({ audio_msg.frames }, { ref_audio_msg.frames }); - } - - #[test] - fn audio_socket_capture_ready() { - let (sock1, sock2) = UnixStream::pair().unwrap(); - let mut audio_socket_send = AudioSocket::new(sock1); - let mut audio_socket_recv = AudioSocket::new(sock2); - audio_socket_send - .capture_ready(256) - .expect("Failed to send capture ready message."); - - // Test receiving by using raw audio_message since CRAS audio server use this. - let audio_msg: audio_message = audio_socket_recv - .read_from_socket() - .expect("Failed to read audio message from AudioSocket."); - let ref_audio_msg = audio_message { - id: CRAS_AUDIO_MESSAGE_ID::AUDIO_MESSAGE_DATA_CAPTURED, - error: 0, - frames: 256, - }; - // Use brace to copy unaligned data locally - assert_eq!({ audio_msg.id }, { ref_audio_msg.id }); - assert_eq!({ audio_msg.error }, { ref_audio_msg.error }); - assert_eq!({ audio_msg.frames }, { ref_audio_msg.frames }); - } - - #[test] - fn audio_socket_send_when_broken_pipe() { - let sock1 = { - let (sock1, _) = UnixStream::pair().unwrap(); - sock1 - }; - let mut audio_socket = AudioSocket::new(sock1); - let res = audio_socket.data_ready(256); - //Broken pipe - assert_eq!( - res.expect_err("Result should be an error.").kind(), - io::Error::from_raw_os_error(32).kind(), - "Error should be broken pipe.", - ); - } -} diff --git a/cras/client/libcras/src/cras_client_message.rs b/cras/client/libcras/src/cras_client_message.rs deleted file mode 100644 index c1c5ec5c..00000000 --- a/cras/client/libcras/src/cras_client_message.rs +++ /dev/null @@ -1,200 +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. -use std::{array::TryFromSliceError, convert::TryInto, error, fmt, io, mem, os::unix::io::RawFd}; - -use cras_sys::gen::{ - cras_client_connected, cras_client_message, cras_client_stream_connected, - CRAS_CLIENT_MAX_MSG_SIZE, - CRAS_CLIENT_MESSAGE_ID::{self, *}, -}; -use data_model::DataInit; -use sys_util::ScmSocket; - -use crate::cras_server_socket::CrasServerSocket; -use crate::cras_shm::*; -use crate::cras_stream; - -#[derive(Debug)] -pub enum Error { - IoError(io::Error), - SysUtilError(sys_util::Error), - CrasStreamError(cras_stream::Error), - ArrayTryFromSliceError(TryFromSliceError), - InvalidSize, - MessageTypeError, - MessageNumFdError, - MessageTruncated, - MessageIdError, - MessageFromSliceError, -} - -impl error::Error for Error {} - -impl fmt::Display for Error { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - Error::IoError(ref err) => err.fmt(f), - Error::SysUtilError(ref err) => err.fmt(f), - Error::MessageTypeError => write!(f, "Message type error"), - Error::CrasStreamError(ref err) => err.fmt(f), - Error::ArrayTryFromSliceError(ref err) => err.fmt(f), - Error::MessageNumFdError => write!(f, "Message the number of fds is not matched"), - Error::MessageTruncated => write!(f, "Read truncated message"), - Error::MessageIdError => write!(f, "No such id"), - Error::MessageFromSliceError => write!(f, "Message from slice error"), - Error::InvalidSize => write!(f, "Invalid data size"), - } - } -} - -type Result<T> = std::result::Result<T, Error>; - -impl From<io::Error> for Error { - fn from(io_err: io::Error) -> Self { - Error::IoError(io_err) - } -} - -impl From<sys_util::Error> for Error { - fn from(sys_util_err: sys_util::Error) -> Self { - Error::SysUtilError(sys_util_err) - } -} - -impl From<cras_stream::Error> for Error { - fn from(err: cras_stream::Error) -> Self { - Error::CrasStreamError(err) - } -} - -impl From<TryFromSliceError> for Error { - fn from(err: TryFromSliceError) -> Self { - Error::ArrayTryFromSliceError(err) - } -} - -/// A handled server result from one message sent from CRAS server. -pub enum ServerResult { - /// client_id, CrasServerStateShmFd - Connected(u32, CrasServerStateShmFd), - /// stream_id, header_fd, samples_fd - StreamConnected(u32, CrasAudioShmHeaderFd, CrasShmFd), - DebugInfoReady, -} - -impl ServerResult { - /// Reads and handles one server message and converts `CrasClientMessage` into `ServerResult` - /// with error handling. - /// - /// # Arguments - /// * `server_socket`: A reference to `CrasServerSocket`. - pub fn handle_server_message(server_socket: &CrasServerSocket) -> Result<ServerResult> { - let message = CrasClientMessage::try_new(&server_socket)?; - match message.get_id()? { - CRAS_CLIENT_MESSAGE_ID::CRAS_CLIENT_CONNECTED => { - let cmsg: &cras_client_connected = message.get_message()?; - // CRAS server should return a shared memory area which contains - // `cras_server_state`. - let server_state_fd = unsafe { CrasServerStateShmFd::new(message.fds[0]) }; - Ok(ServerResult::Connected(cmsg.client_id, server_state_fd)) - } - CRAS_CLIENT_MESSAGE_ID::CRAS_CLIENT_STREAM_CONNECTED => { - let cmsg: &cras_client_stream_connected = message.get_message()?; - // CRAS should return two shared memory areas the first which has - // mem::size_of::<cras_audio_shm_header>() bytes, and the second which has - // `samples_shm_size` bytes. - Ok(ServerResult::StreamConnected( - cmsg.stream_id, - // Safe because CRAS ensures that the first fd contains a cras_audio_shm_header - unsafe { CrasAudioShmHeaderFd::new(message.fds[0]) }, - // Safe because CRAS ensures that the second fd has length 'samples_shm_size' - unsafe { CrasShmFd::new(message.fds[1], cmsg.samples_shm_size as usize) }, - )) - } - CRAS_CLIENT_MESSAGE_ID::CRAS_CLIENT_AUDIO_DEBUG_INFO_READY => { - Ok(ServerResult::DebugInfoReady) - } - _ => Err(Error::MessageTypeError), - } - } -} - -// A structure for raw message with fds from CRAS server. -struct CrasClientMessage { - fds: [RawFd; 2], - data: [u8; CRAS_CLIENT_MAX_MSG_SIZE as usize], - len: usize, -} - -/// The default constructor won't be used outside of this file and it's an optimization to prevent -/// having to copy the message data from a temp buffer. -impl Default for CrasClientMessage { - // Initializes fields with default values. - fn default() -> Self { - Self { - fds: [-1; 2], - data: [0; CRAS_CLIENT_MAX_MSG_SIZE as usize], - len: 0, - } - } -} - -impl CrasClientMessage { - // Reads a message from server_socket and checks validity of the read result - fn try_new(server_socket: &CrasServerSocket) -> Result<CrasClientMessage> { - let mut message: Self = Default::default(); - let (len, fd_nums) = server_socket.recv_with_fds(&mut message.data, &mut message.fds)?; - - if len < mem::size_of::<cras_client_message>() { - Err(Error::MessageTruncated) - } else { - message.len = len; - message.check_fd_nums(fd_nums)?; - Ok(message) - } - } - - // Check if `fd nums` of a read result is valid - fn check_fd_nums(&self, fd_nums: usize) -> Result<()> { - match self.get_id()? { - CRAS_CLIENT_CONNECTED => match fd_nums { - 1 => Ok(()), - _ => Err(Error::MessageNumFdError), - }, - CRAS_CLIENT_STREAM_CONNECTED => match fd_nums { - // CRAS should return two shared memory areas the first which has - // mem::size_of::<cras_audio_shm_header>() bytes, and the second which has - // `samples_shm_size` bytes. - 2 => Ok(()), - _ => Err(Error::MessageNumFdError), - }, - CRAS_CLIENT_AUDIO_DEBUG_INFO_READY => match fd_nums { - 0 => Ok(()), - _ => Err(Error::MessageNumFdError), - }, - _ => Err(Error::MessageTypeError), - } - } - - // Gets the message id - fn get_id(&self) -> Result<CRAS_CLIENT_MESSAGE_ID> { - let offset = mem::size_of::<u32>(); - match u32::from_le_bytes(self.data[offset..offset + 4].try_into()?) { - id if id == (CRAS_CLIENT_CONNECTED as u32) => Ok(CRAS_CLIENT_CONNECTED), - id if id == (CRAS_CLIENT_STREAM_CONNECTED as u32) => Ok(CRAS_CLIENT_STREAM_CONNECTED), - id if id == (CRAS_CLIENT_AUDIO_DEBUG_INFO_READY as u32) => { - Ok(CRAS_CLIENT_AUDIO_DEBUG_INFO_READY) - } - _ => Err(Error::MessageIdError), - } - } - - // Gets a reference to the message content - fn get_message<T: DataInit>(&self) -> Result<&T> { - if self.len != mem::size_of::<T>() { - return Err(Error::InvalidSize); - } - T::from_slice(&self.data[..mem::size_of::<T>()]).ok_or(Error::MessageFromSliceError) - } -} diff --git a/cras/client/libcras/src/cras_server_socket.rs b/cras/client/libcras/src/cras_server_socket.rs deleted file mode 100644 index 4a7d9151..00000000 --- a/cras/client/libcras/src/cras_server_socket.rs +++ /dev/null @@ -1,124 +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. -use std::os::unix::io::{AsRawFd, RawFd}; -use std::{io, mem}; - -use cras_sys::gen::{cras_disconnect_stream_message, cras_server_message, CRAS_SERVER_MESSAGE_ID}; -use sys_util::{net::UnixSeqpacket, ScmSocket}; - -use data_model::DataInit; - -/// Server socket type to connect. -pub enum CrasSocketType { - /// A server socket type supports only playback function. - Legacy, - /// A server socket type supports both playback and capture functions. - Unified, -} - -impl CrasSocketType { - fn sock_path(&self) -> &str { - match self { - Self::Legacy => "/run/cras/.cras_socket", - Self::Unified => "/run/cras/.cras_unified", - } - } -} - -/// A socket connecting to the CRAS audio server. -pub struct CrasServerSocket { - socket: UnixSeqpacket, -} - -impl CrasServerSocket { - pub fn new() -> io::Result<CrasServerSocket> { - Self::with_type(CrasSocketType::Legacy) - } - - /// Creates a `CrasServerSocket` with given `CrasSocketType`. - /// - /// # Errors - /// - /// Returns the `io::Error` generated when connecting to the socket on failure. - pub fn with_type(socket_type: CrasSocketType) -> io::Result<CrasServerSocket> { - Ok(CrasServerSocket { - socket: UnixSeqpacket::connect(socket_type.sock_path())?, - }) - } - - /// Sends a sized and packed server messge to the server socket. The message - /// must implement `Sized` and `DataInit`. - /// # Arguments - /// * `message` - A sized and packed message. - /// * `fds` - A slice of fds to send. - /// - /// # Returns - /// * Length of written bytes in `usize`. - /// - /// # Errors - /// Return error if the socket fails to write message to server. - pub fn send_server_message_with_fds<M: Sized + DataInit>( - &self, - message: &M, - fds: &[RawFd], - ) -> io::Result<usize> { - match fds.len() { - 0 => self.socket.send(message.as_slice()), - _ => { - let ioslice = io::IoSlice::new(message.as_slice()); - match self.send_with_fds(&[ioslice], fds) { - Ok(len) => Ok(len), - Err(err) => Err(io::Error::new(io::ErrorKind::Other, format!("{}", err))), - } - } - } - } - - /// Creates a clone of the underlying socket. The returned clone can also be - /// used to communicate with the cras server. - pub fn try_clone(&self) -> io::Result<CrasServerSocket> { - let new_sock = self.socket.try_clone()?; - Ok(CrasServerSocket { socket: new_sock }) - } - - /// Send a message to request disconnection of the given stream. - /// - /// Builds a `cras_disconnect_stream_message` containing `stream_id` and - /// sends it to the server. - /// No response is expected. - /// - /// # Arguments - /// - /// * `stream_id` - The id of the stream that should be disconnected. - /// - /// # Errors - /// - /// * If the message was not written to the server socket successfully. - pub fn disconnect_stream(&self, stream_id: u32) -> io::Result<()> { - let msg_header = cras_server_message { - length: mem::size_of::<cras_disconnect_stream_message>() as u32, - id: CRAS_SERVER_MESSAGE_ID::CRAS_SERVER_DISCONNECT_STREAM, - }; - let server_cmsg = cras_disconnect_stream_message { - header: msg_header, - stream_id, - }; - self.send_server_message_with_fds(&server_cmsg, &[]) - .map(|_| ()) - } -} - -// For using `recv_with_fds` and `send_with_fds`. -impl ScmSocket for CrasServerSocket { - fn socket_fd(&self) -> RawFd { - self.socket.as_raw_fd() - } -} - -// For using `PollContex`. -impl AsRawFd for CrasServerSocket { - fn as_raw_fd(&self) -> RawFd { - self.socket.as_raw_fd() - } -} diff --git a/cras/client/libcras/src/cras_shm.rs b/cras/client/libcras/src/cras_shm.rs deleted file mode 100644 index 05533753..00000000 --- a/cras/client/libcras/src/cras_shm.rs +++ /dev/null @@ -1,1308 +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. -use std::convert::TryFrom; -use std::io; -use std::mem; -use std::os::unix::io::{AsRawFd, RawFd}; -use std::ptr; -use std::ptr::NonNull; -use std::slice; -use std::sync::atomic::{self, Ordering}; -use std::thread; - -use cras_sys::gen::{ - audio_dev_debug_info, audio_stream_debug_info, cras_audio_shm_header, cras_iodev_info, - cras_ionode_info, cras_server_state, CRAS_MAX_IODEVS, CRAS_MAX_IONODES, CRAS_NUM_SHM_BUFFERS, - CRAS_SERVER_STATE_VERSION, CRAS_SHM_BUFFERS_MASK, MAX_DEBUG_DEVS, MAX_DEBUG_STREAMS, -}; -use cras_sys::{ - AudioDebugInfo, AudioDevDebugInfo, AudioStreamDebugInfo, CrasIodevInfo, CrasIonodeInfo, -}; -use data_model::{VolatileRef, VolatileSlice}; -use sys_util::warn; - -/// A structure wrapping a fd which contains a shared `cras_audio_shm_header`. -/// * `shm_fd` - A shared memory fd contains a `cras_audio_shm_header` -pub struct CrasAudioShmHeaderFd { - fd: CrasShmFd, -} - -impl CrasAudioShmHeaderFd { - /// Creates a `CrasAudioShmHeaderFd` by shared memory fd - /// # Arguments - /// * `fd` - A shared memory file descriptor, which will be owned by the resulting structure and - /// the fd will be closed on drop. - /// - /// # Returns - /// A structure wrapping a `CrasShmFd` with the input fd and `size` which equals to - /// the size of `cras_audio_shm_header`. - /// - /// To use this function safely, we need to make sure - /// - The input fd is a valid shared memory fd. - /// - The input shared memory fd won't be used by others. - /// - The shared memory area in the input fd contains a `cras_audio_shm_header`. - pub unsafe fn new(fd: libc::c_int) -> Self { - Self { - fd: CrasShmFd::new(fd, mem::size_of::<cras_audio_shm_header>()), - } - } -} - -/// A wrapper for the raw structure `cras_audio_shm_header` with -/// size information for the separate audio samples shm area and several -/// `VolatileRef` to sub fields for safe access to the header. -pub struct CrasAudioHeader<'a> { - addr: *mut libc::c_void, - /// Size of the buffer for samples in CrasAudioBuffer - samples_len: usize, - used_size: VolatileRef<'a, u32>, - frame_size: VolatileRef<'a, u32>, - read_buf_idx: VolatileRef<'a, u32>, - write_buf_idx: VolatileRef<'a, u32>, - read_offset: [VolatileRef<'a, u32>; CRAS_NUM_SHM_BUFFERS as usize], - write_offset: [VolatileRef<'a, u32>; CRAS_NUM_SHM_BUFFERS as usize], - buffer_offset: [VolatileRef<'a, u64>; CRAS_NUM_SHM_BUFFERS as usize], -} - -// It is safe to send audio buffers between threads as this struct has exclusive ownership of the -// pointers contained in it. -unsafe impl<'a> Send for CrasAudioHeader<'a> {} - -/// An unsafe macro for getting `VolatileRef` for a field from a given NonNull pointer. -/// It Supports -/// - Nested sub-field -/// - Element of an array field -/// -/// To use this macro safely, we need to -/// - Make sure the pointer address is readable and writable for its structure. -/// - Make sure all `VolatileRef`s generated from this macro have exclusive ownership for the same -/// pointer. -#[macro_export] -macro_rules! vref_from_addr { - ($addr:ident, $($field:ident).*) => { - VolatileRef::new(&mut $addr.as_mut().$($field).* as *mut _) - }; - - ($addr:ident, $field:ident[$idx:tt]) => { - VolatileRef::new(&mut $addr.as_mut().$field[$idx] as *mut _) - }; -} - -// Generates error when an index is out of range. -fn index_out_of_range() -> io::Error { - io::Error::new(io::ErrorKind::InvalidInput, "Index out of range.") -} - -impl<'a> CrasAudioHeader<'a> { - // Creates a `CrasAudioHeader` with given `CrasAudioShmHeaderFd` and `samples_len` - fn new(header_fd: CrasAudioShmHeaderFd, samples_len: usize) -> io::Result<Self> { - // Safe because the creator of CrasAudioShmHeaderFd already - // ensured that header_fd contains a cras_audio_shm_header. - let mmap_addr = unsafe { - cras_mmap( - header_fd.fd.size, - libc::PROT_READ | libc::PROT_WRITE, - header_fd.fd.as_raw_fd(), - )? - }; - - let mut addr = NonNull::new(mmap_addr as *mut cras_audio_shm_header) - .ok_or_else(|| io::Error::new(io::ErrorKind::Other, "Failed to create header."))?; - - // Safe because we know that mmap_addr (contained in addr) contains a - // cras_audio_shm_header, and the mapped area will be exclusively - // owned by this struct. - unsafe { - Ok(CrasAudioHeader { - addr: addr.as_ptr() as *mut libc::c_void, - samples_len, - used_size: vref_from_addr!(addr, config.used_size), - frame_size: vref_from_addr!(addr, config.frame_bytes), - read_buf_idx: vref_from_addr!(addr, read_buf_idx), - write_buf_idx: vref_from_addr!(addr, write_buf_idx), - read_offset: [ - vref_from_addr!(addr, read_offset[0]), - vref_from_addr!(addr, read_offset[1]), - ], - write_offset: [ - vref_from_addr!(addr, write_offset[0]), - vref_from_addr!(addr, write_offset[1]), - ], - buffer_offset: [ - vref_from_addr!(addr, buffer_offset[0]), - vref_from_addr!(addr, buffer_offset[1]), - ], - }) - } - } - - /// Calculates the length of a buffer with the given offset. This length will - /// be `used_size`, unless the offset is closer than `used_size` to the end - /// of samples, in which case the length will be as long as possible. - /// - /// If that buffer length is invalid (too small to hold a frame of audio data), - /// then returns an error. - /// The returned buffer length will be rounded down to a multiple of `frame_size`. - fn buffer_len_from_offset(&self, offset: usize) -> io::Result<usize> { - if offset > self.samples_len { - return Err(io::Error::new( - io::ErrorKind::InvalidInput, - format!( - "Buffer offset {} exceeds the length of samples area ({}).", - offset, self.samples_len - ), - )); - } - - let used_size = self.get_used_size(); - let frame_size = self.get_frame_size(); - - // We explicitly allow a buffer shorter than used_size, but only - // at the end of the samples area. - // This is useful if we're playing a file where the number of samples is - // not a multiple of used_size (meaning the length of the samples area - // won't be either). Then, the last buffer played will be smaller than - // used_size. - let mut buffer_length = used_size.min(self.samples_len - offset); - if buffer_length < frame_size { - return Err(io::Error::new( - io::ErrorKind::InvalidInput, - format!( - "Buffer offset {} gives buffer length {} smaller than frame size {}.", - offset, buffer_length, frame_size - ), - )); - } - - // Round buffer_length down to a multiple of frame size - buffer_length = buffer_length / frame_size * frame_size; - Ok(buffer_length) - } - - /// Gets the base of the write buffer and the writable length (rounded to `frame_size`). - /// Does not take into account the write offset. - /// - /// # Returns - /// - /// * (`usize`, `usize`) - write buffer base as an offset from the start of - /// the samples area and buffer length in bytes. - pub fn get_write_offset_and_len(&self) -> io::Result<(usize, usize)> { - let idx = self.get_write_buf_idx() as usize; - let offset = self.get_buffer_offset(idx)?; - let len = self.buffer_len_from_offset(offset)?; - - Ok((offset, len)) - } - - /// Gets the buffer offset of the read buffer. - /// - /// # Returns - /// - /// * `usize` - read offset in bytes - pub fn get_read_buffer_offset(&self) -> io::Result<usize> { - let idx = self.get_read_buf_idx() as usize; - self.get_buffer_offset(idx) - } - - /// Gets the offset of a buffer from the start of samples. - /// - /// # Arguments - /// `index` - 0 <= `index` < `CRAS_NUM_SHM_BUFFERS`. The index of the buffer - /// for which we want the `buffer_offset`. - /// - /// # Returns - /// * `usize` - buffer offset in bytes - fn get_buffer_offset(&self, idx: usize) -> io::Result<usize> { - let buffer_offset = self - .buffer_offset - .get(idx) - .ok_or_else(index_out_of_range)? - .load() as usize; - self.check_buffer_offset(idx, buffer_offset)?; - Ok(buffer_offset) - } - - /// Gets the number of bytes per frame from the shared memory structure. - /// - /// # Returns - /// - /// * `usize` - Number of bytes per frame - pub fn get_frame_size(&self) -> usize { - self.frame_size.load() as usize - } - - /// Gets the max size in bytes of each shared memory buffer within - /// the samples area. - /// - /// # Returns - /// - /// * `usize` - Value of `used_size` fetched from the shared memory header. - pub fn get_used_size(&self) -> usize { - self.used_size.load() as usize - } - - /// Gets the index of the current written buffer. - /// - /// # Returns - /// `u32` - the returned index is less than `CRAS_NUM_SHM_BUFFERS`. - fn get_write_buf_idx(&self) -> u32 { - self.write_buf_idx.load() & CRAS_SHM_BUFFERS_MASK - } - - fn get_read_buf_idx(&self) -> u32 { - self.read_buf_idx.load() & CRAS_SHM_BUFFERS_MASK - } - - /// Switches the written buffer. - fn switch_write_buf_idx(&mut self) { - self.write_buf_idx - .store(self.get_write_buf_idx() as u32 ^ 1u32) - } - - /// Switches the buffer to read. - fn switch_read_buf_idx(&mut self) { - self.read_buf_idx - .store(self.get_read_buf_idx() as u32 ^ 1u32) - } - - /// Checks if the offset value for setting write_offset or read_offset is - /// out of range or not. - /// - /// # Arguments - /// `idx` - The index of the buffer for which we're checking the offset. - /// `offset` - 0 <= `offset` <= `used_size` && `buffer_offset[idx]` + `offset` <= - /// `samples_len`. Writable or readable size equals to 0 when offset equals - /// to `used_size`. - /// - /// # Errors - /// Returns an error if `offset` is out of range or if idx is not a valid - /// buffer idx. - fn check_rw_offset(&self, idx: usize, offset: u32) -> io::Result<()> { - let buffer_len = self.buffer_len_from_offset(self.get_buffer_offset(idx)?)?; - if offset as usize > buffer_len { - return Err(io::Error::new( - io::ErrorKind::InvalidInput, - format!( - "Offset {} is larger than buffer size {}.", - offset, buffer_len - ), - )); - } - - Ok(()) - } - - /// Sets `write_offset[idx]` to the count of written bytes. - /// - /// # Arguments - /// `idx` - 0 <= `idx` < `CRAS_NUM_SHM_BUFFERS` - /// `offset` - 0 <= `offset` <= `used_size` && `offset` + `used_size` <= - /// `samples_len`. Writable size equals to 0 when offset equals to - /// `used_size`. - /// - /// # Errors - /// Returns an error if `offset` is out of range. - fn set_write_offset(&mut self, idx: usize, offset: u32) -> io::Result<()> { - self.check_rw_offset(idx, offset)?; - let write_offset = self.write_offset.get(idx).ok_or_else(index_out_of_range)?; - write_offset.store(offset); - Ok(()) - } - - /// Sets `read_offset[idx]` to count of written bytes. - /// - /// # Arguments - /// `idx` - 0 <= `idx` < `CRAS_NUM_SHM_BUFFERS` - /// `offset` - 0 <= `offset` <= `used_size` && `offset` + `used_size` <= - /// `samples_len`. Readable size equals to 0 when offset equals to - /// `used_size`. - /// - /// # Errors - /// Returns error if index out of range. - fn set_read_offset(&mut self, idx: usize, offset: u32) -> io::Result<()> { - self.check_rw_offset(idx, offset)?; - let read_offset = self.read_offset.get(idx).ok_or_else(index_out_of_range)?; - read_offset.store(offset); - Ok(()) - } - - /// Check that `offset` is a valid buffer offset for the buffer at `idx` - /// An offset is not valid if it is - /// * outside of the samples area - /// * overlaps some other buffer `[other_offset, other_offset + used_size)` - /// * is close enough to the end of the samples area that the buffer would - /// be shorter than `frame_size`. - fn check_buffer_offset(&self, idx: usize, offset: usize) -> io::Result<()> { - let start = offset; - let end = start + self.buffer_len_from_offset(start)?; - - let other_idx = (idx ^ 1) as usize; - let other_start = self - .buffer_offset - .get(other_idx) - .ok_or_else(index_out_of_range)? - .load() as usize; - let other_end = other_start + self.buffer_len_from_offset(other_start)?; - if start < other_end && other_start < end { - // Special case: occasionally we get the same buffer offset twice - // from the intel8x0 kernel driver in crosvm's AC97 device, and we - // don't want to crash in that case. - if start == other_start && end == other_end { - warn!( - "Setting buffer {} to same index/offset as buffer {}, [{}, {})", - idx, other_idx, other_start, other_end - ); - } else { - return Err(io::Error::new( - io::ErrorKind::InvalidInput, - format!( - "Setting buffer {} to [{}, {}) overlaps buffer {} at [{}, {})", - idx, start, end, other_idx, other_start, other_end, - ), - )); - } - } - Ok(()) - } - - /// Sets the location of the audio buffer `idx` within the samples area to - /// `offset`, so that CRAS will read/write samples for that buffer from that - /// offset. - /// - /// # Arguments - /// `idx` - 0 <= `idx` < `CRAS_NUM_SHM_BUFFERS` - /// `offset` - 0 <= `offset` && `offset` + `frame_size` <= `samples_len` - /// - /// # Errors - /// If `idx` is out of range - /// If the offset is invalid, which can happen if `offset` is - /// * outside of the samples area - /// * overlaps some other buffer `[other_offset, other_offset + used_size)` - /// * is close enough to the end of the samples area that the buffer would - /// be shorter than `frame_size`. - pub fn set_buffer_offset(&mut self, idx: usize, offset: usize) -> io::Result<()> { - self.check_buffer_offset(idx, offset)?; - - let buffer_offset = self.buffer_offset.get(idx).ok_or_else(index_out_of_range)?; - buffer_offset.store(offset as u64); - Ok(()) - } - - /// Commits written frames by switching the current buffer to the other one - /// after samples are ready and indexes of current buffer are all set. - /// - Sets `write_offset` of current buffer to `frame_count * frame_size` - /// - Sets `read_offset` of current buffer to `0`. - /// - /// # Arguments - /// - /// * `frame_count` - Number of frames written to the current buffer - /// - /// # Errors - /// - /// * Returns error if `frame_count` is larger than buffer size - /// - /// This function is safe because we switch `write_buf_idx` after letting - /// `write_offset` and `read_offset` ready and we read / write shared memory - /// variables with volatile operations. - pub fn commit_written_frames(&mut self, frame_count: u32) -> io::Result<()> { - // Uses `u64` to prevent possible overflow - let byte_count = frame_count as u64 * self.get_frame_size() as u64; - if byte_count > self.get_used_size() as u64 { - Err(io::Error::new( - io::ErrorKind::InvalidInput, - "frame_count * frame_size is larger than used_size", - )) - } else { - let idx = self.get_write_buf_idx() as usize; - // Sets `write_offset` of current buffer to frame_count * frame_size - self.set_write_offset(idx, byte_count as u32)?; - // Sets `read_offset` of current buffer to `0`. - self.set_read_offset(idx, 0)?; - // Switch to the other buffer - self.switch_write_buf_idx(); - Ok(()) - } - } - - /// Get readable frames in current buffer. - /// - /// # Returns - /// - /// * `usize` - number of readable frames. - /// - /// # Errors - /// - /// Returns error if index out of range. - pub fn get_readable_frames(&self) -> io::Result<usize> { - let idx = self.get_read_buf_idx() as usize; - let read_offset = self.read_offset.get(idx).ok_or_else(index_out_of_range)?; - let write_offset = self.write_offset.get(idx).ok_or_else(index_out_of_range)?; - let nframes = - (write_offset.load() as i32 - read_offset.load() as i32) / self.get_frame_size() as i32; - if nframes < 0 { - Ok(0) - } else { - Ok(nframes as usize) - } - } - - /// Commit read frames from reader, . - /// - Sets `read_offset` of current buffer to `read_offset + frame_count * frame_size`. - /// If `read_offset` is larger than or equal to `write_offset`, then - /// - Sets `read_offset` and `write_offset` to `0` and switch `read_buf_idx`. - /// - /// # Arguments - /// - /// * `frame_count` - Read frames in current read buffer. - /// - /// # Errors - /// - /// Returns error if index out of range. - pub fn commit_read_frames(&mut self, frame_count: u32) -> io::Result<()> { - let idx = self.get_read_buf_idx() as usize; - let read_offset = self.read_offset.get(idx).ok_or_else(index_out_of_range)?; - let write_offset = self.write_offset.get(idx).ok_or_else(index_out_of_range)?; - read_offset.store(read_offset.load() + frame_count * self.get_frame_size() as u32); - if read_offset.load() >= write_offset.load() { - read_offset.store(0); - write_offset.store(0); - self.switch_read_buf_idx(); - } - Ok(()) - } -} - -impl<'a> Drop for CrasAudioHeader<'a> { - fn drop(&mut self) { - // Safe because all references must be gone by the time drop is called. - unsafe { - libc::munmap(self.addr as *mut _, mem::size_of::<cras_audio_shm_header>()); - } - } -} - -// To use this safely, we need to make sure -// - The given fd contains valid space which is larger than `len` + `offset` -unsafe fn cras_mmap_offset( - len: usize, - prot: libc::c_int, - fd: libc::c_int, - offset: usize, -) -> io::Result<*mut libc::c_void> { - if offset > libc::off_t::max_value() as usize { - return Err(io::Error::new( - io::ErrorKind::InvalidInput, - "Requested offset is out of range of `libc::off_t`.", - )); - } - // It's safe because we handle its returned results. - match libc::mmap( - ptr::null_mut(), - len, - prot, - libc::MAP_SHARED, - fd, - offset as libc::off_t, - ) { - libc::MAP_FAILED => Err(io::Error::last_os_error()), - shm_ptr => Ok(shm_ptr), - } -} - -// To use this safely, we need to make sure -// - The given fd contains valid space which is larger than `len` -unsafe fn cras_mmap( - len: usize, - prot: libc::c_int, - fd: libc::c_int, -) -> io::Result<*mut libc::c_void> { - cras_mmap_offset(len, prot, fd, 0) -} - -/// An unsafe macro for getting a `VolatileSlice` representing an entire array -/// field from a given NonNull pointer. -/// -/// To use this macro safely, we need to -/// - Make sure the pointer address is readable and writeable for its struct. -/// - Make sure all `VolatileSlice`s generated from this macro have exclusive ownership for the same -/// pointer. -/// - Make sure the length of the array field is non-zero. -#[macro_export] -macro_rules! vslice_from_addr { - ($addr:ident, $($field:ident).*) => {{ - let ptr = &mut $addr.as_mut().$($field).* as *mut _ as *mut u8; - let size = std::mem::size_of_val(&$addr.as_mut().$($field).*); - VolatileSlice::from_raw_parts(ptr, size) - }}; -} - -/// A structure that points to RO shared memory area - `cras_server_state` -/// The structure is created from a shared memory fd which contains the structure. -#[derive(Debug)] -pub struct CrasServerState<'a> { - addr: *mut libc::c_void, - volume: VolatileRef<'a, u32>, - mute: VolatileRef<'a, i32>, - num_output_devs: VolatileRef<'a, u32>, - output_devs: VolatileSlice<'a>, - num_input_devs: VolatileRef<'a, u32>, - input_devs: VolatileSlice<'a>, - num_output_nodes: VolatileRef<'a, u32>, - num_input_nodes: VolatileRef<'a, u32>, - output_nodes: VolatileSlice<'a>, - input_nodes: VolatileSlice<'a>, - update_count: VolatileRef<'a, u32>, - debug_info_num_devs: VolatileRef<'a, u32>, - debug_info_devs: VolatileSlice<'a>, - debug_info_num_streams: VolatileRef<'a, u32>, - debug_info_streams: VolatileSlice<'a>, -} - -// It is safe to send server_state between threads as this struct has exclusive -// ownership of the shared memory area contained in it. -unsafe impl<'a> Send for CrasServerState<'a> {} - -impl<'a> CrasServerState<'a> { - /// Create a CrasServerState - pub fn try_new(state_fd: CrasServerStateShmFd) -> io::Result<Self> { - // Safe because the creator of CrasServerStateShmFd already - // ensured that state_fd contains a cras_server_state. - let mmap_addr = - unsafe { cras_mmap(state_fd.fd.size, libc::PROT_READ, state_fd.fd.as_raw_fd())? }; - - let mut addr = NonNull::new(mmap_addr as *mut cras_server_state).ok_or_else(|| { - io::Error::new(io::ErrorKind::Other, "Failed to create CrasServerState.") - })?; - - // Safe because we know that addr is a non-null pointer to cras_server_state. - let state_version = unsafe { vref_from_addr!(addr, state_version) }; - if state_version.load() != CRAS_SERVER_STATE_VERSION { - return Err(io::Error::new( - io::ErrorKind::Other, - format!( - "CrasServerState version {} does not match expected version {}", - state_version.load(), - CRAS_SERVER_STATE_VERSION - ), - )); - } - - // Safe because we know that mmap_addr (contained in addr) contains a - // cras_server_state, and the mapped area will be exclusively - // owned by this struct. - unsafe { - Ok(CrasServerState { - addr: addr.as_ptr() as *mut libc::c_void, - volume: vref_from_addr!(addr, volume), - mute: vref_from_addr!(addr, mute), - num_output_devs: vref_from_addr!(addr, num_output_devs), - num_input_devs: vref_from_addr!(addr, num_input_devs), - output_devs: vslice_from_addr!(addr, output_devs), - input_devs: vslice_from_addr!(addr, input_devs), - num_output_nodes: vref_from_addr!(addr, num_output_nodes), - num_input_nodes: vref_from_addr!(addr, num_input_nodes), - output_nodes: vslice_from_addr!(addr, output_nodes), - input_nodes: vslice_from_addr!(addr, input_nodes), - update_count: vref_from_addr!(addr, update_count), - debug_info_num_devs: vref_from_addr!(addr, audio_debug_info.num_devs), - debug_info_devs: vslice_from_addr!(addr, audio_debug_info.devs), - debug_info_num_streams: vref_from_addr!(addr, audio_debug_info.num_streams), - debug_info_streams: vslice_from_addr!(addr, audio_debug_info.streams), - }) - } - } - - /// Gets the system volume. - /// - /// Read the current value for system volume from shared memory. - pub fn get_system_volume(&self) -> u32 { - self.volume.load() - } - - /// Gets the system mute. - /// - /// Read the current value for system mute from shared memory. - pub fn get_system_mute(&self) -> bool { - self.mute.load() != 0 - } - - /// Runs a closure safely such that it can be sure that the server state - /// was not updated during the read. - /// This can be used for an "atomic" read of non-atomic data from the - /// state shared memory. - fn synchronized_state_read<F, T>(&self, mut func: F) -> T - where - F: FnMut() -> T, - { - // Waits until the server has completed a state update before returning - // the current update count. - let begin_server_state_read = || -> u32 { - loop { - let update_count = self.update_count.load(); - if update_count % 2 == 0 { - atomic::fence(Ordering::Acquire); - return update_count; - } else { - thread::yield_now(); - } - } - }; - - // Checks that the update count has not changed since the start - // of the server state read. - let end_server_state_read = |count: u32| -> bool { - let result = count == self.update_count.load(); - atomic::fence(Ordering::Release); - result - }; - - // Get the state's update count and run the provided closure. - // If the update count has not changed once the closure is finished, - // return the result, otherwise repeat the process. - loop { - let update_count = begin_server_state_read(); - let result = func(); - if end_server_state_read(update_count) { - return result; - } - } - } - - /// Gets a list of output devices - /// - /// Read a list of the currently attached output devices from shared memory. - pub fn output_devices(&self) -> impl Iterator<Item = CrasIodevInfo> { - let mut devs: Vec<cras_iodev_info> = vec![Default::default(); CRAS_MAX_IODEVS as usize]; - let num_devs = self.synchronized_state_read(|| { - self.output_devs.copy_to(&mut devs); - self.num_output_devs.load() - }); - devs.into_iter() - .take(num_devs as usize) - .map(CrasIodevInfo::from) - } - - /// Gets a list of input devices - /// - /// Read a list of the currently attached input devices from shared memory. - pub fn input_devices(&self) -> impl Iterator<Item = CrasIodevInfo> { - let mut devs: Vec<cras_iodev_info> = vec![Default::default(); CRAS_MAX_IODEVS as usize]; - let num_devs = self.synchronized_state_read(|| { - self.input_devs.copy_to(&mut devs); - self.num_input_devs.load() - }); - devs.into_iter() - .take(num_devs as usize) - .map(CrasIodevInfo::from) - } - - /// Gets a list of output nodes - /// - /// Read a list of the currently attached output nodes from shared memory. - pub fn output_nodes(&self) -> impl Iterator<Item = CrasIonodeInfo> { - let mut nodes: Vec<cras_ionode_info> = vec![Default::default(); CRAS_MAX_IONODES as usize]; - let num_nodes = self.synchronized_state_read(|| { - self.output_nodes.copy_to(&mut nodes); - self.num_output_nodes.load() - }); - nodes - .into_iter() - .take(num_nodes as usize) - .map(CrasIonodeInfo::from) - } - - /// Gets a list of input nodes - /// - /// Read a list of the currently attached input nodes from shared memory. - pub fn input_nodes(&self) -> impl Iterator<Item = CrasIonodeInfo> { - let mut nodes: Vec<cras_ionode_info> = vec![Default::default(); CRAS_MAX_IONODES as usize]; - let num_nodes = self.synchronized_state_read(|| { - self.input_nodes.copy_to(&mut nodes); - self.num_input_nodes.load() - }); - nodes - .into_iter() - .take(num_nodes as usize) - .map(CrasIonodeInfo::from) - } - - /// Get audio debug info - /// - /// Loads the server's audio_debug_info struct and converts it into an - /// idiomatic rust representation. - /// - /// # Errors - /// * If any of the stream debug information structs are invalid. - pub fn get_audio_debug_info(&self) -> Result<AudioDebugInfo, cras_sys::Error> { - let mut devs: Vec<audio_dev_debug_info> = vec![Default::default(); MAX_DEBUG_DEVS as usize]; - let mut streams: Vec<audio_stream_debug_info> = - vec![Default::default(); MAX_DEBUG_STREAMS as usize]; - let (num_devs, num_streams) = self.synchronized_state_read(|| { - self.debug_info_devs.copy_to(&mut devs); - self.debug_info_streams.copy_to(&mut streams); - ( - self.debug_info_num_devs.load(), - self.debug_info_num_streams.load(), - ) - }); - let dev_info = devs - .into_iter() - .take(num_devs as usize) - .map(AudioDevDebugInfo::from) - .collect(); - let stream_info = streams - .into_iter() - .take(num_streams as usize) - .map(AudioStreamDebugInfo::try_from) - .collect::<Result<Vec<_>, _>>()?; - Ok(AudioDebugInfo::new(dev_info, stream_info)) - } -} - -impl<'a> Drop for CrasServerState<'a> { - /// Call `munmap` for `addr`. - fn drop(&mut self) { - unsafe { - // Safe because all references must be gone by the time drop is called. - libc::munmap(self.addr, mem::size_of::<cras_server_state>()); - } - } -} - -/// A structure holding the mapped shared memory area used to exchange -/// samples with CRAS. The shared memory is owned exclusively by this structure, -/// and will be cleaned up on drop. -/// * `addr` - The address of the mapped shared memory. -/// * `len` - Length of the mapped shared memory in bytes. -pub struct CrasAudioBuffer { - addr: *mut u8, - len: usize, -} - -// It is safe to send audio buffers between threads as this struct has exclusive ownership of the -// shared memory area contained in it. -unsafe impl Send for CrasAudioBuffer {} - -impl CrasAudioBuffer { - fn new(samples_fd: CrasShmFd) -> io::Result<Self> { - // This is safe because we checked that the size of the shm in samples_fd - // was at least samples_fd.size when it was created. - let addr = unsafe { - cras_mmap( - samples_fd.size, - libc::PROT_READ | libc::PROT_WRITE, - samples_fd.as_raw_fd(), - )? as *mut u8 - }; - Ok(Self { - addr, - len: samples_fd.size, - }) - } - - /// Provides a mutable slice to be filled with audio samples. - pub fn get_buffer(&mut self) -> &mut [u8] { - // This is safe because it takes a mutable reference to self, and there can only be one - // taken at a time. Although this is shared memory, the reader side must have it mapped as - // read only. - unsafe { slice::from_raw_parts_mut(self.addr, self.len) } - } -} - -impl Drop for CrasAudioBuffer { - fn drop(&mut self) { - // Safe because all references must be gone by the time drop is called. - unsafe { - libc::munmap(self.addr as *mut _, self.len); - } - } -} - -/// Creates header and buffer from given shared memory fds. -pub fn create_header_and_buffers<'a>( - header_fd: CrasAudioShmHeaderFd, - samples_fd: CrasShmFd, -) -> io::Result<(CrasAudioHeader<'a>, CrasAudioBuffer)> { - let header = CrasAudioHeader::new(header_fd, samples_fd.size)?; - let buffer = CrasAudioBuffer::new(samples_fd)?; - - Ok((header, buffer)) -} - -/// Creates header from header shared memory fds. Use this function -/// when mapping the samples shm is not necessary, for instance with a -/// client-provided shm stream. -pub fn create_header<'a>( - header_fd: CrasAudioShmHeaderFd, - samples_len: usize, -) -> io::Result<CrasAudioHeader<'a>> { - Ok(CrasAudioHeader::new(header_fd, samples_len)?) -} - -/// A structure wrapping a fd which contains a shared memory area and its size. -/// * `fd` - The shared memory file descriptor, a `libc::c_int`. -/// * `size` - Size of the shared memory area. -pub struct CrasShmFd { - fd: libc::c_int, - size: usize, -} - -impl CrasShmFd { - /// Creates a `CrasShmFd` by shared memory fd and size - /// # Arguments - /// * `fd` - A shared memory file descriptor, which will be owned by the resulting structure and - /// the fd will be closed on drop. - /// * `size` - Size of the shared memory. - /// - /// # Returns - /// * `CrasShmFd` - Wrap the input arguments without doing anything. - /// - /// To use this function safely, we need to make sure - /// - The input fd is a valid shared memory fd. - /// - The input shared memory fd won't be used by others. - /// - The input fd contains memory size larger than `size`. - pub unsafe fn new(fd: libc::c_int, size: usize) -> CrasShmFd { - CrasShmFd { fd, size } - } -} - -impl AsRawFd for CrasShmFd { - fn as_raw_fd(&self) -> RawFd { - self.fd - } -} - -impl Drop for CrasShmFd { - fn drop(&mut self) { - // It's safe here if we make sure - // - the input fd is valid and - // - `CrasShmFd` is the only owner - // in `new` function - unsafe { - libc::close(self.fd); - } - } -} - -/// A structure wrapping a fd which contains a shared `cras_server_state`. -/// * `shm_fd` - A shared memory fd contains a `cras_server_state` -pub struct CrasServerStateShmFd { - fd: CrasShmFd, -} - -impl CrasServerStateShmFd { - /// Creates a `CrasServerStateShmFd` by shared memory fd - /// # Arguments - /// * `fd` - A shared memory file descriptor, which will be owned by the resulting structure and - /// the fd will be closed on drop. - /// - /// # Returns - /// A structure wrapping a `CrasShmFd` with the input fd and `size` which equals to - /// the size of `cras_server_sate`. - /// - /// To use this function safely, we need to make sure - /// - The input fd is a valid shared memory fd. - /// - The input shared memory fd won't be used by others. - /// - The shared memory area in the input fd contains a `cras_server_state`. - pub unsafe fn new(fd: libc::c_int) -> Self { - Self { - fd: CrasShmFd::new(fd, mem::size_of::<cras_server_state>()), - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - use std::fs::File; - use std::os::unix::io::IntoRawFd; - use std::sync::{Arc, Mutex}; - use std::thread; - use sys_util::{kernel_has_memfd, SharedMemory}; - - #[test] - fn cras_audio_header_switch_test() { - if !kernel_has_memfd() { - return; - } - let mut header = create_cras_audio_header(20); - assert_eq!(0, header.get_write_buf_idx()); - header.switch_write_buf_idx(); - assert_eq!(1, header.get_write_buf_idx()); - } - - #[test] - fn cras_audio_header_write_offset_test() { - if !kernel_has_memfd() { - return; - } - let mut header = create_cras_audio_header(20); - header.frame_size.store(2); - header.used_size.store(5); - header.set_buffer_offset(0, 12).unwrap(); - - assert_eq!(0, header.write_offset[0].load()); - // Index out of bound - assert!(header.set_write_offset(2, 5).is_err()); - // Offset out of bound - // Buffer length is 4, since that's the largest multiple of frame_size - // less than used_size. - assert!(header.set_write_offset(0, 6).is_err()); - assert_eq!(0, header.write_offset[0].load()); - assert!(header.set_write_offset(0, 5).is_err()); - assert_eq!(0, header.write_offset[0].load()); - assert!(header.set_write_offset(0, 4).is_ok()); - assert_eq!(4, header.write_offset[0].load()); - } - - #[test] - fn cras_audio_header_read_offset_test() { - if !kernel_has_memfd() { - return; - } - let mut header = create_cras_audio_header(20); - header.frame_size.store(2); - header.used_size.store(5); - header.set_buffer_offset(0, 12).unwrap(); - - assert_eq!(0, header.read_offset[0].load()); - // Index out of bound - assert!(header.set_read_offset(2, 5).is_err()); - // Offset out of bound - // Buffer length is 4, since that's the largest multiple of frame_size - // less than used_size. - assert!(header.set_read_offset(0, 6).is_err()); - assert_eq!(0, header.read_offset[0].load()); - assert!(header.set_read_offset(0, 5).is_err()); - assert_eq!(0, header.read_offset[0].load()); - assert!(header.set_read_offset(0, 4).is_ok()); - assert_eq!(4, header.read_offset[0].load()); - } - - #[test] - fn cras_audio_header_commit_written_frame_test() { - if !kernel_has_memfd() { - return; - } - let mut header = create_cras_audio_header(20); - header.frame_size.store(2); - header.used_size.store(10); - header.read_offset[0].store(10); - header.set_buffer_offset(0, 10).unwrap(); - - assert!(header.commit_written_frames(5).is_ok()); - assert_eq!(header.write_offset[0].load(), 10); - assert_eq!(header.read_offset[0].load(), 0); - assert_eq!(header.write_buf_idx.load(), 1); - } - - #[test] - fn cras_audio_header_get_readable_frames_test() { - if !kernel_has_memfd() { - return; - } - let header = create_cras_audio_header(20); - header.frame_size.store(2); - header.used_size.store(10); - header.read_offset[0].store(2); - header.write_offset[0].store(10); - let frames = header - .get_readable_frames() - .expect("Failed to get readable frames."); - assert_eq!(frames, 4); - } - - #[test] - fn cras_audio_header_commit_read_frames_test() { - if !kernel_has_memfd() { - return; - } - let mut header = create_cras_audio_header(20); - header.frame_size.store(2); - header.used_size.store(10); - header.read_offset[0].store(2); - header.write_offset[0].store(10); - header - .commit_read_frames(3) - .expect("Failed to commit read frames."); - assert_eq!(header.get_read_buf_idx(), 0); - assert_eq!(header.read_offset[0].load(), 8); - - header - .commit_read_frames(1) - .expect("Failed to commit read frames."); - // Read buffer should be switched - assert_eq!(header.get_read_buf_idx(), 1); - assert_eq!(header.read_offset[0].load(), 0); - assert_eq!(header.read_offset[0].load(), 0); - } - - #[test] - fn cras_audio_header_get_write_offset_and_len() { - if !kernel_has_memfd() { - return; - } - let header = create_cras_audio_header(30); - header.frame_size.store(2); - header.used_size.store(10); - header.write_buf_idx.store(0); - header.read_offset[0].store(0); - header.write_offset[0].store(0); - header.buffer_offset[0].store(0); - - header.read_buf_idx.store(1); - header.read_offset[1].store(0); - header.write_offset[1].store(0); - header.buffer_offset[1].store(10); - - // standard offsets and lens - let (offset, len) = header.get_write_offset_and_len().unwrap(); - assert_eq!(offset, 0); - assert_eq!(len, 10); - - header.write_buf_idx.store(1); - header.read_buf_idx.store(0); - let (offset, len) = header.get_write_offset_and_len().unwrap(); - assert_eq!(offset, 10); - assert_eq!(len, 10); - - // relocate buffer offsets - header.buffer_offset[1].store(16); - let (offset, len) = header.get_write_offset_and_len().unwrap(); - assert_eq!(offset, 16); - assert_eq!(len, 10); - - header.buffer_offset[0].store(5); - header.write_buf_idx.store(0); - let (offset, len) = header.get_write_offset_and_len().unwrap(); - assert_eq!(offset, 5); - assert_eq!(len, 10); - - header.write_buf_idx.store(0); - header.buffer_offset[0].store(2); - header.read_buf_idx.store(1); - header.buffer_offset[1].store(10); - let result = header.get_write_offset_and_len(); - // Should be an error as write buffer would overrun into other buffer. - assert!(result.is_err()); - - header.buffer_offset[0].store(24); - header.buffer_offset[1].store(10); - let (offset, len) = header.get_write_offset_and_len().unwrap(); - // Should be ok since we're only running up against the end of samples. - assert_eq!(offset, 24); - assert_eq!(len, 6); - - header.buffer_offset[0].store(25); - let (offset, len) = header.get_write_offset_and_len().unwrap(); - // Should be ok, but we'll truncate len to frame_size. - assert_eq!(offset, 25); - assert_eq!(len, 4); - - header.buffer_offset[0].store(29); - let result = header.get_write_offset_and_len(); - // Should be an error as buffer is smaller than frame_size. - assert!(result.is_err()); - } - - #[test] - fn cras_audio_header_set_buffer_offset() { - if !kernel_has_memfd() { - return; - } - let mut header = create_cras_audio_header(30); - header.frame_size.store(2); - header.used_size.store(10); - header.write_buf_idx.store(0); - header.read_offset[0].store(0); - header.write_offset[0].store(0); - header.buffer_offset[0].store(0); - - header.read_buf_idx.store(1); - header.read_offset[1].store(0); - header.write_offset[1].store(0); - header.buffer_offset[1].store(10); - - // Setting buffer_offset to exactly overlap with other buffer is okay - assert!(header.set_buffer_offset(0, 10).is_ok()); - - // Setting buffer_offset to partially overlap other buffer is not okay - assert!(header.set_buffer_offset(0, 9).is_err()); - - header.buffer_offset[0].store(0); - header.write_offset[1].store(8); - // With samples, it's still an error. - assert!(header.set_buffer_offset(0, 9).is_err()); - - // Setting the offset past the end of the other buffer is okay - assert!(header.set_buffer_offset(0, 20).is_ok()); - - // Setting buffer offset such that buffer length is less than used_size - // is okay, but only at the end of the samples area. - assert!(header.set_buffer_offset(0, 21).is_ok()); - assert!(header.set_buffer_offset(0, 27).is_ok()); - - // It's not okay if we get a buffer with length less than frame_size. - assert!(header.set_buffer_offset(0, 29).is_err()); - assert!(header.set_buffer_offset(0, 30).is_err()); - - // If we try to overlap another buffer with that other buffer at the end, - // it's not okay, unless it's the exact same index. - assert!(header.set_buffer_offset(1, 25).is_err()); - assert!(header.set_buffer_offset(1, 27).is_ok()); - assert!(header.set_buffer_offset(1, 28).is_err()); - - // Setting buffer offset past the end of samples is an error. - assert!(header.set_buffer_offset(0, 33).is_err()); - } - - #[test] - fn create_header_and_buffers_test() { - if !kernel_has_memfd() { - return; - } - let header_fd = cras_audio_header_fd(); - let samples_fd = cras_audio_samples_fd(20); - let res = create_header_and_buffers(header_fd, samples_fd); - res.expect("Failed to create header and buffer."); - } - - fn create_shm(size: usize) -> File { - let mut shm = SharedMemory::new(None).expect("failed to create shm"); - shm.set_size(size as u64).expect("failed to set shm size"); - shm.into() - } - - fn create_cras_audio_header<'a>(samples_len: usize) -> CrasAudioHeader<'a> { - CrasAudioHeader::new(cras_audio_header_fd(), samples_len).unwrap() - } - - fn cras_audio_header_fd() -> CrasAudioShmHeaderFd { - let size = mem::size_of::<cras_audio_shm_header>(); - let shm = create_shm(size); - unsafe { CrasAudioShmHeaderFd::new(shm.into_raw_fd()) } - } - - fn cras_audio_samples_fd(size: usize) -> CrasShmFd { - let shm = create_shm(size); - unsafe { CrasShmFd::new(shm.into_raw_fd(), size) } - } - - #[test] - fn cras_mmap_pass() { - if !kernel_has_memfd() { - return; - } - let shm = create_shm(100); - let rc = unsafe { cras_mmap(10, libc::PROT_READ, shm.as_raw_fd()) }; - assert!(rc.is_ok()); - unsafe { libc::munmap(rc.unwrap(), 10) }; - } - - #[test] - fn cras_mmap_failed() { - if !kernel_has_memfd() { - return; - } - let rc = unsafe { cras_mmap(10, libc::PROT_READ, -1) }; - assert!(rc.is_err()); - } - - #[test] - fn cras_server_state() { - let size = mem::size_of::<cras_server_state>(); - let shm = create_shm(size); - unsafe { - let addr = cras_mmap(size, libc::PROT_WRITE, shm.as_raw_fd()) - .expect("failed to mmap state shm"); - { - let state: &mut cras_server_state = &mut *(addr as *mut cras_server_state); - state.state_version = CRAS_SERVER_STATE_VERSION; - state.volume = 47; - state.mute = 1; - } - libc::munmap(addr, size); - }; - let state_fd = unsafe { CrasServerStateShmFd::new(shm.into_raw_fd()) }; - let state = - CrasServerState::try_new(state_fd).expect("try_new failed for valid server_state fd"); - assert_eq!(state.get_system_volume(), 47); - assert_eq!(state.get_system_mute(), true); - } - - #[test] - fn cras_server_state_old_version() { - let size = mem::size_of::<cras_server_state>(); - let shm = create_shm(size); - unsafe { - let addr = cras_mmap(size, libc::PROT_WRITE, shm.as_raw_fd()) - .expect("failed to mmap state shm"); - { - let state: &mut cras_server_state = &mut *(addr as *mut cras_server_state); - state.state_version = CRAS_SERVER_STATE_VERSION - 1; - state.volume = 29; - state.mute = 0; - } - libc::munmap(addr, size); - }; - let state_fd = unsafe { CrasServerStateShmFd::new(shm.into_raw_fd()) }; - CrasServerState::try_new(state_fd) - .expect_err("try_new succeeded for invalid state version"); - } - - #[test] - fn cras_server_sync_state_read() { - let size = mem::size_of::<cras_server_state>(); - let shm = create_shm(size); - let addr = unsafe { cras_mmap(size, libc::PROT_WRITE, shm.as_raw_fd()).unwrap() }; - let state: &mut cras_server_state = unsafe { &mut *(addr as *mut cras_server_state) }; - state.state_version = CRAS_SERVER_STATE_VERSION; - state.update_count = 14; - state.volume = 12; - - let state_fd = unsafe { CrasServerStateShmFd::new(shm.into_raw_fd()) }; - let state_struct = CrasServerState::try_new(state_fd).unwrap(); - - // Create a lock so that we can block the reader while we change the - // update_count; - let lock = Arc::new(Mutex::new(())); - let thread_lock = lock.clone(); - let reader_thread = { - let _guard = lock.lock().unwrap(); - - // Create reader thread that will get the value of volume. Since we - // hold the lock currently, this will block until we release the lock. - let reader_thread = thread::spawn(move || { - state_struct.synchronized_state_read(|| { - let _guard = thread_lock.lock().unwrap(); - state_struct.volume.load() - }) - }); - - // Update volume and change update count so that the synchronized read - // will not return (odd update count means update in progress). - state.volume = 27; - state.update_count = 15; - - reader_thread - }; - - // The lock has been released, but the reader thread should still not - // terminate, because of the update in progress. - - // Yield thread to give reader_thread a chance to get scheduled. - thread::yield_now(); - { - let _guard = lock.lock().unwrap(); - - // Update volume and change update count to indicate the write has - // finished. - state.volume = 42; - state.update_count = 16; - } - - let read_value = reader_thread.join().unwrap(); - assert_eq!(read_value, 42); - } -} diff --git a/cras/client/libcras/src/cras_shm_stream.rs b/cras/client/libcras/src/cras_shm_stream.rs deleted file mode 100644 index f72cc07c..00000000 --- a/cras/client/libcras/src/cras_shm_stream.rs +++ /dev/null @@ -1,191 +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. -use std::time::Duration; -use std::{error, fmt}; - -use audio_streams::{ - shm_streams::{BufferSet, ServerRequest, ShmStream}, - BoxError, SampleFormat, StreamDirection, -}; -use cras_sys::gen::CRAS_AUDIO_MESSAGE_ID; -use sys_util::error; - -use crate::audio_socket::{AudioMessage, AudioSocket}; -use crate::cras_server_socket::CrasServerSocket; -use crate::cras_shm::{self, CrasAudioHeader, CrasAudioShmHeaderFd}; - -#[derive(Debug)] -pub enum Error { - MessageTypeError, - CaptureBufferTooSmall, -} - -impl error::Error for Error {} - -impl fmt::Display for Error { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - Error::MessageTypeError => write!(f, "Message type error"), - Error::CaptureBufferTooSmall => write!( - f, - "Capture buffer too small, must have size at least 'used_size'." - ), - } - } -} - -/// An object that handles interactions with CRAS for a shm stream. -/// The object implements `ShmStream` and so can be used to wait for -/// `ServerRequest` and `BufferComplete` messages. -pub struct CrasShmStream<'a> { - stream_id: u32, - server_socket: CrasServerSocket, - audio_socket: AudioSocket, - direction: StreamDirection, - header: CrasAudioHeader<'a>, - frame_size: usize, - num_channels: usize, - frame_rate: u32, - // The index of the next buffer within SHM to set the buffer offset for. - next_buffer_idx: usize, -} - -impl<'a> CrasShmStream<'a> { - /// Attempt to creates a CrasShmStream with the given arguments. - /// - /// # Arguments - /// - /// * `stream_id` - The server's ID for the stream. - /// * `server_socket` - The socket that is connected to the server. - /// * `audio_socket` - The socket for audio request and audio available messages. - /// * `direction` - The direction of the stream, `Playback` or `Capture`. - /// * `num_channels` - The number of audio channels for the stream. - /// * `format` - The format to use for the stream's samples. - /// * `header_fd` - The file descriptor for the audio header shm area. - /// * `samples_len` - The size of the audio samples shm area. - /// - /// # Returns - /// - /// `CrasShmStream` - CRAS client stream. - /// - /// # Errors - /// - /// * If `header_fd` could not be successfully mmapped. - #[allow(clippy::too_many_arguments)] - pub fn try_new( - stream_id: u32, - server_socket: CrasServerSocket, - audio_socket: AudioSocket, - direction: StreamDirection, - num_channels: usize, - frame_rate: u32, - format: SampleFormat, - header_fd: CrasAudioShmHeaderFd, - samples_len: usize, - ) -> Result<Self, BoxError> { - let header = cras_shm::create_header(header_fd, samples_len)?; - Ok(Self { - stream_id, - server_socket, - audio_socket, - direction, - header, - frame_size: format.sample_bytes() * num_channels, - num_channels, - frame_rate, - // We have either sent zero or two offsets to the server, so we will - // need to update index 0 next. - next_buffer_idx: 0, - }) - } -} - -impl<'a> Drop for CrasShmStream<'a> { - /// Send the disconnect stream message and log an error if sending fails. - fn drop(&mut self) { - if let Err(e) = self.server_socket.disconnect_stream(self.stream_id) { - error!("CrasShmStream::drop error: {}", e); - } - } -} - -impl<'a> ShmStream for CrasShmStream<'a> { - fn frame_size(&self) -> usize { - self.frame_size - } - - fn num_channels(&self) -> usize { - self.num_channels - } - - fn frame_rate(&self) -> u32 { - self.frame_rate - } - - fn wait_for_next_action_with_timeout( - &mut self, - timeout: Duration, - ) -> Result<Option<ServerRequest>, BoxError> { - let expected_id = match self.direction { - StreamDirection::Playback => CRAS_AUDIO_MESSAGE_ID::AUDIO_MESSAGE_REQUEST_DATA, - StreamDirection::Capture => CRAS_AUDIO_MESSAGE_ID::AUDIO_MESSAGE_DATA_READY, - }; - - match self - .audio_socket - .read_audio_message_with_timeout(Some(timeout))? - { - Some(AudioMessage::Success { id, frames }) if id == expected_id => { - Ok(Some(ServerRequest::new(frames as usize, self))) - } - None => Ok(None), - _ => Err(Box::new(Error::MessageTypeError)), - } - } -} - -impl BufferSet for CrasShmStream<'_> { - fn callback(&mut self, offset: usize, frames: usize) -> Result<(), BoxError> { - self.header - .set_buffer_offset(self.next_buffer_idx, offset)?; - self.next_buffer_idx ^= 1; - let frames = frames as u32; - - match self.direction { - StreamDirection::Playback => { - self.header.commit_written_frames(frames)?; - - // Notify CRAS that we've made playback data available. - self.audio_socket.data_ready(frames)? - } - StreamDirection::Capture => { - let used_size = self.header.get_used_size(); - // Because CRAS doesn't know how long our buffer in shm is, we - // must make sure that there are always at least buffer_size - // frames available so that it doesn't write outside the buffer. - if frames < (used_size / self.frame_size) as u32 { - return Err(Box::new(Error::CaptureBufferTooSmall)); - } - - self.header.commit_read_frames(frames)?; - self.audio_socket.capture_ready(frames)?; - } - } - - Ok(()) - } - - fn ignore(&mut self) -> Result<(), BoxError> { - // We send an empty buffer for an ignored playback request since the - // server will not read from a 0-length buffer. We don't do anything for - // an ignored capture request, since we don't have a way to communicate - // buffer length to the server, and we don't want the server writing - // data to offsets within the SHM area that aren't audio buffers. - if self.direction == StreamDirection::Playback { - self.callback(0, 0)?; - } - - Ok(()) - } -} diff --git a/cras/client/libcras/src/cras_stream.rs b/cras/client/libcras/src/cras_stream.rs deleted file mode 100644 index f6004802..00000000 --- a/cras/client/libcras/src/cras_stream.rs +++ /dev/null @@ -1,224 +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. -use std::cmp::min; -use std::io; -use std::marker::PhantomData; -use std::{error, fmt}; - -use audio_streams::{ - capture::{CaptureBuffer, CaptureBufferStream}, - BoxError, BufferDrop, PlaybackBuffer, PlaybackBufferStream, -}; -use cras_sys::gen::{snd_pcm_format_t, CRAS_AUDIO_MESSAGE_ID, CRAS_STREAM_DIRECTION}; -use sys_util::error; - -use crate::audio_socket::{AudioMessage, AudioSocket}; -use crate::cras_server_socket::CrasServerSocket; -use crate::cras_shm::*; - -#[derive(Debug)] -pub enum Error { - IoError(io::Error), - MessageTypeError, -} - -impl error::Error for Error {} - -impl fmt::Display for Error { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - Error::IoError(ref err) => err.fmt(f), - Error::MessageTypeError => write!(f, "Message type error"), - } - } -} - -impl From<io::Error> for Error { - fn from(io_err: io::Error) -> Error { - Error::IoError(io_err) - } -} - -/// A trait controls the state of `CrasAudioHeader` and -/// interacts with server's audio thread through `AudioSocket`. -pub trait CrasStreamData<'a>: Send { - // Creates `CrasStreamData` with only `AudioSocket`. - fn new(audio_sock: AudioSocket, header: CrasAudioHeader<'a>) -> Self; - fn header_mut(&mut self) -> &mut CrasAudioHeader<'a>; - fn audio_sock_mut(&mut self) -> &mut AudioSocket; -} - -/// `CrasStreamData` implementation for `PlaybackBufferStream`. -pub struct CrasPlaybackData<'a> { - audio_sock: AudioSocket, - header: CrasAudioHeader<'a>, -} - -impl<'a> CrasStreamData<'a> for CrasPlaybackData<'a> { - fn new(audio_sock: AudioSocket, header: CrasAudioHeader<'a>) -> Self { - Self { audio_sock, header } - } - - fn header_mut(&mut self) -> &mut CrasAudioHeader<'a> { - &mut self.header - } - - fn audio_sock_mut(&mut self) -> &mut AudioSocket { - &mut self.audio_sock - } -} - -impl<'a> BufferDrop for CrasPlaybackData<'a> { - fn trigger(&mut self, nframes: usize) { - let log_err = |e| error!("BufferDrop error: {}", e); - if let Err(e) = self.header.commit_written_frames(nframes as u32) { - log_err(e); - } - if let Err(e) = self.audio_sock.data_ready(nframes as u32) { - log_err(e); - } - } -} - -/// `CrasStreamData` implementation for `CaptureBufferStream`. -pub struct CrasCaptureData<'a> { - audio_sock: AudioSocket, - header: CrasAudioHeader<'a>, -} - -impl<'a> CrasStreamData<'a> for CrasCaptureData<'a> { - fn new(audio_sock: AudioSocket, header: CrasAudioHeader<'a>) -> Self { - Self { audio_sock, header } - } - - fn header_mut(&mut self) -> &mut CrasAudioHeader<'a> { - &mut self.header - } - - fn audio_sock_mut(&mut self) -> &mut AudioSocket { - &mut self.audio_sock - } -} - -impl<'a> BufferDrop for CrasCaptureData<'a> { - fn trigger(&mut self, nframes: usize) { - let log_err = |e| error!("BufferDrop error: {}", e); - if let Err(e) = self.header.commit_read_frames(nframes as u32) { - log_err(e); - } - if let Err(e) = self.audio_sock.capture_ready(nframes as u32) { - log_err(e); - } - } -} - -#[allow(dead_code)] -pub struct CrasStream<'a, T: CrasStreamData<'a> + BufferDrop> { - stream_id: u32, - server_socket: CrasServerSocket, - block_size: u32, - direction: CRAS_STREAM_DIRECTION, - rate: u32, - num_channels: usize, - format: snd_pcm_format_t, - /// A structure for stream to interact with server audio thread. - controls: T, - /// The `PhantomData` is used by `controls: T` - phantom: PhantomData<CrasAudioHeader<'a>>, - audio_buffer: CrasAudioBuffer, -} - -impl<'a, T: CrasStreamData<'a> + BufferDrop> CrasStream<'a, T> { - /// Creates a CrasStream by given arguments. - /// - /// # Returns - /// `CrasStream` - CRAS client stream. - #[allow(clippy::too_many_arguments)] - pub fn try_new( - stream_id: u32, - server_socket: CrasServerSocket, - block_size: u32, - direction: CRAS_STREAM_DIRECTION, - rate: u32, - num_channels: usize, - format: snd_pcm_format_t, - audio_sock: AudioSocket, - header_fd: CrasAudioShmHeaderFd, - samples_fd: CrasShmFd, - ) -> Result<Self, Error> { - let (header, audio_buffer) = create_header_and_buffers(header_fd, samples_fd)?; - - Ok(Self { - stream_id, - server_socket, - block_size, - direction, - rate, - num_channels, - format, - controls: T::new(audio_sock, header), - phantom: PhantomData, - audio_buffer, - }) - } - - fn wait_request_data(&mut self) -> Result<(), Error> { - match self.controls.audio_sock_mut().read_audio_message()? { - AudioMessage::Success { - id: CRAS_AUDIO_MESSAGE_ID::AUDIO_MESSAGE_REQUEST_DATA, - .. - } => Ok(()), - _ => Err(Error::MessageTypeError), - } - } - - fn wait_data_ready(&mut self) -> Result<u32, Error> { - match self.controls.audio_sock_mut().read_audio_message()? { - AudioMessage::Success { - id: CRAS_AUDIO_MESSAGE_ID::AUDIO_MESSAGE_DATA_READY, - frames, - } => Ok(frames), - _ => Err(Error::MessageTypeError), - } - } -} - -impl<'a, T: CrasStreamData<'a> + BufferDrop> Drop for CrasStream<'a, T> { - /// A blocking drop function, sends the disconnect message to `CrasClient` and waits for - /// the return message. - /// Logs an error message to stderr if the method fails. - fn drop(&mut self) { - if let Err(e) = self.server_socket.disconnect_stream(self.stream_id) { - error!("CrasStream::Drop error: {}", e); - } - } -} - -impl<'a, T: CrasStreamData<'a> + BufferDrop> PlaybackBufferStream for CrasStream<'a, T> { - fn next_playback_buffer(&mut self) -> Result<PlaybackBuffer, BoxError> { - // Wait for request audio message - self.wait_request_data()?; - let header = self.controls.header_mut(); - let frame_size = header.get_frame_size(); - let (offset, len) = header.get_write_offset_and_len()?; - let buf = &mut self.audio_buffer.get_buffer()[offset..offset + len]; - - PlaybackBuffer::new(frame_size, buf, &mut self.controls).map_err(Box::from) - } -} - -impl<'a, T: CrasStreamData<'a> + BufferDrop> CaptureBufferStream for CrasStream<'a, T> { - fn next_capture_buffer(&mut self) -> Result<CaptureBuffer, BoxError> { - // Wait for data ready message - let frames = self.wait_data_ready()?; - let header = self.controls.header_mut(); - let frame_size = header.get_frame_size(); - let shm_frames = header.get_readable_frames()?; - let len = min(shm_frames, frames as usize) * frame_size; - let offset = header.get_read_buffer_offset()?; - let buf = &mut self.audio_buffer.get_buffer()[offset..offset + len]; - - CaptureBuffer::new(frame_size, buf, &mut self.controls).map_err(Box::from) - } -} diff --git a/cras/client/libcras/src/libcras.rs b/cras/client/libcras/src/libcras.rs deleted file mode 100644 index 402a4a27..00000000 --- a/cras/client/libcras/src/libcras.rs +++ /dev/null @@ -1,699 +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. -//! Provides an interface for playing and recording audio through CRAS server. -//! -//! `CrasClient` implements `StreamSource` trait and it can create playback or capture -//! stream - `CrasStream` which can be a -//! - `PlaybackBufferStream` for audio playback or -//! - `CaptureBufferStream` for audio capture. -//! -//! # Example of file audio playback -//! -//! `PlaybackBuffer`s to be filled with audio samples are obtained by calling -//! `next_playback_buffer` from `CrasStream`. -//! -//! Users playing audio fill the provided buffers with audio. When a `PlaybackBuffer` is dropped, -//! the samples written to it are committed to the `CrasStream` it came from. -//! -//! -//! ``` -//! // An example of playing raw audio data from a given file -//! use std::env; -//! use std::fs::File; -//! use std::io::{Read, Write}; -//! use std::thread::{spawn, JoinHandle}; -//! type Result<T> = std::result::Result<T, BoxError>; -//! -//! use libcras::{BoxError, CrasClient, CrasClientType}; -//! use audio_streams::{SampleFormat, StreamSource}; -//! -//! const BUFFER_SIZE: usize = 256; -//! const FRAME_RATE: u32 = 44100; -//! const NUM_CHANNELS: usize = 2; -//! const FORMAT: SampleFormat = SampleFormat::S16LE; -//! -//! # fn main() -> Result<()> { -//! # let args: Vec<String> = env::args().collect(); -//! # match args.len() { -//! # 2 => { -//! let mut cras_client = CrasClient::new()?; -//! cras_client.set_client_type(CrasClientType::CRAS_CLIENT_TYPE_TEST); -//! let (_control, mut stream) = cras_client -//! .new_playback_stream(NUM_CHANNELS, FORMAT, FRAME_RATE, BUFFER_SIZE)?; -//! -//! // Plays 1000 * BUFFER_SIZE samples from the given file -//! let mut file = File::open(&args[1])?; -//! let mut local_buffer = [0u8; BUFFER_SIZE * NUM_CHANNELS * 2]; -//! for _i in 0..1000 { -//! // Reads data to local buffer -//! let _read_count = file.read(&mut local_buffer)?; -//! -//! // Gets writable buffer from stream and -//! let mut buffer = stream.next_playback_buffer()?; -//! // Writes data to stream buffer -//! let _write_frames = buffer.write(&local_buffer)?; -//! } -//! // Stream and client should gracefully be closed out of this scope -//! # } -//! # _ => { -//! # println!("{} /path/to/playback_file.raw", args[0]); -//! # } -//! # }; -//! # Ok(()) -//! # } -//! ``` -//! -//! # Example of file audio capture -//! -//! `CaptureBuffer`s which contain audio samples are obtained by calling -//! `next_capture_buffer` from `CrasStream`. -//! -//! Users get captured audio samples from the provided buffers. When a `CaptureBuffer` is dropped, -//! the number of read samples will be committed to the `CrasStream` it came from. -//! ``` -//! use std::env; -//! use std::fs::File; -//! use std::io::{Read, Write}; -//! use std::thread::{spawn, JoinHandle}; -//! type Result<T> = std::result::Result<T, BoxError>; -//! -//! use libcras::{BoxError, CrasClient, CrasClientType}; -//! use audio_streams::{SampleFormat, StreamSource}; -//! -//! const BUFFER_SIZE: usize = 256; -//! const FRAME_RATE: u32 = 44100; -//! const NUM_CHANNELS: usize = 2; -//! const FORMAT: SampleFormat = SampleFormat::S16LE; -//! -//! # fn main() -> Result<()> { -//! # let args: Vec<String> = env::args().collect(); -//! # match args.len() { -//! # 2 => { -//! let mut cras_client = CrasClient::new()?; -//! cras_client.set_client_type(CrasClientType::CRAS_CLIENT_TYPE_TEST); -//! let (_control, mut stream) = cras_client -//! .new_capture_stream(NUM_CHANNELS, FORMAT, FRAME_RATE, BUFFER_SIZE)?; -//! -//! // Capture 1000 * BUFFER_SIZE samples to the given file -//! let mut file = File::create(&args[1])?; -//! let mut local_buffer = [0u8; BUFFER_SIZE * NUM_CHANNELS * 2]; -//! for _i in 0..1000 { -//! -//! // Gets readable buffer from stream and -//! let mut buffer = stream.next_capture_buffer()?; -//! // Reads data to local buffer -//! let read_count = buffer.read(&mut local_buffer)?; -//! // Writes data to file -//! let _read_frames = file.write(&local_buffer[..read_count])?; -//! } -//! // Stream and client should gracefully be closed out of this scope -//! # } -//! # _ => { -//! # println!("{} /path/to/capture_file.raw", args[0]); -//! # } -//! # }; -//! # Ok(()) -//! # } -//! ``` -use std::io; -use std::mem; -use std::os::unix::{ - io::{AsRawFd, RawFd}, - net::UnixStream, -}; -use std::{error, fmt}; - -pub use audio_streams::BoxError; -use audio_streams::{ - capture::{CaptureBufferStream, NoopCaptureStream}, - shm_streams::{NullShmStream, ShmStream, ShmStreamSource}, - BufferDrop, NoopStreamControl, PlaybackBufferStream, SampleFormat, StreamControl, - StreamDirection, StreamEffect, StreamSource, -}; -use cras_sys::gen::*; -pub use cras_sys::gen::{ - CRAS_CLIENT_TYPE as CrasClientType, CRAS_NODE_TYPE as CrasNodeType, - CRAS_STREAM_EFFECT as CrasStreamEffect, -}; -pub use cras_sys::{AudioDebugInfo, CrasIodevInfo, CrasIonodeInfo, Error as CrasSysError}; -use sys_util::{PollContext, PollToken, SharedMemory}; - -mod audio_socket; -use crate::audio_socket::AudioSocket; -mod cras_server_socket; -use crate::cras_server_socket::CrasServerSocket; -pub use crate::cras_server_socket::CrasSocketType; -mod cras_shm; -use crate::cras_shm::CrasServerState; -pub mod cras_shm_stream; -use crate::cras_shm_stream::CrasShmStream; -mod cras_stream; -use crate::cras_stream::{CrasCaptureData, CrasPlaybackData, CrasStream, CrasStreamData}; -mod cras_client_message; -use crate::cras_client_message::*; - -#[derive(Debug)] -pub enum Error { - CrasClientMessageError(cras_client_message::Error), - CrasStreamError(cras_stream::Error), - CrasSysError(cras_sys::Error), - IoError(io::Error), - SysUtilError(sys_util::Error), - MessageTypeError, - UnexpectedExit, -} - -impl error::Error for Error {} - -impl fmt::Display for Error { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - Error::CrasClientMessageError(ref err) => err.fmt(f), - Error::CrasStreamError(ref err) => err.fmt(f), - Error::CrasSysError(ref err) => err.fmt(f), - Error::IoError(ref err) => err.fmt(f), - Error::SysUtilError(ref err) => err.fmt(f), - Error::MessageTypeError => write!(f, "Message type error"), - Error::UnexpectedExit => write!(f, "Unexpected exit"), - } - } -} - -type Result<T> = std::result::Result<T, Error>; - -impl From<io::Error> for Error { - fn from(io_err: io::Error) -> Self { - Error::IoError(io_err) - } -} - -impl From<sys_util::Error> for Error { - fn from(sys_util_err: sys_util::Error) -> Self { - Error::SysUtilError(sys_util_err) - } -} - -impl From<cras_stream::Error> for Error { - fn from(err: cras_stream::Error) -> Self { - Error::CrasStreamError(err) - } -} - -impl From<cras_client_message::Error> for Error { - fn from(err: cras_client_message::Error) -> Self { - Error::CrasClientMessageError(err) - } -} - -/// A CRAS server client, which implements StreamSource and ShmStreamSource. -/// It can create audio streams connecting to CRAS server. -pub struct CrasClient<'a> { - server_socket: CrasServerSocket, - server_state: CrasServerState<'a>, - client_id: u32, - next_stream_id: u32, - cras_capture: bool, - client_type: CRAS_CLIENT_TYPE, -} - -impl<'a> CrasClient<'a> { - /// Blocks creating a `CrasClient` with registered `client_id` - /// - /// # Results - /// - /// * `CrasClient` - A client to interact with CRAS server - /// - /// # Errors - /// - /// Returns error if error occurs while handling server message or message - /// type is incorrect - pub fn new() -> Result<Self> { - Self::with_type(CrasSocketType::Legacy) - } - - /// Tries to create a `CrasClient` with a given `CrasSocketType`. - /// - /// # Errors - /// - /// Returns error if error occurs while handling server message or message - /// type is incorrect. - pub fn with_type(socket_type: CrasSocketType) -> Result<Self> { - // Create a connection to the server. - let mut server_socket = CrasServerSocket::with_type(socket_type)?; - // Gets client ID and server state fd from server - if let ServerResult::Connected(client_id, server_state_fd) = - CrasClient::wait_for_message(&mut server_socket)? - { - Ok(Self { - server_socket, - server_state: CrasServerState::try_new(server_state_fd)?, - client_id, - next_stream_id: 0, - cras_capture: false, - client_type: CRAS_CLIENT_TYPE::CRAS_CLIENT_TYPE_UNKNOWN, - }) - } else { - Err(Error::MessageTypeError) - } - } - - /// Enables capturing audio through CRAS server. - pub fn enable_cras_capture(&mut self) { - self.cras_capture = true; - } - - /// Set the type of this client to report to CRAS when connecting streams. - pub fn set_client_type(&mut self, client_type: CRAS_CLIENT_TYPE) { - self.client_type = client_type; - } - - /// Sets the system volume to `volume`. - /// - /// Send a message to the server to request setting the system volume - /// to `volume`. No response is returned from the server. - /// - /// # Errors - /// - /// If writing the message to the server socket failed. - pub fn set_system_volume(&mut self, volume: u32) -> Result<()> { - let header = cras_server_message { - length: mem::size_of::<cras_set_system_volume>() as u32, - id: CRAS_SERVER_MESSAGE_ID::CRAS_SERVER_SET_SYSTEM_VOLUME, - }; - let msg = cras_set_system_volume { header, volume }; - - self.server_socket.send_server_message_with_fds(&msg, &[])?; - Ok(()) - } - - /// Sets the system mute status to `mute`. - /// - /// Send a message to the server to request setting the system mute - /// to `mute`. No response is returned from the server. - /// - /// # Errors - /// - /// If writing the message to the server socket failed. - pub fn set_system_mute(&mut self, mute: bool) -> Result<()> { - let header = cras_server_message { - length: mem::size_of::<cras_set_system_mute>() as u32, - id: CRAS_SERVER_MESSAGE_ID::CRAS_SERVER_SET_SYSTEM_MUTE, - }; - let msg = cras_set_system_mute { - header, - mute: mute as i32, - }; - - self.server_socket.send_server_message_with_fds(&msg, &[])?; - Ok(()) - } - - /// Gets the system volume. - /// - /// Read the current value for system volume from the server shared memory. - pub fn get_system_volume(&self) -> u32 { - self.server_state.get_system_volume() - } - - /// Gets the system mute. - /// - /// Read the current value for system mute from the server shared memory. - pub fn get_system_mute(&self) -> bool { - self.server_state.get_system_mute() - } - - /// Gets a list of output devices - /// - /// Read a list of the currently attached output devices from the server shared memory. - pub fn output_devices(&self) -> impl Iterator<Item = CrasIodevInfo> { - self.server_state.output_devices() - } - - /// Gets a list of input devices - /// - /// Read a list of the currently attached input devices from the server shared memory. - pub fn input_devices(&self) -> impl Iterator<Item = CrasIodevInfo> { - self.server_state.input_devices() - } - - /// Gets a list of output nodes - /// - /// Read a list of the currently attached output nodes from the server shared memory. - pub fn output_nodes(&self) -> impl Iterator<Item = CrasIonodeInfo> { - self.server_state.output_nodes() - } - - /// Gets a list of input nodes - /// - /// Read a list of the currently attached input nodes from the server shared memory. - pub fn input_nodes(&self) -> impl Iterator<Item = CrasIonodeInfo> { - self.server_state.input_nodes() - } - - /// Gets the server's audio debug info. - /// - /// Sends a message to the server requesting an update of audio debug info, - /// waits for the response, and then reads the info from the server state. - /// - /// # Errors - /// - /// * If sending the message to the server failed. - /// * If an unexpected response message is received. - pub fn get_audio_debug_info(&mut self) -> Result<AudioDebugInfo> { - let header = cras_server_message { - length: mem::size_of::<cras_dump_audio_thread>() as u32, - id: CRAS_SERVER_MESSAGE_ID::CRAS_SERVER_DUMP_AUDIO_THREAD, - }; - let msg = cras_dump_audio_thread { header }; - - self.server_socket.send_server_message_with_fds(&msg, &[])?; - - match CrasClient::wait_for_message(&mut self.server_socket)? { - ServerResult::DebugInfoReady => Ok(self - .server_state - .get_audio_debug_info() - .map_err(Error::CrasSysError)?), - _ => Err(Error::MessageTypeError), - } - } - - // Gets next server_stream_id from client and increment stream_id counter. - fn next_server_stream_id(&mut self) -> u32 { - let res = self.next_stream_id; - self.next_stream_id += 1; - self.server_stream_id(res) - } - - // Gets server_stream_id from given stream_id - fn server_stream_id(&self, stream_id: u32) -> u32 { - (self.client_id << 16) | stream_id - } - - // Creates general stream with given parameters - fn create_stream<'b, T: BufferDrop + CrasStreamData<'b>>( - &mut self, - device_index: Option<u32>, - block_size: u32, - direction: CRAS_STREAM_DIRECTION, - rate: u32, - channel_num: usize, - format: SampleFormat, - ) -> Result<CrasStream<'b, T>> { - let stream_id = self.next_server_stream_id(); - - // Prepares server message - let audio_format = - cras_audio_format_packed::new(format.into(), rate, channel_num, direction); - let msg_header = cras_server_message { - length: mem::size_of::<cras_connect_message>() as u32, - id: CRAS_SERVER_MESSAGE_ID::CRAS_SERVER_CONNECT_STREAM, - }; - let server_cmsg = cras_connect_message { - header: msg_header, - proto_version: CRAS_PROTO_VER, - direction, - stream_id, - stream_type: CRAS_STREAM_TYPE::CRAS_STREAM_TYPE_DEFAULT, - buffer_frames: block_size, - cb_threshold: block_size, - flags: 0, - format: audio_format, - dev_idx: device_index.unwrap_or(CRAS_SPECIAL_DEVICE::NO_DEVICE as u32), - effects: 0, - client_type: self.client_type, - client_shm_size: 0, - buffer_offsets: [0, 0], - }; - - // Creates AudioSocket pair - let (sock1, sock2) = UnixStream::pair()?; - - // Sends `CRAS_SERVER_CONNECT_STREAM` message - let socks = [sock2.as_raw_fd()]; - self.server_socket - .send_server_message_with_fds(&server_cmsg, &socks)?; - - let audio_socket = AudioSocket::new(sock1); - loop { - let result = CrasClient::wait_for_message(&mut self.server_socket)?; - if let ServerResult::StreamConnected(_stream_id, header_fd, samples_fd) = result { - return CrasStream::try_new( - stream_id, - self.server_socket.try_clone()?, - block_size, - direction, - rate, - channel_num, - format.into(), - audio_socket, - header_fd, - samples_fd, - ) - .map_err(Error::CrasStreamError); - } - } - } - - /// Creates a new playback stream pinned to the device at `device_index`. - /// - /// # Arguments - /// - /// * `device_index` - The device to which the stream will be attached. - /// * `num_channels` - The count of audio channels for the stream. - /// * `format` - The format to use for stream audio samples. - /// * `frame_rate` - The sample rate of the stream. - /// * `buffer_size` - The transfer size granularity in frames. - #[allow(clippy::type_complexity)] - pub fn new_pinned_playback_stream( - &mut self, - device_index: u32, - num_channels: usize, - format: SampleFormat, - frame_rate: u32, - buffer_size: usize, - ) -> std::result::Result<(Box<dyn StreamControl>, Box<dyn PlaybackBufferStream>), BoxError> - { - Ok(( - Box::new(NoopStreamControl::new()), - Box::new(self.create_stream::<CrasPlaybackData>( - Some(device_index), - buffer_size as u32, - CRAS_STREAM_DIRECTION::CRAS_STREAM_OUTPUT, - frame_rate, - num_channels, - format, - )?), - )) - } - - /// Creates a new capture stream pinned to the device at `device_index`. - /// - /// This is useful for, among other things, capturing from a loopback - /// device. - /// - /// # Arguments - /// - /// * `device_index` - The device to which the stream will be attached. - /// * `num_channels` - The count of audio channels for the stream. - /// * `format` - The format to use for stream audio samples. - /// * `frame_rate` - The sample rate of the stream. - /// * `buffer_size` - The transfer size granularity in frames. - #[allow(clippy::type_complexity)] - pub fn new_pinned_capture_stream( - &mut self, - device_index: u32, - num_channels: usize, - format: SampleFormat, - frame_rate: u32, - buffer_size: usize, - ) -> std::result::Result<(Box<dyn StreamControl>, Box<dyn CaptureBufferStream>), BoxError> { - Ok(( - Box::new(NoopStreamControl::new()), - Box::new(self.create_stream::<CrasCaptureData>( - Some(device_index), - buffer_size as u32, - CRAS_STREAM_DIRECTION::CRAS_STREAM_INPUT, - frame_rate, - num_channels, - format, - )?), - )) - } - - // Blocks handling the first server message received from `socket`. - fn wait_for_message(socket: &mut CrasServerSocket) -> Result<ServerResult> { - #[derive(PollToken)] - enum Token { - ServerMsg, - } - let poll_ctx: PollContext<Token> = - PollContext::new().and_then(|pc| pc.add(socket, Token::ServerMsg).and(Ok(pc)))?; - - let events = poll_ctx.wait()?; - // Check the first readable message - let tokens: Vec<Token> = events.iter_readable().map(|e| e.token()).collect(); - tokens - .get(0) - .ok_or(Error::UnexpectedExit) - .and_then(|ref token| { - match token { - Token::ServerMsg => ServerResult::handle_server_message(socket), - } - .map_err(Into::into) - }) - } - - /// Returns any open file descriptors needed by CrasClient. - /// This function is shared between StreamSource and ShmStreamSource. - fn keep_fds(&self) -> Vec<RawFd> { - vec![self.server_socket.as_raw_fd()] - } -} - -impl<'a> StreamSource for CrasClient<'a> { - #[allow(clippy::type_complexity)] - fn new_playback_stream( - &mut self, - num_channels: usize, - format: SampleFormat, - frame_rate: u32, - buffer_size: usize, - ) -> std::result::Result<(Box<dyn StreamControl>, Box<dyn PlaybackBufferStream>), BoxError> - { - Ok(( - Box::new(NoopStreamControl::new()), - Box::new(self.create_stream::<CrasPlaybackData>( - None, - buffer_size as u32, - CRAS_STREAM_DIRECTION::CRAS_STREAM_OUTPUT, - frame_rate, - num_channels, - format, - )?), - )) - } - - #[allow(clippy::type_complexity)] - fn new_capture_stream( - &mut self, - num_channels: usize, - format: SampleFormat, - frame_rate: u32, - buffer_size: usize, - ) -> std::result::Result<(Box<dyn StreamControl>, Box<dyn CaptureBufferStream>), BoxError> { - if self.cras_capture { - Ok(( - Box::new(NoopStreamControl::new()), - Box::new(self.create_stream::<CrasCaptureData>( - None, - buffer_size as u32, - CRAS_STREAM_DIRECTION::CRAS_STREAM_INPUT, - frame_rate, - num_channels, - format, - )?), - )) - } else { - Ok(( - Box::new(NoopStreamControl::new()), - Box::new(NoopCaptureStream::new( - num_channels, - format, - frame_rate, - buffer_size, - )), - )) - } - } - - fn keep_fds(&self) -> Option<Vec<RawFd>> { - Some(CrasClient::keep_fds(self)) - } -} - -impl<'a> ShmStreamSource for CrasClient<'a> { - fn new_stream( - &mut self, - direction: StreamDirection, - num_channels: usize, - format: SampleFormat, - frame_rate: u32, - buffer_size: usize, - effects: &[StreamEffect], - client_shm: &SharedMemory, - buffer_offsets: [u64; 2], - ) -> std::result::Result<Box<dyn ShmStream>, BoxError> { - if direction == StreamDirection::Capture && !self.cras_capture { - return Ok(Box::new(NullShmStream::new( - buffer_size, - num_channels, - format, - frame_rate, - ))); - } - - let buffer_size = buffer_size as u32; - - // Prepares server message - let stream_id = self.next_server_stream_id(); - let audio_format = cras_audio_format_packed::new( - format.into(), - frame_rate, - num_channels, - direction.into(), - ); - let msg_header = cras_server_message { - length: mem::size_of::<cras_connect_message>() as u32, - id: CRAS_SERVER_MESSAGE_ID::CRAS_SERVER_CONNECT_STREAM, - }; - - let server_cmsg = cras_connect_message { - header: msg_header, - proto_version: CRAS_PROTO_VER, - direction: direction.into(), - stream_id, - stream_type: CRAS_STREAM_TYPE::CRAS_STREAM_TYPE_DEFAULT, - buffer_frames: buffer_size, - cb_threshold: buffer_size, - flags: 0, - format: audio_format, - dev_idx: CRAS_SPECIAL_DEVICE::NO_DEVICE as u32, - effects: effects.iter().collect::<CrasStreamEffect>().into(), - client_type: self.client_type, - client_shm_size: client_shm.size(), - buffer_offsets, - }; - - // Creates AudioSocket pair - let (sock1, sock2) = UnixStream::pair()?; - - // Sends `CRAS_SERVER_CONNECT_STREAM` message - let fds = [sock2.as_raw_fd(), client_shm.as_raw_fd()]; - self.server_socket - .send_server_message_with_fds(&server_cmsg, &fds)?; - - loop { - let result = CrasClient::wait_for_message(&mut self.server_socket)?; - if let ServerResult::StreamConnected(_stream_id, header_fd, _samples_fd) = result { - let audio_socket = AudioSocket::new(sock1); - let stream = CrasShmStream::try_new( - stream_id, - self.server_socket.try_clone()?, - audio_socket, - direction, - num_channels, - frame_rate, - format, - header_fd, - client_shm.size() as usize, - )?; - return Ok(Box::new(stream)); - } - } - } - - fn keep_fds(&self) -> Vec<RawFd> { - CrasClient::keep_fds(self) - } -} |