Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
videolan
vlc
Commits
7e692c9e
Commit
7e692c9e
authored
Aug 08, 2012
by
Rémi Denis-Courmont
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
wasapi: implement audio session events (fixes #7203)
This was not tested due to lack of hardware.
parent
7b61b9a1
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
163 additions
and
0 deletions
+163
-0
modules/audio_output/wasapi.c
modules/audio_output/wasapi.c
+163
-0
No files found.
modules/audio_output/wasapi.c
View file @
7e692c9e
...
@@ -24,6 +24,7 @@
...
@@ -24,6 +24,7 @@
#define INITGUID
#define INITGUID
#define COBJMACROS
#define COBJMACROS
#define CONST_VTABLE
#include <assert.h>
#include <assert.h>
#include <audioclient.h>
#include <audioclient.h>
...
@@ -77,19 +78,26 @@ static void Leave(void)
...
@@ -77,19 +78,26 @@ static void Leave(void)
struct
aout_sys_t
struct
aout_sys_t
{
{
audio_output_t
*
aout
;
IAudioClient
*
client
;
IAudioClient
*
client
;
IAudioRenderClient
*
render
;
IAudioRenderClient
*
render
;
IAudioClock
*
clock
;
IAudioClock
*
clock
;
union
union
{
{
ISimpleAudioVolume
*
simple
;
ISimpleAudioVolume
*
simple
;
}
volume
;
}
volume
;
IAudioSessionControl
*
control
;
IAudioSessionControl
*
control
;
struct
IAudioSessionEvents
events
;
LONG
refs
;
UINT32
frames
;
/**< Total buffer size (frames) */
UINT32
frames
;
/**< Total buffer size (frames) */
HANDLE
ready
;
/**< Semaphore from MTA thread */
HANDLE
ready
;
/**< Semaphore from MTA thread */
HANDLE
done
;
/**< Semaphore to MTA thread */
HANDLE
done
;
/**< Semaphore to MTA thread */
};
};
/*** VLC audio output callbacks ***/
static
void
Play
(
audio_output_t
*
aout
,
block_t
*
block
,
mtime_t
*
restrict
drift
)
static
void
Play
(
audio_output_t
*
aout
,
block_t
*
block
,
mtime_t
*
restrict
drift
)
{
{
aout_sys_t
*
sys
=
aout
->
sys
;
aout_sys_t
*
sys
=
aout
->
sys
;
...
@@ -225,6 +233,8 @@ static int SimpleMuteSet(audio_output_t *aout, bool mute)
...
@@ -225,6 +233,8 @@ static int SimpleMuteSet(audio_output_t *aout, bool mute)
return
FAILED
(
hr
)
?
-
1
:
0
;
return
FAILED
(
hr
)
?
-
1
:
0
;
}
}
/*** Audio devices ***/
static
int
DeviceChanged
(
vlc_object_t
*
obj
,
const
char
*
varname
,
static
int
DeviceChanged
(
vlc_object_t
*
obj
,
const
char
*
varname
,
vlc_value_t
prev
,
vlc_value_t
cur
,
void
*
data
)
vlc_value_t
prev
,
vlc_value_t
cur
,
void
*
data
)
{
{
...
@@ -304,6 +314,150 @@ static void GetDevices(vlc_object_t *obj, IMMDeviceEnumerator *it)
...
@@ -304,6 +314,150 @@ static void GetDevices(vlc_object_t *obj, IMMDeviceEnumerator *it)
}
}
/*** Audio session events ***/
static
inline
aout_sys_t
*
vlc_AudioSessionEvents_sys
(
IAudioSessionEvents
*
this
)
{
return
(
aout_sys_t
*
)(((
char
*
)
this
)
-
offsetof
(
aout_sys_t
,
events
));
}
static
STDMETHODIMP
vlc_AudioSessionEvents_QueryInterface
(
IAudioSessionEvents
*
this
,
REFIID
riid
,
void
**
ppv
)
{
if
(
IsEqualIID
(
riid
,
&
IID_IUnknown
)
||
IsEqualIID
(
riid
,
&
IID_IAudioSessionEvents
))
{
*
ppv
=
this
;
IUnknown_AddRef
(
this
);
return
S_OK
;
}
else
{
*
ppv
=
NULL
;
return
E_NOINTERFACE
;
}
}
static
STDMETHODIMP_
(
ULONG
)
vlc_AudioSessionEvents_AddRef
(
IAudioSessionEvents
*
this
)
{
aout_sys_t
*
sys
=
vlc_AudioSessionEvents_sys
(
this
);
return
InterlockedIncrement
(
&
sys
->
refs
);
}
static
STDMETHODIMP_
(
ULONG
)
vlc_AudioSessionEvents_Release
(
IAudioSessionEvents
*
this
)
{
aout_sys_t
*
sys
=
vlc_AudioSessionEvents_sys
(
this
);
return
InterlockedDecrement
(
&
sys
->
refs
);
}
static
STDMETHODIMP
vlc_AudioSessionEvents_OnDisplayNameChanged
(
IAudioSessionEvents
*
this
,
LPCWSTR
wname
,
LPCGUID
ctx
)
{
aout_sys_t
*
sys
=
vlc_AudioSessionEvents_sys
(
this
);
audio_output_t
*
aout
=
sys
->
aout
;
msg_Dbg
(
aout
,
"display name changed: %ls"
,
wname
);
(
void
)
ctx
;
return
S_OK
;
}
static
STDMETHODIMP
vlc_AudioSessionEvents_OnIconPathChanged
(
IAudioSessionEvents
*
this
,
LPCWSTR
wpath
,
LPCGUID
ctx
)
{
aout_sys_t
*
sys
=
vlc_AudioSessionEvents_sys
(
this
);
audio_output_t
*
aout
=
sys
->
aout
;
msg_Dbg
(
aout
,
"icon path changed: %ls"
,
wpath
);
(
void
)
ctx
;
return
S_OK
;
}
static
STDMETHODIMP
vlc_AudioSessionEvents_OnSimpleVolumeChanged
(
IAudioSessionEvents
*
this
,
float
vol
,
WINBOOL
mute
,
LPCGUID
ctx
)
{
aout_sys_t
*
sys
=
vlc_AudioSessionEvents_sys
(
this
);
audio_output_t
*
aout
=
sys
->
aout
;
msg_Dbg
(
aout
,
"simple volume changed: %f, muting %sabled"
,
vol
,
mute
?
"en"
:
"dis"
);
aout_VolumeReport
(
aout
,
vol
);
aout_MuteReport
(
aout
,
mute
==
TRUE
);
(
void
)
ctx
;
return
S_OK
;
}
static
STDMETHODIMP
vlc_AudioSessionEvents_OnChannelVolumeChanged
(
IAudioSessionEvents
*
this
,
DWORD
count
,
float
*
vols
,
DWORD
changed
,
LPCGUID
ctx
)
{
aout_sys_t
*
sys
=
vlc_AudioSessionEvents_sys
(
this
);
audio_output_t
*
aout
=
sys
->
aout
;
msg_Dbg
(
aout
,
"channel volume %lu of %lu changed: %f"
,
changed
,
count
,
vols
[
changed
]);
(
void
)
ctx
;
return
S_OK
;
}
static
STDMETHODIMP
vlc_AudioSessionEvents_OnGroupingParamChanged
(
IAudioSessionEvents
*
this
,
LPCGUID
param
,
LPCGUID
ctx
)
{
aout_sys_t
*
sys
=
vlc_AudioSessionEvents_sys
(
this
);
audio_output_t
*
aout
=
sys
->
aout
;
msg_Dbg
(
aout
,
"grouping parameter changed"
);
(
void
)
param
;
(
void
)
ctx
;
return
S_OK
;
}
static
STDMETHODIMP
vlc_AudioSessionEvents_OnStateChanged
(
IAudioSessionEvents
*
this
,
AudioSessionState
state
)
{
aout_sys_t
*
sys
=
vlc_AudioSessionEvents_sys
(
this
);
audio_output_t
*
aout
=
sys
->
aout
;
msg_Dbg
(
aout
,
"state changed: %d"
,
state
);
return
S_OK
;
}
static
STDMETHODIMP
vlc_AudioSessionEvents_OnSessionDisconnected
(
IAudioSessionEvents
*
this
,
AudioSessionDisconnectReason
reason
)
{
aout_sys_t
*
sys
=
vlc_AudioSessionEvents_sys
(
this
);
audio_output_t
*
aout
=
sys
->
aout
;
msg_Dbg
(
aout
,
"session disconnected: reason %d"
,
reason
);
return
S_OK
;
}
static
const
struct
IAudioSessionEventsVtbl
vlc_AudioSessionEvents
=
{
vlc_AudioSessionEvents_QueryInterface
,
vlc_AudioSessionEvents_AddRef
,
vlc_AudioSessionEvents_Release
,
vlc_AudioSessionEvents_OnDisplayNameChanged
,
vlc_AudioSessionEvents_OnIconPathChanged
,
vlc_AudioSessionEvents_OnSimpleVolumeChanged
,
vlc_AudioSessionEvents_OnChannelVolumeChanged
,
vlc_AudioSessionEvents_OnGroupingParamChanged
,
vlc_AudioSessionEvents_OnStateChanged
,
vlc_AudioSessionEvents_OnSessionDisconnected
,
};
/*** Initialization / deinitialization **/
static
void
vlc_ToWave
(
WAVEFORMATEXTENSIBLE
*
restrict
wf
,
static
void
vlc_ToWave
(
WAVEFORMATEXTENSIBLE
*
restrict
wf
,
audio_sample_format_t
*
restrict
audio
)
audio_sample_format_t
*
restrict
audio
)
{
{
...
@@ -471,9 +625,12 @@ static int Open(vlc_object_t *obj)
...
@@ -471,9 +625,12 @@ static int Open(vlc_object_t *obj)
aout_sys_t
*
sys
=
malloc
(
sizeof
(
*
sys
));
aout_sys_t
*
sys
=
malloc
(
sizeof
(
*
sys
));
if
(
unlikely
(
sys
==
NULL
))
if
(
unlikely
(
sys
==
NULL
))
return
VLC_ENOMEM
;
return
VLC_ENOMEM
;
sys
->
aout
=
aout
;
sys
->
client
=
NULL
;
sys
->
client
=
NULL
;
sys
->
render
=
NULL
;
sys
->
render
=
NULL
;
sys
->
clock
=
NULL
;
sys
->
clock
=
NULL
;
sys
->
events
.
lpVtbl
=
&
vlc_AudioSessionEvents
;
sys
->
refs
=
1
;
sys
->
ready
=
NULL
;
sys
->
ready
=
NULL
;
sys
->
done
=
NULL
;
sys
->
done
=
NULL
;
aout
->
sys
=
sys
;
aout
->
sys
=
sys
;
...
@@ -610,6 +767,9 @@ retry:
...
@@ -610,6 +767,9 @@ retry:
aout
->
volume_set
=
SimpleVolumeSet
;
aout
->
volume_set
=
SimpleVolumeSet
;
aout
->
mute_set
=
SimpleMuteSet
;
aout
->
mute_set
=
SimpleMuteSet
;
}
}
if
(
likely
(
sys
->
control
!=
NULL
))
IAudioSessionControl_RegisterAudioSessionNotification
(
sys
->
control
,
&
sys
->
events
);
var_AddCallback
(
aout
,
"audio-device"
,
DeviceChanged
,
NULL
);
var_AddCallback
(
aout
,
"audio-device"
,
DeviceChanged
,
NULL
);
return
VLC_SUCCESS
;
return
VLC_SUCCESS
;
...
@@ -637,6 +797,9 @@ static void Close (vlc_object_t *obj)
...
@@ -637,6 +797,9 @@ static void Close (vlc_object_t *obj)
aout_sys_t
*
sys
=
aout
->
sys
;
aout_sys_t
*
sys
=
aout
->
sys
;
Enter
();
Enter
();
if
(
likely
(
sys
->
control
!=
NULL
))
IAudioSessionControl_UnregisterAudioSessionNotification
(
sys
->
control
,
&
sys
->
events
);
ReleaseSemaphore
(
sys
->
done
,
1
,
NULL
);
/* tell MTA thread to finish */
ReleaseSemaphore
(
sys
->
done
,
1
,
NULL
);
/* tell MTA thread to finish */
WaitForSingleObject
(
sys
->
ready
,
INFINITE
);
/* wait for that ^ */
WaitForSingleObject
(
sys
->
ready
,
INFINITE
);
/* wait for that ^ */
IAudioClient_Stop
(
sys
->
client
);
/* should not be needed */
IAudioClient_Stop
(
sys
->
client
);
/* should not be needed */
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment