⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wave.cpp

📁 信道仿真源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//////////////////////////////////////////////////////////////////////
// Wave.cpp: implementation of the CWave class.
//
// This class implements an object that reads/writes a wave file.
//
//The following member functions are used to perform all the tasks:
//
//	UINT InOpen( CString* pPathName, WAVEFORMATEX* pWFX,
//									DWORD BufSize, PDWORD FileSize);
//	LONG InRead( PSHORT pData, INT Length );
//	void InClose();
//
//	UINT OutOpen( CString* pPathName, WAVEFORMATEX* pWFX,
//									DWORD BufSize, DWORD SampleLimit);
//	LONG OutWrite( PSHORT pData, INT Length  );
//	void OutClose();
//
//	LONGLONG GetDriveFreeSpace(CString* pPathName);
//
//////////////////////////////////////////////////////////////////////
// Copyright 1999.    Moe Wheatley AE4JY  <ae4jy@mindspring.com>
//
//This program is free software; you can redistribute it and/or
//modify it under the terms of the GNU General Public License
//as published by the Free Software Foundation; either version 2
//of the License, or any later version.
//
//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with this program; if not, write to the Free Software
//Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "Wave.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CWave::CWave()
{
	m_INhmmio = FALSE;
	m_OUThmmio = FALSE;
	m_OutputOpen = FALSE;
	m_pInBuffer = NULL;
	m_pOutBuffer = NULL;
	m_InputOpen = FALSE;
	m_OutputOpen = FALSE;
}

CWave::~CWave()
{

}

//////////////////////////////////////////////////////////////////////
//  This function opens a wave file for reading.  It reads the wave file
//  information and places it in *pWFXSettings.  The file size in
//	number of samples is placed in *pFileSize. Number of samples can be
//  1,2 or 4 bytes long depending on bits per sample and number of channels.
//( ie. a 1000 sample buffer for 16 bit stereo will be a 4000 byte buffer)
//    parameters:
//		pPathName		= CString containing file path name.
//		pWFXSettings	= ptr to WAVEFORMATEX structure to put wavefile settings in.
//		BufSize			= DWORD specifies the wave file buffer size in
//							number of samples.  If the file ends before a 
//							buffer is completed, it is padded with 0's.
//						  If this value is Zero, the WAVEFORMATEX structure is
//							filled in and then the file is closed. This is useful
//							for just getting file info.
//		pFileSize		= pointer where the file length in number of samples is
//							written to.
//    returns:
//        0			if opened OK
//    ErrorCode		if not
//////////////////////////////////////////////////////////////////////
UINT CWave::InOpen( CString* pPathName, WAVEFORMATEX* pWFX, DWORD BufSize, PDWORD pFileSize)
{
LONG dwFmtSize;
MMCKINFO mmckinSubchunk;
MMCKINFO mmckinfoParent;
	m_ErrorCode = NO_ERRORS;
	m_pInBuffer = NULL;
	m_InBufPosition = 0;
	m_InputOpen = FALSE;
	if( !(m_INhmmio = mmioOpen( (LPSTR)(LPCTSTR(*pPathName)), NULL,
									MMIO_READ|MMIO_ALLOCBUF)))
	{
		m_ErrorCode = WAVIN_ERR_OPEN;
	}
	else					//traverse the RIFF header to get info on file
	{
		mmckinfoParent.fccType = mmioFOURCC('W', 'A','V','E');
		if( mmioDescend( m_INhmmio, &mmckinfoParent, NULL,MMIO_FINDRIFF))
		{
			mmioClose(m_INhmmio,0);
			m_ErrorCode = WAVIN_ERR_NOTWAVE;
		}
		else
		{
			mmckinSubchunk.ckid = mmioFOURCC('f', 'm','t',' ');
			if( mmioDescend( m_INhmmio, &mmckinSubchunk,
					&mmckinfoParent,MMIO_FINDCHUNK))
			{
				mmioClose(m_INhmmio,0);
				m_ErrorCode = WAVIN_ERR_INVALID;
			}
			else
			{
				dwFmtSize = mmckinSubchunk.cksize;
				if( mmioRead( m_INhmmio, (HPSTR) &m_InFormat, dwFmtSize)
								!= dwFmtSize)
				{
					mmioClose(m_INhmmio,0);
					m_ErrorCode = WAVIN_ERR_INVALID;
				}
				else
				{
					mmioAscend( m_INhmmio, &mmckinSubchunk, 0);
					mmckinSubchunk.ckid = mmioFOURCC('d', 'a','t','a');
					if( mmioDescend( m_INhmmio, &mmckinSubchunk, 
							     &mmckinfoParent,MMIO_FINDCHUNK))
					{
						mmioClose(m_INhmmio,0);
						m_ErrorCode = WAVIN_ERR_INVALID;
					}
					else
					{
						*pFileSize = mmckinSubchunk.cksize;
						if ( *pFileSize == 0L )
						{
							m_ErrorCode = WAVIN_ERR_NODATA;
							mmioClose(m_INhmmio,0);
						}
						else
						{
							if( ( m_InFormat.wFormatTag != WAVE_FORMAT_PCM )
									|| ( m_InFormat.nChannels != 1 &&
											m_InFormat.nChannels != 2 )
									|| ( m_InFormat.wBitsPerSample != 8 &&
									m_InFormat.wBitsPerSample != 16 ))
							{
								m_ErrorCode = WAVIN_ERR_NOTSUPPORTED;
								mmioClose(m_INhmmio,0);
							}
							else
							{
								if( ( m_InFormat.nSamplesPerSec < 5000 ) ||
									( m_InFormat.nSamplesPerSec > 44100 ) )
								{
									m_ErrorCode = WAVIN_ERR_NOTSUPPORTED;
									mmioClose(m_INhmmio,0);
								}
							}
						}
					}
				}
			}
		}
	}
	if( m_ErrorCode == NO_ERRORS )
	{
		//  write file settings to the "pWFX" structure of the caller.
		pWFX->wFormatTag = m_InFormat.wFormatTag;
		pWFX->nChannels = m_InFormat.nChannels;
		pWFX->nSamplesPerSec = m_InFormat.nSamplesPerSec;
		pWFX->nAvgBytesPerSec = m_InFormat.nAvgBytesPerSec;
		pWFX->nBlockAlign = m_InFormat.nBlockAlign;
		pWFX->wBitsPerSample = m_InFormat.wBitsPerSample;
		m_InBytesPerSample = (m_InFormat.wBitsPerSample/8)*m_InFormat.nChannels;
		*pFileSize = *pFileSize / m_InBytesPerSample;//get # of samples
		// FileSize must be integer number of BufSizes due to padding
		if( BufSize != 0 )  // if not a file check
			*pFileSize += ( BufSize - (*pFileSize%BufSize) );
		// allocate intermediate byte buffer
		m_InBufferSize = BufSize * m_InBytesPerSample;
		m_pInBuffer = new char[ m_InBufferSize ];
		if( m_pInBuffer == NULL )
		{
			InClose();
			m_ErrorCode = MEMORY_ERROR;
		}
		else
		{
			m_InputOpen = TRUE;
		}
	}
	if( BufSize == 0 )  // see if just a file check
		InClose();	// if so close the input file
	return(m_ErrorCode);
}

///////////////////////////////////////////////////////////////////////
// Reads 'Length' samples of double data from the opened wavefile.
//		pData	= Pointer to double data array to be filled.
//		Length	= Number of samples to read into pData.
//
//	returns:
//		Length	if 'Length' samples were succesfully read.
//		0  =	if reaches the end of the file.
//		-1 =	if there is an error ( use GetError() to retrieve error )
///////////////////////////////////////////////////////////////////////
LONG CWave::InRead( double* pData , INT Length )
{
INT i;
LONG numret;
	if( !m_InputOpen )
	{
		InClose();
		m_ErrorCode = WAVIN_ERR_NOTOPEN;
		return -1;
	}
	if( m_InBufPosition == 0 )	//if need to read in new buffer's worth
	{
		numret = mmioRead( m_INhmmio, m_pInBuffer, m_InBufferSize );
		if( numret < 0 )		//read error
		{
			InClose();
			m_ErrorCode = WAVIN_ERR_READING;
			return -1;
		}
		else
		{
			if( numret == 0 )		//end of file
			{
				InClose();
				return 0;
			}
			else
			{
				if( numret < m_InBufferSize )	// got partial buffer so pad it
				{
					if(m_InFormat.wBitsPerSample == 8)
					{
						for( i=numret; i<m_InBufferSize; i++ )
						{
							*(m_pInBuffer+i) = (char)127;
						}
					}
					else
					{
						for( i=numret; i<m_InBufferSize; i++ )
						{
							*(m_pInBuffer+i) = 0;
						}
					}
				}
			}
		}
	}
	if(m_InFormat.wBitsPerSample == 8)
	{
		m_usTemp.bytes.lsb = 0;
		for( i=0; i < (Length*m_InFormat.nChannels); i++ )
		{
			m_usTemp.bytes.msb = *(m_pInBuffer + (m_InBufPosition++) ) - 128;
			*(pData+i) = (double)m_usTemp.both;
		}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -