1use std::sync::{atomic::AtomicU64, Arc};
2
3use crate::{
4 effects::MultiChannelBiQuad,
5 helpers::{db_to_amp, prepapre_cache_vec, sum_simd, FREQS},
6 voice::VoiceControlData,
7 AudioStreamParams, ChannelCount,
8};
9
10use xsynth_soundfonts::FilterType;
11
12use self::{key::KeyData, params::VoiceChannelParams};
13
14use super::AudioPipe;
15
16use biquad::Q_BUTTERWORTH_F32;
17
18use rayon::prelude::*;
19
20mod channel_sf;
21mod key;
22mod params;
23mod voice_buffer;
24mod voice_spawner;
25
26mod event;
27pub use event::*;
28
29pub use params::VoiceChannelStatsReader;
30
31pub(crate) struct ValueLerp {
32 lerp_length: f32,
33 step: f32,
34 current: f32,
35 end: f32,
36}
37
38impl ValueLerp {
39 pub fn new(current: f32, sample_rate: u32) -> Self {
40 Self {
41 lerp_length: sample_rate as f32 * 0.01,
42 step: 0.0,
43 current,
44 end: current,
45 }
46 }
47
48 pub fn set_end(&mut self, end: f32) {
49 self.step = (end - self.current) / self.lerp_length;
50 self.end = end;
51 }
52
53 pub fn get_next(&mut self) -> f32 {
54 if self.end > self.current {
55 self.current = (self.current + self.step).min(self.end);
56 } else if self.end < self.current {
57 self.current = (self.current + self.step).max(self.end);
58 }
59 self.current
60 }
61}
62
63struct Key {
64 data: KeyData,
65 audio_cache: Vec<f32>,
66 event_cache: Vec<KeyNoteEvent>,
67}
68
69impl Key {
70 pub fn new(key: u8, shared_voice_counter: Arc<AtomicU64>, options: ChannelInitOptions) -> Self {
71 Key {
72 data: KeyData::new(key, shared_voice_counter, options),
73 audio_cache: Vec::new(),
74 event_cache: Vec::new(),
75 }
76 }
77}
78
79struct ControlEventData {
80 selected_lsb: i8,
81 selected_msb: i8,
82 pitch_bend_sensitivity_lsb: u8,
83 pitch_bend_sensitivity_msb: u8,
84 pitch_bend_sensitivity: f32,
85 pitch_bend_value: f32,
86 fine_tune_lsb: u8,
87 fine_tune_msb: u8,
88 fine_tune_value: f32,
89 coarse_tune_value: f32,
90 volume: ValueLerp, pan: ValueLerp, cutoff: Option<f32>,
93 resonance: Option<f32>,
94 expression: ValueLerp,
95}
96
97impl ControlEventData {
98 pub fn new_defaults(sample_rate: u32) -> Self {
99 ControlEventData {
100 selected_lsb: -1,
101 selected_msb: -1,
102 pitch_bend_sensitivity_lsb: 0,
103 pitch_bend_sensitivity_msb: 2,
104 pitch_bend_sensitivity: 2.0,
105 pitch_bend_value: 0.0,
106 fine_tune_lsb: 0,
107 fine_tune_msb: 0,
108 fine_tune_value: 0.0,
109 coarse_tune_value: 0.0,
110 volume: ValueLerp::new(1.0, sample_rate),
111 pan: ValueLerp::new(0.5, sample_rate),
112 cutoff: None,
113 resonance: None,
114 expression: ValueLerp::new(1.0, sample_rate),
115 }
116 }
117}
118
119#[derive(Clone, Copy, Debug, PartialEq)]
121#[cfg_attr(
122 feature = "serde",
123 derive(serde::Deserialize, serde::Serialize),
124 serde(default)
125)]
126pub struct ChannelInitOptions {
127 pub fade_out_killing: bool,
133}
134
135#[allow(clippy::derivable_impls)]
136impl Default for ChannelInitOptions {
137 fn default() -> Self {
138 Self {
139 fade_out_killing: false,
140 }
141 }
142}
143
144pub struct VoiceChannel {
164 key_voices: Vec<Key>,
165
166 params: VoiceChannelParams,
167 threadpool: Option<Arc<rayon::ThreadPool>>,
168
169 stream_params: AudioStreamParams,
170
171 control_event_data: ControlEventData,
173
174 voice_control_data: VoiceControlData,
176
177 cutoff: MultiChannelBiQuad,
179}
180
181impl VoiceChannel {
182 pub fn new(
190 options: ChannelInitOptions,
191 stream_params: AudioStreamParams,
192 threadpool: Option<Arc<rayon::ThreadPool>>,
193 ) -> VoiceChannel {
194 fn fill_key_array<T, F: Fn(u8) -> T>(func: F) -> Vec<T> {
195 let mut vec = Vec::with_capacity(128);
196 for i in 0..128 {
197 vec.push(func(i));
198 }
199 vec
200 }
201
202 let params = VoiceChannelParams::new(stream_params);
203 let shared_voice_counter = params.stats.voice_counter.clone();
204
205 VoiceChannel {
206 params,
207 key_voices: fill_key_array(|i| Key::new(i, shared_voice_counter.clone(), options)),
208
209 threadpool,
210
211 stream_params,
212
213 control_event_data: ControlEventData::new_defaults(stream_params.sample_rate),
214 voice_control_data: VoiceControlData::new_defaults(),
215
216 cutoff: MultiChannelBiQuad::new(
217 stream_params.channels.count() as usize,
218 FilterType::LowPass,
219 20000.0,
220 stream_params.sample_rate as f32,
221 None,
222 ),
223 }
224 }
225
226 fn apply_channel_effects(&mut self, out: &mut [f32]) {
227 let control = &mut self.control_event_data;
228
229 match self.stream_params.channels {
230 ChannelCount::Mono => {
231 for sample in out.iter_mut() {
233 let vol = control.volume.get_next() * control.expression.get_next();
234 let vol = vol.powi(2);
235 *sample *= vol;
236 }
237 }
238 ChannelCount::Stereo => {
239 for sample in out.chunks_mut(2) {
241 let vol = control.volume.get_next() * control.expression.get_next();
242 let vol = vol.powi(2);
243 sample[0] *= vol;
244 sample[1] *= vol;
245 }
246
247 for sample in out.chunks_mut(2) {
249 let pan = control.pan.get_next();
250 sample[0] *= ((pan * std::f32::consts::PI / 2.0).cos()).min(1.0);
251 sample[1] *= ((pan * std::f32::consts::PI / 2.0).sin()).min(1.0);
252 }
253 }
254 }
255
256 if let Some(cutoff) = control.cutoff {
258 self.cutoff
259 .set_filter_type(FilterType::LowPass, cutoff, control.resonance);
260 self.cutoff.process(out);
261 }
262 }
263
264 fn push_key_events_and_render(&mut self, out: &mut [f32]) {
265 self.params.load_program();
266
267 out.fill(0.0);
268 match self.threadpool.as_ref() {
269 Some(pool) => {
270 let len = out.len();
271 let key_voices = &mut self.key_voices;
272 let params = &self.params;
273 let control_data = &self.voice_control_data;
274 pool.install(|| {
275 key_voices.par_iter_mut().for_each(move |key| {
276 for e in key.event_cache.drain(..) {
277 key.data
278 .send_event(e, control_data, ¶ms.channel_sf, params.layers);
279 }
280
281 prepapre_cache_vec(&mut key.audio_cache, len, 0.0);
282 key.data.render_to(&mut key.audio_cache);
283 });
284 });
285
286 for key in self.key_voices.iter() {
287 sum_simd(&key.audio_cache, out);
288 }
289 }
290 None => {
291 for key in self.key_voices.iter_mut() {
292 for e in key.event_cache.drain(..) {
293 key.data.send_event(
294 e,
295 &self.voice_control_data,
296 &self.params.channel_sf,
297 self.params.layers,
298 );
299 }
300
301 key.data.render_to(out);
302 }
303 }
304 }
305
306 self.apply_channel_effects(out);
307 }
308
309 fn propagate_voice_controls(&mut self) {
310 for key in self.key_voices.iter_mut() {
311 key.data.process_controls(&self.voice_control_data);
312 }
313 }
314
315 pub fn process_control_event(&mut self, event: ControlEvent) {
318 match event {
319 ControlEvent::Raw(controller, value) => match controller {
320 0x00 => {
321 self.params.set_bank(value);
323 }
324 0x64 => {
325 self.control_event_data.selected_lsb = value as i8;
326 }
327 0x65 => {
328 self.control_event_data.selected_msb = value as i8;
329 }
330 0x06 | 0x26 => {
331 let (lsb, msb) = {
332 let data = &self.control_event_data;
333 (data.selected_lsb, data.selected_msb)
334 };
335 if msb == 0 {
336 match lsb {
337 0 => {
338 match controller {
340 0x06 => {
341 self.control_event_data.pitch_bend_sensitivity_msb = value
342 }
343 0x26 => {
344 self.control_event_data.pitch_bend_sensitivity_lsb = value
345 }
346 _ => (),
347 }
348
349 let sensitivity = {
350 let data = &self.control_event_data;
351 (data.pitch_bend_sensitivity_msb as f32)
352 + (data.pitch_bend_sensitivity_lsb as f32) / 100.0
353 };
354
355 self.process_control_event(ControlEvent::PitchBendSensitivity(
356 sensitivity,
357 ))
358 }
359 1 => {
360 match controller {
362 0x06 => self.control_event_data.fine_tune_msb = value,
363 0x26 => self.control_event_data.fine_tune_lsb = value,
364 _ => (),
365 }
366 let val: u16 = ((self.control_event_data.fine_tune_msb as u16)
367 << 6)
368 + self.control_event_data.fine_tune_lsb as u16;
369 let val = (val as f32 - 4096.0) / 4096.0 * 100.0;
370 self.process_control_event(ControlEvent::FineTune(val));
371 }
372 2 => {
373 if controller == 0x06 {
375 self.process_control_event(ControlEvent::CoarseTune(
376 value as f32 - 64.0,
377 ))
378 }
379 }
380 _ => {}
381 }
382 }
383 }
384 0x07 => {
385 let vol: f32 = value as f32 / 128.0;
387 self.control_event_data.volume.set_end(vol);
388 }
389 0x0A | 0x08 => {
390 let pan: f32 = value as f32 / 128.0;
392 self.control_event_data.pan.set_end(pan);
393 }
394 0x0B => {
395 let expr = value as f32 / 128.0;
397 self.control_event_data.expression.set_end(expr);
398 }
399 0x40 => {
400 let damper = match value {
402 0..=63 => false,
403 64..=127 => true,
404 _ => false,
405 };
406
407 for key in self.key_voices.iter_mut() {
408 key.data.set_damper(damper);
409 }
410 }
411 0x47 => {
412 if value > 64 {
414 let db = (value as f32 - 64.0) / 2.4;
415 let value = db_to_amp(db) * Q_BUTTERWORTH_F32;
416 self.control_event_data.resonance = Some(value);
417 } else {
418 self.control_event_data.resonance = None;
419 }
420 }
421 0x48 => {
422 self.voice_control_data.envelope.release = Some(value);
424 self.propagate_voice_controls();
425 }
426 0x49 => {
427 self.voice_control_data.envelope.attack = Some(value);
429 self.propagate_voice_controls();
430 }
431 0x4A => {
432 if value < 64 {
434 let value = value as usize + 64;
435 let mut freq = FREQS[value];
436 if freq > 7000.0 {
437 let mult = freq / 7000.0 - 1.0;
439 let mult = mult * 2.36 + 1.0;
440 freq = mult * 7000.0;
441 }
442 self.control_event_data.cutoff = Some(freq);
443 } else {
444 self.control_event_data.cutoff = None;
445 }
446 }
447 0x78 => {
448 if value == 0 {
450 self.process_event(ChannelEvent::Audio(ChannelAudioEvent::AllNotesKilled));
451 }
452 }
453 0x79 => {
454 if value == 0 {
456 self.reset_control();
457 }
458 }
459 0x7B => {
460 if value == 0 {
462 self.process_event(ChannelEvent::Audio(ChannelAudioEvent::AllNotesOff));
463 }
464 }
465 _ => {}
466 },
467 ControlEvent::PitchBendSensitivity(sensitivity) => {
468 let pitch_bend = {
469 let data = &mut self.control_event_data;
470 data.pitch_bend_sensitivity = sensitivity;
471 data.pitch_bend_sensitivity * data.pitch_bend_value
472 };
473 self.process_control_event(ControlEvent::PitchBend(pitch_bend));
474 }
475 ControlEvent::PitchBendValue(value) => {
476 let pitch_bend = {
477 let data = &mut self.control_event_data;
478 data.pitch_bend_value = value;
479 data.pitch_bend_sensitivity * data.pitch_bend_value
480 };
481 self.process_control_event(ControlEvent::PitchBend(pitch_bend));
482 }
483 ControlEvent::PitchBend(value) => {
484 self.control_event_data.pitch_bend_value = value;
485 self.process_pitch();
486 }
487 ControlEvent::FineTune(value) => {
488 self.control_event_data.fine_tune_value = value;
489 self.process_pitch();
490 }
491 ControlEvent::CoarseTune(value) => {
492 self.control_event_data.coarse_tune_value = value;
493 self.process_pitch();
494 }
495 }
496 }
497
498 fn process_pitch(&mut self) {
499 let data = &mut self.control_event_data;
500 let pitch_bend = data.pitch_bend_value;
501 let fine_tune = data.fine_tune_value;
502 let coarse_tune = data.coarse_tune_value;
503 let combined = pitch_bend + coarse_tune + fine_tune / 100.0;
504
505 self.voice_control_data.voice_pitch_multiplier = 2.0f32.powf(combined / 12.0);
506 self.propagate_voice_controls();
507 }
508
509 pub fn process_event(&mut self, event: ChannelEvent) {
512 self.push_events_iter(std::iter::once(event));
513 }
514
515 pub fn push_events_iter<T: Iterator<Item = ChannelEvent>>(&mut self, iter: T) {
517 for e in iter {
518 match e {
519 ChannelEvent::Audio(audio) => match audio {
520 ChannelAudioEvent::NoteOn { key, vel } => {
521 if let Some(key) = self.key_voices.get_mut(key as usize) {
522 let ev = KeyNoteEvent::On(vel);
523 key.event_cache.push(ev);
524 }
525 }
526 ChannelAudioEvent::NoteOff { key } => {
527 if let Some(key) = self.key_voices.get_mut(key as usize) {
528 let ev = KeyNoteEvent::Off;
529 key.event_cache.push(ev);
530 }
531 }
532 ChannelAudioEvent::AllNotesOff => {
533 for key in self.key_voices.iter_mut() {
534 let ev = KeyNoteEvent::AllOff;
535 key.event_cache.push(ev);
536 }
537 }
538 ChannelAudioEvent::AllNotesKilled => {
539 for key in self.key_voices.iter_mut() {
540 let ev = KeyNoteEvent::AllKilled;
541 key.event_cache.push(ev);
542 }
543 }
544 ChannelAudioEvent::ResetControl => {
545 self.reset_control();
546 }
547 ChannelAudioEvent::Control(control) => {
548 self.process_control_event(control);
549 }
550 ChannelAudioEvent::ProgramChange(preset) => {
551 self.params.set_preset(preset);
552 }
553 },
554 ChannelEvent::Config(config) => self.params.process_config_event(config),
555 }
556 }
557 }
558
559 pub fn get_channel_stats(&self) -> VoiceChannelStatsReader {
562 let stats = self.params.stats.clone();
563 VoiceChannelStatsReader::new(stats)
564 }
565
566 fn reset_control(&mut self) {
567 self.control_event_data = ControlEventData::new_defaults(self.stream_params.sample_rate);
568 self.voice_control_data = VoiceControlData::new_defaults();
569 self.process_event(ChannelEvent::Audio(ChannelAudioEvent::ProgramChange(0)));
570 self.propagate_voice_controls();
571
572 self.control_event_data.cutoff = None;
573
574 for key in self.key_voices.iter_mut() {
575 key.data.set_damper(false);
576 }
577 }
578}
579
580impl AudioPipe for VoiceChannel {
581 fn stream_params(&self) -> &AudioStreamParams {
582 &self.params.constant.stream_params
583 }
584
585 fn read_samples_unchecked(&mut self, out: &mut [f32]) {
586 self.push_key_events_and_render(out);
587 }
588}