下面是我写的一个wav文件生成类,wav文件的格式参照此链接:
https://ccrma.stanford.edu/courses/422/projects/WaveFormat/
//WAVWriter.h
#pragma once
struct WAVRIFFChunk
{
char id[4]; //"RIFF"
UINT32 size; //filelen - 8
char format[4]; //"WAVE"
WAVRIFFChunk():size(0)
{
memcpy(id, "RIFF", 4);
memcpy(format, "WAVE", 4);
}
};
struct WAVFormatChunk
{
char id[4]; //"fmt "
UINT32 size; //16 for pcm, sizeof this struct
UINT16 AudioFormat; //PCM = 1
UINT16 NumChannels; //Mono = 1, Stereo = 2, etc.
UINT32 SampleRate; //8000, 44100, etc.
UINT32 ByteRate; //== SampleRate * NumChannels * BitsPerSample/8
UINT16 BlockAlign; //== NumChannels * BitsPerSample/8
UINT16 BitsPerSample; //8 bits = 8, 16 bits = 16, etc.
WAVFormatChunk():size(16),AudioFormat(1),//fixed
NumChannels(0),SampleRate(0),ByteRate(0),BlockAlign(0),BitsPerSample(0)
{
memcpy(id, "fmt ", 4);
}
};
struct WAVDataChunk
{
char id[4]; //"data"
UINT32 size; //== NumSamples * NumChannels * BitsPerSample/8
WAVDataChunk():size(0)
{
memcpy(id, "data", 4);
}
};
class CWAVWriter
{
HANDLE m_hFile;
//information
WAVRIFFChunk m_Riff;
WAVFormatChunk m_Format;
WAVDataChunk m_Data;
public:
CWAVWriter(void);
~CWAVWriter(void);
bool Open(const char* lpFile, UINT16 NumChannels, UINT32 SampleRate, UINT16 BitsPerSample);
bool WriteASample(UINT8* buf, UINT32 len);
void Close();
};
//WAVWriter.cpp
#include "StdAfx.h"
#include "WAVWriter.h"
CWAVWriter::CWAVWriter(void):m_hFile(NULL)
{
}
CWAVWriter::~CWAVWriter(void)
{
Close();
}
bool CWAVWriter::Open(const char* lpFile, UINT16 NumChannels, UINT32 SampleRate, UINT16 BitsPerSample)
{
m_Format.NumChannels = NumChannels;
m_Format.SampleRate = SampleRate;
m_Format.BitsPerSample = BitsPerSample;
m_Format.ByteRate = SampleRate * NumChannels * BitsPerSample/8;
m_Format.BlockAlign = NumChannels*BitsPerSample/8;
if (!lpFile)
return false;
m_hFile = ::CreateFile(lpFile, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (!m_hFile)
return false;
::SetFilePointer(m_hFile, sizeof(m_Riff)+sizeof(m_Format)+sizeof(m_Data), NULL, FILE_BEGIN);
return true;
}
bool CWAVWriter::WriteASample(UINT8* buf, UINT32 len)
{
if (!buf || !len)
return false;
DWORD dwWritten;
if (!WriteFile(m_hFile, buf, len, &dwWritten, NULL))
return false;
m_Riff.size += len;
m_Data.size += len;
return true;
}
void CWAVWriter::Close()
{
if (m_hFile)
{
if (INVALID_SET_FILE_POINTER != ::SetFilePointer(m_hFile, 0, NULL, FILE_BEGIN))
{
DWORD dwWritten;
WriteFile(m_hFile, &m_Riff, sizeof(m_Riff), &dwWritten, NULL);
WriteFile(m_hFile, &m_Format, sizeof(m_Format), &dwWritten, NULL);
WriteFile(m_hFile, &m_Data, sizeof(m_Data), &dwWritten, NULL);
}
::CloseHandle(m_hFile);
m_hFile = NULL;
}
}