自己封装的PCM写成WAV文件 欢迎指点

#pragma once

typedef struct
{
	unsigned short int channels;
	unsigned long samplespersec;
	unsigned short int nBitsPerSamples; 
}WAVPARAMETER;

//wav头的结构如下所示:  
typedef struct
{
	char fccID[4];
	unsigned long dwSize;
	char fccType[4];
}HEADER;

typedef struct
{
	char fmt[4];						//'fmt'
	unsigned   long       dwSize;				//0x10;   sizeof(PCMWAVEFORMAT)

	unsigned   short     wFormatTag;			//音频数据编码方式 1PCM 1(WAVE_FORMAT_PCM);  格式类别,1表示为PCM形式的声音数据

	unsigned   short     wChannels;				//通道数
	unsigned   long       dwSamplesPerSec;		//采样率 每秒样本数
	unsigned   long       dwAvgBytesPerSec;		//音频数据传送速率,单位是字节,值为采样率x每次采样大小. 每秒数据量
	//每秒数据量 value = channels*nBitsPerSecond*nBitsPerSamples>>3;
	unsigned   short     wBlockAlign;			//数据块调整数 value = channels*nBitsPerSamples>>3;
	unsigned   short     uiBitsPerSample;		//每样本数据位数 每个声道的精度.如:16bit 在这里就是16.多声道,则每个声道的精度大小都是一样的.
}FMT;

typedef struct
{
	char data[4];
	unsigned long dwSize;
}DATA;


class CWavFile
{
public:
	CWavFile(void);
	~CWavFile(void);
public:
	void SetOutputFile(const char *);
	void SetInputFile(const char *);
	void WriteData(unsigned char *,int);
	void SetParameter(unsigned short int,unsigned long,unsigned short int);
	void StartRecordWav();
	void FinishedRecordWav();
private:
	void WriteHeader();
	void InitData();

private:
	int m_data_length;
	WAVPARAMETER m_wav_parameter;
	FILE *m_pFile;
	const char *m_pOutPutFile;
	const char *m_pInputFile;
private:
	HEADER m_header;
	FMT m_fmt;
	DATA m_data;

};

#include "StdAfx.h"
#include "WavFile.h"

CWavFile::CWavFile(void)
{
	memcpy(m_header.fccID,"RIFF",4);
	memcpy(m_header.fccType,"WAVE",4);
	memcpy(m_fmt.fmt,"fmt ",4);
	memcpy(m_data.data,"data",4);
	InitData();
}

CWavFile::~CWavFile(void)
{
}

void CWavFile::SetOutputFile(const char *ofile)
{
	m_pOutPutFile = ofile;
}

void CWavFile::SetInputFile(const char *ifile)
{
	m_pInputFile = ifile;
}

void CWavFile::SetParameter(unsigned short int channels,unsigned long samplespersec,unsigned short int nBitsPerSamples)
{
	m_wav_parameter.channels = channels;
	m_wav_parameter.samplespersec = samplespersec;
	m_wav_parameter.nBitsPerSamples = nBitsPerSamples;
}

void CWavFile::StartRecordWav()
{
	m_pFile = fopen(m_pOutPutFile,"wb");
	if(NULL == m_pFile)return;
	WriteHeader();
}

void CWavFile::WriteData(unsigned char * data,int len)
{
	fwrite(data,sizeof(unsigned char),len,m_pFile);
	m_data_length += sizeof(unsigned char)*len;
	m_data.dwSize += sizeof(unsigned char)*len;
}

void CWavFile::WriteHeader()
{
	//跳过HEADER
	fseek(m_pFile,sizeof(HEADER),SEEK_CUR);
	//写入FMT
	m_fmt.wChannels = m_wav_parameter.channels;
	m_fmt.wFormatTag = 1;
	m_fmt.dwSize = 0x10;
	m_fmt.dwSamplesPerSec = m_wav_parameter.samplespersec / m_fmt.wChannels;
	m_fmt.uiBitsPerSample = m_wav_parameter.nBitsPerSamples;
	m_fmt.wBlockAlign = m_fmt.wChannels * m_fmt.uiBitsPerSample >> 3;
	m_fmt.dwAvgBytesPerSec = m_fmt.dwSamplesPerSec * m_fmt.wBlockAlign;
	fwrite(&m_fmt,sizeof(FMT),1,m_pFile);
	//跳过DATA
	fseek(m_pFile,sizeof(DATA),SEEK_CUR);
}

void CWavFile::FinishedRecordWav()
{
	rewind(m_pFile);
	m_header.dwSize = 44 + m_data.dwSize;
	fwrite(&m_header,1,sizeof(HEADER),m_pFile);
	fseek(m_pFile,sizeof(FMT),SEEK_CUR);
	fwrite(&m_data,1,sizeof(DATA),m_pFile);
	fclose(m_pFile);
	InitData();
}

void CWavFile::InitData()
{
	m_fmt.dwSize = 0;
	m_data_length = 0;
	m_data.dwSize = 0;
	m_header.dwSize = 0;

	m_pInputFile = NULL;
	m_pOutPutFile = NULL;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值