I forgot to mention that IDirectMusicPerformance is a high level API and needs to call down to lower level APIs. The temptation is to implement stuff directly in IDirectMusicPerformance as that is what applications call. But applications can and do mix and match IDirectMusicPerformance with lower level APIs.
Implementing the lower level graph makes testing it easier, otherwise the tests only pass on Windows and, for instance, we would not be able to use the tests to validate the messages that are passing through using tools.
The implementation in dmime: Implement MusicToReferenceTime and ReferenceToMusicTime. feels wrong:
- Magic value 6510
- DMUS_E_NO_MASTER_CLOCK as error if dmusic pointer is missing
This feels like that should call down to a lower level API and eventually to the SynthSink methods SampleToRefTime / RefTimeToSample. I don't see a path down there though. Maybe calculated based on values it gets from the port via IKsControl::KsProperty? http://doc.51windows.net/directx9_sdk/htm/ksproperty.htm%5C Or maybe by comparing the latency clock to the master clock? https://learn.microsoft.com/en-us/windows-hardware/drivers/audio/clock-synch...
I don't think the performance has anything to do with the output port, they are quite independent, and messages may go to one port or another. I also don't see how these functions could involve the dmusic master clock in any way, but maybe DMUS_E_NO_MASTER_CLOCK is returned because native gets a pointer to dmusic master clock on Init, and checks it here as a hint of whether Init was called or not. I've done the same, so that we use the same master clock for performance time over the entire playback.
Instead, it looks like the magic value needs to involve DMUS_PPQ, as described in https://learn.microsoft.com/en-us/previous-versions/ms807045(v=msdn.10). It should also involve the current tempo, but I couldn't figure how to change it in a way that it has an effect on the music time. I'll leave the value hardcoded for now, as even the formula suggested in https://learn.microsoft.com/en-us/previous-versions/ms810782(v=msdn.10) gives inaccurate values (unless we use a weird default tempo float value) and that 6510 seems to be very accurately returned by native.
I've changed the trace to semi-stub until we can figure this out in a better way but I'd like to have them implemented already so that we can convert PMSG time in SendPMsg.