• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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::fs::File;
6 use std::fs::OpenOptions;
7 use std::io::Error as IOError;
8 use std::io::Seek;
9 use std::io::SeekFrom;
10 use std::io::Write;
11 use std::path::Path;
12 
13 use audio_streams::NoopStreamSourceGenerator;
14 use audio_util::FileStreamSourceGenerator;
15 use base::error;
16 use base::open_file;
17 use base::AsRawDescriptor;
18 use base::RawDescriptor;
19 use thiserror::Error as ThisError;
20 
21 use crate::virtio::snd::common_backend::SndData;
22 use crate::virtio::snd::constants::VIRTIO_SND_D_OUTPUT;
23 use crate::virtio::snd::parameters::Parameters;
24 use crate::virtio::snd::sys::SysAudioStreamSourceGenerator;
25 
26 #[derive(ThisError, Debug)]
27 pub enum Error {
28     #[error("Failed to allocate space: {0}")]
29     AllocateSpace(IOError),
30     #[error("Failed to open file: {0}")]
31     OpenFile(base::Error),
32 }
33 
allocate_space(mut file: &File, size: usize) -> Result<(), Error>34 fn allocate_space(mut file: &File, size: usize) -> Result<(), Error> {
35     file.seek(SeekFrom::Start(size as u64))
36         .map_err(Error::AllocateSpace)?;
37     file.write_all(&[0]).map_err(Error::AllocateSpace)?;
38     file.seek(SeekFrom::Start(0))
39         .map_err(Error::AllocateSpace)?;
40     Ok(())
41 }
42 
open_playback_file(dir_path: &String, stream_id: usize) -> Result<File, Error>43 fn open_playback_file(dir_path: &String, stream_id: usize) -> Result<File, Error> {
44     let file_name = format!("stream-{}.out", stream_id);
45     let file_path = Path::new(dir_path).join(file_name);
46     let file = open_file(
47         file_path,
48         OpenOptions::new().read(true).create(true).write(true),
49     )
50     .map_err(Error::OpenFile)?;
51     Ok(file)
52 }
53 
create_file_stream_source_generators( params: &Parameters, snd_data: &SndData, keep_rds: &mut Vec<RawDescriptor>, ) -> Result<Vec<SysAudioStreamSourceGenerator>, Error>54 pub(crate) fn create_file_stream_source_generators(
55     params: &Parameters,
56     snd_data: &SndData,
57     keep_rds: &mut Vec<RawDescriptor>,
58 ) -> Result<Vec<SysAudioStreamSourceGenerator>, Error> {
59     let mut generators = Vec::new();
60 
61     for (stream, pcm_info) in snd_data.pcm_info.iter().enumerate() {
62         let generator: SysAudioStreamSourceGenerator = if pcm_info.direction == VIRTIO_SND_D_OUTPUT
63         {
64             let file = open_playback_file(&params.playback_path, stream)?;
65             allocate_space(&file, params.playback_size)?;
66             keep_rds.push(file.as_raw_descriptor());
67 
68             Box::new(FileStreamSourceGenerator::new(file, params.playback_size))
69         } else {
70             // Capture is not supported yet
71             Box::new(NoopStreamSourceGenerator::new())
72         };
73 
74         generators.push(generator);
75     }
76     Ok(generators)
77 }
78