Skip to content

Commit

Permalink
Fallback to piano when an instrument is not found
Browse files Browse the repository at this point in the history
  • Loading branch information
arduano committed Dec 9, 2023
1 parent b32e0b4 commit 318999f
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 5 deletions.
43 changes: 38 additions & 5 deletions core/src/channel/channel_sf.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{ops::Deref, sync::Arc};
use std::{iter, ops::Deref, sync::Arc};

use crate::{
soundfont::SoundfontBase,
Expand All @@ -10,6 +10,8 @@ use super::voice_spawner::VoiceSpawnerMatrix;
pub struct ChannelSoundfont {
soundfonts: Vec<Arc<dyn SoundfontBase>>,
matrix: VoiceSpawnerMatrix,
curr_bank: Option<u8>,
curr_preset: Option<u8>,
}

impl Deref for ChannelSoundfont {
Expand All @@ -26,11 +28,15 @@ impl ChannelSoundfont {
ChannelSoundfont {
soundfonts: Vec::new(),
matrix: VoiceSpawnerMatrix::new(),
curr_bank: None,
curr_preset: None,
}
}

pub fn set_soundfonts(&mut self, soundfonts: Vec<Arc<dyn SoundfontBase>>) {
self.soundfonts = soundfonts;
self.curr_bank = None;
self.curr_preset = None;
self.rebuild_matrix(0, 0);
}

Expand All @@ -39,25 +45,52 @@ impl ChannelSoundfont {
}

fn rebuild_matrix(&mut self, bank: u8, preset: u8) {
if self.curr_bank == Some(bank) && self.curr_preset == Some(preset) {
return;
}

dbg!(bank, preset);
for k in 0..128u8 {
for v in 0..128u8 {
let vec = self
// The fallback piano finder in case no other instrument is found
let find_piano_attack = || {
self.soundfonts
.iter()
.map(|sf| sf.get_attack_voice_spawners_at(0, 0, k, v))
.find(|vec| !vec.is_empty())
};

let attack_spawners = self
.soundfonts
.iter()
.map(|sf| sf.get_attack_voice_spawners_at(bank, preset, k, v))
.chain(iter::once_with(find_piano_attack).flatten())
.find(|vec| !vec.is_empty())
.unwrap_or_default();
self.matrix.set_spawners_attack(k, v, vec);

let vec = self
// The fallback piano finder in case no other instrument is found
let find_piano_release = || {
self.soundfonts
.iter()
.map(|sf| sf.get_release_voice_spawners_at(0, 0, k, v))
.find(|vec| !vec.is_empty())
};

let release_spawners = self
.soundfonts
.iter()
.map(|sf| sf.get_release_voice_spawners_at(bank, preset, k, v))
.chain(iter::once_with(find_piano_release).flatten())
.find(|vec| !vec.is_empty())
.unwrap_or_default();
self.matrix.set_spawners_release(k, v, vec);

self.matrix.set_spawners_attack(k, v, attack_spawners);
self.matrix.set_spawners_release(k, v, release_spawners);
}
}

self.curr_bank = Some(bank);
self.curr_preset = Some(preset);
}

pub fn spawn_voices_attack<'a>(
Expand Down
1 change: 1 addition & 0 deletions core/src/soundfont/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#![allow(non_camel_case_types)]
use std::{
collections::{HashMap, HashSet},
io,
Expand Down

0 comments on commit 318999f

Please sign in to comment.