From: Rémi Bernon rbernon@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);
From: Rémi Bernon rbernon@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;
From: Rémi Bernon rbernon@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);
From: Rémi Bernon rbernon@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);
From: Rémi Bernon rbernon@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;
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.
This merge request was approved by Michael Stefaniuc.