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 core::time::Duration;
|
||||||
|
|
||||||
use sdl2::Sdl;
|
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.
|
/// Trivially sends the core's audio data to the SDL audio subsystem for playback.
|
||||||
pub struct Sdl2RateControlledAudioComponent {
|
pub struct Sdl2RateControlledAudioComponent {
|
||||||
sample_rate: f64,
|
sample_rate: f64,
|
||||||
audio_buffer: Vec<i16>,
|
//audio_buffer: Vec<i16>,
|
||||||
dest_spec: AudioSpec,
|
queue: AudioQueueEnum,
|
||||||
audio_device: AudioDevice<>,
|
spec: AudioSpec,
|
||||||
cvt_send: crossbeam_channel::Sender<AudioCVT>,
|
convert: AudioCVT,
|
||||||
send: crossbeam_channel::Sender<Vec<i16>>,
|
//audio_device: AudioDevice<>,
|
||||||
|
//cvt_send: crossbeam_channel::Sender<AudioCVT>,
|
||||||
|
//send: crossbeam_channel::Sender<Vec<i16>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RetroCallbacks for Sdl2RateControlledAudioComponent {
|
impl RetroCallbacks for Sdl2RateControlledAudioComponent {
|
||||||
fn audio_samples(&mut self, stereo_pcm: &[i16]) -> usize {
|
fn audio_samples(&mut self, stereo_pcm: &[i16]) -> usize {
|
||||||
|
let samples = stereo_pcm.len() / 2;
|
||||||
|
|
||||||
self.audio_buffer.extend(stereo_pcm);
|
self.audio_buffer.extend(stereo_pcm);
|
||||||
self.send_audio_samples();
|
|
||||||
stereo_pcm.len() / 2
|
stereo_pcm.len() / 2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,7 +117,8 @@ impl Sdl2RateControlledAudioComponent {
|
||||||
channels: Some(2),
|
channels: Some(2),
|
||||||
samples: None,
|
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
|
let audio_device = audio
|
||||||
.open_playback(None, &desired_spec, |dest_spec| {
|
.open_playback(None, &desired_spec, |dest_spec| {
|
||||||
dest_spec_opt = Some(dest_spec.clone());
|
dest_spec_opt = Some(dest_spec.clone());
|
||||||
|
@ -90,16 +144,20 @@ impl Sdl2RateControlledAudioComponent {
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
callback
|
callback
|
||||||
})
|
})?;
|
||||||
.unwrap();
|
*/
|
||||||
|
|
||||||
Ok(Sdl2RateControlledAudioComponent {
|
Ok(Sdl2RateControlledAudioComponent {
|
||||||
sample_rate: src_freq,
|
sample_rate: src_freq,
|
||||||
|
queue,
|
||||||
|
spec,
|
||||||
|
convert,
|
||||||
|
/*
|
||||||
audio_buffer: Default::default(),
|
audio_buffer: Default::default(),
|
||||||
dest_spec: dest_spec_opt.unwrap(),
|
dest_spec: dest_spec_opt.unwrap(),
|
||||||
audio_device,
|
audio_device,
|
||||||
cvt_send,
|
cvt_send,
|
||||||
send,
|
send,*/
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue