// 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::io; use std::time::Instant; use audio_streams::*; use cros_async::Executor; mod args; mod error; mod performance_data; mod sys; use crate::args::*; use crate::error::Error; use crate::error::Result; 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 { 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 { let mut data = PerformanceData::default(); let generator: Box = create_stream_source_generators(args); let num_channels = args.channels; let format = args.format; let frame_rate = args.rate; let buffer_size = args.buffer_frames; let iterations = args.iterations; let mut stream_source = generator.generate().map_err(Error::GenerateStreamSource)?; let start = Instant::now(); let (_, mut stream) = stream_source .new_async_playback_stream(num_channels, format, frame_rate, buffer_size, ex) .map_err(Error::CreateStream)?; data.cold_start = start.elapsed(); let frame_size = args.format.sample_bytes() * args.channels; let start = Instant::now(); let mut frames_played = 0; for _ in 0..iterations { let mut stream_buffer = stream .next_playback_buffer(ex) .await .map_err(Error::FetchBuffer)?; let bytes = stream_buffer .copy_from(&mut io::repeat(0)) .map_err(Error::WriteBuffer)?; stream_buffer.commit().await; frames_played += bytes / frame_size; data.records .push(BufferConsumptionRecord::new(frames_played, start.elapsed())); } Ok(data) } fn main() -> Result<()> { let args: Args = argh::from_env(); let ex = Executor::new().expect("Failed to create an executor"); let done = run_playback(&ex, &args); match ex.run_until(done) { Ok(Ok(data)) => { let report = data.gen_report(args)?; if args.debug { data.print_records(); } if args.json { println!("{}", serde_json::to_string(&report)?); } else { print!("{}", report); } } Ok(Err(e)) => eprintln!("{}", e), Err(e) => eprintln!("Error happened in executor: {}", e), } Ok(()) }