一个wav文件生成类

来源:互联网 发布:风乎舞雩得乎 编辑:程序博客网 时间:2024/05/22 06:49

 下面是我写的一个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;
    }
}
原创粉丝点击