Skip to content

Commit 0a3cc4d

Browse files
committed
Fix incorrect resolution for driver-initialized events
This makes note and timer events 4 times as short by default, so applications using GDSiON must be adapted accordingly. Previous version used 1/4th of a beat instead of supposed 1/16th.
1 parent 4ef0384 commit 0a3cc4d

File tree

4 files changed

+20
-8
lines changed

4 files changed

+20
-8
lines changed

example/gui/PianoRoll.gd

+1-1
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ func _update_active_key(key: int) -> void:
200200
return
201201

202202
_active_key = key
203-
Controller.music_player.play_note(_active_key, 1)
203+
Controller.music_player.play_note(_active_key, 4)
204204
queue_redraw()
205205

206206
func _clear_active_key() -> void:

src/sequencer/base/mml_sequencer.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -462,9 +462,10 @@ bool MMLSequencer::check_global_sequence_end() {
462462
if (prev_beat == 0) {
463463
_on_beat(0, 0);
464464
} else {
465-
int floor_curr_beat = int(_global_beat_16th);
465+
int floor_curr_beat = (int)_global_beat_16th;
466466
while (floor_prev_beat < floor_curr_beat) {
467467
floor_prev_beat++;
468+
468469
if ((floor_prev_beat & _on_beat_callback_filter) == 0) {
469470
_on_beat((floor_prev_beat - prev_beat) * _bpm->get_sample_per_beat_16th(), floor_prev_beat);
470471
}

src/sion_driver.cpp

+14-5
Original file line numberDiff line numberDiff line change
@@ -669,7 +669,7 @@ SiMMLTrack *SiONDriver::play_sound(int p_sample_number, double p_length, double
669669

670670
if (track) {
671671
track->set_channel_module_type(MT_SAMPLE, 0);
672-
track->key_on(p_sample_number, p_length * sequencer->get_parser_settings()->resolution * 0.0625, delay_samples);
672+
track->key_on(p_sample_number, _convert_event_length(p_length), delay_samples);
673673
}
674674

675675
return track;
@@ -708,7 +708,7 @@ SiMMLTrack *SiONDriver::note_on(int p_note, const Ref<SiONVoice> &p_voice, doubl
708708
if (p_voice.is_valid()) {
709709
p_voice->update_track_voice(track);
710710
}
711-
track->key_on(p_note, p_length * sequencer->get_parser_settings()->resolution * 0.0625, delay_samples);
711+
track->key_on(p_note, _convert_event_length(p_length), delay_samples);
712712
}
713713

714714
return track;
@@ -1039,6 +1039,15 @@ int SiONDriver::start_queue(int p_interval) {
10391039

10401040
// Events.
10411041

1042+
double SiONDriver::_convert_event_length(double p_length) const {
1043+
// Driver methods expect length in 1/16ths of a beat. The event length is in resolution units.
1044+
// Note: In the original implementation this was mistakenly interpreted as 1/16th of
1045+
// the sequencer's note resolution, which only translated to 1/4th of the beat.
1046+
1047+
double beat_resolution = (double)sequencer->get_parser_settings()->resolution / 4.0;
1048+
return p_length * beat_resolution * 0.0625;
1049+
}
1050+
10421051
void SiONDriver::_dispatch_event(const Ref<SiONEvent> &p_event) {
10431052
// This method exists as a proxy. Original implementation relied on native events, whereas we
10441053
// want to rely on signals. For simplicity's sake, we keep original event objects but strip any
@@ -1111,10 +1120,10 @@ void SiONDriver::_timer_callback() {
11111120
emit_signal(timer_interval);
11121121
}
11131122

1114-
void SiONDriver::set_timer_interval(double p_length_16th) {
1115-
_timer_interval_event->length = p_length_16th * sequencer->get_parser_settings()->resolution * 0.0625;
1123+
void SiONDriver::set_timer_interval(double p_length) {
1124+
_timer_interval_event->length = _convert_event_length(p_length);
11161125

1117-
if (p_length_16th > 0) {
1126+
if (p_length > 0) {
11181127
sequencer->set_timer_callback(Callable(this, "_timer_callback"));
11191128
} else {
11201129
sequencer->set_timer_callback(Callable());

src/sion_driver.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,8 @@ class SiONDriver : public Node {
207207

208208
// Events.
209209

210+
double _convert_event_length(double p_length) const;
211+
210212
void _dispatch_event(const Ref<SiONEvent> &p_event);
211213

212214
void _note_on_callback(SiMMLTrack *p_track);
@@ -395,7 +397,7 @@ class SiONDriver : public Node {
395397

396398
void set_beat_callback_interval(double p_length_16th = 1);
397399
// Note: Original code takes a callback. Here you need to connect to the `timer_interval` signal.
398-
void set_timer_interval(double p_length_16th = 1);
400+
void set_timer_interval(double p_length = 1);
399401

400402
// MIDI.
401403
// FIXME: Implement SMF/MIDI support.

0 commit comments

Comments
 (0)