📄 wavefile.cpp
字号:
// WaveFile.cpp: implementation of the CWaveFile class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "WaveFile.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CWaveFile::CWaveFile()
{
m_pWaveFormat = NULL;
m_iDataSize = 0;
}
CWaveFile::~CWaveFile()
{
}
//iMode could be: MMIO_READ, MMIO_WRITE, MMIO_CREATE
BOOL CWaveFile::Open(CString strFileName, int iMode)
{
char szFileName[256];
lstrcpy(szFileName, strFileName);
m_iMode = iMode;
if (m_iMode == MMIO_READ)
{
if(!(m_hMmio = mmioOpen(szFileName, NULL, m_iMode|MMIO_ALLOCBUF)))
{
OutputDebugString("Failed to open file.");
return FALSE;
}
if (!ReadChunk()) return FALSE;
}
else if (m_iMode == MMIO_WRITE || m_iMode == (MMIO_WRITE|MMIO_CREATE))
{
if(!(m_hMmio = mmioOpen(szFileName, NULL, m_iMode|MMIO_ALLOCBUF)))
{
OutputDebugString("Failed to open file.");
return FALSE;
}
}
else
{
OutputDebugString("Invalid mode\n");
return FALSE;
}
return TRUE;
}
void CWaveFile::Close()
{
if (m_iMode == MMIO_WRITE || m_iMode == (MMIO_WRITE|MMIO_CREATE))
{
m_mmckinfoSubchunk.dwFlags = MMIO_DIRTY;
if (mmioAscend(m_hMmio, &m_mmckinfoSubchunk, 0) != 0)
{
OutputDebugString("Ascend out of 'data' chunk failed!\n");
goto Error;
}
m_mmckinfoParent.dwFlags = MMIO_DIRTY;
if (mmioAscend(m_hMmio, &m_mmckinfoParent, 0) != 0)
{
OutputDebugString("Ascend out of 'RIFF' chunk failed!\n");
goto Error;
}
}
Error:
if (mmioClose(m_hMmio, 0) != 0)
OutputDebugString(" Wave file close error!");
if (m_pWaveFormat != NULL)
{
free(m_pWaveFormat);
m_pWaveFormat = NULL;
}
}
int CWaveFile::Read(unsigned char * pData, int iLength)
{
return mmioRead(m_hMmio, (HPSTR) pData, iLength);
}
BOOL CWaveFile::Write(unsigned char * pData, int iLength)
{
if (mmioWrite(m_hMmio, (HPSTR) pData, iLength) != iLength)
{
OutputDebugString("Write Error!\n");
goto Error;
}
return TRUE;
Error:
Close();
return FALSE;
}
BOOL CWaveFile::SetFormat(int iType)
{
int iFormatSize = sizeof(WAVEFORMATEX);
char *cbExtra;
m_pWaveFormat = (WAVEFORMATEX *)malloc(256);
memset(m_pWaveFormat, 0, 256);
cbExtra = (char *)(m_pWaveFormat) + sizeof(WAVEFORMATEX);
m_pWaveFormat->nChannels = 1;
m_pWaveFormat->nSamplesPerSec = 8000;
switch (iType)
{
case WAVE_FILE_PCM:
m_pWaveFormat->wFormatTag = WAVE_FORMAT_PCM;
m_pWaveFormat->nAvgBytesPerSec = 16000;
m_pWaveFormat->nBlockAlign = 2;
m_pWaveFormat->wBitsPerSample = 16;
m_pWaveFormat->cbSize = 0;
case WAVE_FILE_ALAW:
m_pWaveFormat->wFormatTag = WAVE_FORMAT_ALAW;
m_pWaveFormat->nAvgBytesPerSec = 8000;
m_pWaveFormat->nBlockAlign = 1;
m_pWaveFormat->wBitsPerSample = 8;
m_pWaveFormat->cbSize = 0;
break;
case WAVE_FILE_MULAW:
m_pWaveFormat->wFormatTag = WAVE_FORMAT_MULAW;
m_pWaveFormat->nAvgBytesPerSec = 8000;
m_pWaveFormat->nBlockAlign = 1;
m_pWaveFormat->wBitsPerSample = 8;
m_pWaveFormat->cbSize = 0;
break;
case WAVE_FILE_ADPCM:
m_pWaveFormat->wFormatTag = WAVE_FORMAT_ADPCM;
m_pWaveFormat->nAvgBytesPerSec = 4096;
m_pWaveFormat->nBlockAlign = 256;
m_pWaveFormat->wBitsPerSample = 4;
m_pWaveFormat->cbSize = 32;
cbExtra[0] = -12; cbExtra[1] = 1; cbExtra[2] = 7;
cbExtra[5] = 1; cbExtra[9] = 2; cbExtra[11] = -1;
cbExtra[16] = -64; cbExtra[18] = 64; cbExtra[20] = -16;
cbExtra[24] = -52; cbExtra[25] = 1; cbExtra[26] = 48;
cbExtra[27] = -1; cbExtra[28] = -120; cbExtra[29] = 1;
cbExtra[30] = 24; cbExtra[31] = -1;
break;
case WAVE_FILE_GSM610:
m_pWaveFormat->wFormatTag = WAVE_FORMAT_GSM610;
m_pWaveFormat->nAvgBytesPerSec = 1625;
m_pWaveFormat->nBlockAlign = 65;
m_pWaveFormat->wBitsPerSample = 0;
m_pWaveFormat->cbSize = 2;
cbExtra[0] = 64;
cbExtra[1] = 1;
break;
case WAVE_FILE_G729:
m_pWaveFormat->wFormatTag = WAVE_FORMAT_GFDVR;
m_pWaveFormat->nAvgBytesPerSec = 1100;
m_pWaveFormat->nBlockAlign = 11;
m_pWaveFormat->wBitsPerSample = 0;
m_pWaveFormat->cbSize = 0;
break;
case WAVE_FILE_G723_1:
m_pWaveFormat->wFormatTag = 66;
m_pWaveFormat->nChannels = 1;
m_pWaveFormat->nSamplesPerSec = 8000;
m_pWaveFormat->nAvgBytesPerSec = 800;
m_pWaveFormat->nBlockAlign = 24;
m_pWaveFormat->wBitsPerSample = 0;
m_pWaveFormat->cbSize = 10;
cbExtra[0] = 2; cbExtra[1] = 0; cbExtra[2] = (char)0xce;
cbExtra[3] = (char)0x9a; cbExtra[4] = (char)0x32; cbExtra[5] = (char)0xf7;
cbExtra[6] = (char)0xa2; cbExtra[7] = (char)0xae; cbExtra[8] = (char)0xde;
cbExtra[9] = (char)0xac;
break;
default:
OutputDebugString("format not supported!\n");
break;
}
iFormatSize += m_pWaveFormat->cbSize;
if (!WriteChunk(iFormatSize)) return FALSE;
else return TRUE;
}
BOOL CWaveFile::SetFormat(WAVEFORMATEX * pFormat, int iFormatSize)
{
m_pWaveFormat = (WAVEFORMATEX *)malloc(iFormatSize);
memcpy(m_pWaveFormat, pFormat, iFormatSize);
if (!WriteChunk(iFormatSize)) return FALSE;
else return TRUE;
}
BOOL CWaveFile::ReadChunk()
{
// Locate a "RIFF" chunk with a "WAVE" form type to make
// sure the file is a waveform-audio file.
m_mmckinfoParent.fccType = mmioFOURCC('W', 'A', 'V', 'E');
if (mmioDescend(m_hMmio, (LPMMCKINFO) &m_mmckinfoParent, NULL, MMIO_FINDRIFF))
{
OutputDebugString("This is not a waveform-audio file.");
goto Error;
}
// Find the "FMT" chunk (form type "FMT"); it must be
// a subchunk of the "RIFF" chunk.
m_mmckinfoSubchunk.ckid = mmioFOURCC('f', 'm', 't', ' ');
if (mmioDescend(m_hMmio, &m_mmckinfoSubchunk, &m_mmckinfoParent, MMIO_FINDCHUNK))
{
OutputDebugString("Waveform-audio file has no FMT chunk.\n");
goto Error;
}
// Get the size of the "FMT" chunk. Allocate
// and lock memory for it.
m_dwFormatSize = m_mmckinfoSubchunk.cksize;
m_pWaveFormat = (WAVEFORMATEX *)malloc(m_dwFormatSize);
// Read the "FMT" chunk.
if (mmioRead(m_hMmio, (HPSTR) m_pWaveFormat, m_dwFormatSize) != (int)m_dwFormatSize)
{
OutputDebugString("Failed to read format chunk.");
goto Error;
}
// Ascend out of the "FMT" subchunk.
mmioAscend(m_hMmio, &m_mmckinfoSubchunk, 0);
// Find the data subchunk. The current file position should be at
// the beginning of the data chunk; however, you should not make
// this assumption. Use mmioDescend to locate the data chunk.
m_mmckinfoSubchunk.ckid = mmioFOURCC('d', 'a', 't', 'a');
if (mmioDescend(m_hMmio, &m_mmckinfoSubchunk, &m_mmckinfoParent, MMIO_FINDCHUNK))
{
OutputDebugString("Waveform-audio file has no data chunk.");
goto Error;
}
// Get the size of the data subchunk.
m_iDataSize = m_mmckinfoSubchunk.cksize;
if (m_iDataSize == 0L)
{
OutputDebugString("The data chunk contains no data.");
goto Error;
}
return TRUE;
Error:
Close();
return FALSE;
}
BOOL CWaveFile::WriteChunk(int iFormatSize)
{
m_mmckinfoParent.fccType = mmioFOURCC('W', 'A', 'V', 'E');
m_mmckinfoParent.cksize = 0;
if (mmioCreateChunk(m_hMmio, &m_mmckinfoParent, MMIO_CREATERIFF))
{
OutputDebugString("Create RIFF chunk failed!\n");
goto Error;
}
m_mmckinfoSubchunk.ckid = mmioFOURCC('f', 'm', 't', ' ');
m_mmckinfoSubchunk.cksize = iFormatSize; // we know the size of this ck.
if (mmioCreateChunk(m_hMmio, &m_mmckinfoSubchunk, 0))
{
OutputDebugString("Create 'fmt' chunk failed!\n");
goto Error;
}
if (mmioWrite(m_hMmio, (HPSTR) m_pWaveFormat, iFormatSize) != iFormatSize)
{
OutputDebugString("Write Format data failed!\n");
goto Error;
}
// ascend out of the 'fmt' chunk, back into 'RIFF' chunk
if (mmioAscend(m_hMmio, &m_mmckinfoSubchunk, 0) != 0)
{
OutputDebugString("Ascend out of 'fmt' chunk failed!\n");
goto Error;
}
// create the 'data' chunk that holds the waveform samples
m_mmckinfoSubchunk.ckid = mmioFOURCC('d', 'a', 't', 'a');
m_mmckinfoSubchunk.cksize = 0;
if (mmioCreateChunk(m_hMmio, &m_mmckinfoSubchunk, 0) != 0)
{
OutputDebugString("Create 'data' chunk failed!\n");
goto Error;
}
return TRUE;
Error:
Close();
return FALSE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -