Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
M
miniaudio
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Packages
Packages
List
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issues
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
MyCard
miniaudio
Commits
bc222ea0
Commit
bc222ea0
authored
Jan 02, 2017
by
David Reid
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
WASAPI: Add support for integer PCM formats.
parent
cf2bde53
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
64 additions
and
40 deletions
+64
-40
mini_al.h
mini_al.h
+64
-40
No files found.
mini_al.h
View file @
bc222ea0
...
@@ -287,6 +287,7 @@ typedef int mal_result;
...
@@ -287,6 +287,7 @@ typedef int mal_result;
#define MAL_WASAPI_FAILED_TO_CREATE_DEVICE -3073
#define MAL_WASAPI_FAILED_TO_CREATE_DEVICE -3073
#define MAL_WASAPI_FAILED_TO_ACTIVATE_DEVICE -3074
#define MAL_WASAPI_FAILED_TO_ACTIVATE_DEVICE -3074
#define MAL_WASAPI_FAILED_TO_INITIALIZE_DEVICE -3075
#define MAL_WASAPI_FAILED_TO_INITIALIZE_DEVICE -3075
#define MAL_WASAPI_FAILED_TO_FIND_BEST_FORMAT -3076
typedef
struct
mal_device
mal_device
;
typedef
struct
mal_device
mal_device
;
...
@@ -2104,6 +2105,48 @@ static void mal_device_uninit__wasapi(mal_device* pDevice)
...
@@ -2104,6 +2105,48 @@ static void mal_device_uninit__wasapi(mal_device* pDevice)
}
}
}
}
static
mal_result
mal_device__find_best_format__wasapi
(
mal_device
*
pDevice
,
WAVEFORMATEXTENSIBLE
*
pBestFormat
)
{
mal_assert
(
pDevice
!=
NULL
);
mal_assert
(
pBestFormat
!=
NULL
);
WAVEFORMATEXTENSIBLE
wf
;
mal_zero_object
(
&
wf
);
wf
.
Format
.
cbSize
=
sizeof
(
wf
);
wf
.
Format
.
wFormatTag
=
WAVE_FORMAT_EXTENSIBLE
;
wf
.
Format
.
nChannels
=
(
WORD
)
pDevice
->
channels
;
wf
.
Format
.
nSamplesPerSec
=
(
DWORD
)
pDevice
->
sampleRate
;
wf
.
Format
.
wBitsPerSample
=
(
WORD
)
mal_get_sample_size_in_bytes
(
pDevice
->
format
)
*
8
;
wf
.
Format
.
nBlockAlign
=
(
wf
.
Format
.
nChannels
*
wf
.
Format
.
wBitsPerSample
)
/
8
;
wf
.
Format
.
nAvgBytesPerSec
=
wf
.
Format
.
nBlockAlign
*
wf
.
Format
.
nSamplesPerSec
;
wf
.
Samples
.
wValidBitsPerSample
=
wf
.
Format
.
wBitsPerSample
;
wf
.
dwChannelMask
=
~
(((
DWORD
)
-
1
)
<<
pDevice
->
channels
);
if
(
pDevice
->
format
==
mal_format_f32
)
{
wf
.
SubFormat
=
MAL_GUID_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT
;
}
else
{
wf
.
SubFormat
=
MAL_GUID_KSDATAFORMAT_SUBTYPE_PCM
;
}
WAVEFORMATEXTENSIBLE
*
pBestFormatTemp
;
#ifdef __cplusplus
HRESULT
hr
=
((
IAudioClient
*
)
pDevice
->
wasapi
.
pAudioClient
)
->
IsFormatSupported
(
AUDCLNT_SHAREMODE_SHARED
,
(
WAVEFORMATEX
*
)
&
wf
,
(
WAVEFORMATEX
**
)
&
pBestFormatTemp
);
#else
HRESULT
hr
=
((
IAudioClient
*
)
pDevice
->
wasapi
.
pAudioClient
)
->
lpVtbl
->
IsFormatSupported
((
IAudioClient
*
)
pDevice
->
wasapi
.
pAudioClient
,
AUDCLNT_SHAREMODE_SHARED
,
(
WAVEFORMATEX
*
)
&
wf
,
(
WAVEFORMATEX
**
)
&
pBestFormatTemp
);
#endif
if
(
hr
!=
S_OK
&&
hr
!=
S_FALSE
&&
hr
!=
AUDCLNT_E_UNSUPPORTED_FORMAT
)
{
return
MAL_WASAPI_FAILED_TO_FIND_BEST_FORMAT
;
}
if
(
pBestFormatTemp
!=
NULL
)
{
mal_copy_memory
(
pBestFormat
,
pBestFormatTemp
,
sizeof
(
*
pBestFormat
));
((
MAL_PFN_CoTaskMemFree
)
pDevice
->
pContext
->
win32
.
CoTaskMemFree
)(
pBestFormatTemp
);
}
else
{
mal_copy_memory
(
pBestFormat
,
&
wf
,
sizeof
(
*
pBestFormat
));
}
return
MAL_SUCCESS
;
}
static
mal_result
mal_device_init__wasapi
(
mal_context
*
pContext
,
mal_device_type
type
,
mal_device_id
*
pDeviceID
,
mal_device_config
*
pConfig
,
mal_device
*
pDevice
)
static
mal_result
mal_device_init__wasapi
(
mal_context
*
pContext
,
mal_device_type
type
,
mal_device_id
*
pDeviceID
,
mal_device_config
*
pConfig
,
mal_device
*
pDevice
)
{
{
(
void
)
pContext
;
(
void
)
pContext
;
...
@@ -2169,44 +2212,31 @@ static mal_result mal_device_init__wasapi(mal_context* pContext, mal_device_type
...
@@ -2169,44 +2212,31 @@ static mal_result mal_device_init__wasapi(mal_context* pContext, mal_device_type
REFERENCE_TIME
bufferDurationInMicroseconds
=
((
mal_uint64
)
pConfig
->
bufferSizeInFrames
*
1000
*
1000
)
/
pConfig
->
sampleRate
;
REFERENCE_TIME
bufferDurationInMicroseconds
=
((
mal_uint64
)
pConfig
->
bufferSizeInFrames
*
1000
*
1000
)
/
pConfig
->
sampleRate
;
WAVEFORMATEXTENSIBLE
wf
;
WAVEFORMATEXTENSIBLE
wf
;
mal_zero_object
(
&
wf
);
mal_result
result
=
mal_device__find_best_format__wasapi
(
pDevice
,
&
wf
);
wf
.
Format
.
cbSize
=
sizeof
(
wf
);
if
(
result
!=
MAL_SUCCESS
)
{
wf
.
Format
.
wFormatTag
=
WAVE_FORMAT_EXTENSIBLE
;
wf
.
Format
.
nChannels
=
(
WORD
)
pConfig
->
channels
;
wf
.
Format
.
nSamplesPerSec
=
(
DWORD
)
pConfig
->
sampleRate
;
wf
.
Format
.
wBitsPerSample
=
(
WORD
)
mal_get_sample_size_in_bytes
(
pConfig
->
format
)
*
8
;
wf
.
Format
.
nBlockAlign
=
(
wf
.
Format
.
nChannels
*
wf
.
Format
.
wBitsPerSample
)
/
8
;
wf
.
Format
.
nAvgBytesPerSec
=
wf
.
Format
.
nBlockAlign
*
wf
.
Format
.
nSamplesPerSec
;
wf
.
Samples
.
wValidBitsPerSample
=
wf
.
Format
.
wBitsPerSample
;
wf
.
dwChannelMask
=
(
pConfig
->
channels
<=
2
)
?
0
:
~
(((
DWORD
)
-
1
)
<<
pConfig
->
channels
);
wf
.
SubFormat
=
MAL_GUID_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT
;
WAVEFORMATEXTENSIBLE
*
pClosestWF
;
#if 0
#ifdef __cplusplus
hr = ((IAudioClient*)pDevice->wasapi.pAudioClient)->IsFormatSupported(AUDCLNT_SHAREMODE_SHARED, (WAVEFORMATEX*)&wf, (WAVEFORMATEX**)&pClosestWF);
#else
hr = ((IAudioClient*)pDevice->wasapi.pAudioClient)->lpVtbl->IsFormatSupported((IAudioClient*)pDevice->wasapi.pAudioClient, AUDCLNT_SHAREMODE_SHARED, (WAVEFORMATEX*)&wf, (WAVEFORMATEX**)&pClosestWF);
#endif
if
(
hr
!=
S_OK
&&
hr
!=
S_FALSE
)
{
mal_device_uninit__wasapi
(
pDevice
);
mal_device_uninit__wasapi
(
pDevice
);
return
mal_post_error
(
pDevice
,
"[WASAPI] Failed to
ge
t device mix format."
,
MAL_WASAPI_FAILED_TO_ACTIVATE_DEVICE
);
return
mal_post_error
(
pDevice
,
"[WASAPI] Failed to
find bes
t device mix format."
,
MAL_WASAPI_FAILED_TO_ACTIVATE_DEVICE
);
}
}
#else
#ifdef __cplusplus
if
(
IsEqualGUID
(
&
wf
.
SubFormat
,
&
MAL_GUID_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT
))
{
hr
=
((
IAudioClient
*
)
pDevice
->
wasapi
.
pAudioClient
)
->
GetMixFormat
((
WAVEFORMATEX
**
)
&
pClosestWF
);
pDevice
->
internalFormat
=
mal_format_f32
;
#else
}
else
{
hr
=
((
IAudioClient
*
)
pDevice
->
wasapi
.
pAudioClient
)
->
lpVtbl
->
GetMixFormat
((
IAudioClient
*
)
pDevice
->
wasapi
.
pAudioClient
,
(
WAVEFORMATEX
**
)
&
pClosestWF
);
if
(
wf
.
Format
.
wBitsPerSample
==
32
)
{
#endif
pDevice
->
internalFormat
=
mal_format_s32
;
if
(
hr
!=
S_OK
&&
hr
!=
S_FALSE
)
{
}
else
if
(
wf
.
Format
.
wBitsPerSample
==
24
)
{
pDevice
->
internalFormat
=
mal_format_s24
;
}
else
if
(
wf
.
Format
.
wBitsPerSample
==
16
)
{
pDevice
->
internalFormat
=
mal_format_s16
;
}
else
if
(
wf
.
Format
.
wBitsPerSample
==
8
)
{
pDevice
->
internalFormat
=
mal_format_u8
;
}
else
{
mal_device_uninit__wasapi
(
pDevice
);
mal_device_uninit__wasapi
(
pDevice
);
return
mal_post_error
(
pDevice
,
"[WASAPI] Failed to get device mix format."
,
MAL_WASAPI_FAILED_TO_ACTIVATE_DEVICE
);
return
mal_post_error
(
pDevice
,
"[WASAPI] Device's native format is not supported."
,
MAL_FORMAT_NOT_SUPPORTED
);
}
}
}
#endif
//if (hr != S_OK) {
pDevice
->
internalChannels
=
wf
.
Format
.
nChannels
;
mal_copy_memory
(
&
wf
,
pClosestWF
,
sizeof
(
wf
));
//pDevice->internalSampleRate = wf.Format.nSamplesPerSec; // TODO: Uncomment this when SRC is implemented.
//}
#ifdef __cplusplus
#ifdef __cplusplus
hr
=
((
IAudioClient
*
)
pDevice
->
wasapi
.
pAudioClient
)
->
Initialize
(
AUDCLNT_SHAREMODE_SHARED
,
0
,
bufferDurationInMicroseconds
*
10
,
0
,
(
WAVEFORMATEX
*
)
&
wf
,
NULL
);
hr
=
((
IAudioClient
*
)
pDevice
->
wasapi
.
pAudioClient
)
->
Initialize
(
AUDCLNT_SHAREMODE_SHARED
,
0
,
bufferDurationInMicroseconds
*
10
,
0
,
(
WAVEFORMATEX
*
)
&
wf
,
NULL
);
...
@@ -2214,13 +2244,10 @@ static mal_result mal_device_init__wasapi(mal_context* pContext, mal_device_type
...
@@ -2214,13 +2244,10 @@ static mal_result mal_device_init__wasapi(mal_context* pContext, mal_device_type
hr
=
((
IAudioClient
*
)
pDevice
->
wasapi
.
pAudioClient
)
->
lpVtbl
->
Initialize
((
IAudioClient
*
)
pDevice
->
wasapi
.
pAudioClient
,
AUDCLNT_SHAREMODE_SHARED
,
0
,
bufferDurationInMicroseconds
*
10
,
0
,
(
WAVEFORMATEX
*
)
&
wf
,
NULL
);
hr
=
((
IAudioClient
*
)
pDevice
->
wasapi
.
pAudioClient
)
->
lpVtbl
->
Initialize
((
IAudioClient
*
)
pDevice
->
wasapi
.
pAudioClient
,
AUDCLNT_SHAREMODE_SHARED
,
0
,
bufferDurationInMicroseconds
*
10
,
0
,
(
WAVEFORMATEX
*
)
&
wf
,
NULL
);
#endif
#endif
if
(
FAILED
(
hr
))
{
if
(
FAILED
(
hr
))
{
((
MAL_PFN_CoTaskMemFree
)
pContext
->
win32
.
CoTaskMemFree
)(
pClosestWF
);
mal_device_uninit__wasapi
(
pDevice
);
mal_device_uninit__wasapi
(
pDevice
);
return
mal_post_error
(
pDevice
,
"[WASAPI] Failed to activate device."
,
MAL_WASAPI_FAILED_TO_INITIALIZE_DEVICE
);
return
mal_post_error
(
pDevice
,
"[WASAPI] Failed to activate device."
,
MAL_WASAPI_FAILED_TO_INITIALIZE_DEVICE
);
}
}
((
MAL_PFN_CoTaskMemFree
)
pContext
->
win32
.
CoTaskMemFree
)(
pClosestWF
);
#ifdef __cplusplus
#ifdef __cplusplus
hr
=
((
IAudioClient
*
)
pDevice
->
wasapi
.
pAudioClient
)
->
GetBufferSize
(
&
pDevice
->
bufferSizeInFrames
);
hr
=
((
IAudioClient
*
)
pDevice
->
wasapi
.
pAudioClient
)
->
GetBufferSize
(
&
pDevice
->
bufferSizeInFrames
);
#else
#else
...
@@ -6031,10 +6058,7 @@ void mal_pcm_f32_to_s32(int* pOut, const float* pIn, unsigned int count)
...
@@ -6031,10 +6058,7 @@ void mal_pcm_f32_to_s32(int* pOut, const float* pIn, unsigned int count)
//
//
// WASAPI
// WASAPI
// ------
// ------
// - Add support for non-f32 formats.
// - Add support for exclusive mode?
// - Add support for exclusive mode?
// - GetMixFormat() instead of IsFormatSupported().
// - Requires a large suite of conversion routines including channel shuffling, SRC and format conversion.
// - Look into event callbacks: AUDCLNT_STREAMFLAGS_EVENTCALLBACK
// - Look into event callbacks: AUDCLNT_STREAMFLAGS_EVENTCALLBACK
// - Clean up that terrible "__cplusplus" mess by implementing wrapper functions.
// - Clean up that terrible "__cplusplus" mess by implementing wrapper functions.
//
//
...
...
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