19#ifndef _USE_MATH_DEFINES
20#define _USE_MATH_DEFINES
54 InitializeCriticalSection(&
m_lock);
61 DEBUG_INFO(
"DESTRUCTOR: CWinAudioStream: START\n");
66 DeleteCriticalSection(&
m_lock);
68 DEBUG_INFO(
"DESTRUCTOR: CWinAudioStream: END\n");
90 format = *(WAVEFORMATEX*)media.pbFormat;
163 DMO_MEDIA_TYPE media;
165 format = *(WAVEFORMATEX*)media.pbFormat;
169 MMRESULT ret = ::waveOutOpen(&
m_hWave, WAVE_MAPPER, &format, NULL, NULL, 0);
170 if (ret!=MMSYSERR_NOERROR)
return FALSE;
215 if (buf.buf==NULL || buf.vldsz<=0)
return;
217 Write((
const void*)buf.buf, (ULONG)buf.vldsz, NULL);
244 if (pcbRead==NULL)
return E_INVALIDARG;
246 ULONG bytesPendingToRead = cbBuffer;
253 ULONG bytesRead = cbBuffer - bytesPendingToRead;
256 *pcbRead = bytesRead;
265 if (plibNewPosition!=NULL) plibNewPosition->QuadPart =
m_readBufferCount + dlibMove.QuadPart;
277 if (!(header->dwFlags & WHDR_DONE))
return E_FAIL ;
279 MMRESULT ret = ::waveOutUnprepareHeader(
m_hWave, header,
sizeof(WAVEHDR));
280 if (ret!=MMSYSERR_NOERROR)
return E_FAIL;
282 header->dwBufferLength = (DWORD)bufsz;
284 memcpy(header->lpData, pbuf, bufsz);
286 ret = ::waveOutPrepareHeader(
m_hWave, header,
sizeof(WAVEHDR));
287 if (ret!=MMSYSERR_NOERROR) {
288 header->dwFlags = WHDR_DONE;
292 ret = ::waveOutWrite(
m_hWave, header,
sizeof(WAVEHDR));
293 if (ret!=MMSYSERR_NOERROR) {
294 header->dwFlags = WHDR_DONE;
313 EnterCriticalSection(&
m_lock);
326 LeaveCriticalSection(&
m_lock);
335 if (pMediaBuf!=NULL) {
336 EnterCriticalSection(&
m_lock);
341 LeaveCriticalSection(&
m_lock);
349 EnterCriticalSection(&
m_lock);
362 LeaveCriticalSection(&
m_lock);
369 if (cbData<=0)
return;
375 BYTE* pWriteData = NULL;
376 DWORD cbWriteData = 0;
377 DWORD cbMaxLength = 0;
383 if (cbWriteData+cbData<cbMaxLength) {
384 memcpy(pWriteData+cbWriteData, pData, cbData);
393 memcpy(pWriteData, pData, cbData);
402 EnterCriticalSection(&
m_lock);
407 LeaveCriticalSection(&
m_lock);
414 EnterCriticalSection(&
m_lock);
428 DWORD dwDataLength = 0;
433 *ppbData = (*ppbData) + cbToCopy;
434 *pcbData = (*pcbData) - cbToCopy;
450 LeaveCriticalSection(&
m_lock);
465 HANDLE mmHandle = NULL;
466 DWORD mmTaskIndex = 0;
469 bool bContinue =
true;
471 BYTE* pbOutputBuffer = NULL;
474 DMO_OUTPUT_DATA_BUFFER OutputBufferStruct = {0};
475 OutputBufferStruct.pBuffer = (IMediaBuffer*)&outputBuffer;
478 ULONG cbProduced = 0;
481 mmHandle = AvSetMmThreadCharacteristics(_T(
"Audio"), &mmTaskIndex);
485 if (WaitForSingleObject(
m_hStopEvent, 0)==WAIT_OBJECT_0) {
491 outputBuffer.
clear();
492 OutputBufferStruct.dwStatus = 0;
494 hr =
m_pMediaObj->ProcessOutput(0, 1, &OutputBufferStruct, &dwStatus);
499 else if (hr==S_FALSE) {
512 }
while (OutputBufferStruct.dwStatus & DMO_OUTPUT_DATA_BUFFERF_INCOMPLETE);
520 AvRevertMmThreadCharacteristics(mmHandle);
523 if (FAILED(hr))
return FALSE;
STDMETHODIMP Read(void *, ULONG, ULONG *)
CWinMediaBuffer * m_readBuffer
void QueueCapturedBuffer(CWinMediaBuffer *pMediaBuf)
void Back2BufferStack(CWinMediaBuffer *pMediaBuf)
static UINT CaptureThread(LPVOID pParam)
CWinThread * m_captureThread
CWinAudioStream(IMediaObject *pObj)
MediaBufferStack m_bufferStack
CWinMediaBuffer * GetWriteBuffer(void)
CWinMediaBuffer * m_writeBuffer
STDMETHODIMP Seek(LARGE_INTEGER, DWORD, ULARGE_INTEGER *)
virtual ~CWinAudioStream(void)
BOOL startCapture(WAVEFORMATEX *format=NULL)
IMediaObject * m_pMediaObj
void Back2BufferStackAll(void)
ULONG m_outputBufferIndex
void freeOutputHeaders(void)
STDMETHODIMP Write(const void *, ULONG, ULONG *)
void QueueCapturedData(BYTE *pData, UINT cbData)
static const UINT MaxOutputBuffers
void ReadOneBuffer(BYTE **ppbData, ULONG *pcbData)
BOOL openOutput(ULONG bufcount=100, WAVEFORMATEX *format=NULL)
static const UINT MaxReadBuffers
MediaBufferQueue m_bufferQueue