2 * Audio Renderer (CLSID_AudioRender)
5 * - implement IReferenceClock.
8 * Copyright (C) Hidenori TAKESHIMA <hidenori@a2.ctktv.ne.jp>
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
39 #include "wine/debug.h"
40 WINE_DEFAULT_DEBUG_CHANNEL(quartz);
42 #include "quartz_private.h"
47 static const WCHAR QUARTZ_AudioRender_Name[] =
48 { 'A','u','d','i','o',' ','R','e','n','d','e','r',0 };
49 static const WCHAR QUARTZ_AudioRenderPin_Name[] =
54 /***************************************************************************
56 * CAudioRendererImpl waveOut methods (internal)
61 HRESULT QUARTZ_HRESULT_From_MMRESULT( MMRESULT mr )
67 case MMSYSERR_NOERROR:
78 void CAudioRendererImpl_waveOutEventCallback(
79 HWAVEOUT hwo, UINT uMsg,
80 DWORD dwInstance, DWORD dwParam1, DWORD dwParam2 )
82 CAudioRendererImpl* This = (CAudioRendererImpl*)dwInstance;
84 if ( uMsg == WOM_DONE )
85 SetEvent( This->m_hEventRender );
89 void CAudioRendererImpl_waveOutReset(
90 CAudioRendererImpl* This )
92 if ( !This->m_fWaveOutInit )
95 waveOutReset( This->m_hWaveOut );
96 SetEvent( This->m_hEventRender );
100 void CAudioRendererImpl_waveOutUninit(
101 CAudioRendererImpl* This )
105 TRACE("(%p)\n",This);
107 if ( !This->m_fWaveOutInit )
110 waveOutReset( This->m_hWaveOut );
111 SetEvent( This->m_hEventRender );
113 for ( i = 0; i < WINE_QUARTZ_WAVEOUT_COUNT; i++ )
115 if ( This->m_hdr[i].dwFlags & WHDR_PREPARED )
117 waveOutUnprepareHeader(
119 &This->m_hdr[i], sizeof(WAVEHDR) );
120 This->m_hdr[i].dwFlags = 0;
122 if ( This->m_hdr[i].lpData != NULL )
124 QUARTZ_FreeMem( This->m_hdr[i].lpData );
125 This->m_hdr[i].lpData = NULL;
129 waveOutClose( This->m_hWaveOut );
130 This->m_hWaveOut = (HWAVEOUT)NULL;
131 if ( This->m_hEventRender != (HANDLE)NULL )
133 CloseHandle( This->m_hEventRender );
134 This->m_hEventRender = (HANDLE)NULL;
137 This->m_fWaveOutInit = FALSE;
141 HRESULT CAudioRendererImpl_waveOutInit(
142 CAudioRendererImpl* This, WAVEFORMATEX* pwfx )
149 if ( This->m_fWaveOutInit )
154 if ( pwfx->nBlockAlign == 0 )
157 This->m_hEventRender = (HANDLE)NULL;
158 This->m_hWaveOut = (HWAVEOUT)NULL;
159 This->m_dwBlockSize = 0;
160 This->m_phdrCur = NULL;
161 ZeroMemory( &This->m_hdr, sizeof(This->m_hdr) );
165 &This->m_hWaveOut, WAVE_MAPPER, pwfx,
166 (DWORD)CAudioRendererImpl_waveOutEventCallback, (DWORD)This,
168 hr = QUARTZ_HRESULT_From_MMRESULT( mr );
171 This->m_fWaveOutInit = TRUE;
173 This->m_hEventRender = CreateEventA(
174 NULL, TRUE, TRUE, NULL );
175 if ( This->m_hEventRender == (HANDLE)NULL )
181 dwBlockSize = pwfx->nAvgBytesPerSec / pwfx->nBlockAlign;
182 if ( dwBlockSize == 0 )
184 dwBlockSize *= pwfx->nBlockAlign;
185 This->m_dwBlockSize = dwBlockSize;
187 for ( i = 0; i < WINE_QUARTZ_WAVEOUT_COUNT; i++ )
189 This->m_hdr[i].lpData = (CHAR*)QUARTZ_AllocMem( dwBlockSize );
190 if ( This->m_hdr[i].lpData == NULL )
195 mr = waveOutPrepareHeader(
197 &This->m_hdr[i], sizeof(WAVEHDR) );
198 hr = QUARTZ_HRESULT_From_MMRESULT( mr );
201 This->m_hdr[i].dwFlags |= WHDR_DONE;
202 This->m_hdr[i].dwBufferLength = dwBlockSize;
203 This->m_hdr[i].dwUser = i;
208 CAudioRendererImpl_waveOutUninit(This);
213 /* FIXME: Not used for now */
215 static HRESULT CAudioRendererImpl_waveOutPause( CAudioRendererImpl* This )
217 if ( !This->m_fWaveOutInit )
220 return QUARTZ_HRESULT_From_MMRESULT( waveOutPause(
221 This->m_hWaveOut ) );
224 static HRESULT CAudioRendererImpl_waveOutRun( CAudioRendererImpl* This )
226 if ( !This->m_fWaveOutInit )
229 return QUARTZ_HRESULT_From_MMRESULT( waveOutRestart(
230 This->m_hWaveOut ) );
235 WAVEHDR* CAudioRendererImpl_waveOutGetBuffer(
236 CAudioRendererImpl* This )
240 if ( !This->m_fWaveOutInit )
243 if ( This->m_phdrCur != NULL )
244 return This->m_phdrCur;
246 for ( i = 0; i < WINE_QUARTZ_WAVEOUT_COUNT; i++ )
248 if ( This->m_hdr[i].dwFlags & WHDR_DONE )
250 This->m_phdrCur = &(This->m_hdr[i]);
251 This->m_phdrCur->dwFlags &= ~WHDR_DONE;
252 This->m_phdrCur->dwBufferLength = 0;
253 return This->m_phdrCur;
261 HRESULT CAudioRendererImpl_waveOutWriteData(
262 CAudioRendererImpl* This,
263 const BYTE* pData, DWORD cbData, DWORD* pcbWritten )
269 if ( !This->m_fWaveOutInit )
275 if ( CAudioRendererImpl_waveOutGetBuffer(This) == NULL )
278 cbAvail = This->m_dwBlockSize - This->m_phdrCur->dwBufferLength;
279 if ( cbAvail > cbData )
281 memcpy( This->m_phdrCur->lpData, pData, cbAvail );
284 This->m_phdrCur->dwBufferLength += cbAvail;
286 *pcbWritten = cbAvail;
292 HRESULT CAudioRendererImpl_waveOutFlush(
293 CAudioRendererImpl* This )
298 if ( !This->m_fWaveOutInit )
300 if ( This->m_phdrCur == NULL )
303 if ( This->m_phdrCur->dwBufferLength == 0 )
308 This->m_phdrCur, sizeof(WAVEHDR) );
309 hr = QUARTZ_HRESULT_From_MMRESULT( mr );
313 This->m_phdrCur = NULL;
318 /* FIXME: Not used for now */
321 HRESULT CAudioRendererImpl_waveOutGetVolume(
322 CAudioRendererImpl* This,
323 DWORD* pdwLeft, DWORD* pdwRight )
329 if ( !This->m_fWaveOutInit )
332 mr = waveOutGetVolume(
333 This->m_hWaveOut, &dwVol );
334 hr = QUARTZ_HRESULT_From_MMRESULT( mr );
338 *pdwLeft = LOWORD(dwVol);
339 *pdwRight = HIWORD(dwVol);
345 HRESULT CAudioRendererImpl_waveOutSetVolume(
346 CAudioRendererImpl* This,
347 DWORD dwLeft, DWORD dwRight )
352 if ( !This->m_fWaveOutInit )
355 dwVol = dwLeft | (dwRight<<16);
357 mr = waveOutSetVolume(
358 This->m_hWaveOut, dwVol );
359 return QUARTZ_HRESULT_From_MMRESULT( mr );
363 /***************************************************************************
365 * CAudioRendererImpl methods
370 static HRESULT CAudioRendererImpl_OnActive( CBaseFilterImpl* pImpl )
372 CAudioRendererImpl_THIS(pImpl,basefilter);
375 FIXME( "(%p)\n", This );
377 if ( This->pPin->pin.pmtConn == NULL )
380 This->m_fInFlush = FALSE;
382 /* FIXME - don't work correctly.
383 hr = CAudioRendererImpl_waveOutRun(This);
391 static HRESULT CAudioRendererImpl_OnInactive( CBaseFilterImpl* pImpl )
393 CAudioRendererImpl_THIS(pImpl,basefilter);
397 FIXME( "(%p)\n", This );
399 if ( This->pPin->pin.pmtConn == NULL )
402 pwfx = (WAVEFORMATEX*)This->pPin->pin.pmtConn->pbFormat;
406 This->m_fInFlush = FALSE;
408 hr = CAudioRendererImpl_waveOutInit(This,pwfx);
412 /* FIXME - may cause deadlock.
413 hr = CAudioRendererImpl_waveOutPause(This);
421 static HRESULT CAudioRendererImpl_OnStop( CBaseFilterImpl* pImpl )
423 CAudioRendererImpl_THIS(pImpl,basefilter);
425 FIXME( "(%p)\n", This );
427 CAudioRendererImpl_waveOutUninit(This);
429 This->m_fInFlush = FALSE;
431 TRACE("returned\n" );
436 static const CBaseFilterHandlers filterhandlers =
438 CAudioRendererImpl_OnActive, /* pOnActive */
439 CAudioRendererImpl_OnInactive, /* pOnInactive */
440 CAudioRendererImpl_OnStop, /* pOnStop */
443 /***************************************************************************
445 * CAudioRendererPinImpl methods
449 static HRESULT CAudioRendererPinImpl_OnDisconnect( CPinBaseImpl* pImpl )
451 CAudioRendererPinImpl_THIS(pImpl,pin);
453 TRACE("(%p)\n",This);
455 if ( This->meminput.pAllocator != NULL )
457 IMemAllocator_Decommit(This->meminput.pAllocator);
458 IMemAllocator_Release(This->meminput.pAllocator);
459 This->meminput.pAllocator = NULL;
466 static HRESULT CAudioRendererPinImpl_CheckMediaType( CPinBaseImpl* pImpl, const AM_MEDIA_TYPE* pmt )
468 CAudioRendererPinImpl_THIS(pImpl,pin);
469 const WAVEFORMATEX* pwfx;
471 TRACE("(%p,%p)\n",This,pmt);
473 if ( !IsEqualGUID( &pmt->majortype, &MEDIATYPE_Audio ) )
475 TRACE("not audio\n");
478 if ( !IsEqualGUID( &pmt->subtype, &MEDIASUBTYPE_NULL ) &&
479 !IsEqualGUID( &pmt->subtype, &MEDIASUBTYPE_PCM ) )
484 if ( !IsEqualGUID( &pmt->formattype, &FORMAT_WaveFormatEx ) )
490 TRACE("testing WAVE header\n");
492 if ( pmt->cbFormat < (sizeof(WAVEFORMATEX)-sizeof(WORD)) )
495 pwfx = (const WAVEFORMATEX*)pmt->pbFormat;
498 if ( pwfx->wFormatTag != 1 )
501 TRACE("returned successfully.\n");
506 static HRESULT CAudioRendererPinImpl_Receive( CPinBaseImpl* pImpl, IMediaSample* pSample )
508 CAudioRendererPinImpl_THIS(pImpl,pin);
514 FIXME( "(%p,%p)\n",This,pSample );
516 if ( !This->pRender->m_fWaveOutInit )
518 if ( This->pRender->m_fInFlush )
520 if ( pSample == NULL )
523 hr = IMediaSample_GetPointer( pSample, &pData );
526 dwDataLength = (DWORD)IMediaSample_GetActualDataLength( pSample );
530 TRACE("trying to write %lu bytes\n",dwDataLength);
532 ResetEvent( This->pRender->m_hEventRender );
533 hr = CAudioRendererImpl_waveOutWriteData(
534 This->pRender,pData,dwDataLength,&dwWritten);
539 WaitForSingleObject( This->pRender->m_hEventRender, INFINITE );
543 dwDataLength -= dwWritten;
544 hr = CAudioRendererImpl_waveOutFlush(This->pRender);
547 if ( dwDataLength == 0 )
554 static HRESULT CAudioRendererPinImpl_ReceiveCanBlock( CPinBaseImpl* pImpl )
556 CAudioRendererPinImpl_THIS(pImpl,pin);
558 TRACE( "(%p)\n", This );
564 static HRESULT CAudioRendererPinImpl_EndOfStream( CPinBaseImpl* pImpl )
566 CAudioRendererPinImpl_THIS(pImpl,pin);
568 FIXME( "(%p)\n", This );
570 This->pRender->m_fInFlush = FALSE;
572 /* FIXME - don't notify twice until stopped or seeked. */
573 return CBaseFilterImpl_MediaEventNotify(
574 &This->pRender->basefilter, EC_COMPLETE,
575 (LONG_PTR)S_OK, (LONG_PTR)(IBaseFilter*)(This->pRender) );
578 static HRESULT CAudioRendererPinImpl_BeginFlush( CPinBaseImpl* pImpl )
580 CAudioRendererPinImpl_THIS(pImpl,pin);
582 FIXME( "(%p)\n", This );
584 This->pRender->m_fInFlush = TRUE;
585 CAudioRendererImpl_waveOutReset(This->pRender);
590 static HRESULT CAudioRendererPinImpl_EndFlush( CPinBaseImpl* pImpl )
592 CAudioRendererPinImpl_THIS(pImpl,pin);
594 FIXME( "(%p)\n", This );
596 This->pRender->m_fInFlush = FALSE;
601 static HRESULT CAudioRendererPinImpl_NewSegment( CPinBaseImpl* pImpl, REFERENCE_TIME rtStart, REFERENCE_TIME rtStop, double rate )
603 CAudioRendererPinImpl_THIS(pImpl,pin);
605 FIXME( "(%p)\n", This );
607 This->pRender->m_fInFlush = FALSE;
612 static const CBasePinHandlers pinhandlers =
614 NULL, /* pOnPreConnect */
615 NULL, /* pOnPostConnect */
616 CAudioRendererPinImpl_OnDisconnect, /* pOnDisconnect */
617 CAudioRendererPinImpl_CheckMediaType, /* pCheckMediaType */
618 NULL, /* pQualityNotify */
619 CAudioRendererPinImpl_Receive, /* pReceive */
620 CAudioRendererPinImpl_ReceiveCanBlock, /* pReceiveCanBlock */
621 CAudioRendererPinImpl_EndOfStream, /* pEndOfStream */
622 CAudioRendererPinImpl_BeginFlush, /* pBeginFlush */
623 CAudioRendererPinImpl_EndFlush, /* pEndFlush */
624 CAudioRendererPinImpl_NewSegment, /* pNewSegment */
628 /***************************************************************************
630 * new/delete CAudioRendererImpl
634 /* can I use offsetof safely? - FIXME? */
635 static QUARTZ_IFEntry FilterIFEntries[] =
637 { &IID_IPersist, offsetof(CAudioRendererImpl,basefilter)-offsetof(CAudioRendererImpl,unk) },
638 { &IID_IMediaFilter, offsetof(CAudioRendererImpl,basefilter)-offsetof(CAudioRendererImpl,unk) },
639 { &IID_IBaseFilter, offsetof(CAudioRendererImpl,basefilter)-offsetof(CAudioRendererImpl,unk) },
640 { &IID_IBasicAudio, offsetof(CAudioRendererImpl,basaud)-offsetof(CAudioRendererImpl,unk) },
643 static HRESULT CAudioRendererImpl_OnQueryInterface(
644 IUnknown* punk, const IID* piid, void** ppobj )
646 CAudioRendererImpl_THIS(punk,unk);
648 if ( This->pSeekPass == NULL )
649 return E_NOINTERFACE;
651 if ( IsEqualGUID( &IID_IMediaPosition, piid ) ||
652 IsEqualGUID( &IID_IMediaSeeking, piid ) )
654 TRACE( "IMediaSeeking(or IMediaPosition) is queried\n" );
655 return IUnknown_QueryInterface( (IUnknown*)(&This->pSeekPass->unk), piid, ppobj );
658 return E_NOINTERFACE;
661 static void QUARTZ_DestroyAudioRenderer(IUnknown* punk)
663 CAudioRendererImpl_THIS(punk,unk);
665 TRACE( "(%p)\n", This );
667 if ( This->pPin != NULL )
669 IUnknown_Release(This->pPin->unk.punkControl);
672 if ( This->pSeekPass != NULL )
674 IUnknown_Release((IUnknown*)&This->pSeekPass->unk);
675 This->pSeekPass = NULL;
678 CAudioRendererImpl_UninitIBasicAudio(This);
679 CBaseFilterImpl_UninitIBaseFilter(&This->basefilter);
681 DeleteCriticalSection( &This->m_csReceive );
684 HRESULT QUARTZ_CreateAudioRenderer(IUnknown* punkOuter,void** ppobj)
686 CAudioRendererImpl* This = NULL;
689 TRACE("(%p,%p)\n",punkOuter,ppobj);
691 This = (CAudioRendererImpl*)
692 QUARTZ_AllocObj( sizeof(CAudioRendererImpl) );
694 return E_OUTOFMEMORY;
695 This->pSeekPass = NULL;
697 This->m_fInFlush = FALSE;
698 This->m_fWaveOutInit = FALSE;
699 This->m_hEventRender = (HANDLE)NULL;
701 QUARTZ_IUnkInit( &This->unk, punkOuter );
702 This->qiext.pNext = NULL;
703 This->qiext.pOnQueryInterface = &CAudioRendererImpl_OnQueryInterface;
704 QUARTZ_IUnkAddDelegation( &This->unk, &This->qiext );
706 hr = CBaseFilterImpl_InitIBaseFilter(
708 This->unk.punkControl,
710 QUARTZ_AudioRender_Name,
714 hr = CAudioRendererImpl_InitIBasicAudio(This);
717 CBaseFilterImpl_UninitIBaseFilter(&This->basefilter);
723 QUARTZ_FreeObj(This);
727 This->unk.pEntries = FilterIFEntries;
728 This->unk.dwEntries = sizeof(FilterIFEntries)/sizeof(FilterIFEntries[0]);
729 This->unk.pOnFinalRelease = QUARTZ_DestroyAudioRenderer;
731 InitializeCriticalSection( &This->m_csReceive );
733 hr = QUARTZ_CreateAudioRendererPin(
735 &This->basefilter.csFilter,
739 hr = QUARTZ_CompList_AddComp(
740 This->basefilter.pInPins,
741 (IUnknown*)&This->pPin->pin,
744 hr = QUARTZ_CreateSeekingPassThruInternal(
745 (IUnknown*)&(This->unk), &This->pSeekPass,
746 TRUE, (IPin*)&(This->pPin->pin) );
750 IUnknown_Release( This->unk.punkControl );
754 *ppobj = (void*)&(This->unk);
760 /***************************************************************************
762 * new/delete CAudioRendererPinImpl
766 /* can I use offsetof safely? - FIXME? */
767 static QUARTZ_IFEntry PinIFEntries[] =
769 { &IID_IPin, offsetof(CAudioRendererPinImpl,pin)-offsetof(CAudioRendererPinImpl,unk) },
770 { &IID_IMemInputPin, offsetof(CAudioRendererPinImpl,meminput)-offsetof(CAudioRendererPinImpl,unk) },
773 static void QUARTZ_DestroyAudioRendererPin(IUnknown* punk)
775 CAudioRendererPinImpl_THIS(punk,unk);
777 TRACE( "(%p)\n", This );
779 CPinBaseImpl_UninitIPin( &This->pin );
780 CMemInputPinBaseImpl_UninitIMemInputPin( &This->meminput );
783 HRESULT QUARTZ_CreateAudioRendererPin(
784 CAudioRendererImpl* pFilter,
785 CRITICAL_SECTION* pcsPin,
786 CRITICAL_SECTION* pcsPinReceive,
787 CAudioRendererPinImpl** ppPin)
789 CAudioRendererPinImpl* This = NULL;
792 TRACE("(%p,%p,%p,%p)\n",pFilter,pcsPin,pcsPinReceive,ppPin);
794 This = (CAudioRendererPinImpl*)
795 QUARTZ_AllocObj( sizeof(CAudioRendererPinImpl) );
797 return E_OUTOFMEMORY;
799 QUARTZ_IUnkInit( &This->unk, NULL );
800 This->pRender = pFilter;
802 hr = CPinBaseImpl_InitIPin(
804 This->unk.punkControl,
805 pcsPin, pcsPinReceive,
806 &pFilter->basefilter,
807 QUARTZ_AudioRenderPin_Name,
813 hr = CMemInputPinBaseImpl_InitIMemInputPin(
815 This->unk.punkControl,
819 CPinBaseImpl_UninitIPin( &This->pin );
825 QUARTZ_FreeObj(This);
829 This->unk.pEntries = PinIFEntries;
830 This->unk.dwEntries = sizeof(PinIFEntries)/sizeof(PinIFEntries[0]);
831 This->unk.pOnFinalRelease = QUARTZ_DestroyAudioRendererPin;
835 TRACE("returned successfully.\n");
841 /***************************************************************************
843 * CAudioRendererImpl::IBasicAudio
847 static HRESULT WINAPI
848 IBasicAudio_fnQueryInterface(IBasicAudio* iface,REFIID riid,void** ppobj)
850 CAudioRendererImpl_THIS(iface,basaud);
852 TRACE("(%p)->()\n",This);
854 return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
858 IBasicAudio_fnAddRef(IBasicAudio* iface)
860 CAudioRendererImpl_THIS(iface,basaud);
862 TRACE("(%p)->()\n",This);
864 return IUnknown_AddRef(This->unk.punkControl);
868 IBasicAudio_fnRelease(IBasicAudio* iface)
870 CAudioRendererImpl_THIS(iface,basaud);
872 TRACE("(%p)->()\n",This);
874 return IUnknown_Release(This->unk.punkControl);
877 static HRESULT WINAPI
878 IBasicAudio_fnGetTypeInfoCount(IBasicAudio* iface,UINT* pcTypeInfo)
880 CAudioRendererImpl_THIS(iface,basaud);
882 FIXME("(%p)->()\n",This);
887 static HRESULT WINAPI
888 IBasicAudio_fnGetTypeInfo(IBasicAudio* iface,UINT iTypeInfo, LCID lcid, ITypeInfo** ppobj)
890 CAudioRendererImpl_THIS(iface,basaud);
892 FIXME("(%p)->()\n",This);
897 static HRESULT WINAPI
898 IBasicAudio_fnGetIDsOfNames(IBasicAudio* iface,REFIID riid, LPOLESTR* ppwszName, UINT cNames, LCID lcid, DISPID* pDispId)
900 CAudioRendererImpl_THIS(iface,basaud);
902 FIXME("(%p)->()\n",This);
907 static HRESULT WINAPI
908 IBasicAudio_fnInvoke(IBasicAudio* iface,DISPID DispId, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarRes, EXCEPINFO* pExcepInfo, UINT* puArgErr)
910 CAudioRendererImpl_THIS(iface,basaud);
912 FIXME("(%p)->()\n",This);
918 static HRESULT WINAPI
919 IBasicAudio_fnput_Volume(IBasicAudio* iface,long lVol)
921 CAudioRendererImpl_THIS(iface,basaud);
923 FIXME("(%p)->()\n",This);
928 static HRESULT WINAPI
929 IBasicAudio_fnget_Volume(IBasicAudio* iface,long* plVol)
931 CAudioRendererImpl_THIS(iface,basaud);
933 FIXME("(%p)->()\n",This);
938 static HRESULT WINAPI
939 IBasicAudio_fnput_Balance(IBasicAudio* iface,long lBalance)
941 CAudioRendererImpl_THIS(iface,basaud);
943 FIXME("(%p)->()\n",This);
948 static HRESULT WINAPI
949 IBasicAudio_fnget_Balance(IBasicAudio* iface,long* plBalance)
951 CAudioRendererImpl_THIS(iface,basaud);
953 FIXME("(%p)->()\n",This);
959 static ICOM_VTABLE(IBasicAudio) ibasicaudio =
961 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
962 /* IUnknown fields */
963 IBasicAudio_fnQueryInterface,
964 IBasicAudio_fnAddRef,
965 IBasicAudio_fnRelease,
966 /* IDispatch fields */
967 IBasicAudio_fnGetTypeInfoCount,
968 IBasicAudio_fnGetTypeInfo,
969 IBasicAudio_fnGetIDsOfNames,
970 IBasicAudio_fnInvoke,
971 /* IBasicAudio fields */
972 IBasicAudio_fnput_Volume,
973 IBasicAudio_fnget_Volume,
974 IBasicAudio_fnput_Balance,
975 IBasicAudio_fnget_Balance,
979 HRESULT CAudioRendererImpl_InitIBasicAudio( CAudioRendererImpl* This )
981 TRACE("(%p)\n",This);
982 ICOM_VTBL(&This->basaud) = &ibasicaudio;
987 void CAudioRendererImpl_UninitIBasicAudio( CAudioRendererImpl* This )
989 TRACE("(%p)\n",This);