1use std::cmp;
2use std::collections::HashMap;
3use std::sync::Arc;
4
5use crate::array_math::ArrayMath;
6use crate::channel::Channel;
7use crate::chorus::Chorus;
8use crate::error::SynthesizerError;
9use crate::region_pair::RegionPair;
10use crate::reverb::Reverb;
11use crate::soundfont::SoundFont;
12use crate::soundfont_math::SoundFontMath;
13use crate::synthesizer_settings::SynthesizerSettings;
14use crate::voice_collection::VoiceCollection;
15
16#[derive(Debug)]
18#[non_exhaustive]
19pub struct Synthesizer {
20 pub(crate) sound_font: Arc<SoundFont>,
21 pub(crate) sample_rate: i32,
22 pub(crate) block_size: usize,
23 pub(crate) maximum_polyphony: usize,
24
25 preset_lookup: HashMap<i32, usize>,
26 default_preset: usize,
27
28 channels: Vec<Channel>,
29
30 voices: VoiceCollection,
31
32 block_left: Vec<f32>,
33 block_right: Vec<f32>,
34
35 inverse_block_size: f32,
36
37 block_read: usize,
38
39 master_volume: f32,
40
41 effects: Option<Effects>,
42}
43
44impl Synthesizer {
45 pub const CHANNEL_COUNT: usize = 16;
47 pub const PERCUSSION_CHANNEL: usize = 9;
49
50 pub fn new(
57 sound_font: &Arc<SoundFont>,
58 settings: &SynthesizerSettings,
59 ) -> Result<Self, SynthesizerError> {
60 settings.validate()?;
61
62 let mut preset_lookup: HashMap<i32, usize> = HashMap::new();
63
64 let mut min_preset_id = i32::MAX;
65 let mut default_preset: usize = 0;
66 for i in 0..sound_font.presets.len() {
67 let preset = &sound_font.presets[i];
68
69 let preset_id = (preset.bank_number << 16) | preset.patch_number;
74 preset_lookup.insert(preset_id, i);
75
76 if preset_id < min_preset_id {
79 default_preset = i;
80 min_preset_id = preset_id;
81 }
82 }
83
84 let mut channels: Vec<Channel> = Vec::with_capacity(Synthesizer::CHANNEL_COUNT);
85 for i in 0..Synthesizer::CHANNEL_COUNT {
86 channels.push(Channel::new(i == Synthesizer::PERCUSSION_CHANNEL));
87 }
88
89 let voices = VoiceCollection::new(settings);
90
91 let block_left: Vec<f32> = vec![0_f32; settings.block_size];
92 let block_right: Vec<f32> = vec![0_f32; settings.block_size];
93
94 let inverse_block_size = 1_f32 / settings.block_size as f32;
95
96 let block_read = settings.block_size;
97
98 let master_volume = 0.5_f32;
99
100 let effects = if settings.enable_reverb_and_chorus {
101 Some(Effects::new(settings))
102 } else {
103 None
104 };
105
106 Ok(Self {
107 sound_font: Arc::clone(sound_font),
108 sample_rate: settings.sample_rate,
109 block_size: settings.block_size,
110 maximum_polyphony: settings.maximum_polyphony,
111 preset_lookup,
112 default_preset,
113 channels,
114 voices,
115 block_left,
116 block_right,
117 inverse_block_size,
118 block_read,
119 master_volume,
120 effects,
121 })
122 }
123
124 pub fn process_midi_message(&mut self, channel: i32, command: i32, data1: i32, data2: i32) {
133 if !(0 <= channel && channel < self.channels.len() as i32) {
134 return;
135 }
136
137 let channel_info = &mut self.channels[channel as usize];
138
139 match command {
140 0x80 => self.note_off(channel, data1), 0x90 => self.note_on(channel, data1, data2), 0xB0 => match data1 {
144 0x00 => channel_info.set_bank(data2), 0x01 => channel_info.set_modulation_coarse(data2), 0x21 => channel_info.set_modulation_fine(data2), 0x06 => channel_info.data_entry_coarse(data2), 0x26 => channel_info.data_entry_fine(data2), 0x07 => channel_info.set_volume_coarse(data2), 0x27 => channel_info.set_volume_fine(data2), 0x0A => channel_info.set_pan_coarse(data2), 0x2A => channel_info.set_pan_fine(data2), 0x0B => channel_info.set_expression_coarse(data2), 0x2B => channel_info.set_expression_fine(data2), 0x40 => channel_info.set_hold_pedal(data2), 0x5B => channel_info.set_reverb_send(data2), 0x5D => channel_info.set_chorus_send(data2), 0x63 => channel_info.set_nrpn_coarse(data2), 0x62 => channel_info.set_nrpn_fine(data2), 0x65 => channel_info.set_rpn_coarse(data2), 0x64 => channel_info.set_rpn_fine(data2), 0x78 => self.note_off_all_channel(channel, true), 0x79 => self.reset_all_controllers_channel(channel), 0x7B => self.note_off_all_channel(channel, false), _ => (),
166 },
167 0xC0 => channel_info.set_patch(data1), 0xE0 => channel_info.set_pitch_bend(data1, data2), _ => (),
170 }
171 }
172
173 pub fn note_off(&mut self, channel: i32, key: i32) {
180 if !(0 <= channel && channel < self.channels.len() as i32) {
181 return;
182 }
183
184 for voice in self.voices.get_active_voices().iter_mut() {
185 if voice.channel() == channel && voice.key() == key {
186 voice.end();
187 }
188 }
189 }
190
191 pub fn note_on(&mut self, channel: i32, key: i32, velocity: i32) {
199 if velocity == 0 {
200 self.note_off(channel, key);
201 return;
202 }
203
204 if !(0 <= channel && channel < self.channels.len() as i32) {
205 return;
206 }
207
208 let channel_info = &self.channels[channel as usize];
209
210 let preset_id = (channel_info.get_bank_number() << 16) | channel_info.get_patch_number();
211
212 let mut preset = self.default_preset;
213 match self.preset_lookup.get(&preset_id) {
214 Some(value) => preset = *value,
215 None => {
216 let gm_preset_id = if channel_info.get_bank_number() < 128 {
220 channel_info.get_patch_number()
221 } else {
222 128 << 16
223 };
224
225 if let Some(value) = self.preset_lookup.get(&gm_preset_id) {
227 preset = *value
228 }
229 }
230 }
231
232 let preset = &self.sound_font.presets[preset];
233 for preset_region in preset.regions.iter() {
234 if preset_region.contains(key, velocity) {
235 let instrument = &self.sound_font.instruments[preset_region.instrument];
236 for instrument_region in instrument.regions.iter() {
237 if instrument_region.contains(key, velocity) {
238 let region_pair = RegionPair::new(preset_region, instrument_region);
239
240 if let Some(value) = self.voices.request_new(instrument_region, channel) {
241 value.start(®ion_pair, channel, key, velocity)
242 }
243 }
244 }
245 }
246 }
247 }
248
249 pub fn note_off_all(&mut self, immediate: bool) {
255 if immediate {
256 self.voices.clear();
257 } else {
258 for voice in self.voices.get_active_voices().iter_mut() {
259 voice.end();
260 }
261 }
262 }
263
264 pub fn note_off_all_channel(&mut self, channel: i32, immediate: bool) {
271 if immediate {
272 for voice in self.voices.get_active_voices().iter_mut() {
273 if voice.channel() == channel {
274 voice.kill();
275 }
276 }
277 } else {
278 for voice in self.voices.get_active_voices().iter_mut() {
279 if voice.channel() == channel {
280 voice.end();
281 }
282 }
283 }
284 }
285
286 pub fn reset_all_controllers(&mut self) {
288 for channel in &mut self.channels {
289 channel.reset_all_controllers();
290 }
291 }
292
293 pub fn reset_all_controllers_channel(&mut self, channel: i32) {
299 if !(0 <= channel && channel < self.channels.len() as i32) {
300 return;
301 }
302
303 self.channels[channel as usize].reset_all_controllers();
304 }
305
306 pub fn reset(&mut self) {
308 self.voices.clear();
309
310 for channel in &mut self.channels {
311 channel.reset();
312 }
313
314 if let Some(effects) = self.effects.as_mut() {
315 effects.reverb.mute();
316 effects.chorus.mute();
317 }
318
319 self.block_read = self.block_size;
320 }
321
322 pub fn render(&mut self, left: &mut [f32], right: &mut [f32]) {
333 if left.len() != right.len() {
334 panic!("The output buffers for the left and right must be the same length.");
335 }
336
337 let left_length = left.len();
338
339 let mut wrote = 0;
340 while wrote < left_length {
341 if self.block_read == self.block_size {
342 self.render_block();
343 self.block_read = 0;
344 }
345
346 let src_rem = self.block_size - self.block_read;
347 let dst_rem = left_length - wrote;
348 let rem = cmp::min(src_rem, dst_rem);
349
350 for t in 0..rem {
351 left[wrote + t] = self.block_left[self.block_read + t];
352 right[wrote + t] = self.block_right[self.block_read + t];
353 }
354
355 self.block_read += rem;
356 wrote += rem;
357 }
358 }
359
360 fn render_block(&mut self) {
361 self.voices
362 .process(&self.sound_font.wave_data, &self.channels);
363
364 self.block_left.fill(0_f32);
365 self.block_right.fill(0_f32);
366 for voice in self.voices.get_active_voices().iter_mut() {
367 let previous_gain_left = self.master_volume * voice.previous_mix_gain_left;
368 let current_gain_left = self.master_volume * voice.current_mix_gain_left;
369 Synthesizer::write_block(
370 previous_gain_left,
371 current_gain_left,
372 voice.block(),
373 &mut self.block_left[..],
374 self.inverse_block_size,
375 );
376 let previous_gain_right = self.master_volume * voice.previous_mix_gain_right;
377 let current_gain_right = self.master_volume * voice.current_mix_gain_right;
378 Synthesizer::write_block(
379 previous_gain_right,
380 current_gain_right,
381 voice.block(),
382 &mut self.block_right[..],
383 self.inverse_block_size,
384 );
385 }
386
387 if let Some(effects) = self.effects.as_mut() {
388 let chorus = &mut effects.chorus;
389 let chorus_input_left = &mut effects.chorus_input_left[..];
390 let chorus_input_right = &mut effects.chorus_input_right[..];
391 let chorus_output_left = &mut effects.chorus_output_left[..];
392 let chorus_output_right = &mut effects.chorus_output_right[..];
393 chorus_input_left.fill(0_f32);
394 chorus_input_right.fill(0_f32);
395 for voice in self.voices.get_active_voices().iter_mut() {
396 let previous_gain_left = voice.previous_chorus_send * voice.previous_mix_gain_left;
397 let current_gain_left = voice.current_chorus_send * voice.current_mix_gain_left;
398 Synthesizer::write_block(
399 previous_gain_left,
400 current_gain_left,
401 voice.block(),
402 chorus_input_left,
403 self.inverse_block_size,
404 );
405 let previous_gain_right =
406 voice.previous_chorus_send * voice.previous_mix_gain_right;
407 let current_gain_right = voice.current_chorus_send * voice.current_mix_gain_right;
408 Synthesizer::write_block(
409 previous_gain_right,
410 current_gain_right,
411 voice.block(),
412 chorus_input_right,
413 self.inverse_block_size,
414 );
415 }
416 chorus.process(
417 chorus_input_left,
418 chorus_input_right,
419 chorus_output_left,
420 chorus_output_right,
421 );
422 ArrayMath::multiply_add(
423 self.master_volume,
424 chorus_output_left,
425 &mut self.block_left[..],
426 );
427 ArrayMath::multiply_add(
428 self.master_volume,
429 chorus_output_right,
430 &mut self.block_right[..],
431 );
432
433 let reverb = &mut effects.reverb;
434 let reverb_input = &mut effects.reverb_input[..];
435 let reverb_output_left = &mut effects.reverb_output_left[..];
436 let reverb_output_right = &mut effects.reverb_output_right[..];
437 reverb_input.fill(0_f32);
438 for voice in self.voices.get_active_voices().iter_mut() {
439 let previous_gain = reverb.get_input_gain()
440 * voice.previous_reverb_send
441 * (voice.previous_mix_gain_left + voice.previous_mix_gain_right);
442 let current_gain = reverb.get_input_gain()
443 * voice.current_reverb_send
444 * (voice.current_mix_gain_left + voice.current_mix_gain_right);
445 Synthesizer::write_block(
446 previous_gain,
447 current_gain,
448 voice.block(),
449 &mut reverb_input[..],
450 self.inverse_block_size,
451 );
452 }
453
454 reverb.process(reverb_input, reverb_output_left, reverb_output_right);
455 ArrayMath::multiply_add(
456 self.master_volume,
457 reverb_output_left,
458 &mut self.block_left[..],
459 );
460 ArrayMath::multiply_add(
461 self.master_volume,
462 reverb_output_right,
463 &mut self.block_right[..],
464 );
465 }
466 }
467
468 fn write_block(
469 previous_gain: f32,
470 current_gain: f32,
471 source: &[f32],
472 destination: &mut [f32],
473 inverse_block_size: f32,
474 ) {
475 if SoundFontMath::max(previous_gain, current_gain) < SoundFontMath::NON_AUDIBLE {
476 return;
477 }
478
479 if (current_gain - previous_gain).abs() < 1.0E-3_f32 {
480 ArrayMath::multiply_add(current_gain, source, destination);
481 } else {
482 let step = inverse_block_size * (current_gain - previous_gain);
483 ArrayMath::multiply_add_slope(previous_gain, step, source, destination);
484 }
485 }
486
487 pub fn get_sound_font(&self) -> &SoundFont {
489 &self.sound_font
490 }
491
492 pub fn get_sample_rate(&self) -> i32 {
494 self.sample_rate
495 }
496
497 pub fn get_block_size(&self) -> usize {
499 self.block_size
500 }
501
502 pub fn get_maximum_polyphony(&self) -> usize {
504 self.maximum_polyphony
505 }
506
507 pub fn get_enable_reverb_and_chorus(&self) -> bool {
509 self.effects.is_some()
510 }
511
512 pub fn get_master_volume(&self) -> f32 {
514 self.master_volume
515 }
516
517 pub fn set_master_volume(&mut self, value: f32) {
523 self.master_volume = value;
524 }
525}
526
527#[derive(Debug)]
528struct Effects {
529 reverb: Reverb,
530 reverb_input: Vec<f32>,
531 reverb_output_left: Vec<f32>,
532 reverb_output_right: Vec<f32>,
533
534 chorus: Chorus,
535 chorus_input_left: Vec<f32>,
536 chorus_input_right: Vec<f32>,
537 chorus_output_left: Vec<f32>,
538 chorus_output_right: Vec<f32>,
539}
540
541impl Effects {
542 fn new(settings: &SynthesizerSettings) -> Effects {
543 Self {
544 reverb: Reverb::new(settings.sample_rate),
545 reverb_input: vec![0_f32; settings.block_size],
546 reverb_output_left: vec![0_f32; settings.block_size],
547 reverb_output_right: vec![0_f32; settings.block_size],
548 chorus: Chorus::new(settings.sample_rate, 0.002, 0.0019, 0.4),
549 chorus_input_left: vec![0_f32; settings.block_size],
550 chorus_input_right: vec![0_f32; settings.block_size],
551 chorus_output_left: vec![0_f32; settings.block_size],
552 chorus_output_right: vec![0_f32; settings.block_size],
553 }
554 }
555}