use crate::metadata::{YmMetadata, metadata_from_ay};
use ym2149::Ym2149Backend;
use ym2149_ay_replayer::{AyMetadata as AyFileMetadata, AyPlayer, CPC_UNSUPPORTED_MSG};
use ym2149_common::{ChiptunePlayerBase, PlaybackState};
pub struct AyWasmPlayer {
player: AyPlayer,
frame_count: usize,
duration_secs: f32,
unsupported: bool,
}
impl AyWasmPlayer {
pub fn new(player: AyPlayer, meta: &AyFileMetadata) -> (Self, YmMetadata) {
let metadata = metadata_from_ay(meta);
let frame_count = metadata.frame_count as usize;
let duration_secs = metadata.duration_seconds;
(
Self {
player,
frame_count,
duration_secs,
unsupported: false,
},
metadata,
)
}
pub fn duration_seconds(&self) -> f32 {
self.duration_secs
}
pub fn play(&mut self) -> Result<(), String> {
if self.unsupported {
return Err(CPC_UNSUPPORTED_MSG.to_string());
}
ChiptunePlayerBase::play(&mut self.player);
self.check_support()
}
pub fn pause(&mut self) {
ChiptunePlayerBase::pause(&mut self.player);
}
pub fn stop(&mut self) {
ChiptunePlayerBase::stop(&mut self.player);
}
pub fn state(&self) -> PlaybackState {
ChiptunePlayerBase::state(&self.player)
}
pub fn frame_position(&self) -> usize {
self.player.current_frame()
}
pub fn frame_count(&self) -> usize {
self.frame_count
}
pub fn playback_position(&self) -> f32 {
ChiptunePlayerBase::playback_position(&self.player)
}
pub fn generate_samples(&mut self, count: usize) -> Vec<f32> {
if self.unsupported {
return vec![0.0; count];
}
let mut samples = ChiptunePlayerBase::generate_samples(&mut self.player, count);
if self.check_support().is_err() {
samples.fill(0.0);
}
samples
}
pub fn generate_samples_into(&mut self, buffer: &mut [f32]) {
ChiptunePlayerBase::generate_samples_into(&mut self.player, buffer);
if self.check_support().is_err() {
buffer.fill(0.0);
}
}
pub fn set_channel_mute(&mut self, channel: usize, mute: bool) {
ChiptunePlayerBase::set_channel_mute(&mut self.player, channel, mute);
}
pub fn is_channel_muted(&self, channel: usize) -> bool {
ChiptunePlayerBase::is_channel_muted(&self.player, channel)
}
pub fn dump_registers(&self) -> [u8; 16] {
self.player.chip().dump_registers()
}
pub fn set_color_filter(&mut self, enabled: bool) {
self.player.set_color_filter(enabled);
}
fn check_support(&mut self) -> Result<(), String> {
if self.unsupported || self.player.requires_cpc_firmware() {
self.unsupported = true;
Err(CPC_UNSUPPORTED_MSG.to_string())
} else {
Ok(())
}
}
}