From: Anton Baskanov baskanov@gmail.com
This improves the clock granularity and fixes uneven playback of some tracks. --- dlls/dmsynth/synthsink.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/dlls/dmsynth/synthsink.c b/dlls/dmsynth/synthsink.c index dd0066e828f..41339dd34c5 100644 --- a/dlls/dmsynth/synthsink.c +++ b/dlls/dmsynth/synthsink.c @@ -44,6 +44,7 @@ struct synth_sink
CRITICAL_SECTION cs; REFERENCE_TIME latency_time; + REFERENCE_TIME latency;
DWORD written; /* number of bytes written out */ HANDLE stop_event; @@ -178,9 +179,13 @@ static HRESULT synth_sink_wait_play_end(struct synth_sink *sink, IDirectSoundBuf static HRESULT synth_sink_render_data(struct synth_sink *sink, IDirectMusicSynth *synth, IDirectSoundBuffer *buffer, WAVEFORMATEX *format, short *samples, DWORD samples_size) { + REFERENCE_TIME master_time; REFERENCE_TIME sample_time; HRESULT hr;
+ if (FAILED(hr = IReferenceClock_GetTime(sink->master_clock, &master_time))) + ERR("Failed to get master clock time, hr %#lx\n", hr); + if (FAILED(hr = IDirectMusicSynth_Render(synth, samples, samples_size / format->nBlockAlign, sink->written / format->nBlockAlign))) ERR("Failed to render synthesizer samples, hr %#lx\n", hr); @@ -190,7 +195,7 @@ static HRESULT synth_sink_render_data(struct synth_sink *sink, IDirectMusicSynth ERR("Failed to convert sample position to time, hr %#lx\n", hr);
EnterCriticalSection(&sink->cs); - sink->latency_time = sample_time; + sink->latency = sample_time - master_time; LeaveCriticalSection(&sink->cs);
return hr; @@ -696,13 +701,19 @@ static ULONG WINAPI latency_clock_Release(IReferenceClock *iface) static HRESULT WINAPI latency_clock_GetTime(IReferenceClock *iface, REFERENCE_TIME *time) { struct synth_sink *This = impl_from_IReferenceClock(iface); + REFERENCE_TIME master_time; + HRESULT hr;
TRACE("(%p, %p)\n", iface, time);
if (!time) return E_INVALIDARG; if (!This->active) return E_FAIL;
+ if (FAILED(hr = IReferenceClock_GetTime(This->master_clock, &master_time))) + return hr; + EnterCriticalSection(&This->cs); + This->latency_time = max(This->latency_time, master_time + This->latency); *time = This->latency_time; LeaveCriticalSection(&This->cs);