/*
 * Audio Renderer (CLSID_AudioRender)
 *
 * FIXME
 *  - implement IReferenceClock.
 *
 * Copyright (C) Hidenori TAKESHIMA <hidenori@a2.ctktv.ne.jp>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "config.h"

#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "mmsystem.h"
#include "winerror.h"
#include "strmif.h"
#include "control.h"
#include "vfwmsgs.h"
#include "uuids.h"
#include "evcode.h"

#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(quartz);

#include "quartz_private.h"
#include "audren.h"
#include "seekpass.h"


static const WCHAR QUARTZ_AudioRender_Name[] =
{ 'A','u','d','i','o',' ','R','e','n','d','e','r',0 };
static const WCHAR QUARTZ_AudioRenderPin_Name[] =
{ 'I','n',0 };



/***************************************************************************
 *
 *	CAudioRendererImpl waveOut methods (internal)
 *
 */

static
HRESULT QUARTZ_HRESULT_From_MMRESULT( MMRESULT mr )
{
	HRESULT hr = E_FAIL;

	switch ( mr )
	{
	case MMSYSERR_NOERROR:
		hr = S_OK;
		break;
	case MMSYSERR_NOMEM:
		hr = E_OUTOFMEMORY;
		break;
	}

	return hr;
}

void CAudioRendererImpl_waveOutEventCallback(
	HWAVEOUT hwo, UINT uMsg,
	DWORD dwInstance, DWORD dwParam1, DWORD dwParam2 )
{
	CAudioRendererImpl* This = (CAudioRendererImpl*)dwInstance;

	if ( uMsg == WOM_DONE )
		SetEvent( This->m_hEventRender );
}

static
void CAudioRendererImpl_waveOutReset(
	CAudioRendererImpl* This )
{
	if ( !This->m_fWaveOutInit )
		return;

	waveOutReset( This->m_hWaveOut );
	SetEvent( This->m_hEventRender );
}

static
void CAudioRendererImpl_waveOutUninit(
	CAudioRendererImpl* This )
{
	DWORD i;

	TRACE("(%p)\n",This);

	if ( !This->m_fWaveOutInit )
		return;

	waveOutReset( This->m_hWaveOut );
	SetEvent( This->m_hEventRender );

	for ( i = 0; i < WINE_QUARTZ_WAVEOUT_COUNT; i++ )
	{
		if ( This->m_hdr[i].dwFlags & WHDR_PREPARED )
		{
			waveOutUnprepareHeader(
				This->m_hWaveOut,
				&This->m_hdr[i], sizeof(WAVEHDR) );
			This->m_hdr[i].dwFlags = 0;
		}
		if ( This->m_hdr[i].lpData != NULL )
		{
			QUARTZ_FreeMem( This->m_hdr[i].lpData );
			This->m_hdr[i].lpData = NULL;
		}
	}

	waveOutClose( This->m_hWaveOut );
	This->m_hWaveOut = (HWAVEOUT)NULL;
	if ( This->m_hEventRender != (HANDLE)NULL )
	{
		CloseHandle( This->m_hEventRender );
		This->m_hEventRender = (HANDLE)NULL;
	}

	This->m_fWaveOutInit = FALSE;
}

static
HRESULT CAudioRendererImpl_waveOutInit(
	CAudioRendererImpl* This, WAVEFORMATEX* pwfx )
{
	MMRESULT mr;
	HRESULT hr;
	DWORD i;
	DWORD dwBlockSize;

	if ( This->m_fWaveOutInit )
		return NOERROR;

	if ( pwfx == NULL )
		return E_POINTER;
	if ( pwfx->nBlockAlign == 0 )
		return E_INVALIDARG;

	This->m_hEventRender = (HANDLE)NULL;
	This->m_hWaveOut = (HWAVEOUT)NULL;
	This->m_dwBlockSize = 0;
	This->m_phdrCur = NULL;
	ZeroMemory( &This->m_hdr, sizeof(This->m_hdr) );


	mr = waveOutOpen(
		&This->m_hWaveOut, WAVE_MAPPER, pwfx,
		(DWORD)CAudioRendererImpl_waveOutEventCallback, (DWORD)This,
		CALLBACK_FUNCTION );
	hr = QUARTZ_HRESULT_From_MMRESULT( mr );
	if ( FAILED(hr) )
		return hr;
	This->m_fWaveOutInit = TRUE;

	This->m_hEventRender = CreateEventA(
		NULL, TRUE, TRUE, NULL );
	if ( This->m_hEventRender == (HANDLE)NULL )
	{
		hr = E_OUTOFMEMORY;
		goto err;
	}

	dwBlockSize = pwfx->nAvgBytesPerSec / pwfx->nBlockAlign;
	if ( dwBlockSize == 0 )
		dwBlockSize = 1;
	dwBlockSize *= pwfx->nBlockAlign;
	This->m_dwBlockSize = dwBlockSize;

	for ( i = 0; i < WINE_QUARTZ_WAVEOUT_COUNT; i++ )
	{
		This->m_hdr[i].lpData = (CHAR*)QUARTZ_AllocMem( dwBlockSize );
		if ( This->m_hdr[i].lpData == NULL )
		{
			hr = E_OUTOFMEMORY;
			goto err;
		}
		mr = waveOutPrepareHeader(
				This->m_hWaveOut,
				&This->m_hdr[i], sizeof(WAVEHDR) );
		hr = QUARTZ_HRESULT_From_MMRESULT( mr );
		if ( FAILED(hr) )
			goto err;
		This->m_hdr[i].dwFlags |= WHDR_DONE;
		This->m_hdr[i].dwBufferLength = dwBlockSize;
		This->m_hdr[i].dwUser = i;
	}

	return S_OK;
err:
	CAudioRendererImpl_waveOutUninit(This);
	return hr;
}

static HRESULT CAudioRendererImpl_waveOutPause( CAudioRendererImpl* This )
{
	if ( !This->m_fWaveOutInit )
		return E_UNEXPECTED;

	return QUARTZ_HRESULT_From_MMRESULT( waveOutPause(
			This->m_hWaveOut ) );
}

static HRESULT CAudioRendererImpl_waveOutRun( CAudioRendererImpl* This )
{
	if ( !This->m_fWaveOutInit )
		return E_UNEXPECTED;

	return QUARTZ_HRESULT_From_MMRESULT( waveOutRestart(
			This->m_hWaveOut ) );
}

static
WAVEHDR* CAudioRendererImpl_waveOutGetBuffer(
	CAudioRendererImpl* This )
{
	DWORD i;

	if ( !This->m_fWaveOutInit )
		return NULL;

	if ( This->m_phdrCur != NULL )
		return This->m_phdrCur;

	for ( i = 0; i < WINE_QUARTZ_WAVEOUT_COUNT; i++ )
	{
		if ( This->m_hdr[i].dwFlags & WHDR_DONE )
		{
			This->m_phdrCur = &(This->m_hdr[i]);
			This->m_phdrCur->dwFlags &= ~WHDR_DONE;
			This->m_phdrCur->dwBufferLength = 0;
			return This->m_phdrCur;
		}
	}

	return NULL;
}

static
HRESULT CAudioRendererImpl_waveOutWriteData(
	CAudioRendererImpl* This,
	const BYTE* pData, DWORD cbData, DWORD* pcbWritten )
{
	DWORD	cbAvail;

	*pcbWritten = 0;

	if ( !This->m_fWaveOutInit )
		return E_UNEXPECTED;

	if ( cbData == 0 )
		return S_OK;

	if ( CAudioRendererImpl_waveOutGetBuffer(This) == NULL )
		return S_FALSE;

	cbAvail = This->m_dwBlockSize - This->m_phdrCur->dwBufferLength;
	if ( cbAvail > cbData )
		cbAvail = cbData;
	memcpy( This->m_phdrCur->lpData, pData, cbAvail );
	pData += cbAvail;
	cbData -= cbAvail;
	This->m_phdrCur->dwBufferLength += cbAvail;

	*pcbWritten = cbAvail;

	return S_OK;
}

static
HRESULT CAudioRendererImpl_waveOutFlush(
	CAudioRendererImpl* This )
{
	MMRESULT mr;
	HRESULT hr;

	if ( !This->m_fWaveOutInit )
		return E_UNEXPECTED;
	if ( This->m_phdrCur == NULL )
		return E_UNEXPECTED;

	if ( This->m_phdrCur->dwBufferLength == 0 )
		return S_OK;

	mr = waveOutWrite(
		This->m_hWaveOut,
		This->m_phdrCur, sizeof(WAVEHDR) );
	hr = QUARTZ_HRESULT_From_MMRESULT( mr );
	if ( FAILED(hr) )
		return hr;

	This->m_phdrCur = NULL;
	return S_OK;
}

#if 0
/* FIXME: Not used for now */

static
HRESULT CAudioRendererImpl_waveOutGetVolume(
	CAudioRendererImpl* This,
	DWORD* pdwLeft, DWORD* pdwRight )
{
	MMRESULT mr;
	HRESULT hr;
	DWORD	dwVol;

	if ( !This->m_fWaveOutInit )
		return E_UNEXPECTED;

	mr = waveOutGetVolume(
		This->m_hWaveOut, &dwVol );
	hr = QUARTZ_HRESULT_From_MMRESULT( mr );
	if ( FAILED(hr) )
		return hr;

	*pdwLeft = LOWORD(dwVol);
	*pdwRight = HIWORD(dwVol);

	return NOERROR;
}

#endif

static
HRESULT CAudioRendererImpl_waveOutSetVolume(
	CAudioRendererImpl* This,
	DWORD dwLeft, DWORD dwRight )
{
	MMRESULT mr;
	DWORD	dwVol;

	if ( !This->m_fWaveOutInit )
		return E_UNEXPECTED;

	dwVol = dwLeft | (dwRight<<16);

	mr = waveOutSetVolume(
		This->m_hWaveOut, dwVol );
	return QUARTZ_HRESULT_From_MMRESULT( mr );
}

static HRESULT CAudioRendererImpl_UpdateVolume( CAudioRendererImpl* This )
{
	HRESULT hr;
	long	leftlevel;
	long	rightlevel;

	if ( This->m_lAudioBalance >= 0 )
	{
		leftlevel = This->m_lAudioVolume - This->m_lAudioBalance;
		rightlevel = This->m_lAudioVolume;
	}
	else
	{
		leftlevel = This->m_lAudioVolume;
		rightlevel = This->m_lAudioVolume + This->m_lAudioBalance;
	}
	leftlevel = QUARTZ_DBToAmpFactor( leftlevel );
	rightlevel = QUARTZ_DBToAmpFactor( rightlevel );

	hr = CAudioRendererImpl_waveOutSetVolume(
		This, (DWORD)leftlevel, (DWORD)rightlevel );
	if ( hr == E_UNEXPECTED )
		hr = S_OK;

	return hr;
}


/***************************************************************************
 *
 *	CAudioRendererImpl methods
 *
 */


static HRESULT CAudioRendererImpl_OnActive( CBaseFilterImpl* pImpl )
{
	CAudioRendererImpl_THIS(pImpl,basefilter);
	HRESULT hr;

	FIXME( "(%p)\n", This );

	if ( This->pPin->pin.pmtConn == NULL )
		return NOERROR;

	This->m_fInFlush = FALSE;

	hr = CAudioRendererImpl_waveOutRun(This);
	if ( FAILED(hr) )
		return hr;

	return NOERROR;
}

static HRESULT CAudioRendererImpl_OnInactive( CBaseFilterImpl* pImpl )
{
	CAudioRendererImpl_THIS(pImpl,basefilter);
	WAVEFORMATEX*	pwfx;
	HRESULT hr;

	FIXME( "(%p)\n", This );

	if ( This->pPin->pin.pmtConn == NULL )
		return NOERROR;

	pwfx = (WAVEFORMATEX*)This->pPin->pin.pmtConn->pbFormat;
	if ( pwfx == NULL )
		return E_FAIL;

	This->m_fInFlush = FALSE;

	hr = CAudioRendererImpl_waveOutInit(This,pwfx);
	if ( FAILED(hr) )
		return hr;

	hr = CAudioRendererImpl_waveOutPause(This);
	if ( FAILED(hr) )
		return hr;

	return NOERROR;
}

static HRESULT CAudioRendererImpl_OnStop( CBaseFilterImpl* pImpl )
{
	CAudioRendererImpl_THIS(pImpl,basefilter);

	FIXME( "(%p)\n", This );

	This->m_fInFlush = TRUE;

	CAudioRendererImpl_waveOutUninit(This);

	This->m_fInFlush = FALSE;

	TRACE("returned\n" );

	return NOERROR;
}

static const CBaseFilterHandlers filterhandlers =
{
	CAudioRendererImpl_OnActive, /* pOnActive */
	CAudioRendererImpl_OnInactive, /* pOnInactive */
	CAudioRendererImpl_OnStop, /* pOnStop */
};

/***************************************************************************
 *
 *	CAudioRendererPinImpl methods
 *
 */

static HRESULT CAudioRendererPinImpl_OnDisconnect( CPinBaseImpl* pImpl )
{
	CAudioRendererPinImpl_THIS(pImpl,pin);

	TRACE("(%p)\n",This);

	if ( This->meminput.pAllocator != NULL )
	{
		IMemAllocator_Decommit(This->meminput.pAllocator);
		IMemAllocator_Release(This->meminput.pAllocator);
		This->meminput.pAllocator = NULL;
	}

	return NOERROR;
}


static HRESULT CAudioRendererPinImpl_CheckMediaType( CPinBaseImpl* pImpl, const AM_MEDIA_TYPE* pmt )
{
	CAudioRendererPinImpl_THIS(pImpl,pin);
	const WAVEFORMATEX* pwfx;

	TRACE("(%p,%p)\n",This,pmt);

	if ( !IsEqualGUID( &pmt->majortype, &MEDIATYPE_Audio ) )
	{
		TRACE("not audio\n");
		return E_FAIL;
	}
	if ( !IsEqualGUID( &pmt->subtype, &MEDIASUBTYPE_NULL ) &&
		 !IsEqualGUID( &pmt->subtype, &MEDIASUBTYPE_PCM ) )
	{
		TRACE("not PCM\n");
		return E_FAIL;
	}
	if ( !IsEqualGUID( &pmt->formattype, &FORMAT_WaveFormatEx ) )
	{
		TRACE("not WAVE\n");
		return E_FAIL;
	}

	TRACE("testing WAVE header\n");

	if ( pmt->cbFormat < (sizeof(WAVEFORMATEX)-sizeof(WORD)) )
		return E_FAIL;

	pwfx = (const WAVEFORMATEX*)pmt->pbFormat;
	if ( pwfx == NULL )
		return E_FAIL;
	if ( pwfx->wFormatTag != 1 )
		return E_FAIL;

	TRACE("returned successfully.\n");

	return NOERROR;
}

static HRESULT CAudioRendererPinImpl_Receive( CPinBaseImpl* pImpl, IMediaSample* pSample )
{
	CAudioRendererPinImpl_THIS(pImpl,pin);
	HRESULT hr;
	BYTE*	pData = NULL;
	DWORD	dwDataLength;
	DWORD	dwWritten;

	TRACE( "(%p,%p)\n",This,pSample );

	if ( !This->pRender->m_fWaveOutInit )
		return E_UNEXPECTED;
	if ( pSample == NULL )
		return E_POINTER;

	hr = IMediaSample_GetPointer( pSample, &pData );
	if ( FAILED(hr) )
		return hr;
	dwDataLength = (DWORD)IMediaSample_GetActualDataLength( pSample );

	while ( 1 )
	{
		TRACE("trying to write %lu bytes\n",dwDataLength);

		if ( This->pRender->m_fInFlush )
			return S_FALSE;

		ResetEvent( This->pRender->m_hEventRender );
		hr = CAudioRendererImpl_waveOutWriteData(
			This->pRender,pData,dwDataLength,&dwWritten);
		if ( FAILED(hr) )
			break;
		if ( hr == S_FALSE )
		{
			WaitForSingleObject( This->pRender->m_hEventRender, INFINITE );
			continue;
		}
		pData += dwWritten;
		dwDataLength -= dwWritten;
		hr = CAudioRendererImpl_waveOutFlush(This->pRender);
		if ( FAILED(hr) )
			break;
		if ( dwDataLength == 0 )
			break;
	}

	return hr;
}

static HRESULT CAudioRendererPinImpl_ReceiveCanBlock( CPinBaseImpl* pImpl )
{
	CAudioRendererPinImpl_THIS(pImpl,pin);

	TRACE( "(%p)\n", This );

	/* might block. */
	return S_OK;
}

static HRESULT CAudioRendererPinImpl_EndOfStream( CPinBaseImpl* pImpl )
{
	CAudioRendererPinImpl_THIS(pImpl,pin);

	FIXME( "(%p)\n", This );

	This->pRender->m_fInFlush = FALSE;

	/* FIXME - don't notify twice until stopped or seeked. */
	return CBaseFilterImpl_MediaEventNotify(
		&This->pRender->basefilter, EC_COMPLETE,
		(LONG_PTR)S_OK, (LONG_PTR)(IBaseFilter*)(This->pRender) );
}

static HRESULT CAudioRendererPinImpl_BeginFlush( CPinBaseImpl* pImpl )
{
	CAudioRendererPinImpl_THIS(pImpl,pin);

	FIXME( "(%p)\n", This );

	This->pRender->m_fInFlush = TRUE;
	CAudioRendererImpl_waveOutReset(This->pRender);

	return NOERROR;
}

static HRESULT CAudioRendererPinImpl_EndFlush( CPinBaseImpl* pImpl )
{
	CAudioRendererPinImpl_THIS(pImpl,pin);

	FIXME( "(%p)\n", This );

	This->pRender->m_fInFlush = FALSE;

	return NOERROR;
}

static HRESULT CAudioRendererPinImpl_NewSegment( CPinBaseImpl* pImpl, REFERENCE_TIME rtStart, REFERENCE_TIME rtStop, double rate )
{
	CAudioRendererPinImpl_THIS(pImpl,pin);

	FIXME( "(%p)\n", This );

	This->pRender->m_fInFlush = FALSE;

	return NOERROR;
}

static const CBasePinHandlers pinhandlers =
{
	NULL, /* pOnPreConnect */
	NULL, /* pOnPostConnect */
	CAudioRendererPinImpl_OnDisconnect, /* pOnDisconnect */
	CAudioRendererPinImpl_CheckMediaType, /* pCheckMediaType */
	NULL, /* pQualityNotify */
	CAudioRendererPinImpl_Receive, /* pReceive */
	CAudioRendererPinImpl_ReceiveCanBlock, /* pReceiveCanBlock */
	CAudioRendererPinImpl_EndOfStream, /* pEndOfStream */
	CAudioRendererPinImpl_BeginFlush, /* pBeginFlush */
	CAudioRendererPinImpl_EndFlush, /* pEndFlush */
	CAudioRendererPinImpl_NewSegment, /* pNewSegment */
};


/***************************************************************************
 *
 *	new/delete CAudioRendererImpl
 *
 */

/* can I use offsetof safely? - FIXME? */
static QUARTZ_IFEntry FilterIFEntries[] =
{
  { &IID_IPersist, offsetof(CAudioRendererImpl,basefilter)-offsetof(CAudioRendererImpl,unk) },
  { &IID_IMediaFilter, offsetof(CAudioRendererImpl,basefilter)-offsetof(CAudioRendererImpl,unk) },
  { &IID_IBaseFilter, offsetof(CAudioRendererImpl,basefilter)-offsetof(CAudioRendererImpl,unk) },
  { &IID_IBasicAudio, offsetof(CAudioRendererImpl,basaud)-offsetof(CAudioRendererImpl,unk) },
};

static HRESULT CAudioRendererImpl_OnQueryInterface(
	IUnknown* punk, const IID* piid, void** ppobj )
{
	CAudioRendererImpl_THIS(punk,unk);

	if ( This->pSeekPass == NULL )
		return E_NOINTERFACE;

	if ( IsEqualGUID( &IID_IMediaPosition, piid ) ||
		 IsEqualGUID( &IID_IMediaSeeking, piid ) )
	{
		TRACE( "IMediaSeeking(or IMediaPosition) is queried\n" );
		return IUnknown_QueryInterface( (IUnknown*)(&This->pSeekPass->unk), piid, ppobj );
	}

	return E_NOINTERFACE;
}

static void QUARTZ_DestroyAudioRenderer(IUnknown* punk)
{
	CAudioRendererImpl_THIS(punk,unk);

	TRACE( "(%p)\n", This );

	if ( This->pPin != NULL )
	{
		IUnknown_Release(This->pPin->unk.punkControl);
		This->pPin = NULL;
	}
	if ( This->pSeekPass != NULL )
	{
		IUnknown_Release((IUnknown*)&This->pSeekPass->unk);
		This->pSeekPass = NULL;
	}

	CAudioRendererImpl_UninitIBasicAudio(This);
	CBaseFilterImpl_UninitIBaseFilter(&This->basefilter);

	DeleteCriticalSection( &This->m_csReceive );
}

HRESULT QUARTZ_CreateAudioRenderer(IUnknown* punkOuter,void** ppobj)
{
	CAudioRendererImpl*	This = NULL;
	HRESULT hr;

	TRACE("(%p,%p)\n",punkOuter,ppobj);

	This = (CAudioRendererImpl*)
		QUARTZ_AllocObj( sizeof(CAudioRendererImpl) );
	if ( This == NULL )
		return E_OUTOFMEMORY;
	This->pSeekPass = NULL;
	This->pPin = NULL;
	This->m_fInFlush = FALSE;
	This->m_lAudioVolume = 0;
	This->m_lAudioBalance = 0;
	This->m_fWaveOutInit = FALSE;
	This->m_hEventRender = (HANDLE)NULL;

	QUARTZ_IUnkInit( &This->unk, punkOuter );
	This->qiext.pNext = NULL;
	This->qiext.pOnQueryInterface = &CAudioRendererImpl_OnQueryInterface;
	QUARTZ_IUnkAddDelegation( &This->unk, &This->qiext );

	hr = CBaseFilterImpl_InitIBaseFilter(
		&This->basefilter,
		This->unk.punkControl,
		&CLSID_AudioRender,
		QUARTZ_AudioRender_Name,
		&filterhandlers );
	if ( SUCCEEDED(hr) )
	{
		hr = CAudioRendererImpl_InitIBasicAudio(This);
		if ( FAILED(hr) )
		{
			CBaseFilterImpl_UninitIBaseFilter(&This->basefilter);
		}
	}

	if ( FAILED(hr) )
	{
		QUARTZ_FreeObj(This);
		return hr;
	}

	This->unk.pEntries = FilterIFEntries;
	This->unk.dwEntries = sizeof(FilterIFEntries)/sizeof(FilterIFEntries[0]);
	This->unk.pOnFinalRelease = QUARTZ_DestroyAudioRenderer;

	InitializeCriticalSection( &This->m_csReceive );

	hr = QUARTZ_CreateAudioRendererPin(
		This,
		&This->basefilter.csFilter,
		&This->m_csReceive,
		&This->pPin );
	if ( SUCCEEDED(hr) )
		hr = QUARTZ_CompList_AddComp(
			This->basefilter.pInPins,
			(IUnknown*)&This->pPin->pin,
			NULL, 0 );
	if ( SUCCEEDED(hr) )
		hr = QUARTZ_CreateSeekingPassThruInternal(
			(IUnknown*)&(This->unk), &This->pSeekPass,
			TRUE, (IPin*)&(This->pPin->pin) );

	if ( FAILED(hr) )
	{
		IUnknown_Release( This->unk.punkControl );
		return hr;
	}

	*ppobj = (void*)&(This->unk);

	return S_OK;
}


/***************************************************************************
 *
 *	new/delete CAudioRendererPinImpl
 *
 */

/* can I use offsetof safely? - FIXME? */
static QUARTZ_IFEntry PinIFEntries[] =
{
  { &IID_IPin, offsetof(CAudioRendererPinImpl,pin)-offsetof(CAudioRendererPinImpl,unk) },
  { &IID_IMemInputPin, offsetof(CAudioRendererPinImpl,meminput)-offsetof(CAudioRendererPinImpl,unk) },
};

static void QUARTZ_DestroyAudioRendererPin(IUnknown* punk)
{
	CAudioRendererPinImpl_THIS(punk,unk);

	TRACE( "(%p)\n", This );

	CPinBaseImpl_UninitIPin( &This->pin );
	CMemInputPinBaseImpl_UninitIMemInputPin( &This->meminput );
}

HRESULT QUARTZ_CreateAudioRendererPin(
	CAudioRendererImpl* pFilter,
	CRITICAL_SECTION* pcsPin,
	CRITICAL_SECTION* pcsPinReceive,
	CAudioRendererPinImpl** ppPin)
{
	CAudioRendererPinImpl*	This = NULL;
	HRESULT hr;

	TRACE("(%p,%p,%p,%p)\n",pFilter,pcsPin,pcsPinReceive,ppPin);

	This = (CAudioRendererPinImpl*)
		QUARTZ_AllocObj( sizeof(CAudioRendererPinImpl) );
	if ( This == NULL )
		return E_OUTOFMEMORY;

	QUARTZ_IUnkInit( &This->unk, NULL );
	This->pRender = pFilter;

	hr = CPinBaseImpl_InitIPin(
		&This->pin,
		This->unk.punkControl,
		pcsPin, pcsPinReceive,
		&pFilter->basefilter,
		QUARTZ_AudioRenderPin_Name,
		FALSE,
		&pinhandlers );

	if ( SUCCEEDED(hr) )
	{
		hr = CMemInputPinBaseImpl_InitIMemInputPin(
			&This->meminput,
			This->unk.punkControl,
			&This->pin );
		if ( FAILED(hr) )
		{
			CPinBaseImpl_UninitIPin( &This->pin );
		}
	}

	if ( FAILED(hr) )
	{
		QUARTZ_FreeObj(This);
		return hr;
	}

	This->unk.pEntries = PinIFEntries;
	This->unk.dwEntries = sizeof(PinIFEntries)/sizeof(PinIFEntries[0]);
	This->unk.pOnFinalRelease = QUARTZ_DestroyAudioRendererPin;

	*ppPin = This;

	TRACE("returned successfully.\n");

	return S_OK;
}


/***************************************************************************
 *
 *	CAudioRendererImpl::IBasicAudio
 *
 */

static HRESULT WINAPI
IBasicAudio_fnQueryInterface(IBasicAudio* iface,REFIID riid,void** ppobj)
{
	CAudioRendererImpl_THIS(iface,basaud);

	TRACE("(%p)->()\n",This);

	return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
}

static ULONG WINAPI
IBasicAudio_fnAddRef(IBasicAudio* iface)
{
	CAudioRendererImpl_THIS(iface,basaud);

	TRACE("(%p)->()\n",This);

	return IUnknown_AddRef(This->unk.punkControl);
}

static ULONG WINAPI
IBasicAudio_fnRelease(IBasicAudio* iface)
{
	CAudioRendererImpl_THIS(iface,basaud);

	TRACE("(%p)->()\n",This);

	return IUnknown_Release(This->unk.punkControl);
}

static HRESULT WINAPI
IBasicAudio_fnGetTypeInfoCount(IBasicAudio* iface,UINT* pcTypeInfo)
{
	CAudioRendererImpl_THIS(iface,basaud);

	FIXME("(%p)->()\n",This);

	return E_NOTIMPL;
}

static HRESULT WINAPI
IBasicAudio_fnGetTypeInfo(IBasicAudio* iface,UINT iTypeInfo, LCID lcid, ITypeInfo** ppobj)
{
	CAudioRendererImpl_THIS(iface,basaud);

	FIXME("(%p)->()\n",This);

	return E_NOTIMPL;
}

static HRESULT WINAPI
IBasicAudio_fnGetIDsOfNames(IBasicAudio* iface,REFIID riid, LPOLESTR* ppwszName, UINT cNames, LCID lcid, DISPID* pDispId)
{
	CAudioRendererImpl_THIS(iface,basaud);

	FIXME("(%p)->()\n",This);

	return E_NOTIMPL;
}

static HRESULT WINAPI
IBasicAudio_fnInvoke(IBasicAudio* iface,DISPID DispId, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarRes, EXCEPINFO* pExcepInfo, UINT* puArgErr)
{
	CAudioRendererImpl_THIS(iface,basaud);

	FIXME("(%p)->()\n",This);

	return E_NOTIMPL;
}


static HRESULT WINAPI
IBasicAudio_fnput_Volume(IBasicAudio* iface,long lVol)
{
	CAudioRendererImpl_THIS(iface,basaud);
	HRESULT hr;

	FIXME("(%p)->(%ld)\n",This,lVol);

	if ( lVol > 0 || lVol < -10000 )
		return E_INVALIDARG;

	EnterCriticalSection( &This->basefilter.csFilter );
	This->m_lAudioVolume = lVol;
	hr = CAudioRendererImpl_UpdateVolume( This );
	LeaveCriticalSection( &This->basefilter.csFilter );

	return hr;
}

static HRESULT WINAPI
IBasicAudio_fnget_Volume(IBasicAudio* iface,long* plVol)
{
	CAudioRendererImpl_THIS(iface,basaud);

	FIXME("(%p)->(%p)\n",This,plVol);

	if ( plVol == NULL )
		return E_POINTER;

	EnterCriticalSection( &This->basefilter.csFilter );
	*plVol = This->m_lAudioVolume;
	LeaveCriticalSection( &This->basefilter.csFilter );

	return S_OK;
}

static HRESULT WINAPI
IBasicAudio_fnput_Balance(IBasicAudio* iface,long lBalance)
{
	CAudioRendererImpl_THIS(iface,basaud);
	HRESULT hr;

	FIXME("(%p)->(%ld)\n",This,lBalance);

	if ( lBalance > 0 || lBalance < -10000 )
		return E_INVALIDARG;

	EnterCriticalSection( &This->basefilter.csFilter );
	This->m_lAudioBalance = lBalance;
	hr = CAudioRendererImpl_UpdateVolume( This );
	LeaveCriticalSection( &This->basefilter.csFilter );

	return hr;
}

static HRESULT WINAPI
IBasicAudio_fnget_Balance(IBasicAudio* iface,long* plBalance)
{
	CAudioRendererImpl_THIS(iface,basaud);

	FIXME("(%p)->(%p)\n",This,plBalance);

	if ( plBalance == NULL )
		return E_POINTER;

	EnterCriticalSection( &This->basefilter.csFilter );
	*plBalance = This->m_lAudioBalance;
	LeaveCriticalSection( &This->basefilter.csFilter );

	return S_OK;
}


static ICOM_VTABLE(IBasicAudio) ibasicaudio =
{
	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
	/* IUnknown fields */
	IBasicAudio_fnQueryInterface,
	IBasicAudio_fnAddRef,
	IBasicAudio_fnRelease,
	/* IDispatch fields */
	IBasicAudio_fnGetTypeInfoCount,
	IBasicAudio_fnGetTypeInfo,
	IBasicAudio_fnGetIDsOfNames,
	IBasicAudio_fnInvoke,
	/* IBasicAudio fields */
	IBasicAudio_fnput_Volume,
	IBasicAudio_fnget_Volume,
	IBasicAudio_fnput_Balance,
	IBasicAudio_fnget_Balance,
};


HRESULT CAudioRendererImpl_InitIBasicAudio( CAudioRendererImpl* This )
{
	TRACE("(%p)\n",This);
	ICOM_VTBL(&This->basaud) = &ibasicaudio;

	return NOERROR;
}

void CAudioRendererImpl_UninitIBasicAudio( CAudioRendererImpl* This )
{
	TRACE("(%p)\n",This);
}

