Click here to Skip to main content
15,896,063 members
Articles / Desktop Programming / MFC

A Simple Prototype for Demonstration of Voice Communication via Network/Internet

Rate me:
Please Sign up or sign in to vote.
4.35/5 (24 votes)
14 Jun 2000 204.3K   8.4K   102  
Voice communication
/**************************************************************************
 *    file:         vtPlayWave.h                                          *
 *    create:       June 10, 2000                                         *
 *    copyright:    @ 2000, by Zhaohui Xing                               *
 *    e-mail:       xinghh@yahoo.com                                      * 
 *    description:  implementation of VTPlayWave class                    *
 **************************************************************************/

#include "stdafx.h"
#include "vtWave.h"

/**************************************************************************
 *  Default constructor                                                   *
 **************************************************************************/
VTPlayWave::VTPlayWave() : VTWave()
{
}


/**************************************************************************
 *  Constructor                                                           *
 **************************************************************************/
VTPlayWave::VTPlayWave(HWND hwnd, int iFormat)
   :VTWave(hwnd, iFormat)
{
}


/**************************************************************************
 *  Destructor                                                           *
 **************************************************************************/
VTPlayWave::~VTPlayWave()
{
	// If wave output device still open
	// close it
	if(m_hwOut)
	   waveOutClose(m_hwOut);
	
	// Release the memory for wave header
	if(m_pWhdrOut)
	   CleanMemory();
}


/**************************************************************************
 *  Allocate memory for the header structure of wave output               *
 **************************************************************************/
BOOL VTPlayWave::AllocMemory(void)
{
	// Allocated buffer for WAVEHDR structure
	m_pWhdrOut = (WAVEHDR*)HeapAlloc(GetProcessHeap(),                         
	                      HEAP_ZERO_MEMORY,                         
	                      sizeof(WAVEHDR));
	
	// Success
	if(m_pWhdrOut)                                                  
	{        
		// Allocate buffer of wave data in wave header structure
	    m_pWhdrOut->lpData = (char*)HeapAlloc(GetProcessHeap(),             
	                                  HEAP_ZERO_MEMORY,             
	                                  VT_MAX);                 
		// Set wave data buffer length
	    m_pWhdrOut->dwBufferLength = VT_MAX;

		// Set the flag of wave header structure
		m_pWhdrOut->dwFlags = 0;
	}
	else  // An error ocurred
	{
        MessageBox(m_hWnd, "Failed to allocate memory for output device", 
			       "Error in allocating output device memory", MB_OK);
	    return FALSE;
	}

	// OK
	return TRUE;
}


/**************************************************************************
 *  Clearn the memory of the header structure of wave output              *
 **************************************************************************/
void VTPlayWave::CleanMemory(void)
{
	// If not clean the buffer
	if(m_pWhdrOut)
	{
		// First clean the buffer of wave data
		if(m_pWhdrOut->lpData)
            HeapFree(GetProcessHeap(), 0, m_pWhdrOut->lpData);                 

        // Clean all
		HeapFree(GetProcessHeap(), 0, m_pWhdrOut);
        m_pWhdrOut = NULL;
	}
}


/**************************************************************************
 *  Initialize and open the wave output device                            *
 **************************************************************************/
BOOL VTPlayWave::Initialize(void)
{
    WAVEOUTCAPS  woc;                                               
	WAVEFORMATEX wfx;
	UINT         uiDevID;
	MMRESULT     rc;                                                
	UINT         nMaxDevices = waveOutGetNumDevs();                  
    char         sError[129];
	
	m_hwOut = NULL;
	
	// Check the correct wave output device to open
	for(uiDevID = 0; uiDevID < nMaxDevices; uiDevID++)                         
	{                                              
		// Get output device caps
	    rc = waveOutGetDevCaps(uiDevID, &woc, sizeof(woc));
	    if(rc == MMSYSERR_NOERROR)                                  
		{
			// Set the correct format for wave output device
	        wfx.nChannels = VTWAVECHANNEL[m_iFormat];  //1: mono, 2, stereo
		    wfx.nSamplesPerSec  = VTWAVEFREQ[m_iFormat];
            wfx.wFormatTag      = WAVE_FORMAT_PCM;
		    wfx.wBitsPerSample  = VTWAVEBITS[m_iFormat];
            wfx.nBlockAlign     = wfx.nChannels*wfx.wBitsPerSample/8;
            wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;  
       	    wfx.cbSize          = 0;

			// Open the wave output device
	        rc = waveOutOpen(&m_hwOut, uiDevID, &wfx, (DWORD)m_hWnd, 0,                   
	                        CALLBACK_WINDOW);
	                                      
            // If failed
            if(rc != MMSYSERR_NOERROR)
			{           
				// Get the error information
	            waveOutGetErrorText(rc, sError, 128),                    
	            MessageBox(m_hWnd, sError, "Error in output device opening", 
				           MB_OK);

				// Return false
	            return FALSE;
			}
	       
	        break;                                                        
		}                                                             
	}                                                               
	
    // Device not found
    if(m_hwOut == NULL)
    {
        MessageBox(m_hWnd, "Can't find correct output device to open", 
		          "Error in e open playing device", MB_OK);
	    return FALSE;
    }

    // OK
	return TRUE;
}


/**************************************************************************
 *  Start to play the sound                                               *
 **************************************************************************/
BOOL VTPlayWave::StartPlay(void)
{
    MMRESULT    rc;
    char        sError[129];

	// Initialize and open the wave output device
	Initialize();

	// Pause the device for preparing the data
	waveOutPause(m_hwOut);
	                                                                
	// prepare the buffers
	rc = waveOutPrepareHeader(m_hwOut, m_pWhdrOut, sizeof(WAVEHDR));       
	                                                                
	// write buffers to the queue                            
	if(rc == MMSYSERR_NOERROR)                                  
	    rc = waveOutWrite(m_hwOut, m_pWhdrOut, sizeof(WAVEHDR));       
	else // Failed                                                               
	{             
		// Get error information
	    waveOutGetErrorText(rc, sError, 128),                        
	    MessageBox(m_hWnd, sError, "Error in preparing output buffer", MB_OK);
		// Stop
        StopPlay();        
	    return FALSE;                                              
	}
	
	// Start playback (device currently paused)                                                               
    rc = waveOutRestart(m_hwOut);
	
	// Failed
	if(rc != MMSYSERR_NOERROR)
	{
		// Get error information
        waveOutGetErrorText(rc, sError, 128),                        
	    MessageBox(m_hWnd, sError, "Error in starting output device", MB_OK);
		// Stop
        StopPlay();  
	    return FALSE;                                              
	}

	// OK
	return TRUE;
}


/**************************************************************************
 *  Stop playing the sound                                                *
 **************************************************************************/
void VTPlayWave::StopPlay(void)
{
	if(m_hwOut)
	{
		// Pause the output device
	    waveOutPause(m_hwOut);
	
	    // Unprepare headers                                                      
        waveOutUnprepareHeader(m_hwOut, m_pWhdrOut, sizeof(WAVEHDR));           
 
	    //Close the wave output device
	    waveOutClose(m_hwOut);
	    m_hwOut = NULL;
	}
}


/**************************************************************************
 *  Reset wave data buffer to read new sound data                         *
 **************************************************************************/
void VTPlayWave::ResetPlay(void)
{
	// Pause the output device
	waveOutPause(m_hwOut);
    
	// Reset the wave header buffer
    waveOutUnprepareHeader(m_hwOut, m_pWhdrOut, sizeof(WAVEHDR));           
}


/**************************************************************************
 *  After reset wave data buffer and read new sound data,restart to play  *
 *  the sound                                                             *
 **************************************************************************/
BOOL VTPlayWave::RestartPlay(void)
{
    MMRESULT    rc;
    char        sError[129];
	
	// Prepare the buffers
	rc = waveOutPrepareHeader(m_hwOut, m_pWhdrOut, sizeof(WAVEHDR));       
	                                                                
	// Write buffers to the queue                            
	if(rc == MMSYSERR_NOERROR)                                  
	    rc = waveOutWrite(m_hwOut, m_pWhdrOut, sizeof(WAVEHDR));       
	else // Failed                                                                
	{             
		// Get error information
	    waveOutGetErrorText(rc, sError, 128),                        
	    MessageBox(m_hWnd, sError, "Error in preparing output \
		           buffer for re-play", MB_OK);
		// Not continus
        StopPlay();        
	    return FALSE;                                              
	}
	
	// Restart playback device currently paused                                                               
    rc = waveOutRestart(m_hwOut);
	
	// Failed
	if(rc != MMSYSERR_NOERROR)
	{
		// Get the error information
        waveOutGetErrorText(rc, sError, 128),                        
	    MessageBox(m_hWnd, sError, "Error in starting output \
		           device for re-play", MB_OK);
		// Not continus
        StopPlay();  
	    return FALSE;                                              
	}

	// OK
	return TRUE;
}


/**************************************************************************
 * Set new sound data to the output header structure                      *
 **************************************************************************/
void VTPlayWave::SetPlayData(void* pWaveData, unsigned int lBufSize)
{
	unsigned int lRealSize;
    
	// Limited the data buffer length
	if(lBufSize > VT_MAX)
        lRealSize = VT_MAX;
	else
        lRealSize = lBufSize; 

	// Clean buffer
	memset((void*)m_pWhdrOut->lpData, 0, VT_MAX);
	// Copy buffer
    memcpy((void*)m_pWhdrOut->lpData, pWaveData, lRealSize);
	m_pWhdrOut->dwBufferLength = lRealSize;
}



By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.


Written By
Canada Canada
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions