use cpal::{
traits::{DeviceTrait, HostTrait},
Stream,
};
use cpal::{SampleFormat, SampleRate, SupportedStreamConfigRange};
const SAMPLE_RATE : usize = 48000;
pub enum IT2Driver {
SB16, HQ
}
pub fn load_bytes(mod_data: Vec<u8>, driver: IT2Driver) {
unsafe {
let driver = match driver {
IT2Driver::SB16 => it2play_sys::DRIVER_SB16MMX.try_into().unwrap(),
IT2Driver::HQ => it2play_sys::DRIVER_HQ.try_into().unwrap(),
};
it2play_sys::Music_Init(SAMPLE_RATE.try_into().unwrap(), 1024, driver);
it2play_sys::Music_LoadFromData(mod_data.as_ptr() as *mut u8, mod_data.len().try_into().unwrap());
}
}
pub fn free() {
unsafe {
it2play_sys::Music_FreeSong();
it2play_sys::Music_Close();
}
}
pub fn play(order: u16) {
unsafe {
it2play_sys::Song.ProcessRow = 0;
it2play_sys::Music_PlaySong(order);
}
}
pub fn stop() {
unsafe {
it2play_sys::Music_Stop();
}
}
pub fn generate_stream() -> Stream {
let host = cpal::default_host();
let device = host
.default_output_device()
.expect("it2play_rs::generate_stream: No output device available");
let mut supported_cfgs = device.supported_output_configs().unwrap();
let Some(config) = supported_cfgs.find(desired_config) else {
panic!("it2play_rs::generate_stream: Output device doesn't support desired parameters (i16 sample types/48000hz sample rate)");
};
let config = config.with_sample_rate(SampleRate(SAMPLE_RATE.try_into().unwrap())).config();
return device
.build_output_stream(
&config,
move |data: &mut [i16], _cpal| read(config.sample_rate.0 as _, data),
|err| {
dbg!(err);
},
None, )
.unwrap();
}
fn read(_rate: i32, stream: &mut [i16]) {
unsafe {
it2play_sys::Music_FillAudioBuffer(stream.as_mut_ptr(), (stream.len() / 2).try_into().unwrap());
};
}
fn desired_config(cfg: &SupportedStreamConfigRange) -> bool {
cfg.channels() == 2
&& cfg.sample_format() == SampleFormat::I16
&& cfg.max_sample_rate() >= SampleRate(SAMPLE_RATE.try_into().unwrap())
}