ttxiaoxitt
ttxiaoxitt
2018-02-02 09:59

关于WindowsC++的录音保存为wav格式的音频文件的问题?

5
  • c++
  • 音频编码
  • 软件工程

我的这个程序是:启动程序进行录音,录音结束,将录音保存为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));

}

}

  • 点赞
  • 回答
  • 收藏
  • 复制链接分享

4条回答

为你推荐