firewheel_core/
silence_mask.rs

1use core::u64;
2
3/// An optional optimization hint on which channels contain all
4/// zeros (silence). The first bit (`0x1`) is the first channel,
5/// the second bit is the second channel, and so on.
6#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash)]
7pub struct SilenceMask(pub u64);
8
9impl SilenceMask {
10    /// A mask with no channels marked as silent
11    pub const NONE_SILENT: Self = Self(0);
12
13    /// A mask with only the first channel marked as silent
14    pub const MONO_SILENT: Self = Self(0b1);
15
16    /// A mask with only the first two channels marked as silent
17    pub const STEREO_SILENT: Self = Self(0b11);
18
19    /// Construct a new [`SilenceMask`] with all channels marked as
20    /// silent.
21    ///
22    /// `num_channels` must be less than or equal to `64`.
23    pub const fn new_all_silent(num_channels: usize) -> Self {
24        if num_channels >= 64 {
25            Self(u64::MAX)
26        } else {
27            Self((0b1 << num_channels) - 1)
28        }
29    }
30
31    /// Returns `true` if the channel is marked as silent, `false`
32    /// otherwise.
33    ///
34    /// `i` must be less than `64`.
35    pub const fn is_channel_silent(&self, i: usize) -> bool {
36        self.0 & (0b1 << i) != 0
37    }
38
39    /// Returns `true` if any channel is marked as silent, `false`
40    /// otherwise.
41    ///
42    /// `num_channels` must be less than or equal to `64`.
43    pub const fn any_channel_silent(&self, num_channels: usize) -> bool {
44        if num_channels >= 64 {
45            self.0 != 0
46        } else {
47            self.0 & ((0b1 << num_channels) - 1) != 0
48        }
49    }
50
51    /// Returns `true` if all channels are marked as silent, `false`
52    /// otherwise.
53    ///
54    /// `num_channels` must be less than or equal to `64`.
55    pub const fn all_channels_silent(&self, num_channels: usize) -> bool {
56        if num_channels >= 64 {
57            self.0 == u64::MAX
58        } else {
59            let mask = (0b1 << num_channels) - 1;
60            self.0 & mask == mask
61        }
62    }
63
64    /// Mark/un-mark the given channel as silent.
65    ///
66    /// `i` must be less than `64`.
67    pub fn set_channel(&mut self, i: usize, silent: bool) {
68        if silent {
69            self.0 |= 0b1 << i;
70        } else {
71            self.0 &= !(0b1 << i);
72        }
73    }
74
75    pub const fn union(self, other: Self) -> Self {
76        SilenceMask(self.0 & other.0)
77    }
78
79    pub fn union_with(&mut self, other: Self) {
80        self.0 &= other.0;
81    }
82}