2 * Copyright 2011-2012 Maarten Lankhorst
3 * Copyright 2010-2011 Maarten Lankhorst for CodeWeavers
4 * Copyright 2011 Andrew Eikum for CodeWeavers
5 * Copyright 2022 Huw Davies
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 #include <audiopolicy.h>
25 #include <mmdeviceapi.h>
28 #include <wine/debug.h>
29 #include <wine/unixlib.h>
34 WINE_DEFAULT_DEBUG_CHANNEL(mmdevapi
);
36 extern void sessions_lock(void) DECLSPEC_HIDDEN
;
37 extern void sessions_unlock(void) DECLSPEC_HIDDEN
;
39 void set_stream_volumes(struct audio_client
*This
)
41 struct set_volumes_params params
;
43 params
.stream
= This
->stream
;
44 params
.master_volume
= (This
->session
->mute
? 0.0f
: This
->session
->master_vol
);
45 params
.volumes
= This
->vols
;
46 params
.session_volumes
= This
->session
->channel_vols
;
48 WINE_UNIX_CALL(set_volumes
, ¶ms
);
51 static inline struct audio_client
*impl_from_IAudioStreamVolume(IAudioStreamVolume
*iface
)
53 return CONTAINING_RECORD(iface
, struct audio_client
, IAudioStreamVolume_iface
);
56 static HRESULT WINAPI
streamvolume_QueryInterface(IAudioStreamVolume
*iface
, REFIID riid
,
59 TRACE("(%p)->(%s, %p)\n", iface
, debugstr_guid(riid
), ppv
);
64 if (IsEqualIID(riid
, &IID_IUnknown
) ||
65 IsEqualIID(riid
, &IID_IAudioStreamVolume
))
67 else if (IsEqualIID(riid
, &IID_IMarshal
)) {
68 struct audio_client
*This
= impl_from_IAudioStreamVolume(iface
);
69 return IUnknown_QueryInterface(This
->marshal
, riid
, ppv
);
75 IUnknown_AddRef((IUnknown
*)*ppv
);
80 static ULONG WINAPI
streamvolume_AddRef(IAudioStreamVolume
*iface
)
82 struct audio_client
*This
= impl_from_IAudioStreamVolume(iface
);
83 return IAudioClient3_AddRef(&This
->IAudioClient3_iface
);
86 static ULONG WINAPI
streamvolume_Release(IAudioStreamVolume
*iface
)
88 struct audio_client
*This
= impl_from_IAudioStreamVolume(iface
);
89 return IAudioClient3_Release(&This
->IAudioClient3_iface
);
92 static HRESULT WINAPI
streamvolume_GetChannelCount(IAudioStreamVolume
*iface
, UINT32
*out
)
94 struct audio_client
*This
= impl_from_IAudioStreamVolume(iface
);
96 TRACE("(%p)->(%p)\n", This
, out
);
101 *out
= This
->channel_count
;
106 static HRESULT WINAPI
streamvolume_SetChannelVolume(IAudioStreamVolume
*iface
, UINT32 index
,
109 struct audio_client
*This
= impl_from_IAudioStreamVolume(iface
);
111 TRACE("(%p)->(%d, %f)\n", This
, index
, level
);
113 if (level
< 0.f
|| level
> 1.f
)
117 return AUDCLNT_E_NOT_INITIALIZED
;
119 if (index
>= This
->channel_count
)
124 This
->vols
[index
] = level
;
125 set_stream_volumes(This
);
132 static HRESULT WINAPI
streamvolume_GetChannelVolume(IAudioStreamVolume
*iface
, UINT32 index
,
135 struct audio_client
*This
= impl_from_IAudioStreamVolume(iface
);
137 TRACE("(%p)->(%d, %p)\n", This
, index
, level
);
143 return AUDCLNT_E_NOT_INITIALIZED
;
145 if (index
>= This
->channel_count
)
148 *level
= This
->vols
[index
];
153 static HRESULT WINAPI
streamvolume_SetAllVolumes(IAudioStreamVolume
*iface
, UINT32 count
,
156 struct audio_client
*This
= impl_from_IAudioStreamVolume(iface
);
159 TRACE("(%p)->(%d, %p)\n", This
, count
, levels
);
165 return AUDCLNT_E_NOT_INITIALIZED
;
167 if (count
!= This
->channel_count
)
172 for (i
= 0; i
< count
; ++i
)
173 This
->vols
[i
] = levels
[i
];
174 set_stream_volumes(This
);
181 static HRESULT WINAPI
streamvolume_GetAllVolumes(IAudioStreamVolume
*iface
, UINT32 count
,
184 struct audio_client
*This
= impl_from_IAudioStreamVolume(iface
);
187 TRACE("(%p)->(%d, %p)\n", This
, count
, levels
);
193 return AUDCLNT_E_NOT_INITIALIZED
;
195 if (count
!= This
->channel_count
)
200 for (i
= 0; i
< count
; ++i
)
201 levels
[i
] = This
->vols
[i
];
208 const IAudioStreamVolumeVtbl AudioStreamVolume_Vtbl
=
210 streamvolume_QueryInterface
,
212 streamvolume_Release
,
213 streamvolume_GetChannelCount
,
214 streamvolume_SetChannelVolume
,
215 streamvolume_GetChannelVolume
,
216 streamvolume_SetAllVolumes
,
217 streamvolume_GetAllVolumes