1use std::convert::TryInto;
2
3use crate::db_internal::{audio_alloc, audio_allocCompressed, audio_free, audio_getUsage, audio_queueSetParam_i, audio_queueSetParam_f, audio_queueStartVoice, audio_queueStopVoice, audio_getVoiceState, audio_getTime, audio_setReverbParams, audio_initSynth, audio_playMidi, audio_setMidiReverb, audio_setMidiVolume};
4
5pub const VOICE_COUNT: usize = 32;
6
7#[repr(C)]
8#[derive(Clone)]
9pub struct AudioSample {
10 pub handle: i32,
11 pub samplerate: i32,
12}
13
14#[repr(C)]
15#[derive(Clone, Copy)]
16pub enum AudioVoiceParam {
17 Volume,
18 Pitch,
19 Detune,
20 Pan,
21 SampleData,
22 Samplerate,
23 LoopEnabled,
24 LoopStart,
25 LoopEnd,
26 Reverb,
27 FadeInDuration,
28 FadeOutDuration,
29 Start,
30 Stop,
31}
32
33impl AudioSample {
34 pub fn create_s8(pcm_data: &[i8], samplerate: i32) -> Result<AudioSample,()> {
36 let handle = unsafe { audio_alloc(pcm_data.as_ptr().cast(), pcm_data.len().try_into().unwrap(), 0) };
37 if handle == -1 {
38 return Err(());
39 }
40
41 return Ok(AudioSample {
42 handle: handle,
43 samplerate: samplerate
44 });
45 }
46
47 pub fn create_s16(pcm_data: &[i16], samplerate: i32) -> Result<AudioSample,()> {
49 let handle = unsafe { audio_alloc(pcm_data.as_ptr().cast(), (pcm_data.len() * 2).try_into().unwrap(), 1) };
50 if handle == -1 {
51 return Err(());
52 }
53
54 return Ok(AudioSample {
55 handle: handle,
56 samplerate: samplerate
57 });
58 }
59
60 pub fn create_adpcm(adpcm_data: &[u8], chunk_size: i32, samplerate: i32) -> Result<AudioSample,()> {
62 let handle = unsafe { audio_allocCompressed(adpcm_data.as_ptr().cast(), adpcm_data.len().try_into().unwrap(), chunk_size) };
63 if handle == -1 {
64 return Err(());
65 }
66
67 return Ok(AudioSample {
68 handle: handle,
69 samplerate: samplerate
70 });
71 }
72}
73
74impl Drop for AudioSample {
75 fn drop(&mut self) {
76 unsafe { audio_free(self.handle); }
77 }
78}
79
80pub fn get_usage() -> i32 {
82 unsafe { return audio_getUsage(); }
83}
84
85pub fn queue_set_voice_param_i(slot: i32, param: AudioVoiceParam, value: i32, time: f64) {
87 assert!(slot >= 0 && slot < VOICE_COUNT.try_into().unwrap(), "Tried to set parameter for invalid voice handle");
88 unsafe { audio_queueSetParam_i(slot, param, value, time); }
89}
90
91pub fn queue_set_voice_param_f(slot: i32, param: AudioVoiceParam, value: f32, time: f64) {
93 assert!(slot >= 0 && slot < VOICE_COUNT.try_into().unwrap(), "Tried to set parameter for invalid voice handle");
94 unsafe { audio_queueSetParam_f(slot, param, value, time); }
95}
96
97pub fn queue_start_voice(slot: i32, time: f64) {
99 assert!(slot >= 0 && slot < VOICE_COUNT.try_into().unwrap(), "Tried to start invalid voice handle");
100 unsafe { audio_queueStartVoice(slot, time) };
101}
102
103pub fn queue_stop_voice(slot: i32, time: f64) {
105 assert!(slot >= 0 && slot < VOICE_COUNT.try_into().unwrap(), "Tried to stop invalid voice handle");
106 unsafe { audio_queueStopVoice(slot, time) };
107}
108
109pub fn get_voice_state(slot: i32) -> bool {
111 assert!(slot >= 0 && slot < VOICE_COUNT.try_into().unwrap(), "Tried to get state of invalid voice handle");
112 unsafe { return audio_getVoiceState(slot) };
113}
114
115pub fn get_time() -> f64 {
117 unsafe { return audio_getTime(); }
118}
119
120pub fn set_reverb(room_size: f32, damping: f32, width: f32, wet: f32, dry: f32) {
122 unsafe { audio_setReverbParams(room_size, damping, width, wet, dry); }
123}
124
125pub fn init_synth(sf2_data: &[u8]) -> Result<(),()> {
127 unsafe {
128 let result = audio_initSynth(sf2_data.as_ptr(), sf2_data.len().try_into().unwrap());
129 if result {
130 return Ok(());
131 } else {
132 return Err(());
133 }
134 }
135}
136
137pub fn play_midi(midi_data: &[u8], looping: bool) -> Result<(),()> {
139 unsafe {
140 let result = audio_playMidi(midi_data.as_ptr(), midi_data.len().try_into().unwrap(), looping);
141 if result {
142 return Ok(());
143 } else {
144 return Err(());
145 }
146 }
147}
148
149pub fn set_midi_reverb(enabled: bool) {
151 unsafe { audio_setMidiReverb(enabled); }
152}
153
154pub fn set_midi_volume(volume: f32) {
156 unsafe { audio_setMidiVolume(volume); }
157}