summaryrefslogtreecommitdiffstats
path: root/third_party/rust/audio-mixer/src/channel.rs
blob: ef58018ad9a063949f9174b097070e54d8f2370a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
// The number of channels must be unique and start from 0. They will be treated as indice in the
// mixing matrix and used to form unique bitflags in the channel map, which is a bitmap.
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum Channel {
    FrontLeft = 0,
    FrontRight = 1,
    FrontCenter = 2,
    LowFrequency = 3,
    BackLeft = 4,
    BackRight = 5,
    FrontLeftOfCenter = 6,
    FrontRightOfCenter = 7,
    BackCenter = 8,
    SideLeft = 9,
    SideRight = 10,
    TopCenter = 11,
    TopFrontLeft = 12,
    TopFrontCenter = 13,
    TopFrontRight = 14,
    TopBackLeft = 15,
    TopBackCenter = 16,
    TopBackRight = 17,
    Silence = 18,
}

impl Channel {
    pub const fn number(self) -> usize {
        self as usize
    }

    pub const fn count() -> usize {
        Channel::Silence as usize + 1
    }

    pub const fn bitmask(self) -> u32 {
        1 << self as usize
    }
}

bitflags! {
    pub struct ChannelMap: u32 {
        const FRONT_LEFT = Channel::FrontLeft.bitmask();
        const FRONT_RIGHT = Channel::FrontRight.bitmask();
        const FRONT_CENTER = Channel::FrontCenter.bitmask();
        const LOW_FREQUENCY = Channel::LowFrequency.bitmask();
        const BACK_LEFT = Channel::BackLeft.bitmask();
        const BACK_RIGHT = Channel::BackRight.bitmask();
        const FRONT_LEFT_OF_CENTER = Channel::FrontLeftOfCenter.bitmask();
        const FRONT_RIGHT_OF_CENTER = Channel::FrontRightOfCenter.bitmask();
        const BACK_CENTER = Channel::BackCenter.bitmask();
        const SIDE_LEFT = Channel::SideLeft.bitmask();
        const SIDE_RIGHT = Channel::SideRight.bitmask();
        const TOP_CENTER = Channel::TopCenter.bitmask();
        const TOP_FRONT_LEFT = Channel::TopFrontLeft.bitmask();
        const TOP_FRONT_CENTER = Channel::TopFrontCenter.bitmask();
        const TOP_FRONT_RIGHT = Channel::TopFrontRight.bitmask();
        const TOP_BACK_LEFT = Channel::TopBackLeft.bitmask();
        const TOP_BACK_CENTER = Channel::TopBackCenter.bitmask();
        const TOP_BACK_RIGHT = Channel::TopBackRight.bitmask();
        const SILENCE = Channel::Silence.bitmask();
    }
}

// Avoid printing the following types in debugging context {:?} by declaring them in impl
// rather than bitflags! {} scope.
impl ChannelMap {
    pub const FRONT_2: Self = Self {
        bits: Self::FRONT_LEFT.bits() | Self::FRONT_RIGHT.bits(),
    };
    pub const BACK_2: Self = Self {
        bits: Self::BACK_LEFT.bits() | Self::BACK_RIGHT.bits(),
    };
    pub const FRONT_2_OF_CENTER: Self = Self {
        bits: Self::FRONT_LEFT_OF_CENTER.bits() | Self::FRONT_RIGHT_OF_CENTER.bits(),
    };
    pub const SIDE_2: Self = Self {
        bits: Self::SIDE_LEFT.bits() | Self::SIDE_RIGHT.bits(),
    };
}

impl From<Channel> for ChannelMap {
    fn from(channel: Channel) -> Self {
        ChannelMap::from_bits(channel.bitmask()).expect("convert an invalid channel")
    }
}