audio: Removed unwraps in mixer.rs and replaced with reasoned expects

This commit is contained in:
Nathan Adams 2022-12-30 23:30:00 +01:00
parent 7a9e8b4771
commit 3b24d849e7
2 changed files with 61 additions and 20 deletions

View File

@ -307,8 +307,9 @@ impl Iterator for StreamTagReader {
// RESEARCHME: How does Flash Player actually determine when there is an audio gap or not? // RESEARCHME: How does Flash Player actually determine when there is an audio gap or not?
// If an MP3 audio track has gaps, Flash Player will often play it out of sync (too early). // If an MP3 audio track has gaps, Flash Player will often play it out of sync (too early).
// Seems closely related to `stream_info.num_samples_per_block`. // Seems closely related to `stream_info.num_samples_per_block`.
let num_samples = let num_samples = u16::from_le_bytes(
u16::from_le_bytes(audio_block[..2].try_into().unwrap()); audio_block[..2].try_into().expect("2 bytes fit into a u16"),
);
self.mp3_samples_buffered += i32::from(num_samples); self.mp3_samples_buffered += i32::from(num_samples);
audio_block = &audio_block[4..]; audio_block = &audio_block[4..];
} }

View File

@ -33,9 +33,13 @@ impl CircBuf {
/// being written to. /// being written to.
pub fn get(&self) -> &[[f32; 2]; 1024] { pub fn get(&self) -> &[[f32; 2]; 1024] {
if self.pos < 1024 { if self.pos < 1024 {
self.samples[1024..2048].try_into().unwrap() self.samples[1024..2048]
.try_into()
.expect("Length is 1024, cast is infallible")
} else { } else {
self.samples[0..1024].try_into().unwrap() self.samples[0..1024]
.try_into()
.expect("Length is 1024, cast is infallible")
} }
} }
} }
@ -263,9 +267,15 @@ impl AudioMixer {
+ dasp::sample::ToSample<f32> + dasp::sample::ToSample<f32>
+ dasp::sample::FromSample<i16>, + dasp::sample::FromSample<i16>,
{ {
let mut sound_instances = self.sound_instances.lock().unwrap(); let mut sound_instances = self
let volume = *self.volume.read().unwrap(); .sound_instances
let mut output_memory = self.output_memory.write().unwrap(); .lock()
.expect("Cannot be called reentrant");
let volume = *self.volume.read().expect("Cannot be called reentrant");
let mut output_memory = self
.output_memory
.write()
.expect("Cannot be called reentrant");
Self::mix_audio::<T>( Self::mix_audio::<T>(
&mut sound_instances, &mut sound_instances,
volume, volume,
@ -468,7 +478,10 @@ impl AudioMixer {
} }
pub fn get_sample_history(&self) -> [[f32; 2]; 1024] { pub fn get_sample_history(&self) -> [[f32; 2]; 1024] {
let output_memory = self.output_memory.read().unwrap(); let output_memory = self
.output_memory
.read()
.expect("Cannot be called reentrant");
*output_memory.get() *output_memory.get()
} }
@ -533,7 +546,10 @@ impl AudioMixer {
// feed the decoder audio data on the fly. // feed the decoder audio data on the fly.
let stream = self.make_stream_from_swf_slice(stream_info, clip_data)?; let stream = self.make_stream_from_swf_slice(stream_info, clip_data)?;
let mut sound_instances = self.sound_instances.lock().unwrap(); let mut sound_instances = self
.sound_instances
.lock()
.expect("Cannot be called reentrant");
let handle = sound_instances.insert(SoundInstance::new_stream(stream)); let handle = sound_instances.insert(SoundInstance::new_stream(stream));
Ok(handle) Ok(handle)
} }
@ -563,19 +579,28 @@ impl AudioMixer {
}; };
// Add sound instance to active list. // Add sound instance to active list.
let mut sound_instances = self.sound_instances.lock().unwrap(); let mut sound_instances = self
.sound_instances
.lock()
.expect("Cannot be called reentrant");
let handle = sound_instances.insert(SoundInstance::new_sound(sound_handle, stream)); let handle = sound_instances.insert(SoundInstance::new_sound(sound_handle, stream));
Ok(handle) Ok(handle)
} }
/// Stops a playing sound instance. /// Stops a playing sound instance.
pub fn stop_sound(&mut self, sound: SoundInstanceHandle) { pub fn stop_sound(&mut self, sound: SoundInstanceHandle) {
let mut sound_instances = self.sound_instances.lock().unwrap(); let mut sound_instances = self
.sound_instances
.lock()
.expect("Cannot be called reentrant");
sound_instances.remove(sound); sound_instances.remove(sound);
} }
pub fn stop_all_sounds(&mut self) { pub fn stop_all_sounds(&mut self) {
let mut sound_instances = self.sound_instances.lock().unwrap(); let mut sound_instances = self
.sound_instances
.lock()
.expect("Cannot be called reentrant");
// This is a workaround for a bug in generational-arena: // This is a workaround for a bug in generational-arena:
// Arena::clear does not properly bump the generational index, allowing for stale references // Arena::clear does not properly bump the generational index, allowing for stale references
// to continue to work (this caused #1315). Arena::remove will force a generation bump. // to continue to work (this caused #1315). Arena::remove will force a generation bump.
@ -590,7 +615,10 @@ impl AudioMixer {
/// ///
////// Returns `None` if the sound is no longer playing. ////// Returns `None` if the sound is no longer playing.
pub fn get_sound_position(&self, instance: SoundInstanceHandle) -> Option<f64> { pub fn get_sound_position(&self, instance: SoundInstanceHandle) -> Option<f64> {
let sound_instances = self.sound_instances.lock().unwrap(); let sound_instances = self
.sound_instances
.lock()
.expect("Cannot be called reentrant");
sound_instances.get(instance).map(|instance| { sound_instances.get(instance).map(|instance| {
// Get the current sample position from the underlying audio source. // Get the current sample position from the underlying audio source.
let num_sample_frames: f64 = instance.stream.source_position().into(); let num_sample_frames: f64 = instance.stream.source_position().into();
@ -600,7 +628,10 @@ impl AudioMixer {
} }
pub fn get_sound_peak(&self, instance: SoundInstanceHandle) -> Option<[f32; 2]> { pub fn get_sound_peak(&self, instance: SoundInstanceHandle) -> Option<[f32; 2]> {
let sound_instances = self.sound_instances.lock().unwrap(); let sound_instances = self
.sound_instances
.lock()
.expect("Cannot be called reentrant");
sound_instances.get(instance).map(|instance| instance.peak) sound_instances.get(instance).map(|instance| instance.peak)
} }
@ -633,7 +664,10 @@ impl AudioMixer {
instance: SoundInstanceHandle, instance: SoundInstanceHandle,
transform: SoundTransform, transform: SoundTransform,
) { ) {
let mut sound_instances = self.sound_instances.lock().unwrap(); let mut sound_instances = self
.sound_instances
.lock()
.expect("Cannot be called reentrant");
if let Some(instance) = sound_instances.get_mut(instance) { if let Some(instance) = sound_instances.get_mut(instance) {
instance.left_transform = [transform.left_to_left, transform.right_to_left]; instance.left_transform = [transform.left_to_left, transform.right_to_left];
instance.right_transform = [transform.left_to_right, transform.right_to_right]; instance.right_transform = [transform.left_to_right, transform.right_to_right];
@ -641,11 +675,11 @@ impl AudioMixer {
} }
pub fn volume(&self) -> f32 { pub fn volume(&self) -> f32 {
*self.volume.read().unwrap() *self.volume.read().expect("Cannot be called reentrant")
} }
pub fn set_volume(&mut self, volume: f32) { pub fn set_volume(&mut self, volume: f32) {
*self.volume.write().unwrap() = volume *self.volume.write().expect("Cannot be called reentrant") = volume
} }
} }
@ -679,9 +713,15 @@ impl AudioMixerProxy {
+ dasp::sample::ToSample<f32> + dasp::sample::ToSample<f32>
+ dasp::sample::FromSample<i16>, + dasp::sample::FromSample<i16>,
{ {
let mut sound_instances = self.sound_instances.lock().unwrap(); let mut sound_instances = self
let volume = *self.volume.read().unwrap(); .sound_instances
let mut output_memory = self.output_memory.write().unwrap(); .lock()
.expect("Cannot be called reentrant");
let volume = *self.volume.read().expect("Cannot be called reentrant");
let mut output_memory = self
.output_memory
.write()
.expect("Cannot be called reentrant");
AudioMixer::mix_audio::<T>( AudioMixer::mix_audio::<T>(
&mut sound_instances, &mut sound_instances,
volume, volume,