📄 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) */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -