📄 wave.cpp
字号:
#include <windows.h>
#include <mmsystem.h>
#include <stdio.h>
#include <TAPI.h>
#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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -