www.pudn.com > VoiceModem.zip > SOUND.C


// MESSAGE.C 
#include "comdial.h" 
 
/* quick and dirty RIFF chunk */ 
BYTE ab_riffchunk[] = {'R','I','F','F',  0,0,0,0, 'W','A','V','E'}; 
/* quick and dirty format chunk tag */ 
BYTE ab_formatchunktag[] = {'f','m','t',' ',  0,0,0,0}; 
/* quick and dirty data chunk header */ 
BYTE ab_datachunktag[] = {'d','a','t','a',  0,0,0,0}; 
 
/* message headers */ 
WAVEHDR inMessageHeader = {NULL, 0, 0, 0, 0 /* no flags */, 0 /* no loops */,   
                           NULL, 0}; 
 
/* handle to main window */ 
extern HWND hTTYWnd; 
 
/* format of in-message */ 
WAVEFORMATEX messageFormat = {WAVE_FORMAT_PCM, 1, 8000, 8000, 1, 16}; 
 
/**************************************************************************** 
    FUNCTION: recordMessage 
    PURPOSE:  begin recording voice message 
****************************************************************************/ 
/* record the voice message  - 60s max */ 
HWAVEIN recordMessage (DWORD dw_devid) 
{ 
HWAVEIN h_wavein;  
LONG lrc; 
DWORD dw_60sbufsz = 60L * (LONG)messageFormat.nSamplesPerSec *  
                            (LONG)messageFormat.wBitsPerSample/8L; 
HANDLE hData; 
 
 
 /* check support for format */ 
 if (lrc=waveInOpen( NULL, (WORD) dw_devid, &messageFormat, 
                 (DWORD)hTTYWnd, 0, WAVE_FORMAT_QUERY)) { 
     MessageBox (NULL, "Unsupported format.", "", MB_OK); 
     return 0; 
 } 
 
 /* open recorder. */ 
 if (lrc=waveInOpen( &h_wavein, (WORD) dw_devid, &messageFormat, 
                 (DWORD)hTTYWnd, 0, CALLBACK_WINDOW)) { 
     MessageBox (NULL, "Error opening wave record device.", "", MB_OK); 
     return 0; 
 } 
 
 /* allocate 60s message buffer */ 
 hData = GlobalAlloc (GPTR, dw_60sbufsz); 
 if ((inMessageHeader.lpData = GlobalLock(hData)) == NULL) { 
     MessageBox (NULL, "Not enough memory.", "", MB_OK); 
     return 0; 
 } 
  
 inMessageHeader.dwBufferLength = dw_60sbufsz; 
 if (lrc=waveInPrepareHeader(h_wavein, &inMessageHeader, sizeof(WAVEHDR))) { 
	 GlobalFree (hData); 
     MessageBox (NULL, "Error preparing message header.", "", MB_OK); 
     return 0; 
 } 
 
 /* pass down a 60s buffer to record into */ 
 if (waveInAddBuffer (h_wavein, &inMessageHeader, sizeof(WAVEHDR))) { 
	 GlobalFree (hData); 
     MessageBox (NULL, "Error adding buffer.", "", MB_OK); 
     return 0; 
 } 
 
 inMessageHeader.dwUser = (DWORD) hData; 
 
 waveInStart (h_wavein); /* start recording */ 
 return h_wavein; 
     
} /* end function (record message) */ 
/**************************************************************************** 
    FUNCTION: saveMessage 
    PURPOSE:  save a recorded voice message 
****************************************************************************/ 
/* save the message after the caller hangs up, or after 60s */ 
int saveMessage (char *name, LPWAVEHDR hdr) 
{ 
HANDLE h_file; 
DWORD n_written; 
 
    h_file = CreateFile (name, GENERIC_READ|GENERIC_WRITE, 0,  
    					NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,NULL); 
    if (h_file == NULL) { 
        MessageBox (NULL, "Error opening file.", "", MB_OK); 
        return -1; 
    } 
   
    /* write out the RIFF chunk */ 
    *((DWORD *)&ab_riffchunk[4])=4 + sizeof(ab_formatchunktag) +  
                                 sizeof(messageFormat) + sizeof(ab_datachunktag) +  
                                 hdr->dwBytesRecorded; 
    WriteFile (h_file, ab_riffchunk, sizeof(ab_riffchunk), &n_written, NULL); 
    *((DWORD *)&ab_formatchunktag[4]) = sizeof(messageFormat); /* write  tag */ 
    WriteFile (h_file, ab_formatchunktag, sizeof(ab_formatchunktag), &n_written, NULL); 
 
    /* write out the canned format header */ 
    WriteFile (h_file, &messageFormat, sizeof(messageFormat), &n_written, NULL); 
 
    /* write out the data chunk tag */ 
    *((DWORD *)&ab_datachunktag[4]) = hdr->dwBytesRecorded; 
    WriteFile (h_file, ab_datachunktag, sizeof(ab_datachunktag), &n_written, NULL); 
 
    /* write out the data chunk */ 
    WriteFile (h_file, hdr->lpData, hdr->dwBytesRecorded, &n_written, NULL); 
    CloseHandle (h_file); /* close message file */ 
    return 0; 
 
} /* end function (save message) */ 
 
/**************************************************************************** 
    FUNCTION:  
    PURPOSE:   
****************************************************************************/ 
/* begin playing out the message */ 
HWAVEOUT playSound (DWORD dw_devid, char *szWaveFile, HWND hWnd) 
{ 
HWAVEOUT        hWave; 
HMMIO            hmmio; 
MMCKINFO        mmckinfoParent; 
MMCKINFO        mmckinfoSubchunk; 
DWORD            dwFmtSize; 
DWORD            dwDataSize; 
HPSTR            lpWaveData; 
WAVEHDR *    lpWaveHdr; 
WAVEFORMATEX *lpWaveFormat; 
     
    /* Open wave file */ 
    hmmio = mmioOpen(szWaveFile, NULL, MMIO_READ | MMIO_ALLOCBUF); 
    if(!hmmio) 
    { 
        return 0; 
    } 
 
    /* Locate a 'RIFF' chunk with a 'WAVE' form type */ 
    mmckinfoParent.fccType = mmioFOURCC('W', 'A', 'V', 'E'); 
    if (mmioDescend(hmmio, (LPMMCKINFO) &mmckinfoParent, NULL, MMIO_FINDRIFF)) 
    { 
        mmioClose(hmmio, 0); 
        return 0; 
    } 
     
    /* Find the format chunk */ 
    mmckinfoSubchunk.ckid = mmioFOURCC('f', 'm', 't', ' '); 
    if (mmioDescend(hmmio, &mmckinfoSubchunk, &mmckinfoParent, MMIO_FINDCHUNK)) 
    { 
        mmioClose(hmmio, 0); 
        return 0; 
    } 
 
    /* Get the size of the format chunk, allocate memory for it */ 
    dwFmtSize = mmckinfoSubchunk.cksize; 
    lpWaveFormat = (WAVEFORMATEX *) calloc (1, dwFmtSize); 
    if (!lpWaveFormat) 
    { 
        mmioClose(hmmio, 0); 
        return 0; 
    } 
 
    /* Read the format chunk */ 
    if (mmioRead(hmmio, (LPSTR) lpWaveFormat, dwFmtSize) != (LONG) dwFmtSize) 
    { 
        free( lpWaveFormat ); 
        mmioClose(hmmio, 0); 
        return 0; 
    } 
     
    /* Ascend out of the format subchunk */ 
    mmioAscend(hmmio, &mmckinfoSubchunk, 0); 
     
    /* Find the data subchunk */ 
    mmckinfoSubchunk.ckid = mmioFOURCC('d', 'a', 't', 'a'); 
    if (mmioDescend(hmmio, &mmckinfoSubchunk, &mmckinfoParent, MMIO_FINDCHUNK)) 
    { 
        free( lpWaveFormat ); 
        mmioClose(hmmio, 0); 
        return 0; 
    } 
   
 
   
    /* Get the size of the data subchunk */ 
    dwDataSize = mmckinfoSubchunk.cksize; 
    if (dwDataSize == 0L) 
    { 
        free( lpWaveFormat ); 
        mmioClose(hmmio, 0); 
        return 0; 
    } 
         
    /* Allocate and lock memory for the waveform data. */ 
    lpWaveData = (LPSTR) calloc (1, dwDataSize ); 
    if (!lpWaveData) 
    { 
        free( lpWaveFormat ); 
        mmioClose(hmmio, 0); 
        return 0; 
    } 
 
    /* Read the waveform data subchunk */ 
    if(mmioRead(hmmio, (HPSTR) lpWaveData, dwDataSize) != (LONG) dwDataSize) 
    { 
        free(lpWaveFormat); 
        free(lpWaveData); 
        mmioClose(hmmio, 0); 
        return 0; 
    } 
 
    /* We're done with the file, close it */ 
    mmioClose(hmmio, 0); 
 
    /* Allocate a waveform data header */ 
    lpWaveHdr = (WAVEHDR *) calloc (1,(DWORD)sizeof(WAVEHDR)); 
    if (!lpWaveHdr) 
    { 
        free(lpWaveData); 
        free(lpWaveFormat); 
        return 0; 
    } 
 
    /* Set up WAVEHDR structure and prepare it to be written to wave device */ 
    lpWaveHdr->lpData = lpWaveData; 
    lpWaveHdr->dwBufferLength = dwDataSize; 
    lpWaveHdr->dwFlags = 0L; 
    lpWaveHdr->dwLoops = 0L; 
    lpWaveHdr->dwUser  = 0L; 
 
    /* make sure wave device can play our format */ 
    if (waveOutOpen((LPHWAVEOUT)NULL, 
                    (WORD)dw_devid, 
                    (LPWAVEFORMATEX)lpWaveFormat,  
                    0L, 0L, WAVE_FORMAT_QUERY)) { 
        free( lpWaveFormat ); 
        free(lpWaveData); 
        free(lpWaveHdr); 
        MessageBox (NULL, "Unsupported wave format.", "", MB_OK); 
        return 0; 
    } 
 
    /* open the wave device corresponding to the line */ 
    if (waveOutOpen (    &hWave,  
                        (WORD)dw_devid,  
                        (LPWAVEFORMATEX)lpWaveFormat,  
                        (DWORD)hWnd,  
                        0L,  
                        CALLBACK_WINDOW)) 
    { 
        free( lpWaveFormat ); 
        free(lpWaveData); 
        free(lpWaveHdr); 
        MessageBox (NULL, "Error opening wave device.", "", MB_OK); 
        return 0; 
    } 
   
    free( lpWaveFormat ); 
 
     /* prepare the message header for playing */ 
    if (waveOutPrepareHeader (hWave, lpWaveHdr, sizeof(WAVEHDR))) { 
       MessageBox (NULL, "Error preparing message header.", "", MB_OK); 
        free(lpWaveData); 
        free(lpWaveHdr); 
        return 0; 
    } 
 
    /* play the message right from the data segment;  set the play message flag */ 
    if (waveOutWrite (hWave, lpWaveHdr, sizeof (WAVEHDR))) { 
        MessageBox (NULL, "Error writing wave message.", "", MB_OK); 
        free(lpWaveData); 
        free(lpWaveHdr); 
        return 0; 
    } 
 
 
    return hWave; 
 
} /* end function (play message) */