[QUARTZ]
[reactos.git] / reactos / dll / directx / quartz / dsoundrender.c
index aae7e68..1d87a7f 100644 (file)
@@ -32,6 +32,7 @@
 #include "evcode.h"
 #include "strmif.h"
 #include "dsound.h"
+#include "amaudio.h"
 
 #include "wine/unicode.h"
 #include "wine/debug.h"
@@ -45,12 +46,14 @@ static const IPinVtbl DSoundRender_InputPin_Vtbl;
 static const IBasicAudioVtbl IBasicAudio_Vtbl;
 static const IReferenceClockVtbl IReferenceClock_Vtbl;
 static const IMediaSeekingVtbl IMediaSeeking_Vtbl;
+static const IAMDirectSoundVtbl IAMDirectSound_Vtbl;
 
 typedef struct DSoundRenderImpl
 {
     const IBaseFilterVtbl * lpVtbl;
     const IBasicAudioVtbl *IBasicAudio_vtbl;
     const IReferenceClockVtbl *IReferenceClock_vtbl;
+    const IAMDirectSoundVtbl *IAMDirectSound_vtbl;
 
     LONG refCount;
     CRITICAL_SECTION csFilter;
@@ -233,11 +236,12 @@ static HRESULT DSoundRender_SendSampleData(DSoundRenderImpl* This, const BYTE *d
 
 static HRESULT DSoundRender_Sample(LPVOID iface, IMediaSample * pSample)
 {
-    DSoundRenderImpl *This = (DSoundRenderImpl *)iface;
+    DSoundRenderImpl *This = iface;
     LPBYTE pbSrcStream = NULL;
     long cbSrcStream = 0;
     REFERENCE_TIME tStart, tStop;
     HRESULT hr;
+    AM_MEDIA_TYPE *amt;
 
     TRACE("%p %p\n", iface, pSample);
 
@@ -259,6 +263,39 @@ static HRESULT DSoundRender_Sample(LPVOID iface, IMediaSample * pSample)
         return VFW_E_WRONG_STATE;
     }
 
+    if (IMediaSample_GetMediaType(pSample, &amt) == S_OK)
+    {
+        AM_MEDIA_TYPE *orig = &This->pInputPin->pin.mtCurrent;
+        WAVEFORMATEX *origfmt = (WAVEFORMATEX *)orig->pbFormat;
+        WAVEFORMATEX *newfmt = (WAVEFORMATEX *)amt->pbFormat;
+
+        if (origfmt->wFormatTag == newfmt->wFormatTag &&
+            origfmt->nChannels == newfmt->nChannels &&
+            origfmt->nBlockAlign == newfmt->nBlockAlign &&
+            origfmt->wBitsPerSample == newfmt->wBitsPerSample &&
+            origfmt->cbSize ==  newfmt->cbSize)
+        {
+            if (origfmt->nSamplesPerSec != newfmt->nSamplesPerSec)
+            {
+                hr = IDirectSoundBuffer_SetFrequency(This->dsbuffer,
+                                                     newfmt->nSamplesPerSec);
+                if (FAILED(hr))
+                {
+                    LeaveCriticalSection(&This->csFilter);
+                    return VFW_E_TYPE_NOT_ACCEPTED;
+                }
+                FreeMediaType(orig);
+                CopyMediaType(orig, amt);
+                IMediaSample_SetMediaType(pSample, NULL);
+            }
+        }
+        else
+        {
+            LeaveCriticalSection(&This->csFilter);
+            return VFW_E_TYPE_NOT_ACCEPTED;
+        }
+    }
+
     SetEvent(This->state_change);
 
     hr = IMediaSample_GetPointer(pSample, &pbSrcStream);
@@ -370,6 +407,7 @@ HRESULT DSoundRender_create(IUnknown * pUnkOuter, LPVOID * ppv)
     pDSoundRender->lpVtbl = &DSoundRender_Vtbl;
     pDSoundRender->IBasicAudio_vtbl = &IBasicAudio_Vtbl;
     pDSoundRender->IReferenceClock_vtbl = &IReferenceClock_Vtbl;
+    pDSoundRender->IAMDirectSound_vtbl = &IAMDirectSound_Vtbl;
     pDSoundRender->refCount = 1;
     InitializeCriticalSection(&pDSoundRender->csFilter);
     pDSoundRender->csFilter.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": DSoundRenderImpl.csFilter");
@@ -404,7 +442,7 @@ HRESULT DSoundRender_create(IUnknown * pUnkOuter, LPVOID * ppv)
             return HRESULT_FROM_WIN32(GetLastError());
         }
 
-        *ppv = (LPVOID)pDSoundRender;
+        *ppv = pDSoundRender;
     }
     else
     {
@@ -426,19 +464,21 @@ static HRESULT WINAPI DSoundRender_QueryInterface(IBaseFilter * iface, REFIID ri
     *ppv = NULL;
 
     if (IsEqualIID(riid, &IID_IUnknown))
-        *ppv = (LPVOID)This;
+        *ppv = This;
     else if (IsEqualIID(riid, &IID_IPersist))
-        *ppv = (LPVOID)This;
+        *ppv = This;
     else if (IsEqualIID(riid, &IID_IMediaFilter))
-        *ppv = (LPVOID)This;
+        *ppv = This;
     else if (IsEqualIID(riid, &IID_IBaseFilter))
-        *ppv = (LPVOID)This;
+        *ppv = This;
     else if (IsEqualIID(riid, &IID_IBasicAudio))
-        *ppv = (LPVOID)&(This->IBasicAudio_vtbl);
+        *ppv = &This->IBasicAudio_vtbl;
     else if (IsEqualIID(riid, &IID_IReferenceClock))
-        *ppv = (LPVOID)&(This->IReferenceClock_vtbl);
+        *ppv = &This->IReferenceClock_vtbl;
     else if (IsEqualIID(riid, &IID_IMediaSeeking))
         *ppv = &This->mediaSeeking.lpVtbl;
+    else if (IsEqualIID(riid, &IID_IAMDirectSound))
+        *ppv = &This->IAMDirectSound_vtbl;
 
     if (*ppv)
     {
@@ -1073,10 +1113,10 @@ static HRESULT WINAPI Basicaudio_Invoke(IBasicAudio *iface,
 
 /*** IBasicAudio methods ***/
 static HRESULT WINAPI Basicaudio_put_Volume(IBasicAudio *iface,
-                                           long lVolume) {
+                                            LONG lVolume) {
     ICOM_THIS_MULTI(DSoundRenderImpl, IBasicAudio_vtbl, iface);
 
-    TRACE("(%p/%p)->(%ld)\n", This, iface, lVolume);
+    TRACE("(%p/%p)->(%d)\n", This, iface, lVolume);
 
     if (lVolume > DSBVOLUME_MAX || lVolume < DSBVOLUME_MIN)
         return E_INVALIDARG;
@@ -1091,7 +1131,7 @@ static HRESULT WINAPI Basicaudio_put_Volume(IBasicAudio *iface,
 }
 
 static HRESULT WINAPI Basicaudio_get_Volume(IBasicAudio *iface,
-                                           long *plVolume) {
+                                            LONG *plVolume) {
     ICOM_THIS_MULTI(DSoundRenderImpl, IBasicAudio_vtbl, iface);
 
     TRACE("(%p/%p)->(%p)\n", This, iface, plVolume);
@@ -1104,10 +1144,10 @@ static HRESULT WINAPI Basicaudio_get_Volume(IBasicAudio *iface,
 }
 
 static HRESULT WINAPI Basicaudio_put_Balance(IBasicAudio *iface,
-                                            long lBalance) {
+                                             LONG lBalance) {
     ICOM_THIS_MULTI(DSoundRenderImpl, IBasicAudio_vtbl, iface);
 
-    TRACE("(%p/%p)->(%ld)\n", This, iface, lBalance);
+    TRACE("(%p/%p)->(%d)\n", This, iface, lBalance);
 
     if (lBalance < DSBPAN_LEFT || lBalance > DSBPAN_RIGHT)
         return E_INVALIDARG;
@@ -1122,7 +1162,7 @@ static HRESULT WINAPI Basicaudio_put_Balance(IBasicAudio *iface,
 }
 
 static HRESULT WINAPI Basicaudio_get_Balance(IBasicAudio *iface,
-                                            long *plBalance) {
+                                             LONG *plBalance) {
     ICOM_THIS_MULTI(DSoundRenderImpl, IBasicAudio_vtbl, iface);
 
     TRACE("(%p/%p)->(%p)\n", This, iface, plBalance);
@@ -1294,3 +1334,121 @@ static const IMediaSeekingVtbl IMediaSeeking_Vtbl =
     MediaSeekingImpl_GetRate,
     MediaSeekingImpl_GetPreroll
 };
+
+/*** IUnknown methods ***/
+static HRESULT WINAPI AMDirectSound_QueryInterface(IAMDirectSound *iface,
+                                               REFIID riid,
+                                               LPVOID*ppvObj)
+{
+    ICOM_THIS_MULTI(DSoundRenderImpl, IAMDirectSound_vtbl, iface);
+
+    TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj);
+
+    return DSoundRender_QueryInterface((IBaseFilter*)This, riid, ppvObj);
+}
+
+static ULONG WINAPI AMDirectSound_AddRef(IAMDirectSound *iface)
+{
+    ICOM_THIS_MULTI(DSoundRenderImpl, IAMDirectSound_vtbl, iface);
+
+    TRACE("(%p/%p)->()\n", This, iface);
+
+    return DSoundRender_AddRef((IBaseFilter*)This);
+}
+
+static ULONG WINAPI AMDirectSound_Release(IAMDirectSound *iface)
+{
+    ICOM_THIS_MULTI(DSoundRenderImpl, IAMDirectSound_vtbl, iface);
+
+    TRACE("(%p/%p)->()\n", This, iface);
+
+    return DSoundRender_Release((IBaseFilter*)This);
+}
+
+/*** IAMDirectSound methods ***/
+static HRESULT WINAPI AMDirectSound_GetDirectSoundInterface(IAMDirectSound *iface,  IDirectSound **ds)
+{
+    ICOM_THIS_MULTI(DSoundRenderImpl, IAMDirectSound_vtbl, iface);
+
+    FIXME("(%p/%p)->(%p): stub\n", This, iface, ds);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI AMDirectSound_GetPrimaryBufferInterface(IAMDirectSound *iface, IDirectSoundBuffer **buf)
+{
+    ICOM_THIS_MULTI(DSoundRenderImpl, IAMDirectSound_vtbl, iface);
+
+    FIXME("(%p/%p)->(%p): stub\n", This, iface, buf);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI AMDirectSound_GetSecondaryBufferInterface(IAMDirectSound *iface, IDirectSoundBuffer **buf)
+{
+    ICOM_THIS_MULTI(DSoundRenderImpl, IAMDirectSound_vtbl, iface);
+
+    FIXME("(%p/%p)->(%p): stub\n", This, iface, buf);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI AMDirectSound_ReleaseDirectSoundInterface(IAMDirectSound *iface, IDirectSound *ds)
+{
+    ICOM_THIS_MULTI(DSoundRenderImpl, IAMDirectSound_vtbl, iface);
+
+    FIXME("(%p/%p)->(%p): stub\n", This, iface, ds);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI AMDirectSound_ReleasePrimaryBufferInterface(IAMDirectSound *iface, IDirectSoundBuffer *buf)
+{
+    ICOM_THIS_MULTI(DSoundRenderImpl, IAMDirectSound_vtbl, iface);
+
+    FIXME("(%p/%p)->(%p): stub\n", This, iface, buf);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI AMDirectSound_ReleaseSecondaryBufferInterface(IAMDirectSound *iface, IDirectSoundBuffer *buf)
+{
+    ICOM_THIS_MULTI(DSoundRenderImpl, IAMDirectSound_vtbl, iface);
+
+    FIXME("(%p/%p)->(%p): stub\n", This, iface, buf);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI AMDirectSound_SetFocusWindow(IAMDirectSound *iface, HWND hwnd, BOOL bgsilent)
+{
+    ICOM_THIS_MULTI(DSoundRenderImpl, IAMDirectSound_vtbl, iface);
+
+    FIXME("(%p/%p)->(%p,%d): stub\n", This, iface, hwnd, bgsilent);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI AMDirectSound_GetFocusWindow(IAMDirectSound *iface, HWND hwnd)
+{
+    ICOM_THIS_MULTI(DSoundRenderImpl, IAMDirectSound_vtbl, iface);
+
+    FIXME("(%p/%p)->(%p): stub\n", This, iface, hwnd);
+
+    return E_NOTIMPL;
+}
+
+static const IAMDirectSoundVtbl IAMDirectSound_Vtbl =
+{
+    AMDirectSound_QueryInterface,
+    AMDirectSound_AddRef,
+    AMDirectSound_Release,
+    AMDirectSound_GetDirectSoundInterface,
+    AMDirectSound_GetPrimaryBufferInterface,
+    AMDirectSound_GetSecondaryBufferInterface,
+    AMDirectSound_ReleaseDirectSoundInterface,
+    AMDirectSound_ReleasePrimaryBufferInterface,
+    AMDirectSound_ReleaseSecondaryBufferInterface,
+    AMDirectSound_SetFocusWindow,
+    AMDirectSound_GetFocusWindow
+};