audio_streams_conformance_test/
main.rs

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
5use std::io;
6use std::time::Instant;
7
8use audio_streams::*;
9use cros_async::Executor;
10
11mod args;
12mod error;
13mod performance_data;
14mod sys;
15
16use crate::args::*;
17use crate::error::Error;
18use crate::error::Result;
19use crate::performance_data::*;
20use crate::sys::create_stream_source_generator as sys_create_stream_source_generators;
21
22fn 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
31async 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
66fn 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}