Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
1c643f39
Commit
1c643f39
authored
Aug 25, 2015
by
Andrew Eikum
Committed by
Alexandre Julliard
Aug 26, 2015
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
xaudio2: Implement device activation.
This adds a build-time dependency on openal, and a run-time dependency on openal-soft's ALC_SOFT_loopback extension.
parent
126f0601
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
277 additions
and
6 deletions
+277
-6
configure
configure
+3
-2
configure.ac
configure.ac
+2
-1
Makefile.in
dlls/xaudio2_7/Makefile.in
+1
-0
xaudio_dll.c
dlls/xaudio2_7/xaudio_dll.c
+271
-3
No files found.
configure
View file @
1c643f39
...
...
@@ -13604,13 +13604,14 @@ fi
fi
if
test
"x
$ac_cv_lib_openal
"
!=
xyes
;
then
:
case
"x
$with_openal
"
in
x
)
as_fn_append wine_notices
"|libopenal
${
notice_platform
}
development files not found (or too old), OpenAL
won't be supported.
"
;;
x
)
as_fn_append wine_notices
"|libopenal
${
notice_platform
}
development files not found (or too old), OpenAL
and XAudio2 won't be supported
"
;;
xno
)
;;
*
)
as_fn_error
$?
"libopenal
${
notice_platform
}
development files not found (or too old), OpenAL
won't be supported.
*
)
as_fn_error
$?
"libopenal
${
notice_platform
}
development files not found (or too old), OpenAL
and XAudio2 won't be supported
This is an error since --with-openal was requested."
"
$LINENO
"
5
;;
esac
fi
test
"x
$ac_cv_lib_openal
"
=
xyes
||
enable_openal32
=
${
enable_openal32
:-
no
}
test
"x
$ac_cv_lib_openal
"
=
xyes
||
enable_xaudio2_7
=
${
enable_xaudio2_7
:-
no
}
if
test
"
$ac_cv_header_kstat_h
"
=
"yes"
then
...
...
configure.ac
View file @
1c643f39
...
...
@@ -1738,8 +1738,9 @@ then
AC_DEFINE_UNQUOTED(HAVE_OPENAL,1,[Define to 1 if OpenAL is available])],,)
fi
WINE_NOTICE_WITH(openal,[test "x$ac_cv_lib_openal" != xyes],
[libopenal ${notice_platform}development files not found (or too old), OpenAL
won't be supported.
])
[libopenal ${notice_platform}development files not found (or too old), OpenAL
and XAudio2 won't be supported
])
test "x$ac_cv_lib_openal" = xyes || enable_openal32=${enable_openal32:-no}
test "x$ac_cv_lib_openal" = xyes || enable_xaudio2_7=${enable_xaudio2_7:-no}
dnl **** Check for libkstat ****
if test "$ac_cv_header_kstat_h" = "yes"
...
...
dlls/xaudio2_7/Makefile.in
View file @
1c643f39
MODULE
=
xaudio2_7.dll
IMPORTS
=
advapi32 kernel32 ole32 user32 uuid
EXTRALIBS
=
$(OPENAL_LIBS)
C_SRCS
=
\
xaudio_dll.c
...
...
dlls/xaudio2_7/xaudio_dll.c
View file @
1c643f39
...
...
@@ -41,8 +41,14 @@
#include "mmdeviceapi.h"
#include "audioclient.h"
#include <AL/al.h>
#include <AL/alc.h>
#include <AL/alext.h>
WINE_DEFAULT_DEBUG_CHANNEL
(
xaudio2
);
static
ALCdevice
*
(
ALC_APIENTRY
*
palcLoopbackOpenDeviceSOFT
)(
const
ALCchar
*
);
static
HINSTANCE
instance
;
static
void
dump_fmt
(
const
WAVEFORMATEX
*
fmt
)
...
...
@@ -86,6 +92,13 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD reason, void *pReserved)
case
DLL_PROCESS_ATTACH
:
instance
=
hinstDLL
;
DisableThreadLibraryCalls
(
hinstDLL
);
if
(
!
alcIsExtensionPresent
(
NULL
,
"ALC_SOFT_loopback"
)
||
!
(
palcLoopbackOpenDeviceSOFT
=
alcGetProcAddress
(
NULL
,
"alcLoopbackOpenDeviceSOFT"
))){
ERR
(
"XAudio2 requires the ALC_SOFT_loopback extension (OpenAL-Soft >= 1.14)
\n
"
);
return
FALSE
;
}
break
;
}
return
TRUE
;
...
...
@@ -173,6 +186,14 @@ struct _IXAudio2Impl {
WCHAR
**
devids
;
UINT32
ndevs
;
IAudioClient
*
aclient
;
IAudioRenderClient
*
render
;
WAVEFORMATEXTENSIBLE
fmt
;
ALCdevice
*
al_device
;
ALCcontext
*
al_ctx
;
};
static
inline
IXAudio2Impl
*
impl_from_IXAudio2
(
IXAudio2
*
iface
)
...
...
@@ -190,6 +211,32 @@ IXAudio2Impl *impl_from_IXAudio2MasteringVoice(IXAudio2MasteringVoice *iface)
return
CONTAINING_RECORD
(
iface
,
IXAudio2Impl
,
IXAudio2MasteringVoice_iface
);
}
static
DWORD
get_channel_mask
(
unsigned
int
channels
)
{
switch
(
channels
){
case
0
:
return
0
;
case
1
:
return
KSAUDIO_SPEAKER_MONO
;
case
2
:
return
KSAUDIO_SPEAKER_STEREO
;
case
3
:
return
KSAUDIO_SPEAKER_STEREO
|
SPEAKER_LOW_FREQUENCY
;
case
4
:
return
KSAUDIO_SPEAKER_QUAD
;
/* not _SURROUND */
case
5
:
return
KSAUDIO_SPEAKER_QUAD
|
SPEAKER_LOW_FREQUENCY
;
case
6
:
return
KSAUDIO_SPEAKER_5POINT1
;
/* not 5POINT1_SURROUND */
case
7
:
return
KSAUDIO_SPEAKER_5POINT1
|
SPEAKER_BACK_CENTER
;
case
8
:
return
KSAUDIO_SPEAKER_7POINT1_SURROUND
;
/* Vista deprecates 7POINT1 */
}
FIXME
(
"Unknown speaker configuration: %u
\n
"
,
channels
);
return
0
;
}
static
void
WINAPI
XA2SRC_GetVoiceDetails
(
IXAudio2SourceVoice
*
iface
,
XAUDIO2_VOICE_DETAILS
*
pVoiceDetails
)
{
...
...
@@ -891,7 +938,29 @@ static void WINAPI XA2M_GetOutputMatrix(IXAudio2MasteringVoice *iface,
static
void
WINAPI
XA2M_DestroyVoice
(
IXAudio2MasteringVoice
*
iface
)
{
IXAudio2Impl
*
This
=
impl_from_IXAudio2MasteringVoice
(
iface
);
TRACE
(
"%p
\n
"
,
This
);
EnterCriticalSection
(
&
This
->
lock
);
if
(
!
This
->
aclient
){
LeaveCriticalSection
(
&
This
->
lock
);
return
;
}
IAudioRenderClient_Release
(
This
->
render
);
This
->
render
=
NULL
;
IAudioClient_Release
(
This
->
aclient
);
This
->
aclient
=
NULL
;
alcCloseDevice
(
This
->
al_device
);
This
->
al_device
=
NULL
;
alcDestroyContext
(
This
->
al_ctx
);
This
->
al_ctx
=
NULL
;
LeaveCriticalSection
(
&
This
->
lock
);
}
/* not present in XAudio2 2.7 */
...
...
@@ -1164,6 +1233,8 @@ static ULONG WINAPI IXAudio2Impl_Release(IXAudio2 *iface)
HeapFree
(
GetProcessHeap
(),
0
,
sub
);
}
IXAudio2MasteringVoice_DestroyVoice
(
&
This
->
IXAudio2MasteringVoice_iface
);
if
(
This
->
devenum
)
IMMDeviceEnumerator_Release
(
This
->
devenum
);
for
(
i
=
0
;
i
<
This
->
ndevs
;
++
i
)
...
...
@@ -1322,6 +1393,28 @@ static HRESULT WINAPI IXAudio2Impl_CreateSubmixVoice(IXAudio2 *iface,
return
S_OK
;
}
static
ALenum
al_get_loopback_format
(
const
WAVEFORMATEXTENSIBLE
*
fmt
)
{
if
(
fmt
->
Format
.
wFormatTag
==
WAVE_FORMAT_PCM
||
(
fmt
->
Format
.
wFormatTag
==
WAVE_FORMAT_EXTENSIBLE
&&
IsEqualGUID
(
&
fmt
->
SubFormat
,
&
KSDATAFORMAT_SUBTYPE_PCM
))){
switch
(
fmt
->
Format
.
wBitsPerSample
){
case
8
:
return
ALC_UNSIGNED_BYTE_SOFT
;
case
16
:
return
ALC_SHORT_SOFT
;
case
32
:
return
ALC_INT_SOFT
;
}
}
else
if
(
fmt
->
Format
.
wFormatTag
==
WAVE_FORMAT_IEEE_FLOAT
||
(
fmt
->
Format
.
wFormatTag
==
WAVE_FORMAT_EXTENSIBLE
&&
IsEqualGUID
(
&
fmt
->
SubFormat
,
&
KSDATAFORMAT_SUBTYPE_IEEE_FLOAT
))){
if
(
fmt
->
Format
.
wBitsPerSample
==
32
)
return
ALC_FLOAT_SOFT
;
}
return
0
;
}
static
HRESULT
WINAPI
IXAudio2Impl_CreateMasteringVoice
(
IXAudio2
*
iface
,
IXAudio2MasteringVoice
**
ppMasteringVoice
,
UINT32
inputChannels
,
UINT32
inputSampleRate
,
UINT32
flags
,
const
WCHAR
*
deviceId
,
...
...
@@ -1329,8 +1422,12 @@ static HRESULT WINAPI IXAudio2Impl_CreateMasteringVoice(IXAudio2 *iface,
AUDIO_STREAM_CATEGORY
streamCategory
)
{
IXAudio2Impl
*
This
=
impl_from_IXAudio2
(
iface
);
IMMDevice
*
dev
;
HRESULT
hr
;
WAVEFORMATEX
*
fmt
;
ALCint
attrs
[
7
];
FIXME
(
"(%p)->(%p, %u, %u, 0x%x, %s, %p, 0x%x): stub!
\n
"
,
This
,
TRACE
(
"(%p)->(%p, %u, %u, 0x%x, %s, %p, 0x%x)
\n
"
,
This
,
ppMasteringVoice
,
inputChannels
,
inputSampleRate
,
flags
,
wine_dbgstr_w
(
deviceId
),
pEffectChain
,
streamCategory
);
...
...
@@ -1340,12 +1437,183 @@ static HRESULT WINAPI IXAudio2Impl_CreateMasteringVoice(IXAudio2 *iface,
if
(
pEffectChain
)
WARN
(
"Effect chain is unimplemented
\n
"
);
/* TODO: Initialize mmdevice */
EnterCriticalSection
(
&
This
->
lock
);
/* there can only be one Mastering Voice, so just build it into XA2 */
if
(
This
->
aclient
){
LeaveCriticalSection
(
&
This
->
lock
);
return
XAUDIO2_E_INVALID_CALL
;
}
if
(
!
deviceId
){
if
(
This
->
ndevs
==
0
){
LeaveCriticalSection
(
&
This
->
lock
);
return
ERROR_NOT_FOUND
;
}
deviceId
=
This
->
devids
[
0
];
}
hr
=
IMMDeviceEnumerator_GetDevice
(
This
->
devenum
,
deviceId
,
&
dev
);
if
(
FAILED
(
hr
)){
WARN
(
"GetDevice failed: %08x
\n
"
,
hr
);
hr
=
XAUDIO2_E_DEVICE_INVALIDATED
;
goto
exit
;
}
hr
=
IMMDevice_Activate
(
dev
,
&
IID_IAudioClient
,
CLSCTX_INPROC_SERVER
,
NULL
,
(
void
**
)
&
This
->
aclient
);
if
(
FAILED
(
hr
)){
WARN
(
"Activate(IAudioClient) failed: %08x
\n
"
,
hr
);
IMMDevice_Release
(
dev
);
hr
=
XAUDIO2_E_DEVICE_INVALIDATED
;
goto
exit
;
}
IMMDevice_Release
(
dev
);
hr
=
IAudioClient_GetMixFormat
(
This
->
aclient
,
&
fmt
);
if
(
FAILED
(
hr
)){
WARN
(
"GetMixFormat failed: %08x
\n
"
,
hr
);
hr
=
XAUDIO2_E_DEVICE_INVALIDATED
;
goto
exit
;
}
if
(
sizeof
(
WAVEFORMATEX
)
+
fmt
->
cbSize
>
sizeof
(
WAVEFORMATEXTENSIBLE
)){
FIXME
(
"Mix format doesn't fit into WAVEFORMATEXTENSIBLE!
\n
"
);
hr
=
XAUDIO2_E_DEVICE_INVALIDATED
;
goto
exit
;
}
if
(
inputChannels
==
XAUDIO2_DEFAULT_CHANNELS
)
inputChannels
=
fmt
->
nChannels
;
if
(
inputSampleRate
==
XAUDIO2_DEFAULT_SAMPLERATE
)
inputSampleRate
=
fmt
->
nSamplesPerSec
;
memcpy
(
&
This
->
fmt
,
fmt
,
sizeof
(
WAVEFORMATEX
)
+
fmt
->
cbSize
);
This
->
fmt
.
Format
.
nChannels
=
inputChannels
;
This
->
fmt
.
Format
.
nSamplesPerSec
=
inputSampleRate
;
This
->
fmt
.
Format
.
nBlockAlign
=
This
->
fmt
.
Format
.
nChannels
*
This
->
fmt
.
Format
.
wBitsPerSample
/
8
;
This
->
fmt
.
Format
.
nAvgBytesPerSec
=
This
->
fmt
.
Format
.
nSamplesPerSec
*
This
->
fmt
.
Format
.
nBlockAlign
;
This
->
fmt
.
dwChannelMask
=
get_channel_mask
(
This
->
fmt
.
Format
.
nChannels
);
CoTaskMemFree
(
fmt
);
fmt
=
NULL
;
hr
=
IAudioClient_IsFormatSupported
(
This
->
aclient
,
AUDCLNT_SHAREMODE_SHARED
,
&
This
->
fmt
.
Format
,
&
fmt
);
if
(
hr
==
S_FALSE
){
if
(
sizeof
(
WAVEFORMATEX
)
+
fmt
->
cbSize
>
sizeof
(
WAVEFORMATEXTENSIBLE
)){
FIXME
(
"Mix format doesn't fit into WAVEFORMATEXTENSIBLE!
\n
"
);
hr
=
XAUDIO2_E_DEVICE_INVALIDATED
;
goto
exit
;
}
memcpy
(
&
This
->
fmt
,
fmt
,
sizeof
(
WAVEFORMATEX
)
+
fmt
->
cbSize
);
}
CoTaskMemFree
(
fmt
);
hr
=
IAudioClient_Initialize
(
This
->
aclient
,
AUDCLNT_SHAREMODE_SHARED
,
AUDCLNT_STREAMFLAGS_EVENTCALLBACK
,
inputSampleRate
/* 1s buffer */
,
0
,
&
This
->
fmt
.
Format
,
NULL
);
if
(
FAILED
(
hr
)){
WARN
(
"Initialize failed: %08x
\n
"
,
hr
);
hr
=
XAUDIO2_E_DEVICE_INVALIDATED
;
goto
exit
;
}
hr
=
IAudioClient_GetService
(
This
->
aclient
,
&
IID_IAudioRenderClient
,
(
void
**
)
&
This
->
render
);
if
(
FAILED
(
hr
)){
WARN
(
"GetService(IAudioRenderClient) failed: %08x
\n
"
,
hr
);
hr
=
XAUDIO2_E_DEVICE_INVALIDATED
;
goto
exit
;
}
/* setup openal context */
attrs
[
0
]
=
ALC_FORMAT_CHANNELS_SOFT
;
switch
(
inputChannels
){
case
1
:
attrs
[
1
]
=
ALC_MONO_SOFT
;
break
;
case
2
:
attrs
[
1
]
=
ALC_STEREO_SOFT
;
break
;
case
4
:
attrs
[
1
]
=
ALC_QUAD_SOFT
;
break
;
case
6
:
attrs
[
1
]
=
ALC_5POINT1_SOFT
;
break
;
case
7
:
attrs
[
1
]
=
ALC_6POINT1_SOFT
;
break
;
case
8
:
attrs
[
1
]
=
ALC_7POINT1_SOFT
;
break
;
default:
WARN
(
"OpenAL doesn't support %u channels
\n
"
,
inputChannels
);
LeaveCriticalSection
(
&
This
->
lock
);
return
AUDCLNT_E_UNSUPPORTED_FORMAT
;
}
attrs
[
2
]
=
ALC_FREQUENCY
;
attrs
[
3
]
=
inputSampleRate
;
attrs
[
4
]
=
ALC_FORMAT_TYPE_SOFT
;
attrs
[
5
]
=
al_get_loopback_format
(
&
This
->
fmt
);
attrs
[
6
]
=
0
;
if
(
!
attrs
[
5
]){
WARN
(
"OpenAL can't output samples in this format
\n
"
);
hr
=
XAUDIO2_E_DEVICE_INVALIDATED
;
goto
exit
;
}
This
->
al_device
=
palcLoopbackOpenDeviceSOFT
(
NULL
);
if
(
!
This
->
al_device
){
WARN
(
"alcLoopbackOpenDeviceSOFT failed
\n
"
);
hr
=
XAUDIO2_E_DEVICE_INVALIDATED
;
goto
exit
;
}
This
->
al_ctx
=
alcCreateContext
(
This
->
al_device
,
attrs
);
if
(
!
This
->
al_ctx
){
WARN
(
"alcCreateContext failed
\n
"
);
hr
=
XAUDIO2_E_DEVICE_INVALIDATED
;
goto
exit
;
}
if
(
alcMakeContextCurrent
(
This
->
al_ctx
)
==
ALC_FALSE
){
WARN
(
"alcMakeContextCurrent failed
\n
"
);
hr
=
XAUDIO2_E_DEVICE_INVALIDATED
;
goto
exit
;
}
IAudioClient_Start
(
This
->
aclient
);
*
ppMasteringVoice
=
&
This
->
IXAudio2MasteringVoice_iface
;
return
S_OK
;
exit:
if
(
FAILED
(
hr
)){
if
(
This
->
render
){
IAudioRenderClient_Release
(
This
->
render
);
This
->
render
=
NULL
;
}
if
(
This
->
aclient
){
IAudioClient_Release
(
This
->
aclient
);
This
->
aclient
=
NULL
;
}
if
(
This
->
al_ctx
){
alcDestroyContext
(
This
->
al_ctx
);
This
->
al_ctx
=
NULL
;
}
if
(
This
->
al_device
){
alcCloseDevice
(
This
->
al_device
);
This
->
al_device
=
NULL
;
}
}
LeaveCriticalSection
(
&
This
->
lock
);
return
hr
;
}
static
HRESULT
WINAPI
IXAudio2Impl_StartEngine
(
IXAudio2
*
iface
)
...
...
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