Wine-devel
Threads by month
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
November 2021
- 83 participants
- 756 discussions
Signed-off-by: Julian Rüger <jr98(a)gmx.net>
1
0
22 Nov '21
Signed-off-by: Andrey Gusev <andrey.goosev(a)gmail.com>
---
dlls/winecoreaudio.drv/mmdevdrv.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/winecoreaudio.drv/mmdevdrv.c b/dlls/winecoreaudio.drv/mmdevdrv.c
index 1e37a2a9026..c87aff590e2 100644
--- a/dlls/winecoreaudio.drv/mmdevdrv.c
+++ b/dlls/winecoreaudio.drv/mmdevdrv.c
@@ -2092,8 +2092,8 @@ static HRESULT WINAPI AudioClient_GetService(IAudioClient3 *iface, REFIID riid,
if(*ppv) hr = S_OK;
else{
- return E_NOINTERFACE;
FIXME("stub %s\n", debugstr_guid(riid));
+ return E_NOINTERFACE;
}
end:
--
2.33.1
2
1
Signed-off-by: Huw Davies <huw(a)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
2
1
[PATCH 6/7] winecoreaudio: Move create_stream and release_stream to the unixlib.
by Huw Davies 22 Nov '21
by Huw Davies 22 Nov '21
22 Nov '21
Signed-off-by: Huw Davies <huw(a)codeweavers.com>
---
dlls/winecoreaudio.drv/coreaudio.c | 464 +++++++++++++++++++++++++++++
dlls/winecoreaudio.drv/mmdevdrv.c | 304 +++----------------
dlls/winecoreaudio.drv/unixlib.h | 20 ++
3 files changed, 527 insertions(+), 261 deletions(-)
diff --git a/dlls/winecoreaudio.drv/coreaudio.c b/dlls/winecoreaudio.drv/coreaudio.c
index f3af24f80fb..3ab80efc4e2 100644
--- a/dlls/winecoreaudio.drv/coreaudio.c
+++ b/dlls/winecoreaudio.drv/coreaudio.c
@@ -85,6 +85,30 @@ static HRESULT osstatus_to_hresult(OSStatus sc)
return E_FAIL;
}
+/* copied from kernelbase */
+static int muldiv( int a, int b, int c )
+{
+ LONGLONG ret;
+
+ if (!c) return -1;
+
+ /* We want to deal with a positive divisor to simplify the logic. */
+ if (c < 0)
+ {
+ a = -a;
+ c = -c;
+ }
+
+ /* If the result is positive, we "add" to round. else, we subtract to round. */
+ if ((a < 0 && b < 0) || (a >= 0 && b >= 0))
+ ret = (((LONGLONG)a * b) + (c / 2)) / c;
+ else
+ ret = (((LONGLONG)a * b) - (c / 2)) / c;
+
+ if (ret > 2147483647 || ret < -2147483647) return -1;
+ return ret;
+}
+
static AudioObjectPropertyScope get_scope(EDataFlow flow)
{
return (flow == eRender) ? kAudioDevicePropertyScopeOutput : kAudioDevicePropertyScopeInput;
@@ -241,7 +265,447 @@ static NTSTATUS get_endpoint_ids(void *args)
return STATUS_SUCCESS;
}
+static WAVEFORMATEX *clone_format(const WAVEFORMATEX *fmt)
+{
+ WAVEFORMATEX *ret;
+ size_t size;
+
+ if(fmt->wFormatTag == WAVE_FORMAT_EXTENSIBLE)
+ size = sizeof(WAVEFORMATEXTENSIBLE);
+ else
+ size = sizeof(WAVEFORMATEX);
+
+ ret = malloc(size);
+ if(!ret)
+ return NULL;
+
+ memcpy(ret, fmt, size);
+
+ ret->cbSize = size - sizeof(WAVEFORMATEX);
+
+ return ret;
+}
+
+static void silence_buffer(struct coreaudio_stream *stream, BYTE *buffer, UINT32 frames)
+{
+ WAVEFORMATEXTENSIBLE *fmtex = (WAVEFORMATEXTENSIBLE*)stream->fmt;
+ if((stream->fmt->wFormatTag == WAVE_FORMAT_PCM ||
+ (stream->fmt->wFormatTag == WAVE_FORMAT_EXTENSIBLE &&
+ IsEqualGUID(&fmtex->SubFormat, &KSDATAFORMAT_SUBTYPE_PCM))) &&
+ stream->fmt->wBitsPerSample == 8)
+ memset(buffer, 128, frames * stream->fmt->nBlockAlign);
+ else
+ memset(buffer, 0, frames * stream->fmt->nBlockAlign);
+}
+
+/* CA is pulling data from us */
+static OSStatus ca_render_cb(void *user, AudioUnitRenderActionFlags *flags,
+ const AudioTimeStamp *ts, UInt32 bus, UInt32 nframes,
+ AudioBufferList *data)
+{
+ struct coreaudio_stream *stream = user;
+ UINT32 to_copy_bytes, to_copy_frames, chunk_bytes, lcl_offs_bytes;
+
+ OSSpinLockLock(&stream->lock);
+
+ if(stream->playing){
+ lcl_offs_bytes = stream->lcl_offs_frames * stream->fmt->nBlockAlign;
+ to_copy_frames = min(nframes, stream->held_frames);
+ to_copy_bytes = to_copy_frames * stream->fmt->nBlockAlign;
+
+ chunk_bytes = (stream->bufsize_frames - stream->lcl_offs_frames) * stream->fmt->nBlockAlign;
+
+ if(to_copy_bytes > chunk_bytes){
+ memcpy(data->mBuffers[0].mData, stream->local_buffer + lcl_offs_bytes, chunk_bytes);
+ memcpy(((BYTE *)data->mBuffers[0].mData) + chunk_bytes, stream->local_buffer, to_copy_bytes - chunk_bytes);
+ }else
+ memcpy(data->mBuffers[0].mData, stream->local_buffer + lcl_offs_bytes, to_copy_bytes);
+
+ stream->lcl_offs_frames += to_copy_frames;
+ stream->lcl_offs_frames %= stream->bufsize_frames;
+ stream->held_frames -= to_copy_frames;
+ }else
+ to_copy_bytes = to_copy_frames = 0;
+
+ if(nframes > to_copy_frames)
+ silence_buffer(stream, ((BYTE *)data->mBuffers[0].mData) + to_copy_bytes, nframes - to_copy_frames);
+
+ OSSpinLockUnlock(&stream->lock);
+
+ return noErr;
+}
+
+static void ca_wrap_buffer(BYTE *dst, UINT32 dst_offs, UINT32 dst_bytes,
+ BYTE *src, UINT32 src_bytes)
+{
+ UINT32 chunk_bytes = dst_bytes - dst_offs;
+
+ if(chunk_bytes < src_bytes){
+ memcpy(dst + dst_offs, src, chunk_bytes);
+ memcpy(dst, src + chunk_bytes, src_bytes - chunk_bytes);
+ }else
+ memcpy(dst + dst_offs, src, src_bytes);
+}
+
+/* we need to trigger CA to pull data from the device and give it to us
+ *
+ * raw data from CA is stored in cap_buffer, possibly via wrap_buffer
+ *
+ * raw data is resampled from cap_buffer into resamp_buffer in period-size
+ * chunks and copied to local_buffer
+ */
+static OSStatus ca_capture_cb(void *user, AudioUnitRenderActionFlags *flags,
+ const AudioTimeStamp *ts, UInt32 bus, UInt32 nframes,
+ AudioBufferList *data)
+{
+ struct coreaudio_stream *stream = user;
+ AudioBufferList list;
+ OSStatus sc;
+ UINT32 cap_wri_offs_frames;
+
+ OSSpinLockLock(&stream->lock);
+
+ cap_wri_offs_frames = (stream->cap_offs_frames + stream->cap_held_frames) % stream->cap_bufsize_frames;
+
+ list.mNumberBuffers = 1;
+ list.mBuffers[0].mNumberChannels = stream->fmt->nChannels;
+ list.mBuffers[0].mDataByteSize = nframes * stream->fmt->nBlockAlign;
+
+ if(!stream->playing || cap_wri_offs_frames + nframes > stream->cap_bufsize_frames){
+ if(stream->wrap_bufsize_frames < nframes){
+ free(stream->wrap_buffer);
+ stream->wrap_buffer = malloc(list.mBuffers[0].mDataByteSize);
+ stream->wrap_bufsize_frames = nframes;
+ }
+
+ list.mBuffers[0].mData = stream->wrap_buffer;
+ }else
+ list.mBuffers[0].mData = stream->cap_buffer + cap_wri_offs_frames * stream->fmt->nBlockAlign;
+
+ sc = AudioUnitRender(stream->unit, flags, ts, bus, nframes, &list);
+ if(sc != noErr){
+ OSSpinLockUnlock(&stream->lock);
+ return sc;
+ }
+
+ if(stream->playing){
+ if(list.mBuffers[0].mData == stream->wrap_buffer){
+ ca_wrap_buffer(stream->cap_buffer,
+ cap_wri_offs_frames * stream->fmt->nBlockAlign,
+ stream->cap_bufsize_frames * stream->fmt->nBlockAlign,
+ stream->wrap_buffer, list.mBuffers[0].mDataByteSize);
+ }
+
+ stream->cap_held_frames += list.mBuffers[0].mDataByteSize / stream->fmt->nBlockAlign;
+ if(stream->cap_held_frames > stream->cap_bufsize_frames){
+ stream->cap_offs_frames += stream->cap_held_frames % stream->cap_bufsize_frames;
+ stream->cap_offs_frames %= stream->cap_bufsize_frames;
+ stream->cap_held_frames = stream->cap_bufsize_frames;
+ }
+ }
+
+ OSSpinLockUnlock(&stream->lock);
+ return noErr;
+}
+
+static AudioComponentInstance get_audiounit(EDataFlow dataflow, AudioDeviceID adevid)
+{
+ AudioComponentInstance unit;
+ AudioComponent comp;
+ AudioComponentDescription desc;
+ OSStatus sc;
+
+ memset(&desc, 0, sizeof(desc));
+ desc.componentType = kAudioUnitType_Output;
+ desc.componentSubType = kAudioUnitSubType_HALOutput;
+ desc.componentManufacturer = kAudioUnitManufacturer_Apple;
+
+ if(!(comp = AudioComponentFindNext(NULL, &desc))){
+ WARN("AudioComponentFindNext failed\n");
+ return NULL;
+ }
+
+ sc = AudioComponentInstanceNew(comp, &unit);
+ if(sc != noErr){
+ WARN("AudioComponentInstanceNew failed: %x\n", (int)sc);
+ return NULL;
+ }
+
+ if(dataflow == eCapture){
+ UInt32 enableio;
+
+ enableio = 1;
+ sc = AudioUnitSetProperty(unit, kAudioOutputUnitProperty_EnableIO,
+ kAudioUnitScope_Input, 1, &enableio, sizeof(enableio));
+ if(sc != noErr){
+ WARN("Couldn't enable I/O on input element: %x\n", (int)sc);
+ AudioComponentInstanceDispose(unit);
+ return NULL;
+ }
+
+ enableio = 0;
+ sc = AudioUnitSetProperty(unit, kAudioOutputUnitProperty_EnableIO,
+ kAudioUnitScope_Output, 0, &enableio, sizeof(enableio));
+ if(sc != noErr){
+ WARN("Couldn't disable I/O on output element: %x\n", (int)sc);
+ AudioComponentInstanceDispose(unit);
+ return NULL;
+ }
+ }
+
+ sc = AudioUnitSetProperty(unit, kAudioOutputUnitProperty_CurrentDevice,
+ kAudioUnitScope_Global, 0, &adevid, sizeof(adevid));
+ if(sc != noErr){
+ WARN("Couldn't set audio unit device\n");
+ AudioComponentInstanceDispose(unit);
+ return NULL;
+ }
+
+ return unit;
+}
+
+static void dump_adesc(const char *aux, AudioStreamBasicDescription *desc)
+{
+ TRACE("%s: mSampleRate: %f\n", aux, desc->mSampleRate);
+ TRACE("%s: mBytesPerPacket: %u\n", aux, (unsigned int)desc->mBytesPerPacket);
+ TRACE("%s: mFramesPerPacket: %u\n", aux, (unsigned int)desc->mFramesPerPacket);
+ TRACE("%s: mBytesPerFrame: %u\n", aux, (unsigned int)desc->mBytesPerFrame);
+ TRACE("%s: mChannelsPerFrame: %u\n", aux, (unsigned int)desc->mChannelsPerFrame);
+ TRACE("%s: mBitsPerChannel: %u\n", aux, (unsigned int)desc->mBitsPerChannel);
+}
+
+static HRESULT ca_get_audiodesc(AudioStreamBasicDescription *desc,
+ const WAVEFORMATEX *fmt)
+{
+ const WAVEFORMATEXTENSIBLE *fmtex = (const WAVEFORMATEXTENSIBLE *)fmt;
+
+ desc->mFormatFlags = 0;
+
+ if(fmt->wFormatTag == WAVE_FORMAT_PCM ||
+ (fmt->wFormatTag == WAVE_FORMAT_EXTENSIBLE &&
+ IsEqualGUID(&fmtex->SubFormat, &KSDATAFORMAT_SUBTYPE_PCM))){
+ desc->mFormatID = kAudioFormatLinearPCM;
+ if(fmt->wBitsPerSample > 8)
+ desc->mFormatFlags = kAudioFormatFlagIsSignedInteger;
+ }else if(fmt->wFormatTag == WAVE_FORMAT_IEEE_FLOAT ||
+ (fmt->wFormatTag == WAVE_FORMAT_EXTENSIBLE &&
+ IsEqualGUID(&fmtex->SubFormat, &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT))){
+ desc->mFormatID = kAudioFormatLinearPCM;
+ desc->mFormatFlags = kAudioFormatFlagIsFloat;
+ }else if(fmt->wFormatTag == WAVE_FORMAT_MULAW ||
+ (fmt->wFormatTag == WAVE_FORMAT_EXTENSIBLE &&
+ IsEqualGUID(&fmtex->SubFormat, &KSDATAFORMAT_SUBTYPE_MULAW))){
+ desc->mFormatID = kAudioFormatULaw;
+ }else if(fmt->wFormatTag == WAVE_FORMAT_ALAW ||
+ (fmt->wFormatTag == WAVE_FORMAT_EXTENSIBLE &&
+ IsEqualGUID(&fmtex->SubFormat, &KSDATAFORMAT_SUBTYPE_ALAW))){
+ desc->mFormatID = kAudioFormatALaw;
+ }else
+ return AUDCLNT_E_UNSUPPORTED_FORMAT;
+
+ desc->mSampleRate = fmt->nSamplesPerSec;
+ desc->mBytesPerPacket = fmt->nBlockAlign;
+ desc->mFramesPerPacket = 1;
+ desc->mBytesPerFrame = fmt->nBlockAlign;
+ desc->mChannelsPerFrame = fmt->nChannels;
+ desc->mBitsPerChannel = fmt->wBitsPerSample;
+ desc->mReserved = 0;
+
+ return S_OK;
+}
+
+static HRESULT ca_setup_audiounit(EDataFlow dataflow, AudioComponentInstance unit,
+ const WAVEFORMATEX *fmt, AudioStreamBasicDescription *dev_desc,
+ AudioConverterRef *converter)
+{
+ OSStatus sc;
+ HRESULT hr;
+
+ if(dataflow == eCapture){
+ AudioStreamBasicDescription desc;
+ UInt32 size;
+ Float64 rate;
+ fenv_t fenv;
+ BOOL fenv_stored = TRUE;
+
+ hr = ca_get_audiodesc(&desc, fmt);
+ if(FAILED(hr))
+ return hr;
+ dump_adesc("requested", &desc);
+
+ /* input-only units can't perform sample rate conversion, so we have to
+ * set up our own AudioConverter to support arbitrary sample rates. */
+ size = sizeof(*dev_desc);
+ sc = AudioUnitGetProperty(unit, kAudioUnitProperty_StreamFormat,
+ kAudioUnitScope_Input, 1, dev_desc, &size);
+ if(sc != noErr){
+ WARN("Couldn't get unit format: %x\n", (int)sc);
+ return osstatus_to_hresult(sc);
+ }
+ dump_adesc("hardware", dev_desc);
+
+ rate = dev_desc->mSampleRate;
+ *dev_desc = desc;
+ dev_desc->mSampleRate = rate;
+
+ dump_adesc("final", dev_desc);
+ sc = AudioUnitSetProperty(unit, kAudioUnitProperty_StreamFormat,
+ kAudioUnitScope_Output, 1, dev_desc, sizeof(*dev_desc));
+ if(sc != noErr){
+ WARN("Couldn't set unit format: %x\n", (int)sc);
+ return osstatus_to_hresult(sc);
+ }
+
+ /* AudioConverterNew requires divide-by-zero SSE exceptions to be masked */
+ if(feholdexcept(&fenv)){
+ WARN("Failed to store fenv state\n");
+ fenv_stored = FALSE;
+ }
+
+ sc = AudioConverterNew(dev_desc, &desc, converter);
+
+ if(fenv_stored && fesetenv(&fenv))
+ WARN("Failed to restore fenv state\n");
+
+ if(sc != noErr){
+ WARN("Couldn't create audio converter: %x\n", (int)sc);
+ return osstatus_to_hresult(sc);
+ }
+ }else{
+ hr = ca_get_audiodesc(dev_desc, fmt);
+ if(FAILED(hr))
+ return hr;
+
+ dump_adesc("final", dev_desc);
+ sc = AudioUnitSetProperty(unit, kAudioUnitProperty_StreamFormat,
+ kAudioUnitScope_Input, 0, dev_desc, sizeof(*dev_desc));
+ if(sc != noErr){
+ WARN("Couldn't set format: %x\n", (int)sc);
+ return osstatus_to_hresult(sc);
+ }
+ }
+
+ return S_OK;
+}
+
+static NTSTATUS create_stream(void *args)
+{
+ struct create_stream_params *params = args;
+ struct coreaudio_stream *stream = calloc(1, sizeof(*stream));
+ AURenderCallbackStruct input;
+ OSStatus sc;
+
+ if(!stream){
+ params->result = E_OUTOFMEMORY;
+ return STATUS_SUCCESS;
+ }
+
+ stream->fmt = clone_format(params->fmt);
+ if(!stream->fmt){
+ params->result = E_OUTOFMEMORY;
+ goto end;
+ }
+
+ stream->period_ms = params->period / 10000;
+ stream->period_frames = muldiv(params->period, stream->fmt->nSamplesPerSec, 10000000);
+ stream->dev_id = params->dev_id;
+ stream->flow = params->flow;
+ stream->share = params->share;
+
+ stream->bufsize_frames = muldiv(params->duration, stream->fmt->nSamplesPerSec, 10000000);
+ if(params->share == AUDCLNT_SHAREMODE_EXCLUSIVE)
+ stream->bufsize_frames -= stream->bufsize_frames % stream->period_frames;
+
+ if(!(stream->unit = get_audiounit(stream->flow, stream->dev_id))){
+ params->result = AUDCLNT_E_DEVICE_INVALIDATED;
+ goto end;
+ }
+
+ params->result = ca_setup_audiounit(stream->flow, stream->unit, stream->fmt, &stream->dev_desc, &stream->converter);
+ if(FAILED(params->result)) goto end;
+
+ input.inputProcRefCon = stream;
+ if(stream->flow == eCapture){
+ input.inputProc = ca_capture_cb;
+ sc = AudioUnitSetProperty(stream->unit, kAudioOutputUnitProperty_SetInputCallback,
+ kAudioUnitScope_Output, 1, &input, sizeof(input));
+ }else{
+ input.inputProc = ca_render_cb;
+ sc = AudioUnitSetProperty(stream->unit, kAudioUnitProperty_SetRenderCallback,
+ kAudioUnitScope_Input, 0, &input, sizeof(input));
+ }
+ if(sc != noErr){
+ WARN("Couldn't set callback: %x\n", (int)sc);
+ params->result = osstatus_to_hresult(sc);
+ goto end;
+ }
+
+ sc = AudioUnitInitialize(stream->unit);
+ if(sc != noErr){
+ WARN("Couldn't initialize: %x\n", (int)sc);
+ params->result = osstatus_to_hresult(sc);
+ goto end;
+ }
+
+ /* we play audio continuously because AudioOutputUnitStart sometimes takes
+ * a while to return */
+ sc = AudioOutputUnitStart(stream->unit);
+ if(sc != noErr){
+ WARN("Unit failed to start: %x\n", (int)sc);
+ params->result = osstatus_to_hresult(sc);
+ goto end;
+ }
+
+ stream->local_buffer_size = stream->bufsize_frames * stream->fmt->nBlockAlign;
+ if(NtAllocateVirtualMemory(GetCurrentProcess(), (void **)&stream->local_buffer, 0, &stream->local_buffer_size,
+ MEM_COMMIT, PAGE_READWRITE)){
+ params->result = E_OUTOFMEMORY;
+ goto end;
+ }
+ silence_buffer(stream, stream->local_buffer, stream->bufsize_frames);
+
+ if(stream->flow == eCapture){
+ stream->cap_bufsize_frames = muldiv(params->duration, stream->dev_desc.mSampleRate, 10000000);
+ stream->cap_buffer = malloc(stream->cap_bufsize_frames * stream->fmt->nBlockAlign);
+ }
+ params->result = S_OK;
+
+end:
+ if(FAILED(params->result)){
+ if(stream->converter) AudioConverterDispose(stream->converter);
+ if(stream->unit) AudioComponentInstanceDispose(stream->unit);
+ free(stream->fmt);
+ free(stream);
+ } else
+ params->stream = stream;
+
+ return STATUS_SUCCESS;
+}
+
+static NTSTATUS release_stream( void *args )
+{
+ struct release_stream_params *params = args;
+ struct coreaudio_stream *stream = params->stream;
+
+ if(stream->unit){
+ AudioOutputUnitStop(stream->unit);
+ AudioComponentInstanceDispose(stream->unit);
+ }
+
+ if(stream->converter) AudioConverterDispose(stream->converter);
+ free(stream->wrap_buffer);
+ free(stream->cap_buffer);
+ if(stream->local_buffer)
+ NtFreeVirtualMemory(GetCurrentProcess(), (void **)&stream->local_buffer,
+ &stream->local_buffer_size, MEM_RELEASE);
+ free(stream->fmt);
+ params->result = S_OK;
+ return STATUS_SUCCESS;
+}
+
unixlib_entry_t __wine_unix_call_funcs[] =
{
get_endpoint_ids,
+ create_stream,
+ release_stream,
};
diff --git a/dlls/winecoreaudio.drv/mmdevdrv.c b/dlls/winecoreaudio.drv/mmdevdrv.c
index 0abfebfb1a5..572126562c6 100644
--- a/dlls/winecoreaudio.drv/mmdevdrv.c
+++ b/dlls/winecoreaudio.drv/mmdevdrv.c
@@ -138,6 +138,10 @@ struct ACImpl {
struct coreaudio_stream *stream;
struct list entry;
+
+ /* Temporary */
+ BYTE *feed_wrap_buffer;
+ UINT32 feed_wrap_bufsize_frames;
};
static const IAudioClient3Vtbl AudioClient3_Vtbl;
@@ -613,7 +617,9 @@ static ULONG WINAPI AudioClient_AddRef(IAudioClient3 *iface)
static ULONG WINAPI AudioClient_Release(IAudioClient3 *iface)
{
ACImpl *This = impl_from_IAudioClient3(iface);
+ struct release_stream_params params;
ULONG ref;
+
ref = InterlockedDecrement(&This->ref);
TRACE("(%p) Refcount now %u\n", This, ref);
if(!ref){
@@ -627,22 +633,13 @@ static ULONG WINAPI AudioClient_Release(IAudioClient3 *iface)
WaitForSingleObject(event, INFINITE);
CloseHandle(event);
}
- if (This->stream){
- AudioOutputUnitStop(This->stream->unit);
- AudioComponentInstanceDispose(This->stream->unit);
- if(This->stream->converter)
- AudioConverterDispose(This->stream->converter);
- HeapFree(GetProcessHeap(), 0, This->stream->cap_buffer);
- if(This->stream->local_buffer)
- NtFreeVirtualMemory(GetCurrentProcess(), (void **)&This->stream->local_buffer,
- &This->stream->local_buffer_size, MEM_RELEASE);
+ if(This->stream){
if(This->stream->tmp_buffer)
NtFreeVirtualMemory(GetCurrentProcess(), (void **)&This->stream->tmp_buffer,
&This->stream->tmp_buffer_size, MEM_RELEASE);
- free(This->stream->wrap_buffer);
HeapFree(GetProcessHeap(), 0, This->stream->resamp_buffer);
- CoTaskMemFree(This->stream->fmt);
- HeapFree(GetProcessHeap(), 0, This->stream);
+ params.stream = This->stream;
+ UNIX_CALL(release_stream, ¶ms);
}
if(This->session){
EnterCriticalSection(&g_sessions_lock);
@@ -650,6 +647,7 @@ static ULONG WINAPI AudioClient_Release(IAudioClient3 *iface)
LeaveCriticalSection(&g_sessions_lock);
}
HeapFree(GetProcessHeap(), 0, This->vols);
+ free(This->feed_wrap_buffer);
IMMDevice_Release(This->parent);
IUnknown_Release(This->pUnkFTMarshal);
HeapFree(GetProcessHeap(), 0, This);
@@ -717,27 +715,6 @@ static DWORD get_channel_mask(unsigned int channels)
return 0;
}
-static WAVEFORMATEX *clone_format(const WAVEFORMATEX *fmt)
-{
- WAVEFORMATEX *ret;
- size_t size;
-
- if(fmt->wFormatTag == WAVE_FORMAT_EXTENSIBLE)
- size = sizeof(WAVEFORMATEXTENSIBLE);
- else
- size = sizeof(WAVEFORMATEX);
-
- ret = CoTaskMemAlloc(size);
- if(!ret)
- return NULL;
-
- memcpy(ret, fmt, size);
-
- ret->cbSize = size - sizeof(WAVEFORMATEX);
-
- return ret;
-}
-
static HRESULT ca_get_audiodesc(AudioStreamBasicDescription *desc,
const WAVEFORMATEX *fmt)
{
@@ -881,43 +858,6 @@ static void silence_buffer(struct coreaudio_stream *stream, BYTE *buffer, UINT32
memset(buffer, 0, frames * stream->fmt->nBlockAlign);
}
-/* CA is pulling data from us */
-static OSStatus ca_render_cb(void *user, AudioUnitRenderActionFlags *flags,
- const AudioTimeStamp *ts, UInt32 bus, UInt32 nframes,
- AudioBufferList *data)
-{
- ACImpl *This = user;
- UINT32 to_copy_bytes, to_copy_frames, chunk_bytes, lcl_offs_bytes;
-
- OSSpinLockLock(&This->stream->lock);
-
- if(This->stream->playing){
- lcl_offs_bytes = This->stream->lcl_offs_frames * This->stream->fmt->nBlockAlign;
- to_copy_frames = min(nframes, This->stream->held_frames);
- to_copy_bytes = to_copy_frames * This->stream->fmt->nBlockAlign;
-
- chunk_bytes = (This->stream->bufsize_frames - This->stream->lcl_offs_frames) * This->stream->fmt->nBlockAlign;
-
- if(to_copy_bytes > chunk_bytes){
- memcpy(data->mBuffers[0].mData, This->stream->local_buffer + lcl_offs_bytes, chunk_bytes);
- memcpy(((BYTE *)data->mBuffers[0].mData) + chunk_bytes, This->stream->local_buffer, to_copy_bytes - chunk_bytes);
- }else
- memcpy(data->mBuffers[0].mData, This->stream->local_buffer + lcl_offs_bytes, to_copy_bytes);
-
- This->stream->lcl_offs_frames += to_copy_frames;
- This->stream->lcl_offs_frames %= This->stream->bufsize_frames;
- This->stream->held_frames -= to_copy_frames;
- }else
- to_copy_bytes = to_copy_frames = 0;
-
- if(nframes > to_copy_frames)
- silence_buffer(This->stream, ((BYTE *)data->mBuffers[0].mData) + to_copy_bytes, nframes - to_copy_frames);
-
- OSSpinLockUnlock(&This->stream->lock);
-
- return noErr;
-}
-
static UINT buf_ptr_diff(UINT left, UINT right, UINT bufsize)
{
if(left <= right)
@@ -945,18 +885,18 @@ static OSStatus feed_cb(AudioConverterRef converter, UInt32 *nframes, AudioBuffe
if(This->stream->cap_offs_frames + *nframes > This->stream->cap_bufsize_frames){
UINT32 chunk_frames = This->stream->cap_bufsize_frames - This->stream->cap_offs_frames;
- if(This->stream->wrap_bufsize_frames < *nframes){
- free(This->stream->wrap_buffer);
- This->stream->wrap_buffer = malloc(data->mBuffers[0].mDataByteSize);
- This->stream->wrap_bufsize_frames = *nframes;
+ if(This->feed_wrap_bufsize_frames < *nframes){
+ free(This->feed_wrap_buffer);
+ This->feed_wrap_buffer = malloc(data->mBuffers[0].mDataByteSize);
+ This->feed_wrap_bufsize_frames = *nframes;
}
- memcpy(This->stream->wrap_buffer, This->stream->cap_buffer + This->stream->cap_offs_frames * This->stream->fmt->nBlockAlign,
+ memcpy(This->feed_wrap_buffer, This->stream->cap_buffer + This->stream->cap_offs_frames * This->stream->fmt->nBlockAlign,
chunk_frames * This->stream->fmt->nBlockAlign);
- memcpy(This->stream->wrap_buffer + chunk_frames * This->stream->fmt->nBlockAlign, This->stream->cap_buffer,
+ memcpy(This->feed_wrap_buffer + chunk_frames * This->stream->fmt->nBlockAlign, This->stream->cap_buffer,
(*nframes - chunk_frames) * This->stream->fmt->nBlockAlign);
- data->mBuffers[0].mData = This->stream->wrap_buffer;
+ data->mBuffers[0].mData = This->feed_wrap_buffer;
}else
data->mBuffers[0].mData = This->stream->cap_buffer + This->stream->cap_offs_frames * This->stream->fmt->nBlockAlign;
@@ -1017,67 +957,6 @@ static void capture_resample(ACImpl *This)
}
}
-/* we need to trigger CA to pull data from the device and give it to us
- *
- * raw data from CA is stored in cap_buffer, possibly via wrap_buffer
- *
- * raw data is resampled from cap_buffer into resamp_buffer in period-size
- * chunks and copied to local_buffer
- */
-static OSStatus ca_capture_cb(void *user, AudioUnitRenderActionFlags *flags,
- const AudioTimeStamp *ts, UInt32 bus, UInt32 nframes,
- AudioBufferList *data)
-{
- ACImpl *This = user;
- AudioBufferList list;
- OSStatus sc;
- UINT32 cap_wri_offs_frames;
-
- OSSpinLockLock(&This->stream->lock);
-
- cap_wri_offs_frames = (This->stream->cap_offs_frames + This->stream->cap_held_frames) % This->stream->cap_bufsize_frames;
-
- list.mNumberBuffers = 1;
- list.mBuffers[0].mNumberChannels = This->stream->fmt->nChannels;
- list.mBuffers[0].mDataByteSize = nframes * This->stream->fmt->nBlockAlign;
-
- if(!This->stream->playing || cap_wri_offs_frames + nframes > This->stream->cap_bufsize_frames){
- if(This->stream->wrap_bufsize_frames < nframes){
- free(This->stream->wrap_buffer);
- This->stream->wrap_buffer = malloc(list.mBuffers[0].mDataByteSize);
- This->stream->wrap_bufsize_frames = nframes;
- }
-
- list.mBuffers[0].mData = This->stream->wrap_buffer;
- }else
- list.mBuffers[0].mData = This->stream->cap_buffer + cap_wri_offs_frames * This->stream->fmt->nBlockAlign;
-
- sc = AudioUnitRender(This->stream->unit, flags, ts, bus, nframes, &list);
- if(sc != noErr){
- OSSpinLockUnlock(&This->stream->lock);
- return sc;
- }
-
- if(This->stream->playing){
- if(list.mBuffers[0].mData == This->stream->wrap_buffer){
- ca_wrap_buffer(This->stream->cap_buffer,
- cap_wri_offs_frames * This->stream->fmt->nBlockAlign,
- This->stream->cap_bufsize_frames * This->stream->fmt->nBlockAlign,
- This->stream->wrap_buffer, list.mBuffers[0].mDataByteSize);
- }
-
- This->stream->cap_held_frames += list.mBuffers[0].mDataByteSize / This->stream->fmt->nBlockAlign;
- if(This->stream->cap_held_frames > This->stream->cap_bufsize_frames){
- This->stream->cap_offs_frames += This->stream->cap_held_frames % This->stream->cap_bufsize_frames;
- This->stream->cap_offs_frames %= This->stream->cap_bufsize_frames;
- This->stream->cap_held_frames = This->stream->cap_bufsize_frames;
- }
- }
-
- OSSpinLockUnlock(&This->stream->lock);
- return noErr;
-}
-
static void dump_adesc(const char *aux, AudioStreamBasicDescription *desc)
{
TRACE("%s: mSampleRate: %f\n", aux, desc->mSampleRate);
@@ -1168,9 +1047,8 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient3 *iface,
const GUID *sessionguid)
{
ACImpl *This = impl_from_IAudioClient3(iface);
- struct coreaudio_stream *stream;
- HRESULT hr;
- OSStatus sc;
+ struct release_stream_params release_params;
+ struct create_stream_params params;
UINT32 i;
TRACE("(%p)->(%x, %x, %s, %s, %p, %s)\n", This, mode, flags,
@@ -1233,146 +1111,50 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient3 *iface,
return AUDCLNT_E_ALREADY_INITIALIZED;
}
- stream = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*stream));
- if(!stream){
- LeaveCriticalSection(&g_sessions_lock);
- return E_OUTOFMEMORY;
- }
-
- stream->fmt = clone_format(fmt);
- if(!stream->fmt){
- HeapFree(GetProcessHeap(), 0, stream);
- LeaveCriticalSection(&g_sessions_lock);
- return E_OUTOFMEMORY;
- }
-
- stream->period_ms = period / 10000;
- stream->period_frames = MulDiv(period, stream->fmt->nSamplesPerSec, 10000000);
-
- stream->bufsize_frames = MulDiv(duration, fmt->nSamplesPerSec, 10000000);
- if(mode == AUDCLNT_SHAREMODE_EXCLUSIVE)
- stream->bufsize_frames -= stream->bufsize_frames % stream->period_frames;
-
- if(!(stream->unit = get_audiounit(This->dataflow, This->adevid))){
- CoTaskMemFree(stream->fmt);
- HeapFree(GetProcessHeap(), 0, stream);
- LeaveCriticalSection(&g_sessions_lock);
- return AUDCLNT_E_DEVICE_INVALIDATED;
- }
-
- hr = ca_setup_audiounit(This->dataflow, stream->unit, stream->fmt, &stream->dev_desc, &stream->converter);
- if(FAILED(hr)){
- CoTaskMemFree(stream->fmt);
- HeapFree(GetProcessHeap(), 0, stream);
- LeaveCriticalSection(&g_sessions_lock);
- return hr;
- }
-
- if(This->dataflow == eCapture){
- AURenderCallbackStruct input;
-
- memset(&input, 0, sizeof(input));
- input.inputProc = &ca_capture_cb;
- input.inputProcRefCon = This;
-
- sc = AudioUnitSetProperty(stream->unit, kAudioOutputUnitProperty_SetInputCallback,
- kAudioUnitScope_Output, 1, &input, sizeof(input));
- if(sc != noErr){
- WARN("Couldn't set callback: %x\n", (int)sc);
- AudioConverterDispose(stream->converter);
- CoTaskMemFree(stream->fmt);
- HeapFree(GetProcessHeap(), 0, stream);
- LeaveCriticalSection(&g_sessions_lock);
- return osstatus_to_hresult(sc);
- }
- }else{
- AURenderCallbackStruct input;
-
- memset(&input, 0, sizeof(input));
- input.inputProc = &ca_render_cb;
- input.inputProcRefCon = This;
-
- sc = AudioUnitSetProperty(stream->unit, kAudioUnitProperty_SetRenderCallback,
- kAudioUnitScope_Input, 0, &input, sizeof(input));
- if(sc != noErr){
- WARN("Couldn't set callback: %x\n", (int)sc);
- CoTaskMemFree(stream->fmt);
- HeapFree(GetProcessHeap(), 0, stream);
- LeaveCriticalSection(&g_sessions_lock);
- return osstatus_to_hresult(sc);
- }
- }
+ params.dev_id = This->adevid;
+ params.flow = This->dataflow;
+ params.share = mode;
+ params.duration = duration;
+ params.period = period;
+ params.fmt = fmt;
- sc = AudioUnitInitialize(stream->unit);
- if(sc != noErr){
- WARN("Couldn't initialize: %x\n", (int)sc);
- if(stream->converter)
- AudioConverterDispose(stream->converter);
- CoTaskMemFree(stream->fmt);
- HeapFree(GetProcessHeap(), 0, stream);
- LeaveCriticalSection(&g_sessions_lock);
- return osstatus_to_hresult(sc);
- }
-
- /* we play audio continuously because AudioOutputUnitStart sometimes takes
- * a while to return */
- sc = AudioOutputUnitStart(stream->unit);
- if(sc != noErr){
- WARN("Unit failed to start: %x\n", (int)sc);
- if(stream->converter)
- AudioConverterDispose(stream->converter);
- CoTaskMemFree(stream->fmt);
- HeapFree(GetProcessHeap(), 0, stream);
- LeaveCriticalSection(&g_sessions_lock);
- return osstatus_to_hresult(sc);
- }
-
- stream->local_buffer_size = stream->bufsize_frames * fmt->nBlockAlign;
- NtAllocateVirtualMemory(GetCurrentProcess(), (void **)&stream->local_buffer, 0,
- &stream->local_buffer_size, MEM_COMMIT, PAGE_READWRITE);
- silence_buffer(stream, stream->local_buffer, stream->bufsize_frames);
-
- if(This->dataflow == eCapture){
- stream->cap_bufsize_frames = MulDiv(duration, stream->dev_desc.mSampleRate, 10000000);
- stream->cap_buffer = HeapAlloc(GetProcessHeap(), 0, stream->cap_bufsize_frames * stream->fmt->nBlockAlign);
- }
+ UNIX_CALL(create_stream, ¶ms);
+ if(FAILED(params.result)) goto end;
- stream->share = mode;
This->flags = flags;
This->channel_count = fmt->nChannels;
This->period_ms = period / 10000;
This->vols = HeapAlloc(GetProcessHeap(), 0, This->channel_count * sizeof(float));
if(!This->vols){
- CoTaskMemFree(stream->fmt);
- HeapFree(GetProcessHeap(), 0, stream);
- LeaveCriticalSection(&g_sessions_lock);
- return E_OUTOFMEMORY;
+ params.result = E_OUTOFMEMORY;
+ goto end;
}
for(i = 0; i < This->channel_count; ++i)
This->vols[i] = 1.f;
- hr = get_audio_session(sessionguid, This->parent, fmt->nChannels,
- &This->session);
- if(FAILED(hr)){
- CoTaskMemFree(stream->fmt);
- HeapFree(GetProcessHeap(), 0, stream);
- HeapFree(GetProcessHeap(), 0, This->vols);
- This->vols = NULL;
- LeaveCriticalSection(&g_sessions_lock);
- return E_INVALIDARG;
- }
+ params.result = get_audio_session(sessionguid, This->parent, fmt->nChannels, &This->session);
+ if(FAILED(params.result)) goto end;
list_add_tail(&This->session->clients, &This->entry);
- ca_setvol(This, stream, -1);
+ ca_setvol(This, params.stream, -1);
- This->stream = stream;
+end:
+ if(FAILED(params.result)){
+ if(params.stream){
+ release_params.stream = This->stream;
+ UNIX_CALL(release_stream, &release_params);
+ }
+ HeapFree(GetProcessHeap(), 0, This->vols);
+ This->vols = NULL;
+ }else
+ This->stream = params.stream;
LeaveCriticalSection(&g_sessions_lock);
- return S_OK;
+ return params.result;
}
static HRESULT WINAPI AudioClient_GetBufferSize(IAudioClient3 *iface,
diff --git a/dlls/winecoreaudio.drv/unixlib.h b/dlls/winecoreaudio.drv/unixlib.h
index 1b773b7f820..7ebdc0b7786 100644
--- a/dlls/winecoreaudio.drv/unixlib.h
+++ b/dlls/winecoreaudio.drv/unixlib.h
@@ -57,9 +57,29 @@ struct get_endpoint_ids_params
unsigned int default_idx;
};
+struct create_stream_params
+{
+ DWORD dev_id;
+ EDataFlow flow;
+ AUDCLNT_SHAREMODE share;
+ REFERENCE_TIME duration;
+ REFERENCE_TIME period;
+ const WAVEFORMATEX *fmt;
+ HRESULT result;
+ struct coreaudio_stream *stream;
+};
+
+struct release_stream_params
+{
+ struct coreaudio_stream *stream;
+ HRESULT result;
+};
+
enum unix_funcs
{
unix_get_endpoint_ids,
+ unix_create_stream,
+ unix_release_stream,
};
extern unixlib_handle_t coreaudio_handle;
--
2.23.0
2
1
[PATCH 5/7] winecoreaudio: Use the presence of stream to indicate the init state.
by Huw Davies 22 Nov '21
by Huw Davies 22 Nov '21
22 Nov '21
Signed-off-by: Huw Davies <huw(a)codeweavers.com>
---
dlls/winecoreaudio.drv/mmdevdrv.c | 211 +++++++++++++-----------------
1 file changed, 93 insertions(+), 118 deletions(-)
diff --git a/dlls/winecoreaudio.drv/mmdevdrv.c b/dlls/winecoreaudio.drv/mmdevdrv.c
index 1e678b08c5b..0abfebfb1a5 100644
--- a/dlls/winecoreaudio.drv/mmdevdrv.c
+++ b/dlls/winecoreaudio.drv/mmdevdrv.c
@@ -129,7 +129,6 @@ struct ACImpl {
HANDLE event;
float *vols;
- BOOL initted;
AudioDeviceID adevid;
AudioObjectPropertyScope scope;
HANDLE timer;
@@ -541,11 +540,6 @@ HRESULT WINAPI AUDDRV_GetAudioEndpoint(GUID *guid, IMMDevice *dev, IAudioClient
This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ACImpl));
if(!This)
return E_OUTOFMEMORY;
- This->stream = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*This->stream));
- if(!This->stream){
- HeapFree(GetProcessHeap(), 0, This);
- return E_OUTOFMEMORY;
- }
This->IAudioClient3_iface.lpVtbl = &AudioClient3_Vtbl;
This->IAudioRenderClient_iface.lpVtbl = &AudioRenderClient_Vtbl;
@@ -561,16 +555,12 @@ HRESULT WINAPI AUDDRV_GetAudioEndpoint(GUID *guid, IMMDevice *dev, IAudioClient
else if(dataflow == eCapture)
This->scope = kAudioDevicePropertyScopeInput;
else{
- HeapFree(GetProcessHeap(), 0, This->stream);
HeapFree(GetProcessHeap(), 0, This);
return E_INVALIDARG;
}
- This->stream->lock = 0;
-
hr = CoCreateFreeThreadedMarshaler((IUnknown *)&This->IAudioClient3_iface, &This->pUnkFTMarshal);
if (FAILED(hr)) {
- HeapFree(GetProcessHeap(), 0, This->stream);
HeapFree(GetProcessHeap(), 0, This);
return hr;
}
@@ -637,29 +627,31 @@ static ULONG WINAPI AudioClient_Release(IAudioClient3 *iface)
WaitForSingleObject(event, INFINITE);
CloseHandle(event);
}
- AudioOutputUnitStop(This->stream->unit);
- AudioComponentInstanceDispose(This->stream->unit);
- if(This->stream->converter)
- AudioConverterDispose(This->stream->converter);
+ if (This->stream){
+ AudioOutputUnitStop(This->stream->unit);
+ AudioComponentInstanceDispose(This->stream->unit);
+ if(This->stream->converter)
+ AudioConverterDispose(This->stream->converter);
+ HeapFree(GetProcessHeap(), 0, This->stream->cap_buffer);
+ if(This->stream->local_buffer)
+ NtFreeVirtualMemory(GetCurrentProcess(), (void **)&This->stream->local_buffer,
+ &This->stream->local_buffer_size, MEM_RELEASE);
+ if(This->stream->tmp_buffer)
+ NtFreeVirtualMemory(GetCurrentProcess(), (void **)&This->stream->tmp_buffer,
+ &This->stream->tmp_buffer_size, MEM_RELEASE);
+ free(This->stream->wrap_buffer);
+ HeapFree(GetProcessHeap(), 0, This->stream->resamp_buffer);
+ CoTaskMemFree(This->stream->fmt);
+ HeapFree(GetProcessHeap(), 0, This->stream);
+ }
if(This->session){
EnterCriticalSection(&g_sessions_lock);
list_remove(&This->entry);
LeaveCriticalSection(&g_sessions_lock);
}
HeapFree(GetProcessHeap(), 0, This->vols);
- HeapFree(GetProcessHeap(), 0, This->stream->cap_buffer);
- if(This->stream->local_buffer)
- NtFreeVirtualMemory(GetCurrentProcess(), (void **)&This->stream->local_buffer,
- &This->stream->local_buffer_size, MEM_RELEASE);
- if(This->stream->tmp_buffer)
- NtFreeVirtualMemory(GetCurrentProcess(), (void **)&This->stream->tmp_buffer,
- &This->stream->tmp_buffer_size, MEM_RELEASE);
- free(This->stream->wrap_buffer);
- HeapFree(GetProcessHeap(), 0, This->stream->resamp_buffer);
- CoTaskMemFree(This->stream->fmt);
IMMDevice_Release(This->parent);
IUnknown_Release(This->pUnkFTMarshal);
- HeapFree(GetProcessHeap(), 0, This->stream);
HeapFree(GetProcessHeap(), 0, This);
}
return ref;
@@ -1176,6 +1168,7 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient3 *iface,
const GUID *sessionguid)
{
ACImpl *This = impl_from_IAudioClient3(iface);
+ struct coreaudio_stream *stream;
HRESULT hr;
OSStatus sc;
UINT32 i;
@@ -1235,40 +1228,42 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient3 *iface,
EnterCriticalSection(&g_sessions_lock);
- if(This->initted){
+ if(This->stream){
LeaveCriticalSection(&g_sessions_lock);
return AUDCLNT_E_ALREADY_INITIALIZED;
}
- OSSpinLockLock(&This->stream->lock);
+ stream = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*stream));
+ if(!stream){
+ LeaveCriticalSection(&g_sessions_lock);
+ return E_OUTOFMEMORY;
+ }
- This->stream->fmt = clone_format(fmt);
- if(!This->stream->fmt){
- OSSpinLockUnlock(&This->stream->lock);
+ stream->fmt = clone_format(fmt);
+ if(!stream->fmt){
+ HeapFree(GetProcessHeap(), 0, stream);
LeaveCriticalSection(&g_sessions_lock);
return E_OUTOFMEMORY;
}
- This->stream->period_ms = period / 10000;
- This->stream->period_frames = MulDiv(period, This->stream->fmt->nSamplesPerSec, 10000000);
+ stream->period_ms = period / 10000;
+ stream->period_frames = MulDiv(period, stream->fmt->nSamplesPerSec, 10000000);
- This->stream->bufsize_frames = MulDiv(duration, fmt->nSamplesPerSec, 10000000);
+ stream->bufsize_frames = MulDiv(duration, fmt->nSamplesPerSec, 10000000);
if(mode == AUDCLNT_SHAREMODE_EXCLUSIVE)
- This->stream->bufsize_frames -= This->stream->bufsize_frames % This->stream->period_frames;
+ stream->bufsize_frames -= stream->bufsize_frames % stream->period_frames;
- if(!(This->stream->unit = get_audiounit(This->dataflow, This->adevid))){
- CoTaskMemFree(This->stream->fmt);
- This->stream->fmt = NULL;
- OSSpinLockUnlock(&This->stream->lock);
+ if(!(stream->unit = get_audiounit(This->dataflow, This->adevid))){
+ CoTaskMemFree(stream->fmt);
+ HeapFree(GetProcessHeap(), 0, stream);
LeaveCriticalSection(&g_sessions_lock);
return AUDCLNT_E_DEVICE_INVALIDATED;
}
- hr = ca_setup_audiounit(This->dataflow, This->stream->unit, This->stream->fmt, &This->stream->dev_desc, &This->stream->converter);
+ hr = ca_setup_audiounit(This->dataflow, stream->unit, stream->fmt, &stream->dev_desc, &stream->converter);
if(FAILED(hr)){
- CoTaskMemFree(This->stream->fmt);
- This->stream->fmt = NULL;
- OSSpinLockUnlock(&This->stream->lock);
+ CoTaskMemFree(stream->fmt);
+ HeapFree(GetProcessHeap(), 0, stream);
LeaveCriticalSection(&g_sessions_lock);
return hr;
}
@@ -1280,15 +1275,13 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient3 *iface,
input.inputProc = &ca_capture_cb;
input.inputProcRefCon = This;
- sc = AudioUnitSetProperty(This->stream->unit, kAudioOutputUnitProperty_SetInputCallback,
+ sc = AudioUnitSetProperty(stream->unit, kAudioOutputUnitProperty_SetInputCallback,
kAudioUnitScope_Output, 1, &input, sizeof(input));
if(sc != noErr){
WARN("Couldn't set callback: %x\n", (int)sc);
- AudioConverterDispose(This->stream->converter);
- This->stream->converter = NULL;
- CoTaskMemFree(This->stream->fmt);
- This->stream->fmt = NULL;
- OSSpinLockUnlock(&This->stream->lock);
+ AudioConverterDispose(stream->converter);
+ CoTaskMemFree(stream->fmt);
+ HeapFree(GetProcessHeap(), 0, stream);
LeaveCriticalSection(&g_sessions_lock);
return osstatus_to_hresult(sc);
}
@@ -1299,68 +1292,60 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient3 *iface,
input.inputProc = &ca_render_cb;
input.inputProcRefCon = This;
- sc = AudioUnitSetProperty(This->stream->unit, kAudioUnitProperty_SetRenderCallback,
+ sc = AudioUnitSetProperty(stream->unit, kAudioUnitProperty_SetRenderCallback,
kAudioUnitScope_Input, 0, &input, sizeof(input));
if(sc != noErr){
WARN("Couldn't set callback: %x\n", (int)sc);
- CoTaskMemFree(This->stream->fmt);
- This->stream->fmt = NULL;
- OSSpinLockUnlock(&This->stream->lock);
+ CoTaskMemFree(stream->fmt);
+ HeapFree(GetProcessHeap(), 0, stream);
LeaveCriticalSection(&g_sessions_lock);
return osstatus_to_hresult(sc);
}
}
- sc = AudioUnitInitialize(This->stream->unit);
+ sc = AudioUnitInitialize(stream->unit);
if(sc != noErr){
WARN("Couldn't initialize: %x\n", (int)sc);
- if(This->stream->converter){
- AudioConverterDispose(This->stream->converter);
- This->stream->converter = NULL;
- }
- CoTaskMemFree(This->stream->fmt);
- This->stream->fmt = NULL;
- OSSpinLockUnlock(&This->stream->lock);
+ if(stream->converter)
+ AudioConverterDispose(stream->converter);
+ CoTaskMemFree(stream->fmt);
+ HeapFree(GetProcessHeap(), 0, stream);
LeaveCriticalSection(&g_sessions_lock);
return osstatus_to_hresult(sc);
}
/* we play audio continuously because AudioOutputUnitStart sometimes takes
* a while to return */
- sc = AudioOutputUnitStart(This->stream->unit);
+ sc = AudioOutputUnitStart(stream->unit);
if(sc != noErr){
WARN("Unit failed to start: %x\n", (int)sc);
- if(This->stream->converter){
- AudioConverterDispose(This->stream->converter);
- This->stream->converter = NULL;
- }
- CoTaskMemFree(This->stream->fmt);
- This->stream->fmt = NULL;
- OSSpinLockUnlock(&This->stream->lock);
+ if(stream->converter)
+ AudioConverterDispose(stream->converter);
+ CoTaskMemFree(stream->fmt);
+ HeapFree(GetProcessHeap(), 0, stream);
LeaveCriticalSection(&g_sessions_lock);
return osstatus_to_hresult(sc);
}
- This->stream->local_buffer_size = This->stream->bufsize_frames * fmt->nBlockAlign;
- NtAllocateVirtualMemory(GetCurrentProcess(), (void **)&This->stream->local_buffer, 0,
- &This->stream->local_buffer_size, MEM_COMMIT, PAGE_READWRITE);
- silence_buffer(This->stream, This->stream->local_buffer, This->stream->bufsize_frames);
+ stream->local_buffer_size = stream->bufsize_frames * fmt->nBlockAlign;
+ NtAllocateVirtualMemory(GetCurrentProcess(), (void **)&stream->local_buffer, 0,
+ &stream->local_buffer_size, MEM_COMMIT, PAGE_READWRITE);
+ silence_buffer(stream, stream->local_buffer, stream->bufsize_frames);
if(This->dataflow == eCapture){
- This->stream->cap_bufsize_frames = MulDiv(duration, This->stream->dev_desc.mSampleRate, 10000000);
- This->stream->cap_buffer = HeapAlloc(GetProcessHeap(), 0, This->stream->cap_bufsize_frames * This->stream->fmt->nBlockAlign);
+ stream->cap_bufsize_frames = MulDiv(duration, stream->dev_desc.mSampleRate, 10000000);
+ stream->cap_buffer = HeapAlloc(GetProcessHeap(), 0, stream->cap_bufsize_frames * stream->fmt->nBlockAlign);
}
- This->stream->share = mode;
+ stream->share = mode;
This->flags = flags;
This->channel_count = fmt->nChannels;
This->period_ms = period / 10000;
This->vols = HeapAlloc(GetProcessHeap(), 0, This->channel_count * sizeof(float));
if(!This->vols){
- CoTaskMemFree(This->stream->fmt);
- This->stream->fmt = NULL;
- OSSpinLockUnlock(&This->stream->lock);
+ CoTaskMemFree(stream->fmt);
+ HeapFree(GetProcessHeap(), 0, stream);
LeaveCriticalSection(&g_sessions_lock);
return E_OUTOFMEMORY;
}
@@ -1371,22 +1356,20 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient3 *iface,
hr = get_audio_session(sessionguid, This->parent, fmt->nChannels,
&This->session);
if(FAILED(hr)){
- CoTaskMemFree(This->stream->fmt);
- This->stream->fmt = NULL;
+ CoTaskMemFree(stream->fmt);
+ HeapFree(GetProcessHeap(), 0, stream);
HeapFree(GetProcessHeap(), 0, This->vols);
This->vols = NULL;
- OSSpinLockUnlock(&This->stream->lock);
LeaveCriticalSection(&g_sessions_lock);
return E_INVALIDARG;
}
list_add_tail(&This->session->clients, &This->entry);
- ca_setvol(This, This->stream, -1);
+ ca_setvol(This, stream, -1);
- This->initted = TRUE;
+ This->stream = stream;
- OSSpinLockUnlock(&This->stream->lock);
LeaveCriticalSection(&g_sessions_lock);
return S_OK;
@@ -1402,12 +1385,10 @@ static HRESULT WINAPI AudioClient_GetBufferSize(IAudioClient3 *iface,
if(!frames)
return E_POINTER;
- OSSpinLockLock(&This->stream->lock);
-
- if(!This->initted){
- OSSpinLockUnlock(&This->stream->lock);
+ if(!This->stream)
return AUDCLNT_E_NOT_INITIALIZED;
- }
+
+ OSSpinLockLock(&This->stream->lock);
*frames = This->stream->bufsize_frames;
@@ -1484,12 +1465,10 @@ static HRESULT WINAPI AudioClient_GetStreamLatency(IAudioClient3 *iface,
if(!out)
return E_POINTER;
- OSSpinLockLock(&This->stream->lock);
-
- if(!This->initted){
- OSSpinLockUnlock(&This->stream->lock);
+ if(!This->stream)
return AUDCLNT_E_NOT_INITIALIZED;
- }
+
+ OSSpinLockLock(&This->stream->lock);
addr.mScope = This->scope;
addr.mSelector = kAudioDevicePropertyLatency;
@@ -1524,7 +1503,7 @@ static HRESULT WINAPI AudioClient_GetStreamLatency(IAudioClient3 *iface,
static HRESULT AudioClient_GetCurrentPadding_nolock(ACImpl *This,
UINT32 *numpad)
{
- if(!This->initted)
+ if(!This->stream)
return AUDCLNT_E_NOT_INITIALIZED;
if(This->dataflow == eCapture)
@@ -1546,6 +1525,9 @@ static HRESULT WINAPI AudioClient_GetCurrentPadding(IAudioClient3 *iface,
if(!numpad)
return E_POINTER;
+ if(!This->stream)
+ return AUDCLNT_E_NOT_INITIALIZED;
+
OSSpinLockLock(&This->stream->lock);
hr = AudioClient_GetCurrentPadding_nolock(This, numpad);
@@ -1898,12 +1880,10 @@ static HRESULT WINAPI AudioClient_Start(IAudioClient3 *iface)
TRACE("(%p)\n", This);
- OSSpinLockLock(&This->stream->lock);
-
- if(!This->initted){
- OSSpinLockUnlock(&This->stream->lock);
+ if(!This->stream)
return AUDCLNT_E_NOT_INITIALIZED;
- }
+
+ OSSpinLockLock(&This->stream->lock);
if(This->stream->playing){
OSSpinLockUnlock(&This->stream->lock);
@@ -1937,12 +1917,10 @@ static HRESULT WINAPI AudioClient_Stop(IAudioClient3 *iface)
TRACE("(%p)\n", This);
- OSSpinLockLock(&This->stream->lock);
-
- if(!This->initted){
- OSSpinLockUnlock(&This->stream->lock);
+ if(!This->stream)
return AUDCLNT_E_NOT_INITIALIZED;
- }
+
+ OSSpinLockLock(&This->stream->lock);
if(!This->stream->playing){
OSSpinLockUnlock(&This->stream->lock);
@@ -1962,12 +1940,10 @@ static HRESULT WINAPI AudioClient_Reset(IAudioClient3 *iface)
TRACE("(%p)\n", This);
- OSSpinLockLock(&This->stream->lock);
-
- if(!This->initted){
- OSSpinLockUnlock(&This->stream->lock);
+ if(!This->stream)
return AUDCLNT_E_NOT_INITIALIZED;
- }
+
+ OSSpinLockLock(&This->stream->lock);
if(This->stream->playing){
OSSpinLockUnlock(&This->stream->lock);
@@ -2007,11 +1983,12 @@ static HRESULT WINAPI AudioClient_SetEventHandle(IAudioClient3 *iface,
if(!event)
return E_INVALIDARG;
+ if(!This->stream)
+ return AUDCLNT_E_NOT_INITIALIZED;
+
EnterCriticalSection(&g_sessions_lock);
- if(!This->initted)
- hr = AUDCLNT_E_NOT_INITIALIZED;
- else if(!(This->flags & AUDCLNT_STREAMFLAGS_EVENTCALLBACK))
+ if(!(This->flags & AUDCLNT_STREAMFLAGS_EVENTCALLBACK))
hr = AUDCLNT_E_EVENTHANDLE_NOT_EXPECTED;
else if(This->event){
FIXME("called twice\n");
@@ -2036,12 +2013,10 @@ static HRESULT WINAPI AudioClient_GetService(IAudioClient3 *iface, REFIID riid,
return E_POINTER;
*ppv = NULL;
- EnterCriticalSection(&g_sessions_lock);
+ if(!This->stream)
+ return AUDCLNT_E_NOT_INITIALIZED;
- if(!This->initted){
- hr = AUDCLNT_E_NOT_INITIALIZED;
- goto end;
- }
+ EnterCriticalSection(&g_sessions_lock);
if(IsEqualIID(riid, &IID_IAudioRenderClient)){
if(This->dataflow != eRender){
--
2.23.0
2
1
22 Nov '21
This is a temporary measure that will enable the client volumes to be
initialized without having the stream set.
Signed-off-by: Huw Davies <huw(a)codeweavers.com>
---
dlls/winecoreaudio.drv/mmdevdrv.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/dlls/winecoreaudio.drv/mmdevdrv.c b/dlls/winecoreaudio.drv/mmdevdrv.c
index abe77d11ee9..1e678b08c5b 100644
--- a/dlls/winecoreaudio.drv/mmdevdrv.c
+++ b/dlls/winecoreaudio.drv/mmdevdrv.c
@@ -178,7 +178,7 @@ static CRITICAL_SECTION g_sessions_lock = { &g_sessions_lock_debug, -1, 0, 0, 0,
static struct list g_sessions = LIST_INIT(g_sessions);
static AudioSessionWrapper *AudioSessionWrapper_Create(ACImpl *client);
-static HRESULT ca_setvol(ACImpl *This, UINT32 index);
+static HRESULT ca_setvol(ACImpl *This, struct coreaudio_stream *stream, UINT32 index);
static inline ACImpl *impl_from_IAudioClient3(IAudioClient3 *iface)
{
@@ -1382,7 +1382,7 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient3 *iface,
list_add_tail(&This->session->clients, &This->entry);
- ca_setvol(This, -1);
+ ca_setvol(This, This->stream, -1);
This->initted = TRUE;
@@ -2978,7 +2978,7 @@ static const IAudioSessionControl2Vtbl AudioSessionControl2_Vtbl =
};
/* index == -1 means set all channels, otherwise sets only the given channel */
-static HRESULT ca_setvol(ACImpl *This, UINT32 index)
+static HRESULT ca_setvol(ACImpl *This, struct coreaudio_stream *stream, UINT32 index)
{
Float32 level;
OSStatus sc;
@@ -2989,7 +2989,7 @@ static HRESULT ca_setvol(ACImpl *This, UINT32 index)
if(index == (UINT32)-1){
UINT32 i;
level = 1.;
- for(i = 0; i < This->stream->fmt->nChannels; ++i){
+ for(i = 0; i < stream->fmt->nChannels; ++i){
Float32 tmp;
tmp = This->session->master_vol *
This->session->channel_vols[i] * This->vols[i];
@@ -3000,7 +3000,7 @@ static HRESULT ca_setvol(ACImpl *This, UINT32 index)
This->session->channel_vols[index] * This->vols[index];
}
- sc = AudioUnitSetParameter(This->stream->unit, kHALOutputParam_Volume,
+ sc = AudioUnitSetParameter(stream->unit, kHALOutputParam_Volume,
kAudioUnitScope_Global, 0, level, 0);
if(sc != noErr)
WARN("Couldn't set volume: %x\n", (int)sc);
@@ -3015,7 +3015,7 @@ static HRESULT ca_session_setvol(AudioSession *session, UINT32 index)
LIST_FOR_EACH_ENTRY(client, &session->clients, ACImpl, entry){
HRESULT hr;
- hr = ca_setvol(client, index);
+ hr = ca_setvol(client, client->stream, index);
if(FAILED(hr))
ret = hr;
}
@@ -3214,7 +3214,7 @@ static HRESULT WINAPI AudioStreamVolume_SetChannelVolume(
This->vols[index] = level;
WARN("CoreAudio doesn't support per-channel volume control\n");
- ret = ca_setvol(This, index);
+ ret = ca_setvol(This, This->stream, index);
LeaveCriticalSection(&g_sessions_lock);
@@ -3259,7 +3259,7 @@ static HRESULT WINAPI AudioStreamVolume_SetAllVolumes(
for(i = 0; i < count; ++i)
This->vols[i] = levels[i];
- ret = ca_setvol(This, -1);
+ ret = ca_setvol(This, This->stream, -1);
LeaveCriticalSection(&g_sessions_lock);
--
2.23.0
2
1
22 Nov '21
Signed-off-by: Huw Davies <huw(a)codeweavers.com>
---
dlls/winecoreaudio.drv/mmdevdrv.c | 26 +++++++++++++-------------
1 file changed, 13 insertions(+), 13 deletions(-)
diff --git a/dlls/winecoreaudio.drv/mmdevdrv.c b/dlls/winecoreaudio.drv/mmdevdrv.c
index 56f533f8bc1..abe77d11ee9 100644
--- a/dlls/winecoreaudio.drv/mmdevdrv.c
+++ b/dlls/winecoreaudio.drv/mmdevdrv.c
@@ -877,16 +877,16 @@ static void ca_wrap_buffer(BYTE *dst, UINT32 dst_offs, UINT32 dst_bytes,
memcpy(dst + dst_offs, src, src_bytes);
}
-static void silence_buffer(ACImpl *This, BYTE *buffer, UINT32 frames)
-{
- WAVEFORMATEXTENSIBLE *fmtex = (WAVEFORMATEXTENSIBLE*)This->stream->fmt;
- if((This->stream->fmt->wFormatTag == WAVE_FORMAT_PCM ||
- (This->stream->fmt->wFormatTag == WAVE_FORMAT_EXTENSIBLE &&
- IsEqualGUID(&fmtex->SubFormat, &KSDATAFORMAT_SUBTYPE_PCM))) &&
- This->stream->fmt->wBitsPerSample == 8)
- memset(buffer, 128, frames * This->stream->fmt->nBlockAlign);
+static void silence_buffer(struct coreaudio_stream *stream, BYTE *buffer, UINT32 frames)
+{
+ WAVEFORMATEXTENSIBLE *fmtex = (WAVEFORMATEXTENSIBLE*)stream->fmt;
+ if((stream->fmt->wFormatTag == WAVE_FORMAT_PCM ||
+ (stream->fmt->wFormatTag == WAVE_FORMAT_EXTENSIBLE &&
+ IsEqualGUID(&fmtex->SubFormat, &KSDATAFORMAT_SUBTYPE_PCM))) &&
+ stream->fmt->wBitsPerSample == 8)
+ memset(buffer, 128, frames * stream->fmt->nBlockAlign);
else
- memset(buffer, 0, frames * This->stream->fmt->nBlockAlign);
+ memset(buffer, 0, frames * stream->fmt->nBlockAlign);
}
/* CA is pulling data from us */
@@ -919,7 +919,7 @@ static OSStatus ca_render_cb(void *user, AudioUnitRenderActionFlags *flags,
to_copy_bytes = to_copy_frames = 0;
if(nframes > to_copy_frames)
- silence_buffer(This, ((BYTE *)data->mBuffers[0].mData) + to_copy_bytes, nframes - to_copy_frames);
+ silence_buffer(This->stream, ((BYTE *)data->mBuffers[0].mData) + to_copy_bytes, nframes - to_copy_frames);
OSSpinLockUnlock(&This->stream->lock);
@@ -1344,7 +1344,7 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient3 *iface,
This->stream->local_buffer_size = This->stream->bufsize_frames * fmt->nBlockAlign;
NtAllocateVirtualMemory(GetCurrentProcess(), (void **)&This->stream->local_buffer, 0,
&This->stream->local_buffer_size, MEM_COMMIT, PAGE_READWRITE);
- silence_buffer(This, This->stream->local_buffer, This->stream->bufsize_frames);
+ silence_buffer(This->stream, This->stream->local_buffer, This->stream->bufsize_frames);
if(This->dataflow == eCapture){
This->stream->cap_bufsize_frames = MulDiv(duration, This->stream->dev_desc.mSampleRate, 10000000);
@@ -2318,7 +2318,7 @@ static HRESULT WINAPI AudioRenderClient_GetBuffer(IAudioRenderClient *iface,
This->stream->getbuf_last = frames;
}
- silence_buffer(This, *data, frames);
+ silence_buffer(This->stream, *data, frames);
OSSpinLockUnlock(&This->stream->lock);
@@ -2357,7 +2357,7 @@ static HRESULT WINAPI AudioRenderClient_ReleaseBuffer(
buffer = This->stream->tmp_buffer;
if(flags & AUDCLNT_BUFFERFLAGS_SILENT)
- silence_buffer(This, buffer, frames);
+ silence_buffer(This->stream, buffer, frames);
if(This->stream->getbuf_last < 0)
ca_wrap_buffer(This->stream->local_buffer,
--
2.23.0
2
1
[PATCH 2/7] winecoreaudio: Move creation of the audio unit to IAudioClient_Initialize().
by Huw Davies 22 Nov '21
by Huw Davies 22 Nov '21
22 Nov '21
Signed-off-by: Huw Davies <huw(a)codeweavers.com>
---
dlls/winecoreaudio.drv/mmdevdrv.c | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/dlls/winecoreaudio.drv/mmdevdrv.c b/dlls/winecoreaudio.drv/mmdevdrv.c
index 642610b4b60..56f533f8bc1 100644
--- a/dlls/winecoreaudio.drv/mmdevdrv.c
+++ b/dlls/winecoreaudio.drv/mmdevdrv.c
@@ -580,12 +580,6 @@ HRESULT WINAPI AUDDRV_GetAudioEndpoint(GUID *guid, IMMDevice *dev, IAudioClient
This->adevid = adevid;
- if(!(This->stream->unit = get_audiounit(This->dataflow, This->adevid))){
- HeapFree(GetProcessHeap(), 0, This->stream);
- HeapFree(GetProcessHeap(), 0, This);
- return AUDCLNT_E_DEVICE_INVALIDATED;
- }
-
*out = (IAudioClient *)&This->IAudioClient3_iface;
IAudioClient3_AddRef(&This->IAudioClient3_iface);
@@ -1262,6 +1256,14 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient3 *iface,
if(mode == AUDCLNT_SHAREMODE_EXCLUSIVE)
This->stream->bufsize_frames -= This->stream->bufsize_frames % This->stream->period_frames;
+ if(!(This->stream->unit = get_audiounit(This->dataflow, This->adevid))){
+ CoTaskMemFree(This->stream->fmt);
+ This->stream->fmt = NULL;
+ OSSpinLockUnlock(&This->stream->lock);
+ LeaveCriticalSection(&g_sessions_lock);
+ return AUDCLNT_E_DEVICE_INVALIDATED;
+ }
+
hr = ca_setup_audiounit(This->dataflow, This->stream->unit, This->stream->fmt, &This->stream->dev_desc, &This->stream->converter);
if(FAILED(hr)){
CoTaskMemFree(This->stream->fmt);
--
2.23.0
2
1
[PATCH 1/7] winecoreaudio: Use NtAllocateVirtualMemory() for local and tmp buffers.
by Huw Davies 22 Nov '21
by Huw Davies 22 Nov '21
22 Nov '21
Signed-off-by: Huw Davies <huw(a)codeweavers.com>
---
dlls/winecoreaudio.drv/mmdevdrv.c | 28 ++++++++++++++++++++--------
dlls/winecoreaudio.drv/unixlib.h | 2 +-
2 files changed, 21 insertions(+), 9 deletions(-)
diff --git a/dlls/winecoreaudio.drv/mmdevdrv.c b/dlls/winecoreaudio.drv/mmdevdrv.c
index 1e37a2a9026..642610b4b60 100644
--- a/dlls/winecoreaudio.drv/mmdevdrv.c
+++ b/dlls/winecoreaudio.drv/mmdevdrv.c
@@ -653,9 +653,13 @@ static ULONG WINAPI AudioClient_Release(IAudioClient3 *iface)
LeaveCriticalSection(&g_sessions_lock);
}
HeapFree(GetProcessHeap(), 0, This->vols);
- HeapFree(GetProcessHeap(), 0, This->stream->tmp_buffer);
HeapFree(GetProcessHeap(), 0, This->stream->cap_buffer);
- HeapFree(GetProcessHeap(), 0, This->stream->local_buffer);
+ if(This->stream->local_buffer)
+ NtFreeVirtualMemory(GetCurrentProcess(), (void **)&This->stream->local_buffer,
+ &This->stream->local_buffer_size, MEM_RELEASE);
+ if(This->stream->tmp_buffer)
+ NtFreeVirtualMemory(GetCurrentProcess(), (void **)&This->stream->tmp_buffer,
+ &This->stream->tmp_buffer_size, MEM_RELEASE);
free(This->stream->wrap_buffer);
HeapFree(GetProcessHeap(), 0, This->stream->resamp_buffer);
CoTaskMemFree(This->stream->fmt);
@@ -1335,7 +1339,9 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient3 *iface,
return osstatus_to_hresult(sc);
}
- This->stream->local_buffer = HeapAlloc(GetProcessHeap(), 0, This->stream->bufsize_frames * fmt->nBlockAlign);
+ This->stream->local_buffer_size = This->stream->bufsize_frames * fmt->nBlockAlign;
+ NtAllocateVirtualMemory(GetCurrentProcess(), (void **)&This->stream->local_buffer, 0,
+ &This->stream->local_buffer_size, MEM_COMMIT, PAGE_READWRITE);
silence_buffer(This, This->stream->local_buffer, This->stream->bufsize_frames);
if(This->dataflow == eCapture){
@@ -2292,9 +2298,12 @@ static HRESULT WINAPI AudioRenderClient_GetBuffer(IAudioRenderClient *iface,
if(This->stream->wri_offs_frames + frames > This->stream->bufsize_frames){
if(This->stream->tmp_buffer_frames < frames){
- HeapFree(GetProcessHeap(), 0, This->stream->tmp_buffer);
- This->stream->tmp_buffer = HeapAlloc(GetProcessHeap(), 0, frames * This->stream->fmt->nBlockAlign);
- if(!This->stream->tmp_buffer){
+ NtFreeVirtualMemory(GetCurrentProcess(), (void **)&This->stream->tmp_buffer,
+ &This->stream->tmp_buffer_size, MEM_RELEASE);
+ This->stream->tmp_buffer_size = frames * This->stream->fmt->nBlockAlign;
+ if(NtAllocateVirtualMemory(GetCurrentProcess(), (void **)&This->stream->tmp_buffer, 0,
+ &This->stream->tmp_buffer_size, MEM_COMMIT, PAGE_READWRITE)){
+ This->stream->tmp_buffer_frames = 0;
OSSpinLockUnlock(&This->stream->lock);
return E_OUTOFMEMORY;
}
@@ -2449,8 +2458,11 @@ static HRESULT WINAPI AudioCaptureClient_GetBuffer(IAudioCaptureClient *iface,
chunk_frames = This->stream->bufsize_frames - This->stream->lcl_offs_frames;
if(chunk_frames < This->stream->period_frames){
chunk_bytes = chunk_frames * This->stream->fmt->nBlockAlign;
- if(!This->stream->tmp_buffer)
- This->stream->tmp_buffer = HeapAlloc(GetProcessHeap(), 0, This->stream->period_frames * This->stream->fmt->nBlockAlign);
+ if(!This->stream->tmp_buffer){
+ This->stream->tmp_buffer_size = This->stream->period_frames * This->stream->fmt->nBlockAlign;
+ NtAllocateVirtualMemory(GetCurrentProcess(), (void **)&This->stream->tmp_buffer, 0,
+ &This->stream->tmp_buffer_size, MEM_COMMIT, PAGE_READWRITE);
+ }
*data = This->stream->tmp_buffer;
memcpy(*data, This->stream->local_buffer + This->stream->lcl_offs_frames * This->stream->fmt->nBlockAlign, chunk_bytes);
memcpy((*data) + chunk_bytes, This->stream->local_buffer, This->stream->period_frames * This->stream->fmt->nBlockAlign - chunk_bytes);
diff --git a/dlls/winecoreaudio.drv/unixlib.h b/dlls/winecoreaudio.drv/unixlib.h
index 6a991f1de98..1b773b7f820 100644
--- a/dlls/winecoreaudio.drv/unixlib.h
+++ b/dlls/winecoreaudio.drv/unixlib.h
@@ -29,7 +29,6 @@ struct coreaudio_stream /* To be made private */
AUDCLNT_SHAREMODE share;
BOOL playing;
- SIZE_T local_buffer_size, tmp_buffer_size;
UINT32 period_ms, period_frames;
UINT32 bufsize_frames, resamp_bufsize_frames;
UINT32 lcl_offs_frames, held_frames, wri_offs_frames, tmp_buffer_frames;
@@ -39,6 +38,7 @@ struct coreaudio_stream /* To be made private */
INT32 getbuf_last;
WAVEFORMATEX *fmt;
BYTE *local_buffer, *cap_buffer, *wrap_buffer, *resamp_buffer, *tmp_buffer;
+ SIZE_T local_buffer_size, tmp_buffer_size;
};
struct endpoint
--
2.23.0
2
1
[PATCH 1/6] wined3d: Move the "buffer_offset" field to struct wined3d_bo.
by Zebediah Figura 22 Nov '21
by Zebediah Figura 22 Nov '21
22 Nov '21
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
dlls/wined3d/adapter_vk.c | 14 +++++++-------
dlls/wined3d/buffer.c | 4 ++--
dlls/wined3d/context_gl.c | 8 ++++----
dlls/wined3d/context_vk.c | 10 +++++-----
dlls/wined3d/device.c | 6 +++---
dlls/wined3d/state.c | 4 ++--
dlls/wined3d/texture.c | 8 ++++----
dlls/wined3d/view.c | 8 ++++----
dlls/wined3d/wined3d_private.h | 3 +--
9 files changed, 32 insertions(+), 33 deletions(-)
diff --git a/dlls/wined3d/adapter_vk.c b/dlls/wined3d/adapter_vk.c
index e6f5bf108c7..f9a31265cd3 100644
--- a/dlls/wined3d/adapter_vk.c
+++ b/dlls/wined3d/adapter_vk.c
@@ -1011,7 +1011,7 @@ static void *adapter_vk_map_bo_address(struct wined3d_context *context,
vk_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
vk_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
vk_barrier.buffer = bo->vk_buffer;
- vk_barrier.offset = bo->buffer_offset + (uintptr_t)data->addr;
+ vk_barrier.offset = bo->b.buffer_offset + (uintptr_t)data->addr;
vk_barrier.size = size;
VK_CALL(vkCmdPipelineBarrier(vk_command_buffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
VK_PIPELINE_STAGE_HOST_BIT, 0, 0, NULL, 1, &vk_barrier, 0, NULL));
@@ -1113,8 +1113,8 @@ void adapter_vk_copy_bo_address(struct wined3d_context *context,
src_access_mask = vk_access_mask_from_buffer_usage(src_bo->usage);
dst_access_mask = vk_access_mask_from_buffer_usage(dst_bo->usage);
- region.srcOffset = src_bo->buffer_offset + (uintptr_t)src->addr;
- region.dstOffset = dst_bo->buffer_offset + (uintptr_t)dst->addr;
+ region.srcOffset = src_bo->b.buffer_offset + (uintptr_t)src->addr;
+ region.dstOffset = dst_bo->b.buffer_offset + (uintptr_t)dst->addr;
region.size = size;
vk_barrier[0].sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
@@ -1781,7 +1781,7 @@ static void adapter_vk_draw_primitive(struct wined3d_device *device,
for (i = 0; i < ARRAY_SIZE(context_vk->vk_so_counters); ++i)
{
context_vk->vk_so_counters[i] = bo->vk_buffer;
- context_vk->vk_so_offsets[i] = bo->buffer_offset + i * sizeof(uint32_t) * 2;
+ context_vk->vk_so_offsets[i] = bo->b.buffer_offset + i * sizeof(uint32_t) * 2;
}
}
@@ -1805,13 +1805,13 @@ static void adapter_vk_draw_primitive(struct wined3d_device *device,
{
stride = sizeof(VkDrawIndexedIndirectCommand);
VK_CALL(vkCmdDrawIndexedIndirect(vk_command_buffer, bo->vk_buffer,
- bo->buffer_offset + parameters->u.indirect.offset, size / stride, stride));
+ bo->b.buffer_offset + parameters->u.indirect.offset, size / stride, stride));
}
else
{
stride = sizeof(VkDrawIndirectCommand);
VK_CALL(vkCmdDrawIndirect(vk_command_buffer, bo->vk_buffer,
- bo->buffer_offset + parameters->u.indirect.offset, size / stride, stride));
+ bo->b.buffer_offset + parameters->u.indirect.offset, size / stride, stride));
}
}
else
@@ -1871,7 +1871,7 @@ static void adapter_vk_dispatch_compute(struct wined3d_device *device,
wined3d_context_vk_reference_bo(context_vk, bo);
VK_CALL(vkCmdDispatchIndirect(vk_command_buffer, bo->vk_buffer,
- bo->buffer_offset + parameters->u.indirect.offset));
+ bo->b.buffer_offset + parameters->u.indirect.offset));
}
else
{
diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c
index 315ea05260e..d3aeb2e76f4 100644
--- a/dlls/wined3d/buffer.c
+++ b/dlls/wined3d/buffer.c
@@ -1521,7 +1521,7 @@ const VkDescriptorBufferInfo *wined3d_buffer_vk_get_buffer_info(struct wined3d_b
return &buffer_vk->buffer_info;
buffer_vk->buffer_info.buffer = bo->vk_buffer;
- buffer_vk->buffer_info.offset = bo->buffer_offset;
+ buffer_vk->buffer_info.offset = bo->b.buffer_offset;
buffer_vk->buffer_info.range = buffer_vk->b.resource.size;
buffer_vk->b.bo_user.valid = true;
@@ -1702,7 +1702,7 @@ void wined3d_buffer_vk_barrier(struct wined3d_buffer_vk *buffer_vk,
vk_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
vk_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
vk_barrier.buffer = bo->vk_buffer;
- vk_barrier.offset = bo->buffer_offset;
+ vk_barrier.offset = bo->b.buffer_offset;
vk_barrier.size = buffer_vk->b.resource.size;
VK_CALL(vkCmdPipelineBarrier(wined3d_context_vk_get_command_buffer(context_vk),
vk_pipeline_stage_mask_from_bind_flags(src_bind_mask),
diff --git a/dlls/wined3d/context_gl.c b/dlls/wined3d/context_gl.c
index 2751a4a2182..69eb13f3027 100644
--- a/dlls/wined3d/context_gl.c
+++ b/dlls/wined3d/context_gl.c
@@ -2922,7 +2922,7 @@ bool wined3d_context_gl_create_bo(struct wined3d_context_gl *context_gl, GLsizei
list_init(&bo->b.users);
bo->command_fence_id = 0;
bo->b.memory_offset = 0;
- bo->buffer_offset = 0;
+ bo->b.buffer_offset = 0;
bo->b.map_ptr = NULL;
return true;
@@ -3789,7 +3789,7 @@ static void wined3d_context_gl_bind_unordered_access_views(struct wined3d_contex
if (view_gl->counter_bo.id)
GL_EXTCALL(glBindBufferRange(GL_ATOMIC_COUNTER_BUFFER, i, view_gl->counter_bo.id,
- view_gl->counter_bo.buffer_offset, view_gl->counter_bo.size));
+ view_gl->counter_bo.b.buffer_offset, view_gl->counter_bo.size));
}
checkGLcall("Bind unordered access views");
}
@@ -4915,7 +4915,7 @@ void draw_primitive(struct wined3d_device *device, const struct wined3d_state *s
if (!bo || !stream_info->all_vbo)
idx_data = index_buffer->resource.heap_memory;
else
- idx_data = (void *)wined3d_bo_gl(bo)->buffer_offset;
+ idx_data = (void *)bo->buffer_offset;
idx_data = (const BYTE *)idx_data + state->index_offset;
if (state->index_format == WINED3DFMT_R16_UINT)
@@ -5077,7 +5077,7 @@ static const void *get_vertex_attrib_pointer(const struct wined3d_stream_info_el
const uint8_t *offset = element->data.addr + state->load_base_vertex_index * element->stride;
if (element->data.buffer_object)
- offset += wined3d_bo_gl(element->data.buffer_object)->buffer_offset;
+ offset += element->data.buffer_object->buffer_offset;
return offset;
}
diff --git a/dlls/wined3d/context_vk.c b/dlls/wined3d/context_vk.c
index ec3554ddc30..56b2da53060 100644
--- a/dlls/wined3d/context_vk.c
+++ b/dlls/wined3d/context_vk.c
@@ -456,8 +456,8 @@ static bool wined3d_context_vk_create_slab_bo(struct wined3d_context_vk *context
*bo = slab->bo;
bo->memory = NULL;
bo->slab = slab;
- bo->buffer_offset = idx * object_size;
- bo->b.memory_offset = slab->bo.b.memory_offset + bo->buffer_offset;
+ bo->b.buffer_offset = idx * object_size;
+ bo->b.memory_offset = slab->bo.b.memory_offset + bo->b.buffer_offset;
bo->size = size;
list_init(&bo->b.users);
bo->command_buffer_id = 0;
@@ -465,7 +465,7 @@ static bool wined3d_context_vk_create_slab_bo(struct wined3d_context_vk *context
TRACE("Using buffer 0x%s, memory 0x%s, offset 0x%s for bo %p.\n",
wine_dbgstr_longlong(bo->vk_buffer), wine_dbgstr_longlong(bo->vk_memory),
- wine_dbgstr_longlong(bo->buffer_offset), bo);
+ wine_dbgstr_longlong(bo->b.buffer_offset), bo);
return true;
}
@@ -534,7 +534,7 @@ BOOL wined3d_context_vk_create_bo(struct wined3d_context_vk *context_vk, VkDevic
}
bo->b.map_ptr = NULL;
- bo->buffer_offset = 0;
+ bo->b.buffer_offset = 0;
bo->size = size;
bo->usage = usage;
bo->memory_type = adapter_vk->memory_properties.memoryTypes[memory_type_idx].propertyFlags;
@@ -961,7 +961,7 @@ void wined3d_context_vk_destroy_bo(struct wined3d_context_vk *context_vk, const
if (bo->b.map_ptr)
wined3d_bo_slab_vk_unmap(slab_vk, context_vk);
object_size = slab_vk->bo.size / 32;
- idx = bo->buffer_offset / object_size;
+ idx = bo->b.buffer_offset / object_size;
wined3d_context_vk_destroy_bo_slab_slice(context_vk, slab_vk, idx, bo->command_buffer_id);
return;
}
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index c5de58c29c9..7fb8a7ec3a6 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -657,9 +657,9 @@ bool wined3d_device_vk_create_null_resources(struct wined3d_device_vk *device_vk
memory_type = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
if (!wined3d_context_vk_create_bo(context_vk, 16, usage, memory_type, &r->bo))
return false;
- VK_CALL(vkCmdFillBuffer(vk_command_buffer, r->bo.vk_buffer, r->bo.buffer_offset, r->bo.size, 0x00000000u));
+ VK_CALL(vkCmdFillBuffer(vk_command_buffer, r->bo.vk_buffer, r->bo.b.buffer_offset, r->bo.size, 0x00000000u));
r->buffer_info.buffer = r->bo.vk_buffer;
- r->buffer_info.offset = r->bo.buffer_offset;
+ r->buffer_info.offset = r->bo.b.buffer_offset;
r->buffer_info.range = r->bo.size;
if (!wined3d_null_image_vk_init(&r->image_1d, context_vk, vk_command_buffer, VK_IMAGE_TYPE_1D, 1, 1))
@@ -735,7 +735,7 @@ bool wined3d_device_vk_create_null_views(struct wined3d_device_vk *device_vk, st
buffer_create_info.flags = 0;
buffer_create_info.buffer = r->bo.vk_buffer;
buffer_create_info.format = VK_FORMAT_R32_UINT;
- buffer_create_info.offset = r->bo.buffer_offset;
+ buffer_create_info.offset = r->bo.b.buffer_offset;
buffer_create_info.range = r->bo.size;
if ((vr = VK_CALL(vkCreateBufferView(device_vk->vk_device,
diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c
index e0dba8701bc..c76e0c2b604 100644
--- a/dlls/wined3d/state.c
+++ b/dlls/wined3d/state.c
@@ -4600,7 +4600,7 @@ static void state_cb(struct wined3d_context *context, const struct wined3d_state
buffer = buffer_state->buffer;
bo_gl = wined3d_bo_gl(buffer->buffer_object);
GL_EXTCALL(glBindBufferRange(GL_UNIFORM_BUFFER, base + i,
- bo_gl->id, bo_gl->buffer_offset + buffer_state->offset, buffer_state->size));
+ bo_gl->id, bo_gl->b.buffer_offset + buffer_state->offset, buffer_state->size));
buffer->bo_user.valid = true;
}
checkGLcall("bind constant buffers");
@@ -4677,7 +4677,7 @@ static void state_so(struct wined3d_context *context, const struct wined3d_state
}
size = buffer->resource.size - offset;
GL_EXTCALL(glBindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, i,
- bo_gl->id, bo_gl->buffer_offset + offset, size));
+ bo_gl->id, bo_gl->b.buffer_offset + offset, size));
buffer->bo_user.valid = true;
}
checkGLcall("bind transform feedback buffers");
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c
index 7e2da350f5a..87ae569b549 100644
--- a/dlls/wined3d/texture.c
+++ b/dlls/wined3d/texture.c
@@ -4764,7 +4764,7 @@ static void wined3d_texture_vk_upload_data(struct wined3d_context *context,
vk_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
vk_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
vk_barrier.buffer = src_bo->vk_buffer;
- vk_barrier.offset = src_bo->buffer_offset + (size_t)src_bo_addr->addr;
+ vk_barrier.offset = src_bo->b.buffer_offset + (size_t)src_bo_addr->addr;
vk_barrier.size = sub_resource->size;
src_offset += (size_t)src_bo_addr->addr;
@@ -4788,7 +4788,7 @@ static void wined3d_texture_vk_upload_data(struct wined3d_context *context,
dst_texture_vk->layout, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
dst_texture_vk->image.vk_image, &vk_range);
- region.bufferOffset = src_bo->buffer_offset + src_offset;
+ region.bufferOffset = src_bo->b.buffer_offset + src_offset;
region.bufferRowLength = (src_row_pitch / src_format->block_byte_count) * src_format->block_width;
if (src_row_pitch)
region.bufferImageHeight = (src_slice_pitch / src_row_pitch) * src_format->block_height;
@@ -4941,7 +4941,7 @@ static void wined3d_texture_vk_download_data(struct wined3d_context *context,
vk_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
vk_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
vk_barrier.buffer = dst_bo->vk_buffer;
- vk_barrier.offset = dst_bo->buffer_offset + (size_t)dst_bo_addr->addr;
+ vk_barrier.offset = dst_bo->b.buffer_offset + (size_t)dst_bo_addr->addr;
vk_barrier.size = sub_resource->size;
bo_stage_flags = vk_pipeline_stage_mask_from_buffer_usage(dst_bo->usage);
@@ -4964,7 +4964,7 @@ static void wined3d_texture_vk_download_data(struct wined3d_context *context,
src_texture_vk->layout, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
src_texture_vk->image.vk_image, &vk_range);
- region.bufferOffset = dst_bo->buffer_offset + dst_offset;
+ region.bufferOffset = dst_bo->b.buffer_offset + dst_offset;
region.bufferRowLength = 0;
region.bufferImageHeight = 0;
region.imageSubresource.aspectMask = vk_range.aspectMask;
diff --git a/dlls/wined3d/view.c b/dlls/wined3d/view.c
index b902812aded..b981602f1a2 100644
--- a/dlls/wined3d/view.c
+++ b/dlls/wined3d/view.c
@@ -685,7 +685,7 @@ static VkBufferView wined3d_view_vk_create_vk_buffer_view(struct wined3d_context
create_info.flags = 0;
create_info.buffer = bo->vk_buffer;
create_info.format = view_format_vk->vk_format;
- create_info.offset = bo->buffer_offset + offset;
+ create_info.offset = bo->b.buffer_offset + offset;
create_info.range = size;
device_vk = wined3d_device_vk(buffer_vk->b.resource.device);
@@ -2101,7 +2101,7 @@ void wined3d_unordered_access_view_vk_clear(struct wined3d_unordered_access_view
buffer_info.buffer = constants_bo.vk_buffer;
buffer_info.range = constants_bo.size;
- buffer_info.offset = constants_bo.buffer_offset;
+ buffer_info.offset = constants_bo.b.buffer_offset;
vk_info = context_vk->vk_info;
@@ -2234,7 +2234,7 @@ static void wined3d_unordered_access_view_vk_cs_init(void *object)
wined3d_context_vk_end_current_render_pass(context_vk);
VK_CALL(vkCmdFillBuffer(wined3d_context_vk_get_command_buffer(context_vk),
- uav_vk->counter_bo.vk_buffer, uav_vk->counter_bo.buffer_offset, sizeof(uint32_t), 0));
+ uav_vk->counter_bo.vk_buffer, uav_vk->counter_bo.b.buffer_offset, sizeof(uint32_t), 0));
wined3d_context_vk_reference_bo(context_vk, &uav_vk->counter_bo);
create_info.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
@@ -2242,7 +2242,7 @@ static void wined3d_unordered_access_view_vk_cs_init(void *object)
create_info.flags = 0;
create_info.buffer = uav_vk->counter_bo.vk_buffer;
create_info.format = VK_FORMAT_R32_UINT;
- create_info.offset = uav_vk->counter_bo.buffer_offset;
+ create_info.offset = uav_vk->counter_bo.b.buffer_offset;
create_info.range = sizeof(uint32_t);
if ((vr = VK_CALL(vkCreateBufferView(device_vk->vk_device,
&create_info, NULL, &uav_vk->vk_counter_view))) < 0)
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 79b02c2448d..2fce585c6b1 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1597,6 +1597,7 @@ struct wined3d_bo
{
struct list users;
void *map_ptr;
+ size_t buffer_offset;
size_t memory_offset;
bool coherent;
};
@@ -1606,7 +1607,6 @@ struct wined3d_bo_gl
struct wined3d_bo b;
GLuint id;
- GLsizeiptr buffer_offset;
GLsizeiptr size;
GLenum binding;
GLenum usage;
@@ -1641,7 +1641,6 @@ struct wined3d_bo_vk
VkDeviceMemory vk_memory;
- VkDeviceSize buffer_offset;
VkDeviceSize size;
VkBufferUsageFlags usage;
VkMemoryPropertyFlags memory_type;
--
2.33.0
3
12