rustysynth_ext/
preset_region.rs1use crate::error::SoundFontError;
2use crate::generator::Generator;
3use crate::generator_type::GeneratorType;
4use crate::instrument::Instrument;
5use crate::soundfont_math::SoundFontMath;
6use crate::zone::Zone;
7
8fn set_parameter(gs: &mut [i16; GeneratorType::COUNT], generator: &Generator) {
9 let index = generator.generator_type as usize;
10
11 if index < gs.len() {
13 gs[index] = generator.value as i16;
14 }
15}
16
17#[derive(Debug)]
20#[non_exhaustive]
21pub struct PresetRegion {
22 pub(crate) gs: [i16; GeneratorType::COUNT],
23 pub(crate) instrument: usize,
24}
25
26impl PresetRegion {
27 fn new(
28 preset_id: usize,
29 global: &Zone,
30 local: &Zone,
31 samples: &[Instrument],
32 ) -> Result<Self, SoundFontError> {
33 let mut gs: [i16; GeneratorType::COUNT] = [0; GeneratorType::COUNT];
34 gs[GeneratorType::KEY_RANGE as usize] = 0x7F00;
35 gs[GeneratorType::VELOCITY_RANGE as usize] = 0x7F00;
36
37 for generator in global.generators.iter() {
38 set_parameter(&mut gs, generator);
39 }
40
41 for generator in local.generators.iter() {
42 set_parameter(&mut gs, generator);
43 }
44
45 let instrument_id = gs[GeneratorType::INSTRUMENT as usize] as usize;
46 if instrument_id >= samples.len() {
47 return Err(SoundFontError::InvalidInstrumentId {
48 preset_id,
49 instrument_id,
50 });
51 }
52
53 Ok(Self {
54 gs,
55 instrument: instrument_id,
56 })
57 }
58
59 pub(crate) fn create(
60 preset_id: usize,
61 zones: &[Zone],
62 instruments: &[Instrument],
63 ) -> Result<Vec<PresetRegion>, SoundFontError> {
64 if zones[0].generators.is_empty()
66 || zones[0].generators.last().unwrap().generator_type != GeneratorType::INSTRUMENT
67 {
68 let global = &zones[0];
70
71 let count = zones.len() - 1;
73 let mut regions: Vec<PresetRegion> = Vec::with_capacity(count);
74 for i in 0..count {
75 regions.push(PresetRegion::new(
76 preset_id,
77 global,
78 &zones[i + 1],
79 instruments,
80 )?);
81 }
82
83 Ok(regions)
84 } else {
85 let count = zones.len();
87 let mut regions: Vec<PresetRegion> = Vec::with_capacity(count);
88 for zone in zones.iter().take(count) {
89 regions.push(PresetRegion::new(
90 preset_id,
91 &Zone::empty(),
92 zone,
93 instruments,
94 )?);
95 }
96
97 Ok(regions)
98 }
99 }
100
101 pub fn contains(&self, key: i32, velocity: i32) -> bool {
109 let contains_key = self.get_key_range_start() <= key && key <= self.get_key_range_end();
110 let contains_velocity = self.get_velocity_range_start() <= velocity
111 && velocity <= self.get_velocity_range_end();
112 contains_key && contains_velocity
113 }
114
115 pub fn get_modulation_lfo_to_pitch(&self) -> i32 {
116 self.gs[GeneratorType::MODULATION_LFO_TO_PITCH as usize] as i32
117 }
118
119 pub fn get_vibrato_lfo_to_pitch(&self) -> i32 {
120 self.gs[GeneratorType::VIBRATO_LFO_TO_PITCH as usize] as i32
121 }
122
123 pub fn get_modulation_envelope_to_pitch(&self) -> i32 {
124 self.gs[GeneratorType::MODULATION_ENVELOPE_TO_PITCH as usize] as i32
125 }
126
127 pub fn get_initial_filter_cutoff_frequency(&self) -> f32 {
128 SoundFontMath::cents_to_multiplying_factor(
129 self.gs[GeneratorType::INITIAL_FILTER_CUTOFF_FREQUENCY as usize] as f32,
130 )
131 }
132
133 pub fn get_initial_filter_q(&self) -> f32 {
134 0.1_f32 * self.gs[GeneratorType::INITIAL_FILTER_Q as usize] as f32
135 }
136
137 pub fn get_modulation_lfo_to_filter_cutoff_frequency(&self) -> i32 {
138 self.gs[GeneratorType::MODULATION_LFO_TO_FILTER_CUTOFF_FREQUENCY as usize] as i32
139 }
140
141 pub fn get_modulation_envelope_to_filter_cutoff_frequency(&self) -> i32 {
142 self.gs[GeneratorType::MODULATION_ENVELOPE_TO_FILTER_CUTOFF_FREQUENCY as usize] as i32
143 }
144
145 pub fn get_modulation_lfo_to_volume(&self) -> f32 {
146 0.1_f32 * self.gs[GeneratorType::MODULATION_LFO_TO_VOLUME as usize] as f32
147 }
148
149 pub fn get_chorus_effects_send(&self) -> f32 {
150 0.1_f32 * self.gs[GeneratorType::CHORUS_EFFECTS_SEND as usize] as f32
151 }
152
153 pub fn get_reverb_effects_send(&self) -> f32 {
154 0.1_f32 * self.gs[GeneratorType::REVERB_EFFECTS_SEND as usize] as f32
155 }
156
157 pub fn get_pan(&self) -> f32 {
158 0.1_f32 * self.gs[GeneratorType::PAN as usize] as f32
159 }
160
161 pub fn get_delay_modulation_lfo(&self) -> f32 {
162 SoundFontMath::cents_to_multiplying_factor(
163 self.gs[GeneratorType::DELAY_MODULATION_LFO as usize] as f32,
164 )
165 }
166
167 pub fn get_frequency_modulation_lfo(&self) -> f32 {
168 SoundFontMath::cents_to_multiplying_factor(
169 self.gs[GeneratorType::FREQUENCY_MODULATION_LFO as usize] as f32,
170 )
171 }
172
173 pub fn get_delay_vibrato_lfo(&self) -> f32 {
174 SoundFontMath::cents_to_multiplying_factor(
175 self.gs[GeneratorType::DELAY_VIBRATO_LFO as usize] as f32,
176 )
177 }
178
179 pub fn get_frequency_vibrato_lfo(&self) -> f32 {
180 SoundFontMath::cents_to_multiplying_factor(
181 self.gs[GeneratorType::FREQUENCY_VIBRATO_LFO as usize] as f32,
182 )
183 }
184
185 pub fn get_delay_modulation_envelope(&self) -> f32 {
186 SoundFontMath::cents_to_multiplying_factor(
187 self.gs[GeneratorType::DELAY_MODULATION_ENVELOPE as usize] as f32,
188 )
189 }
190
191 pub fn get_attack_modulation_envelope(&self) -> f32 {
192 SoundFontMath::cents_to_multiplying_factor(
193 self.gs[GeneratorType::ATTACK_MODULATION_ENVELOPE as usize] as f32,
194 )
195 }
196
197 pub fn get_hold_modulation_envelope(&self) -> f32 {
198 SoundFontMath::cents_to_multiplying_factor(
199 self.gs[GeneratorType::HOLD_MODULATION_ENVELOPE as usize] as f32,
200 )
201 }
202
203 pub fn get_decay_modulation_envelope(&self) -> f32 {
204 SoundFontMath::cents_to_multiplying_factor(
205 self.gs[GeneratorType::DECAY_MODULATION_ENVELOPE as usize] as f32,
206 )
207 }
208
209 pub fn get_sustain_modulation_envelope(&self) -> f32 {
210 0.1_f32 * self.gs[GeneratorType::SUSTAIN_MODULATION_ENVELOPE as usize] as f32
211 }
212
213 pub fn get_release_modulation_envelope(&self) -> f32 {
214 SoundFontMath::cents_to_multiplying_factor(
215 self.gs[GeneratorType::RELEASE_MODULATION_ENVELOPE as usize] as f32,
216 )
217 }
218
219 pub fn get_key_number_to_modulation_envelope_hold(&self) -> i32 {
220 self.gs[GeneratorType::KEY_NUMBER_TO_MODULATION_ENVELOPE_HOLD as usize] as i32
221 }
222
223 pub fn get_key_number_to_modulation_envelope_decay(&self) -> i32 {
224 self.gs[GeneratorType::KEY_NUMBER_TO_MODULATION_ENVELOPE_DECAY as usize] as i32
225 }
226
227 pub fn get_delay_volume_envelope(&self) -> f32 {
228 SoundFontMath::cents_to_multiplying_factor(
229 self.gs[GeneratorType::DELAY_VOLUME_ENVELOPE as usize] as f32,
230 )
231 }
232
233 pub fn get_attack_volume_envelope(&self) -> f32 {
234 SoundFontMath::cents_to_multiplying_factor(
235 self.gs[GeneratorType::ATTACK_VOLUME_ENVELOPE as usize] as f32,
236 )
237 }
238
239 pub fn get_hold_volume_envelope(&self) -> f32 {
240 SoundFontMath::cents_to_multiplying_factor(
241 self.gs[GeneratorType::HOLD_VOLUME_ENVELOPE as usize] as f32,
242 )
243 }
244
245 pub fn get_decay_volume_envelope(&self) -> f32 {
246 SoundFontMath::cents_to_multiplying_factor(
247 self.gs[GeneratorType::DECAY_VOLUME_ENVELOPE as usize] as f32,
248 )
249 }
250
251 pub fn get_sustain_volume_envelope(&self) -> f32 {
252 0.1_f32 * self.gs[GeneratorType::SUSTAIN_VOLUME_ENVELOPE as usize] as f32
253 }
254
255 pub fn get_release_volume_envelope(&self) -> f32 {
256 SoundFontMath::cents_to_multiplying_factor(
257 self.gs[GeneratorType::RELEASE_VOLUME_ENVELOPE as usize] as f32,
258 )
259 }
260
261 pub fn get_key_number_to_volume_envelope_hold(&self) -> i32 {
262 self.gs[GeneratorType::KEY_NUMBER_TO_VOLUME_ENVELOPE_HOLD as usize] as i32
263 }
264
265 pub fn get_key_number_to_volume_envelope_decay(&self) -> i32 {
266 self.gs[GeneratorType::KEY_NUMBER_TO_VOLUME_ENVELOPE_DECAY as usize] as i32
267 }
268
269 pub fn get_key_range_start(&self) -> i32 {
270 self.gs[GeneratorType::KEY_RANGE as usize] as i32 & 0xFF
271 }
272
273 pub fn get_key_range_end(&self) -> i32 {
274 (self.gs[GeneratorType::KEY_RANGE as usize] as i32 >> 8) & 0xFF
275 }
276
277 pub fn get_velocity_range_start(&self) -> i32 {
278 self.gs[GeneratorType::VELOCITY_RANGE as usize] as i32 & 0xFF
279 }
280
281 pub fn get_velocity_range_end(&self) -> i32 {
282 (self.gs[GeneratorType::VELOCITY_RANGE as usize] as i32 >> 8) & 0xFF
283 }
284
285 pub fn get_initial_attenuation(&self) -> f32 {
286 0.1_f32 * self.gs[GeneratorType::INITIAL_ATTENUATION as usize] as f32
287 }
288
289 pub fn get_coarse_tune(&self) -> i32 {
290 self.gs[GeneratorType::COARSE_TUNE as usize] as i32
291 }
292
293 pub fn get_fine_tune(&self) -> i32 {
294 self.gs[GeneratorType::FINE_TUNE as usize] as i32
295 }
296
297 pub fn get_scale_tuning(&self) -> i32 {
298 self.gs[GeneratorType::SCALE_TUNING as usize] as i32
299 }
300
301 pub fn get_instrument_id(&self) -> usize {
302 self.instrument
303 }
304}