Newer
Older
use boytacean::gb::{AudioProvider, GameBoy};
audio::{AudioCallback, AudioDevice, AudioSpec, AudioSpecDesired},
use std::sync::{Arc, Mutex};
/// Specification of the audion settings that have been put in place
/// for the playing of this audio wave.
spec: AudioSpec,
/// The object that is going to be used as the provider of the audio
/// operation.
audio_provider: Arc<Mutex<Box<GameBoy>>>,
/// The number of audio ticks that have passed since the beginning
/// of the audio playback, the value wraps around (avoids overflow).
ticks: usize,
impl AudioCallback for AudioWave {
type Channel = f32;
fn callback(&mut self, out: &mut [f32]) {
self.ticks = self.ticks.wrapping_add(out.len() as usize);
out.fill(0.0);
match self.audio_provider.try_lock() {
Ok(provider) => {
for (place, data) in out.iter_mut().zip(provider.output_buffer_apu().iter()) {
*place = *data as f32 / 7.0;
}
}
Err(_) => (),
}
self.audio_provider.lock().unwrap().clear_buffer_apu();
/*
for x in out.iter_mut() {
*x = match self.audio_provider.lock() {
Ok(mut provider) => {
let value = provider.output_clock_apu(1, self.spec.freq as u32) as f32 / 7.0;
value
}
Err(_) => 0.0,
}
}
}
pub struct Audio {
pub device: AudioDevice<AudioWave>,
pub audio_subsystem: AudioSubsystem,
}
impl Audio {
pub fn new(sdl: &Sdl, audio_provider: Arc<Mutex<Box<GameBoy>>>) -> Self {
let audio_subsystem = sdl.audio().unwrap();
let desired_spec = AudioSpecDesired {
freq: Some(44100),
channels: Some(1),
};
let device = audio_subsystem
.open_playback(None, &desired_spec, |spec| AudioWave {
spec: spec,
audio_provider: audio_provider,
ticks: 0,
})
.unwrap();
// starts the playback by resuming the audio
// device's activity
device.resume();
Self {
device,
audio_subsystem,
}