Started Implementing Video Renderer.
[wine/multimedia.git] / dlls / quartz / audren.c
blob50e613ea5b395fadf00a353b7baf3751060f6d36
1 /*
2 * Audio Renderer (CLSID_AudioRender)
4 * FIXME
5 * - implements IRefereneceClock.
6 * - implements seeking.
8 * hidenori@a2.ctktv.ne.jp
9 */
11 #include "config.h"
13 #include "windef.h"
14 #include "winbase.h"
15 #include "wingdi.h"
16 #include "winuser.h"
17 #include "mmsystem.h"
18 #include "winerror.h"
19 #include "wine/obj_base.h"
20 #include "wine/obj_oleaut.h"
21 #include "strmif.h"
22 #include "control.h"
23 #include "vfwmsgs.h"
24 #include "uuids.h"
25 #include "evcode.h"
27 #include "debugtools.h"
28 DEFAULT_DEBUG_CHANNEL(quartz);
30 #include "quartz_private.h"
31 #include "audren.h"
34 static const WCHAR QUARTZ_AudioRender_Name[] =
35 { 'A','u','d','i','o',' ','R','e','n','d','e','r',0 };
36 static const WCHAR QUARTZ_AudioRenderPin_Name[] =
37 { 'I','n',0 };
41 /***************************************************************************
43 * CAudioRendererImpl waveOut methods (internal)
47 static
48 HRESULT QUARTZ_HRESULT_From_MMRESULT( MMRESULT mr )
50 HRESULT hr = E_FAIL;
52 switch ( mr )
54 case MMSYSERR_NOERROR:
55 hr = S_OK;
56 break;
57 case MMSYSERR_NOMEM:
58 hr = E_OUTOFMEMORY;
59 break;
62 return hr;
65 void CAudioRendererImpl_waveOutEventCallback(
66 HWAVEOUT hwo, UINT uMsg,
67 DWORD dwInstance, DWORD dwParam1, DWORD dwParam2 )
69 CAudioRendererImpl* This = (CAudioRendererImpl*)dwInstance;
71 if ( uMsg == WOM_DONE )
72 SetEvent( This->m_hEventRender );
75 static
76 void CAudioRendererImpl_waveOutReset(
77 CAudioRendererImpl* This )
79 if ( !This->m_fWaveOutInit )
80 return;
82 waveOutReset( This->m_hWaveOut );
83 SetEvent( This->m_hEventRender );
86 static
87 void CAudioRendererImpl_waveOutUninit(
88 CAudioRendererImpl* This )
90 DWORD i;
92 TRACE("(%p)\n",This);
94 if ( !This->m_fWaveOutInit )
95 return;
97 waveOutReset( This->m_hWaveOut );
98 SetEvent( This->m_hEventRender );
100 for ( i = 0; i < WINE_QUARTZ_WAVEOUT_COUNT; i++ )
102 if ( This->m_hdr[i].dwFlags & WHDR_PREPARED )
104 waveOutUnprepareHeader(
105 This->m_hWaveOut,
106 &This->m_hdr[i], sizeof(WAVEHDR) );
107 This->m_hdr[i].dwFlags = 0;
109 if ( This->m_hdr[i].lpData != NULL )
111 QUARTZ_FreeMem( This->m_hdr[i].lpData );
112 This->m_hdr[i].lpData = NULL;
116 waveOutClose( This->m_hWaveOut );
117 This->m_hWaveOut = (HWAVEOUT)NULL;
118 if ( This->m_hEventRender != (HANDLE)NULL )
120 CloseHandle( This->m_hEventRender );
121 This->m_hEventRender = (HANDLE)NULL;
124 This->m_fWaveOutInit = FALSE;
127 static
128 HRESULT CAudioRendererImpl_waveOutInit(
129 CAudioRendererImpl* This, WAVEFORMATEX* pwfx )
131 MMRESULT mr;
132 HRESULT hr;
133 DWORD i;
134 DWORD dwBlockSize;
136 if ( This->m_fWaveOutInit )
137 return E_UNEXPECTED;
139 if ( pwfx == NULL )
140 return E_POINTER;
141 if ( pwfx->nBlockAlign == 0 )
142 return E_INVALIDARG;
144 This->m_hEventRender = (HANDLE)NULL;
145 This->m_hWaveOut = (HWAVEOUT)NULL;
146 This->m_dwBlockSize = 0;
147 This->m_phdrCur = NULL;
148 ZeroMemory( &This->m_hdr, sizeof(This->m_hdr) );
151 mr = waveOutOpen(
152 &This->m_hWaveOut, WAVE_MAPPER, pwfx,
153 (DWORD)CAudioRendererImpl_waveOutEventCallback, (DWORD)This,
154 CALLBACK_FUNCTION );
155 hr = QUARTZ_HRESULT_From_MMRESULT( mr );
156 if ( FAILED(hr) )
157 return hr;
158 This->m_fWaveOutInit = TRUE;
160 This->m_hEventRender = CreateEventA(
161 NULL, TRUE, TRUE, NULL );
162 if ( This->m_hEventRender == (HANDLE)NULL )
164 hr = E_OUTOFMEMORY;
165 goto err;
168 dwBlockSize = pwfx->nAvgBytesPerSec / pwfx->nBlockAlign;
169 if ( dwBlockSize == 0 )
170 dwBlockSize = 1;
171 dwBlockSize *= pwfx->nBlockAlign;
172 This->m_dwBlockSize = dwBlockSize;
174 for ( i = 0; i < WINE_QUARTZ_WAVEOUT_COUNT; i++ )
176 This->m_hdr[i].lpData = (CHAR*)QUARTZ_AllocMem( dwBlockSize );
177 if ( This->m_hdr[i].lpData == NULL )
179 hr = E_OUTOFMEMORY;
180 goto err;
182 mr = waveOutPrepareHeader(
183 This->m_hWaveOut,
184 &This->m_hdr[i], sizeof(WAVEHDR) );
185 hr = QUARTZ_HRESULT_From_MMRESULT( mr );
186 if ( FAILED(hr) )
187 goto err;
188 This->m_hdr[i].dwFlags |= WHDR_DONE;
189 This->m_hdr[i].dwBufferLength = dwBlockSize;
190 This->m_hdr[i].dwUser = i;
193 return S_OK;
194 err:
195 CAudioRendererImpl_waveOutUninit(This);
196 return hr;
199 static
200 WAVEHDR* CAudioRendererImpl_waveOutGetBuffer(
201 CAudioRendererImpl* This )
203 DWORD i;
205 if ( !This->m_fWaveOutInit )
206 return NULL;
208 if ( This->m_phdrCur != NULL )
209 return This->m_phdrCur;
211 for ( i = 0; i < WINE_QUARTZ_WAVEOUT_COUNT; i++ )
213 if ( This->m_hdr[i].dwFlags & WHDR_DONE )
215 This->m_phdrCur = &(This->m_hdr[i]);
216 This->m_phdrCur->dwFlags &= ~WHDR_DONE;
217 This->m_phdrCur->dwBufferLength = 0;
218 return This->m_phdrCur;
222 return NULL;
225 static
226 HRESULT CAudioRendererImpl_waveOutWriteData(
227 CAudioRendererImpl* This,
228 const BYTE* pData, DWORD cbData, DWORD* pcbWritten )
230 DWORD cbAvail;
232 *pcbWritten = 0;
234 if ( !This->m_fWaveOutInit )
235 return E_UNEXPECTED;
237 if ( cbData == 0 )
238 return S_OK;
240 if ( CAudioRendererImpl_waveOutGetBuffer(This) == NULL )
241 return S_FALSE;
243 cbAvail = This->m_dwBlockSize - This->m_phdrCur->dwBufferLength;
244 if ( cbAvail > cbData )
245 cbAvail = cbData;
246 memcpy( This->m_phdrCur->lpData, pData, cbAvail );
247 pData += cbAvail;
248 cbData -= cbAvail;
249 This->m_phdrCur->dwBufferLength += cbAvail;
251 *pcbWritten = cbAvail;
253 return S_OK;
256 static
257 HRESULT CAudioRendererImpl_waveOutFlush(
258 CAudioRendererImpl* This )
260 MMRESULT mr;
261 HRESULT hr;
263 if ( !This->m_fWaveOutInit )
264 return E_UNEXPECTED;
265 if ( This->m_phdrCur == NULL )
266 return E_UNEXPECTED;
268 if ( This->m_phdrCur->dwBufferLength == 0 )
269 return S_OK;
271 mr = waveOutWrite(
272 This->m_hWaveOut,
273 This->m_phdrCur, sizeof(WAVEHDR) );
274 hr = QUARTZ_HRESULT_From_MMRESULT( mr );
275 if ( FAILED(hr) )
276 return hr;
278 This->m_phdrCur = NULL;
279 return S_OK;
282 static
283 HRESULT CAudioRendererImpl_waveOutGetVolume(
284 CAudioRendererImpl* This,
285 DWORD* pdwLeft, DWORD* pdwRight )
287 MMRESULT mr;
288 HRESULT hr;
289 DWORD dwVol;
291 if ( !This->m_fWaveOutInit )
292 return E_UNEXPECTED;
294 mr = waveOutGetVolume(
295 This->m_hWaveOut, &dwVol );
296 hr = QUARTZ_HRESULT_From_MMRESULT( mr );
297 if ( FAILED(hr) )
298 return hr;
300 *pdwLeft = LOWORD(dwVol);
301 *pdwRight = HIWORD(dwVol);
303 return NOERROR;
306 static
307 HRESULT CAudioRendererImpl_waveOutSetVolume(
308 CAudioRendererImpl* This,
309 DWORD dwLeft, DWORD dwRight )
311 MMRESULT mr;
312 DWORD dwVol;
314 if ( !This->m_fWaveOutInit )
315 return E_UNEXPECTED;
317 dwVol = dwLeft | (dwRight<<16);
319 mr = waveOutSetVolume(
320 This->m_hWaveOut, dwVol );
321 return QUARTZ_HRESULT_From_MMRESULT( mr );
324 /***************************************************************************
326 * CAudioRendererImpl methods
331 static HRESULT CAudioRendererImpl_OnActive( CBaseFilterImpl* pImpl )
333 CAudioRendererImpl_THIS(pImpl,basefilter);
334 WAVEFORMATEX* pwfx;
336 FIXME( "(%p)\n", This );
338 if ( This->pPin->pin.pmtConn == NULL )
339 return NOERROR;
341 pwfx = (WAVEFORMATEX*)This->pPin->pin.pmtConn->pbFormat;
342 if ( pwfx == NULL )
343 return E_FAIL;
345 This->m_fInFlush = FALSE;
347 return CAudioRendererImpl_waveOutInit(This,pwfx);
350 static HRESULT CAudioRendererImpl_OnInactive( CBaseFilterImpl* pImpl )
352 CAudioRendererImpl_THIS(pImpl,basefilter);
354 FIXME( "(%p)\n", This );
356 CAudioRendererImpl_waveOutUninit(This);
358 This->m_fInFlush = FALSE;
360 TRACE("returned\n" );
362 return NOERROR;
365 static const CBaseFilterHandlers filterhandlers =
367 CAudioRendererImpl_OnActive, /* pOnActive */
368 CAudioRendererImpl_OnInactive, /* pOnInactive */
369 NULL, /* pOnStop */
372 /***************************************************************************
374 * CAudioRendererPinImpl methods
378 static HRESULT CAudioRendererPinImpl_CheckMediaType( CPinBaseImpl* pImpl, const AM_MEDIA_TYPE* pmt )
380 CAudioRendererPinImpl_THIS(pImpl,pin);
381 const WAVEFORMATEX* pwfx;
383 TRACE("(%p,%p)\n",This,pmt);
385 if ( !IsEqualGUID( &pmt->majortype, &MEDIATYPE_Audio ) )
386 return E_FAIL;
387 if ( !IsEqualGUID( &pmt->subtype, &MEDIASUBTYPE_PCM ) )
388 return E_FAIL;
389 if ( !IsEqualGUID( &pmt->formattype, &FORMAT_WaveFormatEx ) )
390 return E_FAIL;
391 if ( pmt->cbFormat < (sizeof(WAVEFORMATEX)-sizeof(WORD)) )
392 return E_FAIL;
394 pwfx = (const WAVEFORMATEX*)pmt->pbFormat;
395 if ( pwfx == NULL )
396 return E_FAIL;
397 if ( pwfx->wFormatTag != 1 )
398 return E_FAIL;
400 return NOERROR;
403 static HRESULT CAudioRendererPinImpl_Receive( CPinBaseImpl* pImpl, IMediaSample* pSample )
405 CAudioRendererPinImpl_THIS(pImpl,pin);
406 HRESULT hr;
407 BYTE* pData = NULL;
408 DWORD dwDataLength;
409 DWORD dwWritten;
411 FIXME( "(%p,%p)\n",This,pSample );
413 if ( !This->pRender->m_fWaveOutInit )
414 return E_UNEXPECTED;
415 if ( This->pRender->m_fInFlush )
416 return S_FALSE;
417 if ( pSample == NULL )
418 return E_POINTER;
420 hr = IMediaSample_GetPointer( pSample, &pData );
421 if ( FAILED(hr) )
422 return hr;
423 dwDataLength = (DWORD)IMediaSample_GetActualDataLength( pSample );
425 while ( 1 )
427 TRACE("trying to write %lu bytes\n",dwDataLength);
429 ResetEvent( This->pRender->m_hEventRender );
430 hr = CAudioRendererImpl_waveOutWriteData(
431 This->pRender,pData,dwDataLength,&dwWritten);
432 if ( FAILED(hr) )
433 break;
434 if ( hr == S_FALSE )
436 WaitForSingleObject( This->pRender->m_hEventRender, INFINITE );
437 continue;
439 pData += dwWritten;
440 dwDataLength -= dwWritten;
441 hr = CAudioRendererImpl_waveOutFlush(This->pRender);
442 if ( FAILED(hr) )
443 break;
444 if ( dwDataLength == 0 )
445 break;
448 return hr;
451 static HRESULT CAudioRendererPinImpl_ReceiveCanBlock( CPinBaseImpl* pImpl )
453 CAudioRendererPinImpl_THIS(pImpl,pin);
455 TRACE( "(%p)\n", This );
457 /* might block. */
458 return S_OK;
461 static HRESULT CAudioRendererPinImpl_EndOfStream( CPinBaseImpl* pImpl )
463 CAudioRendererPinImpl_THIS(pImpl,pin);
465 FIXME( "(%p)\n", This );
467 This->pRender->m_fInFlush = FALSE;
469 /* FIXME - don't notify twice until stopped or seeked. */
470 return CBaseFilterImpl_MediaEventNotify(
471 &This->pRender->basefilter, EC_COMPLETE,
472 (LONG_PTR)S_OK, (LONG_PTR)(IBaseFilter*)(This->pRender) );
475 static HRESULT CAudioRendererPinImpl_BeginFlush( CPinBaseImpl* pImpl )
477 CAudioRendererPinImpl_THIS(pImpl,pin);
479 FIXME( "(%p)\n", This );
481 This->pRender->m_fInFlush = TRUE;
482 CAudioRendererImpl_waveOutReset(This->pRender);
484 return NOERROR;
487 static HRESULT CAudioRendererPinImpl_EndFlush( CPinBaseImpl* pImpl )
489 CAudioRendererPinImpl_THIS(pImpl,pin);
491 FIXME( "(%p)\n", This );
493 This->pRender->m_fInFlush = FALSE;
495 return NOERROR;
498 static HRESULT CAudioRendererPinImpl_NewSegment( CPinBaseImpl* pImpl, REFERENCE_TIME rtStart, REFERENCE_TIME rtStop, double rate )
500 CAudioRendererPinImpl_THIS(pImpl,pin);
502 FIXME( "(%p)\n", This );
504 This->pRender->m_fInFlush = FALSE;
506 return NOERROR;
509 static const CBasePinHandlers pinhandlers =
511 NULL, /* pOnPreConnect */
512 NULL, /* pOnPostConnect */
513 NULL, /* pOnDisconnect */
514 CAudioRendererPinImpl_CheckMediaType, /* pCheckMediaType */
515 NULL, /* pQualityNotify */
516 CAudioRendererPinImpl_Receive, /* pReceive */
517 CAudioRendererPinImpl_ReceiveCanBlock, /* pReceiveCanBlock */
518 CAudioRendererPinImpl_EndOfStream, /* pEndOfStream */
519 CAudioRendererPinImpl_BeginFlush, /* pBeginFlush */
520 CAudioRendererPinImpl_EndFlush, /* pEndFlush */
521 CAudioRendererPinImpl_NewSegment, /* pNewSegment */
525 /***************************************************************************
527 * new/delete CAudioRendererImpl
531 /* can I use offsetof safely? - FIXME? */
532 static QUARTZ_IFEntry FilterIFEntries[] =
534 { &IID_IPersist, offsetof(CAudioRendererImpl,basefilter)-offsetof(CAudioRendererImpl,unk) },
535 { &IID_IMediaFilter, offsetof(CAudioRendererImpl,basefilter)-offsetof(CAudioRendererImpl,unk) },
536 { &IID_IBaseFilter, offsetof(CAudioRendererImpl,basefilter)-offsetof(CAudioRendererImpl,unk) },
537 { &IID_IBasicAudio, offsetof(CAudioRendererImpl,basaud)-offsetof(CAudioRendererImpl,unk) },
540 static void QUARTZ_DestroyAudioRenderer(IUnknown* punk)
542 CAudioRendererImpl_THIS(punk,unk);
544 TRACE( "(%p)\n", This );
546 if ( This->pPin != NULL )
548 IUnknown_Release(This->pPin->unk.punkControl);
549 This->pPin = NULL;
552 CAudioRendererImpl_UninitIBasicAudio(This);
553 CBaseFilterImpl_UninitIBaseFilter(&This->basefilter);
556 HRESULT QUARTZ_CreateAudioRenderer(IUnknown* punkOuter,void** ppobj)
558 CAudioRendererImpl* This = NULL;
559 HRESULT hr;
561 TRACE("(%p,%p)\n",punkOuter,ppobj);
563 This = (CAudioRendererImpl*)
564 QUARTZ_AllocObj( sizeof(CAudioRendererImpl) );
565 if ( This == NULL )
566 return E_OUTOFMEMORY;
567 This->pPin = NULL;
568 This->m_fInFlush = FALSE;
569 This->m_fWaveOutInit = FALSE;
570 This->m_hEventRender = (HANDLE)NULL;
572 QUARTZ_IUnkInit( &This->unk, punkOuter );
574 hr = CBaseFilterImpl_InitIBaseFilter(
575 &This->basefilter,
576 This->unk.punkControl,
577 &CLSID_AudioRender,
578 QUARTZ_AudioRender_Name,
579 &filterhandlers );
580 if ( SUCCEEDED(hr) )
582 hr = CAudioRendererImpl_InitIBasicAudio(This);
583 if ( FAILED(hr) )
585 CBaseFilterImpl_UninitIBaseFilter(&This->basefilter);
589 if ( FAILED(hr) )
591 QUARTZ_FreeObj(This);
592 return hr;
595 This->unk.pEntries = FilterIFEntries;
596 This->unk.dwEntries = sizeof(FilterIFEntries)/sizeof(FilterIFEntries[0]);
597 This->unk.pOnFinalRelease = QUARTZ_DestroyAudioRenderer;
599 hr = QUARTZ_CreateAudioRendererPin(
600 This,
601 &This->basefilter.csFilter,
602 &This->pPin );
603 if ( SUCCEEDED(hr) )
604 hr = QUARTZ_CompList_AddComp(
605 This->basefilter.pInPins,
606 (IUnknown*)&This->pPin->pin,
607 NULL, 0 );
608 if ( FAILED(hr) )
610 IUnknown_Release( This->unk.punkControl );
611 return hr;
614 *ppobj = (void*)&(This->unk);
616 return S_OK;
620 /***************************************************************************
622 * new/delete CAudioRendererPinImpl
626 /* can I use offsetof safely? - FIXME? */
627 static QUARTZ_IFEntry PinIFEntries[] =
629 { &IID_IPin, offsetof(CAudioRendererPinImpl,pin)-offsetof(CAudioRendererPinImpl,unk) },
630 { &IID_IMemInputPin, offsetof(CAudioRendererPinImpl,meminput)-offsetof(CAudioRendererPinImpl,unk) },
633 static void QUARTZ_DestroyAudioRendererPin(IUnknown* punk)
635 CAudioRendererPinImpl_THIS(punk,unk);
637 TRACE( "(%p)\n", This );
639 CPinBaseImpl_UninitIPin( &This->pin );
640 CMemInputPinBaseImpl_UninitIMemInputPin( &This->meminput );
643 HRESULT QUARTZ_CreateAudioRendererPin(
644 CAudioRendererImpl* pFilter,
645 CRITICAL_SECTION* pcsPin,
646 CAudioRendererPinImpl** ppPin)
648 CAudioRendererPinImpl* This = NULL;
649 HRESULT hr;
651 TRACE("(%p,%p,%p)\n",pFilter,pcsPin,ppPin);
653 This = (CAudioRendererPinImpl*)
654 QUARTZ_AllocObj( sizeof(CAudioRendererPinImpl) );
655 if ( This == NULL )
656 return E_OUTOFMEMORY;
658 QUARTZ_IUnkInit( &This->unk, NULL );
659 This->pRender = pFilter;
661 hr = CPinBaseImpl_InitIPin(
662 &This->pin,
663 This->unk.punkControl,
664 pcsPin,
665 &pFilter->basefilter,
666 QUARTZ_AudioRenderPin_Name,
667 FALSE,
668 &pinhandlers );
670 if ( SUCCEEDED(hr) )
672 hr = CMemInputPinBaseImpl_InitIMemInputPin(
673 &This->meminput,
674 This->unk.punkControl,
675 &This->pin );
676 if ( FAILED(hr) )
678 CPinBaseImpl_UninitIPin( &This->pin );
682 if ( FAILED(hr) )
684 QUARTZ_FreeObj(This);
685 return hr;
688 This->unk.pEntries = PinIFEntries;
689 This->unk.dwEntries = sizeof(PinIFEntries)/sizeof(PinIFEntries[0]);
690 This->unk.pOnFinalRelease = QUARTZ_DestroyAudioRendererPin;
692 *ppPin = This;
694 TRACE("returned successfully.\n");
696 return S_OK;
700 /***************************************************************************
702 * CAudioRendererImpl::IBasicAudio
706 static HRESULT WINAPI
707 IBasicAudio_fnQueryInterface(IBasicAudio* iface,REFIID riid,void** ppobj)
709 CAudioRendererImpl_THIS(iface,basaud);
711 TRACE("(%p)->()\n",This);
713 return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
716 static ULONG WINAPI
717 IBasicAudio_fnAddRef(IBasicAudio* iface)
719 CAudioRendererImpl_THIS(iface,basaud);
721 TRACE("(%p)->()\n",This);
723 return IUnknown_AddRef(This->unk.punkControl);
726 static ULONG WINAPI
727 IBasicAudio_fnRelease(IBasicAudio* iface)
729 CAudioRendererImpl_THIS(iface,basaud);
731 TRACE("(%p)->()\n",This);
733 return IUnknown_Release(This->unk.punkControl);
736 static HRESULT WINAPI
737 IBasicAudio_fnGetTypeInfoCount(IBasicAudio* iface,UINT* pcTypeInfo)
739 CAudioRendererImpl_THIS(iface,basaud);
741 FIXME("(%p)->()\n",This);
743 return E_NOTIMPL;
746 static HRESULT WINAPI
747 IBasicAudio_fnGetTypeInfo(IBasicAudio* iface,UINT iTypeInfo, LCID lcid, ITypeInfo** ppobj)
749 CAudioRendererImpl_THIS(iface,basaud);
751 FIXME("(%p)->()\n",This);
753 return E_NOTIMPL;
756 static HRESULT WINAPI
757 IBasicAudio_fnGetIDsOfNames(IBasicAudio* iface,REFIID riid, LPOLESTR* ppwszName, UINT cNames, LCID lcid, DISPID* pDispId)
759 CAudioRendererImpl_THIS(iface,basaud);
761 FIXME("(%p)->()\n",This);
763 return E_NOTIMPL;
766 static HRESULT WINAPI
767 IBasicAudio_fnInvoke(IBasicAudio* iface,DISPID DispId, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarRes, EXCEPINFO* pExcepInfo, UINT* puArgErr)
769 CAudioRendererImpl_THIS(iface,basaud);
771 FIXME("(%p)->()\n",This);
773 return E_NOTIMPL;
777 static HRESULT WINAPI
778 IBasicAudio_fnput_Volume(IBasicAudio* iface,long lVol)
780 CAudioRendererImpl_THIS(iface,basaud);
782 FIXME("(%p)->()\n",This);
784 return E_NOTIMPL;
787 static HRESULT WINAPI
788 IBasicAudio_fnget_Volume(IBasicAudio* iface,long* plVol)
790 CAudioRendererImpl_THIS(iface,basaud);
792 FIXME("(%p)->()\n",This);
794 return E_NOTIMPL;
797 static HRESULT WINAPI
798 IBasicAudio_fnput_Balance(IBasicAudio* iface,long lBalance)
800 CAudioRendererImpl_THIS(iface,basaud);
802 FIXME("(%p)->()\n",This);
804 return E_NOTIMPL;
807 static HRESULT WINAPI
808 IBasicAudio_fnget_Balance(IBasicAudio* iface,long* plBalance)
810 CAudioRendererImpl_THIS(iface,basaud);
812 FIXME("(%p)->()\n",This);
814 return E_NOTIMPL;
818 static ICOM_VTABLE(IBasicAudio) ibasicaudio =
820 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
821 /* IUnknown fields */
822 IBasicAudio_fnQueryInterface,
823 IBasicAudio_fnAddRef,
824 IBasicAudio_fnRelease,
825 /* IDispatch fields */
826 IBasicAudio_fnGetTypeInfoCount,
827 IBasicAudio_fnGetTypeInfo,
828 IBasicAudio_fnGetIDsOfNames,
829 IBasicAudio_fnInvoke,
830 /* IBasicAudio fields */
831 IBasicAudio_fnput_Volume,
832 IBasicAudio_fnget_Volume,
833 IBasicAudio_fnput_Balance,
834 IBasicAudio_fnget_Balance,
838 HRESULT CAudioRendererImpl_InitIBasicAudio( CAudioRendererImpl* This )
840 TRACE("(%p)\n",This);
841 ICOM_VTBL(&This->basaud) = &ibasicaudio;
843 return NOERROR;
846 void CAudioRendererImpl_UninitIBasicAudio( CAudioRendererImpl* This )
848 TRACE("(%p)\n",This);