#include "stdafx.h"
#include "AudioAllGather.h"
#include <windows.h>
#pragma comment(lib,"Winmm.lib")
CAudioAllGather::CAudioAllGather()
{
}
CAudioAllGather::~CAudioAllGather()
{
Free();
}
bool CAudioAllGather::Init()
{
if (bInit_) return true;
bInit_ = true;
return true;
}
void CAudioAllGather::SetPath(std::vector<std::string> const & listFileName)
{
listFileName_ = listFileName;
}
void CAudioAllGather::Free()
{
if (!bInit_) return;
bInit_ = false;
}
void CALLBACK waveCaptureProc(HWAVEIN hwi,
UINT uMsg,
DWORD_PTR dwInstance,
DWORD_PTR dwParam1,
DWORD_PTR dwParam2)
{
sAudioInfo *pInfo = reinterpret_cast<sAudioInfo *>(dwInstance);
if (!pInfo->bStart)
{
return;
}
LPWAVEHDR waveH = (LPWAVEHDR)dwParam1;
if ((WIM_DATA == uMsg))
{
/*if (pInfo->bStart)
{
waveInUnprepareHeader(hwi, waveH,sizeof(WAVEHDR));
}*/
fwrite(waveH->lpData, 1, waveH->dwBytesRecorded, pInfo->pFile.get()); //写出数据
auto id = GetCurrentThreadId();
//printf("Capture:[%d]\n", waveH->dwBytesRecorded);
//std::lock_guard<std::mutex> lc(pInfo->bStartMu);
if (pInfo->bStart)
{
//waveInPrepareHeader(hwi, waveH, sizeof(WAVEHDR));
waveInAddBuffer(hwi, waveH, sizeof(WAVEHDR)); //buffer重新放入采集队列
}
}
}
bool CAudioAllGather::Start()
{
if (!bInit_)
{
return false;
}
if (bStart_)
{
return false;
}
bStart_ = true;
auto nNum = waveInGetNumDevs();
auto itFile = listFileName_.begin();
for (int i = 0; i < nNum && itFile != listFileName_.end(); i++) //循环打印设备的信息
{
std::shared_ptr<sAudioInfo> pInfo = std::make_shared<sAudioInfo>();
pInfo->pParent = this;
WAVEINCAPS wic = {};
waveInGetDevCaps(i, &wic, sizeof(WAVEINCAPS)); //注意,i即为DeviceID
//printf("[Capture] DeviceNum:[%d], DevicePID:[%d], DeviceName:%s\n", i, wic.wPid, wic.szPname);
HWAVEIN hWave = {};
WAVEFORMATEX waveForm = {};
memset(&waveForm, 0, sizeof(WAVEFORMATEX));
waveForm.wFormatTag = WAVE_FORMAT_PCM;
waveForm.nChannels = 2;
//waveForm.nSamplesPerSec = 48000;
waveForm.nSamplesPerSec = 5000;
waveForm.nBlockAlign = 4;
waveForm.wBitsPerSample = 16;
waveForm.nAvgBytesPerSec = waveForm.nChannels*waveForm.nSamplesPerSec*waveForm.wBitsPerSample / 8;
waveForm.cbSize = 0;
MMRESULT ret = waveInOpen(&hWave, i, &waveForm, (DWORD_PTR)waveCaptureProc, reinterpret_cast<DWORD_PTR>(pInfo.get()), CALLBACK_FUNCTION);
if (MMSYSERR_NOERROR != ret)
{
goto errOpenWave;
}
listAudio_.push_back(pInfo);
pInfo->nInde = i;
pInfo->strAudioName = wic.szPname;
pInfo->hWave = hWave;
{
FILE *pFile = nullptr;
fopen_s(&pFile, (*itFile).c_str(), "wb");
if (nullptr == pFile)
{
goto errFile;
}
pInfo->pFile = std::shared_ptr<FILE>(pFile, [](FILE *p) {fclose(p); });
fwrite("RIFF",4,1,pFile);
int nFileLen = 0;
fwrite(&nFileLen, 4, 1, pFile);
fwrite("WAVE", 4, 1, pFile);
fwrite("fmt ", 4, 1, pFile);
int pclen = sizeof(PCMWAVEFORMAT);
fwrite(&pclen, 4, 1, pFile);
PCMWAVEFORMAT pc = {};
pc.wf.wFormatTag = 1;
pc.wf.nChannels = waveForm.nChannels;
pc.wf.nSamplesPerSec = waveForm.nSamplesPerSec;
pc.wf.nAvgBytesPerSec = waveForm.nAvgBytesPerSec;
pc.wf.nBlockAlign = waveForm.nBlockAlign;
pc.wBitsPerSample = waveForm.wBitsPerSample;
fwrite(&pc, sizeof(pc), 1, pFile);
fwrite("data", 4, 1, pFile);
int pALen = 0;
fwrite(&pALen, 4, 1, pFile);
}
for (int i = 0; i != bufferNum_; i++)
{
WAVEHDR *pWaveHDR = nullptr;
try
{
pWaveHDR = new WAVEHDR;
}
catch (const std::exception&)
{
goto errBuffer;
}
std::shared_ptr<WAVEHDR> shWaveHDR = std::shared_ptr<WAVEHDR>(pWaveHDR
,[](WAVEHDR *p)
{
if (p->lpData)
{
delete[] p->lpData;
}
delete p;
}
);
pInfo->listBuffer.push_back(shWaveHDR);
char *pBuffer = nullptr;
try
{
pBuffer = new char[bufferLen_];
}
catch (const std::exception&)
{
goto errBuffer;
}
shWaveHDR->lpData = pBuffer;
shWaveHDR->dwBufferLength = bufferLen_;
shWaveHDR->dwBytesRecorded = 0;
shWaveHDR->dwUser = 0;
shWaveHDR->dwFlags = 0;
shWaveHDR->dwLoops = 1;
shWaveHDR->lpNext = nullptr;
shWaveHDR->reserved = 0;
waveInPrepareHeader(hWave, shWaveHDR.get(), sizeof(WAVEHDR));
waveInAddBuffer(hWave, shWaveHDR.get(), sizeof(WAVEHDR));
}
pInfo->bStart = true;
waveInStart(hWave);
}
return true;
errOpenWave:
errFile:
errBuffer:
for (auto s : listAudio_)
{
if (s->bStart)
{
waveInStop(s->hWave);
}
for (auto buffer : s->listBuffer)
{
waveInUnprepareHeader(s->hWave, buffer.get(), sizeof(WAVEHDR));
}
waveInClose(s->hWave);
}
listAudio_.clear();
bStart_ = false;
return false;
}
void CAudioAllGather::Stop()
{
bStart_ = false;
auto id = GetCurrentThreadId();
for (auto s : listAudio_)
{
//std::lock_guard<std::mutex> lc(s->bStartMu);
if (s->bStart)
{
s->bStart = false;
waveInStop(s->hWave);
waveInReset(s->hWave);
}
for (auto buffer : s->listBuffer)
{
waveInUnprepareHeader(s->hWave, buffer.get(), sizeof(WAVEHDR));
}
waveInClose(s->hWave);
if (s->pFile)
{
int nLen = ftell(s->pFile.get());
fseek(s->pFile.get(), 4, SEEK_SET);
int nTemp = nLen - 8;
fwrite(&nTemp, 4, 1, s->pFile.get());
//int nSeek = 5 * 4 + sizeof(PCMWAVEFORMAT) + 4;
fseek(s->pFile.get(), 40, SEEK_SET);
nTemp = nLen - 44;
fwrite(&nTemp, 4, 1, s->pFile.get());
}
}
listAudio_.clear();
}
void CAudioAllGather::Pause(bool bPause)
{
}
录音测试代码
最新推荐文章于 2024-01-23 17:36:10 发布