storm/audio/loaders/
flac.rs

1use crate::audio::sound::{Sound, SoundError};
2use alloc::vec::Vec;
3use claxon::{Error as ClaxonError, FlacReader};
4
5/// Interpret a slice of bytes as a FLAC file and decodes it into a sound.
6pub 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}