Skip to content

Commit e85187c

Browse files
committed
add wav codec
1 parent d7bf264 commit e85187c

File tree

10 files changed

+687
-0
lines changed

10 files changed

+687
-0
lines changed

WAV_Codec/AudioInfo.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#pragma once
2+
#include <windows.h>
3+
#include <stdio.h>
4+
#include <assert.h>
5+
#include <time.h>
6+
7+
#pragma comment(lib, "winmm.lib")
8+
9+
#define AUDIO_AVGBYTESPERSEC 96000
10+
#define AUDIO_SAMPLESPERSEC 44100
11+
#define AUDIO_CHANNELS 2
12+
#define AUDIO_BITSPERSAMPLE 16
13+
14+
#define AUDIO_BUFF_MAXCOUNT 3 // 3个缓冲区;
15+
#define AUDIO_BUFF_MAXSIZE 176400 // 每个缓冲区的最大录音数据(最大值);
16+
17+
class AudioInfo
18+
{
19+
public:
20+
AudioInfo()
21+
{
22+
iAvgBytesPerSec = AUDIO_AVGBYTESPERSEC;
23+
iChannels = AUDIO_CHANNELS;
24+
iBitsPerSample = AUDIO_BITSPERSAMPLE;
25+
iSamplesPerSec = AUDIO_SAMPLESPERSEC;
26+
}
27+
28+
int iAvgBytesPerSec; // 码率;
29+
int iChannels; // 通道数;
30+
int iBitsPerSample; // 采样位数;
31+
int iSamplesPerSec; // 采样频率;
32+
};

WAV_Codec/WAVDecoder.cpp

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
#include "WAVDecoder.h"
2+
3+
CWAVDecoder::CWAVDecoder()
4+
{
5+
m_bStop = true;
6+
m_pCallBack = NULL;
7+
}
8+
9+
CWAVDecoder::~CWAVDecoder()
10+
{
11+
}
12+
13+
void CWAVDecoder::SetAudioBack(OnSetAudioBuff pCallBack)
14+
{
15+
m_pCallBack = pCallBack;
16+
}
17+
18+
void CWAVDecoder::SetAudioInfo(const AudioInfo& info)
19+
{
20+
m_audioInfo = info;
21+
}
22+
23+
int CWAVDecoder::Start()
24+
{
25+
memset(&m_waveform, 0, sizeof(WAVEFORMATEX));
26+
int iChannels = m_audioInfo.iChannels;
27+
int iBitsPerSample = m_audioInfo.iBitsPerSample;
28+
m_waveform.wFormatTag = WAVE_FORMAT_PCM; // 声音格式为PCM;
29+
m_waveform.nSamplesPerSec = m_audioInfo.iSamplesPerSec; // 采样率;
30+
m_waveform.wBitsPerSample = iBitsPerSample; // 采样比特,16bits/次;
31+
m_waveform.nChannels = iChannels; // 采样声道数,2声道;
32+
m_waveform.nAvgBytesPerSec = m_audioInfo.iAvgBytesPerSec; // 每秒的数据率,就是每秒能采集多少字节的数据;
33+
m_waveform.nBlockAlign = (iChannels * iBitsPerSample) / 8; // 一个块的大小,采样bit的bits数乘以声道数/8;
34+
m_waveform.cbSize = 0; // 额外外信息大小, 一般为0;
35+
36+
// 打开设备;
37+
MMRESULT iRes = waveOutOpen(&m_hWaveOut, WAVE_MAPPER, &m_waveform, (DWORD)(WaveOutProc), (DWORD)this, CALLBACK_FUNCTION);
38+
if (iRes != 0)
39+
{
40+
printf("open waveIn err!\n");
41+
exit(0);
42+
}
43+
44+
for (int i = 0; i < AUDIO_BUFF_MAXCOUNT; i++) // 设置内存块格式;
45+
{
46+
m_arrHdr[i].lpData = m_BuffOut[i];
47+
m_arrHdr[i].dwBufferLength = AUDIO_BUFF_MAXSIZE;
48+
m_arrHdr[i].dwBytesRecorded = 0;
49+
m_arrHdr[i].dwUser = i;
50+
m_arrHdr[i].dwFlags = 0;
51+
waveOutPrepareHeader(m_hWaveOut, &m_arrHdr[i], sizeof(WAVEHDR)); // 准备内存块录音;
52+
waveOutWrite(m_hWaveOut, &m_arrHdr[i], sizeof(WAVEHDR)); // 增加内存块;
53+
}
54+
55+
m_bStop = false;
56+
57+
return 0;
58+
}
59+
60+
int CWAVDecoder::Stop()
61+
{
62+
// 此处不能释放, 去线程结束时释放;
63+
m_bStop = true;
64+
65+
return 0;
66+
}
67+
68+
DWORD CALLBACK CWAVDecoder::WaveOutProc(HWAVEIN hwi, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
69+
{
70+
CWAVDecoder* pThis = reinterpret_cast<CWAVDecoder*>(dwInstance);
71+
assert(pThis);
72+
73+
if (uMsg == WOM_DONE)
74+
{
75+
WAVEHDR*p = (WAVEHDR*)dwParam1;
76+
int i = p->dwUser;
77+
waveOutUnprepareHeader(pThis->m_hWaveOut, p, sizeof(WAVEHDR));
78+
79+
int iDataSize = 0;
80+
if (pThis->m_pCallBack)
81+
{
82+
iDataSize = pThis->m_pCallBack(pThis->m_BuffOut[i], AUDIO_BUFF_MAXSIZE);
83+
}
84+
if (iDataSize < AUDIO_BUFF_MAXSIZE)
85+
{
86+
printf("play over!\n");
87+
pThis->m_bStop = true;
88+
return 0;
89+
}
90+
91+
p->lpData = pThis->m_BuffOut[i];
92+
p->dwBufferLength = iDataSize;
93+
p->dwBytesRecorded = 0;
94+
p->dwUser = i;
95+
p->dwFlags = 0;
96+
97+
waveOutPrepareHeader(pThis->m_hWaveOut, p, sizeof(WAVEHDR)); //准备内存块录音
98+
waveOutWrite(pThis->m_hWaveOut, p, sizeof(WAVEHDR));
99+
}
100+
if (uMsg == WOM_OPEN)
101+
{
102+
printf("wom open\n");
103+
}
104+
if (uMsg == WOM_CLOSE)
105+
{
106+
printf("wom close\n");
107+
}
108+
return 0;
109+
}
110+
111+
int CWAVDecoder::Clear()
112+
{
113+
waveOutRestart(m_hWaveOut);
114+
for (int i = 0; i < AUDIO_BUFF_MAXCOUNT; i++)
115+
{
116+
waveOutUnprepareHeader(m_hWaveOut, &m_arrHdr[i], sizeof(WAVEHDR));
117+
}
118+
printf("Start Close\n");
119+
waveOutClose(m_hWaveOut);
120+
121+
return 1;
122+
}

WAV_Codec/WAVDecoder.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#pragma once
2+
#include "AudioInfo.h"
3+
4+
// 获取AudioBuff的回调函数 原始PCM数据;
5+
typedef int(*OnSetAudioBuff)(char* pBuff, int iBuffSize);
6+
7+
class CWAVDecoder
8+
{
9+
public:
10+
CWAVDecoder();
11+
~CWAVDecoder();
12+
13+
void SetAudioBack(OnSetAudioBuff pCallBack);
14+
void SetAudioInfo(const AudioInfo& info);
15+
16+
int Start();
17+
int Stop();
18+
int Clear();
19+
20+
// 回调函数,需要时由外部传入数据;
21+
static DWORD CALLBACK WaveOutProc(HWAVEIN hwi, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2);
22+
23+
private:
24+
bool m_bStop;
25+
AudioInfo m_audioInfo;
26+
27+
HWAVEOUT m_hWaveOut; // 输出设备;
28+
WAVEFORMATEX m_waveform; // 采集音频的格式,结构体;
29+
WAVEHDR m_arrHdr[AUDIO_BUFF_MAXCOUNT]; // 采集音频时包含数据缓存的结构体;
30+
char m_BuffOut[AUDIO_BUFF_MAXCOUNT][AUDIO_BUFF_MAXSIZE];
31+
OnSetAudioBuff m_pCallBack;
32+
};

WAV_Codec/WAVEncoder.cpp

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
#include "WAVEncoder.h"
2+
3+
CWAVEncoder::CWAVEncoder()
4+
{
5+
m_bStop = true;
6+
m_pCallBack = NULL;
7+
}
8+
9+
CWAVEncoder::~CWAVEncoder()
10+
{
11+
}
12+
13+
void CWAVEncoder::SetAudioBack(OnGetAudioBuff pCallBack)
14+
{
15+
m_pCallBack = pCallBack;
16+
}
17+
18+
void CWAVEncoder::SetAudioInfo(const AudioInfo& info)
19+
{
20+
m_audioInfo = info;
21+
}
22+
23+
int CWAVEncoder::Start()
24+
{
25+
memset(&waveform, 0, sizeof(WAVEFORMATEX));
26+
int iChannels = m_audioInfo.iChannels;
27+
int iBitsPerSample = m_audioInfo.iBitsPerSample;
28+
waveform.wFormatTag = WAVE_FORMAT_PCM; // 声音格式为PCM;
29+
waveform.nSamplesPerSec = m_audioInfo.iSamplesPerSec; // 采样率;
30+
waveform.wBitsPerSample = iBitsPerSample; // 采样比特,16bits/次;
31+
waveform.nChannels = iChannels; // 采样声道数,2声道;
32+
waveform.nAvgBytesPerSec = m_audioInfo.iAvgBytesPerSec; // 每秒的数据率,就是每秒能采集多少字节的数据;
33+
waveform.nBlockAlign = (iChannels * iBitsPerSample) / 8; // 一个块的大小,采样bit的bits数乘以声道数/8;
34+
waveform.cbSize = 0; // 额外外信息大小, 一般为0;
35+
36+
// 打开设备;
37+
MMRESULT iRes = waveInOpen(&hWaveIn, WAVE_MAPPER, &waveform, (DWORD)(WaveInProc), (DWORD)this, CALLBACK_FUNCTION);
38+
if (iRes != 0)
39+
{
40+
printf("open waveIn err!\n");
41+
exit(0);
42+
}
43+
unsigned int iWaveID = -1;
44+
waveInGetID(hWaveIn, &iWaveID); // 你所使用的输入设备ID,-1为默认;
45+
printf("you use waveid: %d \n", iWaveID);
46+
47+
for (int i = 0; i < AUDIO_BUFF_MAXCOUNT; i++) // 设置内存块格式;
48+
{
49+
wHdr[i].lpData = chBuff[i];
50+
wHdr[i].dwBufferLength = AUDIO_BUFF_MAXSIZE;
51+
wHdr[i].dwBytesRecorded = 0;
52+
wHdr[i].dwUser = i;
53+
wHdr[i].dwFlags = 0;
54+
waveInPrepareHeader(hWaveIn, &wHdr[i], sizeof(WAVEHDR)); // 准备内存块录音;
55+
waveInAddBuffer(hWaveIn, &wHdr[i], sizeof(WAVEHDR)); // 增加内存块;
56+
}
57+
58+
m_bStop = false;
59+
waveInStart(hWaveIn); //开始录音;
60+
61+
return 0;
62+
}
63+
64+
int CWAVEncoder::Stop()
65+
{
66+
// 此处不能释放, 去线程结束时释放;
67+
m_bStop = true;
68+
69+
return 0;
70+
}
71+
72+
DWORD CALLBACK CWAVEncoder::WaveInProc(HWAVEIN hwi, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
73+
{
74+
CWAVEncoder* pThis = reinterpret_cast<CWAVEncoder*>(dwInstance);
75+
assert(pThis);
76+
77+
if (uMsg == WIM_DATA)
78+
{
79+
WAVEHDR* p = (WAVEHDR*)dwParam1; // dwParam1指向WAVEHDR的地址;
80+
printf("getdate id: %d size:%d timestemp:%d\n", p->dwUser, p->dwBytesRecorded, clock());
81+
int iIndex = p->dwUser;
82+
if (pThis->m_bStop) //0表示停止了
83+
{
84+
waveInUnprepareHeader(pThis->hWaveIn, p, sizeof(WAVEHDR)); // 释放;
85+
return 0;
86+
}
87+
else
88+
{
89+
if (pThis->m_pCallBack)
90+
{
91+
pThis->m_pCallBack(pThis->chBuff[iIndex], p->dwBytesRecorded);
92+
}
93+
waveInUnprepareHeader(pThis->hWaveIn, p, sizeof(WAVEHDR)); // 释放;
94+
}
95+
p->lpData = pThis->chBuff[iIndex];
96+
p->dwBufferLength = AUDIO_BUFF_MAXSIZE;
97+
p->dwBytesRecorded = 0;
98+
p->dwUser = iIndex;
99+
p->dwFlags = 0;
100+
waveInPrepareHeader(pThis->hWaveIn, p, sizeof(WAVEHDR)); // 准备内存块录音;
101+
waveInAddBuffer(pThis->hWaveIn, p, sizeof(WAVEHDR)); // 增加内存块;
102+
}
103+
if (uMsg == WIM_OPEN)
104+
{
105+
printf("open\n");
106+
}
107+
if (uMsg == WIM_CLOSE)
108+
{
109+
printf("close\n");
110+
}
111+
return 0;
112+
}
113+
114+
int CWAVEncoder::Clear()
115+
{
116+
printf("Start Stop\n");
117+
waveInStop(hWaveIn);
118+
printf("Start Reset\n");
119+
waveInReset(hWaveIn);
120+
printf("Start Close\n");
121+
waveInClose(hWaveIn);
122+
123+
return 1;
124+
}

WAV_Codec/WAVEncoder.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#pragma once
2+
#include <windows.h>
3+
#include <stdio.h>
4+
#include "AudioInfo.h"
5+
6+
// 获取AudioBuff的回调函数 原始PCM数据;
7+
typedef int(*OnGetAudioBuff)(const char* pBuff, const int& iBuffSize);
8+
9+
class CWAVEncoder
10+
{
11+
public:
12+
CWAVEncoder();
13+
~CWAVEncoder();
14+
15+
void SetAudioBack(OnGetAudioBuff pCallBack);
16+
void SetAudioInfo(const AudioInfo& info);
17+
18+
int Start();
19+
int Stop();
20+
int Clear();
21+
22+
// 回调函数,当缓冲区录满就会调用该函数;
23+
static DWORD CALLBACK WaveInProc(HWAVEIN hwi, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2);
24+
25+
private:
26+
bool m_bStop;
27+
AudioInfo m_audioInfo;
28+
29+
HWAVEIN hWaveIn; // 输入设备;
30+
WAVEFORMATEX waveform; // 采集音频的格式,结构体;
31+
WAVEHDR wHdr[AUDIO_BUFF_MAXCOUNT]; // 采集音频时包含数据缓存的结构体;
32+
char chBuff[AUDIO_BUFF_MAXCOUNT][AUDIO_BUFF_MAXSIZE];
33+
OnGetAudioBuff m_pCallBack;
34+
};

WAV_Codec/WAV_Codec.sln

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio 2013
4+
VisualStudioVersion = 12.0.21005.1
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WAV_Codec", "WAV_Codec.vcxproj", "{015D9418-85CA-4049-8BD0-2FE794F991BB}"
7+
EndProject
8+
Global
9+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
10+
Debug|Win32 = Debug|Win32
11+
Release|Win32 = Release|Win32
12+
EndGlobalSection
13+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
14+
{015D9418-85CA-4049-8BD0-2FE794F991BB}.Debug|Win32.ActiveCfg = Debug|Win32
15+
{015D9418-85CA-4049-8BD0-2FE794F991BB}.Debug|Win32.Build.0 = Debug|Win32
16+
{015D9418-85CA-4049-8BD0-2FE794F991BB}.Release|Win32.ActiveCfg = Release|Win32
17+
{015D9418-85CA-4049-8BD0-2FE794F991BB}.Release|Win32.Build.0 = Release|Win32
18+
EndGlobalSection
19+
GlobalSection(SolutionProperties) = preSolution
20+
HideSolutionNode = FALSE
21+
EndGlobalSection
22+
EndGlobal

0 commit comments

Comments
 (0)