www.pudn.com > AM.rar > WAVE.CPP
#include#include #include #include #include "Wave.h" char lpErrMsg[100]; // save wave error message //--------------------------------------------------------------------------- //play wave by WavePlay //--------------------------------------------------------------------------- HWAVEOUT WavePlay(DWORD nID, LPSTR lpFileName ,LPLINEINFO pLineData) { WAVEFORMATEX *lpWaveFormat = NULL; WAVEHDR *lpWaveHdr = NULL; WAVEHDR *lpWaveHdr2 = NULL; HMMIO hmmioH; HWAVEOUT hWaveOut = NULL; MMCKINFO mmParent, mmSubchunk; DWORD dwFmtSize, dwDataSize; HPSTR lpWaveData = NULL; MMRESULT mmrc; // Open wave file hmmioH = mmioOpen(lpFileName, NULL, MMIO_READ); if(!hmmioH) { printf("\n###Line %d Input WAVE file open failed",pLineData->nLineID); wsprintf(lpErrMsg,"Line %d Input WAVE file open failed", pLineData->nLineID); MessageBox(NULL,"lpErrMsg","WavePlay",MB_OK); return NULL; } // Locate a RIFF? chunk with a WAVE? Form type mmParent.fccType = mmioFOURCC('W', 'A', 'V', 'E'); if (mmioDescend(hmmioH, (LPMMCKINFO) &mmParent, NULL, MMIO_FINDRIFF)) { mmioClose(hmmioH, 0); printf("\n###Line %d Corrupted WAVE file(no WAVE form type)",pLineData->nLineID); wsprintf(lpErrMsg,"Line %d Corrupted WAVE file(no WAVE form type)", pLineData->nLineID); MessageBox(NULL,lpErrMsg,"WavePlay",MB_OK); return NULL; } // Find the format chunk mmSubchunk.ckid = mmioFOURCC('f', 'm', 't', ' '); if (mmioDescend(hmmioH, &mmSubchunk, &mmParent, MMIO_FINDCHUNK)) { mmioClose(hmmioH, 0); printf("\n###Line %d Corrupted WAVE file(no fmt chunk)",pLineData->nLineID); wsprintf(lpErrMsg,"Line %d Corrupted WAVE file(no fmt chunk)", pLineData->nLineID); MessageBox(NULL,lpErrMsg,"WavePlay",MB_OK); return NULL; } // Get the size of the format chunk, allocate memory for it dwFmtSize = mmSubchunk.cksize; lpWaveFormat = (WAVEFORMATEX *) malloc(dwFmtSize); if (!lpWaveFormat) { printf("\n###Line %d Memory alloc for waveformat failed",pLineData->nLineID); wsprintf(lpErrMsg,"Line %d Memory alloc for waveformat failed", pLineData->nLineID); MessageBox(NULL,lpErrMsg,"WavePlay",MB_OK); mmioClose(hmmioH, 0); return NULL; } ZeroMemory((PVOID)lpWaveFormat, dwFmtSize); // Read the format chunk if (mmioRead(hmmioH, (HPSTR) lpWaveFormat, dwFmtSize) != (LONG) dwFmtSize) { printf("\n###Line %d Read fmt chunk failed",pLineData->nLineID); wsprintf(lpErrMsg,"Line %d Read fmt chunk failed", pLineData->nLineID); MessageBox(NULL,lpErrMsg,"WavePlay",MB_OK); mmioClose(hmmioH, 0); goto PlayFailed; } // Ascend out of the format subchunk mmioAscend(hmmioH, &mmSubchunk, 0); // Find the data subchunk mmSubchunk.ckid = mmioFOURCC('d', 'a', 't', 'a'); if (mmioDescend(hmmioH, &mmSubchunk, &mmParent, MMIO_FINDCHUNK)) { printf("\n###Line %d Could not find data subchunk",pLineData->nLineID); wsprintf(lpErrMsg,"Line %d Could not find data subchunk", pLineData->nLineID); MessageBox(NULL,lpErrMsg,"WavePlay",MB_OK); mmioClose(hmmioH, 0); goto PlayFailed; } // Get the size of the data subchunk dwDataSize = mmSubchunk.cksize; if (dwDataSize == 0L) { printf("\n###Line %d No data to play",pLineData->nLineID); wsprintf(lpErrMsg,"Line %d No data to play", pLineData->nLineID); MessageBox(NULL,lpErrMsg,"WavePlay",MB_OK); mmioClose(hmmioH, 0); goto PlayFailed; } //check dwDataSize is greater than WAVEBUFSIZE(=16000) ,then assign value to dwplaysize pLineData->dwPlaySize = dwDataSize > WAVEBUFSIZE ? WAVEBUFSIZE : dwDataSize; // Read the waveform data subchunk if(mmioRead(hmmioH, (HPSTR) pLineData->lpWaveDataAlloc, pLineData->dwPlaySize)!= (LONG)pLineData->dwPlaySize) { printf("\n###Line %d Data read failed",pLineData->nLineID); wsprintf(lpErrMsg,"Line %d Data read failed", pLineData->nLineID); MessageBox(NULL,lpErrMsg,"WavePlay",MB_OK); mmioClose(hmmioH, 0); goto PlayFailed; } dwDataSize -= pLineData->dwPlaySize; //decrease dwDataSize after read it // Allocate a waveform data header lpWaveHdr = (WAVEHDR *) malloc((DWORD)sizeof(WAVEHDR)); lpWaveHdr2 = (WAVEHDR *) malloc((DWORD)sizeof(WAVEHDR)); if (!lpWaveHdr || !lpWaveHdr2) { printf("\n###Line %d Memory alloc for WAVE header failed",pLineData->nLineID); wsprintf(lpErrMsg,"Line %d Memory alloc for WAVE header failed", pLineData->nLineID); MessageBox(NULL,lpErrMsg,"WavePlay",MB_OK); goto PlayFailed; } // Set up WAVEHDR structure and prepare it to be written to wave device lpWaveHdr->lpData = pLineData->lpWaveDataAlloc; lpWaveHdr->dwBufferLength = pLineData->dwPlaySize; lpWaveHdr->dwFlags = 0L; lpWaveHdr->dwLoops = 0L; lpWaveHdr->dwUser = (DWORD) nID; //read enough size into hmmioH pLineData->dwPlaySize = dwDataSize > WAVEBUFSIZE ? WAVEBUFSIZE : dwDataSize; // Read the waveform data subchunk if(mmioRead(hmmioH, (HPSTR) pLineData->lpWaveDataAlloc2, pLineData->dwPlaySize)!= (LONG)pLineData->dwPlaySize) { printf("\n###Line %d Data read failed",pLineData->nLineID); wsprintf(lpErrMsg,"Line %d Data read failed", pLineData->nLineID); MessageBox(NULL,lpErrMsg,"WavePlay",MB_OK); mmioClose(hmmioH, 0); goto PlayFailed; } dwDataSize -= pLineData->dwPlaySize; // Set up WAVEHDR2 structure and prepare it to be written to wave device lpWaveHdr2->lpData = pLineData->lpWaveDataAlloc2; lpWaveHdr2->dwBufferLength = pLineData->dwPlaySize; lpWaveHdr2->dwFlags = 0L; lpWaveHdr2->dwLoops = 0L; lpWaveHdr2->dwUser = (DWORD) nID; /* make sure wave device can play our format */ if (mmrc = waveOutOpen((LPHWAVEOUT)NULL, nID, lpWaveFormat, 0L, 0L, WAVE_FORMAT_QUERY | WAVE_MAPPED)) { printf("\n###Line %d First waveOutOpen failed error# %x",pLineData->nLineID, mmrc); wsprintf(lpErrMsg,"Line %d First waveOutOpen failed error# %x", pLineData->nLineID,mmrc); MessageBox(NULL,lpErrMsg,"WavePlay",MB_OK); goto PlayFailed; } //open the wave device corresponding to the line if (mmrc = waveOutOpen (&hWaveOut, nID, lpWaveFormat, (DWORD)WaveCallBack, (DWORD)pLineData, CALLBACK_FUNCTION | WAVE_MAPPED)) //0L { printf("\n###Line %d opening wave device error #%x",pLineData->nLineID, mmrc); wsprintf(lpErrMsg,"Line %d opening wave device error #%x", pLineData->nLineID,mmrc); MessageBox(NULL,lpErrMsg,"WavePlay",MB_OK); goto PlayFailed; } //prepare the message header for playing if (waveOutPrepareHeader (hWaveOut, lpWaveHdr, sizeof(WAVEHDR)) || waveOutPrepareHeader (hWaveOut, lpWaveHdr2, sizeof(WAVEHDR))) { printf("\n###Line %d error preparing message header",pLineData->nLineID); wsprintf(lpErrMsg,"Line %d error preparing message header", pLineData->nLineID); MessageBox(NULL,lpErrMsg,"WavePlay",MB_OK); goto PlayFailed; } // Set the volume before playing waveOutSetVolume(hWaveOut, 0x8888); //volume level form 0x0000 ~ 0xFFFF // play the message right from the data segment, set the play message flag // play wave data from lpwaveHdr if (waveOutWrite (hWaveOut, lpWaveHdr, sizeof (WAVEHDR)) || waveOutWrite (hWaveOut, lpWaveHdr2, sizeof (WAVEHDR))) { printf("\n###Line %d error writing wave message",pLineData->nLineID); wsprintf(lpErrMsg,"Line %d error writing wave message", pLineData->nLineID); MessageBox(NULL,lpErrMsg,"WavePlay",MB_OK); goto PlayFailed; } printf("\nLine %d play %s...",pLineData->nLineID,lpFileName); // restore to pLineData then can use later pLineData->hmmioH = hmmioH; pLineData->dwDataSize = dwDataSize; pLineData->lpWaveHdr = lpWaveHdr; pLineData->lpWaveHdr2 = lpWaveHdr2; pLineData->dwWaveStage = 1; pLineData->wWaveBufState = 0; free( lpWaveFormat ); return hWaveOut; PlayFailed: if(lpWaveFormat) free( lpWaveFormat ); if(lpWaveHdr) free(lpWaveHdr); if(lpWaveHdr2) free(lpWaveHdr2); if(hWaveOut) waveOutClose(hWaveOut); return NULL; } //--------------------------------------------------------------------------- //Record income call by WaveRecord //--------------------------------------------------------------------------- HWAVEIN WaveRecord(UINT nID, DWORD dwBufSize,LPLINEINFO pLineData) { HWAVEIN hWaveIn; WAVEFORMATEX pcWaveFormat = {WAVE_FORMAT_PCM, 1, 8000, 8000, 1,8}; LPWAVEHDR lpWaveHdr = NULL; LPWAVEHDR lpWaveHdr2 = NULL; HMMIO hmmioH; MMCKINFO mmParent, mmSubchunk; PWAVEININFO pCash = (PWAVEININFO)new WAVEININFO; WORD wrc,cSamples; char lpszName[15]; //assign the dwdatasize for record pLineData->dwDataSize = dwBufSize < WAVEBUFSIZE*2 ? WAVEBUFSIZE*2 : dwBufSize; wsprintf(lpszName,"income%d.wav", pLineData->nLineID); //indicate file name //create chunk for income%d.wav hmmioH = mmioOpen(lpszName,NULL,MMIO_CREATE|MMIO_WRITE); mmParent.fccType = mmioFOURCC('W','A','V','E'); mmParent.cksize = 0L; mmioCreateChunk(hmmioH,&mmParent,MMIO_CREATERIFF); mmSubchunk.ckid = mmioFOURCC('f','m','t',' '); mmSubchunk.cksize = 0L; mmioCreateChunk(hmmioH, &mmSubchunk, 0 ); mmioWrite(hmmioH, (HPSTR) (LPWAVEFORMATEX)&pcWaveFormat, sizeof(pcWaveFormat)); mmioAscend(hmmioH, &mmSubchunk, 0); mmSubchunk.ckid = mmioFOURCC('f','a','c','t'); mmSubchunk.cksize = 0L; mmioCreateChunk(hmmioH, &mmSubchunk, 0); cSamples = 0L; mmioWrite(hmmioH, (HPSTR)&cSamples, sizeof(DWORD)); mmioAscend(hmmioH, &mmSubchunk, 0); mmSubchunk.ckid = mmioFOURCC('d','a','t','a'); mmSubchunk.cksize = 0L; mmioCreateChunk(hmmioH, &mmSubchunk, 0); if(!pCash) { printf("\n###Line %d Memory allocation failed in record",pLineData->nLineID); wsprintf(lpErrMsg,"Line %d Memory allocation failed in record", pLineData->nLineID); MessageBox(NULL,lpErrMsg,"WaveRecord",MB_OK); return NULL; } pCash->WF = pcWaveFormat ; // open recorder if (wrc = waveInOpen( &hWaveIn, (WORD) nID, (LPWAVEFORMATEX)&pcWaveFormat, (DWORD)WaveCallBack, (DWORD)pLineData, CALLBACK_FUNCTION | WAVE_MAPPED)) { printf("\n###Line %d opening wave record device error #%x",pLineData->nLineID, wrc); wsprintf(lpErrMsg,"Line %d opening wave record device error #%x", pLineData->nLineID,wrc); MessageBox(NULL,lpErrMsg,"WaveRecord",MB_OK); goto RecordFailed; } // allocate wave header lpWaveHdr = (LPWAVEHDR) malloc((long)sizeof(WAVEHDR)); lpWaveHdr2 = (LPWAVEHDR) malloc((long)sizeof(WAVEHDR)); if(!lpWaveHdr || !lpWaveHdr2) { printf("\n###Line %d Memory alloc for in/header failed",pLineData->nLineID); wsprintf(lpErrMsg,"Line %d Memory alloc for in/header failed", pLineData->nLineID); MessageBox(NULL,lpErrMsg,"WaveRecord",MB_OK); goto RecordFailed; } // Set up WAVEHDR structure and prepare it to be read from wave device lpWaveHdr->lpData = pLineData->lpWaveDataAlloc; lpWaveHdr->dwBufferLength = WAVEBUFSIZE; lpWaveHdr->dwFlags=0L; lpWaveHdr->dwLoops=0L; lpWaveHdr->dwUser = (DWORD)pCash; lpWaveHdr2->lpData = pLineData->lpWaveDataAlloc2; lpWaveHdr2->dwBufferLength = WAVEBUFSIZE; lpWaveHdr2->dwFlags=0L; lpWaveHdr2->dwLoops=0L; lpWaveHdr2->dwUser = (DWORD)pCash; //prepare the message header for recording if (waveInPrepareHeader(hWaveIn, lpWaveHdr, sizeof(WAVEHDR)) || waveInPrepareHeader(hWaveIn, lpWaveHdr2, sizeof(WAVEHDR))) { printf("\n###Line %d Error preparing message header.",pLineData->nLineID); wsprintf(lpErrMsg,"Line %d Error preparing message header.", pLineData->nLineID); MessageBox(NULL,lpErrMsg,"WaveRecord",MB_OK); goto RecordFailed; } //add lpwavehdr into wave device if (waveInAddBuffer (hWaveIn, lpWaveHdr, sizeof(WAVEHDR))|| waveInAddBuffer (hWaveIn, lpWaveHdr2, sizeof(WAVEHDR))) { printf("\n###Line %d Error adding buffer",pLineData->nLineID); wsprintf(lpErrMsg,"Line %d Error adding buffer", pLineData->nLineID); MessageBox(NULL,lpErrMsg,"WaveRecord",MB_OK); goto RecordFailed; } //start recording if(waveInStart(hWaveIn)) { printf("\n###Line %d Failed to start recording",pLineData->nLineID); wsprintf(lpErrMsg,"Line %d Failed to start recording", pLineData->nLineID); MessageBox(NULL,lpErrMsg,"WaveRecord",MB_OK); goto RecordFailed; } //restore info to pLineData , then will be use later pLineData->hmmioH = hmmioH; pLineData->mmParent = mmParent; pLineData->mmSubchunk = mmSubchunk; pLineData->lpWaveHdr = lpWaveHdr; pLineData->lpWaveHdr2 = lpWaveHdr2; pLineData->wWaveBufState = 0; pLineData->dwWaveStage = 1; pLineData->dwDataSize -= WAVEBUFSIZE*2; printf("\nLine %d start recording in [income%d.wav]....(press # to stop record)",pLineData->nLineID,pLineData->nLineID); return hWaveIn; RecordFailed: if(pCash) delete pCash; if(lpWaveHdr) free(lpWaveHdr); if(hWaveIn) waveInClose(hWaveIn); return NULL; } //--------------------------------------------------------------------------- // WIM & WOM message handler // Wave call back function void CALLBACK WaveCallBack( HWAVEOUT hwo, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2) { LPLINEINFO pLineData = (LPLINEINFO)dwInstance; //printf("\nhwo=%x,uMsg=%x,dwInstance=%x,p1=%x,p2=%x,pLineout=%x", // hwo,uMsg,dwInstance,dwParam1,dwParam2,&pLineOut); switch ( uMsg ) { case WOM_DONE : //wave out callback come here if( pLineData->dwWaveStage ) //continue read wave data ? { if ( pLineData->dwDataSize == 0) //check wave date size { pLineData->dwWaveStage = 0; break; } if ( pLineData->wWaveBufState ) //check which buf need waveoutwrite lineSetAppSpecific(pLineData->hCall, TAPI_SETAPP_ADDPLAYSTAGE2); else lineSetAppSpecific(pLineData->hCall, TAPI_SETAPP_ADDPLAYSTAGE); break; } switch (pLineData->dwCallState) { case TAPI_PLAYGREET: lineSetAppSpecific(pLineData->hCall, TAPI_SETAPP_ENDPLAYGREET); break; case TAPI_PREPAREPLAYICM: lineSetAppSpecific(pLineData->hCall, TAPI_SETAPP_PREPAREPLAYICM); break; case TAPI_PLAYICM: lineSetAppSpecific(pLineData->hCall, TAPI_SETAPP_ENDPLAYICM); break; } break; case WIM_DATA: //wave in callback come here if( pLineData->dwWaveStage ) //continue record ? { if ( pLineData->dwDataSize == 0) //check wave date size { pLineData->dwWaveStage = 0; break; } if ( pLineData->wWaveBufState ) //check which buf need to write into hmmioH lineSetAppSpecific(pLineData->hCall, TAPI_SETAPP_ADDRECORDSTAGE2); else lineSetAppSpecific(pLineData->hCall, TAPI_SETAPP_ADDRECORDSTAGE); break; } if (pLineData->dwCallState & TAPI_RECORDICM) { lineSetAppSpecific(pLineData->hCall, TAPI_SETAPP_ENDRECORDICM); } break; } //end switch case (uMsg) }