From: Anton Baskanov baskanov@gmail.com
--- dlls/dmime/performance.c | 46 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 3 deletions(-)
diff --git a/dlls/dmime/performance.c b/dlls/dmime/performance.c index 9f35ef1b389..45d0511f20e 100644 --- a/dlls/dmime/performance.c +++ b/dlls/dmime/performance.c @@ -38,6 +38,7 @@ struct channel DWORD midi_group; DWORD midi_channel; IDirectMusicPort *port; + IKsControl *control; };
struct channel_block @@ -269,6 +270,7 @@ static void channel_block_free(struct wine_rb_entry *entry, void *context) for (i = 0; i < ARRAY_SIZE(block->channels); i++) { struct channel *channel = block->channels + i; + if (channel->control) IKsControl_Release(channel->control); if (channel->port) IDirectMusicPort_Release(channel->port); }
@@ -284,7 +286,7 @@ static struct channel *performance_get_channel(struct performance *This, DWORD c }
static HRESULT channel_block_init(struct performance *This, DWORD block_num, - IDirectMusicPort *port, DWORD midi_group) + IDirectMusicPort *port, IKsControl *control, DWORD midi_group) { struct channel_block *block; struct wine_rb_entry *entry; @@ -304,8 +306,10 @@ static HRESULT channel_block_init(struct performance *This, DWORD block_num, struct channel *channel = block->channels + i; channel->midi_group = midi_group; channel->midi_channel = i; + if (channel->control) IKsControl_Release(channel->control); if (channel->port) IDirectMusicPort_Release(channel->port); if ((channel->port = port)) IDirectMusicPort_AddRef(channel->port); + if ((channel->control = control)) IKsControl_AddRef(channel->control); }
return S_OK; @@ -1179,7 +1183,7 @@ static HRESULT perf_dmport_create(struct performance *perf, DMUS_PORTPARAMS *par
for (i = 0; i < params->dwChannelGroups; i++) { - if (FAILED(hr = channel_block_init(perf, i, port, i + 1))) + if (FAILED(hr = channel_block_init(perf, i, port, control, i + 1))) ERR("Failed to init channel block, hr %#lx\n", hr); }
@@ -1233,6 +1237,8 @@ static HRESULT WINAPI performance_AssignPChannelBlock(IDirectMusicPerformance8 * DWORD block_num, IDirectMusicPort *port, DWORD midi_group) { struct performance *This = impl_from_IDirectMusicPerformance8(iface); + IKsControl *control; + HRESULT hr;
FIXME("(%p, %ld, %p, %ld): semi-stub\n", This, block_num, port, midi_group);
@@ -1240,7 +1246,10 @@ static HRESULT WINAPI performance_AssignPChannelBlock(IDirectMusicPerformance8 * if (block_num > MAXDWORD / 16) return E_INVALIDARG; if (This->audio_paths_enabled) return DMUS_E_AUDIOPATHS_IN_USE;
- return channel_block_init(This, block_num, port, midi_group); + if (FAILED(hr = IDirectMusicPort_QueryInterface(port, &IID_IKsControl, (void **)&control))) + return hr; + + return channel_block_init(This, block_num, port, control, midi_group); }
static HRESULT WINAPI performance_AssignPChannel(IDirectMusicPerformance8 *iface, DWORD channel_num, @@ -1248,6 +1257,7 @@ static HRESULT WINAPI performance_AssignPChannel(IDirectMusicPerformance8 *iface { struct performance *This = impl_from_IDirectMusicPerformance8(iface); struct channel *channel; + IKsControl *control; HRESULT hr;
FIXME("(%p)->(%ld, %p, %ld, %ld) semi-stub\n", This, channel_num, port, midi_group, midi_channel); @@ -1255,6 +1265,9 @@ static HRESULT WINAPI performance_AssignPChannel(IDirectMusicPerformance8 *iface if (!port) return E_POINTER; if (This->audio_paths_enabled) return DMUS_E_AUDIOPATHS_IN_USE;
+ if (FAILED(hr = IDirectMusicPort_QueryInterface(port, &IID_IKsControl, (void **)&control))) + return hr; + if (!(channel = performance_get_channel(This, channel_num))) { if (FAILED(hr = IDirectMusicPerformance8_AssignPChannelBlock(iface, @@ -1266,8 +1279,12 @@ static HRESULT WINAPI performance_AssignPChannel(IDirectMusicPerformance8 *iface
channel->midi_group = midi_group; channel->midi_channel = midi_channel; + if (channel->control) IDirectMusicPort_Release(channel->control); if (channel->port) IDirectMusicPort_Release(channel->port); if ((channel->port = port)) IDirectMusicPort_AddRef(channel->port); + if ((channel->control = control)) IKsControl_AddRef(channel->control); + + IKsControl_Release(control);
return S_OK; } @@ -1371,6 +1388,28 @@ static HRESULT WINAPI performance_GetGlobalParam(IDirectMusicPerformance8 *iface return S_OK; }
+static void update_master_volume(struct performance *This) +{ + struct channel_block *block; + KSPROPERTY volume_prop; + DWORD volume_size; + int i; + + volume_prop.Set = GUID_DMUS_PROP_Volume; + volume_prop.Id = 0; + volume_prop.Flags = KSPROPERTY_TYPE_SET; + + RB_FOR_EACH_ENTRY(block, &This->channel_blocks, struct channel_block, entry) + { + for (i = 0; i < ARRAYSIZE(block->channels); ++i) + { + IKsControl_KsProperty(block->channels[i].control, &volume_prop, + sizeof(volume_prop), &This->lMasterVolume, sizeof(This->lMasterVolume), + &volume_size); + } + } +} + static HRESULT WINAPI performance_SetGlobalParam(IDirectMusicPerformance8 *iface, REFGUID rguidType, void *pParam, DWORD dwSize) { @@ -1392,6 +1431,7 @@ static HRESULT WINAPI performance_SetGlobalParam(IDirectMusicPerformance8 *iface } if (IsEqualGUID (rguidType, &GUID_PerfMasterVolume)) { memcpy(&This->lMasterVolume, pParam, dwSize); + update_master_volume(This); TRACE("=> MasterVolume set to %li\n", This->lMasterVolume); }