summaryrefslogtreecommitdiff
path: root/src/main.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs30
1 files changed, 25 insertions, 5 deletions
diff --git a/src/main.rs b/src/main.rs
index 9c3001b..7dd7706 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -23,6 +23,8 @@ struct NoteInfo {
pedal_down: bool,
presets: [usize; CHANNEL_COUNT],
notes: [Vec<Note>; CHANNEL_COUNT],
+ channel_volumes: [f32; CHANNEL_COUNT],
+ master_volume: f32,
}
static NOTE_INFO: Mutex<NoteInfo> = Mutex::new(NoteInfo {
@@ -31,6 +33,8 @@ static NOTE_INFO: Mutex<NoteInfo> = Mutex::new(NoteInfo {
notes: [vec![], vec![], vec![], vec![], vec![], vec![], vec![], vec![], vec![], vec![], vec![], vec![], vec![], vec![], vec![], vec![]],
pedal_down: false,
presets: [0; CHANNEL_COUNT],
+ channel_volumes: [1.0; CHANNEL_COUNT],
+ master_volume: 1.0,
});
static SOUNDFONT: Mutex<Option<soundfont::SoundFont>> = Mutex::new(None);
@@ -124,9 +128,11 @@ fn get_audio_stream() -> Result<cpal::Stream, String> {
}
let pitch_bend = note_info.pitch_bend;
for channel in 0..CHANNEL_COUNT {
+ let volume = 0.1 * note_info.master_volume * note_info.channel_volumes[channel];
let notes = &mut note_info.notes[channel];
for note in notes.iter_mut() {
note.req.set_tune(pitch_bend as i32);
+ note.req.set_volume(volume);
match sf.add_samples_interlaced(&mut note.req, data, sample_rate) {
Ok(true) => {}
Ok(false) => note.kill = true,
@@ -171,8 +177,7 @@ fn play_note(channel: i64, note: i64, vel: i64) {
let preset = note_info.presets[channel];
if let Some(sf) = maybe_sf.as_mut() {
match sf.request(preset, note, vel) {
- Ok(mut req) => {
- req.set_volume(0.1);
+ Ok(req) => {
note_info.notes[channel].push(Note {
key: note,
req,
@@ -249,11 +254,11 @@ fn load_soundfont(filename: &str) {
}
fn load_preset(channel: i64, preset: i64) {
- if !check_channel(channel as usize) {
- return;
- }
let preset = preset as usize;
let channel = channel as usize;
+ if !check_channel(channel) {
+ return;
+ }
let mut note_info = NOTE_INFO.lock().expect("couldn't lock notes");
let mut soundfont = SOUNDFONT.lock().expect("couldn't lock soundfont.");
if let Some(sf) = soundfont.as_mut() {
@@ -269,6 +274,20 @@ fn load_preset(channel: i64, preset: i64) {
}
+fn set_volume(channel: i64, volume: f64) {
+ let volume = if volume.is_nan() { 0.0 } else { volume as f32 };
+ let mut note_info = NOTE_INFO.lock().expect("couldn't lock notes");
+ if channel == -1 {
+ note_info.master_volume = volume as f32;
+ return;
+ }
+ let channel = channel as usize;
+ if !check_channel(channel) {
+ return;
+ }
+ note_info.channel_volumes[channel] = volume as f32;
+}
+
fn call_fn_if_exists(engine: &rhai::Engine, ast: &rhai::AST, name: &str, args: impl rhai::FuncArgs) {
let mut scope = rhai::Scope::new();
match engine.call_fn::<()>(&mut scope, &ast, name, args).map_err(|e| *e) {
@@ -288,6 +307,7 @@ fn playmidi_main() -> Result<(), String> {
engine.register_fn("pm_release_note", release_note);
engine.register_fn("pm_set_pedal", set_pedal_down);
engine.register_fn("pm_bend_pitch", set_pitch_bend);
+ engine.register_fn("pm_set_volume", set_volume);
let engine = engine; // de-multablify
let mut ast = engine.compile_file("config.rhai".into()).map_err(|e| format!("{}", e))?;