我的这个程序是:启动程序进行录音,录音结束,将录音保存为wav格式的文件。
问题是:我保存的这个wav音频文件有问题,打开后没有我录的声音。
以下是我的源代码:
#include "stdafx.h"
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#pragma comment(lib, "winmm.lib")
#define BUFFER_SIZE (44100*16*2/8*5) // 录制声音长度 ,5是指5秒
#define FRAGMENT_SIZE 1024 // 缓存区大小
#define FRAGMENT_NUM 4 // 缓存区个数
static unsigned char buffer[BUFFER_SIZE] = {0};
static int buf_count = 0;
// 函数定义
void CALLBACK waveInProc(HWAVEIN hwi,
UINT uMsg,
DWORD_PTR dwInstance,
DWORD_PTR dwParam1,
DWORD_PTR dwParam2 );
/* wav音频头部格式 */
typedef struct _wave_pcm_hdr
{
char riff[4]; // = "RIFF"
intsize_8; // = FileSize - 8
char wave[4]; // = "WAVE"
char fmt[4]; // = "fmt "
intfmt_size;// = 下一个结构体的大小 : 16
short int format_tag; // = PCM : 1
short int channels; // = 通道数 : 1
intsamples_per_sec; // = 采样率 : 8000 | 6000 | 11025 | 16000
intavg_bytes_per_sec; // = 每秒字节数 : samples_per_sec * bits_per_sample / 8
short int block_align; // = 每采样点字节数 : wBitsPerSample / 8
short int bits_per_sample; // = 量化比特数: 8 | 16
char data[4]; // = "data";
intdata_size; // = 纯数据长度 : FileSize - 44
} wave_pcm_hdr;
/* 默认wav音频头部数据 */
wave_pcm_hdr default_wav_hdr =
{
{ 'R', 'I', 'F', 'F' },
0,
{'W', 'A', 'V', 'E'},
{'f', 'm', 't', ' '},
16,
1,
1,
16000,
32000,
2,
16,
{'d', 'a', 't', 'a'},
0
};
// 入口
int main()
{
/* 录音 */
// Device
int nReturn = waveInGetNumDevs();
printf("输入设备数目:%d\n", nReturn);
for (int i=0; i<nReturn; i++)
{
WAVEINCAPS wic;
waveInGetDevCaps(i, &wic, sizeof(WAVEINCAPS));
printf("#%d\t设备名:%s\n", i, wic.szPname);
}
// open
HWAVEIN hWaveIn;
WAVEFORMATEX wavform;
wavform.wFormatTag = WAVE_FORMAT_PCM;
wavform.nChannels = 2;
wavform.nSamplesPerSec = 44100;
wavform.nAvgBytesPerSec = 44100*16*2/8;
wavform.nBlockAlign = 4;
wavform.wBitsPerSample = 16;
wavform.cbSize = 0;
waveInOpen(&hWaveIn, WAVE_MAPPER, &wavform, (DWORD_PTR)waveInProc, 0, CALLBACK_FUNCTION);
WAVEINCAPS wic;
waveInGetDevCaps((UINT_PTR)hWaveIn, &wic, sizeof(WAVEINCAPS));
printf("打开的输入设备:%s\n", wic.szPname);
// prepare buffer
static WAVEHDR wh[FRAGMENT_NUM];
for (int i=0; i<FRAGMENT_NUM; i++)
{
wh[i].lpData = new char[FRAGMENT_SIZE];
wh[i].dwBufferLength = FRAGMENT_SIZE;
wh[i].dwBytesRecorded = 0;
wh[i].dwUser = NULL;
wh[i].dwFlags = 0;
wh[i].dwLoops = 1;
wh[i].lpNext = NULL;
wh[i].reserved = 0;
waveInPrepareHeader(hWaveIn, &wh[i], sizeof(WAVEHDR));//准备波形数据块头用于录音
waveInAddBuffer(hWaveIn, &wh[i], sizeof(WAVEHDR)); //指定波形数据块为录音输入缓存
}
// record
printf("Start to Record...\n");
buf_count = 0;
waveInStart(hWaveIn); //启动输入 的waveInStart功能开始在给定的波形音频输入设备的输入。//开始录音
while (buf_count < BUFFER_SIZE)
{
Sleep(1);
}
printf("Record Over!\n\n");
//将录音保存为wav格式的文件
SYSTEMTIME systemtime;
GetLocalTime(&systemtime);
char filename[256];
sprintf_s(filename, 256, "%d-%d-%d_%d_%d_%d.wav", systemtime.wYear, systemtime.wMonth, systemtime.wDay, systemtime.wHour, systemtime.wMinute, systemtime.wSecond);
//m_pWavFile = wav_write_open(filename, 8000, 16, 1);
FILE * fp = fopen(filename, "wb");
wave_pcm_hdr wav_hdr = default_wav_hdr;
fwrite(&wav_hdr, sizeof(wav_hdr), 1, fp);//头
fwrite(buffer, sizeof(buffer) ,1, fp);//数据
// clean
waveInStop(hWaveIn);
waveInReset(hWaveIn);
for (int i=0; i<FRAGMENT_NUM; i++)
{
waveInUnprepareHeader(hWaveIn, &wh[i], sizeof(WAVEHDR));
delete wh[i].lpData;
}
waveInClose(hWaveIn);
system("pause");
printf("\n");
return 0;
}
// 录音回调函数
void CALLBACK waveInProc(HWAVEIN hwi,
UINT uMsg,
DWORD_PTR dwInstance,
DWORD_PTR dwParam1,
DWORD_PTR dwParam2 )
{
LPWAVEHDR pwh = (LPWAVEHDR)dwParam1;
if ((WIM_DATA==uMsg) && (buf_count
{
int temp = BUFFER_SIZE - buf_count;
temp = (temp>pwh->dwBytesRecorded) ? pwh->dwBytesRecorded : temp;
memcpy(buffer+buf_count, pwh->lpData, temp);
buf_count += temp;
waveInAddBuffer(hwi, pwh, sizeof(WAVEHDR));
}
}