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; }