声音播放问题?

onestation 2006-03-12 09:18:39
在线程中使用
::sndPlaySoundA(
"sound\\1.wav", SND_SYNC|SND_FILENAME);
播放声音,当声音正在播放时关闭程序,窗口关闭,但程序常驻内存不能退出,如何解决?
...全文
413 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
onestation 2006-03-15
  • 打赏
  • 举报
回复
最后不是声音的问题,是程序没有调用exit(0)
Jimmy_Xia 2006-03-14
  • 打赏
  • 举报
回复
class CWave:public CObject
{
//Construction
public:
CWave();
virtual ~CWave();

//Operations
public:
DWORD OpenDevice();
DWORD CloseDevice();
DWORD Play(CWnd *pParentWnd,LPCSTR pFileName);
DWORD Stop();

//Implementation
protected:
void DisplayErrorMsg(DWORD dwError);

//Members
protected:
MCIDEVICEID m_nDeviceID;
MCIDEVICEID m_nElementID;
};

//Cwave类的实现代码,Cwave.cpp
#include <stdafx.h>
#include "cwave.h"

CWave::CWave()
{
m_nDeviceID=0;
m_nElementID=0;
}

CWave::~CWave()
{
if(m_nElementID)
Stop();
if(m_nDeviceID)
CloseDevice();
}

DWORD CWave::OpenDevice()
{
DWORD dwResult=0;

if (m_nDeviceID)
{
MCI_OPEN_PARMS mciOpenParms;

mciOpenParms.lpstrDeviceType=(LPSTR)MCI_DEVTYPE_WAVEFORM_AUDIO;

//open the wave device
dwResult = mciSendCommand(NULL,
MCI_OPEN,
MCI_OPEN_TYPE|MCI_OPEN_TYPE_ID|MCI_WAIT,
(DWORD)(LPVOID)&mciOpenParms);

//save device identifier,will use eith other MCI commands
m_nDeviceID = mciOpenParms.wDeviceID;

//display error message if failed
if(dwResult)
DisplayErrorMsg(dwResult);
}
//return result of MCI operation
return dwResult;
}

DWORD CWave::CloseDevice()
{
DWORD dwResult=0;

//close if currently open
if(m_nDeviceID)
{
//close the MCI device
dwResult=mciSendCommand(m_nDeviceID,MCI_CLOSE,NULL,NULL);

//display error message if failed
if(dwResult)
DisplayErrorMsg(dwResult);

//set identifier to close state
else
m_nDeviceID=0;
}

//return result of MCI operation
return dwResult;
}

DWORD CWave::Play(CWnd* pWnd,LPCSTR pFileName)
{
MCI_OPEN_PARMS mciOpenParms;
//initialize structure
memset(&mciOpenParms,0,sizeof(MCI_OPEN_PARMS));

//set the WAV file name to be played
mciOpenParms.lpstrElementName=pFileName;

//first open the device
DWORD dwResult=mciSendCommand(m_nDeviceID,MCI_OPEN,
MCI_OPEN_ELEMENT,(DWORD)(LPVOID)&mciOpenParms);

//display error message if failed
if(dwResult)
DisplayErrorMsg(dwResult);

//if successful,instruct the device to play the WAV file
else
{
//save element indentifier
m_nElementID=mciOpenParms.wDeviceID;

MCI_PLAY_PARMS mciPlayParms;

//set the window that will receive notification message
mciPlayParms.dwCallback=(DWORD)pWnd->m_hWnd;

//instruct device to play file
dwResult=mciSendCommand(m_nElementID,MCI_PLAY,
MCI_NOTIFY,(DWORD)(LPVOID)&mciPlayParms);

//display error and close element if failed
if(dwResult)
{
DisplayErrorMsg(dwResult);
Stop();
}
}

//return result of MCI operation
return dwResult;
}

DWORD CWave::Stop()
{
DWORD dwResult=0;

//close if element is currently open
if(m_nElementID)
{
dwResult=mciSendCommand(m_nElementID,MCI_CLOSE,NULL,NULL);

//display error message if failed
if(dwResult)
DisplayErrorMsg(dwResult);
//set identifier to closed state
else
m_nElementID=0;
}
return dwResult;
}

void CWave::DisplayErrorMsg(DWORD dwError)
{
//check if there was an error
if(dwError)
{
//character string that contains error message
char szErrorMsg[MAXERRORLENGTH];

//retrieve string associated error message
if(!mciGetErrorString(dwError,szErrorMsg,sizeof(szErrorMsg)))
strcpy(szErrorMsg,"Unknown Error");
//display error string in message box
AfxMessageBox(szErrorMsg);
}
}
Jimmy_Xia 2006-03-14
  • 打赏
  • 举报
回复
如何播放大型 WAV 文件?



作者:hermess





平时,你在多媒体软件的设计中是怎样处理声音文件的呢?使用Windows 提供的API函数 sndPlaySound来实现WAV文件的播放?但是,你有没有遇到过这种情况呢:当WAV文件大于可用内存时,sndPlaySound 函数就不能进行播放!!!那么,如何利用MCI播放大型音频文件呢?

本文将介绍一种方法。

Windows支持两种RIFF(resource interchange file format,“资源交互文件格式”)音 频文件:MIDI的RMID文件和波形音频文件格式WAV文件,本文将介绍如何用MCI命令播放大型W AV文件。用sndPlaySound播放音频文件只需要一行代码。比如实现异步播放的方法为 sndPlaySound("c:\windows\ding.wav",SND_ASYNC);
由此可以看到,sndPlaySound 的使用是很简单的。但是用sndPlaySound播放音频文件有 一个限制,即整个音频文件必须全部调入可用的物理内存。因此应用sndPlaySound播放的音频 文件相对较小,最大约100K。要播放大一些的音频文件(在多媒体设计中是经常要遇到的情况 )需要使用MCI的功能。这里创建了一个Cwave类,可以处理播放音频的MCI命令,因为该类能够 执行很多的MCI命令和建立了数据结构,所以只需要简单的成员函数(如OpenDevice, CloseDe vice, Play和Stop)。在CWave类中抽象了特定的MCI命令和数据结构,只含几个简单的成员函 数OpenDevice, CloseDevice, Play和Stop。波形音频设备是一个复合设备,如果打开波形设 备,然后打开并关闭每个波形元素,最后关闭波形设备,这样可以使得播放性能更好。调用C wave::OpenDevice就可以打开波形设备,OpenDevice将MCI_OPEN命令传递给mciSendCommand函 数,如果调用成功,就用数据结构MCI_OPEN_PARMS的wDeviceID成员返回波形设备的标识符, 该标识符保存在一个供以后使用的私有数据成员中。一旦打开了Cwace对象,通过Cwace::Pla y播放WAV文件就就绪了,WAV文件名和一个窗口指针被传递给Play方法以便将MCI通知消息发送 到制定的窗口。
WAV文件的播放首先要通过分配一个MCI_OPEN_PARMS结构并给所要播放的WAV文件设置
lpstrElementName成员打开WAV文件。将该结构和MCI_OPEN传递给mciSendCommand,打开WAV文件 并用MCI_OPEN_PARMS结构的wDeviceID成员返回元素标识符。第二步是命令波形音频设备播放 WAV文件。分配了MCI_PLAY_PARMS结构并将dwCallback成员设置为窗口句柄。如果要同步播放 音频波形文件,就增加MCI_WAIT标志并跳过窗口句柄。这样做会使应用程序在mciSendComman d函数返回之前等待WAV文件播放完毕。最可能的情况是异步播放大型WAV文件,可以象下面那 样指定MCI_NOTIFY标志并设置dwCallback成员做到这一点。 MCI_PLAY_PARMS mciPlayParms;
MciPlayParms.dwCallback=(DWORD)pWnd->m_hWnd;
DwResult=mciSendCommand(m_nDevice,
MCI_PLAY,
MCI_NOTIFY,
(DWORD)(LPVOID)&mciPlayParms);

这样就开始了WAV文件的播放,并且在播放完毕后,MM_MCINOTIFY消息会发送到指定的窗口。一个WAV文件播放所发生的事件序列为:(1)命令播放WAV文件并立即返回;(2)播放WAV文 件;(3)完成后发送通知消息。
完成播放后关闭WAV文件元素是程序员的责任,简单的调用Cwave类的Stop成员函数就可以了。Stop成员函数将WAV文件标识符和MCI_CLOSE命令传递给mciSendCommand函数,不必为该命令分配一个MCI结构,下述代码关闭了WAV文件: mciSendCommand(m_nElement,MCI_CLOSE,NULL,NULL);

播放完所有的WAV文件后必须关闭波形音频设备,Cwave类的析构函数调用Cwave::Close Device自动完成。 将本文中介绍的CWave类加入到自己的程序中,就可以方便的应用它播放音频文件了。
//建立Cwave类,放在Wave.h文件中:
mythay 2006-03-13
  • 打赏
  • 举报
回复
那你应该在播放时不让退出。
不过你为什么不使用包装过的类呢,那样岂不是更好。
一条晚起的虫 2006-03-13
  • 打赏
  • 举报
回复
正在播放时不允许退出
onestation 2006-03-13
  • 打赏
  • 举报
回复
有没有其它办法啊?我需要的就是SND_SYNC!
rageliu 2006-03-13
  • 打赏
  • 举报
回复
up
onestation 2006-03-13
  • 打赏
  • 举报
回复
mythay(小黑) : 请问是哪个包装过的类?
DentistryDoctor 2006-03-12
  • 打赏
  • 举报
回复
SND_SYNC=>SND_ASYNC
striking 2006-03-12
  • 打赏
  • 举报
回复
SND_SYNC 改成 SND_ASYNC

异步播放。

15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧