📄 playsnd.c
字号:
{ // 打开声音设备失败
RETAILMSG(1,("waveOutOpen Failure\r\n"));
// MessageBox(NULL,("WaveOutOpen"),("Error"),MB_OK);
ShowErrorCode(result);
bPlaying=FALSE;
// RETAILMSG(1,("***bPlaying %d\r\n",bPlaying));
return FALSE;
}
// 初始化数据结构
for (i=0;i<MAX_BUFFERNUM;i++)
{
// wh[i].lpData=NULL;
wh[i].dwBufferLength=0;
wh[i].dwBytesRecorded=0;
wh[i].lpNext=NULL;
//InsertFreewh(&wh[i]);
}
// RETAILMSG(1,(("WaveOutOpen Success %X\r\n"),hwo));
hPlayOverEvent = CreateEvent(NULL,0,0,NULL); // 创建一个播放完成事件
return TRUE;
}
static void AddBuffer(LPWAVEHDR lpwh)
{
MMRESULT result;
// RETAILMSG(1,(("AddBuffer ...\r\n")));
if (lpwh->dwBufferLength == 0)
{
// RETAILMSG(1,(("the buffer size == 0\r\n")));
return ;
}
lpwh->dwBytesRecorded=0;
lpwh->lpNext=NULL;
// RETAILMSG(1,(("waveOutPrepareHeader ...\r\n")));
result=waveOutPrepareHeader(hwo,lpwh,sizeof(WAVEHDR));
if (result!=MMSYSERR_NOERROR )
{
ShowErrorCode(result);
// RETAILMSG(1,("waveOutPrepareHeader Failure %d\r\n",result));
return ;
}
// RETAILMSG(1,(("waveOutWrite ...\r\n")));
result=waveOutWrite(hwo,lpwh,sizeof(WAVEHDR));
if (result!=MMSYSERR_NOERROR )
{
// RETAILMSG(1,("waveOutWrite Failure %d\r\n",result));
ShowErrorCode(result);
return ;
}
uPlayingNum ++;
// RETAILMSG(1,(("AddBuffer Success\r\n")));
}
static BOOL FillBuffer(LPWAVEHDR lpwh)
{
LPTSTR lpBuffer;
int dwReadLen;
// RETAILMSG(1,(("FillBuffer ... lpwh = %X\r\n"),lpwh));
if (hFile == INVALID_HANDLE_VALUE)
{
if (uPlayingNum == 0)
{
waveOutClose(hwo);
hwo = 0;
}
// RETAILMSG(1,(("The File Had not Open\r\n")));
return FALSE;
}
if (bStoping == TRUE)
{
CloseHandle(hFile);
hFile = INVALID_HANDLE_VALUE;
if (uPlayingNum == 0)
{
waveOutClose(hwo);
hwo = 0;
}
return FALSE;
}
if (lpwh->lpData == NULL)
{
lpBuffer = (LPTSTR)malloc(MAX_BUFFERLENGTH);
if (lpBuffer == NULL)
{
// RETAILMSG(1,(("Malloc Failure\r\n")));
return FALSE;
}
lpwh->lpData = lpBuffer;
// RETAILMSG(1,("malloc memory %x \r\n",lpwh->lpData));
}
else
{
lpBuffer = lpwh->lpData;
}
READAGAIN:
dwReadLen = g_stDataHeader.len - g_dwReadLen;
if (dwReadLen > MAX_BUFFERLENGTH)
dwReadLen = MAX_BUFFERLENGTH;
// RETAILMSG(1,(("Read Data From File ...\r\n")));
// RETAILMSG(1,(("hFile = %X\r\n"),hFile));
// RETAILMSG(1,(("lpBuffer = %X\r\n"),lpBuffer));
if (ReadFile(hFile,lpBuffer,dwReadLen,&dwReadLen,NULL) == FALSE)
{
CloseHandle(hFile);
hFile = INVALID_HANDLE_VALUE;
if (uPlayingNum == 0)
{
waveOutClose(hwo);
hwo = 0;
}
return FALSE;
}
if (dwReadLen == 0)
{
// RETAILMSG(1,(("Read File To End , and Close The File\r\n")));
if (g_fuSound & SND_LOOP)
{
g_dwReadLen = 0;
SetFilePointer(hFile,0,0,FILE_BEGIN);
goto READAGAIN;
}
// free(lpBuffer);
CloseHandle(hFile);
hFile = INVALID_HANDLE_VALUE;
if (uPlayingNum == 0)
{
waveOutClose(hwo);
hwo = 0;
}
return FALSE;
}
// RETAILMSG(1,(("Read Data From File OK !!!\r\n")));
lpwh->dwBufferLength = dwReadLen;
g_dwReadLen += dwReadLen;
//lpwh->dwFlags
// RETAILMSG(1,(("FillBuffer Success\r\n")));
return TRUE;
}
static BOOL GetSoundInfo(void )
{
// DWORD dwFileSize;
// RIFFHEADER stRiffHeader;
/// WAVEID stWaveID;
// CHUNKHEADER stChunkHeader;
if (GetRiffHeader(&g_stRiffHeader) == FALSE)
return FALSE;
if (GetWaveID(&g_stWaveID) == FALSE)
return FALSE;
if (GetChunkHeader(&g_stChunkHeader) == FALSE)
return FALSE;
if (GetDataHeader(&g_stDataHeader) == FALSE)
return FALSE;
return TRUE;
}
static BOOL GetRiffHeader(PRIFFHEADER pRiffHeader)
{
DWORD dwReadLen;
ReadFile(hFile,pRiffHeader->id,4,&dwReadLen,NULL);
if (dwReadLen != 4)
{
return FALSE;
}
if (strnicmp(pRiffHeader->id,"RIFF",4) != 0)
return FALSE;
ReadFile(hFile,&pRiffHeader->len,4,&dwReadLen,NULL);
return TRUE;
}
static BOOL GetWaveID(PWAVEID pWaveID)
{
DWORD dwReadLen;
ReadFile(hFile,pWaveID->id,4,&dwReadLen,NULL);
if (dwReadLen != 4)
{
return FALSE;
}
if (strnicmp(pWaveID->id,"WAVE",4) != 0)
return FALSE;
return TRUE;
}
static BOOL GetChunkHeader(PCHUNKHEADER pChunkHeader)
{
DWORD dwReadLen;
char *pRemainHeader;
ReadFile(hFile,pChunkHeader->id,4,&dwReadLen,NULL);
if (dwReadLen != 4)
{
return FALSE;
}
if (strnicmp(pChunkHeader->id,"fmt ",4) != 0)
{
if (strnicmp(pChunkHeader->id,"data",4) != 0)
return FALSE;
}
ReadFile(hFile,&pChunkHeader->len,4,&dwReadLen,NULL);
if (pChunkHeader->len == 0)
return FALSE;
pRemainHeader = (char *)malloc(pChunkHeader->len);
if (pRemainHeader == NULL)
return FALSE;
ReadFile(hFile,pRemainHeader,pChunkHeader->len,&dwReadLen,NULL);
if (pChunkHeader->len != dwReadLen)
return FALSE;
pChunkHeader->common_field.wFormatTag = MAKEWORD(pRemainHeader[0],pRemainHeader[1]);
if (pChunkHeader->common_field.wFormatTag != WAVE_FORMAT_PCM)
{
free(pRemainHeader);
return FALSE;
}
pChunkHeader->common_field.wChannels = MAKEWORD(pRemainHeader[2],pRemainHeader[3]);
pChunkHeader->common_field.dwSamplesPerSec = *(DWORD *)&pRemainHeader[4];
pChunkHeader->common_field.dwAvgBytesPerSec = *(DWORD *)&pRemainHeader[8];
pChunkHeader->common_field.wBlockAlign = MAKEWORD(pRemainHeader[12],pRemainHeader[13]);
pChunkHeader->PCM_format_specific.wBitsPerSample = MAKEWORD(pRemainHeader[14],pRemainHeader[15]);
free(pRemainHeader);
return TRUE;
}
static BOOL GetDataHeader(PDATAHEADER pDataHeader)
{
DWORD dwReadLen;
NextID:
ReadFile(hFile,pDataHeader->id,4,&dwReadLen,NULL);
if (dwReadLen != 4)
{
return FALSE;
}
if (strnicmp(pDataHeader->id,"data",4) != 0)
{
// Have other chunk
DWORD len, i;
BYTE bData;
ReadFile(hFile,&len,4,&dwReadLen,NULL);
for (i = 0; i< len ; i++)
ReadFile(hFile,&bData,1,&dwReadLen,NULL);
goto NextID;
}
ReadFile(hFile,&pDataHeader->len,4,&dwReadLen,NULL);
return TRUE;
}
// ********************************************************************
// 声明:DWORD WINAPI Audio_ASyncProc(VOID * pParam)
// 返回值:
// 成功返回TRUE,失败返回FALSE
// 功能描述:sndPlaySound处理异步操作时等待播放完成时的进程
// 引用:
// ********************************************************************
static DWORD WINAPI Audio_ASyncProc(VOID * pParam)
{
// int i;
// while(bPlaying == TRUE)
WaitForSingleObject(hPlayOverEvent,INFINITE);
/* for (i=0;i<MAX_BUFFERNUM;i++)
{
if (wh[i].lpData)
{
RETAILMSG(1,("free memory %x \r\n",wh[i].lpData));
free(wh[i].lpData);
wh[i].lpData = NULL;
}
}
*/
// RETAILMSG(1,("Exit hThread \r\n"));
bStoped = TRUE;
return TRUE;
}
static void ShowErrorCode(MMRESULT result)
{
switch(result)
{
case MMSYSERR_INVALHANDLE:
// MessageBox(NULL,TEXT("Specified device handle is invalid. "),TEXT("Error"),MB_OK);
RETAILMSG(1,(TEXT("Specified device handle is invalid. \r\n")));
break;
case MMSYSERR_NODRIVER:
// MessageBox(NULL,TEXT("No device driver is present. "),TEXT("Error"),MB_OK);
RETAILMSG(1,(TEXT("No device driver is present. \r\n")));
break;
case MMSYSERR_NOMEM:
// MessageBox(NULL,TEXT("Unable to allocate or lock memory. "),TEXT("Error"),MB_OK);
RETAILMSG(1,(TEXT("Unable to allocate or lock memory. \r\n")));
break;
case MMSYSERR_NOTSUPPORTED:
// MessageBox(NULL,TEXT("Specified device is synchronous and does not support pausing."),TEXT("Error"),MB_OK);
RETAILMSG(1,(TEXT("Specified device is synchronous and does not support pausing.\r\n")));
break;
case MMSYSERR_ALLOCATED:
// MessageBox(NULL,TEXT("Specified resource is already allocated. "),TEXT("Error"),MB_OK);
RETAILMSG(1,(TEXT("Specified resource is already allocated. \r\n")));
break;
case MMSYSERR_BADDEVICEID:
// MessageBox(NULL,TEXT(" Specified device identifier is out of range. "),TEXT("Error"),MB_OK);
RETAILMSG(1,(TEXT(" Specified device identifier is out of range. \r\n")));
break;
case WAVERR_BADFORMAT:
// MessageBox(NULL,TEXT(" Attempted to open with an unsupported waveform-audio format. "),TEXT("Error"),MB_OK);
RETAILMSG(1,(TEXT(" Attempted to open with an unsupported waveform-audio format. \r\n")));
break;
case WAVERR_SYNC :
// MessageBox(NULL,TEXT("The device is synchronous but waveOutOpen was called without using the WAVE_ALLOWSYNC flag."),TEXT("Error"),MB_OK);
RETAILMSG(1,(TEXT("The device is synchronous but waveOutOpen was called without using the WAVE_ALLOWSYNC flag.\r\n")));
break;
default:
// MessageBox(NULL,TEXT("No Name Error."),TEXT("Error"),MB_OK);
RETAILMSG(1,(TEXT("No Name Error.(%d)\r\n"),result));
break;
}
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -