Skip to content

Commit 4227472

Browse files
committed
fixes #83, load proper instrument on WASM
1 parent 7692ed0 commit 4227472

File tree

5 files changed

+59
-13
lines changed

5 files changed

+59
-13
lines changed

apps/notation_viewer/index.html

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,19 +24,31 @@
2424
}
2525
</style>
2626
<script src='https://surikov.github.io/webaudiofont/npm/dist/WebAudioFontPlayer.js'></script>
27-
<script src='https://surikov.github.io/webaudiofontdata/sound/0250_SoundBlasterOld_sf2.js'></script>
2827
<script>
2928
var AudioContextFunc = window.AudioContext || window.webkitAudioContext;
3029
var audioContext = new AudioContextFunc();
30+
var channels = new Map();
3131
var player=new WebAudioFontPlayer();
32-
player.loader.decodeAfterLoading(audioContext, '_tone_0250_SoundBlasterOld_sf2');
3332

34-
function play_note(semitones, seconds){
35-
player.queueWaveTable(audioContext, audioContext.destination
36-
, _tone_0250_SoundBlasterOld_sf2, 0, semitones, seconds);
33+
function play_note(channel, semitones, seconds, volume){
34+
const info = channels.get(channel);
35+
if (info) {
36+
player.queueWaveTable(audioContext, audioContext.destination, window[info.variable], 0, semitones, seconds, volume);
37+
}
3738
}
3839

39-
function load_instrument(program) {
40+
function init_channel(channel, program) {
41+
var nn = player.loader.findInstrument(program);
42+
var info = player.loader.instrumentInfo(nn);
43+
channels.set(channel, info);
44+
console.log('init_channel(', channel, program, ') -> info:', info);
45+
player.loader.startLoad(audioContext, info.url, info.variable);
46+
}
47+
48+
function load_instruments() {
49+
player.loader.waitLoad(function () {
50+
console.log('load_instruments: finished', channels);
51+
});
4052
}
4153
</script>
4254
</head>

crates/notation_midi/src/midi_hub.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use midir::{MidiOutput, MidiOutputConnection};
2-
use notation_model::prelude::PlaySpeed;
3-
use std::sync::Mutex;
2+
use notation_model::prelude::{PlaySpeed, Tab};
3+
use std::sync::{Arc, Mutex};
44

5-
use crate::prelude::{MidiMessage, MidiSettings, MidiSynth};
5+
use crate::prelude::{MidiMessage, MidiSettings, MidiState, MidiSynth};
66

77
pub struct MidiHub {
88
pub output_conn: Option<Mutex<MidiOutputConnection>>,
@@ -63,6 +63,16 @@ impl MidiHub {
6363
self.check_output_conn();
6464
}
6565
}
66+
pub fn switch_tab(&mut self, settings: &MidiSettings, state: &mut MidiState, tab: Arc<Tab>) {
67+
state.switch_tab(&settings, self, tab.clone());
68+
self.init_channels(settings, state);
69+
}
70+
pub fn init_channels(&mut self, settings: &MidiSettings, state: &MidiState) {
71+
self.check_output(settings);
72+
if let Some(synth) = &self.output_synth {
73+
synth.init_channels(settings, state);
74+
}
75+
}
6676
pub fn send(&mut self, settings: &MidiSettings, speed: &PlaySpeed, msg: &MidiMessage) {
6777
self.check_output(settings);
6878
if let Some(synth) = &self.output_synth {

crates/notation_midi/src/midi_plugin.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ fn on_switch_tab(
3333
mut play_control_evts: EventWriter<PlayControlEvent>,
3434
) {
3535
for evt in evts.iter() {
36-
state.switch_tab(&settings, &mut hub, evt.tab.clone());
36+
hub.switch_tab(&settings, &mut state, evt.tab.clone());
3737
_do_tick(
3838
&settings,
3939
&mut state,

crates/notation_midi/src/native/midi_synth.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use helgoboss_midi::StructuredShortMessage;
22

3-
use crate::prelude::MidiMessage;
3+
use crate::prelude::{MidiMessage, MidiSettings, MidiState};
44
use notation_model::prelude::PlaySpeed;
55

66
use super::audio_stream::DoubleAudioBuffer;
@@ -42,6 +42,8 @@ impl MidiSynth {
4242
synth.write(data).unwrap();
4343
});
4444
}
45+
pub fn init_channels(&self, _settings: &MidiSettings, _state: &MidiState) {
46+
}
4547
pub fn send(&self, _speed: &PlaySpeed, msg: &MidiMessage) -> Result<(), String> {
4648
match msg.midi {
4749
StructuredShortMessage::NoteOff {

crates/notation_midi/src/wasm/midi_synth.rs

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use helgoboss_midi::StructuredShortMessage;
22
use wasm_bindgen::prelude::*;
33

4-
use crate::prelude::MidiMessage;
4+
use crate::prelude::{MidiMessage, MidiSettings, MidiState};
55
use notation_model::prelude::{Entry, PlaySpeed};
66

77
pub struct MidiSynth {}
@@ -10,6 +10,14 @@ impl MidiSynth {
1010
pub fn try_new() -> Option<MidiSynth> {
1111
Some(MidiSynth {})
1212
}
13+
pub fn init_channels(&self, _settings: &MidiSettings, state: &MidiState) {
14+
for channel in state.channels.iter() {
15+
if channel.track.is_some() {
16+
init_channel(channel.channel.into(), channel.program.into());
17+
}
18+
}
19+
load_instruments();
20+
}
1321
pub fn send(&self, speed: &PlaySpeed, msg: &MidiMessage) -> Result<(), String> {
1422
match msg.midi {
1523
StructuredShortMessage::NoteOff {
@@ -22,8 +30,10 @@ impl MidiSynth {
2230
key_number,
2331
velocity,
2432
} => Ok(play_note(
33+
channel.into(),
2534
key_number.into(),
2635
speed.calc_seconds(msg.entry.tied_units()),
36+
u8::from(velocity) as f32 / 128.0,
2737
)),
2838
_ => Err("NOT_IMPLEMENTED".to_owned()),
2939
}
@@ -33,5 +43,17 @@ impl MidiSynth {
3343
#[wasm_bindgen]
3444
extern "C" {
3545
#[wasm_bindgen(js_namespace = window)]
36-
fn play_note(seminones: u8, seconds: f32);
46+
fn init_channel(channel: u8, program: u8);
47+
}
48+
49+
#[wasm_bindgen]
50+
extern "C" {
51+
#[wasm_bindgen(js_namespace = window)]
52+
fn load_instruments();
53+
}
54+
55+
#[wasm_bindgen]
56+
extern "C" {
57+
#[wasm_bindgen(js_namespace = window)]
58+
fn play_note(channel: u8, seminones: u8, seconds: f32, volume: f32);
3759
}

0 commit comments

Comments
 (0)