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
					
				
					 1 changed files with 69 additions and 11 deletions
				
			
		| 
						 | 
				
			
			@ -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…
	
	Add table
		
		Reference in a new issue