apu
This commit is contained in:
parent
a9227af750
commit
ac416cc722
|
@ -9,9 +9,13 @@ pub struct Apu {
|
||||||
triangle: Triangle,
|
triangle: Triangle,
|
||||||
noise: Noise,
|
noise: Noise,
|
||||||
dmc: DMC,
|
dmc: DMC,
|
||||||
|
|
||||||
|
square_table: Vec<f32>,
|
||||||
|
tnd_table: Vec<f32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Square {
|
struct Square {
|
||||||
|
sample: u16,
|
||||||
duty_cycle: usize,
|
duty_cycle: usize,
|
||||||
length_counter_halt: bool, // (this bit is also the envelope's loop flag)
|
length_counter_halt: bool, // (this bit is also the envelope's loop flag)
|
||||||
constant_volume_flag: bool, // (0: use volume from envelope; 1: use constant volume)
|
constant_volume_flag: bool, // (0: use volume from envelope; 1: use constant volume)
|
||||||
|
@ -24,6 +28,7 @@ struct Square {
|
||||||
// $4008 Hlll.llll Triangle channel length counter halt and linear counter load (write)
|
// $4008 Hlll.llll Triangle channel length counter halt and linear counter load (write)
|
||||||
// bit 7 H--- ---- Halt length counter (this bit is also the linear counter's control flag)
|
// bit 7 H--- ---- Halt length counter (this bit is also the linear counter's control flag)
|
||||||
struct Triangle {
|
struct Triangle {
|
||||||
|
sample: u16,
|
||||||
timer: usize,
|
timer: usize,
|
||||||
length_counter: usize, // (this bit is also the linear counter's control flag)
|
length_counter: usize, // (this bit is also the linear counter's control flag)
|
||||||
linear_counter: usize,
|
linear_counter: usize,
|
||||||
|
@ -32,6 +37,7 @@ struct Triangle {
|
||||||
// $400E M---.PPPP Mode and period (write)
|
// $400E M---.PPPP Mode and period (write)
|
||||||
// bit 7 M--- ---- Mode flag
|
// bit 7 M--- ---- Mode flag
|
||||||
struct Noise {
|
struct Noise {
|
||||||
|
sample: u16,
|
||||||
timer: usize,
|
timer: usize,
|
||||||
length_counter: usize,
|
length_counter: usize,
|
||||||
envelope: usize,
|
envelope: usize,
|
||||||
|
@ -45,12 +51,18 @@ struct DMC {
|
||||||
|
|
||||||
impl Apu {
|
impl Apu {
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
|
let square_table = (0..31).map(|x| 95.52/(8128.0 / x as f32) + 100.0).collect();
|
||||||
|
let tnd_table = (0..203).map(|x| 163.67/(24329.0 / x as f32) + 100.0).collect();
|
||||||
Apu {
|
Apu {
|
||||||
square1: Square::new(),
|
square1: Square::new(),
|
||||||
square2: Square::new(),
|
square2: Square::new(),
|
||||||
triangle: Triangle::new(),
|
triangle: Triangle::new(),
|
||||||
noise: Noise::new(),
|
noise: Noise::new(),
|
||||||
dmc: DMC::new(),
|
dmc: DMC::new(),
|
||||||
|
|
||||||
|
square_table: square_table,
|
||||||
|
tnd_table: tnd_table,
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,4 +93,14 @@ impl Apu {
|
||||||
0x4017 => self.frame_counter(value),
|
0x4017 => self.frame_counter(value),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn mix(&self) -> f32 {
|
||||||
|
let square_out = self.square_table[self.square1.sample + self.square2.sample as usize];
|
||||||
|
let tnd_out = self.tnd_table[(3*self.triangle.sample)+(2*self.noise.sample)+self.dmc.sample as usize];
|
||||||
|
square_out + tnd_out
|
||||||
|
}
|
||||||
|
|
||||||
|
fn frame_counter(value: u8) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
extern crate sdl2;
|
||||||
|
|
||||||
|
use sdl2::audio::{AudioCallback, AudioSpecDesired};
|
||||||
|
|
||||||
|
pub struct Speaker {
|
||||||
|
buffer: [u8; 4096],
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AudioCallback for Speaker {
|
||||||
|
type Channel = f32;
|
||||||
|
fn callback(&mut self, out: &mut [f32]) {
|
||||||
|
for (i, x) in out.iter_mut().enumerate() {
|
||||||
|
*x = self.buffer[i]; // get data from apu
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn initialize(context: &sdl2::Sdl) -> Result<sdl2::audio::AudioDevice<SquareWave>, String> {
|
||||||
|
let audio_subsystem = context.audio()?;
|
||||||
|
|
||||||
|
let desired_spec = AudioSpecDesired {
|
||||||
|
freq: Some(44_100),
|
||||||
|
channels: Some(1), // mono
|
||||||
|
samples: 4096, // default sample size
|
||||||
|
};
|
||||||
|
|
||||||
|
audio_subsystem.open_playback(None, &desired_spec, |spec| {
|
||||||
|
// Show obtained AudioSpec
|
||||||
|
println!("{:?}", spec);
|
||||||
|
|
||||||
|
// initialize the audio callback
|
||||||
|
Speaker{buffer: [0; 4096]}
|
||||||
|
})
|
||||||
|
}
|
Loading…
Reference in New Issue