storm/audio/loaders/
flac.rs1use crate::audio::sound::{Sound, SoundError};
2use alloc::vec::Vec;
3use claxon::{Error as ClaxonError, FlacReader};
4
5pub fn read_flac(bytes: &[u8]) -> Result<Sound, SoundError> {
7 let mut reader = FlacReader::new(bytes).map_err(map)?;
8 let mut buffer = if let Some(samples) = reader.streaminfo().samples {
9 Vec::with_capacity(samples as usize)
10 } else {
11 Vec::new()
12 };
13 let scale = (1 << reader.streaminfo().bits_per_sample) / 2;
14 let scale = 1.0 / scale as f32;
15 match reader.streaminfo().channels {
16 1 => {
17 for sample in reader.samples() {
18 let x = sample.unwrap() as f32 * scale;
19 buffer.push([x, x]);
20 }
21 }
22 2 => {
23 let mut iter = reader.samples();
24 while let Some(sample) = iter.next() {
25 let x = sample.unwrap() as f32 * scale;
26 let y = iter.next().unwrap().unwrap() as f32 * scale;
27 buffer.push([x, y]);
28 }
29 }
30 _ => return Err(SoundError::UnsupportedChannelCount),
31 }
32 Sound::new(reader.streaminfo().sample_rate, buffer)
33}
34
35fn map(error: ClaxonError) -> SoundError {
36 match error {
37 ClaxonError::IoError(_) => SoundError::InvalidFormat,
38 ClaxonError::FormatError(_) => SoundError::InvalidFormat,
39 ClaxonError::Unsupported(_) => SoundError::UnsupportedFeature,
40 }
41}