aboutsummaryrefslogtreecommitdiffstats
path: root/src/audio.rs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/audio.rs97
1 files changed, 53 insertions, 44 deletions
diff --git a/src/audio.rs b/src/audio.rs
index 62afd93..62d13ff 100644
--- a/src/audio.rs
+++ b/src/audio.rs
@@ -101,7 +101,7 @@ impl AudioEngine {
101 101
102struct AudioData { 102struct AudioData {
103 format: Box<dyn symphonia::core::formats::FormatReader>, 103 format: Box<dyn symphonia::core::formats::FormatReader>,
104 decoder: Box<dyn symphonia::core::codecs::Decoder>, 104 decoder: Box<dyn symphonia::core::codecs::audio::AudioDecoder>,
105 sample_rate: u32, 105 sample_rate: u32,
106 channels: u16, 106 channels: u16,
107 sample_buffer: Vec<f32>, 107 sample_buffer: Vec<f32>,
@@ -165,10 +165,10 @@ fn audio_thread(
165 165
166 let device_sample_rate = config.sample_rate(); 166 let device_sample_rate = config.sample_rate();
167 let channels = config.channels(); 167 let channels = config.channels();
168 eprintln!( 168 crate::debug_eprintln(format_args!(
169 "Default output: {} Hz, {} channels", 169 "Default output: {} Hz, {} channels",
170 device_sample_rate, channels 170 device_sample_rate, channels
171 ); 171 ));
172 172
173 let mut current_stream: Option<cpal::Stream> = None; 173 let mut current_stream: Option<cpal::Stream> = None;
174 let audio_data: Arc<Mutex<Option<AudioData>>> = Arc::new(Mutex::new(None)); 174 let audio_data: Arc<Mutex<Option<AudioData>>> = Arc::new(Mutex::new(None));
@@ -186,13 +186,16 @@ fn audio_thread(
186 186
187 match open_audio_file(&path) { 187 match open_audio_file(&path) {
188 Ok(mut data) => { 188 Ok(mut data) => {
189 eprintln!("File: {} Hz, {} channels", data.sample_rate, data.channels); 189 crate::debug_eprintln(format_args!(
190 "File: {} Hz, {} channels",
191 data.sample_rate, data.channels
192 ));
190 193
191 if data.sample_rate != device_sample_rate { 194 if data.sample_rate != device_sample_rate {
192 eprintln!( 195 crate::debug_eprintln(format_args!(
193 "Resampling from {} Hz to {} Hz", 196 "Resampling from {} Hz to {} Hz",
194 data.sample_rate, device_sample_rate 197 data.sample_rate, device_sample_rate
195 ); 198 ));
196 data.resample_ratio = 199 data.resample_ratio =
197 Some(device_sample_rate as f64 / data.sample_rate as f64); 200 Some(device_sample_rate as f64 / data.sample_rate as f64);
198 } 201 }
@@ -201,28 +204,23 @@ fn audio_thread(
201 let channels = data.channels as usize; 204 let channels = data.channels as usize;
202 for _ in 0..100 { 205 for _ in 0..100 {
203 match data.format.next_packet() { 206 match data.format.next_packet() {
204 Ok(packet) => match data.decoder.decode(&packet) { 207 Ok(Some(packet)) => match data.decoder.decode(&packet) {
205 Ok(decoded) => { 208 Ok(decoded) => {
206 let spec = *decoded.spec(); 209 let num_samples = decoded.samples_interleaved();
207 let mut sample_buf = symphonia::core::audio::SampleBuffer::< 210 let mut samples = vec![0.0f32; num_samples];
208 f32, 211 decoded.copy_to_slice_interleaved(&mut samples);
209 >::new(
210 decoded.capacity() as u64, spec
211 );
212 sample_buf.copy_interleaved_ref(decoded);
213 let samples = sample_buf.samples();
214 212
215 let resampled = if let Some(ratio) = data.resample_ratio { 213 let resampled = if let Some(ratio) = data.resample_ratio {
216 resample_linear(samples, ratio, channels) 214 resample_linear(&samples, ratio, channels)
217 } else { 215 } else {
218 samples.to_vec() 216 samples
219 }; 217 };
220 218
221 data.sample_buffer.extend(resampled); 219 data.sample_buffer.extend(resampled);
222 } 220 }
223 Err(_) => break, 221 Err(_) => break,
224 }, 222 },
225 Err(_) => break, 223 _ => break,
226 } 224 }
227 } 225 }
228 data.buffer_pos = 0; 226 data.buffer_pos = 0;
@@ -274,29 +272,26 @@ fn audio_thread(
274 272
275 // Decode more data 273 // Decode more data
276 match state.format.next_packet() { 274 match state.format.next_packet() {
277 Ok(packet) => { 275 Ok(Some(packet)) => {
278 match state.decoder.decode(&packet) { 276 match state.decoder.decode(&packet) {
279 Ok(decoded) => { 277 Ok(decoded) => {
280 let spec = *decoded.spec(); 278 let num_samples =
281 let mut sample_buf = 279 decoded.samples_interleaved();
282 symphonia::core::audio::SampleBuffer::< 280 let mut samples =
283 f32, 281 vec![0.0f32; num_samples];
284 >::new( 282 decoded.copy_to_slice_interleaved(
285 decoded.capacity() as u64, spec 283 &mut samples,
286 ); 284 );
287 sample_buf
288 .copy_interleaved_ref(decoded);
289 let samples = sample_buf.samples();
290 285
291 // Resample if needed 286 // Resample if needed
292 let resampled = if let Some(ratio) = 287 let resampled = if let Some(ratio) =
293 state.resample_ratio 288 state.resample_ratio
294 { 289 {
295 resample_linear( 290 resample_linear(
296 samples, ratio, channels, 291 &samples, ratio, channels,
297 ) 292 )
298 } else { 293 } else {
299 samples.to_vec() 294 samples
300 }; 295 };
301 296
302 // Copy what we can to output 297 // Copy what we can to output
@@ -323,7 +318,7 @@ fn audio_thread(
323 Err(_) => break, 318 Err(_) => break,
324 } 319 }
325 } 320 }
326 Err(_) => break, 321 _ => break,
327 } 322 }
328 } 323 }
329 324
@@ -419,36 +414,50 @@ fn audio_thread(
419} 414}
420 415
421fn open_audio_file(path: &PathBuf) -> Result<AudioData, Box<dyn std::error::Error>> { 416fn open_audio_file(path: &PathBuf) -> Result<AudioData, Box<dyn std::error::Error>> {
422 use symphonia::core::audio::Channels; 417 use symphonia::core::audio::layouts::CHANNEL_LAYOUT_STEREO;
418 use symphonia::core::codecs::audio::AudioDecoderOptions;
419 use symphonia::core::formats::probe::Hint;
423 use symphonia::core::io::MediaSourceStream; 420 use symphonia::core::io::MediaSourceStream;
424 421
425 let file = std::fs::File::open(path)?; 422 let file = std::fs::File::open(path)?;
426 let mss = MediaSourceStream::new(Box::new(file), Default::default()); 423 let mss = MediaSourceStream::new(Box::new(file), Default::default());
427 424
428 let hint = symphonia::core::probe::Hint::new(); 425 let hint = Hint::new();
429 let probed = symphonia::default::get_probe().format( 426 let format = symphonia::default::get_probe().probe(
430 &hint, 427 &hint,
431 mss, 428 mss,
432 &Default::default(), 429 Default::default(),
433 &Default::default(), 430 Default::default(),
434 )?; 431 )?;
435 432
436 let format = probed.format;
437 let track = format 433 let track = format
438 .tracks() 434 .tracks()
439 .iter() 435 .iter()
440 .find(|t| t.codec_params.sample_rate.is_some()) 436 .find(|t| {
437 t.codec_params
438 .as_ref()
439 .and_then(|p| p.audio())
440 .and_then(|a| a.sample_rate)
441 .is_some()
442 })
441 .ok_or("No suitable track found")?; 443 .ok_or("No suitable track found")?;
442 444
443 let sample_rate = track.codec_params.sample_rate.unwrap_or(44100); 445 let codec_params = track
444 let channels = track
445 .codec_params 446 .codec_params
447 .as_ref()
448 .ok_or("No codec parameters")?
449 .audio()
450 .ok_or("Not an audio track")?;
451
452 let sample_rate = codec_params.sample_rate.unwrap_or(44100);
453 let channels = codec_params
446 .channels 454 .channels
447 .unwrap_or(Channels::FRONT_LEFT | Channels::FRONT_RIGHT) 455 .clone()
456 .unwrap_or(CHANNEL_LAYOUT_STEREO)
448 .count() as u16; 457 .count() as u16;
449 458
450 let decoder = 459 let decoder = symphonia::default::get_codecs()
451 symphonia::default::get_codecs().make(&track.codec_params, &Default::default())?; 460 .make_audio_decoder(codec_params, &AudioDecoderOptions::default())?;
452 461
453 Ok(AudioData { 462 Ok(AudioData {
454 format, 463 format,