-
Notifications
You must be signed in to change notification settings - Fork 81
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
687 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
#pragma once | ||
#include <windows.h> | ||
#include <stdio.h> | ||
#include <assert.h> | ||
#include <time.h> | ||
|
||
#pragma comment(lib, "winmm.lib") | ||
|
||
#define AUDIO_AVGBYTESPERSEC 96000 | ||
#define AUDIO_SAMPLESPERSEC 44100 | ||
#define AUDIO_CHANNELS 2 | ||
#define AUDIO_BITSPERSAMPLE 16 | ||
|
||
#define AUDIO_BUFF_MAXCOUNT 3 // 3个缓冲区; | ||
#define AUDIO_BUFF_MAXSIZE 176400 // 每个缓冲区的最大录音数据(最大值); | ||
|
||
class AudioInfo | ||
{ | ||
public: | ||
AudioInfo() | ||
{ | ||
iAvgBytesPerSec = AUDIO_AVGBYTESPERSEC; | ||
iChannels = AUDIO_CHANNELS; | ||
iBitsPerSample = AUDIO_BITSPERSAMPLE; | ||
iSamplesPerSec = AUDIO_SAMPLESPERSEC; | ||
} | ||
|
||
int iAvgBytesPerSec; // 码率; | ||
int iChannels; // 通道数; | ||
int iBitsPerSample; // 采样位数; | ||
int iSamplesPerSec; // 采样频率; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
#include "WAVDecoder.h" | ||
|
||
CWAVDecoder::CWAVDecoder() | ||
{ | ||
m_bStop = true; | ||
m_pCallBack = NULL; | ||
} | ||
|
||
CWAVDecoder::~CWAVDecoder() | ||
{ | ||
} | ||
|
||
void CWAVDecoder::SetAudioBack(OnSetAudioBuff pCallBack) | ||
{ | ||
m_pCallBack = pCallBack; | ||
} | ||
|
||
void CWAVDecoder::SetAudioInfo(const AudioInfo& info) | ||
{ | ||
m_audioInfo = info; | ||
} | ||
|
||
int CWAVDecoder::Start() | ||
{ | ||
memset(&m_waveform, 0, sizeof(WAVEFORMATEX)); | ||
int iChannels = m_audioInfo.iChannels; | ||
int iBitsPerSample = m_audioInfo.iBitsPerSample; | ||
m_waveform.wFormatTag = WAVE_FORMAT_PCM; // 声音格式为PCM; | ||
m_waveform.nSamplesPerSec = m_audioInfo.iSamplesPerSec; // 采样率; | ||
m_waveform.wBitsPerSample = iBitsPerSample; // 采样比特,16bits/次; | ||
m_waveform.nChannels = iChannels; // 采样声道数,2声道; | ||
m_waveform.nAvgBytesPerSec = m_audioInfo.iAvgBytesPerSec; // 每秒的数据率,就是每秒能采集多少字节的数据; | ||
m_waveform.nBlockAlign = (iChannels * iBitsPerSample) / 8; // 一个块的大小,采样bit的bits数乘以声道数/8; | ||
m_waveform.cbSize = 0; // 额外外信息大小, 一般为0; | ||
|
||
// 打开设备; | ||
MMRESULT iRes = waveOutOpen(&m_hWaveOut, WAVE_MAPPER, &m_waveform, (DWORD)(WaveOutProc), (DWORD)this, CALLBACK_FUNCTION); | ||
if (iRes != 0) | ||
{ | ||
printf("open waveIn err!\n"); | ||
exit(0); | ||
} | ||
|
||
for (int i = 0; i < AUDIO_BUFF_MAXCOUNT; i++) // 设置内存块格式; | ||
{ | ||
m_arrHdr[i].lpData = m_BuffOut[i]; | ||
m_arrHdr[i].dwBufferLength = AUDIO_BUFF_MAXSIZE; | ||
m_arrHdr[i].dwBytesRecorded = 0; | ||
m_arrHdr[i].dwUser = i; | ||
m_arrHdr[i].dwFlags = 0; | ||
waveOutPrepareHeader(m_hWaveOut, &m_arrHdr[i], sizeof(WAVEHDR)); // 准备内存块录音; | ||
waveOutWrite(m_hWaveOut, &m_arrHdr[i], sizeof(WAVEHDR)); // 增加内存块; | ||
} | ||
|
||
m_bStop = false; | ||
|
||
return 0; | ||
} | ||
|
||
int CWAVDecoder::Stop() | ||
{ | ||
// 此处不能释放, 去线程结束时释放; | ||
m_bStop = true; | ||
|
||
return 0; | ||
} | ||
|
||
DWORD CALLBACK CWAVDecoder::WaveOutProc(HWAVEIN hwi, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2) | ||
{ | ||
CWAVDecoder* pThis = reinterpret_cast<CWAVDecoder*>(dwInstance); | ||
assert(pThis); | ||
|
||
if (uMsg == WOM_DONE) | ||
{ | ||
WAVEHDR*p = (WAVEHDR*)dwParam1; | ||
int i = p->dwUser; | ||
waveOutUnprepareHeader(pThis->m_hWaveOut, p, sizeof(WAVEHDR)); | ||
|
||
int iDataSize = 0; | ||
if (pThis->m_pCallBack) | ||
{ | ||
iDataSize = pThis->m_pCallBack(pThis->m_BuffOut[i], AUDIO_BUFF_MAXSIZE); | ||
} | ||
if (iDataSize < AUDIO_BUFF_MAXSIZE) | ||
{ | ||
printf("play over!\n"); | ||
pThis->m_bStop = true; | ||
return 0; | ||
} | ||
|
||
p->lpData = pThis->m_BuffOut[i]; | ||
p->dwBufferLength = iDataSize; | ||
p->dwBytesRecorded = 0; | ||
p->dwUser = i; | ||
p->dwFlags = 0; | ||
|
||
waveOutPrepareHeader(pThis->m_hWaveOut, p, sizeof(WAVEHDR)); //准备内存块录音 | ||
waveOutWrite(pThis->m_hWaveOut, p, sizeof(WAVEHDR)); | ||
} | ||
if (uMsg == WOM_OPEN) | ||
{ | ||
printf("wom open\n"); | ||
} | ||
if (uMsg == WOM_CLOSE) | ||
{ | ||
printf("wom close\n"); | ||
} | ||
return 0; | ||
} | ||
|
||
int CWAVDecoder::Clear() | ||
{ | ||
waveOutRestart(m_hWaveOut); | ||
for (int i = 0; i < AUDIO_BUFF_MAXCOUNT; i++) | ||
{ | ||
waveOutUnprepareHeader(m_hWaveOut, &m_arrHdr[i], sizeof(WAVEHDR)); | ||
} | ||
printf("Start Close\n"); | ||
waveOutClose(m_hWaveOut); | ||
|
||
return 1; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
#pragma once | ||
#include "AudioInfo.h" | ||
|
||
// 获取AudioBuff的回调函数 原始PCM数据; | ||
typedef int(*OnSetAudioBuff)(char* pBuff, int iBuffSize); | ||
|
||
class CWAVDecoder | ||
{ | ||
public: | ||
CWAVDecoder(); | ||
~CWAVDecoder(); | ||
|
||
void SetAudioBack(OnSetAudioBuff pCallBack); | ||
void SetAudioInfo(const AudioInfo& info); | ||
|
||
int Start(); | ||
int Stop(); | ||
int Clear(); | ||
|
||
// 回调函数,需要时由外部传入数据; | ||
static DWORD CALLBACK WaveOutProc(HWAVEIN hwi, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2); | ||
|
||
private: | ||
bool m_bStop; | ||
AudioInfo m_audioInfo; | ||
|
||
HWAVEOUT m_hWaveOut; // 输出设备; | ||
WAVEFORMATEX m_waveform; // 采集音频的格式,结构体; | ||
WAVEHDR m_arrHdr[AUDIO_BUFF_MAXCOUNT]; // 采集音频时包含数据缓存的结构体; | ||
char m_BuffOut[AUDIO_BUFF_MAXCOUNT][AUDIO_BUFF_MAXSIZE]; | ||
OnSetAudioBuff m_pCallBack; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
#include "WAVEncoder.h" | ||
|
||
CWAVEncoder::CWAVEncoder() | ||
{ | ||
m_bStop = true; | ||
m_pCallBack = NULL; | ||
} | ||
|
||
CWAVEncoder::~CWAVEncoder() | ||
{ | ||
} | ||
|
||
void CWAVEncoder::SetAudioBack(OnGetAudioBuff pCallBack) | ||
{ | ||
m_pCallBack = pCallBack; | ||
} | ||
|
||
void CWAVEncoder::SetAudioInfo(const AudioInfo& info) | ||
{ | ||
m_audioInfo = info; | ||
} | ||
|
||
int CWAVEncoder::Start() | ||
{ | ||
memset(&waveform, 0, sizeof(WAVEFORMATEX)); | ||
int iChannels = m_audioInfo.iChannels; | ||
int iBitsPerSample = m_audioInfo.iBitsPerSample; | ||
waveform.wFormatTag = WAVE_FORMAT_PCM; // 声音格式为PCM; | ||
waveform.nSamplesPerSec = m_audioInfo.iSamplesPerSec; // 采样率; | ||
waveform.wBitsPerSample = iBitsPerSample; // 采样比特,16bits/次; | ||
waveform.nChannels = iChannels; // 采样声道数,2声道; | ||
waveform.nAvgBytesPerSec = m_audioInfo.iAvgBytesPerSec; // 每秒的数据率,就是每秒能采集多少字节的数据; | ||
waveform.nBlockAlign = (iChannels * iBitsPerSample) / 8; // 一个块的大小,采样bit的bits数乘以声道数/8; | ||
waveform.cbSize = 0; // 额外外信息大小, 一般为0; | ||
|
||
// 打开设备; | ||
MMRESULT iRes = waveInOpen(&hWaveIn, WAVE_MAPPER, &waveform, (DWORD)(WaveInProc), (DWORD)this, CALLBACK_FUNCTION); | ||
if (iRes != 0) | ||
{ | ||
printf("open waveIn err!\n"); | ||
exit(0); | ||
} | ||
unsigned int iWaveID = -1; | ||
waveInGetID(hWaveIn, &iWaveID); // 你所使用的输入设备ID,-1为默认; | ||
printf("you use waveid: %d \n", iWaveID); | ||
|
||
for (int i = 0; i < AUDIO_BUFF_MAXCOUNT; i++) // 设置内存块格式; | ||
{ | ||
wHdr[i].lpData = chBuff[i]; | ||
wHdr[i].dwBufferLength = AUDIO_BUFF_MAXSIZE; | ||
wHdr[i].dwBytesRecorded = 0; | ||
wHdr[i].dwUser = i; | ||
wHdr[i].dwFlags = 0; | ||
waveInPrepareHeader(hWaveIn, &wHdr[i], sizeof(WAVEHDR)); // 准备内存块录音; | ||
waveInAddBuffer(hWaveIn, &wHdr[i], sizeof(WAVEHDR)); // 增加内存块; | ||
} | ||
|
||
m_bStop = false; | ||
waveInStart(hWaveIn); //开始录音; | ||
|
||
return 0; | ||
} | ||
|
||
int CWAVEncoder::Stop() | ||
{ | ||
// 此处不能释放, 去线程结束时释放; | ||
m_bStop = true; | ||
|
||
return 0; | ||
} | ||
|
||
DWORD CALLBACK CWAVEncoder::WaveInProc(HWAVEIN hwi, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2) | ||
{ | ||
CWAVEncoder* pThis = reinterpret_cast<CWAVEncoder*>(dwInstance); | ||
assert(pThis); | ||
|
||
if (uMsg == WIM_DATA) | ||
{ | ||
WAVEHDR* p = (WAVEHDR*)dwParam1; // dwParam1指向WAVEHDR的地址; | ||
printf("getdate id: %d size:%d timestemp:%d\n", p->dwUser, p->dwBytesRecorded, clock()); | ||
int iIndex = p->dwUser; | ||
if (pThis->m_bStop) //0表示停止了 | ||
{ | ||
waveInUnprepareHeader(pThis->hWaveIn, p, sizeof(WAVEHDR)); // 释放; | ||
return 0; | ||
} | ||
else | ||
{ | ||
if (pThis->m_pCallBack) | ||
{ | ||
pThis->m_pCallBack(pThis->chBuff[iIndex], p->dwBytesRecorded); | ||
} | ||
waveInUnprepareHeader(pThis->hWaveIn, p, sizeof(WAVEHDR)); // 释放; | ||
} | ||
p->lpData = pThis->chBuff[iIndex]; | ||
p->dwBufferLength = AUDIO_BUFF_MAXSIZE; | ||
p->dwBytesRecorded = 0; | ||
p->dwUser = iIndex; | ||
p->dwFlags = 0; | ||
waveInPrepareHeader(pThis->hWaveIn, p, sizeof(WAVEHDR)); // 准备内存块录音; | ||
waveInAddBuffer(pThis->hWaveIn, p, sizeof(WAVEHDR)); // 增加内存块; | ||
} | ||
if (uMsg == WIM_OPEN) | ||
{ | ||
printf("open\n"); | ||
} | ||
if (uMsg == WIM_CLOSE) | ||
{ | ||
printf("close\n"); | ||
} | ||
return 0; | ||
} | ||
|
||
int CWAVEncoder::Clear() | ||
{ | ||
printf("Start Stop\n"); | ||
waveInStop(hWaveIn); | ||
printf("Start Reset\n"); | ||
waveInReset(hWaveIn); | ||
printf("Start Close\n"); | ||
waveInClose(hWaveIn); | ||
|
||
return 1; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
#pragma once | ||
#include <windows.h> | ||
#include <stdio.h> | ||
#include "AudioInfo.h" | ||
|
||
// 获取AudioBuff的回调函数 原始PCM数据; | ||
typedef int(*OnGetAudioBuff)(const char* pBuff, const int& iBuffSize); | ||
|
||
class CWAVEncoder | ||
{ | ||
public: | ||
CWAVEncoder(); | ||
~CWAVEncoder(); | ||
|
||
void SetAudioBack(OnGetAudioBuff pCallBack); | ||
void SetAudioInfo(const AudioInfo& info); | ||
|
||
int Start(); | ||
int Stop(); | ||
int Clear(); | ||
|
||
// 回调函数,当缓冲区录满就会调用该函数; | ||
static DWORD CALLBACK WaveInProc(HWAVEIN hwi, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2); | ||
|
||
private: | ||
bool m_bStop; | ||
AudioInfo m_audioInfo; | ||
|
||
HWAVEIN hWaveIn; // 输入设备; | ||
WAVEFORMATEX waveform; // 采集音频的格式,结构体; | ||
WAVEHDR wHdr[AUDIO_BUFF_MAXCOUNT]; // 采集音频时包含数据缓存的结构体; | ||
char chBuff[AUDIO_BUFF_MAXCOUNT][AUDIO_BUFF_MAXSIZE]; | ||
OnGetAudioBuff m_pCallBack; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
|
||
Microsoft Visual Studio Solution File, Format Version 12.00 | ||
# Visual Studio 2013 | ||
VisualStudioVersion = 12.0.21005.1 | ||
MinimumVisualStudioVersion = 10.0.40219.1 | ||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WAV_Codec", "WAV_Codec.vcxproj", "{015D9418-85CA-4049-8BD0-2FE794F991BB}" | ||
EndProject | ||
Global | ||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||
Debug|Win32 = Debug|Win32 | ||
Release|Win32 = Release|Win32 | ||
EndGlobalSection | ||
GlobalSection(ProjectConfigurationPlatforms) = postSolution | ||
{015D9418-85CA-4049-8BD0-2FE794F991BB}.Debug|Win32.ActiveCfg = Debug|Win32 | ||
{015D9418-85CA-4049-8BD0-2FE794F991BB}.Debug|Win32.Build.0 = Debug|Win32 | ||
{015D9418-85CA-4049-8BD0-2FE794F991BB}.Release|Win32.ActiveCfg = Release|Win32 | ||
{015D9418-85CA-4049-8BD0-2FE794F991BB}.Release|Win32.Build.0 = Release|Win32 | ||
EndGlobalSection | ||
GlobalSection(SolutionProperties) = preSolution | ||
HideSolutionNode = FALSE | ||
EndGlobalSection | ||
EndGlobal |
Oops, something went wrong.