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

📄 wave.cpp

📁 信道仿真源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	}
	else
	{
		for( i=0; i < (Length*m_InFormat.nChannels); i++ )
		{
			m_usTemp.bytes.lsb = *(m_pInBuffer + (m_InBufPosition++) );
			m_usTemp.bytes.msb = *(m_pInBuffer + (m_InBufPosition++) );
			*( pData + i) = (double)m_usTemp.both;
		}
	}
	if( m_InBufPosition >= m_InBufferSize )
		m_InBufPosition = 0;	// need to read another buffer's worth
	return(Length);
}


//////////////////////////////////////////////////////////////////////
//  Closes the Input wave file if open.
//
//////////////////////////////////////////////////////////////////////
void CWave::InClose()
{
	if( m_INhmmio )
	{
		mmioClose( m_INhmmio, 0 );
		m_INhmmio = NULL;
	}
	if( m_pInBuffer )
	{
		delete m_pInBuffer;
		m_pInBuffer = NULL;
	}
	m_InputOpen = FALSE;
}

//////////////////////////////////////////////////////////////////////
//  This function opens a wave file for writing.
//		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
//		pWFX		= WAVEFORMATEX structure with desired wavefile settings
//		BufSize		= DWORD specifies the wave file buffer size in
//							number of samples.  
//		SampleLimit = limit on number of samples to be written.
//    returns:
//        0			if opened OK
//    ErrorCode		if not
//////////////////////////////////////////////////////////////////////
UINT CWave::OutOpen( CString* pPathName, WAVEFORMATEX* pWFX, 
										DWORD BufSize, DWORD SampleLimit)
{
	GetFreeSpace(pPathName);
	m_OutputOpen = FALSE;
	m_ErrorCode = NO_ERRORS;
	m_pOutBuffer = NULL;
	m_OutBufPosition = 0;
	m_OutSamplesWritten = 0;
	m_OutSampleLimit = SampleLimit;
	memset( &m_mmcktRIFF,0,sizeof(MMCKINFO));
	memset( &m_mmcktSubchunk,0,sizeof(MMCKINFO));
	m_OutFormat = *pWFX;
	m_OutBytesPerSample = (m_OutFormat.wBitsPerSample/8)*m_OutFormat.nChannels;
	m_OutBufferSize = BufSize * m_OutBytesPerSample;
	if( !(m_OUThmmio = mmioOpen( (LPSTR)(LPCTSTR(*pPathName)), NULL,
									MMIO_WRITE|MMIO_ALLOCBUF|MMIO_CREATE )))
	{
		m_ErrorCode = WAVOUT_ERR_OPEN;
	}
	else
	{   // Create the output file RIFF chunk of form type 'WAVE'.
		m_mmcktRIFF.fccType = mmioFOURCC('W', 'A', 'V', 'E');
		if( mmioCreateChunk(m_OUThmmio, &m_mmcktRIFF, MMIO_CREATERIFF) != 0)
		{
			mmioClose(m_OUThmmio,0);
			m_ErrorCode = WAVOUT_ERR_WRITING;
		}
		else
		{	// Are now descended into the 'RIFF' chunk just created.
			// Now create the 'fmt ' chunk. Since the size of this chunk is known,
			// specify it in the MMCKINFO structure so MMIO doesn't have to seek
			// back and set the chunk size after ascending from the chunk.
			m_mmcktSubchunk.ckid = mmioFOURCC('f', 'm', 't', ' ');
			m_mmcktSubchunk.cksize = sizeof(WAVEFORMATEX);  // we know the size of this ck.
			if( mmioCreateChunk(m_OUThmmio, &m_mmcktSubchunk, 0) != 0)
			{
				mmioClose(m_OUThmmio,0);
				m_ErrorCode = WAVOUT_ERR_WRITING;
			}
			else
			{	// Write the WAVEFORMATEX structure to the 'fmt ' chunk.
				if( mmioWrite(m_OUThmmio, (HPSTR)pWFX, sizeof(WAVEFORMATEX))
							!= sizeof(WAVEFORMATEX))
				{
					mmioClose(m_OUThmmio,0);
					m_ErrorCode = WAVOUT_ERR_WRITING;
				}
				else
				{	// Ascend out of the 'fmt ' chunk, back into the 'RIFF' chunk.
					if( mmioAscend(m_OUThmmio, &m_mmcktSubchunk, 0) != 0)
					{
						mmioClose(m_OUThmmio,0);
						m_ErrorCode = WAVOUT_ERR_WRITING;
					}
					else
					{	// Create the 'data' chunk that holds the waveform samples.
						m_mmcktSubchunk.ckid = mmioFOURCC('d', 'a', 't', 'a');
						if (mmioCreateChunk(m_OUThmmio, &m_mmcktSubchunk, 0) != 0)
						{
							mmioClose(m_OUThmmio,0);
							m_ErrorCode = WAVOUT_ERR_WRITING;
						}
					}
				}
			}
		}
	}

	if( m_ErrorCode == NO_ERRORS )
	{
		// allocate intermediate byte buffer
		m_pOutBuffer = new char[ m_OutBufferSize ];
		if( m_pOutBuffer == NULL )
		{
			OutClose();
			m_ErrorCode = MEMORY_ERROR;
		}
		else
		{
			m_OutputOpen = TRUE;
		}
	}
	return m_ErrorCode;
}

///////////////////////////////////////////////////////////////////////
// Writes 'Length' doubles to the open wavefile.
//    parameters:
//		pData	= pointer to block of 'Length' SHORT INT's to output.
//		Length	= Number of samples to write from pData. If is zero
//					then the output file is closed.
//
// Returns:
//		'Length' if data was succesfully placed in the output buffers.
//       0 if output has finished( reached the specified sample limit )
//      -1		 if error ( use GetError() to retrieve error )
///////////////////////////////////////////////////////////////////////
LONG CWave::OutWrite( double* pData, INT Length)
{
INT i;
	if( !m_OutputOpen )
	{
		OutClose();
		m_ErrorCode = WAVOUT_ERR_NOTOPEN;
		return -1;
	}
	if( Length == 0 )
	{
		if( mmioWrite( m_OUThmmio, m_pOutBuffer, m_OutBufPosition ) < 0 )
		{
			OutClose();
			m_ErrorCode = WAVOUT_ERR_WRITING;
			return -1;
		}
		OutClose();
		return 0;
	}
	if( Length > 0 )
	{
		if(m_OutFormat.wBitsPerSample == 16)
		{
			for( i=0; i < (Length*m_OutFormat.nChannels); i++ )
			{
				m_usTemp.both = (SHORT)(*( pData + i));
				*(m_pOutBuffer + (m_OutBufPosition++)) = m_usTemp.bytes.lsb;
				*(m_pOutBuffer + (m_OutBufPosition++)) = m_usTemp.bytes.msb;
			}
		}
		else
		{
			for( i=0; i < (Length*m_OutFormat.nChannels); i++ )
			{
				m_usTemp.both = (SHORT)(*(pData + i) + 32768.0);
				*(m_pOutBuffer + (m_OutBufPosition++)) = (char)m_usTemp.bytes.msb;
			}
		}
	}
	if( m_OutBufPosition >= m_OutBufferSize )
	{
		m_OutBufPosition = 0;	// need to write another buffer's worth
		if( mmioWrite( m_OUThmmio, m_pOutBuffer, m_OutBufferSize ) < 0 )
		{
			OutClose();
			m_ErrorCode = WAVOUT_ERR_WRITING;
			return -1;
		}
	}
	m_OutSamplesWritten += Length;
	if( m_OutSamplesWritten >= m_OutSampleLimit )
	{
		OutClose();
		return 0;
	}
	return Length;
}

//////////////////////////////////////////////////////////////////////
//  Closes the Output wave file by first updating the information chunk
//    with the length of data that was written then closing it.
//////////////////////////////////////////////////////////////////////
void CWave::OutClose()
{
   if( m_OUThmmio )
   {
	   if( m_OutputOpen )	// need to update file and data lengths in
	   {					// the wave header if the file was opened
	   		if( mmioWrite( m_OUThmmio, m_pOutBuffer, m_OutBufPosition ) >= 0 )
			{
				// Ascend out of the 'data' chunk, back into the 'RIFF' chunk.
				if( mmioAscend(m_OUThmmio, &m_mmcktSubchunk, 0) == 0)
					// Ascend out of the 'RIFF' chunk, writing the RIFF file length.
					mmioAscend(m_OUThmmio, &m_mmcktRIFF, 0);
			}
	   }
		mmioClose( m_OUThmmio, 0 );
		m_OUThmmio = FALSE;
	}
	if( m_pOutBuffer )
	{
		delete m_pOutBuffer;
		m_pOutBuffer = NULL;
	}
	m_OutputOpen = FALSE;
}

/////////////////////////////////////////////////////////////////
// returns free disk space on drive specified by pPathName.
// The extra logic is for dealing with early Win95 versions that don't
// support the extended disk space function "GetDiskFreeSpaceEx(..)".
/////////////////////////////////////////////////////////////////
LONGLONG CWave::GetDriveFreeSpace(CString* pPathName)
{
typedef BOOL (CALLBACK* LPFNDLLFUNC)(LPCTSTR, PULARGE_INTEGER,
					 PULARGE_INTEGER, PULARGE_INTEGER);

LONGLONG SpaceFree;
	SpaceFree = 0;					// see if it exists
	HMODULE hKernel = GetModuleHandle( _T("kernel32.dll"));
	LPFNDLLFUNC pFunct = (LPFNDLLFUNC)GetProcAddress( hKernel,"GetDiskFreeSpaceExA");
	if(pFunct != NULL)		//if function is in kernel32.dll
	{
		ULARGE_INTEGER TotalSpace;
		ULARGE_INTEGER FreeSpace;
		pFunct( pPathName->Left(3), &FreeSpace, &TotalSpace, NULL);
		SpaceFree = FreeSpace.QuadPart;
	}
	else					//else is WIn95 pre OSR2 so use old function
	{
		DWORD SectorsPerCluster, BytesPerSector;
		DWORD NumberOfFreeClusters, TotalNumberOfClusters;
		if( GetDiskFreeSpace( pPathName->Left(3),
					&SectorsPerCluster, &BytesPerSector,
					&NumberOfFreeClusters, &TotalNumberOfClusters ) ) 
		SpaceFree = (LONGLONG)(NumberOfFreeClusters*SectorsPerCluster*BytesPerSector);
	}
	return SpaceFree;
}

⌨️ 快捷键说明

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