diff --git a/dlls/xaudio2_7/xaudio_dll.c b/dlls/xaudio2_7/xaudio_dll.c index 346e15d1eae..b13436c01f2 100644 --- a/dlls/xaudio2_7/xaudio_dll.c +++ b/dlls/xaudio2_7/xaudio_dll.c @@ -71,16 +71,23 @@ HRESULT WINAPI DllUnregisterServer(void) } typedef struct { + IXAudio27 IXAudio27_iface; IXAudio2 IXAudio2_iface; LONG ref; + + DWORD version; } IXAudio2Impl; -/*** IUnknown methods ***/ static inline IXAudio2Impl *impl_from_IXAudio2(IXAudio2 *iface) { return CONTAINING_RECORD(iface, IXAudio2Impl, IXAudio2_iface); } +static inline IXAudio2Impl *impl_from_IXAudio27(IXAudio27 *iface) +{ + return CONTAINING_RECORD(iface, IXAudio2Impl, IXAudio27_iface); +} + static HRESULT WINAPI IXAudio2Impl_QueryInterface(IXAudio2 *iface, REFIID riid, void **ppvObject) { @@ -88,13 +95,16 @@ static HRESULT WINAPI IXAudio2Impl_QueryInterface(IXAudio2 *iface, REFIID riid, TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), ppvObject); - *ppvObject = NULL; - if(IsEqualGUID(riid, &IID_IUnknown) || - IsEqualGUID(riid, &IID_IXAudio2)) - { - IXAudio2_AddRef(iface); - *ppvObject = iface; + IsEqualGUID(riid, &IID_IXAudio2)) + *ppvObject = &This->IXAudio2_iface; + else if(IsEqualGUID(riid, &IID_IXAudio27)) + *ppvObject = &This->IXAudio27_iface; + else + *ppvObject = NULL; + + if(*ppvObject){ + IUnknown_AddRef((IUnknown*)*ppvObject); return S_OK; } @@ -106,10 +116,9 @@ static HRESULT WINAPI IXAudio2Impl_QueryInterface(IXAudio2 *iface, REFIID riid, static ULONG WINAPI IXAudio2Impl_AddRef(IXAudio2 *iface) { IXAudio2Impl *This = impl_from_IXAudio2(iface); - - TRACE("(%p)->()\n", This); - - return InterlockedIncrement(&This->ref); + ULONG ref = InterlockedIncrement(&This->ref); + TRACE("(%p)->(): Refcount now %u\n", This, ref); + return ref; } static ULONG WINAPI IXAudio2Impl_Release(IXAudio2 *iface) @@ -117,7 +126,7 @@ static ULONG WINAPI IXAudio2Impl_Release(IXAudio2 *iface) IXAudio2Impl *This = impl_from_IXAudio2(iface); ULONG ref = InterlockedDecrement(&This->ref); - TRACE("(%p)->()\n", This); + TRACE("(%p)->(): Refcount now %u\n", This, ref); if (!ref) HeapFree(GetProcessHeap(), 0, This); @@ -125,37 +134,6 @@ static ULONG WINAPI IXAudio2Impl_Release(IXAudio2 *iface) return ref; } -/*** IXAudio2 methods ***/ -static HRESULT WINAPI IXAudio2Impl_GetDeviceCount(IXAudio2 *iface, - UINT32 *pCount) -{ - IXAudio2Impl *This = impl_from_IXAudio2(iface); - - FIXME("(%p)->(%p): stub!\n", This, pCount); - - return E_NOTIMPL; -} - -static HRESULT WINAPI IXAudio2Impl_GetDeviceDetails(IXAudio2 *iface, - UINT32 index, XAUDIO2_DEVICE_DETAILS *pDeviceDetails) -{ - IXAudio2Impl *This = impl_from_IXAudio2(iface); - - FIXME("(%p)->(%u, %p): stub!\n", This, index, pDeviceDetails); - - return E_NOTIMPL; -} - -static HRESULT WINAPI IXAudio2Impl_Initialize(IXAudio2 *iface, UINT32 flags, - XAUDIO2_PROCESSOR processor) -{ - IXAudio2Impl *This = impl_from_IXAudio2(iface); - - FIXME("(%p)->(%u, %u): stub!\n", This, flags, processor); - - return S_OK; -} - static HRESULT WINAPI IXAudio2Impl_RegisterForCallbacks(IXAudio2 *iface, IXAudio2EngineCallback *pCallback) { @@ -182,7 +160,7 @@ static HRESULT WINAPI IXAudio2Impl_CreateSourceVoice(IXAudio2 *iface, { IXAudio2Impl *This = impl_from_IXAudio2(iface); - FIXME("(%p)->(%p, %p, %u, %f, %p, %p, %p): stub!\n", This, ppSourceVoice, + FIXME("(%p)->(%p, %p, 0x%x, %f, %p, %p, %p): stub!\n", This, ppSourceVoice, pSourceFormat, flags, maxFrequencyRatio, pCallback, pSendList, pEffectChain); @@ -197,7 +175,7 @@ static HRESULT WINAPI IXAudio2Impl_CreateSubmixVoice(IXAudio2 *iface, { IXAudio2Impl *This = impl_from_IXAudio2(iface); - FIXME("(%p)->(%p, %u, %u, %u, %u, %p, %p): stub!\n", This, ppSubmixVoice, + FIXME("(%p)->(%p, %u, %u, 0x%x, %u, %p, %p): stub!\n", This, ppSubmixVoice, inputChannels, inputSampleRate, flags, processingStage, pSendList, pEffectChain); @@ -206,15 +184,17 @@ static HRESULT WINAPI IXAudio2Impl_CreateSubmixVoice(IXAudio2 *iface, static HRESULT WINAPI IXAudio2Impl_CreateMasteringVoice(IXAudio2 *iface, IXAudio2MasteringVoice **ppMasteringVoice, UINT32 inputChannels, - UINT32 inputSampleRate, UINT32 flags, UINT32 deviceIndex, - const XAUDIO2_EFFECT_CHAIN *pEffectChain) + UINT32 inputSampleRate, UINT32 flags, const WCHAR *deviceId, + const XAUDIO2_EFFECT_CHAIN *pEffectChain, + AUDIO_STREAM_CATEGORY streamCategory) { IXAudio2Impl *This = impl_from_IXAudio2(iface); - FIXME("(%p)->(%p, %u, %u, %u, %u, %p): stub!\n", This, ppMasteringVoice, - inputChannels, inputSampleRate, flags, deviceIndex, pEffectChain); + FIXME("(%p)->(%p, %u, %u, 0x%x, %s, %p, 0x%x): stub!\n", This, + ppMasteringVoice, inputChannels, inputSampleRate, flags, + wine_dbgstr_w(deviceId), pEffectChain, streamCategory); - return S_OK; + return E_NOTIMPL; } static HRESULT WINAPI IXAudio2Impl_StartEngine(IXAudio2 *iface) @@ -238,7 +218,7 @@ static HRESULT WINAPI IXAudio2Impl_CommitChanges(IXAudio2 *iface, { IXAudio2Impl *This = impl_from_IXAudio2(iface); - FIXME("(%p)->(%u): stub!\n", This, operationSet); + FIXME("(%p)->(0x%x): stub!\n", This, operationSet); return E_NOTIMPL; } @@ -260,14 +240,12 @@ static void WINAPI IXAudio2Impl_SetDebugConfiguration(IXAudio2 *iface, FIXME("(%p)->(%p, %p): stub!\n", This, pDebugConfiguration, pReserved); } +/* XAudio2 2.8 */ static const IXAudio2Vtbl XAudio2_Vtbl = { IXAudio2Impl_QueryInterface, IXAudio2Impl_AddRef, IXAudio2Impl_Release, - IXAudio2Impl_GetDeviceCount, - IXAudio2Impl_GetDeviceDetails, - IXAudio2Impl_Initialize, IXAudio2Impl_RegisterForCallbacks, IXAudio2Impl_UnregisterForCallbacks, IXAudio2Impl_CreateSourceVoice, @@ -280,6 +258,154 @@ static const IXAudio2Vtbl XAudio2_Vtbl = IXAudio2Impl_SetDebugConfiguration }; +static HRESULT WINAPI XA27_QueryInterface(IXAudio27 *iface, REFIID riid, + void **ppvObject) +{ + IXAudio2Impl *This = impl_from_IXAudio27(iface); + return IXAudio2Impl_QueryInterface(&This->IXAudio2_iface, riid, ppvObject); +} + +static ULONG WINAPI XA27_AddRef(IXAudio27 *iface) +{ + IXAudio2Impl *This = impl_from_IXAudio27(iface); + return IXAudio2Impl_AddRef(&This->IXAudio2_iface); +} + +static ULONG WINAPI XA27_Release(IXAudio27 *iface) +{ + IXAudio2Impl *This = impl_from_IXAudio27(iface); + return IXAudio2Impl_Release(&This->IXAudio2_iface); +} + +static HRESULT WINAPI XA27_GetDeviceCount(IXAudio27 *iface, UINT32 *pCount) +{ + IXAudio2Impl *This = impl_from_IXAudio27(iface); + TRACE("(%p)->(%p)\n", This, pCount); + return E_NOTIMPL; +} + +static HRESULT WINAPI XA27_GetDeviceDetails(IXAudio27 *iface, UINT32 index, + XAUDIO2_DEVICE_DETAILS *pDeviceDetails) +{ + IXAudio2Impl *This = impl_from_IXAudio27(iface); + TRACE("(%p)->(%u, %p)\n", This, index, pDeviceDetails); + return E_NOTIMPL; +} + +static HRESULT WINAPI XA27_Initialize(IXAudio27 *iface, UINT32 flags, + XAUDIO2_PROCESSOR processor) +{ + IXAudio2Impl *This = impl_from_IXAudio27(iface); + TRACE("(%p)->(0x%x, 0x%x)\n", This, flags, processor); + return E_NOTIMPL; +} + +static HRESULT WINAPI XA27_RegisterForCallbacks(IXAudio27 *iface, + IXAudio2EngineCallback *pCallback) +{ + IXAudio2Impl *This = impl_from_IXAudio27(iface); + return IXAudio2Impl_RegisterForCallbacks(&This->IXAudio2_iface, pCallback); +} + +static void WINAPI XA27_UnregisterForCallbacks(IXAudio27 *iface, + IXAudio2EngineCallback *pCallback) +{ + IXAudio2Impl *This = impl_from_IXAudio27(iface); + IXAudio2Impl_UnregisterForCallbacks(&This->IXAudio2_iface, pCallback); +} + +static HRESULT WINAPI XA27_CreateSourceVoice(IXAudio27 *iface, + IXAudio2SourceVoice **ppSourceVoice, const WAVEFORMATEX *pSourceFormat, + UINT32 flags, float maxFrequencyRatio, + IXAudio2VoiceCallback *pCallback, const XAUDIO2_VOICE_SENDS *pSendList, + const XAUDIO2_EFFECT_CHAIN *pEffectChain) +{ + IXAudio2Impl *This = impl_from_IXAudio27(iface); + return IXAudio2Impl_CreateSourceVoice(&This->IXAudio2_iface, ppSourceVoice, + pSourceFormat, flags, maxFrequencyRatio, pCallback, pSendList, + pEffectChain); +} + +static HRESULT WINAPI XA27_CreateSubmixVoice(IXAudio27 *iface, + IXAudio2SubmixVoice **ppSubmixVoice, UINT32 inputChannels, + UINT32 inputSampleRate, UINT32 flags, UINT32 processingStage, + const XAUDIO2_VOICE_SENDS *pSendList, + const XAUDIO2_EFFECT_CHAIN *pEffectChain) +{ + IXAudio2Impl *This = impl_from_IXAudio27(iface); + return IXAudio2Impl_CreateSubmixVoice(&This->IXAudio2_iface, ppSubmixVoice, + inputChannels, inputSampleRate, flags, processingStage, pSendList, + pEffectChain); +} + +static HRESULT WINAPI XA27_CreateMasteringVoice(IXAudio27 *iface, + IXAudio2MasteringVoice **ppMasteringVoice, UINT32 inputChannels, + UINT32 inputSampleRate, UINT32 flags, UINT32 deviceIndex, + const XAUDIO2_EFFECT_CHAIN *pEffectChain) +{ + IXAudio2Impl *This = impl_from_IXAudio27(iface); + TRACE("(%p)->(%p, %u, %u, 0x%x, %u, %p)\n", This, ppMasteringVoice, + inputChannels, inputSampleRate, flags, deviceIndex, + pEffectChain); + /* TODO: Convert DeviceIndex to DeviceId */ + return IXAudio2Impl_CreateMasteringVoice(&This->IXAudio2_iface, + ppMasteringVoice, inputChannels, inputSampleRate, flags, 0, + pEffectChain, AudioCategory_GameEffects); +} + +static HRESULT WINAPI XA27_StartEngine(IXAudio27 *iface) +{ + IXAudio2Impl *This = impl_from_IXAudio27(iface); + return IXAudio2Impl_StartEngine(&This->IXAudio2_iface); +} + +static void WINAPI XA27_StopEngine(IXAudio27 *iface) +{ + IXAudio2Impl *This = impl_from_IXAudio27(iface); + return IXAudio2Impl_StopEngine(&This->IXAudio2_iface); +} + +static HRESULT WINAPI XA27_CommitChanges(IXAudio27 *iface, UINT32 operationSet) +{ + IXAudio2Impl *This = impl_from_IXAudio27(iface); + return IXAudio2Impl_CommitChanges(&This->IXAudio2_iface, operationSet); +} + +static void WINAPI XA27_GetPerformanceData(IXAudio27 *iface, + XAUDIO2_PERFORMANCE_DATA *pPerfData) +{ + IXAudio2Impl *This = impl_from_IXAudio27(iface); + return IXAudio2Impl_GetPerformanceData(&This->IXAudio2_iface, pPerfData); +} + +static void WINAPI XA27_SetDebugConfiguration(IXAudio27 *iface, + const XAUDIO2_DEBUG_CONFIGURATION *pDebugConfiguration, + void *pReserved) +{ + IXAudio2Impl *This = impl_from_IXAudio27(iface); + return IXAudio2Impl_SetDebugConfiguration(&This->IXAudio2_iface, + pDebugConfiguration, pReserved); +} + +static const IXAudio27Vtbl XAudio27_Vtbl = { + XA27_QueryInterface, + XA27_AddRef, + XA27_Release, + XA27_GetDeviceCount, + XA27_GetDeviceDetails, + XA27_Initialize, + XA27_RegisterForCallbacks, + XA27_UnregisterForCallbacks, + XA27_CreateSourceVoice, + XA27_CreateSubmixVoice, + XA27_CreateMasteringVoice, + XA27_StartEngine, + XA27_StopEngine, + XA27_CommitChanges, + XA27_GetPerformanceData, + XA27_SetDebugConfiguration +}; + static HRESULT WINAPI XAudio2CF_QueryInterface(IClassFactory *iface, REFIID riid, void **ppobj) { if(IsEqualGUID(riid, &IID_IUnknown) @@ -322,8 +448,14 @@ static HRESULT WINAPI XAudio2CF_CreateInstance(IClassFactory *iface, IUnknown *p if(!object) return E_OUTOFMEMORY; + object->IXAudio27_iface.lpVtbl = &XAudio27_Vtbl; object->IXAudio2_iface.lpVtbl = &XAudio2_Vtbl; + if(IsEqualGUID(riid, &IID_IXAudio27)) + object->version = 27; + else + object->version = 28; + hr = IXAudio2_QueryInterface(&object->IXAudio2_iface, riid, ppobj); if(FAILED(hr)) HeapFree(GetProcessHeap(), 0, object); diff --git a/include/audiosessiontypes.h b/include/audiosessiontypes.h index b9435f127fb..2f785743539 100644 --- a/include/audiosessiontypes.h +++ b/include/audiosessiontypes.h @@ -45,4 +45,16 @@ typedef enum _AudioSessionState AudioSessionStateExpired, } AudioSessionState; +typedef enum _AUDIO_STREAM_CATEGORY +{ + AudioCategory_Other = 0, + AudioCategory_ForegroundOnlyMedia, + AudioCategory_BackgroundCapableMedia, + AudioCategory_Communications, + AudioCategory_Alerts, + AudioCategory_SoundEffects, + AudioCategory_GameEffects, + AudioCategory_GameMedia +} AUDIO_STREAM_CATEGORY; + #endif diff --git a/include/xaudio2.idl b/include/xaudio2.idl index 71f0a34dc92..9213f4180b9 100644 --- a/include/xaudio2.idl +++ b/include/xaudio2.idl @@ -19,6 +19,8 @@ import "unknwn.idl"; import "mmdeviceapi.idl"; +import "audiosessiontypes.h"; + [ uuid(5a508685-a254-4fba-9b82-9a24b00306af) ] @@ -328,7 +330,9 @@ typedef struct XAUDIO2_VOICE_STATE [ local ] -interface IXAudio2SourceVoice : IXAudio2Voice +/* XAudio2 2.7's IXAudio2SourceVoice interface. Actually called + * IXAudio2SourceVoice in the Jun 2010 DX SDK */ +interface IXAudio27SourceVoice : IXAudio2Voice { HRESULT Start( [in, defaultvalue(0)] UINT32 Flags, @@ -359,6 +363,41 @@ interface IXAudio2SourceVoice : IXAudio2Voice HRESULT SetSourceSampleRate([in] UINT32 NewSourceSampleRate); } +[ + local +] +/* XAudio2 2.8's IXAudio2SourceVoice interface. */ +interface IXAudio2SourceVoice : IXAudio2Voice +{ + HRESULT Start( + [in, defaultvalue(0)] UINT32 Flags, + [in, defaultvalue(XAUDIO2_COMMIT_NOW)] UINT32 OperationSet); + + HRESULT Stop( + [in, defaultvalue(0)] UINT32 Flags, + [in, defaultvalue(XAUDIO2_COMMIT_NOW)] UINT32 OperationSet); + + HRESULT SubmitSourceBuffer( + [in] const XAUDIO2_BUFFER* pBuffer, + [in, defaultvalue(NULL)] const XAUDIO2_BUFFER_WMA* pBufferWMA); + + HRESULT FlushSourceBuffers(); + + HRESULT Discontinuity(); + + HRESULT ExitLoop([in, defaultvalue(XAUDIO2_COMMIT_NOW)] UINT32 OperationSet); + + void GetState([out] XAUDIO2_VOICE_STATE* pVoiceState, [in, defaultvalue(0)] UINT32 Flags); + + HRESULT SetFrequencyRatio( + [in] float Ratio, + [in, defaultvalue(XAUDIO2_COMMIT_NOW)] UINT32 OperationSet); + + void GetFrequencyRatio([out] float* pRatio); + + HRESULT SetSourceSampleRate([in] UINT32 NewSourceSampleRate); +} + [ local ] @@ -371,6 +410,8 @@ interface IXAudio2SubmixVoice : IXAudio2Voice ] interface IXAudio2MasteringVoice : IXAudio2Voice { + /* not present in XAudio2 2.7 */ + void GetChannelMask([out] DWORD *pChannelMask); } [ @@ -410,7 +451,9 @@ typedef struct XAUDIO2_DEBUG_CONFIGURATION object, uuid(8bcf1f58-9fe7-4583-8ac6-e2adc465c8bb), ] -interface IXAudio2 : IUnknown +/* XAudio2 2.7's IXAudio2 interface. Actually called IXAudio2 in the Jun 2010 + * DX SDK */ +interface IXAudio27 : IUnknown { HRESULT GetDeviceCount([out] UINT32* pCount); @@ -465,6 +508,57 @@ interface IXAudio2 : IUnknown [in, defaultvalue(NULL)] void* pReserved); } +[ + object, + uuid(60d8dac8-5aa1-4e8e-b597-2f5e2883d484), +] +/* XAudio2 2.8's IXAudio2 interface. */ +interface IXAudio2 : IUnknown +{ + HRESULT RegisterForCallbacks([in] IXAudio2EngineCallback* pCallback); + + void UnregisterForCallbacks([in] IXAudio2EngineCallback* pCallback); + + HRESULT CreateSourceVoice( + [out] IXAudio2SourceVoice** ppSourceVoice, + [in] const WAVEFORMATEX* pSourceFormat, + [in, defaultvalue(0)] UINT32 Flags, + [in, defaultvalue(XAUDIO2_DEFAULT_FREQ_RATIO)] float MaxFrequencyRatio, + [in, defaultvalue(NULL)] IXAudio2VoiceCallback* pCallback, + [in, defaultvalue(NULL)] const XAUDIO2_VOICE_SENDS* pSendList, + [in, defaultvalue(NULL)] const XAUDIO2_EFFECT_CHAIN* pEffectChain); + + HRESULT CreateSubmixVoice( + [out] IXAudio2SubmixVoice** ppSubmixVoice, + [in] UINT32 InputChannels, + [in] UINT32 InputSampleRate, + [in, defaultvalue(0)] UINT32 Flags, + [in, defaultvalue(0)] UINT32 ProcessingStage, + [in, defaultvalue(NULL)] const XAUDIO2_VOICE_SENDS* pSendList, + [in, defaultvalue(NULL)] const XAUDIO2_EFFECT_CHAIN* pEffectChain); + + HRESULT CreateMasteringVoice( + [out] IXAudio2MasteringVoice** ppMasteringVoice, + [in, defaultvalue(XAUDIO2_DEFAULT_CHANNELS)] UINT32 InputChannels, + [in, defaultvalue(XAUDIO2_DEFAULT_SAMPLERATE)] UINT32 InputSampleRate, + [in, defaultvalue(0)] UINT32 Flags, + [in, defaultvalue(NULL)] LPCWSTR DeviceId, + [in, defaultvalue(NULL)] const XAUDIO2_EFFECT_CHAIN* pEffectChain, + [in, defaultvalue(AudioCategory_GameEffects)] AUDIO_STREAM_CATEGORY StreamCategory); + + HRESULT StartEngine(); + + void StopEngine(); + + HRESULT CommitChanges([in] UINT32 OperationSet); + + void GetPerformanceData([out] XAUDIO2_PERFORMANCE_DATA* pPerfData); + + [local] void SetDebugConfiguration( + [in] const XAUDIO2_DEBUG_CONFIGURATION* pDebugConfiguration, + [in, defaultvalue(NULL)] void* pReserved); +} + const UINT32 XAUDIO2_DEBUG_ENGINE = 1; const UINT32 XAUDIO2_VOICE_NOPITCH = 2; const UINT32 XAUDIO2_VOICE_NOSRC = 4; @@ -497,30 +591,4 @@ cpp_quote("inline static float XAudio2CutoffFrequencyToRadians(float cutofffreq, cpp_quote("inline static float XAudio2RadiansToCutoffFrequency(float radians, float samplerate) { return samplerate * asinf(radians/2.0f) / (float)M_PI; }") cpp_quote("#endif") -cpp_quote("#ifdef __cplusplus") -cpp_quote("inline static HRESULT XAudio2Create(IXAudio2** pxaudio2, UINT32 flags = 0, XAUDIO2_PROCESSOR processor = XAUDIO2_DEFAULT_PROCESSOR) {") -cpp_quote(" IXAudio2* xaudio2;") -cpp_quote(" HRESULT hr = CoCreateInstance(__uuidof(XAudio2), NULL, CLSCTX_INPROC_SERVER, __uuidof(IXAudio2), (void**)&xaudio2);") -cpp_quote(" if (SUCCEEDED(hr)) {") -cpp_quote(" hr = xaudio2->Initialize(flags, processor);") -cpp_quote(" if (SUCCEEDED(hr))") -cpp_quote(" *pxaudio2 = xaudio2;") -cpp_quote(" else") -cpp_quote(" xaudio2->Release();") -cpp_quote(" }") -cpp_quote(" return hr;") -cpp_quote("}") -cpp_quote("#else") -cpp_quote("inline static HRESULT XAudio2Create(IXAudio2** pxaudio2, UINT32 flags, XAUDIO2_PROCESSOR processor) {") -cpp_quote(" IXAudio2* xaudio2;") -cpp_quote(" HRESULT hr = CoCreateInstance(&CLSID_XAudio2, NULL, CLSCTX_INPROC_SERVER, &IID_IXAudio2, (void**)&xaudio2);") -cpp_quote(" if (SUCCEEDED(hr)) {") -cpp_quote(" hr = xaudio2->lpVtbl->Initialize(xaudio2, flags, processor);") -cpp_quote(" if (SUCCEEDED(hr))") -cpp_quote(" *pxaudio2 = xaudio2;") -cpp_quote(" else") -cpp_quote(" xaudio2->lpVtbl->Release(xaudio2);") -cpp_quote(" }") -cpp_quote(" return hr;") -cpp_quote("}") -cpp_quote("#endif") +cpp_quote("HRESULT WINAPI XAudio2Create(IXAudio2** pxaudio2, UINT32 flags, XAUDIO2_PROCESSOR processor);")