fluidlite/
font.rs

1use crate::{ffi, Bank, FontId, PresetId};
2use std::marker::PhantomData;
3
4/**
5The SoundFont interface
6 */
7pub trait IsFont {
8    fn get_id(&self) -> FontId;
9    fn get_name(&self) -> Option<&str>;
10    fn get_preset(&self, bank: Bank, num: PresetId) -> Option<PresetRef<'_>>;
11}
12
13/**
14The SoundFont preset interface
15 */
16pub trait IsPreset {
17    fn get_name(&self) -> Option<&str>;
18    fn get_banknum(&self) -> Option<Bank>;
19    fn get_num(&self) -> Option<PresetId>;
20}
21
22/**
23Reference to SoundFont object
24 */
25#[repr(transparent)]
26pub struct FontRef<'a> {
27    handle: *mut ffi::fluid_sfont_t,
28    phantom: PhantomData<&'a ()>,
29}
30
31impl<'a> FontRef<'a> {
32    pub(crate) fn from_ptr(handle: *mut ffi::fluid_sfont_t) -> Self {
33        Self {
34            handle,
35            phantom: PhantomData,
36        }
37    }
38
39    pub(crate) fn as_ptr(&self) -> *mut ffi::fluid_sfont_t {
40        self.handle
41    }
42}
43
44/**
45Reference to Preset object
46 */
47#[repr(transparent)]
48pub struct PresetRef<'a> {
49    handle: *mut ffi::fluid_preset_t,
50    phantom: PhantomData<&'a ()>,
51}
52
53impl<'a> PresetRef<'a> {
54    pub(crate) fn from_ptr(handle: *mut ffi::fluid_preset_t) -> Self {
55        Self {
56            handle,
57            phantom: PhantomData,
58        }
59    }
60}
61
62mod private {
63    use crate::{
64        ffi, option_from_ptr, private::HasHandle, Bank, FontId, FontRef, IsFont, IsPreset,
65        PresetId, PresetRef,
66    };
67    use std::ffi::CStr;
68
69    impl<X> IsFont for X
70    where
71        X: HasHandle<Handle = ffi::fluid_sfont_t>,
72    {
73        fn get_id(&self) -> FontId {
74            let handle = self.get_handle();
75            let font_c = unsafe { &*handle };
76            font_c.id
77        }
78
79        fn get_name(&self) -> Option<&str> {
80            let handle = self.get_handle();
81            let font_c = unsafe { &*handle };
82            let get_name = font_c.get_name?;
83            let name = unsafe { (get_name)(handle) };
84            let name = unsafe { CStr::from_ptr(name) };
85            name.to_str().ok()
86        }
87
88        fn get_preset(&self, bank: Bank, num: PresetId) -> Option<PresetRef<'_>> {
89            let handle = self.get_handle();
90            let font_c = unsafe { &*handle };
91            let get_preset = font_c.get_preset?;
92            option_from_ptr(unsafe { (get_preset)(handle, bank, num) }).map(PresetRef::from_ptr)
93        }
94    }
95
96    impl<'a> HasHandle for FontRef<'a> {
97        type Handle = ffi::fluid_sfont_t;
98
99        fn get_handle(&self) -> *mut Self::Handle {
100            self.handle
101        }
102    }
103
104    impl<X> IsPreset for X
105    where
106        X: HasHandle<Handle = ffi::fluid_preset_t>,
107    {
108        fn get_name(&self) -> Option<&str> {
109            let handle = self.get_handle();
110            let font_c = unsafe { &*handle };
111            let get_name = font_c.get_name?;
112            let name = unsafe { (get_name)(handle) };
113            let name = unsafe { CStr::from_ptr(name) };
114            name.to_str().ok()
115        }
116
117        fn get_banknum(&self) -> Option<Bank> {
118            let handle = self.get_handle();
119            let preset_c = unsafe { &*handle };
120            let get_banknum = preset_c.get_banknum?;
121            let num = unsafe { (get_banknum)(handle) };
122            if num < 0 {
123                None
124            } else {
125                Some(num as _)
126            }
127        }
128
129        fn get_num(&self) -> Option<PresetId> {
130            let handle = self.get_handle();
131            let preset_c = unsafe { &*handle };
132            let get_num = preset_c.get_num?;
133            let num = unsafe { (get_num)(handle) };
134            if num < 0 {
135                None
136            } else {
137                Some(num as _)
138            }
139        }
140    }
141
142    impl<'a> HasHandle for PresetRef<'a> {
143        type Handle = ffi::fluid_preset_t;
144
145        fn get_handle(&self) -> *mut Self::Handle {
146            self.handle
147        }
148    }
149}