Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
wine
Manage
Activity
Members
Labels
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Package registry
Container Registry
Model registry
Operate
Terraform modules
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Zsolt Vadász
wine
Commits
ae9338c1
Commit
ae9338c1
authored
13 years ago
by
Andrew Eikum
Committed by
Alexandre Julliard
13 years ago
Browse files
Options
Downloads
Patches
Plain Diff
winealsa.drv: Implement volume control interfaces.
parent
af92572b
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
dlls/winealsa.drv/mmdevdrv.c
+456
-27
456 additions, 27 deletions
dlls/winealsa.drv/mmdevdrv.c
with
456 additions
and
27 deletions
dlls/winealsa.drv/mmdevdrv.c
+
456
−
27
View file @
ae9338c1
...
...
@@ -62,11 +62,19 @@ typedef struct _AudioSession {
EDataFlow
dataflow
;
float
master_vol
;
UINT32
channel_count
;
float
*
channel_vols
;
CRITICAL_SECTION
lock
;
struct
list
entry
;
}
AudioSession
;
typedef
struct
_AudioSessionWrapper
{
IAudioSessionControl2
IAudioSessionControl2_iface
;
IChannelAudioVolume
IChannelAudioVolume_iface
;
ISimpleAudioVolume
ISimpleAudioVolume_iface
;
LONG
ref
;
...
...
@@ -78,9 +86,9 @@ struct ACImpl {
IAudioClient
IAudioClient_iface
;
IAudioRenderClient
IAudioRenderClient_iface
;
IAudioCaptureClient
IAudioCaptureClient_iface
;
ISimpleAudioVolume
ISimpleAudioVolume_iface
;
IAudioClock
IAudioClock_iface
;
IAudioClock2
IAudioClock2_iface
;
IAudioStreamVolume
IAudioStreamVolume_iface
;
LONG
ref
;
...
...
@@ -95,6 +103,7 @@ struct ACImpl {
DWORD
flags
;
AUDCLNT_SHAREMODE
share
;
HANDLE
event
;
float
*
vols
;
BOOL
initted
,
started
;
UINT64
written_frames
,
held_frames
,
tmp_buffer_frames
;
...
...
@@ -133,6 +142,8 @@ static const IAudioSessionControl2Vtbl AudioSessionControl2_Vtbl;
static
const
ISimpleAudioVolumeVtbl
SimpleAudioVolume_Vtbl
;
static
const
IAudioClockVtbl
AudioClock_Vtbl
;
static
const
IAudioClock2Vtbl
AudioClock2_Vtbl
;
static
const
IAudioStreamVolumeVtbl
AudioStreamVolume_Vtbl
;
static
const
IChannelAudioVolumeVtbl
ChannelAudioVolume_Vtbl
;
int
wine_snd_pcm_recover
(
snd_pcm_t
*
pcm
,
int
err
,
int
silent
);
static
AudioSessionWrapper
*
AudioSessionWrapper_Create
(
ACImpl
*
client
);
...
...
@@ -157,9 +168,14 @@ static inline AudioSessionWrapper *impl_from_IAudioSessionControl2(IAudioSession
return
CONTAINING_RECORD
(
iface
,
AudioSessionWrapper
,
IAudioSessionControl2_iface
);
}
static
inline
ACImpl
*
impl_from_ISimpleAudioVolume
(
ISimpleAudioVolume
*
iface
)
static
inline
AudioSessionWrapper
*
impl_from_ISimpleAudioVolume
(
ISimpleAudioVolume
*
iface
)
{
return
CONTAINING_RECORD
(
iface
,
AudioSessionWrapper
,
ISimpleAudioVolume_iface
);
}
static
inline
AudioSessionWrapper
*
impl_from_IChannelAudioVolume
(
IChannelAudioVolume
*
iface
)
{
return
CONTAINING_RECORD
(
iface
,
A
CImpl
,
ISimple
AudioVolume_iface
);
return
CONTAINING_RECORD
(
iface
,
A
udioSessionWrapper
,
IChannel
AudioVolume_iface
);
}
static
inline
ACImpl
*
impl_from_IAudioClock
(
IAudioClock
*
iface
)
...
...
@@ -172,6 +188,11 @@ static inline ACImpl *impl_from_IAudioClock2(IAudioClock2 *iface)
return
CONTAINING_RECORD
(
iface
,
ACImpl
,
IAudioClock2_iface
);
}
static
inline
ACImpl
*
impl_from_IAudioStreamVolume
(
IAudioStreamVolume
*
iface
)
{
return
CONTAINING_RECORD
(
iface
,
ACImpl
,
IAudioStreamVolume_iface
);
}
BOOL
WINAPI
DllMain
(
HINSTANCE
dll
,
DWORD
reason
,
void
*
reserved
)
{
if
(
reason
==
DLL_PROCESS_ATTACH
){
...
...
@@ -227,9 +248,9 @@ HRESULT WINAPI AUDDRV_GetAudioEndpoint(void *key, IMMDevice *dev,
This
->
IAudioClient_iface
.
lpVtbl
=
&
AudioClient_Vtbl
;
This
->
IAudioRenderClient_iface
.
lpVtbl
=
&
AudioRenderClient_Vtbl
;
This
->
IAudioCaptureClient_iface
.
lpVtbl
=
&
AudioCaptureClient_Vtbl
;
This
->
ISimpleAudioVolume_iface
.
lpVtbl
=
&
SimpleAudioVolume_Vtbl
;
This
->
IAudioClock_iface
.
lpVtbl
=
&
AudioClock_Vtbl
;
This
->
IAudioClock2_iface
.
lpVtbl
=
&
AudioClock2_Vtbl
;
This
->
IAudioStreamVolume_iface
.
lpVtbl
=
&
AudioStreamVolume_Vtbl
;
if
(
dataflow
==
eRender
)
stream
=
SND_PCM_STREAM_PLAYBACK
;
...
...
@@ -312,10 +333,13 @@ static ULONG WINAPI AudioClient_Release(IAudioClient *iface)
list_remove
(
&
This
->
entry
);
if
(
list_empty
(
&
This
->
session
->
clients
)){
list_remove
(
&
This
->
session
->
entry
);
DeleteCriticalSection
(
&
This
->
session
->
lock
);
HeapFree
(
GetProcessHeap
(),
0
,
This
->
session
->
channel_vols
);
HeapFree
(
GetProcessHeap
(),
0
,
This
->
session
);
}
LeaveCriticalSection
(
&
g_sessions_lock
);
}
HeapFree
(
GetProcessHeap
(),
0
,
This
->
vols
);
HeapFree
(
GetProcessHeap
(),
0
,
This
->
local_buffer
);
HeapFree
(
GetProcessHeap
(),
0
,
This
->
hw_params
);
CoTaskMemFree
(
This
->
fmt
);
...
...
@@ -379,7 +403,8 @@ static WAVEFORMATEX *clone_format(const WAVEFORMATEX *fmt)
return
ret
;
}
static
AudioSession
*
create_session
(
const
GUID
*
guid
,
EDataFlow
flow
)
static
AudioSession
*
create_session
(
const
GUID
*
guid
,
EDataFlow
flow
,
int
num_channels
)
{
AudioSession
*
ret
;
...
...
@@ -395,6 +420,21 @@ static AudioSession *create_session(const GUID *guid, EDataFlow flow)
list_add_head
(
&
g_sessions
,
&
ret
->
entry
);
InitializeCriticalSection
(
&
ret
->
lock
);
ret
->
channel_count
=
num_channels
;
ret
->
channel_vols
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
float
)
*
num_channels
);
if
(
!
ret
->
channel_vols
){
HeapFree
(
GetProcessHeap
(),
0
,
ret
);
return
NULL
;
}
for
(;
num_channels
>
0
;
--
num_channels
)
ret
->
channel_vols
[
num_channels
-
1
]
=
1
.
f
;
ret
->
master_vol
=
1
.
f
;
return
ret
;
}
...
...
@@ -409,7 +449,7 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient *iface,
snd_pcm_uframes_t
boundary
;
const
WAVEFORMATEXTENSIBLE
*
fmtex
=
(
const
WAVEFORMATEXTENSIBLE
*
)
fmt
;
unsigned
int
time_us
,
rate
;
int
err
;
int
err
,
i
;
HRESULT
hr
=
S_OK
;
TRACE
(
"(%p)->(%x, %x, %s, %s, %p, %s)
\n
"
,
This
,
mode
,
flags
,
...
...
@@ -621,13 +661,23 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient *iface,
goto
exit
;
}
This
->
vols
=
HeapAlloc
(
GetProcessHeap
(),
0
,
fmt
->
nChannels
*
sizeof
(
float
));
if
(
!
This
->
vols
){
hr
=
E_OUTOFMEMORY
;
goto
exit
;
}
for
(
i
=
0
;
i
<
fmt
->
nChannels
;
++
i
)
This
->
vols
[
i
]
=
1
.
f
;
This
->
share
=
mode
;
This
->
flags
=
flags
;
EnterCriticalSection
(
&
g_sessions_lock
);
if
(
!
sessionguid
||
IsEqualGUID
(
sessionguid
,
&
GUID_NULL
)){
This
->
session
=
create_session
(
&
GUID_NULL
,
This
->
dataflow
);
This
->
session
=
create_session
(
&
GUID_NULL
,
This
->
dataflow
,
fmt
->
nChannels
);
if
(
!
This
->
session
){
LeaveCriticalSection
(
&
g_sessions_lock
);
hr
=
E_OUTOFMEMORY
;
...
...
@@ -636,13 +686,21 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient *iface,
}
else
{
AudioSession
*
session
;
LIST_FOR_EACH_ENTRY
(
session
,
&
g_sessions
,
AudioSession
,
entry
)
LIST_FOR_EACH_ENTRY
(
session
,
&
g_sessions
,
AudioSession
,
entry
)
{
if
(
IsEqualGUID
(
sessionguid
,
&
session
->
guid
)
&&
This
->
dataflow
==
session
->
dataflow
)
This
->
dataflow
==
session
->
dataflow
){
if
(
session
->
channel_count
!=
fmt
->
nChannels
){
LeaveCriticalSection
(
&
g_sessions_lock
);
hr
=
E_INVALIDARG
;
goto
exit
;
}
This
->
session
=
session
;
}
}
if
(
!
This
->
session
){
This
->
session
=
create_session
(
sessionguid
,
This
->
dataflow
);
This
->
session
=
create_session
(
sessionguid
,
This
->
dataflow
,
fmt
->
nChannels
);
if
(
!
This
->
session
){
LeaveCriticalSection
(
&
g_sessions_lock
);
hr
=
E_OUTOFMEMORY
;
...
...
@@ -664,6 +722,14 @@ exit:
HeapFree
(
GetProcessHeap
(),
0
,
This
->
local_buffer
);
This
->
local_buffer
=
NULL
;
}
if
(
This
->
fmt
){
HeapFree
(
GetProcessHeap
(),
0
,
This
->
fmt
);
This
->
fmt
=
NULL
;
}
if
(
This
->
vols
){
HeapFree
(
GetProcessHeap
(),
0
,
This
->
vols
);
This
->
vols
=
NULL
;
}
}
LeaveCriticalSection
(
&
This
->
lock
);
...
...
@@ -1432,6 +1498,10 @@ static HRESULT WINAPI AudioClient_GetService(IAudioClient *iface, REFIID riid,
return
AUDCLNT_E_WRONG_ENDPOINT_TYPE
;
}
*
ppv
=
&
This
->
IAudioCaptureClient_iface
;
}
else
if
(
IsEqualIID
(
riid
,
&
IID_IAudioClock
)){
*
ppv
=
&
This
->
IAudioClock_iface
;
}
else
if
(
IsEqualIID
(
riid
,
&
IID_IAudioStreamVolume
)){
*
ppv
=
&
This
->
IAudioStreamVolume_iface
;
}
else
if
(
IsEqualIID
(
riid
,
&
IID_IAudioSessionControl
)){
if
(
!
This
->
session_wrapper
){
This
->
session_wrapper
=
AudioSessionWrapper_Create
(
This
);
...
...
@@ -1442,10 +1512,26 @@ static HRESULT WINAPI AudioClient_GetService(IAudioClient *iface, REFIID riid,
}
*
ppv
=
&
This
->
session_wrapper
->
IAudioSessionControl2_iface
;
}
else
if
(
IsEqualIID
(
riid
,
&
IID_IChannelAudioVolume
)){
if
(
!
This
->
session_wrapper
){
This
->
session_wrapper
=
AudioSessionWrapper_Create
(
This
);
if
(
!
This
->
session_wrapper
){
LeaveCriticalSection
(
&
This
->
lock
);
return
E_OUTOFMEMORY
;
}
}
*
ppv
=
&
This
->
session_wrapper
->
IChannelAudioVolume_iface
;
}
else
if
(
IsEqualIID
(
riid
,
&
IID_ISimpleAudioVolume
)){
*
ppv
=
&
This
->
ISimpleAudioVolume_iface
;
}
else
if
(
IsEqualIID
(
riid
,
&
IID_IAudioClock
)){
*
ppv
=
&
This
->
IAudioClock_iface
;
if
(
!
This
->
session_wrapper
){
This
->
session_wrapper
=
AudioSessionWrapper_Create
(
This
);
if
(
!
This
->
session_wrapper
){
LeaveCriticalSection
(
&
This
->
lock
);
return
E_OUTOFMEMORY
;
}
}
*
ppv
=
&
This
->
session_wrapper
->
ISimpleAudioVolume_iface
;
}
if
(
*
ppv
){
...
...
@@ -1981,6 +2067,8 @@ static AudioSessionWrapper *AudioSessionWrapper_Create(ACImpl *client)
return
NULL
;
ret
->
IAudioSessionControl2_iface
.
lpVtbl
=
&
AudioSessionControl2_Vtbl
;
ret
->
ISimpleAudioVolume_iface
.
lpVtbl
=
&
SimpleAudioVolume_Vtbl
;
ret
->
IChannelAudioVolume_iface
.
lpVtbl
=
&
ChannelAudioVolume_Vtbl
;
ret
->
client
=
client
;
ret
->
session
=
client
->
session
;
...
...
@@ -2253,42 +2341,64 @@ static HRESULT WINAPI SimpleAudioVolume_QueryInterface(
static
ULONG
WINAPI
SimpleAudioVolume_AddRef
(
ISimpleAudioVolume
*
iface
)
{
A
CImpl
*
This
=
impl_from_ISimpleAudioVolume
(
iface
);
return
I
Audio
Client
_AddRef
(
&
This
->
IAudio
Client
_iface
);
A
udioSessionWrapper
*
This
=
impl_from_ISimpleAudioVolume
(
iface
);
return
Audio
SessionControl
_AddRef
(
&
This
->
IAudio
SessionControl2
_iface
);
}
static
ULONG
WINAPI
SimpleAudioVolume_Release
(
ISimpleAudioVolume
*
iface
)
{
A
CImpl
*
This
=
impl_from_ISimpleAudioVolume
(
iface
);
return
I
Audio
Client
_Release
(
&
This
->
IAudio
Client
_iface
);
A
udioSessionWrapper
*
This
=
impl_from_ISimpleAudioVolume
(
iface
);
return
Audio
SessionControl
_Release
(
&
This
->
IAudio
SessionControl2
_iface
);
}
static
HRESULT
WINAPI
SimpleAudioVolume_SetMasterVolume
(
ISimpleAudioVolume
*
iface
,
float
level
,
const
GUID
*
context
)
{
ACImpl
*
This
=
impl_from_ISimpleAudioVolume
(
iface
);
AudioSessionWrapper
*
This
=
impl_from_ISimpleAudioVolume
(
iface
);
AudioSession
*
session
=
This
->
session
;
FIXM
E
(
"(%p)->(%f, %
p) - stub
\n
"
,
This
,
level
,
context
);
TRAC
E
(
"(%p)->(%f, %
s)
\n
"
,
session
,
level
,
wine_dbgstr_guid
(
context
)
)
;
return
E_NOTIMPL
;
if
(
level
<
0
.
f
||
level
>
1
.
f
)
return
E_INVALIDARG
;
if
(
context
)
FIXME
(
"Notifications not supported yet
\n
"
);
TRACE
(
"ALSA does not support volume control
\n
"
);
EnterCriticalSection
(
&
session
->
lock
);
session
->
master_vol
=
level
;
LeaveCriticalSection
(
&
session
->
lock
);
return
S_OK
;
}
static
HRESULT
WINAPI
SimpleAudioVolume_GetMasterVolume
(
ISimpleAudioVolume
*
iface
,
float
*
level
)
{
ACImpl
*
This
=
impl_from_ISimpleAudioVolume
(
iface
);
AudioSessionWrapper
*
This
=
impl_from_ISimpleAudioVolume
(
iface
);
AudioSession
*
session
=
This
->
session
;
FIXM
E
(
"(%p)->(%p)
- stub
\n
"
,
This
,
level
);
TRAC
E
(
"(%p)->(%p)
\n
"
,
session
,
level
);
return
E_NOTIMPL
;
if
(
!
level
)
return
NULL_PTR_ERR
;
*
level
=
session
->
master_vol
;
return
S_OK
;
}
static
HRESULT
WINAPI
SimpleAudioVolume_SetMute
(
ISimpleAudioVolume
*
iface
,
BOOL
mute
,
const
GUID
*
context
)
{
ACImpl
*
This
=
impl_from_ISimpleAudioVolume
(
iface
);
AudioSessionWrapper
*
This
=
impl_from_ISimpleAudioVolume
(
iface
);
AudioSession
*
session
=
This
->
session
;
FIXME
(
"(%p)->(%u, %p) - stub
\n
"
,
This
,
mute
,
context
);
FIXME
(
"(%p)->(%u, %p) - stub
\n
"
,
session
,
mute
,
context
);
return
E_NOTIMPL
;
}
...
...
@@ -2296,9 +2406,13 @@ static HRESULT WINAPI SimpleAudioVolume_SetMute(ISimpleAudioVolume *iface,
static
HRESULT
WINAPI
SimpleAudioVolume_GetMute
(
ISimpleAudioVolume
*
iface
,
BOOL
*
mute
)
{
ACImpl
*
This
=
impl_from_ISimpleAudioVolume
(
iface
);
AudioSessionWrapper
*
This
=
impl_from_ISimpleAudioVolume
(
iface
);
AudioSession
*
session
=
This
->
session
;
FIXME
(
"(%p)->(%p) - stub
\n
"
,
This
,
mute
);
FIXME
(
"(%p)->(%p) - stub
\n
"
,
session
,
mute
);
if
(
!
mute
)
return
NULL_PTR_ERR
;
return
E_NOTIMPL
;
}
...
...
@@ -2313,3 +2427,318 @@ static const ISimpleAudioVolumeVtbl SimpleAudioVolume_Vtbl =
SimpleAudioVolume_SetMute
,
SimpleAudioVolume_GetMute
};
static
HRESULT
WINAPI
AudioStreamVolume_QueryInterface
(
IAudioStreamVolume
*
iface
,
REFIID
riid
,
void
**
ppv
)
{
TRACE
(
"(%p)->(%s, %p)
\n
"
,
iface
,
debugstr_guid
(
riid
),
ppv
);
if
(
!
ppv
)
return
E_POINTER
;
*
ppv
=
NULL
;
if
(
IsEqualIID
(
riid
,
&
IID_IUnknown
)
||
IsEqualIID
(
riid
,
&
IID_IAudioStreamVolume
))
*
ppv
=
iface
;
if
(
*
ppv
){
IUnknown_AddRef
((
IUnknown
*
)
*
ppv
);
return
S_OK
;
}
WARN
(
"Unknown interface %s
\n
"
,
debugstr_guid
(
riid
));
return
E_NOINTERFACE
;
}
static
ULONG
WINAPI
AudioStreamVolume_AddRef
(
IAudioStreamVolume
*
iface
)
{
ACImpl
*
This
=
impl_from_IAudioStreamVolume
(
iface
);
return
IAudioClient_AddRef
(
&
This
->
IAudioClient_iface
);
}
static
ULONG
WINAPI
AudioStreamVolume_Release
(
IAudioStreamVolume
*
iface
)
{
ACImpl
*
This
=
impl_from_IAudioStreamVolume
(
iface
);
return
IAudioClient_Release
(
&
This
->
IAudioClient_iface
);
}
static
HRESULT
WINAPI
AudioStreamVolume_GetChannelCount
(
IAudioStreamVolume
*
iface
,
UINT32
*
out
)
{
ACImpl
*
This
=
impl_from_IAudioStreamVolume
(
iface
);
TRACE
(
"(%p)->(%p)
\n
"
,
This
,
out
);
if
(
!
out
)
return
E_POINTER
;
*
out
=
This
->
fmt
->
nChannels
;
return
S_OK
;
}
static
HRESULT
WINAPI
AudioStreamVolume_SetChannelVolume
(
IAudioStreamVolume
*
iface
,
UINT32
index
,
float
level
)
{
ACImpl
*
This
=
impl_from_IAudioStreamVolume
(
iface
);
TRACE
(
"(%p)->(%d, %f)
\n
"
,
This
,
index
,
level
);
if
(
level
<
0
.
f
||
level
>
1
.
f
)
return
E_INVALIDARG
;
if
(
index
>=
This
->
fmt
->
nChannels
)
return
E_INVALIDARG
;
TRACE
(
"ALSA does not support volume control
\n
"
);
EnterCriticalSection
(
&
This
->
lock
);
This
->
vols
[
index
]
=
level
;
LeaveCriticalSection
(
&
This
->
lock
);
return
S_OK
;
}
static
HRESULT
WINAPI
AudioStreamVolume_GetChannelVolume
(
IAudioStreamVolume
*
iface
,
UINT32
index
,
float
*
level
)
{
ACImpl
*
This
=
impl_from_IAudioStreamVolume
(
iface
);
TRACE
(
"(%p)->(%d, %p)
\n
"
,
This
,
index
,
level
);
if
(
!
level
)
return
E_POINTER
;
if
(
index
>=
This
->
fmt
->
nChannels
)
return
E_INVALIDARG
;
*
level
=
This
->
vols
[
index
];
return
S_OK
;
}
static
HRESULT
WINAPI
AudioStreamVolume_SetAllVolumes
(
IAudioStreamVolume
*
iface
,
UINT32
count
,
const
float
*
levels
)
{
ACImpl
*
This
=
impl_from_IAudioStreamVolume
(
iface
);
int
i
;
TRACE
(
"(%p)->(%d, %p)
\n
"
,
This
,
count
,
levels
);
if
(
!
levels
)
return
E_POINTER
;
if
(
count
!=
This
->
fmt
->
nChannels
)
return
E_INVALIDARG
;
TRACE
(
"ALSA does not support volume control
\n
"
);
EnterCriticalSection
(
&
This
->
lock
);
for
(
i
=
0
;
i
<
count
;
++
i
)
This
->
vols
[
i
]
=
levels
[
i
];
LeaveCriticalSection
(
&
This
->
lock
);
return
S_OK
;
}
static
HRESULT
WINAPI
AudioStreamVolume_GetAllVolumes
(
IAudioStreamVolume
*
iface
,
UINT32
count
,
float
*
levels
)
{
ACImpl
*
This
=
impl_from_IAudioStreamVolume
(
iface
);
int
i
;
TRACE
(
"(%p)->(%d, %p)
\n
"
,
This
,
count
,
levels
);
if
(
!
levels
)
return
E_POINTER
;
if
(
count
!=
This
->
fmt
->
nChannels
)
return
E_INVALIDARG
;
EnterCriticalSection
(
&
This
->
lock
);
for
(
i
=
0
;
i
<
count
;
++
i
)
levels
[
i
]
=
This
->
vols
[
i
];
LeaveCriticalSection
(
&
This
->
lock
);
return
S_OK
;
}
static
const
IAudioStreamVolumeVtbl
AudioStreamVolume_Vtbl
=
{
AudioStreamVolume_QueryInterface
,
AudioStreamVolume_AddRef
,
AudioStreamVolume_Release
,
AudioStreamVolume_GetChannelCount
,
AudioStreamVolume_SetChannelVolume
,
AudioStreamVolume_GetChannelVolume
,
AudioStreamVolume_SetAllVolumes
,
AudioStreamVolume_GetAllVolumes
};
static
HRESULT
WINAPI
ChannelAudioVolume_QueryInterface
(
IChannelAudioVolume
*
iface
,
REFIID
riid
,
void
**
ppv
)
{
TRACE
(
"(%p)->(%s, %p)
\n
"
,
iface
,
debugstr_guid
(
riid
),
ppv
);
if
(
!
ppv
)
return
E_POINTER
;
*
ppv
=
NULL
;
if
(
IsEqualIID
(
riid
,
&
IID_IUnknown
)
||
IsEqualIID
(
riid
,
&
IID_IChannelAudioVolume
))
*
ppv
=
iface
;
if
(
*
ppv
){
IUnknown_AddRef
((
IUnknown
*
)
*
ppv
);
return
S_OK
;
}
WARN
(
"Unknown interface %s
\n
"
,
debugstr_guid
(
riid
));
return
E_NOINTERFACE
;
}
static
ULONG
WINAPI
ChannelAudioVolume_AddRef
(
IChannelAudioVolume
*
iface
)
{
AudioSessionWrapper
*
This
=
impl_from_IChannelAudioVolume
(
iface
);
return
AudioSessionControl_AddRef
(
&
This
->
IAudioSessionControl2_iface
);
}
static
ULONG
WINAPI
ChannelAudioVolume_Release
(
IChannelAudioVolume
*
iface
)
{
AudioSessionWrapper
*
This
=
impl_from_IChannelAudioVolume
(
iface
);
return
AudioSessionControl_Release
(
&
This
->
IAudioSessionControl2_iface
);
}
static
HRESULT
WINAPI
ChannelAudioVolume_GetChannelCount
(
IChannelAudioVolume
*
iface
,
UINT32
*
out
)
{
AudioSessionWrapper
*
This
=
impl_from_IChannelAudioVolume
(
iface
);
AudioSession
*
session
=
This
->
session
;
TRACE
(
"(%p)->(%p)
\n
"
,
session
,
out
);
if
(
!
out
)
return
NULL_PTR_ERR
;
*
out
=
session
->
channel_count
;
return
S_OK
;
}
static
HRESULT
WINAPI
ChannelAudioVolume_SetChannelVolume
(
IChannelAudioVolume
*
iface
,
UINT32
index
,
float
level
,
const
GUID
*
context
)
{
AudioSessionWrapper
*
This
=
impl_from_IChannelAudioVolume
(
iface
);
AudioSession
*
session
=
This
->
session
;
TRACE
(
"(%p)->(%d, %f, %s)
\n
"
,
session
,
index
,
level
,
wine_dbgstr_guid
(
context
));
if
(
level
<
0
.
f
||
level
>
1
.
f
)
return
E_INVALIDARG
;
if
(
index
>=
session
->
channel_count
)
return
E_INVALIDARG
;
if
(
context
)
FIXME
(
"Notifications not supported yet
\n
"
);
TRACE
(
"ALSA does not support volume control
\n
"
);
EnterCriticalSection
(
&
session
->
lock
);
session
->
channel_vols
[
index
]
=
level
;
LeaveCriticalSection
(
&
session
->
lock
);
return
S_OK
;
}
static
HRESULT
WINAPI
ChannelAudioVolume_GetChannelVolume
(
IChannelAudioVolume
*
iface
,
UINT32
index
,
float
*
level
)
{
AudioSessionWrapper
*
This
=
impl_from_IChannelAudioVolume
(
iface
);
AudioSession
*
session
=
This
->
session
;
TRACE
(
"(%p)->(%d, %p)
\n
"
,
session
,
index
,
level
);
if
(
!
level
)
return
NULL_PTR_ERR
;
if
(
index
>=
session
->
channel_count
)
return
E_INVALIDARG
;
*
level
=
session
->
channel_vols
[
index
];
return
S_OK
;
}
static
HRESULT
WINAPI
ChannelAudioVolume_SetAllVolumes
(
IChannelAudioVolume
*
iface
,
UINT32
count
,
const
float
*
levels
,
const
GUID
*
context
)
{
AudioSessionWrapper
*
This
=
impl_from_IChannelAudioVolume
(
iface
);
AudioSession
*
session
=
This
->
session
;
int
i
;
TRACE
(
"(%p)->(%d, %p, %s)
\n
"
,
session
,
count
,
levels
,
wine_dbgstr_guid
(
context
));
if
(
!
levels
)
return
NULL_PTR_ERR
;
if
(
count
!=
session
->
channel_count
)
return
E_INVALIDARG
;
if
(
context
)
FIXME
(
"Notifications not supported yet
\n
"
);
TRACE
(
"ALSA does not support volume control
\n
"
);
EnterCriticalSection
(
&
session
->
lock
);
for
(
i
=
0
;
i
<
count
;
++
i
)
session
->
channel_vols
[
i
]
=
levels
[
i
];
LeaveCriticalSection
(
&
session
->
lock
);
return
S_OK
;
}
static
HRESULT
WINAPI
ChannelAudioVolume_GetAllVolumes
(
IChannelAudioVolume
*
iface
,
UINT32
count
,
float
*
levels
)
{
AudioSessionWrapper
*
This
=
impl_from_IChannelAudioVolume
(
iface
);
AudioSession
*
session
=
This
->
session
;
int
i
;
TRACE
(
"(%p)->(%d, %p)
\n
"
,
session
,
count
,
levels
);
if
(
!
levels
)
return
NULL_PTR_ERR
;
if
(
count
!=
session
->
channel_count
)
return
E_INVALIDARG
;
for
(
i
=
0
;
i
<
count
;
++
i
)
levels
[
i
]
=
session
->
channel_vols
[
i
];
return
S_OK
;
}
static
const
IChannelAudioVolumeVtbl
ChannelAudioVolume_Vtbl
=
{
ChannelAudioVolume_QueryInterface
,
ChannelAudioVolume_AddRef
,
ChannelAudioVolume_Release
,
ChannelAudioVolume_GetChannelCount
,
ChannelAudioVolume_SetChannelVolume
,
ChannelAudioVolume_GetChannelVolume
,
ChannelAudioVolume_SetAllVolumes
,
ChannelAudioVolume_GetAllVolumes
};
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment