|
|
// Copyright (c) 1997 - 1998 Microsoft Corporation. All Rights Reserved.
// austrm.h : Declaration of the CAudioStream
/*
Basic design ------------
For simplification purposes we will always provide our own allocator buffer and copy into the application's buffer. This will fix 2 problems:
1. Confusion caused by the filter no filling the allocator's buffers.
2. Problems when the application doesn't supply a big enough buffer.
NOTES -----
Continuous update might be a bit dumb to use for audio */
#ifndef __AUSTREAM_H_
#define __AUSTREAM_H_
/////////////////////////////////////////////////////////////////////////////
// CAudioStream
class ATL_NO_VTABLE CAudioStream : public CComCoClass<CAudioStream, &CLSID_AMAudioStream>, public CByteStream, public IAudioMediaStream { public:
//
// METHODS
//
CAudioStream();
//
// IMediaStream
//
//
// IMediaStream
//
// HACK HACK - the first 2 are duplicates but it won't link
// without
STDMETHODIMP GetMultiMediaStream( /* [out] */ IMultiMediaStream **ppMultiMediaStream) { return CStream::GetMultiMediaStream(ppMultiMediaStream); }
STDMETHODIMP GetInformation( /* [optional][out] */ MSPID *pPurposeId, /* [optional][out] */ STREAM_TYPE *pType) { return CStream::GetInformation(pPurposeId, pType); }
STDMETHODIMP SetState( /* [in] */ FILTER_STATE State ) { return CByteStream::SetState(State); }
STDMETHODIMP SetSameFormat(IMediaStream *pStream, DWORD dwFlags);
STDMETHODIMP AllocateSample( /* [in] */ DWORD dwFlags, /* [out] */ IStreamSample **ppSample );
STDMETHODIMP CreateSharedSample( /* [in] */ IStreamSample *pExistingSample, /* [in] */ DWORD dwFlags, /* [out] */ IStreamSample **ppNewSample );
STDMETHODIMP SendEndOfStream(DWORD dwFlags) { return CStream::SendEndOfStream(dwFlags); } //
// IPin
//
STDMETHODIMP ReceiveConnection(IPin * pConnector, const AM_MEDIA_TYPE *pmt);
//
// IMemAllocator
//
STDMETHODIMP SetProperties(ALLOCATOR_PROPERTIES* pRequest, ALLOCATOR_PROPERTIES* pActual); STDMETHODIMP GetProperties(ALLOCATOR_PROPERTIES* pProps);
//
// IAudioMediaStream
//
STDMETHODIMP GetFormat( /* [optional][out] */ LPWAVEFORMATEX lpWaveFormatCurrent );
STDMETHODIMP SetFormat( /* [in] */ const WAVEFORMATEX *lpWaveFormat );
STDMETHODIMP CreateSample( /* [in] */ IAudioData *pAudioData, /* [in] */ DWORD dwFlags, /* [out] */ IAudioStreamSample **ppSample );
//
// Special CStream methods
//
HRESULT GetMediaType(ULONG Index, AM_MEDIA_TYPE **ppMediaType);
LONG GetChopSize() { #ifdef MY_CHOP_SIZE
if (m_Direction == PINDIR_OUTPUT) { return MY_CHOP_SIZE; } #endif
return 65536; }
DECLARE_REGISTRY_RESOURCEID(IDR_AUDIOSTREAM)
protected: HRESULT InternalSetFormat(const WAVEFORMATEX *pFormat, bool bFromPin); HRESULT CheckFormat(const WAVEFORMATEX *pFormat, bool bForce=false);
BEGIN_COM_MAP(CAudioStream) COM_INTERFACE_ENTRY(IAudioMediaStream) COM_INTERFACE_ENTRY_CHAIN(CStream) END_COM_MAP()
protected: /* Format */ WAVEFORMATEX m_Format; bool m_fForceFormat; };
/////////////////////////////////////////////////////////////////////////////
// CAudioStreamSample
class ATL_NO_VTABLE CAudioStreamSample : public CByteStreamSample, public IAudioStreamSample { public: CAudioStreamSample() {}
// DELEGATE TO BASE CLASS
//
// IStreamSample
//
STDMETHODIMP GetMediaStream( /* [in] */ IMediaStream **ppMediaStream) { return CSample::GetMediaStream(ppMediaStream); }
STDMETHODIMP GetSampleTimes( /* [optional][out] */ STREAM_TIME *pStartTime, /* [optional][out] */ STREAM_TIME *pEndTime, /* [optional][out] */ STREAM_TIME *pCurrentTime) { return CSample::GetSampleTimes( pStartTime, pEndTime, pCurrentTime ); }
STDMETHODIMP SetSampleTimes( /* [optional][in] */ const STREAM_TIME *pStartTime, /* [optional][in] */ const STREAM_TIME *pEndTime) { return CSample::SetSampleTimes(pStartTime, pEndTime); }
STDMETHODIMP Update( /* [in] */ DWORD dwFlags, /* [optional][in] */ HANDLE hEvent, /* [optional][in] */ PAPCFUNC pfnAPC, /* [optional][in] */ DWORD_PTR dwAPCData) { return CByteStreamSample::Update(dwFlags, hEvent, pfnAPC, dwAPCData); }
STDMETHODIMP CompletionStatus( /* [in] */ DWORD dwFlags, /* [optional][in] */ DWORD dwMilliseconds) { return CSample::CompletionStatus(dwFlags, dwMilliseconds); }
BEGIN_COM_MAP(CAudioStreamSample) COM_INTERFACE_ENTRY(IAudioStreamSample) COM_INTERFACE_ENTRY_CHAIN(CSample) END_COM_MAP()
// IAudioStreamSample
STDMETHODIMP GetAudioData(IAudioData **ppAudioData) { return m_pMemData->QueryInterface(IID_IAudioData, (void **)ppAudioData); }
// Set the pointer
HRESULT SetSizeAndPointer(BYTE *pbData, LONG lActual, LONG lSize) { m_pbData = pbData; m_cbSize = (DWORD)lSize; m_cbData = (DWORD)lActual; return S_OK; } };
// Audio data object
class ATL_NO_VTABLE CAudioData : public CComObjectRootEx<CComMultiThreadModel>, public IAudioData, public CComCoClass<CAudioData, &CLSID_AMAudioData> { public: CAudioData(); ~CAudioData();
DECLARE_REGISTRY_RESOURCEID(IDR_AUDIODATA)
BEGIN_COM_MAP(CAudioData) COM_INTERFACE_ENTRY(IAudioData) END_COM_MAP()
//
// IMemoryData
//
STDMETHODIMP SetBuffer( /* [in] */ DWORD cbSize, /* [in] */ BYTE * pbData, /* [in] */ DWORD dwFlags ) { if (dwFlags != 0 || cbSize == 0) { return E_INVALIDARG; } //
// Free anything we allocated ourselves -- We allow multiple calls to this method
//
if (m_bWeAllocatedData) { CoTaskMemFree(m_pbData); m_bWeAllocatedData = false; } m_cbSize = cbSize; if (pbData) { m_pbData = pbData; return S_OK; } else { m_pbData = (BYTE *)CoTaskMemAlloc(cbSize); if (m_pbData) { m_bWeAllocatedData = true; return S_OK; } return E_OUTOFMEMORY; } }
STDMETHODIMP GetInfo( /* [out] */ DWORD *pdwLength, /* [out] */ BYTE **ppbData, /* [out] */ DWORD *pcbActualData ) { if (m_cbSize == 0) { return MS_E_NOTINIT; } if (pdwLength) { *pdwLength = m_cbSize; } if (ppbData) { *ppbData = m_pbData; } if (pcbActualData) { *pcbActualData = m_cbData; } return S_OK; } STDMETHODIMP SetActual( /* [in] */ DWORD cbDataValid ) { if (cbDataValid > m_cbSize) { return E_INVALIDARG; } m_cbData = cbDataValid; return S_OK; }
//
// IAudioData
//
STDMETHODIMP GetFormat( /* [out] [optional] */ WAVEFORMATEX *pWaveFormatCurrent ) { if (pWaveFormatCurrent == NULL) { return E_POINTER; } *pWaveFormatCurrent = m_Format; return S_OK; }
STDMETHODIMP SetFormat( /* [in] */ const WAVEFORMATEX *lpWaveFormat ) { if (lpWaveFormat == NULL) { return E_POINTER; } if (lpWaveFormat->wFormatTag != WAVE_FORMAT_PCM) { return E_INVALIDARG; } m_Format = *lpWaveFormat; return S_OK; }
protected: PBYTE m_pbData; DWORD m_cbSize; DWORD m_cbData; WAVEFORMATEX m_Format; bool m_bWeAllocatedData; };
#endif // __AUSTREAM_H_
|