xsynth_core/soundfont/
audio.rs1use std::{fs::File, io, path::PathBuf, sync::Arc};
2
3use symphonia::core::formats::FormatOptions;
4use symphonia::core::{audio::AudioBuffer, conv::IntoSample, probe::Hint, sample::Sample};
5use symphonia::core::{audio::AudioBufferRef, meta::MetadataOptions};
6use symphonia::core::{audio::Signal, io::MediaSourceStream};
7use symphonia::core::{codecs::DecoderOptions, errors::Error};
8
9use crate::{AudioStreamParams, ChannelCount};
10use thiserror::Error;
11use xsynth_soundfonts::resample::resample_vecs;
12
13#[derive(Debug, Error)]
15pub enum AudioLoadError {
16 #[error("IO Error")]
17 IOError(#[from] io::Error),
18
19 #[error("Audio decoding failed for {0}")]
20 AudioDecodingFailed(PathBuf, Error),
21
22 #[error("Audio file {0} has an invalid channel count")]
23 InvalidChannelCount(PathBuf),
24
25 #[error("Audio file {0} has no tracks")]
26 NoTracks(PathBuf),
27}
28
29type ProcessedSample = (Arc<[Arc<[f32]>]>, u32);
30
31pub(super) fn load_audio_file(
32 path: &PathBuf,
33 stream_params: AudioStreamParams,
34) -> Result<ProcessedSample, AudioLoadError> {
35 let new_sample_rate = stream_params.sample_rate as f32;
36
37 let extension = path.extension().and_then(|ext| ext.to_str());
38
39 let file = Box::new(File::open(path)?);
40
41 let mss = MediaSourceStream::new(file, Default::default());
43
44 let mut hint = Hint::new();
46 if let Some(extension) = extension {
47 hint.with_extension(extension);
48 }
49
50 let format_opts: FormatOptions = Default::default();
52 let metadata_opts: MetadataOptions = Default::default();
53 let decoder_opts: DecoderOptions = Default::default();
54
55 let probed = symphonia::default::get_probe()
57 .format(&hint, mss, &format_opts, &metadata_opts)
58 .map_err(|x| AudioLoadError::AudioDecodingFailed(path.clone(), x))?;
59
60 let mut format = probed.format;
62
63 let track = format
65 .default_track()
66 .ok_or_else(|| AudioLoadError::NoTracks(path.clone()))?;
67
68 let sample_rate = track.codec_params.sample_rate.unwrap_or(44100);
69 let channel_count = track.codec_params.channels.map(|c| c.count()).unwrap_or(1);
70
71 let mut decoder = symphonia::default::get_codecs()
73 .make(&track.codec_params, &decoder_opts)
74 .map_err(|x| AudioLoadError::AudioDecodingFailed(path.clone(), x))?;
75
76 let track_id = track.id;
78
79 let mut builder = BuilderVecs::new(channel_count);
81
82 loop {
83 let packet = match format.next_packet() {
85 Err(symphonia::core::errors::Error::IoError(error))
86 if error.kind() == std::io::ErrorKind::UnexpectedEof =>
87 {
88 break;
90 }
91 Err(error) => return Err(AudioLoadError::AudioDecodingFailed(path.clone(), error)),
92 Ok(packet) => packet,
93 };
94
95 if packet.track_id() != track_id {
97 continue;
98 }
99
100 match decoder.decode(&packet) {
102 Ok(audio_buf) => {
103 builder.push(audio_buf);
104 }
105
106 Err(Error::DecodeError(_)) => (),
107 Err(e) => return Err(AudioLoadError::AudioDecodingFailed(path.clone(), e)),
108 }
109 }
110
111 let built = builder.finish(sample_rate as f32, new_sample_rate, stream_params.channels);
112
113 Ok((built, sample_rate))
114}
115
116struct BuilderVecs {
117 vecs: Vec<Vec<f32>>,
118}
119
120impl BuilderVecs {
121 fn new(channels: usize) -> Self {
122 let mut vecs = Vec::new();
123 for _ in 0..channels {
124 vecs.push(Vec::new());
125 }
126
127 Self { vecs }
128 }
129
130 fn push(&mut self, buffer: AudioBufferRef) {
131 match buffer {
132 AudioBufferRef::U8(buf) => self.push_buffer(&buf),
133 AudioBufferRef::U16(buf) => self.push_buffer(&buf),
134 AudioBufferRef::U24(buf) => self.push_buffer(&buf),
135 AudioBufferRef::U32(buf) => self.push_buffer(&buf),
136 AudioBufferRef::S8(buf) => self.push_buffer(&buf),
137 AudioBufferRef::S16(buf) => self.push_buffer(&buf),
138 AudioBufferRef::S24(buf) => self.push_buffer(&buf),
139 AudioBufferRef::S32(buf) => self.push_buffer(&buf),
140 AudioBufferRef::F32(buf) => self.push_buffer(&buf),
141 AudioBufferRef::F64(buf) => self.push_buffer(&buf),
142 }
143 }
144
145 fn push_buffer(&mut self, buffer: &AudioBuffer<impl Sample + IntoSample<f32>>) {
146 let channels = buffer.spec().channels.count();
147
148 for c in 0..channels {
149 let channel = buffer.chan(c);
150 self.vecs[c].reserve(channel.len());
151 for &sample in channel.iter() {
152 self.vecs[c].push(sample.into_sample());
153 }
154 }
155 }
156
157 fn finish(
158 self,
159 sample_rate: f32,
160 new_sample_rate: f32,
161 channels: ChannelCount,
162 ) -> Arc<[Arc<[f32]>]> {
163 let mut vecs = self.vecs;
164
165 if channels == ChannelCount::Mono && vecs.len() >= 2 {
166 let right = vecs.pop().unwrap_or_default();
167 let left = vecs.pop().unwrap_or_default();
168
169 let combined: Vec<f32> = left
170 .iter()
171 .zip(right.iter())
172 .map(|(&l, &r)| (l + r) * 0.5)
173 .collect();
174 vecs.push(combined);
175 }
176
177 for chan in vecs.iter_mut() {
178 chan.shrink_to_fit();
179 }
180
181 resample_vecs(vecs, sample_rate, new_sample_rate)
182 }
183}