@@ -669,7 +669,7 @@ SiMMLTrack *SiONDriver::play_sound(int p_sample_number, double p_length, double
669
669
670
670
if (track) {
671
671
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);
673
673
}
674
674
675
675
return track;
@@ -708,7 +708,7 @@ SiMMLTrack *SiONDriver::note_on(int p_note, const Ref<SiONVoice> &p_voice, doubl
708
708
if (p_voice.is_valid ()) {
709
709
p_voice->update_track_voice (track);
710
710
}
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);
712
712
}
713
713
714
714
return track;
@@ -1039,6 +1039,15 @@ int SiONDriver::start_queue(int p_interval) {
1039
1039
1040
1040
// Events.
1041
1041
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
+
1042
1051
void SiONDriver::_dispatch_event (const Ref<SiONEvent> &p_event) {
1043
1052
// This method exists as a proxy. Original implementation relied on native events, whereas we
1044
1053
// 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() {
1111
1120
emit_signal (timer_interval);
1112
1121
}
1113
1122
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) ;
1116
1125
1117
- if (p_length_16th > 0 ) {
1126
+ if (p_length > 0 ) {
1118
1127
sequencer->set_timer_callback (Callable (this , " _timer_callback" ));
1119
1128
} else {
1120
1129
sequencer->set_timer_callback (Callable ());
0 commit comments