use core::{ops::Range, u64};
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct SilenceMask(pub u64);
impl SilenceMask {
pub const NONE_SILENT: Self = Self(0);
pub const MONO_SILENT: Self = Self(0b1);
pub const STEREO_SILENT: Self = Self(0b11);
pub const fn new_all_silent(num_channels: usize) -> Self {
if num_channels >= 64 {
Self(u64::MAX)
} else {
Self((0b1 << num_channels) - 1)
}
}
pub const fn is_channel_silent(&self, i: usize) -> bool {
self.0 & (0b1 << i) != 0
}
pub const fn any_channel_silent(&self, num_channels: usize) -> bool {
if num_channels >= 64 {
self.0 != 0
} else {
self.0 & ((0b1 << num_channels) - 1) != 0
}
}
pub const fn all_channels_silent(&self, num_channels: usize) -> bool {
if num_channels >= 64 {
self.0 == u64::MAX
} else {
let mask = (0b1 << num_channels) - 1;
self.0 & mask == mask
}
}
pub const fn range_silent(&self, range: Range<usize>) -> bool {
if range.start >= 64 {
false
} else if range.end >= 64 {
let mask = u64::MAX & !((0b1 << range.start) - 1);
self.0 & mask == mask
} else {
let mask = ((0b1 << range.end) - 1) & !((0b1 << range.start) - 1);
self.0 & mask == mask
}
}
pub fn set_channel(&mut self, i: usize, silent: bool) {
if silent {
self.0 |= 0b1 << i;
} else {
self.0 &= !(0b1 << i);
}
}
pub const fn union(self, other: Self) -> Self {
SilenceMask(self.0 & other.0)
}
pub fn union_with(&mut self, other: Self) {
self.0 &= other.0;
}
pub fn to_constant_mask(self) -> ConstantMask {
ConstantMask(self.0)
}
}
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct ConstantMask(pub u64);
impl ConstantMask {
pub const NONE_CONSTANT: Self = Self(0);
pub const MONO_CONSTANT: Self = Self(0b1);
pub const STEREO_CONSTANT: Self = Self(0b11);
pub const fn new_all_constant(num_channels: usize) -> Self {
if num_channels >= 64 {
Self(u64::MAX)
} else {
Self((0b1 << num_channels) - 1)
}
}
pub const fn is_channel_constant(&self, i: usize) -> bool {
self.0 & (0b1 << i) != 0
}
pub const fn any_channel_constant(&self, num_channels: usize) -> bool {
if num_channels >= 64 {
self.0 != 0
} else {
self.0 & ((0b1 << num_channels) - 1) != 0
}
}
pub const fn all_channels_constant(&self, num_channels: usize) -> bool {
if num_channels >= 64 {
self.0 == u64::MAX
} else {
let mask = (0b1 << num_channels) - 1;
self.0 & mask == mask
}
}
pub const fn range_constant(&self, range: Range<usize>) -> bool {
if range.start >= 64 {
false
} else if range.end >= 64 {
let mask = u64::MAX & !((0b1 << range.start) - 1);
self.0 & mask == mask
} else {
let mask = ((0b1 << range.end) - 1) & !((0b1 << range.start) - 1);
self.0 & mask == mask
}
}
pub fn set_channel(&mut self, i: usize, constant: bool) {
if constant {
self.0 |= 0b1 << i;
} else {
self.0 &= !(0b1 << i);
}
}
pub const fn union(self, other: Self) -> Self {
ConstantMask(self.0 & other.0)
}
pub fn union_with(&mut self, other: Self) {
self.0 &= other.0;
}
pub fn to_silence_mask<V: AsRef<[f32]>>(self, channels: &[V]) -> SilenceMask {
let mut silence_mask = SilenceMask::NONE_SILENT;
for (i, ch) in channels.iter().enumerate() {
let silent = self.is_channel_constant(i) && ch.as_ref()[0] == 0.0;
silence_mask.set_channel(i, silent);
}
silence_mask
}
pub unsafe fn to_silence_mask_unchecked<V: AsRef<[f32]>>(self, channels: &[V]) -> SilenceMask {
let mut silence_mask = SilenceMask::NONE_SILENT;
for (i, ch) in channels.iter().enumerate() {
let silent =
unsafe { self.is_channel_constant(i) && *(ch.as_ref().get_unchecked(0)) == 0.0 };
silence_mask.set_channel(i, silent);
}
silence_mask
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum MaskType {
Silence(SilenceMask),
Constant(ConstantMask),
}
impl Default for MaskType {
fn default() -> Self {
MaskType::Silence(Default::default())
}
}
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct ConnectedMask(pub u64);
impl ConnectedMask {
pub const NONE_CONNECTED: Self = Self(0);
pub const MONO_CONNECTED: Self = Self(0b1);
pub const STEREO_CONNECTED: Self = Self(0b11);
pub const fn is_channel_connected(&self, i: usize) -> bool {
self.0 & (0b1 << i) != 0
}
pub const fn all_channels_connected(&self, num_channels: usize) -> bool {
if num_channels >= 64 {
self.0 == u64::MAX
} else {
let mask = (0b1 << num_channels) - 1;
self.0 & mask == mask
}
}
pub fn set_channel(&mut self, i: usize, connected: bool) {
if connected {
self.0 |= 0b1 << i;
} else {
self.0 &= !(0b1 << i);
}
}
}