www.pudn.com > tapi3.zip > WAVEXG.CPP


// Source for wave functions for the dialer/talker app 
// (c) Dialogic corp 1995 
 
#include "stdafx.h" 
#include                     
#include "wavexg.h"  
 
//static char ppszGNames[MAXWAVEDEVS][16];	// Limit the name by 16 chars; change if need to 
static char szErr[128]; 
 
// Play the WAVE file specified on input                       
HWAVEOUT WavexPlay(HWND hWnd, UINT nID, LPSTR lpFileName) 
{  
	WAVEFORMATEX FAR *lpwfWaveFormat = NULL; 
	WAVEHDR FAR *lpwhWaveHdr = NULL; 
	HMMIO hmmH;       
	HWAVEOUT hWave; 
	MMCKINFO mmParent, mmSubchunk; 
	DWORD dwFmtSize, dwDataSize; 
	HPSTR lpWaveData = NULL; 
	WORD wrc; 
	 
	TRACE("** TALKER32 **: enter Play\r\n"); 
    // Open wave file  
    hmmH = mmioOpen(lpFileName, NULL, MMIO_READ); //| MMIO_ALLOCBUF); 
    if(!hmmH) 
    {    
    	MessageBox(NULL, "Input WAVE file open failed", NULL, MB_ICONSTOP); 
        return FALSE; 
    }                  
     
    // Locate a ‘RIFF’ chunk with a ‘WAVE’ form type  
    mmParent.fccType = mmioFOURCC('W', 'A', 'V', 'E'); 
    if (mmioDescend(hmmH, (LPMMCKINFO) &mmParent, NULL, MMIO_FINDRIFF)) 
	{  
		mmioClose(hmmH, 0); 
        MessageBox(NULL, "Corrupted WAVE file(no WAVE form type)", NULL, MB_ICONSTOP); 
		return FALSE; 
	} 
     
    // Find the format chunk  
    mmSubchunk.ckid = mmioFOURCC('f', 'm', 't', ' '); 
    if (mmioDescend(hmmH, &mmSubchunk, &mmParent, MMIO_FINDCHUNK)) 
    { 
        mmioClose(hmmH, 0); 
        MessageBox(NULL, "Corrupted WAVE file(no fmt chunk)", NULL, MB_ICONSTOP); 
        return FALSE; 
    } 
 
    // Get the size of the format chunk, allocate memory for it  
    dwFmtSize = mmSubchunk.cksize; 
    lpwfWaveFormat = (LPWAVEFORMATEX) malloc(sizeof(WAVEFORMATEX)); //dwFmtSize); 
    if (!lpwfWaveFormat) 
    { 
        MessageBox(NULL, "Memory alloc for waveformat failed", NULL, MB_ICONSTOP); 
        mmioClose(hmmH, 0); 
        return FALSE; 
    } 
 
    // Read the format chunk  
    if (mmioRead(hmmH, (HPSTR) lpwfWaveFormat, dwFmtSize) != (LONG) dwFmtSize) 
    { 
        MessageBox(NULL, "Read fmt chunk failed", NULL, MB_ICONSTOP); 
        mmioClose(hmmH, 0); 
		goto PlayFailed; 
    } 
     
    // Ascend out of the format subchunk  
    mmioAscend(hmmH, &mmSubchunk, 0); 
     
    // Find the data subchunk  
    mmSubchunk.ckid = mmioFOURCC('d', 'a', 't', 'a'); 
    if (mmioDescend(hmmH, &mmSubchunk, &mmParent, MMIO_FINDCHUNK)) 
    { 
        MessageBox(NULL, "Could not find data subchunk)", NULL, MB_ICONSTOP); 
        mmioClose(hmmH, 0); 
		goto PlayFailed; 
    } 
     
    // Get the size of the data subchunk  
    dwDataSize = mmSubchunk.cksize; 
    if (dwDataSize == 0L) 
    { 
        MessageBox(NULL, "No data to play", NULL, MB_ICONSTOP); 
        mmioClose(hmmH, 0); 
		goto PlayFailed; 
    } 
         
	lpwfWaveFormat->cbSize = 0; 
    // Allocate and lock memory for the waveform data.  
    lpWaveData = (HPSTR) malloc(dwDataSize); 
    if (!lpWaveData) 
    { 
        MessageBox(NULL, "Memory alloc for data to play failed", NULL, MB_ICONSTOP); 
        mmioClose(hmmH, 0); 
		goto PlayFailed; 
    } 
 
    // Read the waveform data subchunk  
    if(mmioRead(hmmH, (HPSTR) lpWaveData, dwDataSize) != (LONG) dwDataSize) 
    { 
        MessageBox(NULL, "Data read failed", NULL, MB_ICONSTOP); 
        mmioClose(hmmH, 0); 
		goto PlayFailed; 
    } 
 
    // We’re done with the file, close it  
    mmioClose(hmmH, 0); 
 
    // Allocate a waveform data header  
    lpwhWaveHdr = (WAVEHDR FAR*) malloc(sizeof(WAVEHDR)); 
    if (!lpwhWaveHdr) 
    { 
        MessageBox(NULL, "Memory alloc for WAVE header failed", NULL, MB_ICONSTOP); 
		goto PlayFailed; 
    } 
 
    // Set up WAVEHDR structure and prepare it to be written to wave device  
    lpwhWaveHdr->lpData = lpWaveData; 
    lpwhWaveHdr->dwBufferLength = dwDataSize; 
    lpwhWaveHdr->dwFlags = 0L; 
    lpwhWaveHdr->dwLoops = 0L; 
    lpwhWaveHdr->dwUser  = (DWORD)nID; 
 
    /* make sure wave device can play our format */ 
    if (waveOutOpen((LPHWAVEOUT)NULL, (WORD)nID, lpwfWaveFormat,  
                    0L, 0L, WAVE_FORMAT_QUERY)) 
	{ 
        MessageBox (NULL, "Unsupported wave format", NULL, MB_ICONSTOP); 
		goto PlayFailed; 
    } 
 
    // open the wave device corresponding to the line  
    if (wrc = waveOutOpen (&hWave, (WORD)nID, lpwfWaveFormat,  
                     (DWORD)hWnd, 0L, CALLBACK_WINDOW)) 
	{                                            
		wsprintf(szErr, "Error #%d opening wave device", wrc); 
        MessageBox (NULL, szErr, NULL, MB_ICONSTOP); 
		goto PlayFailed; 
	} 
    free( lpwfWaveFormat ); 
    lpwfWaveFormat = NULL; 
 
    // prepare the message header for playing  
    if (waveOutPrepareHeader (hWave, lpwhWaveHdr, sizeof(WAVEHDR))) 
	{ 
		MessageBox (NULL, "Error preparing message header", NULL, MB_OK); 
		goto PlayFailed; 
    } 
 
    // play the message right from the data segment;  set the play message flag  
    if (waveOutWrite (hWave, lpwhWaveHdr, sizeof (WAVEHDR))) 
	{ 
		MessageBox (NULL, "Error writing wave message", NULL, MB_ICONSTOP); 
        return FALSE; 
    } 
	TRACE("** TALKER32 **: end of Play\r\n"); 
    return hWave;		// DONE !!! 
     
PlayFailed:             
 
    if(lpwfWaveFormat) free( lpwfWaveFormat ); 
    if(lpWaveData) free(lpWaveData); 
    if(lpwhWaveHdr) free(lpwhWaveHdr); 
    return FALSE; 
} 
                     
// WOM message handler 
void WavexFinishPlay(WPARAM wParam, LPARAM lParam) 
{                                      
	LPWAVEHDR lpwhWaveHdr = (LPWAVEHDR)lParam; 
	UINT nInID, nID = (UINT)(lpwhWaveHdr->dwUser); 
	HWAVEIN hWaveIn = NULL, hWaveOut;  
	LONG lrc; 
	 
	// Unprepare the header  
	TRACE("** TALKER32 **: enter FinishPlay\r\n"); 
	waveOutUnprepareHeader((HWAVEOUT)wParam,(LPWAVEHDR)lParam, 
                                   sizeof(WAVEHDR)); 
	waveOutClose((HWAVEOUT)wParam); // close wave device  
	free (lpwhWaveHdr->lpData); // free the wave data  
	free (lpwhWaveHdr); // free the header  
	TRACE("** TALKER32 **: finish FinishPlay\n"); 
	return;	 
} 
 
HWAVEIN WavexRecord(HWND hWnd, UINT nID) 
{ 
    HWAVEIN hWaveIn; 
    DWORD dwBufSize = 0xfffe;//10L * (LONG)pcwfGWaveFormat.wf.nSamplesPerSec *  
                      //      (LONG)pcwfGWaveFormat.wBitsPerSample/8L; 
	WAVEFORMATEX pcwfWaveFormat = {WAVE_FORMAT_PCM, 1, 11025, 11025, 1, 8,0}; 
	LPWAVEHDR lpwhInWaveHdr = NULL; 
	 
	// open recorder  
	if (waveInOpen( &hWaveIn, (WORD) nID, &pcwfWaveFormat, 
                 (DWORD)hWnd, NULL, CALLBACK_WINDOW))  
	{ 
		MessageBox (NULL, "Error opening wave record device.", NULL, MB_ICONSTOP); 
		return NULL; 
	}  
	 
    // allocate wave header 
    if(NULL == (lpwhInWaveHdr = (LPWAVEHDR) malloc(sizeof(WAVEHDR)))) 
	{ 
		MessageBox (NULL, "Memory alloc for in/header failed", NULL, MB_ICONSTOP); 
		return NULL; 
    } 
	 
	// allocate s message buffer  
	if (NULL == (lpwhInWaveHdr->lpData = (HPSTR) malloc(dwBufSize)))  
	{ 
		MessageBox (NULL, "Memory alloc for record failed", NULL, MB_ICONSTOP); 
		return NULL; 
	} 
	lpwhInWaveHdr->dwBufferLength = dwBufSize; 
	lpwhInWaveHdr->dwFlags=0L; 
	lpwhInWaveHdr->dwLoops=0L; 
	if (waveInPrepareHeader(hWaveIn, lpwhInWaveHdr, sizeof(WAVEHDR)))  
	{ 
		MessageBox (NULL, "Error preparing message header.", NULL, MB_ICONSTOP); 
		return FALSE; 
	} 
 
	// pass down a 30s buffer to record into  
	if (waveInAddBuffer (hWaveIn, lpwhInWaveHdr, sizeof(WAVEHDR)))  
	{ 
		MessageBox (NULL, "Error adding buffer", NULL, MB_ICONSTOP); 
		return FALSE; 
	} 
	if(waveInStart(hWaveIn))  
	{ 
		MessageBox (NULL, "Failed to start recording", NULL, MB_ICONSTOP); 
		return FALSE; 
	} 
	return hWaveIn; 
}  
                    
// WIM message handler 
void WavexFinishRecord(WPARAM wParam, LPARAM lParam, LPSTR lpName) 
{    
	LPWAVEHDR lpwhWaveHdr = (LPWAVEHDR) lParam; 
	 
	TRACE("** TALKER32 **: enter FinishRecord\n"); 
	 
	waveInUnprepareHeader((HWAVEIN) wParam, lpwhWaveHdr, sizeof(WAVEHDR)); 
	waveInStop((HWAVEIN) wParam); 
	waveInClose((HWAVEIN) wParam); 
	WavexSaveData(lpwhWaveHdr, lpName);                   
	free(lpwhWaveHdr->lpData); 
	free((LPSTR)lpwhWaveHdr);  
	TRACE("** TALKER32 **: end FinishRecord\r\n"); 
	return;					 
} 
 
// Borrowed from tam.c 
void WavexSaveData(LPWAVEHDR lpwhWH, LPSTR lpName) 
{                                   
	PCMWAVEFORMAT pcwfWF={WAVE_FORMAT_PCM, 1, 11025, 11025, 1,8}; 
 
	// quick and dirty RIFF chunk  
	char abRiffchunk[] = {'R','I','F','F',  0,0,0,0, 'W','A','V','E'}; 
	// quick and dirty format chunk tag  
	char abFormatchunktag[] = {'f','m','t',' ',  0,0,0,0}; 
	// quick and dirty data chunk header  
	char abDatachunktag[] = {'d','a','t','a',  0,0,0,0}; 
	HFILE hFile; 
 
    if(HFILE_ERROR == (hFile = _lcreat ("talker.wav", 0))) // O_CREAT | O_BINARY | O_WRONLY)) 
	{ 
		MessageBox (NULL, "Error opening talker.wav", NULL, MB_ICONSTOP); 
		return; 
	} 
	// write out the RIFF chunk  
	*((DWORD *)&abRiffchunk[4])=4 + sizeof(abFormatchunktag) +  
                                 sizeof(pcwfWF) + sizeof(abDatachunktag) +  
                                 lpwhWH->dwBytesRecorded; 
	_lwrite(hFile, (const char *)abRiffchunk, sizeof(abRiffchunk)); 
	*((DWORD *)&abFormatchunktag[4]) = sizeof(pcwfWF); // write  tag  
	_lwrite(hFile, abFormatchunktag, sizeof(abFormatchunktag)); 
 
	// write out the canned format header  
	_lwrite (hFile, (char *)(&pcwfWF), sizeof(pcwfWF)); 
 
	// write out the data chunk tag  
	*((DWORD *)&abDatachunktag[4]) = lpwhWH->dwBytesRecorded; 
	_lwrite(hFile, abDatachunktag, sizeof(abDatachunktag)); 
 
	// write out the data chunk  
	_hwrite (hFile, lpwhWH->lpData, lpwhWH->dwBytesRecorded); 
	_lclose (hFile);  
	return; 
}