-
-
Notifications
You must be signed in to change notification settings - Fork 75
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Library uses obsolete Windows function #106
Comments
Hi, Thanks for information. But DryWetMIDI uses
The last article shows that
All these timers have super poor accuracy. You can find a lot of discussions on the web on this subject. If shortly, it's impossible to get resolution less than 16 ms with these timers. But playback API needs resolution of 1 ms to achieve the lowest possible latency. Also note that you can use theses timers with DryWetMIDI. There is But right now I don't see a strong reason to get rid of |
I understand your point. I also looked into this issue before. The subject is very poorly documented. Moreover the standard times of C# has 1ms resolution under Linux systems. In addition to it, the demo application to verify the resolution of system shows that 0.1 ms resolution can be achieved, but the method (timeBeginPeriod) used by Multimedia Timers accept only integer number. I do not say that the function need to be replaced ASAP, but that it is good to take a look on the subject. Most of the articles that say the Multimedia Times are the only way are years old, the CPU has far more resolution since than. The other question is which method is used to provide low latency on high FPS applications, as you mentioned the resolution 15 ms can not support higher than 60 FPS usage. |
Hmm, thanks for the info. Very interesting. I'll do some tests and let you know what I get. Thanks again! |
I found very useful document from Microsoft: Timer-Resolution.docx. I'll try to implement recommendations from there and rework how DWM uses high resolution for internal timer. Thanks again for the issue! |
Unfortunately it seems there is a bug in Windows 10 which leads to result of I'll keep the issue open to remember about the problem. |
I've done some tests on Windows, Ubuntu and macOS (virtual machines) to see how Test program: using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using Timer = System.Timers.Timer;
namespace TimerTest
{
class Program
{
static void Main(string[] args)
{
var interval = int.Parse(args[0]);
var stopwatch = new Stopwatch();
var times = new List<long>();
var timer = new Timer(interval);
timer.Elapsed += (_, _) => times.Add(stopwatch.ElapsedMilliseconds);
stopwatch.Start();
timer.Start();
//
SpinWait.SpinUntil(() => times.Count >= 1000);
timer.Stop();
stopwatch.Stop();
//
var time = times[0];
var deltas = new List<long>();
for (var i = 1; i < times.Count; i++)
{
var delta = times[i] - time;
deltas.Add(delta);
time = times[i];
}
//
Console.WriteLine($"Statistics for {times.Count} measures by interval of {interval}ms:");
Console.WriteLine();
Console.WriteLine($"min = {deltas.Min()}");
Console.WriteLine($"max = {deltas.Max()}");
Console.WriteLine($"avg = {deltas.Average()}");
}
}
} Results are: Windows
Ubuntu
macOS
So in fact only Ubuntu have appropriate accuracy for |
Sorry, I am not an advanced programmer, and I don't know if I understand it correctly,
CreateTimerQueueTimer function I also used TimeSetEvent before, then I tried to use CreateTimerQueueTimer in my midi-player and it seems to work (hobby-level) Sorry for non C#, but I thought it is better to post the working original code, than an untested translation
By the way, I saw this thread by chance. I just want to make some tests with this great library to see how I can use it with my (hobby) application. |
@operatortwo Thanks for the info! I'll try it. |
@operatortwo I've done a quick test and unfortunately I see 15.6 ms min interval, even if I set 1 ms. It's standard timer resolution for Windows and there is a bug on Windows 10 which makes impossible to use lower intervals with any methods except old Unfortunately it seems |
I agree that Just made a few tests to find out why I got good measurement results (down to 1 ms) with But there was no effect with the software 'GS wavetable Synth' and also not with class-compliant drivers installed by plug-and-play. |
@operatortwo What is Midi-Driver and Midi-Port? Do you mean plugging hardware devices allows set timer interval down to 1 ms? |
A Midi-Driver is sometimes provided by the manufacturer of a Midi-Hardware for the use of device-specific applications or "to ensure optimal performance". This drivers are normally downloaded an installed by the user. For example:
No. It seems to be more a special function in some, but not all USB-MIDI drivers. I used a litte application that creates a timer, does a loop count 100 and shows the elapsed milliseconds between all timerticks in a list. |
Yes, I know what a device driver is. I thought you mean some special devices and software. Hmm, very interesting. Maybe driver does some OS level manipulations internally. Thanks for the info! |
In the file:
https://github.com/melanchall/drywetmidi/blob/71bc4cabe87e8c69cba90a4f2211753cfe838118/DryWetMidi/Devices/Clock/TickGenerator/MidiTimerWinApi.cs
Library uses obsolete Windows function:
https://docs.microsoft.com/en-us/previous-versions/dd757634(v=vs.85)
https://docs.microsoft.com/en-us/windows/win32/multimedia/starting-a-single-timer
It would be recommended to replace method with new equivalent before method get deprecated and removed from future versions of Windows. As Windows 10 is a subject to obligatory auto-update, all Windows 10 users will be affected in the future.
More informations on the available Times in C#:
https://docs.microsoft.com/en-us/dotnet/api/system.threading.timer?view=net-5.0#remarks
The text was updated successfully, but these errors were encountered: