1 // Copyright 2022 The ChromiumOS Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 use std::io;
6 use std::time::Instant;
7
8 use audio_streams::*;
9 use cros_async::Executor;
10
11 mod args;
12 mod error;
13 mod performance_data;
14 mod sys;
15
16 use crate::args::*;
17 use crate::error::Error;
18 use crate::error::Result;
19 use crate::performance_data::*;
20 use crate::sys::create_stream_source_generator as sys_create_stream_source_generators;
21
create_stream_source_generators(args: &Args) -> Box<dyn StreamSourceGenerator>22 fn create_stream_source_generators(args: &Args) -> Box<dyn StreamSourceGenerator> {
23 match args.stream_source {
24 StreamSourceEnum::NoopStream => Box::new(NoopStreamSourceGenerator::new()),
25 StreamSourceEnum::Sys(stream_source) => {
26 sys_create_stream_source_generators(stream_source, args)
27 }
28 }
29 }
30
run_playback(ex: &Executor, args: &Args) -> Result<PerformanceData>31 async fn run_playback(ex: &Executor, args: &Args) -> Result<PerformanceData> {
32 let mut data = PerformanceData::default();
33 let generator: Box<dyn StreamSourceGenerator> = create_stream_source_generators(args);
34 let num_channels = args.channels;
35 let format = args.format;
36 let frame_rate = args.rate;
37 let buffer_size = args.buffer_frames;
38 let iterations = args.iterations;
39
40 let mut stream_source = generator.generate().map_err(Error::GenerateStreamSource)?;
41 let start = Instant::now();
42 let (_, mut stream) = stream_source
43 .new_async_playback_stream(num_channels, format, frame_rate, buffer_size, ex)
44 .map_err(Error::CreateStream)?;
45 data.cold_start = start.elapsed();
46 let frame_size = args.format.sample_bytes() * args.channels;
47
48 let start = Instant::now();
49 let mut frames_played = 0;
50 for _ in 0..iterations {
51 let mut stream_buffer = stream
52 .next_playback_buffer(ex)
53 .await
54 .map_err(Error::FetchBuffer)?;
55 let bytes = stream_buffer
56 .copy_from(&mut io::repeat(0))
57 .map_err(Error::WriteBuffer)?;
58 stream_buffer.commit().await;
59 frames_played += bytes / frame_size;
60 data.records
61 .push(BufferConsumptionRecord::new(frames_played, start.elapsed()));
62 }
63 Ok(data)
64 }
65
main() -> Result<()>66 fn main() -> Result<()> {
67 let args: Args = argh::from_env();
68 let ex = Executor::new().expect("Failed to create an executor");
69 let done = run_playback(&ex, &args);
70
71 match ex.run_until(done) {
72 Ok(Ok(data)) => {
73 let report = data.gen_report(args)?;
74 if args.debug {
75 data.print_records();
76 }
77 if args.json {
78 println!("{}", serde_json::to_string(&report)?);
79 } else {
80 print!("{}", report);
81 }
82 }
83 Ok(Err(e)) => eprintln!("{}", e),
84 Err(e) => eprintln!("Error happened in executor: {}", e),
85 }
86 Ok(())
87 }
88