I want to play a sound sample (about 2 minute long) and record keystrokes while the sample is playing. I need to know the exact time a key was pressed relative to the play start time, with a resolution of 1 millisecond or less.
First I tried NAudio and a Winforms application. I found it quite impossible to synchronize the playback start time and the keystroke time. I know when I start transferring the sample bytes to NAudio, but not the time it takes between passing the sample and the actual playback. I also know the time my application receives the KeyDown event, but not the time it's actually taken for the event to go all the way from the keyboard hardware to my C# event handler.
This is more or less accurate - I get a 270ms(+- 5ms) delay between the delay reported by the application and the actual delay (I know the actual delay by recording the session and looking at the sample file. The recording is done on a different device, not the computer running the application of course...).
This isn't good enough, because of the +- 5ms. This happens even when I disabled the generation 2 GC during playback. I need to be more accurate than this.
I don't mind switching to C++ and unmanaged code, but I'd like to know which sound playback API to use, and whether there are more accurate ways to get the keyboard input than waiting for the WM_KEYDOWN message.
DirectInput
in buffered mode. It supposedly gives you a high resolution timestamp for each event. I'm not sure how you'd go about correlating that with the audio time. I know inDirectSound
you can find out exactly where playback is in the buffer so it's possible to figure out exactly how many milliseconds you are relative to the beginning of playback but I don't know if there is a good way to turn that into an absolute time. – jaket