📄 waveplay.cpp
字号:
#include <windows.h>
#include <mmsystem.h>
#include <stdio.h>
#include <tapi.h>
#include "WavePlay.h"
//---------------------------------------------------------------------------
//play wave by WavePlay
//---------------------------------------------------------------------------
HWAVEOUT WavePlay(DWORD nID, LPSTR lpFileName ,LPLINEINFO pLineData)
{
WAVEFORMATEX *lpWaveFormat = NULL;
WAVEHDR *lpWaveHdr = NULL;
HMMIO hmmioH;
HWAVEOUT hWaveOut = NULL;
MMCKINFO mmParent, mmSubchunk;
DWORD dwFmtSize, dwDataSize, dwFlags;
HPSTR lpWaveData = NULL;
MMRESULT mmrc;
HPSTR lpWaveDataLock;
// Open wave file
hmmioH = mmioOpen(lpFileName, NULL, MMIO_READ);
if(!hmmioH)
{
printf("\n###Line %d Input WAVE file open failed",pLineData->nLineID);
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);
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);
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);
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);
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);
mmioClose(hmmioH, 0);
goto PlayFailed;
}
// Get the size of the data subchunk
dwDataSize = mmSubchunk.cksize;
if (dwDataSize == 0L)
{
printf("###Line %d No data to play",pLineData->nLineID);
mmioClose(hmmioH, 0);
goto PlayFailed;
}
// Allocate and lock memory for the waveform data.
lpWaveData = (HPSTR) LocalReAlloc(pLineData->lpWaveDataAlloc, dwDataSize, 0);
if (!lpWaveData)
{
printf("\n###Line %d Memory alloc for data to play failed",pLineData->nLineID);
mmioClose(hmmioH, 0);
goto PlayFailed;
}
// Read the waveform data subchunk
pLineData->lpWaveDataAlloc = lpWaveData;
lpWaveDataLock = (HPSTR) LocalLock(lpWaveData);
if(mmioRead(hmmioH, (HPSTR) lpWaveDataLock, dwDataSize) != (LONG) dwDataSize)
{
printf("\n###Line %d Data read failed",pLineData->nLineID);
mmioClose(hmmioH, 0);
goto PlayFailed;
}
// We read done with the file, close it
mmioClose(hmmioH, 0);
// Allocate a waveform data header
lpWaveHdr = (WAVEHDR *) malloc((DWORD)sizeof(WAVEHDR));
if (!lpWaveHdr)
{
printf("\n###Line %d Memory alloc for WAVE header failed",pLineData->nLineID);
goto PlayFailed;
}
// Set up WAVEHDR structure and prepare it to be written to wave device
lpWaveHdr->lpData = lpWaveDataLock;
lpWaveHdr->dwBufferLength = dwDataSize;
lpWaveHdr->dwFlags = 0L;
lpWaveHdr->dwLoops = 0L;
lpWaveHdr->dwUser = (DWORD) nID;
/* make sure wave device can play our format */
dwFlags = WAVE_FORMAT_QUERY | WAVE_MAPPED;
if (mmrc = waveOutOpen((LPHWAVEOUT)NULL, nID, lpWaveFormat,
0L, 0L, dwFlags))
{
printf("\n###Line %d First waveOutOpen failed error# %x",pLineData->nLineID, mmrc);
goto PlayFailed;
}
dwFlags = CALLBACK_FUNCTION | WAVE_MAPPED; //NO CALLBACK
//open the wave device corresponding to the line
if (mmrc = waveOutOpen (&hWaveOut, nID, lpWaveFormat,
(DWORD)WavePlayCallBack, (DWORD)pLineData, dwFlags))
{
printf("\n###Line %d opening wave device error #%x",pLineData->nLineID, mmrc);
goto PlayFailed;
}
//prepare the message header for playing
if (waveOutPrepareHeader (hWaveOut, lpWaveHdr, sizeof(WAVEHDR)))
{
printf("\n###Line %d error preparing message header",pLineData->nLineID);
goto PlayFailed;
}
// Set the volume before playing
waveOutSetVolume(hWaveOut, 0x8888); //volume 0x0000 ~ 0xffff
// play the message right from the data segment; set the play message flag
if (waveOutWrite (hWaveOut, lpWaveHdr, sizeof (WAVEHDR)))
{
printf("\n###Line %d error writing wave message",pLineData->nLineID);
goto PlayFailed;
}
printf("\nLine %d play %s...",pLineData->nLineID,lpFileName);
pLineData->lpWaveHdr = lpWaveHdr;
free( lpWaveFormat );
lpWaveFormat = NULL;
return hWaveOut;
PlayFailed:
if(lpWaveFormat) free( lpWaveFormat );
if(lpWaveDataLock) LocalUnlock(lpWaveData);
if(lpWaveHdr) free(lpWaveHdr);
if(hWaveOut) waveOutClose(hWaveOut);
return NULL;
}
void CALLBACK WavePlayCallBack( HWAVEOUT hwo, UINT uMsg, DWORD dwInstance,
DWORD dwParam1, DWORD dwParam2)
{
LPLINEINFO pLineData = (LPLINEINFO)dwInstance;
if ( uMsg == WOM_DONE ) //0x3BD
{
if (pLineData->dwCallState == TAPI_PLAYGREET) //check playing?
lineSetAppSpecific(pLineData->hCall, TAPI_SETAPP_ENDPLAYGREET);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -