WIP messier shit figuring out audio format changing that the sdl2 crate generics currently make impossible

This commit is contained in:
lifning 2021-11-02 23:43:48 -07:00
parent a1e28e9838
commit c505428895
1 changed files with 69 additions and 11 deletions

View File

@ -6,22 +6,75 @@ use std::path::Path;
use core::time::Duration;
use sdl2::Sdl;
use sdl2::audio::{AudioCallback, AudioDevice, AudioFormat, AudioSpec, AudioSpecDesired, AudioCVT, AudioFormatNum};
use sdl2::audio::{AudioCallback, AudioDevice, AudioFormat, AudioSpec, AudioSpecDesired, AudioCVT, AudioFormatNum, AudioQueue};
enum AudioQueueEnum {
U8(AudioQueue<u8>),
S8(AudioQueue<i8>),
U16(AudioQueue<u16>),
S16(AudioQueue<i16>),
S32(AudioQueue<i32>),
F32(AudioQueue<f32>),
}
impl AudioQueueEnum {
fn sample_size(&self) -> usize {
match self {
AudioQueueEnum::U8(_) => size_of::<u8>(),
AudioQueueEnum::S8(_) => size_of::<i8>(),
AudioQueueEnum::U16(_) => size_of::<u16>(),
AudioQueueEnum::S16(_) => size_of::<i16>(),
AudioQueueEnum::S32(_) => size_of::<i32>(),
AudioQueueEnum::F32(_) => size_of::<f32>(),
}
}
fn queue(&mut self, samples_i16: &[i16], cvt: &AudioCVT) -> bool {
let data = samples_i16.as_mut_ptr() as *mut u8;
let src_len = samples_i16.len() * size_of::<i16>();
let samples_u8 = unsafe { core::slice::from_raw_parts(data, src_len) };
let src = Vec::with_capacity(cvt.capacity(src_len));
src.copy_from_slice(samples_u8);
let resampled_u8 = cvt.convert(src);
fn reinterp<C: AudioFormatNum>(data_u8: Vec<u8>) -> Vec<C> {
const BYTE_SIZE: usize = size_of::<C>();
let ptr = data_u8.as_mut_ptr() as *mut Self::Channel;
let length = (data_u8.len() + (BYTE_SIZE - 1)) / BYTE_SIZE;
let capacity = (data_u8.capacity() + (BYTE_SIZE - 1)) / BYTE_SIZE;
std::mem::forget(data_u8);
unsafe { Vec::from_raw_parts(ptr, length, capacity) }
}
match self {
AudioQueueEnum::U8(q) => q.queue(reinterp(resampled_u8)),
AudioQueueEnum::S8(q) => q.queue(reinterp(resampled_u8)),
AudioQueueEnum::U16(q) => q.queue(reinterp(resampled_u8)),
AudioQueueEnum::S16(q) => q.queue(reinterp(resampled_u8)),
AudioQueueEnum::S32(q) => q.queue(reinterp(resampled_u8)),
AudioQueueEnum::F32(q) => q.queue(reinterp(resampled_u8)),
}
}
}
/// Trivially sends the core's audio data to the SDL audio subsystem for playback.
pub struct Sdl2RateControlledAudioComponent {
sample_rate: f64,
audio_buffer: Vec<i16>,
dest_spec: AudioSpec,
audio_device: AudioDevice<>,
cvt_send: crossbeam_channel::Sender<AudioCVT>,
send: crossbeam_channel::Sender<Vec<i16>>,
//audio_buffer: Vec<i16>,
queue: AudioQueueEnum,
spec: AudioSpec,
convert: AudioCVT,
//audio_device: AudioDevice<>,
//cvt_send: crossbeam_channel::Sender<AudioCVT>,
//send: crossbeam_channel::Sender<Vec<i16>>,
}
impl RetroCallbacks for Sdl2RateControlledAudioComponent {
fn audio_samples(&mut self, stereo_pcm: &[i16]) -> usize {
let samples = stereo_pcm.len() / 2;
self.audio_buffer.extend(stereo_pcm);
self.send_audio_samples();
stereo_pcm.len() / 2
}
@ -64,7 +117,8 @@ impl Sdl2RateControlledAudioComponent {
channels: Some(2),
samples: None,
};
let mut dest_spec_opt = None;
let queue = audio.open_queue::<i16>(None, &desired_spec)?;
/*let mut dest_spec_opt = None;
let audio_device = audio
.open_playback(None, &desired_spec, |dest_spec| {
dest_spec_opt = Some(dest_spec.clone());
@ -90,16 +144,20 @@ impl Sdl2RateControlledAudioComponent {
),
};
callback
})
.unwrap();
})?;
*/
Ok(Sdl2RateControlledAudioComponent {
sample_rate: src_freq,
queue,
spec,
convert,
/*
audio_buffer: Default::default(),
dest_spec: dest_spec_opt.unwrap(),
audio_device,
cvt_send,
send,
send,*/
})
}