pub struct Channel {
period: u16,
position: u16,
value: u8,
pub(crate) tone_off: bool,
pub(crate) noise_off: bool,
pub(crate) envelope_on: bool,
pub(crate) amplitude: u8,
pub(crate) pan_left: f64,
pub(crate) pan_right: f64
}
impl Channel {
pub(crate) fn new() -> Self {
Self {
period: 1,
position: 0,
value: 0,
tone_off: true,
noise_off: true,
envelope_on: false,
amplitude: 0,
pan_left: 0.5,
pan_right: 0.5
}
}
pub(crate) fn render(&mut self) -> u8 {
self.position += 1;
if self.position >= self.period {
self.position = 0;
self.value ^= 1;
}
self.value
}
pub fn period(&self) -> u16 {
self.period
}
pub fn set_period(&mut self, period: u16) {
self.period = (period & 0x0fff).max(1);
}
pub fn period_msb(&self) -> u8 {
(self.period >> 8) as u8
}
pub fn set_period_msb(&mut self, period: u8) {
self.period = ((self.period & 0x00ff) | (((period as u16) & 0x0f) << 8)).max(1);
}
pub fn period_lsb(&self) -> u8 {
(self.period & 0xff) as u8
}
pub fn set_period_lsb(&mut self, period: u8) {
self.period = ((self.period & 0x0f00) | (period as u16)).max(1);
}
pub fn amplitude(&self) -> u8 {
self.amplitude
}
pub fn set_amplitude(&mut self, amplitude: u8) {
self.amplitude = amplitude & 0x0f;
}
pub fn envelope_enabled(&self) -> bool {
self.envelope_on
}
pub fn set_envelope_enabled(&mut self, enabled: bool) {
self.envelope_on = enabled;
}
pub fn amplitude_and_envelope_enabled(&self) -> u8 {
((self.envelope_on as u8) << 4) | self.amplitude
}
pub fn set_amplitude_and_envelope_enabled(&mut self, value: u8) {
self.amplitude = value & 0x0f;
self.envelope_on = value & 0x10 != 0;
}
pub fn tone_disabled(&self) -> bool {
self.tone_off
}
pub fn set_tone_disabled(&mut self, disabled: bool) {
self.tone_off = disabled;
}
pub fn noise_disabled(&self) -> bool {
self.noise_off
}
pub fn set_noise_disabled(&mut self, disabled: bool) {
self.noise_off = disabled;
}
pub fn panning(&self) -> (f64, f64) {
(self.pan_left, self.pan_right)
}
pub fn set_panning(&mut self, balance: f64, equal_power: bool) {
self.pan_left = 1.0 - balance;
self.pan_right = balance;
if equal_power {
self.pan_left = self.pan_left.sqrt();
self.pan_right = self.pan_right.sqrt();
}
}
}