Skip to content

Commit 8ab1b08

Browse files
committed
refs #114, bugfix with click channel not always inited, and wasm compatibility
1 parent 5e339c2 commit 8ab1b08

File tree

4 files changed

+38
-34
lines changed

4 files changed

+38
-34
lines changed

crates/notation_midi/src/midi_message.rs

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,38 +4,42 @@ use notation_model::prelude::*;
44
#[derive(Clone, Debug)]
55
pub struct MidiMessage {
66
pub pass_mode: EntryPassMode,
7-
pos: BarPosition,
8-
delay: Option<Units>,
7+
pub pos: BarPosition,
8+
pub duration: Units,
9+
pub delay: bool,
910
pub midi: StructuredShortMessage,
1011
}
1112
impl MidiMessage {
12-
pub fn new(pass_mode: EntryPassMode, pos: BarPosition, delay: Option<Units>, midi: StructuredShortMessage) -> Self {
13+
pub fn new(pass_mode: EntryPassMode, pos: BarPosition, duration: Units, delay: bool, midi: StructuredShortMessage) -> Self {
1314
Self {
1415
pass_mode,
1516
pos,
17+
duration,
1618
delay,
1719
midi,
1820
}
1921
}
20-
pub fn of_entry(entry: &LaneEntry, delay: Option<Units>, midi: StructuredShortMessage) -> Self {
22+
pub fn of_entry(entry: &LaneEntry, delay: bool, midi: StructuredShortMessage) -> Self {
2123
Self {
2224
pass_mode: entry.pass_mode(),
2325
pos: entry.bar_position(),
26+
duration: entry.tied_units(),
2427
delay,
2528
midi,
2629
}
2730
}
2831
pub fn bar_ordinal(&self) -> usize {
2932
self.pos.bar_ordinal
3033
}
31-
pub fn bar_position(&self) -> BarPosition {
32-
match self.delay {
33-
Some(delay) => self.pos.with_delay(delay),
34-
None => self.pos,
34+
pub fn effect_position(&self) -> BarPosition {
35+
if self.delay {
36+
self.pos.with_delay(self.duration)
37+
} else {
38+
self.pos
3539
}
3640
}
37-
pub fn units_position(&self) -> Units {
38-
self.bar_position().into()
41+
pub fn effect_units(&self) -> Units {
42+
self.effect_position().into()
3943
}
4044
pub fn to_midi(&self) -> [u8; 3] {
4145
[

crates/notation_midi/src/midi_state.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@ impl MidiChannel {
4949
fn ensure_sorted(&mut self) -> bool {
5050
if self.need_sort {
5151
dmsort::sort_by(&mut self.messages, |a, b| {
52-
let units_a = a.units_position().0;
53-
let units_b = b.units_position().0;
52+
let units_a = a.effect_units().0;
53+
let units_b = b.effect_units().0;
5454
if units_a == units_b {
5555
Ordering::Equal
5656
} else if units_a < units_b {
@@ -68,7 +68,7 @@ impl MidiChannel {
6868
pub fn calc_next_index(&mut self, position: &BarPosition) {
6969
let pos_units = Units::from(*position);
7070
for (index, value) in self.messages.iter().enumerate() {
71-
if Units::from(value.bar_position()) >= pos_units {
71+
if Units::from(value.effect_position()) >= pos_units {
7272
self.next_index = index;
7373
return;
7474
}
@@ -134,15 +134,15 @@ impl MidiChannel {
134134
if play_control.is_bar_in_range(next.bar_ordinal())
135135
&& play_control
136136
.position
137-
.is_passed(next.pass_mode, &next.bar_position())
137+
.is_passed(next.pass_mode, &next.effect_position())
138138
{
139139
self.next_index += 1;
140140
count += 1;
141141
if !bypass {
142142
hub.send(settings, speed, next, velocity);
143143
}
144144
} else {
145-
if next.bar_position().bar_ordinal < play_control.begin_bar_ordinal {
145+
if next.effect_position().bar_ordinal < play_control.begin_bar_ordinal {
146146
self.next_index += 1;
147147
} else {
148148
break;
@@ -163,7 +163,7 @@ impl MidiChannel {
163163
hub.send(
164164
settings,
165165
speed,
166-
&MidiMessage::new(first_msg.pass_mode, first_msg.bar_position(), None, msg),
166+
&MidiMessage::new(first_msg.pass_mode, first_msg.pos, first_msg.duration, false, msg),
167167
self.velocity.into(),
168168
);
169169
let msg = StructuredShortMessage::ControlChange {
@@ -174,7 +174,7 @@ impl MidiChannel {
174174
hub.send(
175175
settings,
176176
speed,
177-
&MidiMessage::new(first_msg.pass_mode, first_msg.bar_position(), None, msg),
177+
&MidiMessage::new(first_msg.pass_mode, first_msg.pos, first_msg.duration, false, msg),
178178
self.velocity.into(),
179179
);
180180
}
@@ -267,18 +267,18 @@ impl MidiState {
267267
let scale_root = tab.meta.scale.calc_root_syllable();
268268
let signature = tab.signature();
269269
let bar_units = tab.bar_units();
270-
let beat_delay = Some(Units::from(signature.beat_unit) - Units::MIN_ACCURACY);
270+
let beat_duration = Units::from(signature.beat_unit);
271271
for bar in tab.bars.iter() {
272272
for beat in 0..signature.bar_beats {
273273
let in_bar_pos = Units(beat as f32 * Units::from(signature.beat_unit).0);
274274
let root = bar.get_chord(Some(in_bar_pos)).map(|x| x.root).unwrap_or(scale_root);
275275
let note = tab.meta.scale.calc_click_note(&tab.meta.key, &settings.click_octave, &root);
276276
let pos = BarPosition::new(bar_units, bar.props.bar_ordinal, in_bar_pos);
277277
if let Some(midi_msg) = MidiUtil::note_midi_on_msg(&note, channel.channel, channel.velocity) {
278-
channel.add_message(MidiMessage::new(EntryPassMode::Immediate, pos, None, midi_msg));
278+
channel.add_message(MidiMessage::new(EntryPassMode::Immediate, pos, beat_duration, false, midi_msg));
279279
}
280280
if let Some(midi_msg) = MidiUtil::note_midi_off_msg(&note, channel.channel, channel.velocity) {
281-
channel.add_message(MidiMessage::new(EntryPassMode::Immediate, pos, beat_delay, midi_msg));
281+
channel.add_message(MidiMessage::new(EntryPassMode::Immediate, pos, beat_duration, true, midi_msg));
282282
}
283283
}
284284
}
@@ -378,7 +378,7 @@ impl MidiState {
378378
}
379379
pub fn init_channels(&mut self, settings: &MidiSettings, hub: &mut MidiHub) {
380380
for channel in self.channels.iter_mut() {
381-
if channel.track.is_some() {
381+
if channel.messages.len() > 0 {
382382
channel.init_channel(settings, hub, &self.play_control.play_speed);
383383
channel.calc_next_index(&self.play_control.position.bar);
384384
}

crates/notation_midi/src/midi_util.rs

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ use std::convert::TryFrom;
33
use helgoboss_midi::{Channel, KeyNumber, StructuredShortMessage, U7};
44
use notation_model::prelude::{
55
CoreEntry, Entry, FrettedEntry4, FrettedEntry6, LaneEntry, Note, Pick, Semitones, TabBar, Tone,
6-
Units,
76
};
87

98
use crate::prelude::MidiChannel;
@@ -47,22 +46,21 @@ impl MidiUtil {
4746
_bar: &TabBar,
4847
entry: &LaneEntry,
4948
tone: &Tone,
50-
) -> Option<Vec<(Option<Units>, StructuredShortMessage)>> {
49+
) -> Option<Vec<(bool, StructuredShortMessage)>> {
5150
if tone.is_none() || entry.prev_is_tie() {
5251
return None;
5352
}
54-
let mut play_msgs: Vec<(Option<Units>, StructuredShortMessage)> = tone
53+
let mut play_msgs: Vec<(bool, StructuredShortMessage)> = tone
5554
.get_notes()
5655
.iter()
5756
.flat_map(|x| MidiUtil::note_midi_on_msg(x, channel.channel, channel.velocity))
58-
.map(|x| (None, x))
57+
.map(|x| (false, x))
5958
.collect();
60-
let delay = entry.tied_units();
61-
let mut stop_msgs: Vec<(Option<Units>, StructuredShortMessage)> = tone
59+
let mut stop_msgs: Vec<(bool, StructuredShortMessage)> = tone
6260
.get_notes()
6361
.iter()
6462
.flat_map(|x| MidiUtil::note_midi_off_msg(x, channel.channel, channel.velocity))
65-
.map(|x| (Some(delay), x))
63+
.map(|x| (true, x))
6664
.collect();
6765
play_msgs.append(&mut stop_msgs);
6866
if play_msgs.len() > 0 {
@@ -76,7 +74,7 @@ impl MidiUtil {
7674
bar: &TabBar,
7775
entry: &LaneEntry,
7876
core_entry: &CoreEntry,
79-
) -> Option<Vec<(Option<Units>, StructuredShortMessage)>> {
77+
) -> Option<Vec<(bool, StructuredShortMessage)>> {
8078
match core_entry {
8179
CoreEntry::Tone(tone, _) => Self::get_tone_midi_msgs(channel, bar, entry, tone),
8280
_ => None,
@@ -86,7 +84,7 @@ impl MidiUtil {
8684
channel: &MidiChannel,
8785
bar: &TabBar,
8886
entry: &LaneEntry,
89-
) -> Option<Vec<(Option<Units>, StructuredShortMessage)>> {
87+
) -> Option<Vec<(bool, StructuredShortMessage)>> {
9088
match entry.proto() {
9189
notation_model::prelude::ProtoEntry::Core(core_entry) => {
9290
Self::get_core_midi_msgs(channel, bar, entry, core_entry)
@@ -110,7 +108,7 @@ macro_rules! impl_get_pick_midi_msgs {
110108
bar: &TabBar,
111109
entry: &LaneEntry,
112110
pick: &Pick,
113-
) -> Option<Vec<(Option<Units>, StructuredShortMessage)>> {
111+
) -> Option<Vec<(bool, StructuredShortMessage)>> {
114112
if let Some((fretboard, shape)) = bar.$get_fretted_shape(entry) {
115113
let tone = fretboard.pick_tone(&shape, pick);
116114
Self::get_tone_midi_msgs(channel, bar, entry, &tone)
@@ -130,7 +128,7 @@ macro_rules! impl_get_fretted_midi_msgs {
130128
bar: &TabBar,
131129
entry: &LaneEntry,
132130
fretted_entry: &$fretted_entry,
133-
) -> Option<Vec<(Option<Units>, StructuredShortMessage)>> {
131+
) -> Option<Vec<(bool, StructuredShortMessage)>> {
134132
match fretted_entry {
135133
$fretted_entry::Pick(pick, _) => {
136134
Self::$get_pick_midi_msgs(channel, bar, entry, pick)

crates/notation_midi/src/wasm/midi_synth.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@ impl MidiSynth {
2626
channel: _,
2727
key_number: _,
2828
velocity: _,
29-
} => Ok(()),
29+
} => {
30+
Ok(())
31+
},
3032
StructuredShortMessage::NoteOn {
3133
channel,
3234
key_number,
@@ -40,7 +42,7 @@ impl MidiSynth {
4042
Ok(play_note(
4143
channel.into(),
4244
key_number.into(),
43-
speed.calc_seconds(msg.entry.tied_units()),
45+
speed.calc_seconds(msg.duration),
4446
volume * Self::VOLUME_FACTOR,
4547
))
4648
} else {

0 commit comments

Comments
 (0)