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

📄 twave.cpp

📁 AVAYA IPO 430系列交换机Wavedriver的demo程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// TWave.cpp: CtWave class implementation
//

#include "stdafx.h"
#include <assert.h>
#include "tWave.h"

//****************************************************************************
//  Debug tracing functions.
#define DIM(rg) (sizeof(rg)/sizeof(*rg))
#ifdef _DEBUG

static
void WOTRACE(
    MMRESULT    mr,
    LPCTSTR     pszFunc)
{
    if( mr )
    {
        TCHAR   szErr[128];
        waveOutGetErrorText(mr, szErr, DIM(szErr));
        OutputDebugString(pszFunc);
        OutputDebugString("() -- ");
        OutputDebugString(szErr);
        OutputDebugString("\n");
    }
}

static
void WITRACE(
    MMRESULT    mr,
    LPCTSTR     pszFunc)
{
    if( mr )
    {
        TCHAR   szErr[128];
        waveInGetErrorText(mr, szErr, DIM(szErr));
        OutputDebugString(pszFunc);
        OutputDebugString("() -- ");
        OutputDebugString(szErr);
        OutputDebugString("\n");
    }
}

#else

inline void WOTRACE(MMRESULT, LPCSTR) {}
#define WOTRACE 1 ? 0 : WOTRACE

inline void WITRACE(MMRESULT, LPCSTR) {}
#define WITRACE 1 ? 0 : WITRACE

#endif

//*********************************************************************
// CtWave Constuctor.
//  CTWaveSink is a CWnd and CtWaveSink derived class which acts as
//  a message handler for the Wave Driver communications.
CtWave::CtWave(CtWaveSink* pSink):
    m_pSink(pSink),
    m_pDataIn1(0),
    m_pDataIn2(0),
    m_pDataOut1(0),
    m_hWaveOut(0),
    m_hWaveIn(0),
    m_pWaveInHdr1(0),
    m_pWaveInHdr2(0),
	m_bWaveInHdr1InUse(true),
    m_pWaveOutHdr1(0),
    m_nRecordedSize(0),
    m_pFormat(0),
    m_nFormatSize(0),
    m_bStopping(false),
    m_bOwnData(false)
{
	m_nTotalRecording = 0;
}

//*********************************************************************
CtWave::~CtWave()
{
	// Ensure all activity is aborted.
    Close();
}

//*********************************************************************
// Loads a WAV file by name.
bool CtWave::Load(LPCTSTR pszFileName)
{
    // Make sure we're not open
    Close();

//    assert(!m_pFormat);
//    assert(!m_nFormatSize);
//    assert(!m_pDataOut1); //***
//    assert(!m_nRecordedSize);

    // Open the given file for reading using buffered I/O
    HMMIO   hmmio;
    hmmio = mmioOpen(const_cast<TCHAR*>(pszFileName), 0, MMIO_READ | MMIO_ALLOCBUF);
    if( !hmmio )
    {
        OutputDebugString("mmioOpen() -- Failed to open file: ");
        OutputDebugString(pszFileName);
        OutputDebugString("\n");
        return false;
    }

    bool    bSuccess = Load(hmmio);
    
    // We're done with the file, close it
    mmioClose(hmmio, 0);

    return bSuccess;
}

//*********************************************************************
// Loads WAV data from the application resource by numerical ID
bool CtWave::Load(HMODULE hm, UINT nID)
{
    return Load(hm, MAKEINTRESOURCE(nID));
}

//*********************************************************************
// Loads WAV data from the application resource by name
bool CtWave::Load(HMODULE hm, LPCTSTR pszID)
{
    // Make sure we're not open
    Close();

    assert(!m_pFormat);
    assert(!m_nFormatSize);
    assert(!m_pDataOut1); //***
    assert(!m_nRecordedSize);

    // Load the resource
    HRSRC   hrsrc = FindResource(hm, pszID, __TEXT("wave"));
    if( !hrsrc )
    {
        OutputDebugString("Failed to find 'wave' resource ");
        OutputDebugString(pszID);
        OutputDebugString("\n");
        return false;
    }

    assert(SizeofResource(hm, hrsrc));

    HGLOBAL hg = LoadResource(hm, hrsrc);
    if( !hg )
    {
        OutputDebugString("Failed to load 'wave' resource ");
        OutputDebugString(pszID);
        OutputDebugString("\n");
        return false;
    }

    // Open the given resource for reading
    MMIOINFO    mii = { 0 };
    mii.pchBuffer = (HPSTR)hg;
    mii.fccIOProc = FOURCC_MEM;
    mii.cchBuffer = SizeofResource(hm, hrsrc);

    HMMIO   hmmio;
    hmmio = mmioOpen(0, &mii, MMIO_READ | MMIO_ALLOCBUF);
    if( !hmmio )
    {
        OutputDebugString("mmioOpen() -- Failed to open 'wave' resource ");
        OutputDebugString(pszID);
        OutputDebugString("\n");
        return false;
    }

    bool    bSuccess = Load(hmmio);

    // We're done with the file, close it
    mmioClose(hmmio, 0);

    return bSuccess;
}
    
//*********************************************************************
// Loads the WAV data from multiple sources
bool CtWave::Load(HMMIO hmmio)
{
    MMRESULT    mr;
    MMCKINFO    mmckinfoParent;
    MMCKINFO    mmckinfoSubchunk;

    // Locate a 'RIFF' chunk with a 'WAVE' form type to make sure it's a WAVE file
    mmckinfoParent.fccType = mmioFOURCC('W', 'A', 'V', 'E');
    mr = mmioDescend(hmmio, &mmckinfoParent, 0, MMIO_FINDRIFF);
    if( mr )
    {
        WOTRACE(mr, __TEXT("mmioDescend"));
        mmioClose(hmmio, 0);
        return false;
    }
    
    //  Now, find the format chunk (form type 'fmt '). It should be
    //  a subchunk of the 'RIFF' parent chunk.
    mmckinfoSubchunk.ckid = mmioFOURCC('f', 'm', 't', ' ');
    mr = mmioDescend(hmmio, &mmckinfoSubchunk, &mmckinfoParent, MMIO_FINDCHUNK);
    if( mr )
    {
        WOTRACE(mr, __TEXT("mmioDescend"));
        mmioClose(hmmio, 0);
        return false;
    }
    
    // Get the size of the format chunk and allocate memory for it
    DWORD           nFormatSize = mmckinfoSubchunk.cksize;
    WAVEFORMATEX*   pFormat = (WAVEFORMATEX*)(new BYTE[nFormatSize]);
    if( !pFormat )
    {
        OutputDebugString("new[] -- Out of memory\n");
        mmioClose(hmmio, 0);
        return false;
    }
    
    // Read the format chunk
    if( mmioRead(hmmio, (HPSTR)pFormat, nFormatSize) != (LONG)nFormatSize )
    {
        OutputDebugString("mmioRead() -- Failed to read FMT chunk\n");
        delete[] pFormat;
        mmioClose(hmmio, 0);
        return false;
    }
    
    /*
    TRACE1("wFormatTag = %lu\n",        (DWORD) pFormat->wFormatTag);
    TRACE1("nChannels = %lu\n",         (DWORD) pFormat->nChannels );
    TRACE1("nSamplesPerSec = %lu\n",    (DWORD) pFormat->nSamplesPerSec);
    TRACE1("nAvgBytesPerSec = %lu\n",   (DWORD) pFormat->nAvgBytesPerSec);
    TRACE1("nBlockAlign = %lu\n",       (DWORD) pFormat->nBlockAlign);
    TRACE1("wBitsPerSample = %lu\n",    (DWORD) pFormat->wBitsPerSample);
    TRACE1("cbSize = %lu\n",            (DWORD) pFormat->cbSize);
    */

    // Ascend out of the format subchunk
    mmioAscend(hmmio, &mmckinfoSubchunk, 0);
    
    // Find the data subchunk
    mmckinfoSubchunk.ckid = mmioFOURCC('d', 'a', 't', 'a');
    mr = mmioDescend(hmmio, &mmckinfoSubchunk, &mmckinfoParent, MMIO_FINDCHUNK);
    if( mr )
    {
        WOTRACE(mr, __TEXT("mmioDescend"));
        delete[] pFormat;
        mmioClose(hmmio, 0);
        return false;
    }
    
    //  Get the size of the data subchunk
    DWORD   nDataSize = mmckinfoSubchunk.cksize;
    if( !nDataSize )
    {
        OutputDebugString("Data chunk actually has no data\n");
        delete[] pFormat;
        mmioClose(hmmio, 0);
        return false;
    }
    
    //TRACE1("Size of data is %lu\n", nDataSize);
    
    // Allocate memory for the waveform data
    HPSTR   pData = (HPSTR)(new BYTE[nDataSize]);
    if( !pData )
    {
        OutputDebugString("new[] -- Out of memory\n");
        mmioClose(hmmio, 0);
        delete[] pFormat;
        return false;
    }
    
    // Read the waveform data subchunk
    if( mmioRead(hmmio, pData, nDataSize) != (LONG)nDataSize )
    {
        OutputDebugString("mmioRead() -- Failed to read waveform data subchunk\n");
        delete[] pData;
        delete[] pFormat;
        mmioClose(hmmio, 0);
        return false;
    }
    
    // Update the object state
    m_pFormat = pFormat;
    m_nFormatSize = nFormatSize;
    m_nOutputSize = nDataSize;
    m_pDataOut1 = pData; //***
    m_bOwnData = true;

    return true;
}

//*********************************************************************
// Remember buffer and create a new one.
//  Used when recording audio.
bool CtWave::Append()
{
    WAVEHDR* pWaveHdr; 
	HPSTR pData;

	if (m_bWaveInHdr1InUse)
	{
		pWaveHdr = m_pWaveInHdr2;
		pData = m_pDataIn2;
	}
	else
	{
		pWaveHdr = m_pWaveInHdr1;
		pData = m_pDataIn1;
	}

	m_listWaveData.AddTail( pData);
	pData = NULL;

    MMRESULT mr = waveInUnprepareHeader(m_hWaveIn, pWaveHdr, sizeof(WAVEHDR));
    WITRACE(mr, __TEXT("waveInUnprepareHeader"));
    
    // Cache recorded length
    m_nRecordedSize = pWaveHdr->dwBytesRecorded;

	// Remember the total size.
	m_nTotalRecording += m_nRecordedSize;
    CString info;
    info.Format("CtWave::Append() -- BufSize(%d) Total(%d)\n", m_nRecordedSize, m_nTotalRecording);
    OutputDebugString(info);

    delete pWaveHdr;
    pWaveHdr = 0;

	return true;
}

//*********************************************************************
//  Save all buffers to a WAV file.
bool CtWave::Save(LPCTSTR pszFileName)
{
    // Make sure we've got some data
    if( !m_pDataIn1 ) //***
    {
        return false;
    }

    assert(m_pFormat);
    assert(m_nFormatSize);
    assert(m_pDataIn1); //***

    HANDLE  hFile;
    DWORD   nBytesWritten;

    hFile = CreateFile(pszFileName, GENERIC_WRITE, 0, 0,
                       CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
    if( hFile == INVALID_HANDLE_VALUE )
    {
        OutputDebugString("CreateFile() -- Can't open file: ");
        OutputDebugString(pszFileName);
        OutputDebugString("\n");
        return false;
    }
    
    BYTE    rgbRiffChunk[] =        { 'R', 'I', 'F', 'F', 0, 0, 0, 0, 'W', 'A', 'V', 'E', };
    BYTE    rgbFormatChunkTag[] =   { 'f', 'm', 't', ' ', 0, 0, 0, 0, };
    BYTE    rgbDataChunkTag[] =     { 'd', 'a', 't', 'a', 0, 0, 0, 0, };

    // Write out the RIFF chunk
    *((DWORD*)&rgbRiffChunk[4]) = 4 + sizeof(rgbFormatChunkTag) +
                                  m_nFormatSize + sizeof(rgbDataChunkTag) +
                                  m_nTotalRecording;
    if( !WriteFile(hFile, rgbRiffChunk, sizeof(rgbRiffChunk), &nBytesWritten, 0) )
    {
        OutputDebugString("Can't write RIFF chunk\n");
        CloseHandle(hFile);
        return false;
    }

    // Write tag
    *((DWORD*)&rgbFormatChunkTag[4]) = m_nFormatSize;
    if( !WriteFile(hFile, rgbFormatChunkTag, sizeof(rgbFormatChunkTag), &nBytesWritten, 0) )
    {
        OutputDebugString("Can't write fmt chunk\n");
        CloseHandle(hFile);
        return false;
    }
    
    // Write out the canned format header
    if( !WriteFile(hFile, m_pFormat, m_nFormatSize, &nBytesWritten, 0) )
    {
        OutputDebugString("Can't write WAVEFORMATEX chunk\n");
        CloseHandle(hFile);
        return false;
    }
    
    // Write out the data chunk tag
    *((DWORD *)&rgbDataChunkTag[4]) = m_nTotalRecording;
    if( !WriteFile(hFile, rgbDataChunkTag, sizeof(rgbDataChunkTag), &nBytesWritten, 0) )
    {
        OutputDebugString("Can't write data chunk tag\n");
        CloseHandle(hFile);
        return false;
    }
    
	POSITION pos = m_listWaveData.GetHeadPosition();
	while (pos)
	{
		HPSTR pData = (HPSTR)m_listWaveData.GetNext(pos);
		if (pData)
		{
			// Write out the data chunks
			if( !WriteFile(hFile, pData, m_nDataBlockSize, &nBytesWritten, 0) )
			{
				OutputDebugString("Can't write data chunk\n");
				CloseHandle(hFile);
				return false;

⌨️ 快捷键说明

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