mirror of
https://chromium.googlesource.com/crosvm/crosvm
synced 2025-02-09 20:04:20 +00:00
audio_streams_conformance_test: support playback test for cras_stream
Support playback test for cras_stream. It does not support `cargo build --features=chromeos` to enable the libcras support due to the sys_util dependency of libcras. The output result is like: == audio_streams_conformance_test -P cras --iterations 100 Playback Source: CRAS Channels: 2 Format: S16LE Sample rate: 48000 frames/s Buffer size: 240 frames Iterations: 100 Cold start latency: 239.692005ms Records count: 100 [Step] min: 4.68 ms, max: 65.29 ms, average: 5.61 ms, standard deviation: 6.03 ms. [Linear Regression] rate: 47576.23 frames/s, standard error: 284.42 BUG=b:238038707 TEST=emerge-${BOARD} audio_streams_conformance_test TEST=audio_streams_conformance_test -P cras Change-Id: I2547df7b15cd36adb5452ab09d2a38e417b04dbf Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/3864013 Tested-by: Judy Hsiao <judyhsiao@google.com> Commit-Queue: Judy Hsiao <judyhsiao@google.com> Reviewed-by: Chih-Yang Hsia <paulhsia@chromium.org> Auto-Submit: Judy Hsiao <judyhsiao@google.com>
This commit is contained in:
parent
3174c86a36
commit
dbd67e522a
6 changed files with 137 additions and 8 deletions
|
@ -8,12 +8,22 @@ edition = "2021"
|
||||||
name = "audio_streams_conformance_test"
|
name = "audio_streams_conformance_test"
|
||||||
path = "src/main.rs"
|
path = "src/main.rs"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
audio_cras = ["dep:libcras"]
|
||||||
|
chromeos = ["audio_cras"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
argh = "*"
|
argh = "*"
|
||||||
audio_streams = { path = "../../common/audio_streams" } # provided by ebuild
|
audio_streams = "*"
|
||||||
|
cfg-if = "1.0.0"
|
||||||
cros_async = { path = "../../cros_async" } # provided by ebuild
|
cros_async = { path = "../../cros_async" } # provided by ebuild
|
||||||
num = "*"
|
num = "*"
|
||||||
|
libcras = { version = "*", optional = true }
|
||||||
remain = "0.2"
|
remain = "0.2"
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
serde_json = "*"
|
serde_json = "*"
|
||||||
thiserror = "1.0.20"
|
thiserror = "1.0.20"
|
||||||
|
|
||||||
|
[patch.crates-io]
|
||||||
|
audio_streams = { path = "../../common/audio_streams"} # ignored by ebuild
|
||||||
|
libcras = { path = "../../libcras_stub" } # ignored by ebuild
|
||||||
|
|
|
@ -10,17 +10,20 @@ use audio_streams::*;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
use super::error::Error;
|
use super::error::Error;
|
||||||
|
use super::sys::StreamSource as SysStreamSource;
|
||||||
|
|
||||||
// maybe use StreamSourceGenerator directly
|
// maybe use StreamSourceGenerator directly
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Serialize)]
|
#[derive(Copy, Clone, Debug, PartialEq, Serialize)]
|
||||||
pub enum StreamSourceEnum {
|
pub enum StreamSourceEnum {
|
||||||
NoopStream,
|
NoopStream,
|
||||||
|
Sys(SysStreamSource),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for StreamSourceEnum {
|
impl fmt::Display for StreamSourceEnum {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
StreamSourceEnum::NoopStream => write!(f, "noop"),
|
StreamSourceEnum::NoopStream => write!(f, "noop"),
|
||||||
|
StreamSourceEnum::Sys(stream_source) => stream_source.fmt(f),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,7 +33,7 @@ impl FromStr for StreamSourceEnum {
|
||||||
fn from_str(s: &str) -> ::std::result::Result<StreamSourceEnum, Self::Err> {
|
fn from_str(s: &str) -> ::std::result::Result<StreamSourceEnum, Self::Err> {
|
||||||
match s {
|
match s {
|
||||||
"noop" => Ok(StreamSourceEnum::NoopStream),
|
"noop" => Ok(StreamSourceEnum::NoopStream),
|
||||||
_ => Err(Error::InvalidStreamSuorce(s.to_owned())),
|
_ => SysStreamSource::try_from(s).map(StreamSourceEnum::Sys),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -60,7 +63,7 @@ fn default_stream_source() -> StreamSourceEnum {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, FromArgs, Serialize)]
|
#[derive(Copy, Clone, Debug, FromArgs, Serialize)]
|
||||||
/// test test
|
/// audio_streams_conformance_test
|
||||||
pub struct Args {
|
pub struct Args {
|
||||||
/// the StreamSource to use for playback. (default: noop).
|
/// the StreamSource to use for playback. (default: noop).
|
||||||
#[argh(
|
#[argh(
|
||||||
|
@ -69,7 +72,7 @@ pub struct Args {
|
||||||
default = "default_stream_source()",
|
default = "default_stream_source()",
|
||||||
from_str_fn(StreamSourceEnum::from_str)
|
from_str_fn(StreamSourceEnum::from_str)
|
||||||
)]
|
)]
|
||||||
pub playback_source: StreamSourceEnum,
|
pub stream_source: StreamSourceEnum,
|
||||||
/// the channel numbers. (default: 2)
|
/// the channel numbers. (default: 2)
|
||||||
#[argh(option, short = 'c', default = "default_channels()")]
|
#[argh(option, short = 'c', default = "default_channels()")]
|
||||||
pub channels: usize,
|
pub channels: usize,
|
||||||
|
@ -107,7 +110,7 @@ Sample rate: {} frames/s
|
||||||
Buffer size: {} frames
|
Buffer size: {} frames
|
||||||
Iterations: {}
|
Iterations: {}
|
||||||
"#,
|
"#,
|
||||||
self.playback_source,
|
self.stream_source,
|
||||||
self.channels,
|
self.channels,
|
||||||
self.format,
|
self.format,
|
||||||
self.rate,
|
self.rate,
|
||||||
|
|
|
@ -11,17 +11,26 @@ use cros_async::Executor;
|
||||||
mod args;
|
mod args;
|
||||||
mod error;
|
mod error;
|
||||||
mod performance_data;
|
mod performance_data;
|
||||||
|
mod sys;
|
||||||
|
|
||||||
use crate::args::*;
|
use crate::args::*;
|
||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
use crate::error::Result;
|
use crate::error::Result;
|
||||||
use crate::performance_data::*;
|
use crate::performance_data::*;
|
||||||
|
use crate::sys::create_stream_source_generator as sys_create_stream_source_generators;
|
||||||
|
|
||||||
|
fn create_stream_source_generators(args: &Args) -> Box<dyn StreamSourceGenerator> {
|
||||||
|
match args.stream_source {
|
||||||
|
StreamSourceEnum::NoopStream => Box::new(NoopStreamSourceGenerator::new()),
|
||||||
|
StreamSourceEnum::Sys(stream_source) => {
|
||||||
|
sys_create_stream_source_generators(stream_source, args)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async fn run_playback(ex: &Executor, args: &Args) -> Result<PerformanceData> {
|
async fn run_playback(ex: &Executor, args: &Args) -> Result<PerformanceData> {
|
||||||
let mut data = PerformanceData::default();
|
let mut data = PerformanceData::default();
|
||||||
let generator: Box<dyn StreamSourceGenerator> = match args.playback_source {
|
let generator: Box<dyn StreamSourceGenerator> = create_stream_source_generators(args);
|
||||||
StreamSourceEnum::NoopStream => Box::new(NoopStreamSourceGenerator::new()),
|
|
||||||
};
|
|
||||||
let num_channels = args.channels;
|
let num_channels = args.channels;
|
||||||
let format = args.format;
|
let format = args.format;
|
||||||
let frame_rate = args.rate;
|
let frame_rate = args.rate;
|
||||||
|
|
16
tools/audio_streams_conformance_test/src/sys/mod.rs
Normal file
16
tools/audio_streams_conformance_test/src/sys/mod.rs
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
// Copyright 2022 The ChromiumOS Authors.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
cfg_if::cfg_if! {
|
||||||
|
if #[cfg(unix)] {
|
||||||
|
mod unix;
|
||||||
|
use unix as platform;
|
||||||
|
} else if #[cfg(windows)] {
|
||||||
|
mod windows;
|
||||||
|
use windows as platform;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) use platform::create_stream_source_generator;
|
||||||
|
pub use platform::StreamSource;
|
62
tools/audio_streams_conformance_test/src/sys/unix.rs
Normal file
62
tools/audio_streams_conformance_test/src/sys/unix.rs
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
// Copyright 2022 The ChromiumOS Authors.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
|
use audio_streams::StreamSourceGenerator;
|
||||||
|
#[cfg(feature = "audio_cras")]
|
||||||
|
use libcras::{CrasClientType, CrasSocketType, CrasStreamSourceGenerator};
|
||||||
|
use serde::Serialize;
|
||||||
|
|
||||||
|
use crate::args::*;
|
||||||
|
use crate::error::Error;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Serialize)]
|
||||||
|
pub enum StreamSource {
|
||||||
|
#[cfg(feature = "audio_cras")]
|
||||||
|
CRAS,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<&str> for StreamSource {
|
||||||
|
type Error = Error;
|
||||||
|
|
||||||
|
fn try_from(s: &str) -> Result<Self, Self::Error> {
|
||||||
|
match s {
|
||||||
|
#[cfg(feature = "audio_cras")]
|
||||||
|
"cras" => Ok(StreamSource::CRAS),
|
||||||
|
_ => Err(Error::InvalidStreamSuorce(s.to_owned())),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for StreamSource {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
#[cfg(feature = "audio_cras")]
|
||||||
|
StreamSource::CRAS => write!(f, "cras"),
|
||||||
|
_ => write!(f, "unknow stream source"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(unused_variables)]
|
||||||
|
#[cfg(feature = "audio_cras")]
|
||||||
|
fn create_cras_stream_source_generator(args: &Args) -> Box<dyn StreamSourceGenerator> {
|
||||||
|
Box::new(CrasStreamSourceGenerator::new(
|
||||||
|
false,
|
||||||
|
CrasClientType::CRAS_CLIENT_TYPE_TEST,
|
||||||
|
CrasSocketType::Legacy,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(unused_variables)]
|
||||||
|
pub(crate) fn create_stream_source_generator(
|
||||||
|
stream_source: StreamSource,
|
||||||
|
args: &Args,
|
||||||
|
) -> Box<dyn StreamSourceGenerator> {
|
||||||
|
match stream_source {
|
||||||
|
#[cfg(feature = "audio_cras")]
|
||||||
|
StreamSource::CRAS => create_cras_stream_source_generator(args),
|
||||||
|
}
|
||||||
|
}
|
29
tools/audio_streams_conformance_test/src/sys/windows.rs
Normal file
29
tools/audio_streams_conformance_test/src/sys/windows.rs
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
// Copyright 2022 The ChromiumOS Authors.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
use audio_streams::StreamSourceGenerator;
|
||||||
|
|
||||||
|
use crate::args::*;
|
||||||
|
use crate::error::Error;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
|
pub enum StreamSource {}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, FromArgs, Serialize)]
|
||||||
|
pub enum StreamSourceParam {}
|
||||||
|
|
||||||
|
impl TryFrom<&str> for StreamSource {
|
||||||
|
type Error = Error;
|
||||||
|
|
||||||
|
fn try_from(s: &str) -> Result<Self, Self::Error> {
|
||||||
|
todo!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn create_stream_source_generator(
|
||||||
|
stream_source: StreamSource,
|
||||||
|
args: &Args,
|
||||||
|
) -> Vec<Box<dyn StreamSourceGenerator>> {
|
||||||
|
todo!();
|
||||||
|
}
|
Loading…
Reference in a new issue