pub mod arkos;
pub mod ay;
pub mod sndh;
use arkos::ArkosWasmPlayer;
use ay::AyWasmPlayer;
use sndh::SndhWasmPlayer;
use ym2149::Ym2149Backend;
use ym2149_common::{ChiptunePlayerBase, PlaybackState};
#[inline]
fn mono_to_stereo(mono: &[f32], stereo: &mut [f32]) {
for (i, &sample) in mono.iter().enumerate() {
stereo[i * 2] = sample;
stereo[i * 2 + 1] = sample;
}
}
pub enum BrowserSongPlayer {
Ym(Box<ym2149_ym_replayer::YmPlayer>),
Arkos(Box<ArkosWasmPlayer>),
Ay(Box<AyWasmPlayer>),
Sndh(Box<SndhWasmPlayer>),
}
impl BrowserSongPlayer {
pub fn seek_frame(&mut self, frame: usize) -> bool {
match self {
BrowserSongPlayer::Ym(player) => {
player.seek_frame(frame);
true
}
BrowserSongPlayer::Arkos(_) => false,
BrowserSongPlayer::Ay(_) => false,
BrowserSongPlayer::Sndh(player) => player.seek_frame(frame),
}
}
pub fn seek_percentage(&mut self, position: f32) -> bool {
match self {
BrowserSongPlayer::Ym(player) => ChiptunePlayerBase::seek(player.as_mut(), position),
BrowserSongPlayer::Arkos(_) => false,
BrowserSongPlayer::Ay(_) => false,
BrowserSongPlayer::Sndh(player) => player.seek_percentage(position),
}
}
pub fn duration_seconds(&self) -> f32 {
match self {
BrowserSongPlayer::Ym(player) => ChiptunePlayerBase::duration_seconds(player.as_ref()),
BrowserSongPlayer::Arkos(player) => player.duration_seconds(),
BrowserSongPlayer::Ay(player) => player.duration_seconds(),
BrowserSongPlayer::Sndh(player) => player.duration_seconds(),
}
}
pub fn has_duration_info(&self) -> bool {
match self {
BrowserSongPlayer::Ym(_) => true,
BrowserSongPlayer::Arkos(_) => true,
BrowserSongPlayer::Ay(_) => true,
BrowserSongPlayer::Sndh(player) => player.has_duration_info(),
}
}
pub fn play(&mut self) {
match self {
BrowserSongPlayer::Ym(player) => player.play(),
BrowserSongPlayer::Arkos(player) => player.play(),
BrowserSongPlayer::Ay(player) => {
let _ = player.play();
}
BrowserSongPlayer::Sndh(player) => player.play(),
}
}
pub fn pause(&mut self) {
match self {
BrowserSongPlayer::Ym(player) => player.pause(),
BrowserSongPlayer::Arkos(player) => player.pause(),
BrowserSongPlayer::Ay(player) => player.pause(),
BrowserSongPlayer::Sndh(player) => player.pause(),
}
}
pub fn stop(&mut self) {
match self {
BrowserSongPlayer::Ym(player) => player.stop(),
BrowserSongPlayer::Arkos(player) => player.stop(),
BrowserSongPlayer::Ay(player) => player.stop(),
BrowserSongPlayer::Sndh(player) => player.stop(),
}
}
pub fn state(&self) -> PlaybackState {
match self {
BrowserSongPlayer::Ym(player) => player.state(),
BrowserSongPlayer::Arkos(player) => player.state(),
BrowserSongPlayer::Ay(player) => player.state(),
BrowserSongPlayer::Sndh(player) => player.state(),
}
}
pub fn frame_position(&self) -> usize {
match self {
BrowserSongPlayer::Ym(player) => player.get_current_frame(),
BrowserSongPlayer::Arkos(player) => player.frame_position(),
BrowserSongPlayer::Ay(player) => player.frame_position(),
BrowserSongPlayer::Sndh(player) => player.frame_position(),
}
}
pub fn frame_count(&self) -> usize {
match self {
BrowserSongPlayer::Ym(player) => player.frame_count(),
BrowserSongPlayer::Arkos(player) => player.frame_count(),
BrowserSongPlayer::Ay(player) => player.frame_count(),
BrowserSongPlayer::Sndh(player) => player.frame_count(),
}
}
pub fn playback_position(&self) -> f32 {
match self {
BrowserSongPlayer::Ym(player) => player.playback_position(),
BrowserSongPlayer::Arkos(player) => player.playback_position(),
BrowserSongPlayer::Ay(player) => player.playback_position(),
BrowserSongPlayer::Sndh(player) => player.playback_position(),
}
}
pub fn generate_samples(&mut self, count: usize) -> Vec<f32> {
match self {
BrowserSongPlayer::Ym(player) => player.generate_samples(count),
BrowserSongPlayer::Arkos(player) => player.generate_samples(count),
BrowserSongPlayer::Ay(player) => player.generate_samples(count),
BrowserSongPlayer::Sndh(player) => player.generate_samples(count),
}
}
pub fn generate_samples_into(&mut self, buffer: &mut [f32]) {
match self {
BrowserSongPlayer::Ym(player) => player.generate_samples_into(buffer),
BrowserSongPlayer::Arkos(player) => player.generate_samples_into(buffer),
BrowserSongPlayer::Ay(player) => player.generate_samples_into(buffer),
BrowserSongPlayer::Sndh(player) => player.generate_samples_into(buffer),
}
}
pub fn generate_samples_stereo(&mut self, frame_count: usize) -> Vec<f32> {
match self {
BrowserSongPlayer::Sndh(player) => player.generate_samples_stereo(frame_count),
_ => {
let mono = self.generate_samples(frame_count);
let mut stereo = vec![0.0; frame_count * 2];
mono_to_stereo(&mono, &mut stereo);
stereo
}
}
}
pub fn generate_samples_into_stereo(&mut self, buffer: &mut [f32]) {
match self {
BrowserSongPlayer::Sndh(player) => player.generate_samples_into_stereo(buffer),
_ => {
let frame_count = buffer.len() / 2;
let mono = self.generate_samples(frame_count);
mono_to_stereo(&mono, buffer);
}
}
}
pub fn set_channel_mute(&mut self, channel: usize, mute: bool) {
match self {
BrowserSongPlayer::Ym(player) => player.set_channel_mute(channel, mute),
BrowserSongPlayer::Arkos(player) => player.set_channel_mute(channel, mute),
BrowserSongPlayer::Ay(player) => player.set_channel_mute(channel, mute),
BrowserSongPlayer::Sndh(player) => player.set_channel_mute(channel, mute),
}
}
pub fn is_channel_muted(&self, channel: usize) -> bool {
match self {
BrowserSongPlayer::Ym(player) => player.is_channel_muted(channel),
BrowserSongPlayer::Arkos(player) => player.is_channel_muted(channel),
BrowserSongPlayer::Ay(player) => player.is_channel_muted(channel),
BrowserSongPlayer::Sndh(player) => player.is_channel_muted(channel),
}
}
pub fn dump_registers(&self) -> [u8; 16] {
match self {
BrowserSongPlayer::Ym(player) => player.get_chip().dump_registers(),
BrowserSongPlayer::Arkos(player) => player.dump_registers(),
BrowserSongPlayer::Ay(player) => player.dump_registers(),
BrowserSongPlayer::Sndh(player) => player.dump_registers(),
}
}
pub fn set_color_filter(&mut self, enabled: bool) {
match self {
BrowserSongPlayer::Ym(player) => player.get_chip_mut().set_color_filter(enabled),
BrowserSongPlayer::Arkos(player) => player.set_color_filter(enabled),
BrowserSongPlayer::Ay(player) => player.set_color_filter(enabled),
BrowserSongPlayer::Sndh(player) => player.set_color_filter(enabled),
}
}
pub fn subsong_count(&self) -> usize {
match self {
BrowserSongPlayer::Ym(_) => 1,
BrowserSongPlayer::Arkos(_) => 1,
BrowserSongPlayer::Ay(_) => 1,
BrowserSongPlayer::Sndh(player) => player.subsong_count(),
}
}
pub fn current_subsong(&self) -> usize {
match self {
BrowserSongPlayer::Ym(_) => 1,
BrowserSongPlayer::Arkos(_) => 1,
BrowserSongPlayer::Ay(_) => 1,
BrowserSongPlayer::Sndh(player) => player.current_subsong(),
}
}
pub fn set_subsong(&mut self, index: usize) -> bool {
match self {
BrowserSongPlayer::Ym(_) => index == 1,
BrowserSongPlayer::Arkos(_) => index == 1,
BrowserSongPlayer::Ay(_) => index == 1,
BrowserSongPlayer::Sndh(player) => player.set_subsong(index),
}
}
pub fn channel_count(&self) -> usize {
match self {
BrowserSongPlayer::Ym(_) => 3,
BrowserSongPlayer::Arkos(player) => player.channel_count(),
BrowserSongPlayer::Ay(_) => 3,
BrowserSongPlayer::Sndh(player) => player.channel_count(),
}
}
pub fn dump_all_registers(&self) -> Vec<[u8; 16]> {
match self {
BrowserSongPlayer::Ym(player) => vec![player.get_chip().dump_registers()],
BrowserSongPlayer::Arkos(player) => player.dump_all_registers(),
BrowserSongPlayer::Ay(player) => vec![player.dump_registers()],
BrowserSongPlayer::Sndh(player) => vec![player.dump_registers()],
}
}
pub fn loop_count(&self) -> u32 {
match self {
BrowserSongPlayer::Ym(_) => 0,
BrowserSongPlayer::Arkos(_) => 0,
BrowserSongPlayer::Ay(_) => 0,
BrowserSongPlayer::Sndh(player) => player.loop_count(),
}
}
pub fn get_channel_outputs(&self) -> Vec<[f32; 3]> {
match self {
BrowserSongPlayer::Ym(player) => {
let (a, b, c) = player.get_chip().get_channel_outputs();
vec![[a, b, c]]
}
BrowserSongPlayer::Arkos(player) => player.get_channel_outputs(),
BrowserSongPlayer::Ay(player) => {
let (a, b, c) = player.get_channel_outputs();
vec![[a, b, c]]
}
BrowserSongPlayer::Sndh(player) => {
let (a, b, c) = player.get_channel_outputs();
vec![[a, b, c]]
}
}
}
pub fn generate_samples_with_channels(&mut self, count: usize) -> (Vec<f32>, Vec<f32>) {
let mut mono = vec![0.0f32; count];
let channel_count = self.channel_count();
let mut channels = vec![0.0f32; count * channel_count];
match self {
BrowserSongPlayer::Ym(player) => {
use ym2149::Ym2149Backend;
for i in 0..count {
mono[i] = player.generate_sample();
let (a, b, c) = player.get_chip().get_channel_outputs();
channels[i * 3] = a;
channels[i * 3 + 1] = b;
channels[i * 3 + 2] = c;
}
}
BrowserSongPlayer::Arkos(player) => {
player.generate_samples_with_channels_into(&mut mono, &mut channels);
}
BrowserSongPlayer::Ay(player) => {
player.generate_samples_with_channels_into(&mut mono, &mut channels);
}
BrowserSongPlayer::Sndh(player) => {
player.generate_samples_with_channels_into(&mut mono, &mut channels);
}
}
(mono, channels)
}
}