[PATCH 0/5] MR3731: dmsynth: Implement semi-stub sink activate and time conversion methods.
From: Rémi Bernon <rbernon(a)codeweavers.com> --- dlls/dmsynth/synthsink.c | 13 ++++++++++++- dlls/dmsynth/tests/dmsynth.c | 2 +- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/dlls/dmsynth/synthsink.c b/dlls/dmsynth/synthsink.c index fce325681ee..cda44e82191 100644 --- a/dlls/dmsynth/synthsink.c +++ b/dlls/dmsynth/synthsink.c @@ -34,6 +34,7 @@ struct synth_sink IReferenceClock *latency_clock; IReferenceClock *master_clock; IDirectMusicSynth *synth; /* No reference hold! */ + IDirectSound *dsound; BOOL active; }; @@ -181,7 +182,17 @@ static HRESULT WINAPI synth_sink_SetDirectSound(IDirectMusicSynthSink *iface, { struct synth_sink *This = impl_from_IDirectMusicSynthSink(iface); - FIXME("(%p)->(%p, %p): stub\n", This, dsound, dsound_buffer); + TRACE("(%p)->(%p, %p)\n", This, dsound, dsound_buffer); + + if (dsound_buffer) FIXME("Ignoring IDirectSoundBuffer parameter.\n"); + if (This->active) return DMUS_E_SYNTHACTIVE; + + if (This->dsound) IDirectSound_Release(This->dsound); + This->dsound = NULL; + if (!dsound) return S_OK; + + if (!This->synth) return DMUS_E_SYNTHNOTCONFIGURED; + if ((This->dsound = dsound)) IDirectSound_AddRef(This->dsound); return S_OK; } diff --git a/dlls/dmsynth/tests/dmsynth.c b/dlls/dmsynth/tests/dmsynth.c index 6919e22c6d6..f0508bf01d8 100644 --- a/dlls/dmsynth/tests/dmsynth.c +++ b/dlls/dmsynth/tests/dmsynth.c @@ -1234,7 +1234,7 @@ static void test_IDirectMusicSynthSink(void) hr = IDirectMusicSynthSink_SetDirectSound(sink, NULL, NULL); ok(hr == S_OK, "got %#lx\n", hr); hr = IDirectMusicSynthSink_SetDirectSound(sink, dsound, NULL); - todo_wine ok(hr == DMUS_E_SYNTHNOTCONFIGURED, "got %#lx\n", hr); + ok(hr == DMUS_E_SYNTHNOTCONFIGURED, "got %#lx\n", hr); /* Activate requires a synth, dsound and a clock */ ref = get_refcount(synth); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/3731
From: Rémi Bernon <rbernon(a)codeweavers.com> --- dlls/dmsynth/synthsink.c | 1 + 1 file changed, 1 insertion(+) diff --git a/dlls/dmsynth/synthsink.c b/dlls/dmsynth/synthsink.c index cda44e82191..6c4f1ebecb6 100644 --- a/dlls/dmsynth/synthsink.c +++ b/dlls/dmsynth/synthsink.c @@ -125,6 +125,7 @@ static HRESULT WINAPI synth_sink_SetMasterClock(IDirectMusicSynthSink *iface, if (This->active) return E_FAIL; + if (This->master_clock) IReferenceClock_Release(This->master_clock); IReferenceClock_AddRef(clock); This->master_clock = clock; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/3731
From: Rémi Bernon <rbernon(a)codeweavers.com> --- dlls/dmsynth/synthsink.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/dlls/dmsynth/synthsink.c b/dlls/dmsynth/synthsink.c index 6c4f1ebecb6..11edb23db78 100644 --- a/dlls/dmsynth/synthsink.c +++ b/dlls/dmsynth/synthsink.c @@ -122,8 +122,6 @@ static HRESULT WINAPI synth_sink_SetMasterClock(IDirectMusicSynthSink *iface, if (!clock) return E_POINTER; - if (This->active) - return E_FAIL; if (This->master_clock) IReferenceClock_Release(This->master_clock); IReferenceClock_AddRef(clock); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/3731
From: Rémi Bernon <rbernon(a)codeweavers.com> --- dlls/dmsynth/synthsink.c | 27 +++++++++++++++++++++++++-- dlls/dmsynth/tests/dmsynth.c | 14 +++++++------- 2 files changed, 32 insertions(+), 9 deletions(-) diff --git a/dlls/dmsynth/synthsink.c b/dlls/dmsynth/synthsink.c index 11edb23db78..507c87b37c3 100644 --- a/dlls/dmsynth/synthsink.c +++ b/dlls/dmsynth/synthsink.c @@ -35,7 +35,9 @@ struct synth_sink IReferenceClock *master_clock; IDirectMusicSynth *synth; /* No reference hold! */ IDirectSound *dsound; + BOOL active; + REFERENCE_TIME activate_time; }; static inline struct synth_sink *impl_from_IDirectMusicSynthSink(IDirectMusicSynthSink *iface) @@ -43,6 +45,27 @@ static inline struct synth_sink *impl_from_IDirectMusicSynthSink(IDirectMusicSyn return CONTAINING_RECORD(iface, struct synth_sink, IDirectMusicSynthSink_iface); } +static HRESULT synth_sink_activate(struct synth_sink *This) +{ + HRESULT hr; + + if (!This->synth) return DMUS_E_SYNTHNOTCONFIGURED; + if (!This->dsound) return DMUS_E_DSOUND_NOT_SET; + if (!This->master_clock) return DMUS_E_NO_MASTER_CLOCK; + if (This->active) return DMUS_E_SYNTHACTIVE; + + if (FAILED(hr = IReferenceClock_GetTime(This->master_clock, &This->activate_time))) return hr; + + This->active = TRUE; + return S_OK; +} + +static HRESULT synth_sink_deactivate(struct synth_sink *This) +{ + This->active = FALSE; + return S_OK; +} + static HRESULT WINAPI synth_sink_QueryInterface(IDirectMusicSynthSink *iface, REFIID riid, void **ret_iface) { @@ -151,9 +174,9 @@ static HRESULT WINAPI synth_sink_Activate(IDirectMusicSynthSink *iface, { struct synth_sink *This = impl_from_IDirectMusicSynthSink(iface); - FIXME("(%p)->(%d): stub\n", This, enable); + FIXME("(%p)->(%d): semi-stub\n", This, enable); - return S_OK; + return enable ? synth_sink_activate(This) : synth_sink_deactivate(This); } static HRESULT WINAPI synth_sink_SampleToRefTime(IDirectMusicSynthSink *iface, diff --git a/dlls/dmsynth/tests/dmsynth.c b/dlls/dmsynth/tests/dmsynth.c index f0508bf01d8..35cd11980e7 100644 --- a/dlls/dmsynth/tests/dmsynth.c +++ b/dlls/dmsynth/tests/dmsynth.c @@ -1192,7 +1192,7 @@ static void test_IDirectMusicSynthSink(void) /* sink is not configured */ hr = IDirectMusicSynthSink_Activate(sink, TRUE); - todo_wine ok(hr == DMUS_E_SYNTHNOTCONFIGURED, "got %#lx\n", hr); + ok(hr == DMUS_E_SYNTHNOTCONFIGURED, "got %#lx\n", hr); hr = IDirectMusicSynthSink_Activate(sink, FALSE); ok(hr == S_OK, "got %#lx\n", hr); @@ -1247,11 +1247,11 @@ static void test_IDirectMusicSynthSink(void) ok(hr == S_OK, "got %#lx\n", hr); ok(size == 352800, "got %lu\n", size); hr = IDirectMusicSynthSink_Activate(sink, TRUE); - todo_wine ok(hr == DMUS_E_DSOUND_NOT_SET, "got %#lx\n", hr); + ok(hr == DMUS_E_DSOUND_NOT_SET, "got %#lx\n", hr); hr = IDirectMusicSynthSink_SetDirectSound(sink, dsound, NULL); ok(hr == S_OK, "got %#lx\n", hr); hr = IDirectMusicSynthSink_Activate(sink, TRUE); - todo_wine ok(hr == DMUS_E_NO_MASTER_CLOCK, "got %#lx\n", hr); + ok(hr == DMUS_E_NO_MASTER_CLOCK, "got %#lx\n", hr); hr = IDirectMusicSynthSink_SetMasterClock(sink, clock); ok(hr == S_OK, "got %#lx\n", hr); hr = IReferenceClock_GetTime(latency_clock, &time); @@ -1259,7 +1259,7 @@ static void test_IDirectMusicSynthSink(void) hr = IDirectMusicSynthSink_Activate(sink, TRUE); ok(hr == S_OK, "got %#lx\n", hr); hr = IDirectMusicSynthSink_Activate(sink, TRUE); - todo_wine ok(hr == DMUS_E_SYNTHACTIVE, "got %#lx\n", hr); + ok(hr == DMUS_E_SYNTHACTIVE, "got %#lx\n", hr); ref = get_refcount(synth); ok(ref == 1, "got %#lx\n", ref); @@ -1297,13 +1297,13 @@ static void test_IDirectMusicSynthSink(void) ref = get_refcount(synth); ok(ref == 1, "got %#lx\n", ref); hr = IDirectMusicSynthSink_Activate(sink, TRUE); - todo_wine ok(hr == DMUS_E_SYNTHNOTCONFIGURED, "got %#lx\n", hr); + ok(hr == DMUS_E_SYNTHNOTCONFIGURED, "got %#lx\n", hr); /* changing dsound while active fails */ hr = IDirectMusicSynthSink_SetDirectSound(sink, dsound, NULL); - todo_wine ok(hr == DMUS_E_SYNTHACTIVE, "got %#lx\n", hr); + ok(hr == DMUS_E_SYNTHACTIVE, "got %#lx\n", hr); hr = IDirectMusicSynthSink_SetDirectSound(sink, NULL, NULL); - todo_wine ok(hr == DMUS_E_SYNTHACTIVE, "got %#lx\n", hr); + ok(hr == DMUS_E_SYNTHACTIVE, "got %#lx\n", hr); hr = IDirectMusicSynthSink_Activate(sink, FALSE); ok(hr == S_OK, "got %#lx\n", hr); hr = IDirectMusicSynthSink_SetDirectSound(sink, NULL, NULL); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/3731
From: Rémi Bernon <rbernon(a)codeweavers.com> --- dlls/dmsynth/synthsink.c | 36 ++++++++++++++++++++++++++++++++++-- dlls/dmsynth/tests/dmsynth.c | 14 +++++++------- 2 files changed, 41 insertions(+), 9 deletions(-) diff --git a/dlls/dmsynth/synthsink.c b/dlls/dmsynth/synthsink.c index 507c87b37c3..e86763cccd0 100644 --- a/dlls/dmsynth/synthsink.c +++ b/dlls/dmsynth/synthsink.c @@ -45,6 +45,25 @@ static inline struct synth_sink *impl_from_IDirectMusicSynthSink(IDirectMusicSyn return CONTAINING_RECORD(iface, struct synth_sink, IDirectMusicSynthSink_iface); } +static void synth_sink_get_format(struct synth_sink *This, WAVEFORMATEX *format) +{ + DWORD size = sizeof(*format); + HRESULT hr; + + format->wFormatTag = WAVE_FORMAT_PCM; + format->nChannels = 2; + format->wBitsPerSample = 16; + format->nSamplesPerSec = 22050; + format->nBlockAlign = format->nChannels * format->wBitsPerSample / 8; + format->nAvgBytesPerSec = format->nSamplesPerSec * format->nBlockAlign; + + if (This->synth) + { + if (FAILED(hr = IDirectMusicSynth_GetFormat(This->synth, format, &size))) + WARN("Failed to get synth buffer format, hr %#lx\n", hr); + } +} + static HRESULT synth_sink_activate(struct synth_sink *This) { HRESULT hr; @@ -183,8 +202,14 @@ static HRESULT WINAPI synth_sink_SampleToRefTime(IDirectMusicSynthSink *iface, LONGLONG sample_time, REFERENCE_TIME *ref_time) { struct synth_sink *This = impl_from_IDirectMusicSynthSink(iface); + WAVEFORMATEX format; + + TRACE("(%p)->(%I64d, %p)\n", This, sample_time, ref_time); + + if (!ref_time) return E_POINTER; - FIXME("(%p)->(0x%s, %p): stub\n", This, wine_dbgstr_longlong(sample_time), ref_time); + synth_sink_get_format(This, &format); + *ref_time = This->activate_time + ((sample_time * 10000) / format.nSamplesPerSec) * 1000; return S_OK; } @@ -193,8 +218,15 @@ static HRESULT WINAPI synth_sink_RefTimeToSample(IDirectMusicSynthSink *iface, REFERENCE_TIME ref_time, LONGLONG *sample_time) { struct synth_sink *This = impl_from_IDirectMusicSynthSink(iface); + WAVEFORMATEX format; + + TRACE("(%p)->(%I64d, %p)\n", This, ref_time, sample_time); + + if (!sample_time) return E_POINTER; - FIXME("(%p)->(0x%s, %p): stub\n", This, wine_dbgstr_longlong(ref_time), sample_time); + synth_sink_get_format(This, &format); + ref_time -= This->activate_time; + *sample_time = ((ref_time / 1000) * format.nSamplesPerSec) / 10000; return S_OK; } diff --git a/dlls/dmsynth/tests/dmsynth.c b/dlls/dmsynth/tests/dmsynth.c index 35cd11980e7..6d695991cac 100644 --- a/dlls/dmsynth/tests/dmsynth.c +++ b/dlls/dmsynth/tests/dmsynth.c @@ -1197,18 +1197,18 @@ static void test_IDirectMusicSynthSink(void) ok(hr == S_OK, "got %#lx\n", hr); hr = IDirectMusicSynthSink_SampleToRefTime(sink, 0, NULL); - todo_wine ok(hr == E_POINTER, "got %#lx\n", hr); + ok(hr == E_POINTER, "got %#lx\n", hr); time = 0xdeadbeef; hr = IDirectMusicSynthSink_SampleToRefTime(sink, 10, &time); ok(hr == S_OK, "got %#lx\n", hr); - todo_wine ok(time == 4000, "got %I64d\n", time); + ok(time == 4000, "got %I64d\n", time); hr = IDirectMusicSynthSink_RefTimeToSample(sink, 0, NULL); - todo_wine ok(hr == E_POINTER, "got %#lx\n", hr); + ok(hr == E_POINTER, "got %#lx\n", hr); sample = 0xdeadbeef; hr = IDirectMusicSynthSink_RefTimeToSample(sink, 4000, &sample); ok(hr == S_OK, "got %#lx\n", hr); - todo_wine ok(sample == 8, "got %I64d\n", sample); + ok(sample == 8, "got %I64d\n", sample); hr = IDirectMusicSynthSink_GetDesiredBufferSize(sink, &size); ok(hr == DMUS_E_SYNTHNOTCONFIGURED, "got %#lx\n", hr); @@ -1273,12 +1273,12 @@ static void test_IDirectMusicSynthSink(void) sample = 0xdeadbeef; hr = IDirectMusicSynthSink_RefTimeToSample(sink, time, &sample); ok(hr == S_OK, "got %#lx\n", hr); - todo_wine ok(sample <= 3000, "got %I64d\n", sample); + ok(sample <= 3000, "got %I64d\n", sample); tmp_time = time + 1; hr = IDirectMusicSynthSink_SampleToRefTime(sink, sample, &tmp_time); ok(hr == S_OK, "got %#lx\n", hr); - todo_wine ok(tmp_time <= time, "got %I64d\n", tmp_time - time); - ok(time - tmp_time <= 5000, "got %I64d\n", time - tmp_time); + ok(tmp_time <= time, "got %I64d\n", tmp_time - time); + ok(time - tmp_time <= 5000, "got %I64d\n", tmp_time); /* latency clock now works fine */ tmp_time = time; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/3731
Careful with the SetMasterClock setting aka patch 3. I could have sworn that I saw that being disallowed in the method documentation but I couldn't find it. I probably mis-inheritted from the IDirectMusic8::SetMasterClock() documentation: "If another running application is also using DirectMusic, it is not possible to change the master clock until that application is shut down." But that requires a test one way or the other so I'm not blocking that patch. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/3731#note_44342
This merge request was approved by Michael Stefaniuc. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/3731
participants (2)
-
Michael Stefaniuc (@mstefani) -
Rémi Bernon