audio_mixer/
channel.rs

1// The number of channels must be unique and start from 0. They will be treated as indice in the
2// mixing matrix and used to form unique bitflags in the channel map, which is a bitmap.
3#[derive(Copy, Clone, Debug, PartialEq)]
4pub enum Channel {
5    FrontLeft = 0,
6    FrontRight = 1,
7    FrontCenter = 2,
8    LowFrequency = 3,
9    BackLeft = 4,
10    BackRight = 5,
11    FrontLeftOfCenter = 6,
12    FrontRightOfCenter = 7,
13    BackCenter = 8,
14    SideLeft = 9,
15    SideRight = 10,
16    TopCenter = 11,
17    TopFrontLeft = 12,
18    TopFrontCenter = 13,
19    TopFrontRight = 14,
20    TopBackLeft = 15,
21    TopBackCenter = 16,
22    TopBackRight = 17,
23    Silence = 18,
24    Discrete = 19, // To be used based on its index
25}
26
27impl Channel {
28    pub const fn number(self) -> usize {
29        self as usize
30    }
31
32    pub const fn count() -> usize {
33        Channel::Discrete as usize + 1
34    }
35
36    pub const fn bitmask(self) -> u32 {
37        1 << self as usize
38    }
39}
40
41bitflags! {
42    pub struct ChannelMap: u32 {
43        const FRONT_LEFT = Channel::FrontLeft.bitmask();
44        const FRONT_RIGHT = Channel::FrontRight.bitmask();
45        const FRONT_CENTER = Channel::FrontCenter.bitmask();
46        const LOW_FREQUENCY = Channel::LowFrequency.bitmask();
47        const BACK_LEFT = Channel::BackLeft.bitmask();
48        const BACK_RIGHT = Channel::BackRight.bitmask();
49        const FRONT_LEFT_OF_CENTER = Channel::FrontLeftOfCenter.bitmask();
50        const FRONT_RIGHT_OF_CENTER = Channel::FrontRightOfCenter.bitmask();
51        const BACK_CENTER = Channel::BackCenter.bitmask();
52        const SIDE_LEFT = Channel::SideLeft.bitmask();
53        const SIDE_RIGHT = Channel::SideRight.bitmask();
54        const TOP_CENTER = Channel::TopCenter.bitmask();
55        const TOP_FRONT_LEFT = Channel::TopFrontLeft.bitmask();
56        const TOP_FRONT_CENTER = Channel::TopFrontCenter.bitmask();
57        const TOP_FRONT_RIGHT = Channel::TopFrontRight.bitmask();
58        const TOP_BACK_LEFT = Channel::TopBackLeft.bitmask();
59        const TOP_BACK_CENTER = Channel::TopBackCenter.bitmask();
60        const TOP_BACK_RIGHT = Channel::TopBackRight.bitmask();
61        const SILENCE = Channel::Silence.bitmask();
62        const DISCRETE = Channel::Discrete.bitmask();
63    }
64}
65
66// Avoid printing the following types in debugging context {:?} by declaring them in impl
67// rather than bitflags! {} scope.
68impl ChannelMap {
69    pub const FRONT_2: Self = Self::union(Self::FRONT_LEFT, Self::FRONT_RIGHT);
70    pub const BACK_2: Self = Self::union(Self::BACK_LEFT, Self::BACK_RIGHT);
71    pub const FRONT_2_OF_CENTER: Self =
72        Self::union(Self::FRONT_LEFT_OF_CENTER, Self::FRONT_RIGHT_OF_CENTER);
73    pub const SIDE_2: Self = Self::union(Self::SIDE_LEFT, Self::SIDE_RIGHT);
74}
75
76impl From<Channel> for ChannelMap {
77    fn from(channel: Channel) -> Self {
78        ChannelMap::from_bits(channel.bitmask()).expect("convert an invalid channel")
79    }
80}