use crate::PSG_MASTER_CLOCK_HZ as PSG_CLOCK_U32;
const PSG_MASTER_CLOCK_F32: f32 = PSG_CLOCK_U32 as f32;
const PERIOD_DENOMINATOR: f32 = 16.0;
#[inline]
#[must_use]
pub fn channel_period(lo: u8, hi: u8) -> Option<u16> {
let period = (((hi as u16) & 0x0F) << 8) | (lo as u16);
if period == 0 { None } else { Some(period) }
}
#[inline]
#[must_use]
pub fn period_to_frequency(period: u16) -> f32 {
period_to_frequency_with_clock(PSG_MASTER_CLOCK_F32, period)
}
#[inline]
#[must_use]
pub fn period_to_frequency_with_clock(master_clock_hz: f32, period: u16) -> f32 {
if period == 0 {
0.0
} else {
master_clock_hz / (PERIOD_DENOMINATOR * period as f32)
}
}
#[inline]
#[must_use]
pub fn channel_frequencies(registers: &[u8; 16]) -> [Option<f32>; 3] {
channel_frequencies_with_clock(registers, PSG_MASTER_CLOCK_F32)
}
#[inline]
#[must_use]
pub fn channel_frequencies_with_clock(
registers: &[u8; 16],
master_clock_hz: f32,
) -> [Option<f32>; 3] {
[
channel_period(registers[0], registers[1])
.map(|period| period_to_frequency_with_clock(master_clock_hz, period)),
channel_period(registers[2], registers[3])
.map(|period| period_to_frequency_with_clock(master_clock_hz, period)),
channel_period(registers[4], registers[5])
.map(|period| period_to_frequency_with_clock(master_clock_hz, period)),
]
}