2 * Audio Renderer (CLSID_AudioRender)
5 * - implement IReferenceClock.
7 * Copyright (C) Hidenori TAKESHIMA <hidenori@a2.ctktv.ne.jp>
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
38 #include "wine/debug.h"
39 WINE_DEFAULT_DEBUG_CHANNEL(quartz);
41 #include "quartz_private.h"
46 static const WCHAR QUARTZ_AudioRender_Name[] =
47 { 'A','u','d','i','o',' ','R','e','n','d','e','r',0 };
48 static const WCHAR QUARTZ_AudioRenderPin_Name[] =
53 /***************************************************************************
55 * CAudioRendererImpl waveOut methods (internal)
60 HRESULT QUARTZ_HRESULT_From_MMRESULT( MMRESULT mr )
66 case MMSYSERR_NOERROR:
77 void CAudioRendererImpl_waveOutEventCallback(
78 HWAVEOUT hwo, UINT uMsg,
79 DWORD dwInstance, DWORD dwParam1, DWORD dwParam2 )
81 CAudioRendererImpl* This = (CAudioRendererImpl*)dwInstance;
83 if ( uMsg == WOM_DONE )
84 SetEvent( This->m_hEventRender );
88 void CAudioRendererImpl_waveOutReset(
89 CAudioRendererImpl* This )
91 if ( !This->m_fWaveOutInit )
94 waveOutReset( This->m_hWaveOut );
95 SetEvent( This->m_hEventRender );
99 void CAudioRendererImpl_waveOutUninit(
100 CAudioRendererImpl* This )
104 TRACE("(%p)\n",This);
106 if ( !This->m_fWaveOutInit )
109 waveOutReset( This->m_hWaveOut );
110 SetEvent( This->m_hEventRender );
112 for ( i = 0; i < WINE_QUARTZ_WAVEOUT_COUNT; i++ )
114 if ( This->m_hdr[i].dwFlags & WHDR_PREPARED )
116 waveOutUnprepareHeader(
118 &This->m_hdr[i], sizeof(WAVEHDR) );
119 This->m_hdr[i].dwFlags = 0;
121 if ( This->m_hdr[i].lpData != NULL )
123 QUARTZ_FreeMem( This->m_hdr[i].lpData );
124 This->m_hdr[i].lpData = NULL;
128 waveOutClose( This->m_hWaveOut );
129 This->m_hWaveOut = (HWAVEOUT)NULL;
130 if ( This->m_hEventRender != (HANDLE)NULL )
132 CloseHandle( This->m_hEventRender );
133 This->m_hEventRender = (HANDLE)NULL;
136 This->m_fWaveOutInit = FALSE;
140 HRESULT CAudioRendererImpl_waveOutInit(
141 CAudioRendererImpl* This, WAVEFORMATEX* pwfx )
148 if ( This->m_fWaveOutInit )
153 if ( pwfx->nBlockAlign == 0 )
156 This->m_hEventRender = (HANDLE)NULL;
157 This->m_hWaveOut = (HWAVEOUT)NULL;
158 This->m_dwBlockSize = 0;
159 This->m_phdrCur = NULL;
160 ZeroMemory( &This->m_hdr, sizeof(This->m_hdr) );
164 &This->m_hWaveOut, WAVE_MAPPER, pwfx,
165 (DWORD)CAudioRendererImpl_waveOutEventCallback, (DWORD)This,
167 hr = QUARTZ_HRESULT_From_MMRESULT( mr );
170 This->m_fWaveOutInit = TRUE;
172 This->m_hEventRender = CreateEventA(
173 NULL, TRUE, TRUE, NULL );
174 if ( This->m_hEventRender == (HANDLE)NULL )
180 dwBlockSize = pwfx->nAvgBytesPerSec / pwfx->nBlockAlign;
181 if ( dwBlockSize == 0 )
183 dwBlockSize *= pwfx->nBlockAlign;
184 This->m_dwBlockSize = dwBlockSize;
186 for ( i = 0; i < WINE_QUARTZ_WAVEOUT_COUNT; i++ )
188 This->m_hdr[i].lpData = (CHAR*)QUARTZ_AllocMem( dwBlockSize );
189 if ( This->m_hdr[i].lpData == NULL )
194 mr = waveOutPrepareHeader(
196 &This->m_hdr[i], sizeof(WAVEHDR) );
197 hr = QUARTZ_HRESULT_From_MMRESULT( mr );
200 This->m_hdr[i].dwFlags |= WHDR_DONE;
201 This->m_hdr[i].dwBufferLength = dwBlockSize;
202 This->m_hdr[i].dwUser = i;
207 CAudioRendererImpl_waveOutUninit(This);
211 static HRESULT CAudioRendererImpl_waveOutPause( CAudioRendererImpl* This )
213 if ( !This->m_fWaveOutInit )
216 return QUARTZ_HRESULT_From_MMRESULT( waveOutPause(
217 This->m_hWaveOut ) );
220 static HRESULT CAudioRendererImpl_waveOutRun( CAudioRendererImpl* This )
222 if ( !This->m_fWaveOutInit )
225 return QUARTZ_HRESULT_From_MMRESULT( waveOutRestart(
226 This->m_hWaveOut ) );
230 WAVEHDR* CAudioRendererImpl_waveOutGetBuffer(
231 CAudioRendererImpl* This )
235 if ( !This->m_fWaveOutInit )
238 if ( This->m_phdrCur != NULL )
239 return This->m_phdrCur;
241 for ( i = 0; i < WINE_QUARTZ_WAVEOUT_COUNT; i++ )
243 if ( This->m_hdr[i].dwFlags & WHDR_DONE )
245 This->m_phdrCur = &(This->m_hdr[i]);
246 This->m_phdrCur->dwFlags &= ~WHDR_DONE;
247 This->m_phdrCur->dwBufferLength = 0;
248 return This->m_phdrCur;
256 HRESULT CAudioRendererImpl_waveOutWriteData(
257 CAudioRendererImpl* This,
258 const BYTE* pData, DWORD cbData, DWORD* pcbWritten )
264 if ( !This->m_fWaveOutInit )
270 if ( CAudioRendererImpl_waveOutGetBuffer(This) == NULL )
273 cbAvail = This->m_dwBlockSize - This->m_phdrCur->dwBufferLength;
274 if ( cbAvail > cbData )
276 memcpy( This->m_phdrCur->lpData, pData, cbAvail );
279 This->m_phdrCur->dwBufferLength += cbAvail;
281 *pcbWritten = cbAvail;
287 HRESULT CAudioRendererImpl_waveOutFlush(
288 CAudioRendererImpl* This )
293 if ( !This->m_fWaveOutInit )
295 if ( This->m_phdrCur == NULL )
298 if ( This->m_phdrCur->dwBufferLength == 0 )
303 This->m_phdrCur, sizeof(WAVEHDR) );
304 hr = QUARTZ_HRESULT_From_MMRESULT( mr );
308 This->m_phdrCur = NULL;
313 /* FIXME: Not used for now */
316 HRESULT CAudioRendererImpl_waveOutGetVolume(
317 CAudioRendererImpl* This,
318 DWORD* pdwLeft, DWORD* pdwRight )
324 if ( !This->m_fWaveOutInit )
327 mr = waveOutGetVolume(
328 This->m_hWaveOut, &dwVol );
329 hr = QUARTZ_HRESULT_From_MMRESULT( mr );
333 *pdwLeft = LOWORD(dwVol);
334 *pdwRight = HIWORD(dwVol);
342 HRESULT CAudioRendererImpl_waveOutSetVolume(
343 CAudioRendererImpl* This,
344 DWORD dwLeft, DWORD dwRight )
349 if ( !This->m_fWaveOutInit )
352 dwVol = dwLeft | (dwRight<<16);
354 mr = waveOutSetVolume(
355 This->m_hWaveOut, dwVol );
356 return QUARTZ_HRESULT_From_MMRESULT( mr );
359 static HRESULT CAudioRendererImpl_UpdateVolume( CAudioRendererImpl* This )
365 if ( This->m_lAudioBalance >= 0 )
367 leftlevel = This->m_lAudioVolume - This->m_lAudioBalance;
368 rightlevel = This->m_lAudioVolume;
372 leftlevel = This->m_lAudioVolume;
373 rightlevel = This->m_lAudioVolume + This->m_lAudioBalance;
375 leftlevel = QUARTZ_DBToAmpFactor( leftlevel );
376 rightlevel = QUARTZ_DBToAmpFactor( rightlevel );
378 hr = CAudioRendererImpl_waveOutSetVolume(
379 This, (DWORD)leftlevel, (DWORD)rightlevel );
380 if ( hr == E_UNEXPECTED )
387 /***************************************************************************
389 * CAudioRendererImpl methods
394 static HRESULT CAudioRendererImpl_OnActive( CBaseFilterImpl* pImpl )
396 CAudioRendererImpl_THIS(pImpl,basefilter);
399 FIXME( "(%p)\n", This );
401 if ( This->pPin->pin.pmtConn == NULL )
404 This->m_fInFlush = FALSE;
406 hr = CAudioRendererImpl_waveOutRun(This);
413 static HRESULT CAudioRendererImpl_OnInactive( CBaseFilterImpl* pImpl )
415 CAudioRendererImpl_THIS(pImpl,basefilter);
419 FIXME( "(%p)\n", This );
421 if ( This->pPin->pin.pmtConn == NULL )
424 pwfx = (WAVEFORMATEX*)This->pPin->pin.pmtConn->pbFormat;
428 This->m_fInFlush = FALSE;
430 hr = CAudioRendererImpl_waveOutInit(This,pwfx);
434 hr = CAudioRendererImpl_waveOutPause(This);
441 static HRESULT CAudioRendererImpl_OnStop( CBaseFilterImpl* pImpl )
443 CAudioRendererImpl_THIS(pImpl,basefilter);
445 FIXME( "(%p)\n", This );
447 This->m_fInFlush = TRUE;
449 CAudioRendererImpl_waveOutUninit(This);
451 This->m_fInFlush = FALSE;
453 TRACE("returned\n" );
458 static const CBaseFilterHandlers filterhandlers =
460 CAudioRendererImpl_OnActive, /* pOnActive */
461 CAudioRendererImpl_OnInactive, /* pOnInactive */
462 CAudioRendererImpl_OnStop, /* pOnStop */
465 /***************************************************************************
467 * CAudioRendererPinImpl methods
471 static HRESULT CAudioRendererPinImpl_OnDisconnect( CPinBaseImpl* pImpl )
473 CAudioRendererPinImpl_THIS(pImpl,pin);
475 TRACE("(%p)\n",This);
477 if ( This->meminput.pAllocator != NULL )
479 IMemAllocator_Decommit(This->meminput.pAllocator);
480 IMemAllocator_Release(This->meminput.pAllocator);
481 This->meminput.pAllocator = NULL;
488 static HRESULT CAudioRendererPinImpl_CheckMediaType( CPinBaseImpl* pImpl, const AM_MEDIA_TYPE* pmt )
490 CAudioRendererPinImpl_THIS(pImpl,pin);
491 const WAVEFORMATEX* pwfx;
493 TRACE("(%p,%p)\n",This,pmt);
495 if ( !IsEqualGUID( &pmt->majortype, &MEDIATYPE_Audio ) )
497 TRACE("not audio\n");
500 if ( !IsEqualGUID( &pmt->subtype, &MEDIASUBTYPE_NULL ) &&
501 !IsEqualGUID( &pmt->subtype, &MEDIASUBTYPE_PCM ) )
506 if ( !IsEqualGUID( &pmt->formattype, &FORMAT_WaveFormatEx ) )
512 TRACE("testing WAVE header\n");
514 if ( pmt->cbFormat < (sizeof(WAVEFORMATEX)-sizeof(WORD)) )
517 pwfx = (const WAVEFORMATEX*)pmt->pbFormat;
520 if ( pwfx->wFormatTag != 1 )
523 TRACE("returned successfully.\n");
528 static HRESULT CAudioRendererPinImpl_Receive( CPinBaseImpl* pImpl, IMediaSample* pSample )
530 CAudioRendererPinImpl_THIS(pImpl,pin);
536 TRACE( "(%p,%p)\n",This,pSample );
538 if ( !This->pRender->m_fWaveOutInit )
540 if ( pSample == NULL )
543 hr = IMediaSample_GetPointer( pSample, &pData );
546 dwDataLength = (DWORD)IMediaSample_GetActualDataLength( pSample );
550 TRACE("trying to write %lu bytes\n",dwDataLength);
552 if ( This->pRender->m_fInFlush )
555 ResetEvent( This->pRender->m_hEventRender );
556 hr = CAudioRendererImpl_waveOutWriteData(
557 This->pRender,pData,dwDataLength,&dwWritten);
562 WaitForSingleObject( This->pRender->m_hEventRender, INFINITE );
566 dwDataLength -= dwWritten;
567 hr = CAudioRendererImpl_waveOutFlush(This->pRender);
570 if ( dwDataLength == 0 )
577 static HRESULT CAudioRendererPinImpl_ReceiveCanBlock( CPinBaseImpl* pImpl )
579 CAudioRendererPinImpl_THIS(pImpl,pin);
581 TRACE( "(%p)\n", This );
587 static HRESULT CAudioRendererPinImpl_EndOfStream( CPinBaseImpl* pImpl )
589 CAudioRendererPinImpl_THIS(pImpl,pin);
591 FIXME( "(%p)\n", This );
593 This->pRender->m_fInFlush = FALSE;
595 /* FIXME - don't notify twice until stopped or seeked. */
596 return CBaseFilterImpl_MediaEventNotify(
597 &This->pRender->basefilter, EC_COMPLETE,
598 (LONG_PTR)S_OK, (LONG_PTR)(IBaseFilter*)(This->pRender) );
601 static HRESULT CAudioRendererPinImpl_BeginFlush( CPinBaseImpl* pImpl )
603 CAudioRendererPinImpl_THIS(pImpl,pin);
605 FIXME( "(%p)\n", This );
607 This->pRender->m_fInFlush = TRUE;
608 CAudioRendererImpl_waveOutReset(This->pRender);
613 static HRESULT CAudioRendererPinImpl_EndFlush( CPinBaseImpl* pImpl )
615 CAudioRendererPinImpl_THIS(pImpl,pin);
617 FIXME( "(%p)\n", This );
619 This->pRender->m_fInFlush = FALSE;
624 static HRESULT CAudioRendererPinImpl_NewSegment( CPinBaseImpl* pImpl, REFERENCE_TIME rtStart, REFERENCE_TIME rtStop, double rate )
626 CAudioRendererPinImpl_THIS(pImpl,pin);
628 FIXME( "(%p)\n", This );
630 This->pRender->m_fInFlush = FALSE;
635 static const CBasePinHandlers pinhandlers =
637 NULL, /* pOnPreConnect */
638 NULL, /* pOnPostConnect */
639 CAudioRendererPinImpl_OnDisconnect, /* pOnDisconnect */
640 CAudioRendererPinImpl_CheckMediaType, /* pCheckMediaType */
641 NULL, /* pQualityNotify */
642 CAudioRendererPinImpl_Receive, /* pReceive */
643 CAudioRendererPinImpl_ReceiveCanBlock, /* pReceiveCanBlock */
644 CAudioRendererPinImpl_EndOfStream, /* pEndOfStream */
645 CAudioRendererPinImpl_BeginFlush, /* pBeginFlush */
646 CAudioRendererPinImpl_EndFlush, /* pEndFlush */
647 CAudioRendererPinImpl_NewSegment, /* pNewSegment */
651 /***************************************************************************
653 * new/delete CAudioRendererImpl
657 /* can I use offsetof safely? - FIXME? */
658 static QUARTZ_IFEntry FilterIFEntries[] =
660 { &IID_IPersist, offsetof(CAudioRendererImpl,basefilter)-offsetof(CAudioRendererImpl,unk) },
661 { &IID_IMediaFilter, offsetof(CAudioRendererImpl,basefilter)-offsetof(CAudioRendererImpl,unk) },
662 { &IID_IBaseFilter, offsetof(CAudioRendererImpl,basefilter)-offsetof(CAudioRendererImpl,unk) },
663 { &IID_IBasicAudio, offsetof(CAudioRendererImpl,basaud)-offsetof(CAudioRendererImpl,unk) },
666 static HRESULT CAudioRendererImpl_OnQueryInterface(
667 IUnknown* punk, const IID* piid, void** ppobj )
669 CAudioRendererImpl_THIS(punk,unk);
671 if ( This->pSeekPass == NULL )
672 return E_NOINTERFACE;
674 if ( IsEqualGUID( &IID_IMediaPosition, piid ) ||
675 IsEqualGUID( &IID_IMediaSeeking, piid ) )
677 TRACE( "IMediaSeeking(or IMediaPosition) is queried\n" );
678 return IUnknown_QueryInterface( (IUnknown*)(&This->pSeekPass->unk), piid, ppobj );
681 return E_NOINTERFACE;
684 static void QUARTZ_DestroyAudioRenderer(IUnknown* punk)
686 CAudioRendererImpl_THIS(punk,unk);
688 TRACE( "(%p)\n", This );
690 if ( This->pPin != NULL )
692 IUnknown_Release(This->pPin->unk.punkControl);
695 if ( This->pSeekPass != NULL )
697 IUnknown_Release((IUnknown*)&This->pSeekPass->unk);
698 This->pSeekPass = NULL;
701 CAudioRendererImpl_UninitIBasicAudio(This);
702 CBaseFilterImpl_UninitIBaseFilter(&This->basefilter);
704 DeleteCriticalSection( &This->m_csReceive );
707 HRESULT QUARTZ_CreateAudioRenderer(IUnknown* punkOuter,void** ppobj)
709 CAudioRendererImpl* This = NULL;
712 TRACE("(%p,%p)\n",punkOuter,ppobj);
714 This = (CAudioRendererImpl*)
715 QUARTZ_AllocObj( sizeof(CAudioRendererImpl) );
717 return E_OUTOFMEMORY;
718 This->pSeekPass = NULL;
720 This->m_fInFlush = FALSE;
721 This->m_lAudioVolume = 0;
722 This->m_lAudioBalance = 0;
723 This->m_fWaveOutInit = FALSE;
724 This->m_hEventRender = (HANDLE)NULL;
726 QUARTZ_IUnkInit( &This->unk, punkOuter );
727 This->qiext.pNext = NULL;
728 This->qiext.pOnQueryInterface = &CAudioRendererImpl_OnQueryInterface;
729 QUARTZ_IUnkAddDelegation( &This->unk, &This->qiext );
731 hr = CBaseFilterImpl_InitIBaseFilter(
733 This->unk.punkControl,
735 QUARTZ_AudioRender_Name,
739 hr = CAudioRendererImpl_InitIBasicAudio(This);
742 CBaseFilterImpl_UninitIBaseFilter(&This->basefilter);
748 QUARTZ_FreeObj(This);
752 This->unk.pEntries = FilterIFEntries;
753 This->unk.dwEntries = sizeof(FilterIFEntries)/sizeof(FilterIFEntries[0]);
754 This->unk.pOnFinalRelease = QUARTZ_DestroyAudioRenderer;
756 InitializeCriticalSection( &This->m_csReceive );
758 hr = QUARTZ_CreateAudioRendererPin(
760 &This->basefilter.csFilter,
764 hr = QUARTZ_CompList_AddComp(
765 This->basefilter.pInPins,
766 (IUnknown*)&This->pPin->pin,
769 hr = QUARTZ_CreateSeekingPassThruInternal(
770 (IUnknown*)&(This->unk), &This->pSeekPass,
771 TRUE, (IPin*)&(This->pPin->pin) );
775 IUnknown_Release( This->unk.punkControl );
779 *ppobj = (void*)&(This->unk);
785 /***************************************************************************
787 * new/delete CAudioRendererPinImpl
791 /* can I use offsetof safely? - FIXME? */
792 static QUARTZ_IFEntry PinIFEntries[] =
794 { &IID_IPin, offsetof(CAudioRendererPinImpl,pin)-offsetof(CAudioRendererPinImpl,unk) },
795 { &IID_IMemInputPin, offsetof(CAudioRendererPinImpl,meminput)-offsetof(CAudioRendererPinImpl,unk) },
798 static void QUARTZ_DestroyAudioRendererPin(IUnknown* punk)
800 CAudioRendererPinImpl_THIS(punk,unk);
802 TRACE( "(%p)\n", This );
804 CPinBaseImpl_UninitIPin( &This->pin );
805 CMemInputPinBaseImpl_UninitIMemInputPin( &This->meminput );
808 HRESULT QUARTZ_CreateAudioRendererPin(
809 CAudioRendererImpl* pFilter,
810 CRITICAL_SECTION* pcsPin,
811 CRITICAL_SECTION* pcsPinReceive,
812 CAudioRendererPinImpl** ppPin)
814 CAudioRendererPinImpl* This = NULL;
817 TRACE("(%p,%p,%p,%p)\n",pFilter,pcsPin,pcsPinReceive,ppPin);
819 This = (CAudioRendererPinImpl*)
820 QUARTZ_AllocObj( sizeof(CAudioRendererPinImpl) );
822 return E_OUTOFMEMORY;
824 QUARTZ_IUnkInit( &This->unk, NULL );
825 This->pRender = pFilter;
827 hr = CPinBaseImpl_InitIPin(
829 This->unk.punkControl,
830 pcsPin, pcsPinReceive,
831 &pFilter->basefilter,
832 QUARTZ_AudioRenderPin_Name,
838 hr = CMemInputPinBaseImpl_InitIMemInputPin(
840 This->unk.punkControl,
844 CPinBaseImpl_UninitIPin( &This->pin );
850 QUARTZ_FreeObj(This);
854 This->unk.pEntries = PinIFEntries;
855 This->unk.dwEntries = sizeof(PinIFEntries)/sizeof(PinIFEntries[0]);
856 This->unk.pOnFinalRelease = QUARTZ_DestroyAudioRendererPin;
860 TRACE("returned successfully.\n");
866 /***************************************************************************
868 * CAudioRendererImpl::IBasicAudio
872 static HRESULT WINAPI
873 IBasicAudio_fnQueryInterface(IBasicAudio* iface,REFIID riid,void** ppobj)
875 CAudioRendererImpl_THIS(iface,basaud);
877 TRACE("(%p)->()\n",This);
879 return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
883 IBasicAudio_fnAddRef(IBasicAudio* iface)
885 CAudioRendererImpl_THIS(iface,basaud);
887 TRACE("(%p)->()\n",This);
889 return IUnknown_AddRef(This->unk.punkControl);
893 IBasicAudio_fnRelease(IBasicAudio* iface)
895 CAudioRendererImpl_THIS(iface,basaud);
897 TRACE("(%p)->()\n",This);
899 return IUnknown_Release(This->unk.punkControl);
902 static HRESULT WINAPI
903 IBasicAudio_fnGetTypeInfoCount(IBasicAudio* iface,UINT* pcTypeInfo)
905 CAudioRendererImpl_THIS(iface,basaud);
907 FIXME("(%p)->()\n",This);
912 static HRESULT WINAPI
913 IBasicAudio_fnGetTypeInfo(IBasicAudio* iface,UINT iTypeInfo, LCID lcid, ITypeInfo** ppobj)
915 CAudioRendererImpl_THIS(iface,basaud);
917 FIXME("(%p)->()\n",This);
922 static HRESULT WINAPI
923 IBasicAudio_fnGetIDsOfNames(IBasicAudio* iface,REFIID riid, LPOLESTR* ppwszName, UINT cNames, LCID lcid, DISPID* pDispId)
925 CAudioRendererImpl_THIS(iface,basaud);
927 FIXME("(%p)->()\n",This);
932 static HRESULT WINAPI
933 IBasicAudio_fnInvoke(IBasicAudio* iface,DISPID DispId, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarRes, EXCEPINFO* pExcepInfo, UINT* puArgErr)
935 CAudioRendererImpl_THIS(iface,basaud);
937 FIXME("(%p)->()\n",This);
943 static HRESULT WINAPI
944 IBasicAudio_fnput_Volume(IBasicAudio* iface,long lVol)
946 CAudioRendererImpl_THIS(iface,basaud);
949 FIXME("(%p)->(%ld)\n",This,lVol);
951 if ( lVol > 0 || lVol < -10000 )
954 EnterCriticalSection( &This->basefilter.csFilter );
955 This->m_lAudioVolume = lVol;
956 hr = CAudioRendererImpl_UpdateVolume( This );
957 LeaveCriticalSection( &This->basefilter.csFilter );
962 static HRESULT WINAPI
963 IBasicAudio_fnget_Volume(IBasicAudio* iface,long* plVol)
965 CAudioRendererImpl_THIS(iface,basaud);
967 FIXME("(%p)->(%p)\n",This,plVol);
972 EnterCriticalSection( &This->basefilter.csFilter );
973 *plVol = This->m_lAudioVolume;
974 LeaveCriticalSection( &This->basefilter.csFilter );
979 static HRESULT WINAPI
980 IBasicAudio_fnput_Balance(IBasicAudio* iface,long lBalance)
982 CAudioRendererImpl_THIS(iface,basaud);
985 FIXME("(%p)->(%ld)\n",This,lBalance);
987 if ( lBalance > 0 || lBalance < -10000 )
990 EnterCriticalSection( &This->basefilter.csFilter );
991 This->m_lAudioBalance = lBalance;
992 hr = CAudioRendererImpl_UpdateVolume( This );
993 LeaveCriticalSection( &This->basefilter.csFilter );
998 static HRESULT WINAPI
999 IBasicAudio_fnget_Balance(IBasicAudio* iface,long* plBalance)
1001 CAudioRendererImpl_THIS(iface,basaud);
1003 FIXME("(%p)->(%p)\n",This,plBalance);
1005 if ( plBalance == NULL )
1008 EnterCriticalSection( &This->basefilter.csFilter );
1009 *plBalance = This->m_lAudioBalance;
1010 LeaveCriticalSection( &This->basefilter.csFilter );
1016 static ICOM_VTABLE(IBasicAudio) ibasicaudio =
1018 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1019 /* IUnknown fields */
1020 IBasicAudio_fnQueryInterface,
1021 IBasicAudio_fnAddRef,
1022 IBasicAudio_fnRelease,
1023 /* IDispatch fields */
1024 IBasicAudio_fnGetTypeInfoCount,
1025 IBasicAudio_fnGetTypeInfo,
1026 IBasicAudio_fnGetIDsOfNames,
1027 IBasicAudio_fnInvoke,
1028 /* IBasicAudio fields */
1029 IBasicAudio_fnput_Volume,
1030 IBasicAudio_fnget_Volume,
1031 IBasicAudio_fnput_Balance,
1032 IBasicAudio_fnget_Balance,
1036 HRESULT CAudioRendererImpl_InitIBasicAudio( CAudioRendererImpl* This )
1038 TRACE("(%p)\n",This);
1039 ICOM_VTBL(&This->basaud) = &ibasicaudio;
1044 void CAudioRendererImpl_UninitIBasicAudio( CAudioRendererImpl* This )
1046 TRACE("(%p)\n",This);