1use cpal::{
2 BufferSize, OutputCallbackInfo, SampleFormat, SampleRate, SupportedBufferSize,
3 SupportedStreamConfigRange,
4};
5use cpal::{
6 Stream,
7 traits::{DeviceTrait, HostTrait},
8};
9
10const SAMPLE_RATE: usize = 48000;
11
12pub enum IT2Driver {
15 SB16, HQ,
17}
18
19pub fn load_bytes(mut mod_data: Vec<u8>, driver: IT2Driver) {
27 unsafe {
28 let driver = match driver {
29 IT2Driver::SB16 => it2play_sys::DRIVER_SB16MMX.try_into().unwrap(),
30 IT2Driver::HQ => it2play_sys::DRIVER_HQ.try_into().unwrap(),
31 };
32 it2play_sys::Music_Init(SAMPLE_RATE.try_into().unwrap(), 1024, driver);
34 it2play_sys::Music_LoadFromData(mod_data.as_mut_ptr(), mod_data.len().try_into().unwrap());
35 }
36}
37
38pub fn free() {
42 unsafe {
43 it2play_sys::Music_FreeSong();
44 it2play_sys::Music_Close();
45 }
46}
47
48pub fn play(order: u16) {
51 unsafe {
53 it2play_sys::Song.ProcessRow = 0;
54 it2play_sys::Music_PlaySong(order);
55 }
56}
57
58pub fn stop() {
60 unsafe {
61 it2play_sys::Music_Stop();
62 }
63}
64
65pub fn set_global_volume(vol: u16) {
67 unsafe {
68 it2play_sys::Song.GlobalVolume = vol;
69 }
70}
71
72pub fn generate_stream() -> Stream {
74 let host = cpal::default_host();
76 let device = host
77 .default_output_device()
78 .expect("it2play_rs::generate_stream: No output device available");
79
80 let mut supported_cfgs = device.supported_output_configs().unwrap();
81 let Some(config) = supported_cfgs.find(desired_config) else {
82 panic!(
83 "it2play_rs::generate_stream: Output device doesn't support desired parameters (f32 sample types/{}hz sample rate)",
84 SAMPLE_RATE
85 );
86 };
87 let config = config
88 .with_sample_rate(SampleRate(SAMPLE_RATE.try_into().unwrap()))
89 .config();
90 let mut buffer = vec![0i16; 1024]; return device
93 .build_output_stream(
94 &config,
95 move |data, _| read_f32(data, &mut buffer),
96 |err| {
97 dbg!(err);
98 },
99 None, )
101 .unwrap();
102}
103
104fn read_i16(stream: &mut [i16]) {
107 unsafe {
108 it2play_sys::Music_FillAudioBuffer(stream.as_mut_ptr(), (stream.len() / 2) as i32);
109 };
110}
111
112fn read_f32(stream: &mut [f32], buffer: &mut Vec<i16>) {
115 if buffer.len() != stream.len() {
118 buffer.resize(stream.len(), 0i16);
119 }
120 read_i16(buffer);
121 let converted_buffer: Vec<f32> = buffer
123 .into_iter()
124 .map(|x| (*x as f32) / (i16::MAX as f32))
125 .collect();
126 stream.copy_from_slice(&converted_buffer);
127}
128
129fn desired_config(cfg: &SupportedStreamConfigRange) -> bool {
131 cfg.channels() == 2
132 && cfg.sample_format() == SampleFormat::F32
133 && cfg.max_sample_rate() >= SampleRate(SAMPLE_RATE.try_into().unwrap())
134}