2 * Audio Renderer (CLSID_AudioRender)
5 * - implement IReferenceClock.
8 * hidenori@a2.ctktv.ne.jp
25 #include "debugtools.h"
26 DEFAULT_DEBUG_CHANNEL(quartz);
28 #include "quartz_private.h"
33 static const WCHAR QUARTZ_AudioRender_Name[] =
34 { 'A','u','d','i','o',' ','R','e','n','d','e','r',0 };
35 static const WCHAR QUARTZ_AudioRenderPin_Name[] =
40 /***************************************************************************
42 * CAudioRendererImpl waveOut methods (internal)
47 HRESULT QUARTZ_HRESULT_From_MMRESULT( MMRESULT mr )
53 case MMSYSERR_NOERROR:
64 void CAudioRendererImpl_waveOutEventCallback(
65 HWAVEOUT hwo, UINT uMsg,
66 DWORD dwInstance, DWORD dwParam1, DWORD dwParam2 )
68 CAudioRendererImpl* This = (CAudioRendererImpl*)dwInstance;
70 if ( uMsg == WOM_DONE )
71 SetEvent( This->m_hEventRender );
75 void CAudioRendererImpl_waveOutReset(
76 CAudioRendererImpl* This )
78 if ( !This->m_fWaveOutInit )
81 waveOutReset( This->m_hWaveOut );
82 SetEvent( This->m_hEventRender );
86 void CAudioRendererImpl_waveOutUninit(
87 CAudioRendererImpl* This )
93 if ( !This->m_fWaveOutInit )
96 waveOutReset( This->m_hWaveOut );
97 SetEvent( This->m_hEventRender );
99 for ( i = 0; i < WINE_QUARTZ_WAVEOUT_COUNT; i++ )
101 if ( This->m_hdr[i].dwFlags & WHDR_PREPARED )
103 waveOutUnprepareHeader(
105 &This->m_hdr[i], sizeof(WAVEHDR) );
106 This->m_hdr[i].dwFlags = 0;
108 if ( This->m_hdr[i].lpData != NULL )
110 QUARTZ_FreeMem( This->m_hdr[i].lpData );
111 This->m_hdr[i].lpData = NULL;
115 waveOutClose( This->m_hWaveOut );
116 This->m_hWaveOut = (HWAVEOUT)NULL;
117 if ( This->m_hEventRender != (HANDLE)NULL )
119 CloseHandle( This->m_hEventRender );
120 This->m_hEventRender = (HANDLE)NULL;
123 This->m_fWaveOutInit = FALSE;
127 HRESULT CAudioRendererImpl_waveOutInit(
128 CAudioRendererImpl* This, WAVEFORMATEX* pwfx )
135 if ( This->m_fWaveOutInit )
140 if ( pwfx->nBlockAlign == 0 )
143 This->m_hEventRender = (HANDLE)NULL;
144 This->m_hWaveOut = (HWAVEOUT)NULL;
145 This->m_dwBlockSize = 0;
146 This->m_phdrCur = NULL;
147 ZeroMemory( &This->m_hdr, sizeof(This->m_hdr) );
151 &This->m_hWaveOut, WAVE_MAPPER, pwfx,
152 (DWORD)CAudioRendererImpl_waveOutEventCallback, (DWORD)This,
154 hr = QUARTZ_HRESULT_From_MMRESULT( mr );
157 This->m_fWaveOutInit = TRUE;
159 This->m_hEventRender = CreateEventA(
160 NULL, TRUE, TRUE, NULL );
161 if ( This->m_hEventRender == (HANDLE)NULL )
167 dwBlockSize = pwfx->nAvgBytesPerSec / pwfx->nBlockAlign;
168 if ( dwBlockSize == 0 )
170 dwBlockSize *= pwfx->nBlockAlign;
171 This->m_dwBlockSize = dwBlockSize;
173 for ( i = 0; i < WINE_QUARTZ_WAVEOUT_COUNT; i++ )
175 This->m_hdr[i].lpData = (CHAR*)QUARTZ_AllocMem( dwBlockSize );
176 if ( This->m_hdr[i].lpData == NULL )
181 mr = waveOutPrepareHeader(
183 &This->m_hdr[i], sizeof(WAVEHDR) );
184 hr = QUARTZ_HRESULT_From_MMRESULT( mr );
187 This->m_hdr[i].dwFlags |= WHDR_DONE;
188 This->m_hdr[i].dwBufferLength = dwBlockSize;
189 This->m_hdr[i].dwUser = i;
194 CAudioRendererImpl_waveOutUninit(This);
199 /* FIXME: Not used for now */
201 static HRESULT CAudioRendererImpl_waveOutPause( CAudioRendererImpl* This )
203 if ( !This->m_fWaveOutInit )
206 return QUARTZ_HRESULT_From_MMRESULT( waveOutPause(
207 This->m_hWaveOut ) );
210 static HRESULT CAudioRendererImpl_waveOutRun( CAudioRendererImpl* This )
212 if ( !This->m_fWaveOutInit )
215 return QUARTZ_HRESULT_From_MMRESULT( waveOutRestart(
216 This->m_hWaveOut ) );
221 WAVEHDR* CAudioRendererImpl_waveOutGetBuffer(
222 CAudioRendererImpl* This )
226 if ( !This->m_fWaveOutInit )
229 if ( This->m_phdrCur != NULL )
230 return This->m_phdrCur;
232 for ( i = 0; i < WINE_QUARTZ_WAVEOUT_COUNT; i++ )
234 if ( This->m_hdr[i].dwFlags & WHDR_DONE )
236 This->m_phdrCur = &(This->m_hdr[i]);
237 This->m_phdrCur->dwFlags &= ~WHDR_DONE;
238 This->m_phdrCur->dwBufferLength = 0;
239 return This->m_phdrCur;
247 HRESULT CAudioRendererImpl_waveOutWriteData(
248 CAudioRendererImpl* This,
249 const BYTE* pData, DWORD cbData, DWORD* pcbWritten )
255 if ( !This->m_fWaveOutInit )
261 if ( CAudioRendererImpl_waveOutGetBuffer(This) == NULL )
264 cbAvail = This->m_dwBlockSize - This->m_phdrCur->dwBufferLength;
265 if ( cbAvail > cbData )
267 memcpy( This->m_phdrCur->lpData, pData, cbAvail );
270 This->m_phdrCur->dwBufferLength += cbAvail;
272 *pcbWritten = cbAvail;
278 HRESULT CAudioRendererImpl_waveOutFlush(
279 CAudioRendererImpl* This )
284 if ( !This->m_fWaveOutInit )
286 if ( This->m_phdrCur == NULL )
289 if ( This->m_phdrCur->dwBufferLength == 0 )
294 This->m_phdrCur, sizeof(WAVEHDR) );
295 hr = QUARTZ_HRESULT_From_MMRESULT( mr );
299 This->m_phdrCur = NULL;
304 /* FIXME: Not used for now */
307 HRESULT CAudioRendererImpl_waveOutGetVolume(
308 CAudioRendererImpl* This,
309 DWORD* pdwLeft, DWORD* pdwRight )
315 if ( !This->m_fWaveOutInit )
318 mr = waveOutGetVolume(
319 This->m_hWaveOut, &dwVol );
320 hr = QUARTZ_HRESULT_From_MMRESULT( mr );
324 *pdwLeft = LOWORD(dwVol);
325 *pdwRight = HIWORD(dwVol);
331 HRESULT CAudioRendererImpl_waveOutSetVolume(
332 CAudioRendererImpl* This,
333 DWORD dwLeft, DWORD dwRight )
338 if ( !This->m_fWaveOutInit )
341 dwVol = dwLeft | (dwRight<<16);
343 mr = waveOutSetVolume(
344 This->m_hWaveOut, dwVol );
345 return QUARTZ_HRESULT_From_MMRESULT( mr );
349 /***************************************************************************
351 * CAudioRendererImpl methods
356 static HRESULT CAudioRendererImpl_OnActive( CBaseFilterImpl* pImpl )
358 CAudioRendererImpl_THIS(pImpl,basefilter);
361 FIXME( "(%p)\n", This );
363 if ( This->pPin->pin.pmtConn == NULL )
366 This->m_fInFlush = FALSE;
368 /* FIXME - don't work correctly.
369 hr = CAudioRendererImpl_waveOutRun(This);
377 static HRESULT CAudioRendererImpl_OnInactive( CBaseFilterImpl* pImpl )
379 CAudioRendererImpl_THIS(pImpl,basefilter);
383 FIXME( "(%p)\n", This );
385 if ( This->pPin->pin.pmtConn == NULL )
388 pwfx = (WAVEFORMATEX*)This->pPin->pin.pmtConn->pbFormat;
392 This->m_fInFlush = FALSE;
394 hr = CAudioRendererImpl_waveOutInit(This,pwfx);
398 /* FIXME - may cause deadlock.
399 hr = CAudioRendererImpl_waveOutPause(This);
407 static HRESULT CAudioRendererImpl_OnStop( CBaseFilterImpl* pImpl )
409 CAudioRendererImpl_THIS(pImpl,basefilter);
411 FIXME( "(%p)\n", This );
413 CAudioRendererImpl_waveOutUninit(This);
415 This->m_fInFlush = FALSE;
417 TRACE("returned\n" );
422 static const CBaseFilterHandlers filterhandlers =
424 CAudioRendererImpl_OnActive, /* pOnActive */
425 CAudioRendererImpl_OnInactive, /* pOnInactive */
426 CAudioRendererImpl_OnStop, /* pOnStop */
429 /***************************************************************************
431 * CAudioRendererPinImpl methods
435 static HRESULT CAudioRendererPinImpl_OnDisconnect( CPinBaseImpl* pImpl )
437 CAudioRendererPinImpl_THIS(pImpl,pin);
439 TRACE("(%p)\n",This);
441 if ( This->meminput.pAllocator != NULL )
443 IMemAllocator_Decommit(This->meminput.pAllocator);
444 IMemAllocator_Release(This->meminput.pAllocator);
445 This->meminput.pAllocator = NULL;
452 static HRESULT CAudioRendererPinImpl_CheckMediaType( CPinBaseImpl* pImpl, const AM_MEDIA_TYPE* pmt )
454 CAudioRendererPinImpl_THIS(pImpl,pin);
455 const WAVEFORMATEX* pwfx;
457 TRACE("(%p,%p)\n",This,pmt);
459 if ( !IsEqualGUID( &pmt->majortype, &MEDIATYPE_Audio ) )
461 TRACE("not audio\n");
464 if ( !IsEqualGUID( &pmt->subtype, &MEDIASUBTYPE_NULL ) &&
465 !IsEqualGUID( &pmt->subtype, &MEDIASUBTYPE_PCM ) )
470 if ( !IsEqualGUID( &pmt->formattype, &FORMAT_WaveFormatEx ) )
476 TRACE("testing WAVE header\n");
478 if ( pmt->cbFormat < (sizeof(WAVEFORMATEX)-sizeof(WORD)) )
481 pwfx = (const WAVEFORMATEX*)pmt->pbFormat;
484 if ( pwfx->wFormatTag != 1 )
487 TRACE("returned successfully.\n");
492 static HRESULT CAudioRendererPinImpl_Receive( CPinBaseImpl* pImpl, IMediaSample* pSample )
494 CAudioRendererPinImpl_THIS(pImpl,pin);
500 FIXME( "(%p,%p)\n",This,pSample );
502 if ( !This->pRender->m_fWaveOutInit )
504 if ( This->pRender->m_fInFlush )
506 if ( pSample == NULL )
509 hr = IMediaSample_GetPointer( pSample, &pData );
512 dwDataLength = (DWORD)IMediaSample_GetActualDataLength( pSample );
516 TRACE("trying to write %lu bytes\n",dwDataLength);
518 ResetEvent( This->pRender->m_hEventRender );
519 hr = CAudioRendererImpl_waveOutWriteData(
520 This->pRender,pData,dwDataLength,&dwWritten);
525 WaitForSingleObject( This->pRender->m_hEventRender, INFINITE );
529 dwDataLength -= dwWritten;
530 hr = CAudioRendererImpl_waveOutFlush(This->pRender);
533 if ( dwDataLength == 0 )
540 static HRESULT CAudioRendererPinImpl_ReceiveCanBlock( CPinBaseImpl* pImpl )
542 CAudioRendererPinImpl_THIS(pImpl,pin);
544 TRACE( "(%p)\n", This );
550 static HRESULT CAudioRendererPinImpl_EndOfStream( CPinBaseImpl* pImpl )
552 CAudioRendererPinImpl_THIS(pImpl,pin);
554 FIXME( "(%p)\n", This );
556 This->pRender->m_fInFlush = FALSE;
558 /* FIXME - don't notify twice until stopped or seeked. */
559 return CBaseFilterImpl_MediaEventNotify(
560 &This->pRender->basefilter, EC_COMPLETE,
561 (LONG_PTR)S_OK, (LONG_PTR)(IBaseFilter*)(This->pRender) );
564 static HRESULT CAudioRendererPinImpl_BeginFlush( CPinBaseImpl* pImpl )
566 CAudioRendererPinImpl_THIS(pImpl,pin);
568 FIXME( "(%p)\n", This );
570 This->pRender->m_fInFlush = TRUE;
571 CAudioRendererImpl_waveOutReset(This->pRender);
576 static HRESULT CAudioRendererPinImpl_EndFlush( CPinBaseImpl* pImpl )
578 CAudioRendererPinImpl_THIS(pImpl,pin);
580 FIXME( "(%p)\n", This );
582 This->pRender->m_fInFlush = FALSE;
587 static HRESULT CAudioRendererPinImpl_NewSegment( CPinBaseImpl* pImpl, REFERENCE_TIME rtStart, REFERENCE_TIME rtStop, double rate )
589 CAudioRendererPinImpl_THIS(pImpl,pin);
591 FIXME( "(%p)\n", This );
593 This->pRender->m_fInFlush = FALSE;
598 static const CBasePinHandlers pinhandlers =
600 NULL, /* pOnPreConnect */
601 NULL, /* pOnPostConnect */
602 CAudioRendererPinImpl_OnDisconnect, /* pOnDisconnect */
603 CAudioRendererPinImpl_CheckMediaType, /* pCheckMediaType */
604 NULL, /* pQualityNotify */
605 CAudioRendererPinImpl_Receive, /* pReceive */
606 CAudioRendererPinImpl_ReceiveCanBlock, /* pReceiveCanBlock */
607 CAudioRendererPinImpl_EndOfStream, /* pEndOfStream */
608 CAudioRendererPinImpl_BeginFlush, /* pBeginFlush */
609 CAudioRendererPinImpl_EndFlush, /* pEndFlush */
610 CAudioRendererPinImpl_NewSegment, /* pNewSegment */
614 /***************************************************************************
616 * new/delete CAudioRendererImpl
620 /* can I use offsetof safely? - FIXME? */
621 static QUARTZ_IFEntry FilterIFEntries[] =
623 { &IID_IPersist, offsetof(CAudioRendererImpl,basefilter)-offsetof(CAudioRendererImpl,unk) },
624 { &IID_IMediaFilter, offsetof(CAudioRendererImpl,basefilter)-offsetof(CAudioRendererImpl,unk) },
625 { &IID_IBaseFilter, offsetof(CAudioRendererImpl,basefilter)-offsetof(CAudioRendererImpl,unk) },
626 { &IID_IBasicAudio, offsetof(CAudioRendererImpl,basaud)-offsetof(CAudioRendererImpl,unk) },
629 static HRESULT CAudioRendererImpl_OnQueryInterface(
630 IUnknown* punk, const IID* piid, void** ppobj )
632 CAudioRendererImpl_THIS(punk,unk);
634 if ( This->pSeekPass == NULL )
635 return E_NOINTERFACE;
637 if ( IsEqualGUID( &IID_IMediaPosition, piid ) ||
638 IsEqualGUID( &IID_IMediaSeeking, piid ) )
640 TRACE( "IMediaSeeking(or IMediaPosition) is queried\n" );
641 return IUnknown_QueryInterface( (IUnknown*)(&This->pSeekPass->unk), piid, ppobj );
644 return E_NOINTERFACE;
647 static void QUARTZ_DestroyAudioRenderer(IUnknown* punk)
649 CAudioRendererImpl_THIS(punk,unk);
651 TRACE( "(%p)\n", This );
653 if ( This->pPin != NULL )
655 IUnknown_Release(This->pPin->unk.punkControl);
658 if ( This->pSeekPass != NULL )
660 IUnknown_Release((IUnknown*)&This->pSeekPass->unk);
661 This->pSeekPass = NULL;
664 CAudioRendererImpl_UninitIBasicAudio(This);
665 CBaseFilterImpl_UninitIBaseFilter(&This->basefilter);
667 DeleteCriticalSection( &This->m_csReceive );
670 HRESULT QUARTZ_CreateAudioRenderer(IUnknown* punkOuter,void** ppobj)
672 CAudioRendererImpl* This = NULL;
675 TRACE("(%p,%p)\n",punkOuter,ppobj);
677 This = (CAudioRendererImpl*)
678 QUARTZ_AllocObj( sizeof(CAudioRendererImpl) );
680 return E_OUTOFMEMORY;
681 This->pSeekPass = NULL;
683 This->m_fInFlush = FALSE;
684 This->m_fWaveOutInit = FALSE;
685 This->m_hEventRender = (HANDLE)NULL;
687 QUARTZ_IUnkInit( &This->unk, punkOuter );
688 This->qiext.pNext = NULL;
689 This->qiext.pOnQueryInterface = &CAudioRendererImpl_OnQueryInterface;
690 QUARTZ_IUnkAddDelegation( &This->unk, &This->qiext );
692 hr = CBaseFilterImpl_InitIBaseFilter(
694 This->unk.punkControl,
696 QUARTZ_AudioRender_Name,
700 hr = CAudioRendererImpl_InitIBasicAudio(This);
703 CBaseFilterImpl_UninitIBaseFilter(&This->basefilter);
709 QUARTZ_FreeObj(This);
713 This->unk.pEntries = FilterIFEntries;
714 This->unk.dwEntries = sizeof(FilterIFEntries)/sizeof(FilterIFEntries[0]);
715 This->unk.pOnFinalRelease = QUARTZ_DestroyAudioRenderer;
717 InitializeCriticalSection( &This->m_csReceive );
719 hr = QUARTZ_CreateAudioRendererPin(
721 &This->basefilter.csFilter,
725 hr = QUARTZ_CompList_AddComp(
726 This->basefilter.pInPins,
727 (IUnknown*)&This->pPin->pin,
730 hr = QUARTZ_CreateSeekingPassThruInternal(
731 (IUnknown*)&(This->unk), &This->pSeekPass,
732 TRUE, (IPin*)&(This->pPin->pin) );
736 IUnknown_Release( This->unk.punkControl );
740 *ppobj = (void*)&(This->unk);
746 /***************************************************************************
748 * new/delete CAudioRendererPinImpl
752 /* can I use offsetof safely? - FIXME? */
753 static QUARTZ_IFEntry PinIFEntries[] =
755 { &IID_IPin, offsetof(CAudioRendererPinImpl,pin)-offsetof(CAudioRendererPinImpl,unk) },
756 { &IID_IMemInputPin, offsetof(CAudioRendererPinImpl,meminput)-offsetof(CAudioRendererPinImpl,unk) },
759 static void QUARTZ_DestroyAudioRendererPin(IUnknown* punk)
761 CAudioRendererPinImpl_THIS(punk,unk);
763 TRACE( "(%p)\n", This );
765 CPinBaseImpl_UninitIPin( &This->pin );
766 CMemInputPinBaseImpl_UninitIMemInputPin( &This->meminput );
769 HRESULT QUARTZ_CreateAudioRendererPin(
770 CAudioRendererImpl* pFilter,
771 CRITICAL_SECTION* pcsPin,
772 CRITICAL_SECTION* pcsPinReceive,
773 CAudioRendererPinImpl** ppPin)
775 CAudioRendererPinImpl* This = NULL;
778 TRACE("(%p,%p,%p,%p)\n",pFilter,pcsPin,pcsPinReceive,ppPin);
780 This = (CAudioRendererPinImpl*)
781 QUARTZ_AllocObj( sizeof(CAudioRendererPinImpl) );
783 return E_OUTOFMEMORY;
785 QUARTZ_IUnkInit( &This->unk, NULL );
786 This->pRender = pFilter;
788 hr = CPinBaseImpl_InitIPin(
790 This->unk.punkControl,
791 pcsPin, pcsPinReceive,
792 &pFilter->basefilter,
793 QUARTZ_AudioRenderPin_Name,
799 hr = CMemInputPinBaseImpl_InitIMemInputPin(
801 This->unk.punkControl,
805 CPinBaseImpl_UninitIPin( &This->pin );
811 QUARTZ_FreeObj(This);
815 This->unk.pEntries = PinIFEntries;
816 This->unk.dwEntries = sizeof(PinIFEntries)/sizeof(PinIFEntries[0]);
817 This->unk.pOnFinalRelease = QUARTZ_DestroyAudioRendererPin;
821 TRACE("returned successfully.\n");
827 /***************************************************************************
829 * CAudioRendererImpl::IBasicAudio
833 static HRESULT WINAPI
834 IBasicAudio_fnQueryInterface(IBasicAudio* iface,REFIID riid,void** ppobj)
836 CAudioRendererImpl_THIS(iface,basaud);
838 TRACE("(%p)->()\n",This);
840 return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
844 IBasicAudio_fnAddRef(IBasicAudio* iface)
846 CAudioRendererImpl_THIS(iface,basaud);
848 TRACE("(%p)->()\n",This);
850 return IUnknown_AddRef(This->unk.punkControl);
854 IBasicAudio_fnRelease(IBasicAudio* iface)
856 CAudioRendererImpl_THIS(iface,basaud);
858 TRACE("(%p)->()\n",This);
860 return IUnknown_Release(This->unk.punkControl);
863 static HRESULT WINAPI
864 IBasicAudio_fnGetTypeInfoCount(IBasicAudio* iface,UINT* pcTypeInfo)
866 CAudioRendererImpl_THIS(iface,basaud);
868 FIXME("(%p)->()\n",This);
873 static HRESULT WINAPI
874 IBasicAudio_fnGetTypeInfo(IBasicAudio* iface,UINT iTypeInfo, LCID lcid, ITypeInfo** ppobj)
876 CAudioRendererImpl_THIS(iface,basaud);
878 FIXME("(%p)->()\n",This);
883 static HRESULT WINAPI
884 IBasicAudio_fnGetIDsOfNames(IBasicAudio* iface,REFIID riid, LPOLESTR* ppwszName, UINT cNames, LCID lcid, DISPID* pDispId)
886 CAudioRendererImpl_THIS(iface,basaud);
888 FIXME("(%p)->()\n",This);
893 static HRESULT WINAPI
894 IBasicAudio_fnInvoke(IBasicAudio* iface,DISPID DispId, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarRes, EXCEPINFO* pExcepInfo, UINT* puArgErr)
896 CAudioRendererImpl_THIS(iface,basaud);
898 FIXME("(%p)->()\n",This);
904 static HRESULT WINAPI
905 IBasicAudio_fnput_Volume(IBasicAudio* iface,long lVol)
907 CAudioRendererImpl_THIS(iface,basaud);
909 FIXME("(%p)->()\n",This);
914 static HRESULT WINAPI
915 IBasicAudio_fnget_Volume(IBasicAudio* iface,long* plVol)
917 CAudioRendererImpl_THIS(iface,basaud);
919 FIXME("(%p)->()\n",This);
924 static HRESULT WINAPI
925 IBasicAudio_fnput_Balance(IBasicAudio* iface,long lBalance)
927 CAudioRendererImpl_THIS(iface,basaud);
929 FIXME("(%p)->()\n",This);
934 static HRESULT WINAPI
935 IBasicAudio_fnget_Balance(IBasicAudio* iface,long* plBalance)
937 CAudioRendererImpl_THIS(iface,basaud);
939 FIXME("(%p)->()\n",This);
945 static ICOM_VTABLE(IBasicAudio) ibasicaudio =
947 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
948 /* IUnknown fields */
949 IBasicAudio_fnQueryInterface,
950 IBasicAudio_fnAddRef,
951 IBasicAudio_fnRelease,
952 /* IDispatch fields */
953 IBasicAudio_fnGetTypeInfoCount,
954 IBasicAudio_fnGetTypeInfo,
955 IBasicAudio_fnGetIDsOfNames,
956 IBasicAudio_fnInvoke,
957 /* IBasicAudio fields */
958 IBasicAudio_fnput_Volume,
959 IBasicAudio_fnget_Volume,
960 IBasicAudio_fnput_Balance,
961 IBasicAudio_fnget_Balance,
965 HRESULT CAudioRendererImpl_InitIBasicAudio( CAudioRendererImpl* This )
967 TRACE("(%p)\n",This);
968 ICOM_VTBL(&This->basaud) = &ibasicaudio;
973 void CAudioRendererImpl_UninitIBasicAudio( CAudioRendererImpl* This )
975 TRACE("(%p)\n",This);