Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
google
GitHub Repository: google/crosvm
Path: blob/main/devices/src/virtio/snd/file_backend.rs
5394 views
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_or_duplicate;
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
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
43
fn open_playback_file(dir_path: &String, stream_id: usize) -> Result<File, Error> {
44
let file_name = format!("stream-{stream_id}.out");
45
let file_path = Path::new(dir_path).join(file_name);
46
let file = open_file_or_duplicate(
47
file_path,
48
OpenOptions::new().read(true).create(true).write(true),
49
)
50
.map_err(Error::OpenFile)?;
51
Ok(file)
52
}
53
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
79