libflo_audio/streaming/
encoder.rs1use crate::core::{ChannelData, FloResult, FrameType, ResidualEncoding};
2use crate::lossless::Encoder;
3use crate::{compute_crc32, Reader, MAGIC};
4use alloc::vec;
5use alloc::vec::Vec;
6
7pub struct StreamingEncoder {
8 sample_rate: u32,
9 channels: u8,
10 bit_depth: u8,
11 compression_level: u8,
12 sample_buffer: Vec<f32>,
13 samples_per_frame: usize,
14 pending_frames: Vec<EncodedFrame>,
15 encoder: Encoder,
16 total_samples: u64,
17 frame_index: u32,
18}
19
20#[derive(Debug, Clone)]
22pub struct EncodedFrame {
23 pub index: u32,
25 pub timestamp_ms: u32,
27 pub data: Vec<u8>,
29 pub samples: u32,
31}
32
33impl StreamingEncoder {
34 pub fn new(sample_rate: u32, channels: u8, bit_depth: u8) -> Self {
36 let samples_per_frame = sample_rate as usize;
37
38 Self {
39 sample_rate,
40 channels,
41 bit_depth,
42 compression_level: 5,
43 sample_buffer: Vec::with_capacity(samples_per_frame * channels as usize * 2),
44 samples_per_frame,
45 pending_frames: Vec::new(),
46 encoder: Encoder::new(sample_rate, channels, bit_depth),
47 total_samples: 0,
48 frame_index: 0,
49 }
50 }
51
52 pub fn with_compression(mut self, level: u8) -> Self {
54 self.compression_level = level.min(9);
55 self.encoder =
56 Encoder::new(self.sample_rate, self.channels, self.bit_depth).with_compression(level);
57 self
58 }
59
60 pub fn pending_samples(&self) -> usize {
62 self.sample_buffer.len() / self.channels as usize
63 }
64
65 pub fn pending_frames(&self) -> usize {
67 self.pending_frames.len()
68 }
69
70 pub fn push_samples(&mut self, samples: &[f32]) -> FloResult<()> {
74 self.sample_buffer.extend_from_slice(samples);
75 self.try_encode_frames()?;
76 Ok(())
77 }
78
79 pub fn next_frame(&mut self) -> Option<EncodedFrame> {
81 if self.pending_frames.is_empty() {
82 None
83 } else {
84 Some(self.pending_frames.remove(0))
85 }
86 }
87
88 pub fn flush(&mut self) -> FloResult<Option<EncodedFrame>> {
90 if self.sample_buffer.is_empty() {
91 return Ok(None);
92 }
93
94 let samples_per_channel = self.sample_buffer.len() / self.channels as usize;
95 let timestamp_ms = (self.total_samples as f64 / self.sample_rate as f64 * 1000.0) as u32;
96
97 let frame_data = self.encode_frame_data(&self.sample_buffer)?;
98
99 let encoded = EncodedFrame {
100 index: self.frame_index,
101 timestamp_ms,
102 data: frame_data,
103 samples: samples_per_channel as u32,
104 };
105
106 self.total_samples += samples_per_channel as u64;
107 self.frame_index += 1;
108 self.sample_buffer.clear();
109
110 Ok(Some(encoded))
111 }
112
113 pub fn flush_into_frames(&mut self) -> FloResult<usize> {
117 if let Some(frame) = self.flush()? {
118 self.pending_frames.push(frame);
119 }
120 Ok(self.pending_frames.len())
121 }
122
123 pub fn finalize(&mut self, metadata: &[u8]) -> FloResult<Vec<u8>> {
125 if let Some(frame) = self.flush()? {
126 self.pending_frames.push(frame);
127 }
128
129 let mut toc_data = Vec::new();
131 let num_frames = self.pending_frames.len() as u32;
132 toc_data.extend_from_slice(&num_frames.to_le_bytes());
133
134 let mut byte_offset: u64 = 0;
135 for frame in &self.pending_frames {
136 toc_data.extend_from_slice(&frame.index.to_le_bytes());
137 toc_data.extend_from_slice(&byte_offset.to_le_bytes());
138 toc_data.extend_from_slice(&(frame.data.len() as u32).to_le_bytes());
139 toc_data.extend_from_slice(&frame.timestamp_ms.to_le_bytes());
140 byte_offset += frame.data.len() as u64;
141 }
142
143 let mut data_chunk = Vec::new();
145 for frame in &self.pending_frames {
146 data_chunk.extend_from_slice(&frame.data);
147 }
148
149 let data_crc32 = compute_crc32(&data_chunk);
150
151 let header_size: u64 = 66;
152 let toc_size = toc_data.len() as u64;
153 let data_size = data_chunk.len() as u64;
154 let extra_size: u64 = 0;
155 let meta_size = metadata.len() as u64;
156
157 let mut output = Vec::new();
158
159 output.extend_from_slice(&MAGIC);
161
162 output.push(1); output.push(2); output.extend_from_slice(&0u16.to_le_bytes()); output.extend_from_slice(&self.sample_rate.to_le_bytes());
167 output.push(self.channels);
168 output.push(self.bit_depth);
169 let total_samples: u64 = self
171 .pending_frames
172 .iter()
173 .map(|frame| frame.samples as u64)
174 .sum();
175 output.extend_from_slice(&total_samples.to_le_bytes());
176 output.push(self.compression_level);
177 output.extend_from_slice(&[0u8; 3]); output.extend_from_slice(&data_crc32.to_le_bytes());
179 output.extend_from_slice(&header_size.to_le_bytes());
180 output.extend_from_slice(&toc_size.to_le_bytes());
181 output.extend_from_slice(&data_size.to_le_bytes());
182 output.extend_from_slice(&extra_size.to_le_bytes());
183 output.extend_from_slice(&meta_size.to_le_bytes());
184
185 output.extend_from_slice(&toc_data);
187
188 output.extend_from_slice(&data_chunk);
190
191 output.extend_from_slice(metadata);
193
194 self.pending_frames.clear();
195
196 Ok(output)
197 }
198
199 fn try_encode_frames(&mut self) -> FloResult<()> {
204 let frame_samples = self.samples_per_frame * self.channels as usize;
205
206 while self.sample_buffer.len() >= frame_samples {
207 let frame_data: Vec<f32> = self.sample_buffer.drain(..frame_samples).collect();
208 let timestamp_ms =
209 (self.total_samples as f64 / self.sample_rate as f64 * 1000.0) as u32;
210
211 let encoded_data = self.encode_frame_data(&frame_data)?;
212
213 self.pending_frames.push(EncodedFrame {
214 index: self.frame_index,
215 timestamp_ms,
216 data: encoded_data,
217 samples: self.samples_per_frame as u32,
218 });
219
220 self.total_samples += self.samples_per_frame as u64;
221 self.frame_index += 1;
222 }
223
224 Ok(())
225 }
226
227 fn encode_frame_data(&self, samples: &[f32]) -> FloResult<Vec<u8>> {
228 let temp_flo = self.encoder.encode(samples, &[])?;
229
230 let reader = Reader::new();
231 let file = reader.read(&temp_flo)?;
232
233 if file.frames.is_empty() {
234 return Err("No frames encoded".into());
235 }
236
237 let frame = &file.frames[0];
238 let mut data = Vec::new();
239
240 data.push(frame.frame_type);
242 data.extend_from_slice(&frame.frame_samples.to_le_bytes());
243 data.push(frame.flags);
244
245 for ch in &frame.channels {
247 let ch_data = self.serialize_channel(ch, FrameType::from(frame.frame_type));
248 data.extend_from_slice(&(ch_data.len() as u32).to_le_bytes());
249 data.extend_from_slice(&ch_data);
250 }
251
252 Ok(data)
253 }
254
255 fn serialize_channel(&self, ch: &ChannelData, frame_type: FrameType) -> Vec<u8> {
256 match frame_type {
257 FrameType::Silence => vec![],
258 FrameType::Raw | FrameType::Transform => ch.residuals.clone(),
259 _ => {
260 let mut data = Vec::new();
262 data.push(ch.predictor_coeffs.len() as u8);
263 for &coeff in &ch.predictor_coeffs {
264 data.extend_from_slice(&coeff.to_le_bytes());
265 }
266 data.push(ch.shift_bits);
267 data.push(ch.residual_encoding as u8);
268 if ch.residual_encoding == ResidualEncoding::Rice {
269 data.push(ch.rice_parameter);
270 }
271 data.extend_from_slice(&ch.residuals);
272 data
273 }
274 }
275 }
276}