euphony_compiler/
buffer.rs

1use crate::{
2    sample::{DefaultRate, DefaultSample, Rate as _},
3    CachedBuffer, Hash, Writer,
4};
5use euphony_buffer::{decode, symphonia};
6use euphony_node::BufferMap;
7use std::{collections::HashMap, fmt, ops, sync::Arc};
8
9#[derive(Debug)]
10pub struct Map {
11    buffers: HashMap<(u64, u64), Buffer>,
12}
13
14impl Map {
15    pub fn new(buffers: HashMap<(u64, u64), Buffer>) -> Self {
16        Self { buffers }
17    }
18}
19
20impl BufferMap for Map {
21    fn get(&self, id: u64, channel: u64) -> euphony_node::Buffer {
22        let buffer = self
23            .buffers
24            .get(&(id, channel))
25            .unwrap_or_else(|| panic!("missing buffer {} channel {}", id, channel));
26        euphony_node::Buffer {
27            samples: buffer,
28            hash: &buffer.hash,
29        }
30    }
31}
32
33pub struct Buffer {
34    samples: Arc<[f64]>,
35    hash: Hash,
36}
37
38impl Buffer {
39    fn open(cached: CachedBuffer) -> std::io::Result<Self> {
40        Ok(Self {
41            samples: cached.samples,
42            hash: cached.hash,
43        })
44    }
45
46    pub(crate) fn load<W: Writer>(
47        id: u64,
48        path: &str,
49        ext: &str,
50        cache: &W,
51    ) -> symphonia::core::errors::Result<Vec<((u64, u64), Self)>> {
52        let paths = cache.buffer::<_, symphonia::core::errors::Error>(
53            path,
54            DefaultRate::COUNT,
55            |reader| {
56                let mut stream = decode::reader(reader, ext)?;
57                let mut samples = decode::Samples::from_reader(&mut *stream)?;
58
59                samples
60                    .resample(DefaultRate::COUNT as _)
61                    .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e))?;
62
63                Ok(samples.channels)
64            },
65        )?;
66
67        Ok(paths
68            .into_iter()
69            .enumerate()
70            .map(|(channel, cached)| {
71                let buf = Buffer::open(cached).unwrap();
72                ((id, channel as u64), buf)
73            })
74            .collect())
75    }
76}
77
78impl fmt::Debug for Buffer {
79    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
80        f.debug_struct("Buffer").field("len", &self.len()).finish()
81    }
82}
83
84impl ops::Deref for Buffer {
85    type Target = [DefaultSample];
86
87    #[inline]
88    fn deref(&self) -> &Self::Target {
89        self.samples.deref()
90    }
91}