1extern crate alloc;
2
3use alloc::vec::Vec;
4
5#[derive(Debug, Clone, PartialEq)]
24pub struct Chunk {
25 data: Vec<f32>,
26 sample_rate: u32,
27 channels: u16,
28}
29
30impl Chunk {
31 #[must_use]
37 pub fn new(data: Vec<f32>, sample_rate: u32, channels: u16) -> Self {
38 assert!(channels > 0, "channels must be > 0");
39 assert!(sample_rate > 0, "sample_rate must be > 0");
40 Self {
41 data,
42 sample_rate,
43 channels,
44 }
45 }
46
47 #[must_use]
53 pub fn empty(sample_rate: u32, channels: u16) -> Self {
54 Self::new(Vec::new(), sample_rate, channels)
55 }
56
57 #[inline]
59 #[must_use]
60 pub fn data(&self) -> &[f32] {
61 &self.data
62 }
63
64 #[inline]
66 pub fn data_mut(&mut self) -> &mut [f32] {
67 &mut self.data
68 }
69
70 #[inline]
72 #[must_use]
73 pub fn into_data(self) -> Vec<f32> {
74 self.data
75 }
76
77 #[doc(hidden)]
79 #[inline]
80 pub fn set_data(&mut self, data: Vec<f32>) {
81 self.data = data;
82 }
83
84 #[inline]
86 #[must_use]
87 pub fn sample_rate(&self) -> u32 {
88 self.sample_rate
89 }
90
91 #[inline]
93 #[must_use]
94 pub fn channels(&self) -> u16 {
95 self.channels
96 }
97
98 #[inline]
100 #[must_use]
101 pub fn frames(&self) -> usize {
102 if self.channels == 0 {
103 return 0;
104 }
105 self.data.len() / self.channels as usize
106 }
107
108 #[inline]
110 #[must_use]
111 pub fn is_empty(&self) -> bool {
112 self.data.is_empty()
113 }
114
115 #[inline]
117 #[must_use]
118 pub fn len(&self) -> usize {
119 self.data.len()
120 }
121}
122
123#[cfg(test)]
124mod tests {
125 use super::*;
126
127 #[test]
128 fn new_mono_chunk() {
129 let chunk = Chunk::new(vec![1.0, 2.0, 3.0, 4.0], 44100, 1);
130 assert_eq!(chunk.frames(), 4);
131 assert_eq!(chunk.len(), 4);
132 assert_eq!(chunk.channels(), 1);
133 assert_eq!(chunk.sample_rate(), 44100);
134 assert!(!chunk.is_empty());
135 }
136
137 #[test]
138 fn new_stereo_chunk() {
139 let chunk = Chunk::new(vec![1.0, 2.0, 3.0, 4.0], 48000, 2);
140 assert_eq!(chunk.frames(), 2);
141 assert_eq!(chunk.len(), 4);
142 assert_eq!(chunk.channels(), 2);
143 }
144
145 #[test]
146 fn empty_chunk() {
147 let chunk = Chunk::empty(44100, 1);
148 assert!(chunk.is_empty());
149 assert_eq!(chunk.frames(), 0);
150 assert_eq!(chunk.len(), 0);
151 }
152
153 #[test]
154 fn data_access() {
155 let chunk = Chunk::new(vec![0.5, -0.5], 44100, 1);
156 assert_eq!(chunk.data(), &[0.5, -0.5]);
157 }
158
159 #[test]
160 fn data_mut_allows_modification() {
161 let mut chunk = Chunk::new(vec![0.0; 4], 44100, 1);
162 chunk.data_mut()[0] = 1.0;
163 assert_eq!(chunk.data()[0], 1.0);
164 }
165
166 #[test]
167 fn into_data_returns_buffer() {
168 let chunk = Chunk::new(vec![1.0, 2.0], 44100, 1);
169 let data = chunk.into_data();
170 assert_eq!(data, vec![1.0, 2.0]);
171 }
172
173 #[test]
174 fn set_data_replaces_buffer() {
175 let mut chunk = Chunk::new(vec![1.0], 44100, 1);
176 chunk.set_data(vec![2.0, 3.0]);
177 assert_eq!(chunk.data(), &[2.0, 3.0]);
178 assert_eq!(chunk.frames(), 2);
179 }
180
181 #[test]
182 fn clone_and_eq() {
183 let a = Chunk::new(vec![1.0, 2.0], 44100, 2);
184 let b = a.clone();
185 assert_eq!(a, b);
186 }
187
188 #[test]
189 #[should_panic(expected = "channels must be > 0")]
190 fn zero_channels_panics() {
191 let _ = Chunk::new(vec![1.0], 44100, 0);
192 }
193
194 #[test]
195 #[should_panic(expected = "sample_rate must be > 0")]
196 fn zero_sample_rate_panics() {
197 let _ = Chunk::new(vec![1.0], 0, 1);
198 }
199}