WIP messier shit figuring out audio format changing that the sdl2 crate generics currently make impossible
This commit is contained in:
parent
a1e28e9838
commit
c505428895
|
@ -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,*/
|
||||
})
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue