devices/virtio/snd/
common.rs

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
5use audio_streams::SampleFormat;
6use remain::sorted;
7use thiserror::Error as ThisError;
8
9use crate::virtio::snd::constants::*;
10
11#[sorted]
12#[derive(ThisError, Debug)]
13pub 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
22type Result<T> = std::result::Result<T, Error>;
23
24/// Converts VIRTIO_SND_PCM_RATE_* enum to frame rate
25pub 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
48pub 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_*
61pub 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
71pub 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
94pub 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
106pub 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}