wave 文件

本文介绍了一个用于文件操作的C++类`File`,包括文件读写、定位等功能,并在此基础上实现了`CWaveFile`类,用于创建和写入波形(.wav)文件。`CWaveFile`类支持设置波形格式并写入文件头及数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 
#pragma once

class File
{
public:
	File(void);
public:
	~File(void);

	BOOL Open(LPCTSTR lpFileName,DWORD dwDesiredAccess = FILE_WRITE_DATA|FILE_READ_DATA/*参考CreateFile*/);
	DWORD Seek(LONG lDistanceToMove,DWORD dwMoveMethod=FILE_BEGIN/*参考SetFilePointer*/);
	DWORD SeekToBegin( );
	DWORD SeekToEnd( );
	DWORD GetLength( ) const;
	DWORD Read( LPVOID lpBuffer,DWORD nNumberOfBytesToRead);
	DWORD Write(LPVOID lpBuffer,DWORD nNumberOfBytesToWrite);


protected:
	HANDLE m_hFile; 
};

#include "StdAfx.h"
#include 
#include "File.h"
extern DWORD g_dwLastError;
File::File(void)
{
	m_hFile=INVALID_HANDLE_VALUE;
}

File::~File(void)
{
	if (m_hFile!=INVALID_HANDLE_VALUE)
	{
		CloseHandle(m_hFile);
	}
}
BOOL File::Open(LPCTSTR lpFileName,DWORD dwDesiredAccess)
{
	m_hFile = CreateFile(lpFileName,dwDesiredAccess,FILE_SHARE_READ,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
	return m_hFile!=INVALID_HANDLE_VALUE ? TRUE:FALSE;
}

DWORD File::Seek(LONG lDistanceToMove,DWORD dwMoveMethod/*参考SetFilePointer*/)
{
	assert(m_hFile!=INVALID_HANDLE_VALUE);
	return SetFilePointer(m_hFile,lDistanceToMove,NULL,dwMoveMethod);
}

DWORD File::SeekToBegin( )
{
	assert(m_hFile!=INVALID_HANDLE_VALUE);
	return SetFilePointer(m_hFile,0,NULL,FILE_BEGIN);
}
DWORD File::SeekToEnd( )
{
	assert(m_hFile!=INVALID_HANDLE_VALUE);
	return SetFilePointer(m_hFile,0,NULL,FILE_END);
}

DWORD File::GetLength( ) const
{
	assert(m_hFile!=INVALID_HANDLE_VALUE);
	return GetFileSize(m_hFile,NULL);
}

DWORD File::Read( LPVOID lpBuffer,DWORD nNumberOfBytesToRead)
{
	assert(m_hFile!=INVALID_HANDLE_VALUE);
	DWORD dwNumberOfBytesRead; 
	ReadFile(m_hFile,lpBuffer,nNumberOfBytesToRead,&dwNumberOfBytesRead,NULL);
	return dwNumberOfBytesRead;
}

DWORD File::Write(LPVOID lpBuffer,DWORD nNumberOfBytesToWrite)
{
	assert(m_hFile!=INVALID_HANDLE_VALUE);
	DWORD dwNumberOfBytesWrite; 
	WriteFile(m_hFile,lpBuffer,nNumberOfBytesToWrite,&dwNumberOfBytesWrite,NULL);
	return dwNumberOfBytesWrite;
}



#pragma once
#include "file.h"
class CWaveFile :
	public File
{
public:
	CWaveFile(void);
public:
	~CWaveFile(void);
public:
	void  SetWaveFormat(WAVEFORMATEX *pwfx);
	DWORD WriteWavFileHeader();
	DWORD WriteWavData(LPBYTE pData,DWORD nSize);
private:
	DWORD m_dwTotalBytes;
	WAVEFORMATEX m_wfx;
};


#include "StdAfx.h"
#include "CWaveFile.h"
#include 
static const DWORD WAVE_FILE_HEAD_SIZE = sizeof(RIFFLIST) + sizeof(RIFFCHUNK) + sizeof(WAVEFORMATEX) + sizeof(RIFFCHUNK);
CWaveFile::CWaveFile(void)
{
	m_dwTotalBytes = 0;
	ZeroMemory(&m_wfx,sizeof(WAVEFORMATEX));
	m_wfx.wFormatTag = WAVE_FORMAT_PCM;
	m_wfx.nChannels = 2;
	m_wfx.wBitsPerSample = 16;
	m_wfx.nSamplesPerSec = 44100;
	m_wfx.nBlockAlign = m_wfx.nChannels * m_wfx.wBitsPerSample / 8;
	m_wfx.nAvgBytesPerSec = m_wfx.nSamplesPerSec * m_wfx.nBlockAlign;
	m_wfx.cbSize = 0;
}

CWaveFile::~CWaveFile(void)
{
}
void  CWaveFile::SetWaveFormat(WAVEFORMATEX *pwfx)
{
	CopyMemory(&m_wfx,pwfx,sizeof(WAVEFORMATEX));
}
DWORD CWaveFile::WriteWavFileHeader()
{

	BYTE Buffer[WAVE_FILE_HEAD_SIZE];
	RIFFLIST  *pRiffWave = (RIFFLIST *)Buffer;
	RIFFCHUNK *pRiffFmt  = (RIFFCHUNK *)(pRiffWave + 1);
	RIFFCHUNK *pRiffData = (RIFFCHUNK *)(((BYTE *)(pRiffFmt + 1)) + sizeof(WAVEFORMATEX));


	pRiffData->fcc = FCC('data');
	pRiffData->cb = m_dwTotalBytes;

	pRiffFmt->fcc = FCC('fmt ');
	pRiffFmt->cb = sizeof(WAVEFORMATEX);

	CopyMemory(pRiffFmt + 1, &m_wfx, sizeof(WAVEFORMATEX));

	pRiffWave->fcc = FCC('RIFF');
	pRiffWave->cb = m_dwTotalBytes + WAVE_FILE_HEAD_SIZE - sizeof(RIFFCHUNK);
	pRiffWave->fccListType = FCC('WAVE');

	SetFilePointer(m_hFile, 0, NULL, FILE_BEGIN);

	DWORD dwWriten = 0;
	BOOL bRet = WriteFile(m_hFile, Buffer, WAVE_FILE_HEAD_SIZE, &dwWriten, NULL);
	if ((bRet == FALSE) || (dwWriten != WAVE_FILE_HEAD_SIZE))
	{
		return -1;
	}
	return 0;
}

DWORD CWaveFile::WriteWavData(LPBYTE pData,DWORD nSize)
{
	DWORD nByteWrite =  Write(pData,nSize);
	m_dwTotalBytes+=nByteWrite;
	return nByteWrite;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值