rustysynth_ext/
instrument_region.rs1use crate::error::SoundFontError;
2use crate::generator::Generator;
3use crate::generator_type::GeneratorType;
4use crate::loop_mode::LoopMode;
5use crate::sample_header::SampleHeader;
6use crate::soundfont_math::SoundFontMath;
7use crate::zone::Zone;
8
9fn set_parameter(gs: &mut [i16; GeneratorType::COUNT], generator: &Generator) {
10 let index = generator.generator_type as usize;
11
12 if index < gs.len() {
14 gs[index] = generator.value as i16;
15 }
16}
17
18#[derive(Debug)]
21#[non_exhaustive]
22pub struct InstrumentRegion {
23 pub(crate) gs: [i16; GeneratorType::COUNT],
24 pub(crate) sample_start: i32,
25 pub(crate) sample_end: i32,
26 pub(crate) sample_start_loop: i32,
27 pub(crate) sample_end_loop: i32,
28 pub(crate) sample_sample_rate: i32,
29 pub(crate) sample_original_pitch: i32,
30 pub(crate) sample_pitch_correction: i32,
31}
32
33impl InstrumentRegion {
34 fn new(
35 instrument_id: usize,
36 global: &Zone,
37 local: &Zone,
38 samples: &[SampleHeader],
39 ) -> Result<Self, SoundFontError> {
40 let mut gs: [i16; GeneratorType::COUNT] = [0; GeneratorType::COUNT];
41 gs[GeneratorType::INITIAL_FILTER_CUTOFF_FREQUENCY as usize] = 13500;
42 gs[GeneratorType::DELAY_MODULATION_LFO as usize] = -12000;
43 gs[GeneratorType::DELAY_VIBRATO_LFO as usize] = -12000;
44 gs[GeneratorType::DELAY_MODULATION_ENVELOPE as usize] = -12000;
45 gs[GeneratorType::ATTACK_MODULATION_ENVELOPE as usize] = -12000;
46 gs[GeneratorType::HOLD_MODULATION_ENVELOPE as usize] = -12000;
47 gs[GeneratorType::DECAY_MODULATION_ENVELOPE as usize] = -12000;
48 gs[GeneratorType::RELEASE_MODULATION_ENVELOPE as usize] = -12000;
49 gs[GeneratorType::DELAY_VOLUME_ENVELOPE as usize] = -12000;
50 gs[GeneratorType::ATTACK_VOLUME_ENVELOPE as usize] = -12000;
51 gs[GeneratorType::HOLD_VOLUME_ENVELOPE as usize] = -12000;
52 gs[GeneratorType::DECAY_VOLUME_ENVELOPE as usize] = -12000;
53 gs[GeneratorType::RELEASE_VOLUME_ENVELOPE as usize] = -12000;
54 gs[GeneratorType::KEY_RANGE as usize] = 0x7F00;
55 gs[GeneratorType::VELOCITY_RANGE as usize] = 0x7F00;
56 gs[GeneratorType::KEY_NUMBER as usize] = -1;
57 gs[GeneratorType::VELOCITY as usize] = -1;
58 gs[GeneratorType::SCALE_TUNING as usize] = 100;
59 gs[GeneratorType::OVERRIDING_ROOT_KEY as usize] = -1;
60
61 for generator in global.generators.iter() {
62 set_parameter(&mut gs, generator);
63 }
64
65 for generator in local.generators.iter() {
66 set_parameter(&mut gs, generator);
67 }
68
69 let sample_id = gs[GeneratorType::SAMPLE_ID as usize] as usize;
70 if sample_id >= samples.len() {
71 return Err(SoundFontError::InvalidSampleId {
72 instrument_id,
73 sample_id,
74 });
75 }
76 let sample = &samples[sample_id];
77
78 Ok(Self {
79 gs,
80 sample_start: sample.start,
81 sample_end: sample.end,
82 sample_start_loop: sample.start_loop,
83 sample_end_loop: sample.end_loop,
84 sample_sample_rate: sample.sample_rate,
85 sample_original_pitch: sample.original_pitch as i32,
86 sample_pitch_correction: sample.pitch_correction as i32,
87 })
88 }
89
90 pub(crate) fn create(
91 instrument_id: usize,
92 zones: &[Zone],
93 samples: &[SampleHeader],
94 ) -> Result<Vec<InstrumentRegion>, SoundFontError> {
95 if zones[0].generators.is_empty()
97 || zones[0].generators.last().unwrap().generator_type != GeneratorType::SAMPLE_ID
98 {
99 let global = &zones[0];
101
102 let count = zones.len() - 1;
104 let mut regions: Vec<InstrumentRegion> = Vec::with_capacity(count);
105 for i in 0..count {
106 regions.push(InstrumentRegion::new(
107 instrument_id,
108 global,
109 &zones[i + 1],
110 samples,
111 )?);
112 }
113
114 Ok(regions)
115 } else {
116 let count = zones.len();
118 let mut regions: Vec<InstrumentRegion> = Vec::with_capacity(count);
119 for zone in zones.iter().take(count) {
120 regions.push(InstrumentRegion::new(
121 instrument_id,
122 &Zone::empty(),
123 zone,
124 samples,
125 )?);
126 }
127
128 Ok(regions)
129 }
130 }
131
132 pub fn contains(&self, key: i32, velocity: i32) -> bool {
140 let contains_key = self.get_key_range_start() <= key && key <= self.get_key_range_end();
141 let contains_velocity = self.get_velocity_range_start() <= velocity
142 && velocity <= self.get_velocity_range_end();
143 contains_key && contains_velocity
144 }
145
146 pub fn get_sample_start(&self) -> i32 {
147 self.sample_start + self.get_start_address_offset()
148 }
149
150 pub fn get_sample_end(&self) -> i32 {
151 self.sample_end + self.get_end_address_offset()
152 }
153
154 pub fn get_sample_start_loop(&self) -> i32 {
155 self.sample_start_loop + self.get_start_loop_address_offset()
156 }
157
158 pub fn get_sample_end_loop(&self) -> i32 {
159 self.sample_end_loop + self.get_end_loop_address_offset()
160 }
161
162 pub fn get_start_address_offset(&self) -> i32 {
163 32768 * self.gs[GeneratorType::START_ADDRESS_COARSE_OFFSET as usize] as i32
164 + self.gs[GeneratorType::START_ADDRESS_OFFSET as usize] as i32
165 }
166
167 pub fn get_end_address_offset(&self) -> i32 {
168 32768 * self.gs[GeneratorType::END_ADDRESS_COARSE_OFFSET as usize] as i32
169 + self.gs[GeneratorType::END_ADDRESS_OFFSET as usize] as i32
170 }
171
172 pub fn get_start_loop_address_offset(&self) -> i32 {
173 32768 * self.gs[GeneratorType::START_LOOP_ADDRESS_COARSE_OFFSET as usize] as i32
174 + self.gs[GeneratorType::START_LOOP_ADDRESS_OFFSET as usize] as i32
175 }
176
177 pub fn get_end_loop_address_offset(&self) -> i32 {
178 32768 * self.gs[GeneratorType::END_LOOP_ADDRESS_COARSE_OFFSET as usize] as i32
179 + self.gs[GeneratorType::END_LOOP_ADDRESS_OFFSET as usize] as i32
180 }
181
182 pub fn get_modulation_lfo_to_pitch(&self) -> i32 {
183 self.gs[GeneratorType::MODULATION_LFO_TO_PITCH as usize] as i32
184 }
185
186 pub fn get_vibrato_lfo_to_pitch(&self) -> i32 {
187 self.gs[GeneratorType::VIBRATO_LFO_TO_PITCH as usize] as i32
188 }
189
190 pub fn get_modulation_envelope_to_pitch(&self) -> i32 {
191 self.gs[GeneratorType::MODULATION_ENVELOPE_TO_PITCH as usize] as i32
192 }
193
194 pub fn get_initial_filter_cutoff_frequency(&self) -> f32 {
195 SoundFontMath::cents_to_hertz(
196 self.gs[GeneratorType::INITIAL_FILTER_CUTOFF_FREQUENCY as usize] as f32,
197 )
198 }
199
200 pub fn get_initial_filter_q(&self) -> f32 {
201 0.1_f32 * self.gs[GeneratorType::INITIAL_FILTER_Q as usize] as f32
202 }
203
204 pub fn get_modulation_lfo_to_filter_cutoff_frequency(&self) -> i32 {
205 self.gs[GeneratorType::MODULATION_LFO_TO_FILTER_CUTOFF_FREQUENCY as usize] as i32
206 }
207
208 pub fn get_modulation_envelope_to_filter_cutoff_frequency(&self) -> i32 {
209 self.gs[GeneratorType::MODULATION_ENVELOPE_TO_FILTER_CUTOFF_FREQUENCY as usize] as i32
210 }
211
212 pub fn get_modulation_lfo_to_volume(&self) -> f32 {
213 0.1_f32 * self.gs[GeneratorType::MODULATION_LFO_TO_VOLUME as usize] as f32
214 }
215
216 pub fn get_chorus_effects_send(&self) -> f32 {
217 0.1_f32 * self.gs[GeneratorType::CHORUS_EFFECTS_SEND as usize] as f32
218 }
219
220 pub fn get_reverb_effects_send(&self) -> f32 {
221 0.1_f32 * self.gs[GeneratorType::REVERB_EFFECTS_SEND as usize] as f32
222 }
223
224 pub fn get_pan(&self) -> f32 {
225 0.1_f32 * self.gs[GeneratorType::PAN as usize] as f32
226 }
227
228 pub fn get_delay_modulation_lfo(&self) -> f32 {
229 SoundFontMath::timecents_to_seconds(
230 self.gs[GeneratorType::DELAY_MODULATION_LFO as usize] as f32,
231 )
232 }
233
234 pub fn get_frequency_modulation_lfo(&self) -> f32 {
235 SoundFontMath::cents_to_hertz(
236 self.gs[GeneratorType::FREQUENCY_MODULATION_LFO as usize] as f32,
237 )
238 }
239
240 pub fn get_delay_vibrato_lfo(&self) -> f32 {
241 SoundFontMath::timecents_to_seconds(
242 self.gs[GeneratorType::DELAY_VIBRATO_LFO as usize] as f32,
243 )
244 }
245
246 pub fn get_frequency_vibrato_lfo(&self) -> f32 {
247 SoundFontMath::cents_to_hertz(self.gs[GeneratorType::FREQUENCY_VIBRATO_LFO as usize] as f32)
248 }
249
250 pub fn get_delay_modulation_envelope(&self) -> f32 {
251 SoundFontMath::timecents_to_seconds(
252 self.gs[GeneratorType::DELAY_MODULATION_ENVELOPE as usize] as f32,
253 )
254 }
255
256 pub fn get_attack_modulation_envelope(&self) -> f32 {
257 SoundFontMath::timecents_to_seconds(
258 self.gs[GeneratorType::ATTACK_MODULATION_ENVELOPE as usize] as f32,
259 )
260 }
261
262 pub fn get_hold_modulation_envelope(&self) -> f32 {
263 SoundFontMath::timecents_to_seconds(
264 self.gs[GeneratorType::HOLD_MODULATION_ENVELOPE as usize] as f32,
265 )
266 }
267
268 pub fn get_decay_modulation_envelope(&self) -> f32 {
269 SoundFontMath::timecents_to_seconds(
270 self.gs[GeneratorType::DECAY_MODULATION_ENVELOPE as usize] as f32,
271 )
272 }
273
274 pub fn get_sustain_modulation_envelope(&self) -> f32 {
275 0.1_f32 * self.gs[GeneratorType::SUSTAIN_MODULATION_ENVELOPE as usize] as f32
276 }
277
278 pub fn get_release_modulation_envelope(&self) -> f32 {
279 SoundFontMath::timecents_to_seconds(
280 self.gs[GeneratorType::RELEASE_MODULATION_ENVELOPE as usize] as f32,
281 )
282 }
283
284 pub fn get_key_number_to_modulation_envelope_hold(&self) -> i32 {
285 self.gs[GeneratorType::KEY_NUMBER_TO_MODULATION_ENVELOPE_HOLD as usize] as i32
286 }
287
288 pub fn get_key_number_to_modulation_envelope_decay(&self) -> i32 {
289 self.gs[GeneratorType::KEY_NUMBER_TO_MODULATION_ENVELOPE_DECAY as usize] as i32
290 }
291
292 pub fn get_delay_volume_envelope(&self) -> f32 {
293 SoundFontMath::timecents_to_seconds(
294 self.gs[GeneratorType::DELAY_VOLUME_ENVELOPE as usize] as f32,
295 )
296 }
297
298 pub fn get_attack_volume_envelope(&self) -> f32 {
299 SoundFontMath::timecents_to_seconds(
300 self.gs[GeneratorType::ATTACK_VOLUME_ENVELOPE as usize] as f32,
301 )
302 }
303
304 pub fn get_hold_volume_envelope(&self) -> f32 {
305 SoundFontMath::timecents_to_seconds(
306 self.gs[GeneratorType::HOLD_VOLUME_ENVELOPE as usize] as f32,
307 )
308 }
309
310 pub fn get_decay_volume_envelope(&self) -> f32 {
311 SoundFontMath::timecents_to_seconds(
312 self.gs[GeneratorType::DECAY_VOLUME_ENVELOPE as usize] as f32,
313 )
314 }
315
316 pub fn get_sustain_volume_envelope(&self) -> f32 {
317 0.1_f32 * self.gs[GeneratorType::SUSTAIN_VOLUME_ENVELOPE as usize] as f32
318 }
319
320 pub fn get_release_volume_envelope(&self) -> f32 {
321 SoundFontMath::timecents_to_seconds(
322 self.gs[GeneratorType::RELEASE_VOLUME_ENVELOPE as usize] as f32,
323 )
324 }
325
326 pub fn get_key_number_to_volume_envelope_hold(&self) -> i32 {
327 self.gs[GeneratorType::KEY_NUMBER_TO_VOLUME_ENVELOPE_HOLD as usize] as i32
328 }
329
330 pub fn get_key_number_to_volume_envelope_decay(&self) -> i32 {
331 self.gs[GeneratorType::KEY_NUMBER_TO_VOLUME_ENVELOPE_DECAY as usize] as i32
332 }
333
334 pub fn get_key_range_start(&self) -> i32 {
335 self.gs[GeneratorType::KEY_RANGE as usize] as i32 & 0xFF
336 }
337
338 pub fn get_key_range_end(&self) -> i32 {
339 (self.gs[GeneratorType::KEY_RANGE as usize] as i32 >> 8) & 0xFF
340 }
341
342 pub fn get_velocity_range_start(&self) -> i32 {
343 self.gs[GeneratorType::VELOCITY_RANGE as usize] as i32 & 0xFF
344 }
345
346 pub fn get_velocity_range_end(&self) -> i32 {
347 (self.gs[GeneratorType::VELOCITY_RANGE as usize] as i32 >> 8) & 0xFF
348 }
349
350 pub fn get_initial_attenuation(&self) -> f32 {
351 0.1_f32 * self.gs[GeneratorType::INITIAL_ATTENUATION as usize] as f32
352 }
353
354 pub fn get_coarse_tune(&self) -> i32 {
355 self.gs[GeneratorType::COARSE_TUNE as usize] as i32
356 }
357
358 pub fn get_fine_tune(&self) -> i32 {
359 self.gs[GeneratorType::FINE_TUNE as usize] as i32 + self.sample_pitch_correction
360 }
361
362 pub fn get_sample_modes(&self) -> LoopMode {
363 LoopMode::from_i16(self.gs[GeneratorType::SAMPLE_MODES as usize])
364 }
365
366 pub fn get_scale_tuning(&self) -> i32 {
367 self.gs[GeneratorType::SCALE_TUNING as usize] as i32
368 }
369
370 pub fn get_exclusive_class(&self) -> i32 {
371 self.gs[GeneratorType::EXCLUSIVE_CLASS as usize] as i32
372 }
373
374 pub fn get_root_key(&self) -> i32 {
375 if self.gs[GeneratorType::OVERRIDING_ROOT_KEY as usize] != -1 {
376 self.gs[GeneratorType::OVERRIDING_ROOT_KEY as usize] as i32
377 } else {
378 self.sample_original_pitch
379 }
380 }
381
382 pub fn get_sample_id(&self) -> usize {
383 self.gs[GeneratorType::SAMPLE_ID as usize] as usize
384 }
385}