怎样实现多个wav文件的顺序播放,并且要求能够随时暂停。

lzh975 2003-08-20 10:07:02
怎样实现多个wav文件的顺序播放,并且要求能够随时暂停。

请给出较为详细的代码说明,非常谢谢!
...全文
157 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
shiqi001 2003-08-21
  • 打赏
  • 举报
回复
我这儿有一个,给你参考一下吧。

// commci.h: interface for the commci class.

//

//////////////////////////////////////////////////////////////////////

#if !defined(AFX_COMMCI_H__90CEFD04_CC96_11D1_94F8_0000B431BBA1__INCLUDED_)

#define AFX_COMMCI_H__90CEFD04_CC96_11D1_94F8_0000B431BBA1__INCLUDED_



#if _MSC_VER >= 1000

#pragma once

#endif // _MSC_VER >= 1000



//#include <windows.h>

#include <mmsystem.h>



class COMMCI

{

private:

HWND hOwer; //窗口的拥有者

MCI_OPEN_PARMS mciOpen;



public:

COMMCI();

~COMMCI() {Close(); }

MCIERROR Open(LPCSTR DeviceType,LPCSTR filename);

//通过描述字符串打开设备

MCIERROR Open(int DeviceType,LPCSTR filename); //通过设备类型打开设备

MCIERROR Open(LPCSTR filename); //自动检测设备

void Play(HWND hWnd); //播放MCI,hWnd为回调窗口句柄

void Close(void); //关闭设备

void Stop(void); //停止设备

void Pause(void); //暂停设备

DWORD Query(); //检测设备

};



/////////////////////////////////////////////////////////

// COMMCI.CPP 中使用到的结构

/////////////////////////////////////////////////////////

//typedef struct tagMCI_OPEN_PARMS {

// DWORD dwCallback;

// MCIDEVICEID wDeviceID;

// WORD wReserved0;

// LPCSTR lpstrDeviceType;

// LPCSTR lpstrElementName;

// LPCSTR lpstrAlias;

//} MCI_OPEN_PARMS, FAR *LPMCI_OPEN_PARMS;



//typedef struct tagMCI_PLAY_PARMS {

// DWORD dwCallback;

// DWORD dwFrom;

// DWORD dwTo;

//} MCI_PLAY_PARMS, *PMCI_PLAY_PARMS, FAR *LPMCI_PLAY_PARMS;



//typedef struct tagMCI_STATUS_PARMS {

// DWORD dwCallback;

// DWORD dwReturn;

// DWORD dwItem;

// DWORD dwTrack;

//} MCI_STATUS_PARMS, *PMCI_STATUS_PARMS,

FAR * LPMCI_STATUS_PARMS;







//////////////////////////////////////////////////////////

// mci 初始化方式

//////////////////////////////////////////////////////////

//COMMCI.Open("waveaudio",filename); wave ; *.wav ,

//COMMCI.Open("sequencer",filename); midi ; *.mid , *.rmi

//COMMCI.Open("reelmagic",filename); vcd ; *.mpg ,

//COMMCI.Open("avivideo",filename); avi ; *.avi ,





/////////////////////////////////////////////////////////

// mci 状态返回值

/////////////////////////////////////////////////////////

// case MCI_MODE_NOT_READY:

// case MCI_MODE_STOP:

// case MCI_MODE_PLAY:

// case MCI_MODE_RECORD:

// case MCI_MODE_SEEK:

// case MCI_MODE_PAUSE:

// case MCI_MODE_OPEN:



#endif // !defined(AFX_COMMCI_H__90CEFD04_CC96_11D1_94F8_0000B431BBA1__INCLUDED_)





// commci.cpp: implementation of the commci class.

//

//////////////////////////////////////////////////////////////////////



#include "stdafx.h"

//#include "mcitest.h"

#include "commci.h"



#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[]=__FILE__;

#define new DEBUG_NEW

#endif



//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////



COMMCI::COMMCI()

{

memset(this,0,sizeof(COMMCI));

}



MCIERROR COMMCI::Open(LPCSTR DeviceType,LPCSTR filename)

{

//如果有打开的设备就关闭

if (mciOpen.wDeviceID) Close();

//初始化MCI_OPEN_PARMS结构

mciOpen.lpstrDeviceType=DeviceType;

mciOpen.lpstrElementName=filename;

//除了打开设备设备代码为0,下面的任何mciSendCommand语句都要指定设

//备代码。

if ( mciSendCommand(NULL,MCI_OPEN,

MCI_OPEN_TYPE | MCI_OPEN_ELEMENT,

(DWORD)&mciOpen))

return FALSE;

return TRUE;

}



MCIERROR COMMCI::Open(LPCSTR filename)

{

if (mciOpen.wDeviceID) Close();

mciOpen.lpstrElementName=filename;

if ( mciSendCommand(NULL,MCI_OPEN,

/*MCI_OPEN_TYPE |*/ MCI_OPEN_ELEMENT,

(DWORD)&mciOpen))

return FALSE;

return TRUE;

}



MCIERROR COMMCI::Open(int DeviceType,LPCSTR filename)

{

if (mciOpen.wDeviceID) Close();

mciOpen.lpstrDeviceType=(LPCSTR)DeviceType;

mciOpen.lpstrElementName=filename;

return mciSendCommand(NULL,MCI_OPEN,

MCI_OPEN_TYPE | MCI_OPEN_TYPE_ID ,(DWORD)&mciOpen);

}



void COMMCI::Play(HWND hWnd)

{

MCI_PLAY_PARMS mciPlay;

hOwer=hWnd; //回调窗口句柄

//MCI_PLAY_PARMS结构只需要设定回调窗口句柄

mciPlay.dwCallback=(WORD)hOwer;

mciSendCommand(mciOpen.wDeviceID,MCI_PLAY,MCI_NOTIFY,

(DWORD)&mciPlay);

}



void COMMCI::Close(void)

{

if (mciOpen.wDeviceID)

mciSendCommand(mciOpen.wDeviceID,MCI_CLOSE,NULL,NULL);

memset(this,0,sizeof(COMMCI));

}



void COMMCI::Stop(void)

{

if (mciOpen.wDeviceID)

mciSendCommand(mciOpen.wDeviceID,MCI_STOP,NULL,NULL);

}



void COMMCI::Pause(void)

{

if (mciOpen.wDeviceID)

mciSendCommand(mciOpen.wDeviceID,MCI_PAUSE,NULL,NULL);

}





DWORD COMMCI::Query()

{

MCI_STATUS_PARMS mciStatus;

mciStatus.dwItem=MCI_STATUS_MODE;

mciSendCommand(mciOpen.wDeviceID,MCI_STATUS,

MCI_STATUS_ITEM,(LPARAM)&mciStatus);

return mciStatus.dwReturn;

};









对于类COMMCI定义了如下几个成员函数:

· 一个构造函数和一个析构函数。

· 一个打开函数,其参数分别是要打开设备的类型和文件名。

· 播放函数,其参数是回调函数句柄。

· 关闭函数。

· 停止函数。

· 暂停函数。

· 状态检测函数。



在一个MCI的处理过程中,必须使用以下流程:

· 打开一个MCI设备。

· 然后Open播放MCI设备,其间可以暂停和停止播放,

· 最后关闭MCI设备。

在以上任何步骤中,都可以用状态检测函数检测工作状态。

下面我们看一下MCI的实现过程:

1. OPEN MCI

首先,我们 初始化一个MCI_OPEN_PARMS的结构,其中要用到两个值。

其中mciOpen.lpstrDeviceType指定了要打开的设备类型,这些设备类型可从前面的“MCI设备类型”选取。可以是标识或描述字符串,例如语句mciOpen.LpstrDeviceType=MCI_DEVTYPEVCR与语句mciopen.LpstrDeviceType="Vcr"是等价的。若不指定类型则计算机将根据文件名自动识别设备,接下来mciOpen.LpstrElimmentName指定了要打开的文件名,最后调用MciSendComand指定计算机将在结构的wDeviceID中填入打开的设备代码;以后应用程序将根据此设备代码访问MCI设备。



这里谈一下三种打开方式的区别:

[1]:自动识别:打开一个"WAV"文件

MCI_OPEN_PARMS mciOpen;

mciOpen.lpstrDeviceType=0;

mciOpen.lpstrElementName="aaa.wav";

mciSendCommand(NULL,MCI_OPEN, MCI_OPEN_ELEMENT,

(DWORD)&mciOpen);



[2]:指定设备描述:打开CD播放器

MCI_OPEN_PARMS mciOpen;

mciOpen.lpstrDeviceType=(LPSTR)MCI_DEVTYPE_CD_AUDIO ;

mciSendCommand(NULL,MCI_OPEN,MCI_OPEN_TYPE | MCI_OPEN_TYPE_ID,

(DWORD)&mciOpen);



[3]:指定描述字符串: 打开一个AVI文件

MCI_OPEN_PARMS mciOpen;

mciOpen.lpstrDeviceType="avivideo";

mciOpen.lpstrElementName="aaa.avi";

mciSendCommand(NULL,MCI_OPEN,MCI_OPEN_TYPE

| MCI_OPEN_ELEMENT,

(DWORD)&mciOpen);

请注意mciSendCommand函数第三个参数的区别:

MCI_OPEN_TYPE:表示要使用MCI_OPEN_PARMS结构中的LpstrDiviceType参数,这可区分指定设备打开方式和自动识别方式之间的区别。在自动方式中,不需使用LpstrDeviceType参数。因此,也不需指定MCI_OPEN_TYPE。

MCI_OPEN_ELEMENT:表示LpstrDeviceType参数中的是设备表述字符串。

MCI_OPEN_TYPE_ID:表示LpstrDeviceType参数中的是设备描述。



2 PlayMci:

在play函数中,需要一个返回窗口句柄,以便应用程序在播放结束后向此窗口发送一个消息,告诉窗口已经播放结束。我们首先初始化一个MCI_PLAY_PARMS的数据结构:将其中dwCallback参数赋与窗口句柄。然后调用mciSendCommend,当然发送的指令是MCI_PLAY,告诉系统开始播放,另外第三个参数指定MCI_NOTIFY,告诉系统播放完后要通知自己。
lzh975 2003-08-21
  • 打赏
  • 举报
回复
高手都上哪儿去了?
我Ding.
lzh975 2003-08-20
  • 打赏
  • 举报
回复
我看了,尤其是有关mci编程的帮助。
但是,没有找到一种能够满足要求的方法,请问你还能说的再详细些吗?
非常谢谢!!!
michaelwan 2003-08-20
  • 打赏
  • 举报
回复
Platform SDK: Windows Multimedia 看看吧
lzh975 2003-08-20
  • 打赏
  • 举报
回复
今晚高手们是不是看中国队的足球比赛了?
快帮帮我吧。
特别急!!
谢谢!!

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

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