xref: /aosp_15_r20/external/crosvm/devices/src/virtio/snd/common.rs (revision bb4ee6a4ae7042d18b07a98463b9c8b875e44b39)
1 // Copyright 2021 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 audio_streams::SampleFormat;
6 use remain::sorted;
7 use thiserror::Error as ThisError;
8 
9 use crate::virtio::snd::constants::*;
10 
11 #[sorted]
12 #[derive(ThisError, Debug)]
13 pub enum Error {
14     #[error("Unsupported frame rate: {0}")]
15     UnsupportedFrameRate(u32),
16     #[error("Unsupported virtio frame rate: {0}")]
17     UnsupportedVirtioFrameRate(u8),
18     #[error("Unsupported virtio pcm format: {0}")]
19     UnsupportedVirtioPcmFormat(u8),
20 }
21 
22 type Result<T> = std::result::Result<T, Error>;
23 
24 /// Converts VIRTIO_SND_PCM_RATE_* enum to frame rate
from_virtio_frame_rate(virtio_frame_rate: u8) -> Result<u32>25 pub fn from_virtio_frame_rate(virtio_frame_rate: u8) -> Result<u32> {
26     Ok(match virtio_frame_rate {
27         VIRTIO_SND_PCM_RATE_5512 => 5512u32,
28         VIRTIO_SND_PCM_RATE_8000 => 8000u32,
29         VIRTIO_SND_PCM_RATE_11025 => 11025u32,
30         VIRTIO_SND_PCM_RATE_16000 => 16000u32,
31         VIRTIO_SND_PCM_RATE_22050 => 22050u32,
32         VIRTIO_SND_PCM_RATE_32000 => 32000u32,
33         VIRTIO_SND_PCM_RATE_44100 => 44100u32,
34         VIRTIO_SND_PCM_RATE_48000 => 48000u32,
35         VIRTIO_SND_PCM_RATE_64000 => 64000u32,
36         VIRTIO_SND_PCM_RATE_88200 => 88200u32,
37         VIRTIO_SND_PCM_RATE_96000 => 96000u32,
38         VIRTIO_SND_PCM_RATE_176400 => 176400u32,
39         VIRTIO_SND_PCM_RATE_192000 => 192000u32,
40         VIRTIO_SND_PCM_RATE_384000 => 384000u32,
41         _ => {
42             return Err(Error::UnsupportedVirtioFrameRate(virtio_frame_rate));
43         }
44     })
45 }
46 
47 /// Converts VIRTIO_SND_PCM_FMT_* enum to SampleFormat
from_virtio_sample_format(virtio_pcm_format: u8) -> Result<SampleFormat>48 pub fn from_virtio_sample_format(virtio_pcm_format: u8) -> Result<SampleFormat> {
49     Ok(match virtio_pcm_format {
50         VIRTIO_SND_PCM_FMT_U8 => SampleFormat::U8,
51         VIRTIO_SND_PCM_FMT_S16 => SampleFormat::S16LE,
52         VIRTIO_SND_PCM_FMT_S24 => SampleFormat::S24LE,
53         VIRTIO_SND_PCM_FMT_S32 => SampleFormat::S32LE,
54         _ => {
55             return Err(Error::UnsupportedVirtioPcmFormat(virtio_pcm_format));
56         }
57     })
58 }
59 
60 /// Converts SampleFormat to VIRTIO_SND_PCM_FMT_*
from_sample_format(format: SampleFormat) -> u861 pub fn from_sample_format(format: SampleFormat) -> u8 {
62     match format {
63         SampleFormat::U8 => VIRTIO_SND_PCM_FMT_U8,
64         SampleFormat::S16LE => VIRTIO_SND_PCM_FMT_S16,
65         SampleFormat::S24LE => VIRTIO_SND_PCM_FMT_S24,
66         SampleFormat::S32LE => VIRTIO_SND_PCM_FMT_S32,
67     }
68 }
69 
70 /// Converts frame rate to VIRTIO_SND_PCM_RATE_* enum
virtio_frame_rate(frame_rate: u32) -> Result<u8>71 pub fn virtio_frame_rate(frame_rate: u32) -> Result<u8> {
72     Ok(match frame_rate {
73         5512u32 => VIRTIO_SND_PCM_RATE_5512,
74         8000u32 => VIRTIO_SND_PCM_RATE_8000,
75         11025u32 => VIRTIO_SND_PCM_RATE_11025,
76         16000u32 => VIRTIO_SND_PCM_RATE_16000,
77         22050u32 => VIRTIO_SND_PCM_RATE_22050,
78         32000u32 => VIRTIO_SND_PCM_RATE_32000,
79         44100u32 => VIRTIO_SND_PCM_RATE_44100,
80         48000u32 => VIRTIO_SND_PCM_RATE_48000,
81         64000u32 => VIRTIO_SND_PCM_RATE_64000,
82         88200u32 => VIRTIO_SND_PCM_RATE_88200,
83         96000u32 => VIRTIO_SND_PCM_RATE_96000,
84         176400u32 => VIRTIO_SND_PCM_RATE_176400,
85         192000u32 => VIRTIO_SND_PCM_RATE_192000,
86         384000u32 => VIRTIO_SND_PCM_RATE_384000,
87         _ => {
88             return Err(Error::UnsupportedFrameRate(frame_rate));
89         }
90     })
91 }
92 
93 /// Get the name of VIRTIO_SND_R_PCM_* enums
get_virtio_snd_r_pcm_cmd_name(cmd_code: u32) -> &'static str94 pub fn get_virtio_snd_r_pcm_cmd_name(cmd_code: u32) -> &'static str {
95     match cmd_code {
96         0 => "Uninitialized",
97         VIRTIO_SND_R_PCM_SET_PARAMS => "VIRTIO_SND_R_PCM_SET_PARAMS",
98         VIRTIO_SND_R_PCM_PREPARE => "VIRTIO_SND_R_PCM_PREPARE",
99         VIRTIO_SND_R_PCM_START => "VIRTIO_SND_R_PCM_START",
100         VIRTIO_SND_R_PCM_STOP => "VIRTIO_SND_R_PCM_STOP",
101         VIRTIO_SND_R_PCM_RELEASE => "VIRTIO_SND_R_PCM_RELEASE",
102         _ => unreachable!(),
103     }
104 }
105 
get_virtio_direction_name(dir: u8) -> &'static str106 pub fn get_virtio_direction_name(dir: u8) -> &'static str {
107     match dir {
108         VIRTIO_SND_D_OUTPUT => "VIRTIO_SND_D_OUTPUT",
109         VIRTIO_SND_D_INPUT => "VIRTIO_SND_D_INPUT",
110         _ => unreachable!(),
111     }
112 }
113