[PATCH 7/7] winecoreaudio: Move get_mix_format to the unixlib.
Huw Davies
huw at codeweavers.com
Thu Nov 18 01:52:38 CST 2021
Signed-off-by: Huw Davies <huw at codeweavers.com>
---
dlls/winecoreaudio.drv/coreaudio.c | 246 +++++++++++++++++++++++++++
dlls/winecoreaudio.drv/mmdevdrv.c | 256 ++---------------------------
dlls/winecoreaudio.drv/unixlib.h | 9 +
3 files changed, 267 insertions(+), 244 deletions(-)
diff --git a/dlls/winecoreaudio.drv/coreaudio.c b/dlls/winecoreaudio.drv/coreaudio.c
index 3ab80efc4e2..208655d20c6 100644
--- a/dlls/winecoreaudio.drv/coreaudio.c
+++ b/dlls/winecoreaudio.drv/coreaudio.c
@@ -703,9 +703,255 @@ static NTSTATUS release_stream( void *args )
return STATUS_SUCCESS;
}
+static DWORD ca_channel_layout_to_channel_mask(const AudioChannelLayout *layout)
+{
+ int i;
+ DWORD mask = 0;
+
+ for (i = 0; i < layout->mNumberChannelDescriptions; ++i) {
+ switch (layout->mChannelDescriptions[i].mChannelLabel) {
+ default: FIXME("Unhandled channel 0x%x\n",
+ (unsigned int)layout->mChannelDescriptions[i].mChannelLabel); break;
+ case kAudioChannelLabel_Left: mask |= SPEAKER_FRONT_LEFT; break;
+ case kAudioChannelLabel_Mono:
+ case kAudioChannelLabel_Center: mask |= SPEAKER_FRONT_CENTER; break;
+ case kAudioChannelLabel_Right: mask |= SPEAKER_FRONT_RIGHT; break;
+ case kAudioChannelLabel_LeftSurround: mask |= SPEAKER_BACK_LEFT; break;
+ case kAudioChannelLabel_CenterSurround: mask |= SPEAKER_BACK_CENTER; break;
+ case kAudioChannelLabel_RightSurround: mask |= SPEAKER_BACK_RIGHT; break;
+ case kAudioChannelLabel_LFEScreen: mask |= SPEAKER_LOW_FREQUENCY; break;
+ case kAudioChannelLabel_LeftSurroundDirect: mask |= SPEAKER_SIDE_LEFT; break;
+ case kAudioChannelLabel_RightSurroundDirect: mask |= SPEAKER_SIDE_RIGHT; break;
+ case kAudioChannelLabel_TopCenterSurround: mask |= SPEAKER_TOP_CENTER; break;
+ case kAudioChannelLabel_VerticalHeightLeft: mask |= SPEAKER_TOP_FRONT_LEFT; break;
+ case kAudioChannelLabel_VerticalHeightCenter: mask |= SPEAKER_TOP_FRONT_CENTER; break;
+ case kAudioChannelLabel_VerticalHeightRight: mask |= SPEAKER_TOP_FRONT_RIGHT; break;
+ case kAudioChannelLabel_TopBackLeft: mask |= SPEAKER_TOP_BACK_LEFT; break;
+ case kAudioChannelLabel_TopBackCenter: mask |= SPEAKER_TOP_BACK_CENTER; break;
+ case kAudioChannelLabel_TopBackRight: mask |= SPEAKER_TOP_BACK_RIGHT; break;
+ case kAudioChannelLabel_LeftCenter: mask |= SPEAKER_FRONT_LEFT_OF_CENTER; break;
+ case kAudioChannelLabel_RightCenter: mask |= SPEAKER_FRONT_RIGHT_OF_CENTER; break;
+ }
+ }
+
+ return mask;
+}
+
+/* For most hardware on Windows, users must choose a configuration with an even
+ * number of channels (stereo, quad, 5.1, 7.1). Users can then disable
+ * channels, but those channels are still reported to applications from
+ * GetMixFormat! Some applications behave badly if given an odd number of
+ * channels (e.g. 2.1). Here, we find the nearest configuration that Windows
+ * would report for a given channel layout. */
+static void convert_channel_layout(const AudioChannelLayout *ca_layout, WAVEFORMATEXTENSIBLE *fmt)
+{
+ DWORD ca_mask = ca_channel_layout_to_channel_mask(ca_layout);
+
+ TRACE("Got channel mask for CA: 0x%x\n", ca_mask);
+
+ if (ca_layout->mNumberChannelDescriptions == 1)
+ {
+ fmt->Format.nChannels = 1;
+ fmt->dwChannelMask = ca_mask;
+ return;
+ }
+
+ /* compare against known configurations and find smallest configuration
+ * which is a superset of the given speakers */
+
+ if (ca_layout->mNumberChannelDescriptions <= 2 &&
+ (ca_mask & ~KSAUDIO_SPEAKER_STEREO) == 0)
+ {
+ fmt->Format.nChannels = 2;
+ fmt->dwChannelMask = KSAUDIO_SPEAKER_STEREO;
+ return;
+ }
+
+ if (ca_layout->mNumberChannelDescriptions <= 4 &&
+ (ca_mask & ~KSAUDIO_SPEAKER_QUAD) == 0)
+ {
+ fmt->Format.nChannels = 4;
+ fmt->dwChannelMask = KSAUDIO_SPEAKER_QUAD;
+ return;
+ }
+
+ if (ca_layout->mNumberChannelDescriptions <= 4 &&
+ (ca_mask & ~KSAUDIO_SPEAKER_SURROUND) == 0)
+ {
+ fmt->Format.nChannels = 4;
+ fmt->dwChannelMask = KSAUDIO_SPEAKER_SURROUND;
+ return;
+ }
+
+ if (ca_layout->mNumberChannelDescriptions <= 6 &&
+ (ca_mask & ~KSAUDIO_SPEAKER_5POINT1) == 0)
+ {
+ fmt->Format.nChannels = 6;
+ fmt->dwChannelMask = KSAUDIO_SPEAKER_5POINT1;
+ return;
+ }
+
+ if (ca_layout->mNumberChannelDescriptions <= 6 &&
+ (ca_mask & ~KSAUDIO_SPEAKER_5POINT1_SURROUND) == 0)
+ {
+ fmt->Format.nChannels = 6;
+ fmt->dwChannelMask = KSAUDIO_SPEAKER_5POINT1_SURROUND;
+ return;
+ }
+
+ if (ca_layout->mNumberChannelDescriptions <= 8 &&
+ (ca_mask & ~KSAUDIO_SPEAKER_7POINT1) == 0)
+ {
+ fmt->Format.nChannels = 8;
+ fmt->dwChannelMask = KSAUDIO_SPEAKER_7POINT1;
+ return;
+ }
+
+ if (ca_layout->mNumberChannelDescriptions <= 8 &&
+ (ca_mask & ~KSAUDIO_SPEAKER_7POINT1_SURROUND) == 0)
+ {
+ fmt->Format.nChannels = 8;
+ fmt->dwChannelMask = KSAUDIO_SPEAKER_7POINT1_SURROUND;
+ return;
+ }
+
+ /* oddball format, report truthfully */
+ fmt->Format.nChannels = ca_layout->mNumberChannelDescriptions;
+ fmt->dwChannelMask = ca_mask;
+}
+
+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 NTSTATUS get_mix_format(void *args)
+{
+ struct get_mix_format_params *params = args;
+ AudioObjectPropertyAddress addr;
+ AudioChannelLayout *layout;
+ AudioBufferList *buffers;
+ Float64 rate;
+ UInt32 size;
+ OSStatus sc;
+ int i;
+
+ params->fmt->Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
+
+ addr.mScope = get_scope(params->flow);
+ addr.mElement = 0;
+ addr.mSelector = kAudioDevicePropertyPreferredChannelLayout;
+
+ sc = AudioObjectGetPropertyDataSize(params->dev_id, &addr, 0, NULL, &size);
+ if(sc == noErr){
+ layout = malloc(size);
+ sc = AudioObjectGetPropertyData(params->dev_id, &addr, 0, NULL, &size, layout);
+ if(sc == noErr){
+ TRACE("Got channel layout: {tag: 0x%x, bitmap: 0x%x, num_descs: %u}\n",
+ (unsigned int)layout->mChannelLayoutTag, (unsigned int)layout->mChannelBitmap,
+ (unsigned int)layout->mNumberChannelDescriptions);
+
+ if(layout->mChannelLayoutTag == kAudioChannelLayoutTag_UseChannelDescriptions){
+ convert_channel_layout(layout, params->fmt);
+ }else{
+ WARN("Haven't implemented support for this layout tag: 0x%x, guessing at layout\n",
+ (unsigned int)layout->mChannelLayoutTag);
+ params->fmt->Format.nChannels = 0;
+ }
+ }else{
+ TRACE("Unable to get _PreferredChannelLayout property: %x, guessing at layout\n", (int)sc);
+ params->fmt->Format.nChannels = 0;
+ }
+
+ free(layout);
+ }else{
+ TRACE("Unable to get size for _PreferredChannelLayout property: %x, guessing at layout\n", (int)sc);
+ params->fmt->Format.nChannels = 0;
+ }
+
+ if(params->fmt->Format.nChannels == 0){
+ addr.mScope = get_scope(params->flow);
+ addr.mElement = 0;
+ addr.mSelector = kAudioDevicePropertyStreamConfiguration;
+
+ sc = AudioObjectGetPropertyDataSize(params->dev_id, &addr, 0, NULL, &size);
+ if(sc != noErr){
+ WARN("Unable to get size for _StreamConfiguration property: %x\n", (int)sc);
+ params->result = osstatus_to_hresult(sc);
+ return STATUS_SUCCESS;
+ }
+
+ buffers = malloc(size);
+ if(!buffers){
+ params->result = E_OUTOFMEMORY;
+ return STATUS_SUCCESS;
+ }
+
+ sc = AudioObjectGetPropertyData(params->dev_id, &addr, 0, NULL, &size, buffers);
+ if(sc != noErr){
+ free(buffers);
+ WARN("Unable to get _StreamConfiguration property: %x\n", (int)sc);
+ params->result = osstatus_to_hresult(sc);
+ return STATUS_SUCCESS;
+ }
+
+ for(i = 0; i < buffers->mNumberBuffers; ++i)
+ params->fmt->Format.nChannels += buffers->mBuffers[i].mNumberChannels;
+
+ free(buffers);
+
+ params->fmt->dwChannelMask = get_channel_mask(params->fmt->Format.nChannels);
+ }
+
+ addr.mSelector = kAudioDevicePropertyNominalSampleRate;
+ size = sizeof(Float64);
+ sc = AudioObjectGetPropertyData(params->dev_id, &addr, 0, NULL, &size, &rate);
+ if(sc != noErr){
+ WARN("Unable to get _NominalSampleRate property: %x\n", (int)sc);
+ params->result = osstatus_to_hresult(sc);
+ return STATUS_SUCCESS;
+ }
+ params->fmt->Format.nSamplesPerSec = rate;
+
+ params->fmt->Format.wBitsPerSample = 32;
+ params->fmt->SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT;
+
+ params->fmt->Format.nBlockAlign = (params->fmt->Format.wBitsPerSample *
+ params->fmt->Format.nChannels) / 8;
+ params->fmt->Format.nAvgBytesPerSec = params->fmt->Format.nSamplesPerSec *
+ params->fmt->Format.nBlockAlign;
+
+ params->fmt->Samples.wValidBitsPerSample = params->fmt->Format.wBitsPerSample;
+ params->fmt->Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX);
+ params->result = S_OK;
+ return STATUS_SUCCESS;
+}
+
unixlib_entry_t __wine_unix_call_funcs[] =
{
get_endpoint_ids,
create_stream,
release_stream,
+ get_mix_format,
};
diff --git a/dlls/winecoreaudio.drv/mmdevdrv.c b/dlls/winecoreaudio.drv/mmdevdrv.c
index 572126562c6..7ec282c514d 100644
--- a/dlls/winecoreaudio.drv/mmdevdrv.c
+++ b/dlls/winecoreaudio.drv/mmdevdrv.c
@@ -689,32 +689,6 @@ static void dump_fmt(const WAVEFORMATEX *fmt)
}
}
-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 HRESULT ca_get_audiodesc(AudioStreamBasicDescription *desc,
const WAVEFORMATEX *fmt)
{
@@ -1395,134 +1369,11 @@ unsupported:
return AUDCLNT_E_UNSUPPORTED_FORMAT;
}
-static DWORD ca_channel_layout_to_channel_mask(const AudioChannelLayout *layout)
-{
- int i;
- DWORD mask = 0;
-
- for (i = 0; i < layout->mNumberChannelDescriptions; ++i) {
- switch (layout->mChannelDescriptions[i].mChannelLabel) {
- default: FIXME("Unhandled channel 0x%x\n", (unsigned int)layout->mChannelDescriptions[i].mChannelLabel); break;
- case kAudioChannelLabel_Left: mask |= SPEAKER_FRONT_LEFT; break;
- case kAudioChannelLabel_Mono:
- case kAudioChannelLabel_Center: mask |= SPEAKER_FRONT_CENTER; break;
- case kAudioChannelLabel_Right: mask |= SPEAKER_FRONT_RIGHT; break;
- case kAudioChannelLabel_LeftSurround: mask |= SPEAKER_BACK_LEFT; break;
- case kAudioChannelLabel_CenterSurround: mask |= SPEAKER_BACK_CENTER; break;
- case kAudioChannelLabel_RightSurround: mask |= SPEAKER_BACK_RIGHT; break;
- case kAudioChannelLabel_LFEScreen: mask |= SPEAKER_LOW_FREQUENCY; break;
- case kAudioChannelLabel_LeftSurroundDirect: mask |= SPEAKER_SIDE_LEFT; break;
- case kAudioChannelLabel_RightSurroundDirect: mask |= SPEAKER_SIDE_RIGHT; break;
- case kAudioChannelLabel_TopCenterSurround: mask |= SPEAKER_TOP_CENTER; break;
- case kAudioChannelLabel_VerticalHeightLeft: mask |= SPEAKER_TOP_FRONT_LEFT; break;
- case kAudioChannelLabel_VerticalHeightCenter: mask |= SPEAKER_TOP_FRONT_CENTER; break;
- case kAudioChannelLabel_VerticalHeightRight: mask |= SPEAKER_TOP_FRONT_RIGHT; break;
- case kAudioChannelLabel_TopBackLeft: mask |= SPEAKER_TOP_BACK_LEFT; break;
- case kAudioChannelLabel_TopBackCenter: mask |= SPEAKER_TOP_BACK_CENTER; break;
- case kAudioChannelLabel_TopBackRight: mask |= SPEAKER_TOP_BACK_RIGHT; break;
- case kAudioChannelLabel_LeftCenter: mask |= SPEAKER_FRONT_LEFT_OF_CENTER; break;
- case kAudioChannelLabel_RightCenter: mask |= SPEAKER_FRONT_RIGHT_OF_CENTER; break;
- }
- }
-
- return mask;
-}
-
-/* For most hardware on Windows, users must choose a configuration with an even
- * number of channels (stereo, quad, 5.1, 7.1). Users can then disable
- * channels, but those channels are still reported to applications from
- * GetMixFormat! Some applications behave badly if given an odd number of
- * channels (e.g. 2.1). Here, we find the nearest configuration that Windows
- * would report for a given channel layout. */
-static void convert_channel_layout(const AudioChannelLayout *ca_layout, WAVEFORMATEXTENSIBLE *fmt)
-{
- DWORD ca_mask = ca_channel_layout_to_channel_mask(ca_layout);
-
- TRACE("Got channel mask for CA: 0x%x\n", ca_mask);
-
- if (ca_layout->mNumberChannelDescriptions == 1)
- {
- fmt->Format.nChannels = 1;
- fmt->dwChannelMask = ca_mask;
- return;
- }
-
- /* compare against known configurations and find smallest configuration
- * which is a superset of the given speakers */
-
- if (ca_layout->mNumberChannelDescriptions <= 2 &&
- (ca_mask & ~KSAUDIO_SPEAKER_STEREO) == 0)
- {
- fmt->Format.nChannels = 2;
- fmt->dwChannelMask = KSAUDIO_SPEAKER_STEREO;
- return;
- }
-
- if (ca_layout->mNumberChannelDescriptions <= 4 &&
- (ca_mask & ~KSAUDIO_SPEAKER_QUAD) == 0)
- {
- fmt->Format.nChannels = 4;
- fmt->dwChannelMask = KSAUDIO_SPEAKER_QUAD;
- return;
- }
-
- if (ca_layout->mNumberChannelDescriptions <= 4 &&
- (ca_mask & ~KSAUDIO_SPEAKER_SURROUND) == 0)
- {
- fmt->Format.nChannels = 4;
- fmt->dwChannelMask = KSAUDIO_SPEAKER_SURROUND;
- return;
- }
-
- if (ca_layout->mNumberChannelDescriptions <= 6 &&
- (ca_mask & ~KSAUDIO_SPEAKER_5POINT1) == 0)
- {
- fmt->Format.nChannels = 6;
- fmt->dwChannelMask = KSAUDIO_SPEAKER_5POINT1;
- return;
- }
-
- if (ca_layout->mNumberChannelDescriptions <= 6 &&
- (ca_mask & ~KSAUDIO_SPEAKER_5POINT1_SURROUND) == 0)
- {
- fmt->Format.nChannels = 6;
- fmt->dwChannelMask = KSAUDIO_SPEAKER_5POINT1_SURROUND;
- return;
- }
-
- if (ca_layout->mNumberChannelDescriptions <= 8 &&
- (ca_mask & ~KSAUDIO_SPEAKER_7POINT1) == 0)
- {
- fmt->Format.nChannels = 8;
- fmt->dwChannelMask = KSAUDIO_SPEAKER_7POINT1;
- return;
- }
-
- if (ca_layout->mNumberChannelDescriptions <= 8 &&
- (ca_mask & ~KSAUDIO_SPEAKER_7POINT1_SURROUND) == 0)
- {
- fmt->Format.nChannels = 8;
- fmt->dwChannelMask = KSAUDIO_SPEAKER_7POINT1_SURROUND;
- return;
- }
-
- /* oddball format, report truthfully */
- fmt->Format.nChannels = ca_layout->mNumberChannelDescriptions;
- fmt->dwChannelMask = ca_mask;
-}
-
static HRESULT WINAPI AudioClient_GetMixFormat(IAudioClient3 *iface,
WAVEFORMATEX **pwfx)
{
ACImpl *This = impl_from_IAudioClient3(iface);
- WAVEFORMATEXTENSIBLE *fmt;
- OSStatus sc;
- UInt32 size;
- Float64 rate;
- AudioBufferList *buffers;
- AudioChannelLayout *layout;
- AudioObjectPropertyAddress addr;
- int i;
+ struct get_mix_format_params params;
TRACE("(%p)->(%p)\n", This, pwfx);
@@ -1530,104 +1381,21 @@ static HRESULT WINAPI AudioClient_GetMixFormat(IAudioClient3 *iface,
return E_POINTER;
*pwfx = NULL;
- fmt = CoTaskMemAlloc(sizeof(WAVEFORMATEXTENSIBLE));
- if(!fmt)
+ params.dev_id = This->adevid;
+ params.flow = This->dataflow;
+ params.fmt = CoTaskMemAlloc(sizeof(WAVEFORMATEXTENSIBLE));
+ if(!params.fmt)
return E_OUTOFMEMORY;
- fmt->Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
-
- addr.mScope = This->scope;
- addr.mElement = 0;
- addr.mSelector = kAudioDevicePropertyPreferredChannelLayout;
-
- sc = AudioObjectGetPropertyDataSize(This->adevid, &addr, 0, NULL, &size);
- if(sc == noErr){
- layout = HeapAlloc(GetProcessHeap(), 0, size);
-
- sc = AudioObjectGetPropertyData(This->adevid, &addr, 0, NULL, &size, layout);
- if(sc == noErr){
- TRACE("Got channel layout: {tag: 0x%x, bitmap: 0x%x, num_descs: %u}\n",
- (unsigned int)layout->mChannelLayoutTag, (unsigned int)layout->mChannelBitmap,
- (unsigned int)layout->mNumberChannelDescriptions);
-
- if(layout->mChannelLayoutTag == kAudioChannelLayoutTag_UseChannelDescriptions){
- convert_channel_layout(layout, fmt);
- }else{
- WARN("Haven't implemented support for this layout tag: 0x%x, guessing at layout\n", (unsigned int)layout->mChannelLayoutTag);
- fmt->Format.nChannels = 0;
- }
- }else{
- TRACE("Unable to get _PreferredChannelLayout property: %x, guessing at layout\n", (int)sc);
- fmt->Format.nChannels = 0;
- }
-
- HeapFree(GetProcessHeap(), 0, layout);
- }else{
- TRACE("Unable to get size for _PreferredChannelLayout property: %x, guessing at layout\n", (int)sc);
- fmt->Format.nChannels = 0;
- }
-
- if(fmt->Format.nChannels == 0){
- addr.mScope = This->scope;
- addr.mElement = 0;
- addr.mSelector = kAudioDevicePropertyStreamConfiguration;
-
- sc = AudioObjectGetPropertyDataSize(This->adevid, &addr, 0, NULL, &size);
- if(sc != noErr){
- CoTaskMemFree(fmt);
- WARN("Unable to get size for _StreamConfiguration property: %x\n", (int)sc);
- return osstatus_to_hresult(sc);
- }
-
- buffers = HeapAlloc(GetProcessHeap(), 0, size);
- if(!buffers){
- CoTaskMemFree(fmt);
- return E_OUTOFMEMORY;
- }
-
- sc = AudioObjectGetPropertyData(This->adevid, &addr, 0, NULL,
- &size, buffers);
- if(sc != noErr){
- CoTaskMemFree(fmt);
- HeapFree(GetProcessHeap(), 0, buffers);
- WARN("Unable to get _StreamConfiguration property: %x\n", (int)sc);
- return osstatus_to_hresult(sc);
- }
-
- fmt->Format.nChannels = 0;
- for(i = 0; i < buffers->mNumberBuffers; ++i)
- fmt->Format.nChannels += buffers->mBuffers[i].mNumberChannels;
-
- HeapFree(GetProcessHeap(), 0, buffers);
-
- fmt->dwChannelMask = get_channel_mask(fmt->Format.nChannels);
- }
+ UNIX_CALL(get_mix_format, ¶ms);
- addr.mSelector = kAudioDevicePropertyNominalSampleRate;
- size = sizeof(Float64);
- sc = AudioObjectGetPropertyData(This->adevid, &addr, 0, NULL, &size, &rate);
- if(sc != noErr){
- CoTaskMemFree(fmt);
- WARN("Unable to get _NominalSampleRate property: %x\n", (int)sc);
- return osstatus_to_hresult(sc);
- }
- fmt->Format.nSamplesPerSec = rate;
-
- fmt->Format.wBitsPerSample = 32;
- fmt->SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT;
-
- fmt->Format.nBlockAlign = (fmt->Format.wBitsPerSample *
- fmt->Format.nChannels) / 8;
- fmt->Format.nAvgBytesPerSec = fmt->Format.nSamplesPerSec *
- fmt->Format.nBlockAlign;
-
- fmt->Samples.wValidBitsPerSample = fmt->Format.wBitsPerSample;
- fmt->Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX);
-
- *pwfx = (WAVEFORMATEX*)fmt;
- dump_fmt(*pwfx);
+ if(SUCCEEDED(params.result)){
+ *pwfx = ¶ms.fmt->Format;
+ dump_fmt(*pwfx);
+ }else
+ CoTaskMemFree(params.fmt);
- return S_OK;
+ return params.result;
}
static HRESULT WINAPI AudioClient_GetDevicePeriod(IAudioClient3 *iface,
diff --git a/dlls/winecoreaudio.drv/unixlib.h b/dlls/winecoreaudio.drv/unixlib.h
index 7ebdc0b7786..e247b789d55 100644
--- a/dlls/winecoreaudio.drv/unixlib.h
+++ b/dlls/winecoreaudio.drv/unixlib.h
@@ -75,11 +75,20 @@ struct release_stream_params
HRESULT result;
};
+struct get_mix_format_params
+{
+ EDataFlow flow;
+ DWORD dev_id;
+ WAVEFORMATEXTENSIBLE *fmt;
+ HRESULT result;
+};
+
enum unix_funcs
{
unix_get_endpoint_ids,
unix_create_stream,
unix_release_stream,
+ unix_get_mix_format,
};
extern unixlib_handle_t coreaudio_handle;
--
2.23.0
More information about the wine-devel
mailing list