Files
SimpleRemoter/server/2015Remote/Audio.cpp
yuanyuanxiang bd7b9ed492 减少捕获音视频时申请内存次数
减少音频视频捕获过程中频繁申请内存。
2019-01-22 20:44:23 +08:00

236 lines
5.5 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Audio.cpp: implementation of the CAudio class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Audio.h"
#include <iostream>
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CAudio::CAudio()
{
m_bExit = FALSE;
m_hThreadCallBack = false;
m_bIsWaveInUsed = FALSE;
m_bIsWaveOutUsed = FALSE;
m_nWaveInIndex = 0;
m_nWaveOutIndex = 0;
m_hEventWaveIn = CreateEvent(NULL, TRUE, FALSE, NULL);
m_hStartRecord = CreateEvent(NULL, TRUE, FALSE, NULL);
memset(&m_GSMWavefmt, 0, sizeof(GSM610WAVEFORMAT));
m_GSMWavefmt.wfx.wFormatTag = WAVE_FORMAT_GSM610;
m_GSMWavefmt.wfx.nChannels = 1;
m_GSMWavefmt.wfx.nSamplesPerSec = 8000;
m_GSMWavefmt.wfx.nAvgBytesPerSec = 1625;
m_GSMWavefmt.wfx.nBlockAlign = 65;
m_GSMWavefmt.wfx.wBitsPerSample = 0;
m_GSMWavefmt.wfx.cbSize = 2;
m_GSMWavefmt.wSamplesPerBlock = 320;
m_ulBufferLength = 1000;
for (int i = 0; i < 2; ++i)
{
m_InAudioData[i] = new BYTE[m_ulBufferLength];
m_InAudioHeader[i] = new WAVEHDR;
m_OutAudioData[i] = new BYTE[m_ulBufferLength];
m_OutAudioHeader[i] = new WAVEHDR;
}
}
CAudio::~CAudio()
{
m_bExit = TRUE;
if (m_bIsWaveInUsed)
{
waveInStop(m_hWaveIn);
waveInReset(m_hWaveIn);
for (int i = 0; i < 2; ++i)
waveInUnprepareHeader(m_hWaveIn, m_InAudioHeader[i], sizeof(WAVEHDR));
waveInClose(m_hWaveIn);
WAIT (m_hThreadCallBack, 30);
if (m_hThreadCallBack)
printf("ûÓгɹ¦¹Ø±ÕwaveInCallBack.\n");
}
for (int i = 0; i < 2; ++i)
{
delete [] m_InAudioData[i];
m_InAudioData[i] = NULL;
delete [] m_InAudioHeader[i];
m_InAudioHeader[i] = NULL;
}
if (m_hEventWaveIn)
{
SetEvent(m_hEventWaveIn);
CloseHandle(m_hEventWaveIn);
m_hEventWaveIn = NULL;
}
if (m_hStartRecord)
{
SetEvent(m_hStartRecord);
CloseHandle(m_hStartRecord);
m_hStartRecord = NULL;
}
if (m_bIsWaveOutUsed)
{
waveOutReset(m_hWaveOut);
for (int i = 0; i < 2; ++i)
waveOutUnprepareHeader(m_hWaveOut, m_InAudioHeader[i], sizeof(WAVEHDR));
waveOutClose(m_hWaveOut);
}
for (int i = 0; i < 2; ++i)
{
delete [] m_OutAudioData[i];
m_OutAudioData[i] = NULL;
delete [] m_OutAudioHeader[i];
m_OutAudioHeader[i] = NULL;
}
}
BOOL CAudio::InitializeWaveIn()
{
MMRESULT mmResult;
DWORD dwThreadID = 0;
HANDLE h = NULL;
m_hThreadCallBack = h = CreateThread(NULL, 0,
(LPTHREAD_START_ROUTINE)waveInCallBack, (LPVOID)this,
CREATE_SUSPENDED, &dwThreadID);
//´ò¿ªÂ¼ÒôÉ豸COM 1 Ö¸¶¨ÉùÒô¹æ¸ñ 2 Ö§³Öͨ¹ýÏ̻߳ص÷ »»»º³å
mmResult = waveInOpen(&m_hWaveIn, (WORD)WAVE_MAPPER,
&(m_GSMWavefmt.wfx), (LONG)dwThreadID, (LONG)0, CALLBACK_THREAD);
//m_hWaveIn ¼Òô»ú¾ä±ú
if (mmResult != MMSYSERR_NOERROR)
{
return FALSE;
}
//¼ÒôÉ豸 ÐèÒªµÄÁ½¸ö»º³å
for (int i=0; i<2; ++i)
{
m_InAudioHeader[i]->lpData = (LPSTR)m_InAudioData[i]; //m_lpInAudioData Ö¸ÕëÊý×é
m_InAudioHeader[i]->dwBufferLength = m_ulBufferLength;
m_InAudioHeader[i]->dwFlags = 0;
m_InAudioHeader[i]->dwLoops = 0;
waveInPrepareHeader(m_hWaveIn, m_InAudioHeader[i], sizeof(WAVEHDR));
}
waveInAddBuffer(m_hWaveIn, m_InAudioHeader[m_nWaveInIndex], sizeof(WAVEHDR));
ResumeThread(h);
CloseHandle(h);
waveInStart(m_hWaveIn); //¼Òô
m_bIsWaveInUsed = TRUE;
return true;
}
LPBYTE CAudio::GetRecordBuffer(LPDWORD dwBufferSize)
{
//¼Òô»ú
if(m_bIsWaveInUsed==FALSE && InitializeWaveIn()==FALSE)
{
return NULL;
}
if (dwBufferSize == NULL)
{
return NULL;
}
SetEvent(m_hStartRecord);
WaitForSingleObject(m_hEventWaveIn, INFINITE);
*dwBufferSize = m_ulBufferLength;
return m_InAudioData[m_nWaveInIndex]; //·µ³öÕæÕýÊý¾Ý
}
DWORD WINAPI CAudio::waveInCallBack(LPVOID lParam)
{
CAudio *This = (CAudio *)lParam;
MSG Msg;
while (GetMessage(&Msg, NULL, 0, 0))
{
if (This->m_bExit)
break;
if (Msg.message == MM_WIM_DATA)
{
SetEvent(This->m_hEventWaveIn);
WaitForSingleObject(This->m_hStartRecord, INFINITE);
Sleep(1);
This->m_nWaveInIndex = 1 - This->m_nWaveInIndex;
//¸üлº³å
MMRESULT mmResult = waveInAddBuffer(This->m_hWaveIn,
This->m_InAudioHeader[This->m_nWaveInIndex], sizeof(WAVEHDR));
if (mmResult != MMSYSERR_NOERROR)
return -1;
}
if (Msg.message == MM_WIM_CLOSE)
{
break;
}
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
std::cout<<"waveInCallBack end\n";
This->m_hThreadCallBack = false;
return 0;
}
BOOL CAudio::PlayBuffer(LPBYTE szBuffer, DWORD dwBufferSize)
{
if (!m_bIsWaveOutUsed && !InitializeWaveOut()) //1 ÒôƵ¸ñʽ 2 ²¥ÒôÉ豸
return NULL;
for (int i = 0; i < dwBufferSize; i += m_ulBufferLength)
{
memcpy(m_OutAudioData[m_nWaveOutIndex], szBuffer, m_ulBufferLength);
waveOutWrite(m_hWaveOut, m_OutAudioHeader[m_nWaveOutIndex], sizeof(WAVEHDR));
m_nWaveOutIndex = 1 - m_nWaveOutIndex;
}
return true;
}
BOOL CAudio::InitializeWaveOut()
{
if (!waveOutGetNumDevs())
return FALSE;
int i;
for (i = 0; i < 2; ++i)
memset(m_OutAudioData[i], 0, m_ulBufferLength); //ÉùÒôÊý¾Ý
MMRESULT mmResult;
mmResult = waveOutOpen(&m_hWaveOut, (WORD)WAVE_MAPPER, &(m_GSMWavefmt.wfx), (LONG)0, (LONG)0, CALLBACK_NULL);
if (mmResult != MMSYSERR_NOERROR)
return false;
for (i = 0; i < 2; ++i)
{
m_OutAudioHeader[i]->lpData = (LPSTR)m_OutAudioData[i];
m_OutAudioHeader[i]->dwBufferLength = m_ulBufferLength;
m_OutAudioHeader[i]->dwFlags = 0;
m_OutAudioHeader[i]->dwLoops = 0;
waveOutPrepareHeader(m_hWaveOut, m_OutAudioHeader[i], sizeof(WAVEHDR));
}
m_bIsWaveOutUsed = TRUE;
return TRUE;
}