#![allow(dead_code)]
use mos6502::CPU_FREQ;
use memory::CPUBus;
use utils::Sampler;
use core::mem::size_of;
use utils::{Read, Write, load_prefix, save_prefix};
#[repr(C)]
struct LPFilter {
prev_out: i16
}
const AUDIO_LEVEL_MAX: i32 = 32768;
const LP_FACTOR: i32 = (0.815686 * AUDIO_LEVEL_MAX as f32) as i32;
const HP_FACTOR1: i32 = (0.996039 * AUDIO_LEVEL_MAX as f32) as i32;
const HP_FACTOR2: i32 = (0.999835 * AUDIO_LEVEL_MAX as f32) as i32;
fn cutoff(mut x: i32) -> i16 {
if x < -32768 {
x = -32768
} else if x > 32767 {
x = 32767
}
x as i16
}
impl LPFilter {
fn new() -> Self {
LPFilter { prev_out: 0 }
}
fn load(&mut self, reader: &mut Read) -> bool {
load_prefix(self, 0, reader)
}
fn save(&self, writer: &mut Write) -> bool {
save_prefix(self, 0, writer)
}
fn output(&mut self, input: i16) -> i16 {
let out = cutoff(self.prev_out as i32 +
(input as i32 - self.prev_out as i32)
* LP_FACTOR / AUDIO_LEVEL_MAX);
self.prev_out = out;
out
}
}
#[repr(C)]
struct HPFilter {
prev_in: i16,
prev_out: i16,
hp_factor: i32
}
impl HPFilter {
fn new(hp_factor: i32) -> Self {
HPFilter {
prev_in: 0,
prev_out: 0,
hp_factor
}
}
fn load(&mut self, reader: &mut Read) -> bool {
load_prefix(self, 0, reader)
}
fn save(&self, writer: &mut Write) -> bool {
save_prefix(self, 0, writer)
}
fn output(&mut self, input: i16) -> i16 {
let out = cutoff(
self.prev_out as i32 * self.hp_factor / AUDIO_LEVEL_MAX +
input as i32 - self.prev_in as i32);
self.prev_in = input;
self.prev_out = out;
out
}
}
pub trait Speaker {
fn queue(&mut self, sample: i16);
}
const QUARTER_FRAME_FREQ: u32 = 240;
pub const AUDIO_SAMPLE_FREQ: u32 = 44100;
const TRI_SEQ_TABLE: [u8; 32] = [
15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
];
const LEN_TABLE: [u8; 32] = [
10, 254, 20, 2, 40, 4, 80, 6, 160, 8, 60, 10, 14, 12, 26, 14,
12, 16, 24, 18, 48, 20, 96, 22, 192, 24, 72, 26, 16, 28, 32, 30,
];
const DUTY_TABLE: [u8; 4] = [
0b00000010,
0b00000110,
0b00011110,
0b11111001,
];
const PULSE_TABLE: [u16; 31] = [
0x0000, 0x02f8, 0x05df, 0x08b4, 0x0b78, 0x0e2b,
0x10cf, 0x1363, 0x15e9, 0x1860, 0x1ac9, 0x1d25,
0x1f75, 0x21b7, 0x23ee, 0x2618, 0x2837, 0x2a4c,
0x2c55, 0x2e54, 0x3049, 0x3234, 0x3416, 0x35ee,
0x37be, 0x3985, 0x3b43, 0x3cf9, 0x3ea7, 0x404d,
0x41ec
];
const NOISE_PERIOD_TABLE: [u16; 16] = [
4, 8, 16, 32, 64, 96, 128, 160, 202, 254, 380, 508, 762, 1016, 2034, 4068
];
const DMC_TABLE: [u16; 16] = [
214, 190, 170, 160, 143, 127, 113, 107, 95, 80, 71, 64, 53, 42, 36, 27,
];
const TND_TABLE: [u16; 203] = [
0x0000, 0x01b7, 0x036a, 0x051a, 0x06c6, 0x086f,
0x0a15, 0x0bb7, 0x0d56, 0x0ef2, 0x108a, 0x121f,
0x13b1, 0x1540, 0x16cc, 0x1855, 0x19da, 0x1b5d,
0x1cdd, 0x1e59