From e2803185d05392a828841a52aeb41540a26f195c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?YUKI=E3=83=BBTAKA?= <51693943+yuki-is-taka@users.noreply.github.com> Date: Mon, 28 Sep 2026 11:14:11 +0900 Subject: [PATCH] winmidi: convert input timestamps from MidiClock ticks to nanoseconds Windows MIDI Services timestamps are MidiClock ticks (100 ns on current Windows), but libremidi timestamps are in ns, so they came out 100x too small. Convert them using MidiClock::TimestampFrequency(). --- include/libremidi/backends/winmidi/midi_in.hpp | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/include/libremidi/backends/winmidi/midi_in.hpp b/include/libremidi/backends/winmidi/midi_in.hpp index de837375..1cec7282 100644 --- a/include/libremidi/backends/winmidi/midi_in.hpp +++ b/include/libremidi/backends/winmidi/midi_in.hpp @@ -77,6 +77,10 @@ class midi_in_impl final : MidiSession::Create(to_hstring(configuration.client_name))} { this->client_open_ = stdx::error{}; + + m_tick_frequency_hz = MidiClock::TimestampFrequency(); + if (m_tick_frequency_hz == 0) + m_tick_frequency_hz = 10'000'000; // 100 ns ticks } ~midi_in_impl() override @@ -181,6 +185,15 @@ class midi_in_impl final } #endif + // split in two so ticks * 1e9 can't overflow + std::uint64_t ticks_to_ns(std::uint64_t ticks) const noexcept + { + constexpr std::uint64_t ns_per_s = 1'000'000'000ull; + const std::uint64_t whole_seconds = ticks / m_tick_frequency_hz; + const std::uint64_t remainder_ticks = ticks % m_tick_frequency_hz; + return whole_seconds * ns_per_s + (remainder_ticks * ns_per_s) / m_tick_frequency_hz; + } + void process_message( const winrt::Microsoft::Windows::Devices::Midi2::MidiMessageReceivedEventArgs& msg) { @@ -205,7 +218,7 @@ class midi_in_impl final array_view ref{ump_space}; b.GetMany(0, ref); - auto to_ns = [t = ump.Timestamp()] { return t; }; + auto to_ns = [this, t = ump.Timestamp()] { return ticks_to_ns(t); }; m_processing.on_bytes( {ump_space, ump_space + b.Size()}, m_processing.timestamp(to_ns, 0)); } @@ -234,7 +247,7 @@ class midi_in_impl final return; } - auto to_ns = [t = timestamp] { return t; }; + auto to_ns = [this, t = timestamp] { return ticks_to_ns(t); }; m_processing.on_bytes( {ump, ump + wordCount}, m_processing.timestamp(to_ns, 0)); } @@ -282,5 +295,6 @@ class midi_in_impl final #endif midi2::input_state_machine m_processing{this->configuration}; int m_group_filter = -1; + std::uint64_t m_tick_frequency_hz{}; }; }