1#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
11pub enum ChannelLayout {
12 Mono,
14
15 #[default]
17 Stereo,
18
19 Surround51,
21
22 Surround71,
24
25 AmbisonicFoa,
27
28 AmbisonicSoa,
30
31 AmbisonicToa,
33
34 Custom(usize),
36}
37
38impl ChannelLayout {
39 #[inline]
41 pub const fn channel_count(&self) -> usize {
42 match self {
43 Self::Mono => 1,
44 Self::Stereo => 2,
45 Self::Surround51 => 6,
46 Self::Surround71 => 8,
47 Self::AmbisonicFoa => 4,
48 Self::AmbisonicSoa => 9,
49 Self::AmbisonicToa => 16,
50 Self::Custom(n) => *n,
51 }
52 }
53
54 #[inline]
56 pub const fn is_ambisonic(&self) -> bool {
57 matches!(self, Self::AmbisonicFoa | Self::AmbisonicSoa | Self::AmbisonicToa)
58 }
59
60 #[inline]
64 pub const fn ambisonic_order(&self) -> Option<usize> {
65 match self {
66 Self::AmbisonicFoa => Some(1),
67 Self::AmbisonicSoa => Some(2),
68 Self::AmbisonicToa => Some(3),
69 _ => None,
70 }
71 }
72
73 #[inline]
77 pub const fn from_ambisonic_order(order: usize) -> Option<Self> {
78 match order {
79 1 => Some(Self::AmbisonicFoa),
80 2 => Some(Self::AmbisonicSoa),
81 3 => Some(Self::AmbisonicToa),
82 _ => None,
83 }
84 }
85
86 #[inline]
90 pub const fn ambisonic_channel_count(order: usize) -> usize {
91 (order + 1) * (order + 1)
92 }
93}
94
95#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
100pub enum ChannelConfig {
101 #[default]
107 Parallel,
108
109 Explicit,
115}
116
117#[cfg(test)]
118mod tests {
119 use super::*;
120
121 #[test]
122 fn channel_layout_channel_count() {
123 assert_eq!(ChannelLayout::Mono.channel_count(), 1);
124 assert_eq!(ChannelLayout::Stereo.channel_count(), 2);
125 assert_eq!(ChannelLayout::Surround51.channel_count(), 6);
126 assert_eq!(ChannelLayout::Surround71.channel_count(), 8);
127 assert_eq!(ChannelLayout::AmbisonicFoa.channel_count(), 4);
128 assert_eq!(ChannelLayout::AmbisonicSoa.channel_count(), 9);
129 assert_eq!(ChannelLayout::AmbisonicToa.channel_count(), 16);
130 assert_eq!(ChannelLayout::Custom(12).channel_count(), 12);
131 }
132
133 #[test]
134 fn channel_layout_is_ambisonic() {
135 assert!(!ChannelLayout::Mono.is_ambisonic());
136 assert!(!ChannelLayout::Stereo.is_ambisonic());
137 assert!(!ChannelLayout::Surround51.is_ambisonic());
138 assert!(!ChannelLayout::Surround71.is_ambisonic());
139 assert!(ChannelLayout::AmbisonicFoa.is_ambisonic());
140 assert!(ChannelLayout::AmbisonicSoa.is_ambisonic());
141 assert!(ChannelLayout::AmbisonicToa.is_ambisonic());
142 assert!(!ChannelLayout::Custom(4).is_ambisonic());
143 }
144
145 #[test]
146 fn channel_layout_ambisonic_order() {
147 assert_eq!(ChannelLayout::Mono.ambisonic_order(), None);
148 assert_eq!(ChannelLayout::Stereo.ambisonic_order(), None);
149 assert_eq!(ChannelLayout::AmbisonicFoa.ambisonic_order(), Some(1));
150 assert_eq!(ChannelLayout::AmbisonicSoa.ambisonic_order(), Some(2));
151 assert_eq!(ChannelLayout::AmbisonicToa.ambisonic_order(), Some(3));
152 }
153
154 #[test]
155 fn channel_layout_from_ambisonic_order() {
156 assert_eq!(ChannelLayout::from_ambisonic_order(0), None);
157 assert_eq!(
158 ChannelLayout::from_ambisonic_order(1),
159 Some(ChannelLayout::AmbisonicFoa)
160 );
161 assert_eq!(
162 ChannelLayout::from_ambisonic_order(2),
163 Some(ChannelLayout::AmbisonicSoa)
164 );
165 assert_eq!(
166 ChannelLayout::from_ambisonic_order(3),
167 Some(ChannelLayout::AmbisonicToa)
168 );
169 assert_eq!(ChannelLayout::from_ambisonic_order(4), None);
170 }
171
172 #[test]
173 fn channel_layout_ambisonic_channel_count() {
174 assert_eq!(ChannelLayout::ambisonic_channel_count(1), 4);
175 assert_eq!(ChannelLayout::ambisonic_channel_count(2), 9);
176 assert_eq!(ChannelLayout::ambisonic_channel_count(3), 16);
177 }
178
179 #[test]
180 fn channel_layout_default() {
181 assert_eq!(ChannelLayout::default(), ChannelLayout::Stereo);
182 }
183
184 #[test]
185 fn channel_config_default() {
186 assert_eq!(ChannelConfig::default(), ChannelConfig::Parallel);
187 }
188}