"The King of Fighters '98 Ultimate Match Final Edition" depends on this behavior. At least, the build I have is; it seems other builds are not.
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com
-- v6: xactengine3_7: Forward wave bank notifications to the application. faudio: Send WAVEBANKPREPARED notifications. xactengine3_7/tests: Test notifications when loading a wave bank.
From: Giovanni Mascellani gmascellani@codeweavers.com
"The King of Fighters '98 Ultimate Match Final Edition" depends on this behavior. At least, the build I have is; it seems other builds are not.
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com --- dlls/xactengine3_7/tests/xact3.c | 171 +++++++++++++++++++++++++++++++ 1 file changed, 171 insertions(+)
diff --git a/dlls/xactengine3_7/tests/xact3.c b/dlls/xactengine3_7/tests/xact3.c index 623a1c97db8..1b27eb9aa19 100644 --- a/dlls/xactengine3_7/tests/xact3.c +++ b/dlls/xactengine3_7/tests/xact3.c @@ -28,6 +28,7 @@
#include "initguid.h" #include "xact3.h" +#include "xact3wb.h"
DEFINE_GUID(IID_IXACT3Engine30, 0x9e33f661, 0x2d07, 0x43ec, 0x97, 0x04, 0xbb, 0xcb, 0x71, 0xa5, 0x49, 0x72); DEFINE_GUID(IID_IXACT3Engine31, 0xe72c1b9a, 0xd717, 0x41c0, 0x81, 0xa6, 0x50, 0xeb, 0x56, 0xe8, 0x06, 0x49); @@ -90,11 +91,181 @@ static void test_interfaces(void) } }
+static WCHAR *gen_xwb_file(void) +{ + static const WAVEBANKENTRY entry = + { + .Format = + { + .wFormatTag = WAVEBANKMINIFORMAT_TAG_ADPCM, + .nChannels = 2, + .nSamplesPerSec = 22051, + .wBlockAlign = 48, + }, + }; + static const WAVEBANKDATA bank_data = + { + .dwFlags = WAVEBANK_TYPE_STREAMING, + .dwEntryCount = 1, + .szBankName = "test", + .dwEntryMetaDataElementSize = sizeof(entry), + .dwEntryNameElementSize = WAVEBANK_ENTRYNAME_LENGTH, + .dwAlignment = 0x800, + }; + static const WAVEBANKHEADER header = + { + .dwSignature = WAVEBANK_HEADER_SIGNATURE, + .dwVersion = XACT_CONTENT_VERSION, + .dwHeaderVersion = WAVEBANK_HEADER_VERSION, + .Segments = + { + [WAVEBANK_SEGIDX_BANKDATA] = + { + .dwOffset = sizeof(header), + .dwLength = sizeof(bank_data), + }, + [WAVEBANK_SEGIDX_ENTRYMETADATA] = + { + .dwOffset = sizeof(header) + sizeof(bank_data), + .dwLength = sizeof(entry), + }, + }, + }; + static WCHAR path[MAX_PATH]; + DWORD written; + HANDLE file; + + GetTempPathW(ARRAY_SIZE(path), path); + lstrcatW(path, L"test.xwb"); + + file = CreateFileW(path, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0); + ok(file != INVALID_HANDLE_VALUE, "Cannot create file %s, error %ld\n", + wine_dbgstr_w(path), GetLastError()); + + WriteFile(file, &header, sizeof(header), &written, NULL); + ok(written == sizeof(header), "Cannot write header\n"); + + WriteFile(file, &bank_data, sizeof(bank_data), &written, NULL); + ok(written == sizeof(bank_data), "Cannot write bank data\n"); + + WriteFile(file, &entry, sizeof(entry), &written, NULL); + ok(written == sizeof(entry), "Cannot write entry\n"); + + CloseHandle(file); + + return path; +} + +struct notification_cb_data +{ + XACTNOTIFICATIONTYPE type; + IXACT3WaveBank *wave_bank; + BOOL received; + DWORD thread_id; +}; + +static void WINAPI notification_cb(const XACT_NOTIFICATION *notification) +{ + struct notification_cb_data *data = notification->pvContext; + DWORD thread_id = GetCurrentThreadId(); + + data->received = TRUE; + ok(notification->type == data->type, + "Unexpected notification type %u\n", notification->type); + ok(notification->waveBank.pWaveBank == data->wave_bank, "Unexpected wave bank %p instead of %p\n", + notification->waveBank.pWaveBank, data->wave_bank); + ok(thread_id == data->thread_id, "Unexpected thread id %#lx instead of %#lx\n", thread_id, data->thread_id); +} + +static void test_notifications(void) +{ + struct notification_cb_data prepared_data = { 0 }, destroyed_data = { 0 }; + XACT_NOTIFICATION_DESCRIPTION notification_desc = { 0 }; + XACT_STREAMING_PARAMETERS streaming_params = { 0 }; + XACT_RUNTIME_PARAMETERS params = { 0 }; + IXACT3Engine *engine; + WCHAR *filename; + unsigned int i; + HANDLE file; + DWORD state; + HRESULT hr; + + hr = CoCreateInstance(&CLSID_XACTEngine, NULL, CLSCTX_INPROC_SERVER, &IID_IXACT3Engine, (void **)&engine); + ok(hr == S_OK || broken(hr == REGDB_E_CLASSNOTREG) /* Win 10 v1507 */, "Cannot create engine, hr %#lx\n", hr); + + if (hr == REGDB_E_CLASSNOTREG) + { + win_skip("XACT not supported\n"); + return; + } + + params.lookAheadTime = XACT_ENGINE_LOOKAHEAD_DEFAULT; + params.fnNotificationCallback = notification_cb; + + hr = IXACT3Engine_Initialize(engine, ¶ms); + ok(hr == S_OK, "Cannot initialize engine, hr %#lx\n", hr); + + prepared_data.type = XACTNOTIFICATIONTYPE_WAVEBANKPREPARED; + prepared_data.thread_id = GetCurrentThreadId(); + notification_desc.type = XACTNOTIFICATIONTYPE_WAVEBANKPREPARED; + notification_desc.flags = XACT_FLAG_NOTIFICATION_PERSIST; + notification_desc.pvContext = &prepared_data; + hr = IXACT3Engine_RegisterNotification(engine, ¬ification_desc); + ok(hr == S_OK, "Cannot register notification, hr %#lx\n", hr); + + destroyed_data.type = XACTNOTIFICATIONTYPE_WAVEBANKDESTROYED; + destroyed_data.thread_id = GetCurrentThreadId(); + notification_desc.type = XACTNOTIFICATIONTYPE_WAVEBANKDESTROYED; + notification_desc.flags = XACT_FLAG_NOTIFICATION_PERSIST; + notification_desc.pvContext = NULL; + hr = IXACT3Engine_RegisterNotification(engine, ¬ification_desc); + ok(hr == S_OK, "Cannot register notification, hr %#lx\n", hr); + + /* Registering again overrides pvContext, but each notification + * class has its own pvContext. */ + notification_desc.pvContext = &destroyed_data; + hr = IXACT3Engine_RegisterNotification(engine, ¬ification_desc); + ok(hr == S_OK, "Cannot register notification, hr %#lx\n", hr); + + filename = gen_xwb_file(); + + file = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); + ok(file != INVALID_HANDLE_VALUE, "Cannot open file\n"); + + streaming_params.file = file; + streaming_params.packetSize = 0x800; + hr = IXACT3Engine_CreateStreamingWaveBank(engine, &streaming_params, &prepared_data.wave_bank); + ok(hr == S_OK, "Cannot create a streaming wave bank, hr %#lx\n", hr); + destroyed_data.wave_bank = prepared_data.wave_bank; + + for (i = 0; i < 10 && !prepared_data.received; i++) + { + IXACT3Engine_DoWork(engine); + Sleep(1); + } + + hr = IXACT3WaveBank_GetState(prepared_data.wave_bank, &state); + ok(hr == S_OK, "Cannot query wave bank state, hr %#lx\n", hr); + ok(state == XACT_WAVEBANKSTATE_PREPARED, "Wave bank is not in prepared state, but in %#lx\n", state); + + todo_wine ok(prepared_data.received, "The 'wave bank prepared' notification was never received\n"); + ok(!destroyed_data.received, "The 'wave bank destroyed' notification was received too early\n"); + + IXACT3WaveBank_Destroy(prepared_data.wave_bank); + todo_wine ok(destroyed_data.received, "The 'wave bank destroyed' notification was never received\n"); + + CloseHandle(file); + IXACT3Engine_Release(engine); + + DeleteFileW(filename); +} + START_TEST(xact3) { CoInitialize(NULL);
test_interfaces(); + test_notifications();
CoUninitialize(); }
From: Giovanni Mascellani gmascellani@codeweavers.com
The notifications are not sent immediately, but pushed to a queue and sent at the next DoWork() call. This seems to correspond to what happens on Windows.
Corresponding to upstream commit 9e53dbeebfdd8d0f23144b8b1aa895bca2727977.
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com --- libs/faudio/src/FACT.c | 26 ++++++++++++++++++++++++++ libs/faudio/src/FACT_internal.h | 1 + 2 files changed, 27 insertions(+)
diff --git a/libs/faudio/src/FACT.c b/libs/faudio/src/FACT.c index c3596ec2d48..bd8f89d3d8d 100644 --- a/libs/faudio/src/FACT.c +++ b/libs/faudio/src/FACT.c @@ -433,9 +433,17 @@ uint32_t FACTAudioEngine_DoWork(FACTAudioEngine *pEngine) uint8_t i; FACTCue *cue; LinkedList *list; + FACTNotification *note;
FAudio_PlatformLockMutex(pEngine->apiLock);
+ while (pEngine->wb_notifications_list) + { + note = (FACTNotification*) pEngine->wb_notifications_list->entry; + pEngine->notificationCallback(note); + LinkedList_RemoveEntry(&pEngine->wb_notifications_list, note, pEngine->apiLock, pEngine->pFree); + } + list = pEngine->sbList; while (list != NULL) { @@ -495,6 +503,7 @@ uint32_t FACTAudioEngine_CreateInMemoryWaveBank( uint32_t dwAllocAttributes, FACTWaveBank **ppWaveBank ) { + FACTNotification *note; uint32_t retval; FAudio_PlatformLockMutex(pEngine->apiLock); retval = FACT_INTERNAL_ParseWaveBank( @@ -507,6 +516,14 @@ uint32_t FACTAudioEngine_CreateInMemoryWaveBank( 0, ppWaveBank ); + if (pEngine->notifications & NOTIFY_WAVEBANKPREPARED) + { + note = (FACTNotification*) pEngine->pMalloc(sizeof(FACTNotification)); + note->type = FACTNOTIFICATIONTYPE_WAVEBANKPREPARED; + note->waveBank.pWaveBank = *ppWaveBank; + note->pvContext = pEngine->wb_context; + LinkedList_AddEntry(&pEngine->wb_notifications_list, note, pEngine->apiLock, pEngine->pMalloc); + } FAudio_PlatformUnlockMutex(pEngine->apiLock); return retval; } @@ -516,6 +533,7 @@ uint32_t FACTAudioEngine_CreateStreamingWaveBank( const FACTStreamingParameters *pParms, FACTWaveBank **ppWaveBank ) { + FACTNotification *note; uint32_t retval, packetSize; FAudio_PlatformLockMutex(pEngine->apiLock); if ( pEngine->pReadFile == FACT_INTERNAL_DefaultReadFile && @@ -538,6 +556,14 @@ uint32_t FACTAudioEngine_CreateStreamingWaveBank( 1, ppWaveBank ); + if (pEngine->notifications & NOTIFY_WAVEBANKPREPARED) + { + note = (FACTNotification*) pEngine->pMalloc(sizeof(FACTNotification)); + note->type = FACTNOTIFICATIONTYPE_WAVEBANKPREPARED; + note->waveBank.pWaveBank = *ppWaveBank; + note->pvContext = pEngine->wb_context; + LinkedList_AddEntry(&pEngine->wb_notifications_list, note, pEngine->apiLock, pEngine->pMalloc); + } FAudio_PlatformUnlockMutex(pEngine->apiLock); return retval; } diff --git a/libs/faudio/src/FACT_internal.h b/libs/faudio/src/FACT_internal.h index 8d46953be7b..97d09e56c66 100644 --- a/libs/faudio/src/FACT_internal.h +++ b/libs/faudio/src/FACT_internal.h @@ -440,6 +440,7 @@ struct FACTAudioEngine void *sb_context; void *wb_context; void *wave_context; + LinkedList *wb_notifications_list;
/* Settings handle */ void *settings;
On 7/14/22 08:07, Giovanni Mascellani wrote:
From: Giovanni Mascellani gmascellani@codeweavers.com
The notifications are not sent immediately, but pushed to a queue and sent at the next DoWork() call. This seems to correspond to what happens on Windows.
Corresponding to upstream commit 9e53dbeebfdd8d0f23144b8b1aa895bca2727977.
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com
libs/faudio/src/FACT.c | 26 ++++++++++++++++++++++++++ libs/faudio/src/FACT_internal.h | 1 + 2 files changed, 27 insertions(+)
Can we please not do this? It's mean enough to distributions to bundle software, but it's worse when we're bundling local changes as well. Can we just wait for a new version to be released and then import that?
From: Giovanni Mascellani gmascellani@codeweavers.com
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com --- dlls/xactengine3_7/tests/xact3.c | 5 +- dlls/xactengine3_7/xact_dll.c | 201 +++++++++++++++++++++++++++++-- 2 files changed, 192 insertions(+), 14 deletions(-)
diff --git a/dlls/xactengine3_7/tests/xact3.c b/dlls/xactengine3_7/tests/xact3.c index 1b27eb9aa19..5daa18ca81b 100644 --- a/dlls/xactengine3_7/tests/xact3.c +++ b/dlls/xactengine3_7/tests/xact3.c @@ -172,6 +172,7 @@ static void WINAPI notification_cb(const XACT_NOTIFICATION *notification) data->received = TRUE; ok(notification->type == data->type, "Unexpected notification type %u\n", notification->type); + todo_wine_if(notification->type == XACTNOTIFICATIONTYPE_WAVEBANKDESTROYED) ok(notification->waveBank.pWaveBank == data->wave_bank, "Unexpected wave bank %p instead of %p\n", notification->waveBank.pWaveBank, data->wave_bank); ok(thread_id == data->thread_id, "Unexpected thread id %#lx instead of %#lx\n", thread_id, data->thread_id); @@ -248,11 +249,11 @@ static void test_notifications(void) ok(hr == S_OK, "Cannot query wave bank state, hr %#lx\n", hr); ok(state == XACT_WAVEBANKSTATE_PREPARED, "Wave bank is not in prepared state, but in %#lx\n", state);
- todo_wine ok(prepared_data.received, "The 'wave bank prepared' notification was never received\n"); + ok(prepared_data.received, "The 'wave bank prepared' notification was never received\n"); ok(!destroyed_data.received, "The 'wave bank destroyed' notification was received too early\n");
IXACT3WaveBank_Destroy(prepared_data.wave_bank); - todo_wine ok(destroyed_data.received, "The 'wave bank destroyed' notification was never received\n"); + ok(destroyed_data.received, "The 'wave bank destroyed' notification was never received\n");
CloseHandle(file); IXACT3Engine_Release(engine); diff --git a/dlls/xactengine3_7/xact_dll.c b/dlls/xactengine3_7/xact_dll.c index 98c3cf8f076..f7be480656d 100644 --- a/dlls/xactengine3_7/xact_dll.c +++ b/dlls/xactengine3_7/xact_dll.c @@ -34,6 +34,7 @@ #include "xact3.h" #endif #include "wine/debug.h" +#include "wine/rbtree.h"
WINE_DEFAULT_DEBUG_CHANNEL(xact3);
@@ -52,6 +53,42 @@ WINE_DEFAULT_DEBUG_CHANNEL(xact3); #define IXACT3WaveBankVtbl IXACTWaveBankVtbl #endif
+struct wrapper_lookup +{ + struct wine_rb_entry entry; + void *fact; + void *xact; +}; + +static int wrapper_lookup_compare(const void *key, const struct wine_rb_entry *entry) +{ + struct wrapper_lookup *lookup = WINE_RB_ENTRY_VALUE(entry, struct wrapper_lookup, entry); + + return (key > lookup->fact) - (key < lookup->fact); +} + +static void wrapper_lookup_destroy(struct wine_rb_entry *entry, void *context) +{ + struct wrapper_lookup *lookup = WINE_RB_ENTRY_VALUE(entry, struct wrapper_lookup, entry); + + HeapFree(GetProcessHeap(), 0, lookup); +} + +typedef struct _XACT3EngineImpl { + IXACT3Engine IXACT3Engine_iface; + + FACTAudioEngine *fact_engine; + + XACT_READFILE_CALLBACK pReadFile; + XACT_GETOVERLAPPEDRESULT_CALLBACK pGetOverlappedResult; + XACT_NOTIFICATION_CALLBACK notification_callback; + + void *wb_prepared_context; + void *wb_destroyed_context; + struct wine_rb_tree wb_wrapper_lookup; + CRITICAL_SECTION wb_wrapper_lookup_cs; +} XACT3EngineImpl; + typedef struct _XACT3CueImpl { IXACT3Cue IXACT3Cue_iface; FACTCue *fact_cue; @@ -543,6 +580,7 @@ typedef struct _XACT3WaveBankImpl { IXACT3WaveBank IXACT3WaveBank_iface;
FACTWaveBank *fact_wavebank; + struct _XACT3EngineImpl *engine; } XACT3WaveBankImpl;
static inline XACT3WaveBankImpl *impl_from_IXACT3WaveBank(IXACT3WaveBank *iface) @@ -553,10 +591,32 @@ static inline XACT3WaveBankImpl *impl_from_IXACT3WaveBank(IXACT3WaveBank *iface) static HRESULT WINAPI IXACT3WaveBankImpl_Destroy(IXACT3WaveBank *iface) { XACT3WaveBankImpl *This = impl_from_IXACT3WaveBank(iface); + struct wrapper_lookup *lookup; + struct wine_rb_entry *entry; HRESULT hr;
TRACE("(%p)\n", This);
+ EnterCriticalSection(&This->engine->wb_wrapper_lookup_cs); + + entry = wine_rb_get(&This->engine->wb_wrapper_lookup, This->fact_wavebank); + + if (!entry) + { + LeaveCriticalSection(&This->engine->wb_wrapper_lookup_cs); + + WARN("cannot find wave bank in wrapper lookup\n"); + } + else + { + wine_rb_remove(&This->engine->wb_wrapper_lookup, entry); + + LeaveCriticalSection(&This->engine->wb_wrapper_lookup_cs); + + lookup = WINE_RB_ENTRY_VALUE(entry, struct wrapper_lookup, entry); + HeapFree(GetProcessHeap(), 0, lookup); + } + hr = FACTWaveBank_Destroy(This->fact_wavebank); HeapFree(GetProcessHeap(), 0, This); return hr; @@ -709,16 +769,6 @@ static const IXACT3WaveBankVtbl XACT3WaveBank_Vtbl = IXACT3WaveBankImpl_GetState };
-typedef struct _XACT3EngineImpl { - IXACT3Engine IXACT3Engine_iface; - - FACTAudioEngine *fact_engine; - - XACT_READFILE_CALLBACK pReadFile; - XACT_GETOVERLAPPEDRESULT_CALLBACK pGetOverlappedResult; - XACT_NOTIFICATION_CALLBACK notification_callback; -} XACT3EngineImpl; - typedef struct wrap_readfile_struct { XACT3EngineImpl *engine; HANDLE file; @@ -792,7 +842,11 @@ static ULONG WINAPI IXACT3EngineImpl_Release(IXACT3Engine *iface) TRACE("(%p)->(): Refcount now %lu\n", This, ref);
if (!ref) + { + DeleteCriticalSection(&This->wb_wrapper_lookup_cs); + wine_rb_destroy(&This->wb_wrapper_lookup, wrapper_lookup_destroy, NULL); HeapFree(GetProcessHeap(), 0, This); + } return ref; }
@@ -832,9 +886,45 @@ static HRESULT WINAPI IXACT3EngineImpl_GetFinalMixFormat(IXACT3Engine *iface,
#endif
+static XACTNOTIFICATIONTYPE xact_notification_type_from_fact(uint8_t type) +{ + /* we can't use a switch statement, because the constants are static const + * variables, and some compilers can't deal with that */ +#define X(a) if (type == FACTNOTIFICATIONTYPE_##a) return XACTNOTIFICATIONTYPE_##a + X(CUEPREPARED); + X(CUEPLAY); + X(CUESTOP); + X(CUEDESTROYED); + X(MARKER); + X(SOUNDBANKDESTROYED); + X(WAVEBANKDESTROYED); + X(LOCALVARIABLECHANGED); + X(GLOBALVARIABLECHANGED); + X(GUICONNECTED); + X(GUIDISCONNECTED); + X(WAVEPLAY); + X(WAVESTOP); + X(WAVEBANKPREPARED); + X(WAVEBANKSTREAMING_INVALIDCONTENT); +#if XACT3_VER >= 0x0205 + X(WAVEPREPARED); + X(WAVELOOPED); + X(WAVEDESTROYED); +#endif +#undef X + + FIXME("unknown type %#x\n", type); + return 0; +} + static void FACTCALL fact_notification_cb(const FACTNotification *notification) { XACT3EngineImpl *engine = (XACT3EngineImpl *)notification->pvContext; + XACT_NOTIFICATION xnotification; + struct wrapper_lookup *lookup; + struct wine_rb_entry *entry; + + TRACE("notification %p\n", notification->pvContext);
/* Older versions of FAudio don't pass through the context */ if (!engine) @@ -843,7 +933,37 @@ static void FACTCALL fact_notification_cb(const FACTNotification *notification) return; }
- FIXME("Unsupported callback type %d\n", notification->type); + xnotification.type = xact_notification_type_from_fact(notification->type); + xnotification.timeStamp = notification->timeStamp; + + if (notification->type == XACTNOTIFICATIONTYPE_WAVEBANKPREPARED + || notification->type == XACTNOTIFICATIONTYPE_WAVEBANKDESTROYED) + { + EnterCriticalSection(&engine->wb_wrapper_lookup_cs); + entry = wine_rb_get(&engine->wb_wrapper_lookup, notification->waveBank.pWaveBank); + if (!entry) + { + WARN("cannot find wave bank in wrapper lookup\n"); + xnotification.waveBank.pWaveBank = NULL; + } + else + { + lookup = WINE_RB_ENTRY_VALUE(entry, struct wrapper_lookup, entry); + xnotification.waveBank.pWaveBank = lookup->xact; + } + LeaveCriticalSection(&engine->wb_wrapper_lookup_cs); + if (notification->type == XACTNOTIFICATIONTYPE_WAVEBANKPREPARED) + xnotification.pvContext = engine->wb_prepared_context; + else + xnotification.pvContext = engine->wb_destroyed_context; + } + else + { + FIXME("Unsupported callback type %d\n", notification->type); + return; + } + + engine->notification_callback(&xnotification); }
static HRESULT WINAPI IXACT3EngineImpl_Initialize(IXACT3Engine *iface, @@ -969,6 +1089,7 @@ static HRESULT WINAPI IXACT3EngineImpl_CreateInMemoryWaveBank(IXACT3Engine *ifac DWORD dwAllocAttributes, IXACT3WaveBank **ppWaveBank) { XACT3EngineImpl *This = impl_from_IXACT3Engine(iface); + struct wrapper_lookup *lookup; XACT3WaveBankImpl *wb; FACTWaveBank *fwb; UINT ret; @@ -992,8 +1113,32 @@ static HRESULT WINAPI IXACT3EngineImpl_CreateInMemoryWaveBank(IXACT3Engine *ifac return E_OUTOFMEMORY; }
+ lookup = HeapAlloc(GetProcessHeap(), 0, sizeof(*lookup)); + if (!lookup) + { + FACTWaveBank_Destroy(fwb); + HeapFree(GetProcessHeap(), 0, wb); + ERR("Failed to allocate wrapper_lookup!\n"); + return E_OUTOFMEMORY; + } + lookup->fact = fwb; + lookup->xact = &wb->IXACT3WaveBank_iface; + + EnterCriticalSection(&This->wb_wrapper_lookup_cs); + + ret = wine_rb_put(&This->wb_wrapper_lookup, lookup->fact, &lookup->entry); + + LeaveCriticalSection(&This->wb_wrapper_lookup_cs); + + if (ret) + { + WARN("wrapper_lookup already present in the tree??\n"); + HeapFree(GetProcessHeap(), 0, lookup); + } + wb->IXACT3WaveBank_iface.lpVtbl = &XACT3WaveBank_Vtbl; wb->fact_wavebank = fwb; + wb->engine = This; *ppWaveBank = &wb->IXACT3WaveBank_iface;
TRACE("Created in-memory WaveBank: %p\n", wb); @@ -1007,6 +1152,7 @@ static HRESULT WINAPI IXACT3EngineImpl_CreateStreamingWaveBank(IXACT3Engine *ifa { XACT3EngineImpl *This = impl_from_IXACT3Engine(iface); FACTStreamingParameters fakeParms; + struct wrapper_lookup *lookup; wrap_readfile_struct *fake; XACT3WaveBankImpl *wb; FACTWaveBank *fwb; @@ -1040,8 +1186,32 @@ static HRESULT WINAPI IXACT3EngineImpl_CreateStreamingWaveBank(IXACT3Engine *ifa return E_OUTOFMEMORY; }
+ lookup = HeapAlloc(GetProcessHeap(), 0, sizeof(*lookup)); + if (!lookup) + { + FACTWaveBank_Destroy(fwb); + HeapFree(GetProcessHeap(), 0, wb); + ERR("Failed to allocate wrapper_lookup!\n"); + return E_OUTOFMEMORY; + } + lookup->fact = fwb; + lookup->xact = &wb->IXACT3WaveBank_iface; + + EnterCriticalSection(&This->wb_wrapper_lookup_cs); + + ret = wine_rb_put(&This->wb_wrapper_lookup, lookup->fact, &lookup->entry); + + LeaveCriticalSection(&This->wb_wrapper_lookup_cs); + + if (ret) + { + WARN("wrapper_lookup already present in the tree??\n"); + HeapFree(GetProcessHeap(), 0, lookup); + } + wb->IXACT3WaveBank_iface.lpVtbl = &XACT3WaveBank_Vtbl; wb->fact_wavebank = fwb; + wb->engine = This; *ppWaveBank = &wb->IXACT3WaveBank_iface;
TRACE("Created streaming WaveBank: %p\n", wb); @@ -1198,7 +1368,6 @@ static inline void unwrap_notificationdesc(FACTNotificationDescription *fd,
/* We have to unwrap the FACT object first! */ fd->flags = xd->flags; - fd->pvContext = xd->pvContext; if (flags & NOTIFY_cueIndex) fd->cueIndex = xd->cueIndex; #if XACT3_VER >= 0x0205 @@ -1245,6 +1414,11 @@ static HRESULT WINAPI IXACT3EngineImpl_RegisterNotification(IXACT3Engine *iface,
TRACE("(%p)->(%p)\n", This, pNotificationDesc);
+ if (pNotificationDesc->type == XACTNOTIFICATIONTYPE_WAVEBANKPREPARED) + This->wb_prepared_context = pNotificationDesc->pvContext; + else if (pNotificationDesc->type == XACTNOTIFICATIONTYPE_WAVEBANKDESTROYED) + This->wb_destroyed_context = pNotificationDesc->pvContext; + unwrap_notificationdesc(&fdesc, pNotificationDesc); fdesc.pvContext = This; return FACTAudioEngine_RegisterNotification(This->fact_engine, &fdesc); @@ -1438,6 +1612,9 @@ static HRESULT WINAPI XACT3CF_CreateInstance(IClassFactory *iface, IUnknown *pOu return hr; }
+ wine_rb_init(&object->wb_wrapper_lookup, wrapper_lookup_compare); + InitializeCriticalSection(&object->wb_wrapper_lookup_cs); + return hr; }
On Thu Jul 14 13:07:09 2022 +0000, Giovanni Mascellani wrote:
changed this line in [version 6 of the diff](/wine/wine/-/merge_requests/398/diffs?diff_id=5050&start_sha=bb5cc1a48526a61dcb297cccd947d5dedcaf2985#72174166dce765cea1dd4394a588e3cde6f7b9e8_67_0)
Done in the new revision.
On Thu Jul 14 18:35:05 2022 +0000, **** wrote:
Zebediah Figura replied on the mailing list:
On 7/14/22 08:07, Giovanni Mascellani wrote: > From: Giovanni Mascellani <gmascellani@codeweavers.com> > > The notifications are not sent immediately, but pushed to a queue > and sent at the next DoWork() call. This seems to correspond to what > happens on Windows. > > Corresponding to upstream commit 9e53dbeebfdd8d0f23144b8b1aa895bca2727977. > > Signed-off-by: Giovanni Mascellani <gmascellani@codeweavers.com> > --- > libs/faudio/src/FACT.c | 26 ++++++++++++++++++++++++++ > libs/faudio/src/FACT_internal.h | 1 + > 2 files changed, 27 insertions(+) > Can we please not do this? It's mean enough to distributions to bundle software, but it's worse when we're bundling local changes as well. Can we just wait for a new version to be released and then import that? _______________________________________________ wine-gitlab mailing list -- wine-gitlab@winehq.org To unsubscribe send an email to wine-gitlab-leave@winehq.org
I specifically asked Alexandre and he said it's ok. In general I agree we don't want to fork from upstream, but since that change was already accepted upstream it's not a fork. The next time we sync from upstream the change will be there anyway and we're back in the mainline. Adding this change now allows me to submit this PR now instead of waiting a month, and I can't see any drawbacks.
On 7/15/22 02:11, Giovanni Mascellani (@giomasce) wrote:
On Thu Jul 14 18:35:05 2022 +0000, **** wrote:
Zebediah Figura replied on the mailing list:
On 7/14/22 08:07, Giovanni Mascellani wrote: > From: Giovanni Mascellani <gmascellani@codeweavers.com> > > The notifications are not sent immediately, but pushed to a queue > and sent at the next DoWork() call. This seems to correspond to what > happens on Windows. > > Corresponding to upstream commit 9e53dbeebfdd8d0f23144b8b1aa895bca2727977. > > Signed-off-by: Giovanni Mascellani <gmascellani@codeweavers.com> > --- > libs/faudio/src/FACT.c | 26 ++++++++++++++++++++++++++ > libs/faudio/src/FACT_internal.h | 1 + > 2 files changed, 27 insertions(+) > Can we please not do this? It's mean enough to distributions to bundle software, but it's worse when we're bundling local changes as well. Can we just wait for a new version to be released and then import that? _______________________________________________ wine-gitlab mailing list -- wine-gitlab@winehq.org To unsubscribe send an email to wine-gitlab-leave@winehq.org
I specifically asked Alexandre and he said it's ok.
Yes, this petition is directed as much at Alexandre as at anyone else.
In general I agree we don't want to fork from upstream, but since that change was already accepted upstream it's not a fork. The next time we sync from upstream the change will be there anyway and we're back in the mainline. Adding this change now allows me to submit this PR now instead of waiting a month, and I can't see any drawbacks.
With this change, our bundled FAudio does not correspond to any version of FAudio upstream, release or not, which makes things difficult for distributions. If we want to update to unreleased versions, can we please at least update the whole tree to e3c444e4f819, rather than cherry-picking?
With this change, our bundled FAudio does not correspond to any version of FAudio upstream, release or not, which makes things difficult for distributions. If we want to update to unreleased versions, can we please at least update the whole tree to e3c444e4f819, rather than cherry-picking?
I fail to see why this is a problem. Distros can simply continue shipping the current version, and upgrade next month. They won't get the bug fix until they upgrade, but I don't see how delaying the commit would make any difference.
On 7/15/22 12:27, Alexandre Julliard (@julliard) wrote:
With this change, our bundled FAudio does not correspond to any version of FAudio upstream, release or not, which makes things difficult for distributions. If we want to update to unreleased versions, can we please at least update the whole tree to e3c444e4f819, rather than cherry-picking?
I fail to see why this is a problem. Distros can simply continue shipping the current version, and upgrade next month. They won't get the bug fix until they upgrade, but I don't see how delaying the commit would make any difference.
Not all distributions are shipping external FAudio (yet), and those that aren't typically want to track the exact upstream version that a bundled clone is matching. That's not possible if we are selectively cherry-picking patches like this.
Is it that much of an inconvenience just to update the whole tree?
Is it that much of an inconvenience just to update the whole tree?
I don't have a problem with that, if you think it's preferable.
I've been maintaining packages in Debian for ten years and as far as I know it's quite common to cherry pick not-yet-released commits when needed. BTW, I have no problem updating the whole tree, but that's not a released version anyway, unless we wait for it to be released (and I'd hope we don't), so I don't see how that solves your problem. As I said, I have no problem with it anyway, so will update the MR in that sense.