noise channel works!
This commit is contained in:
parent
9f9cd006c0
commit
6676276706
|
@ -19,10 +19,12 @@ impl DacSample {
|
||||||
fn mixed(&self, mixer: &Mixer) -> Vec<f32> {
|
fn mixed(&self, mixer: &Mixer) -> Vec<f32> {
|
||||||
let left = (self.one * mixer.ch1.left.scale())
|
let left = (self.one * mixer.ch1.left.scale())
|
||||||
+ (self.two * mixer.ch2.left.scale())
|
+ (self.two * mixer.ch2.left.scale())
|
||||||
+ (self.three * mixer.ch3.left.scale());
|
+ (self.three * mixer.ch3.left.scale())
|
||||||
|
+ (self.four * mixer.ch4.left.scale());
|
||||||
let right = (self.one * mixer.ch1.right.scale())
|
let right = (self.one * mixer.ch1.right.scale())
|
||||||
+ (self.two * mixer.ch2.right.scale())
|
+ (self.two * mixer.ch2.right.scale())
|
||||||
+ (self.three * mixer.ch3.right.scale());
|
+ (self.three * mixer.ch3.right.scale())
|
||||||
|
+ (self.four * mixer.ch4.right.scale());
|
||||||
vec![
|
vec![
|
||||||
self.mix_channel(left, mixer.vol_left),
|
self.mix_channel(left, mixer.vol_left),
|
||||||
self.mix_channel(right, mixer.vol_right),
|
self.mix_channel(right, mixer.vol_right),
|
||||||
|
@ -133,6 +135,7 @@ impl Apu {
|
||||||
// envelope sweep
|
// envelope sweep
|
||||||
self.channels.one.envelope_tick();
|
self.channels.one.envelope_tick();
|
||||||
self.channels.two.envelope_tick();
|
self.channels.two.envelope_tick();
|
||||||
|
self.channels.four.envelope_tick();
|
||||||
}
|
}
|
||||||
if self.div_apu % 4 == 0 {
|
if self.div_apu % 4 == 0 {
|
||||||
// ch1 frequency sweep
|
// ch1 frequency sweep
|
||||||
|
@ -143,6 +146,7 @@ impl Apu {
|
||||||
self.channels.one.length_tick();
|
self.channels.one.length_tick();
|
||||||
self.channels.two.length_tick();
|
self.channels.two.length_tick();
|
||||||
self.channels.three.length_tick();
|
self.channels.three.length_tick();
|
||||||
|
self.channels.four.length_tick();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,9 +155,15 @@ impl Apu {
|
||||||
&mut izip!(
|
&mut izip!(
|
||||||
self.channels.one.tick(steps).into_iter(),
|
self.channels.one.tick(steps).into_iter(),
|
||||||
self.channels.two.tick(steps).into_iter(),
|
self.channels.two.tick(steps).into_iter(),
|
||||||
self.channels.three.tick(steps).into_iter()
|
self.channels.three.tick(steps).into_iter(),
|
||||||
|
self.channels.four.tick(steps).into_iter()
|
||||||
)
|
)
|
||||||
.map(|(one, two, three)| DacSample { one, two, three })
|
.map(|(one, two, three, four)| DacSample {
|
||||||
|
one,
|
||||||
|
two,
|
||||||
|
three,
|
||||||
|
four,
|
||||||
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
);
|
);
|
||||||
if self.buffer.len() >= CYCLES_PER_FRAME {
|
if self.buffer.len() >= CYCLES_PER_FRAME {
|
||||||
|
|
|
@ -451,6 +451,43 @@ struct Lfsr {
|
||||||
clock_shift: u8,
|
clock_shift: u8,
|
||||||
width: LfsrWidth,
|
width: LfsrWidth,
|
||||||
clock_divider: u8,
|
clock_divider: u8,
|
||||||
|
interval: u16,
|
||||||
|
timer: u16,
|
||||||
|
current_value: u8,
|
||||||
|
register: u16,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Lfsr {
|
||||||
|
fn update(&mut self) {
|
||||||
|
self.interval =
|
||||||
|
(1 << (self.clock_shift as u16)) * (1 + (2 * self.clock_divider as u16)) * 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn tick(&mut self) {
|
||||||
|
self.timer += 1;
|
||||||
|
if self.timer > self.interval {
|
||||||
|
self.timer = 0;
|
||||||
|
self.next_value();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn next_value(&mut self) {
|
||||||
|
let next = if (self.register & 0b1) == ((self.register >> 1) & 0b1) {
|
||||||
|
1
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
};
|
||||||
|
self.register = (self.register & !(0b1 << 15)) | (next << 15);
|
||||||
|
if self.width == LfsrWidth::SevenBit {
|
||||||
|
self.register = (self.register & !(0b1 << 7)) | (next << 7);
|
||||||
|
}
|
||||||
|
self.register >>= 1;
|
||||||
|
self.current_value = if (self.register & 0b1) == 0b1 {
|
||||||
|
0x1
|
||||||
|
} else {
|
||||||
|
0x0
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Lfsr {
|
impl Default for Lfsr {
|
||||||
|
@ -459,6 +496,10 @@ impl Default for Lfsr {
|
||||||
clock_shift: Default::default(),
|
clock_shift: Default::default(),
|
||||||
width: LfsrWidth::FifteenBit,
|
width: LfsrWidth::FifteenBit,
|
||||||
clock_divider: Default::default(),
|
clock_divider: Default::default(),
|
||||||
|
interval: 0,
|
||||||
|
timer: 0,
|
||||||
|
current_value: 0,
|
||||||
|
register: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -489,6 +530,38 @@ impl NoiseChannel {
|
||||||
self.envelope = self.queued_envelope;
|
self.envelope = self.queued_envelope;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn tick(&mut self, steps: usize) -> Vec<f32> {
|
||||||
|
if self.enabled {
|
||||||
|
(0..steps)
|
||||||
|
.map(|_| {
|
||||||
|
self.lfsr.tick();
|
||||||
|
self.dac(self.lfsr.current_value)
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
} else {
|
||||||
|
vec![0.; steps]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn dac(&self, digital: u8) -> f32 {
|
||||||
|
(((digital as f32) * (-2.)) + 1.) * ((self.envelope.current_volume as f32) / 15.)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(super) fn envelope_tick(&mut self) {
|
||||||
|
if self.enabled {
|
||||||
|
self.envelope.tick();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(super) fn length_tick(&mut self) {
|
||||||
|
if self.length_enable && self.enabled {
|
||||||
|
self.length_timer += 1;
|
||||||
|
if self.length_timer >= 64 {
|
||||||
|
self.enabled = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(super) fn update_length_timer(&mut self, data: u8) {
|
pub(super) fn update_length_timer(&mut self, data: u8) {
|
||||||
self.length_timer = data & 0b111111;
|
self.length_timer = data & 0b111111;
|
||||||
}
|
}
|
||||||
|
@ -522,6 +595,7 @@ impl NoiseChannel {
|
||||||
LfsrWidth::FifteenBit
|
LfsrWidth::FifteenBit
|
||||||
};
|
};
|
||||||
self.lfsr.clock_divider = data & 0b111;
|
self.lfsr.clock_divider = data & 0b111;
|
||||||
|
self.lfsr.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn get_frequency_and_randomness(&self) -> u8 {
|
pub(super) fn get_frequency_and_randomness(&self) -> u8 {
|
||||||
|
|
|
@ -94,6 +94,7 @@ pub(super) struct DacSample {
|
||||||
pub(super) one: f32,
|
pub(super) one: f32,
|
||||||
pub(super) two: f32,
|
pub(super) two: f32,
|
||||||
pub(super) three: f32,
|
pub(super) three: f32,
|
||||||
|
pub(super) four: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for DacSample {
|
impl Default for DacSample {
|
||||||
|
@ -102,6 +103,7 @@ impl Default for DacSample {
|
||||||
one: 0.,
|
one: 0.,
|
||||||
two: 0.,
|
two: 0.,
|
||||||
three: 0.,
|
three: 0.,
|
||||||
|
four: 0.,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue