2024-03-06 08:02:15 +05:30
|
|
|
use std::sync::{Arc, Mutex};
|
|
|
|
use sdl2::audio::AudioQueue;
|
|
|
|
use crate::util::EmulatorResult;
|
2024-03-05 21:56:24 +05:30
|
|
|
|
2024-03-06 08:02:15 +05:30
|
|
|
pub struct SdlAudioAdapter {
|
2024-03-05 21:56:24 +05:30
|
|
|
sound_timer: Arc<Mutex<u8>>,
|
|
|
|
phase_inc: f32,
|
|
|
|
phase: f32,
|
|
|
|
volume: f32,
|
2024-03-06 08:02:15 +05:30
|
|
|
audio_queue: AudioQueue<f32>,
|
|
|
|
buf: Vec<f32>,
|
2024-03-05 21:56:24 +05:30
|
|
|
}
|
|
|
|
|
2024-03-06 08:02:15 +05:30
|
|
|
/// An Audio adapter using `AudioQueue`.
|
|
|
|
impl SdlAudioAdapter {
|
|
|
|
pub const SAMPLING_FREQ:i32 = 15360;
|
2024-03-06 08:18:07 +05:30
|
|
|
pub const SAMPLES_PER_FRAME: usize = (Self::SAMPLING_FREQ as usize / 60) * 2;
|
2024-03-05 21:56:24 +05:30
|
|
|
pub fn new(sound_timer: Arc<Mutex<u8>>,
|
2024-03-06 08:02:15 +05:30
|
|
|
freq: f32,
|
|
|
|
volume: f32,
|
|
|
|
audio_queue: AudioQueue<f32>) -> SdlAudioAdapter {
|
|
|
|
audio_queue.resume();
|
|
|
|
SdlAudioAdapter {
|
2024-03-05 21:56:24 +05:30
|
|
|
sound_timer,
|
2024-03-06 08:02:15 +05:30
|
|
|
buf: vec![0f32; Self::SAMPLES_PER_FRAME],
|
2024-03-05 21:56:24 +05:30
|
|
|
phase: 0f32,
|
2024-03-06 08:02:15 +05:30
|
|
|
phase_inc: freq/Self::SAMPLING_FREQ as f32,
|
2024-03-05 21:56:24 +05:30
|
|
|
volume,
|
2024-03-06 08:02:15 +05:30
|
|
|
audio_queue,
|
2024-03-05 21:56:24 +05:30
|
|
|
}
|
|
|
|
}
|
2024-03-06 08:02:15 +05:30
|
|
|
pub fn process_push_audio(&mut self) -> EmulatorResult<()> {
|
|
|
|
// fill the audio vector.
|
|
|
|
let sound_timer = {
|
|
|
|
let sound_timer = self.sound_timer.lock().expect("Could not lock to play audio");
|
|
|
|
sound_timer.clone()
|
|
|
|
};
|
2024-03-06 08:18:07 +05:30
|
|
|
if sound_timer>0 && self.audio_queue.size() < Self::SAMPLING_FREQ as u32 {
|
2024-03-06 08:02:15 +05:30
|
|
|
self.fill_audio();
|
|
|
|
self.audio_queue.queue_audio(&self.buf)?;
|
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
2024-03-05 21:56:24 +05:30
|
|
|
|
2024-03-06 08:02:15 +05:30
|
|
|
fn fill_audio(&mut self) {
|
|
|
|
let out = &mut self.buf;
|
2024-03-05 21:56:24 +05:30
|
|
|
|
|
|
|
// Generate a square wave
|
|
|
|
for x in out.iter_mut() {
|
2024-03-06 08:02:15 +05:30
|
|
|
*x = if self.phase <= 0.5 {
|
|
|
|
self.volume
|
2024-03-05 21:56:24 +05:30
|
|
|
} else {
|
2024-03-06 08:02:15 +05:30
|
|
|
-self.volume
|
2024-03-05 21:56:24 +05:30
|
|
|
};
|
2024-03-06 08:02:15 +05:30
|
|
|
|
2024-03-05 21:56:24 +05:30
|
|
|
self.phase = (self.phase + self.phase_inc) % 1.0;
|
|
|
|
}
|
|
|
|
}
|
2024-03-06 08:02:15 +05:30
|
|
|
}
|