summaryrefslogtreecommitdiff
path: root/src/music
diff options
context:
space:
mode:
authorNiels Martin Hansen <nielsm@indvikleren.dk>2018-06-06 18:20:22 +0200
committerMichael Lutz <michi@icosahedron.de>2018-06-15 23:09:17 +0200
commit11a846e3d517c367112287f797065341e5e5c158 (patch)
treec245a735787032e17ce0d6ded640cd61e9e6b144 /src/music
parent276192f714d6816088791435c1b70dfa7122cdbd (diff)
downloadopenttd-11a846e3d517c367112287f797065341e5e5c158.tar.xz
Change: Compensate for MIDI transmission time when skipping start of song
Diffstat (limited to 'src/music')
-rw-r--r--src/music/dmusic.cpp3
-rw-r--r--src/music/win32_m.cpp9
2 files changed, 10 insertions, 2 deletions
diff --git a/src/music/dmusic.cpp b/src/music/dmusic.cpp
index 3b6ae3454..3f5ca2255 100644
--- a/src/music/dmusic.cpp
+++ b/src/music/dmusic.cpp
@@ -693,6 +693,9 @@ static void MidiThreadProc(void *)
current_segment.start_block = bl;
break;
} else {
+ /* Skip the transmission delay compensation performed in the Win32 MIDI driver.
+ * The DMusic driver will most likely be used with the MS softsynth, which is not subject to transmission delays.
+ */
DEBUG(driver, 2, "DMusic: timer: start from block %d (ticktime %d, realtime %.3f, bytes %d)", (int)bl, (int)block.ticktime, ((int)block.realtime) / 1000.0, (int)preload_bytes);
playback_start_time -= block.realtime * MIDITIME_TO_REFTIME;
break;
diff --git a/src/music/win32_m.cpp b/src/music/win32_m.cpp
index 93991d88b..3c059ebed 100644
--- a/src/music/win32_m.cpp
+++ b/src/music/win32_m.cpp
@@ -184,7 +184,7 @@ void CALLBACK TimerCallback(UINT uTimerID, UINT, DWORD_PTR dwUser, DWORD_PTR, DW
/* find first block after start time and pretend playback started earlier
* this is to allow all blocks prior to the actual start to still affect playback,
* as they may contain important controller and program changes */
- size_t preload_bytes = 0;
+ uint preload_bytes = 0;
for (size_t bl = 0; bl < _midi.current_file.blocks.size(); bl++) {
MidiFile::DataBlock &block = _midi.current_file.blocks[bl];
preload_bytes += block.data.Length();
@@ -194,8 +194,13 @@ void CALLBACK TimerCallback(UINT uTimerID, UINT, DWORD_PTR dwUser, DWORD_PTR, DW
_midi.current_segment.start_block = bl;
break;
} else {
+ /* Calculate offset start time for playback.
+ * The preload_bytes are used to compensate for delay in transmission over traditional serial MIDI interfaces,
+ * which have a bitrate of 31,250 bits/sec, and transmit 1+8+1 start/data/stop bits per byte.
+ * The delay compensation is needed to avoid time-compression of following messages.
+ */
DEBUG(driver, 2, "Win32-MIDI: timer: start from block %d (ticktime %d, realtime %.3f, bytes %d)", (int)bl, (int)block.ticktime, ((int)block.realtime) / 1000.0, (int)preload_bytes);
- _midi.playback_start_time -= block.realtime / 1000;
+ _midi.playback_start_time -= block.realtime / 1000 - preload_bytes * 1000 / 3125;
break;
}
}