使用MCI播放音频文件,MCI为程序员提供了两种方式访问MCI设备或文件:一种是基于消息的命令接口函数;另一种是使用字符串接口函数。两者的区别在于基本命令结构和发送信息到设备的原理。
◆、基于消息的MCI
消息命令控制接口使用消息控制MCI设备,将消息和控制信息以数据结构的形式作为函数参数发送,并接收返回的数据,MCI直接把设备消息和控制消息发送到设备。一条基于MCI的命令包含以下3个部分。
数据结构:该结构包含可传递给MCI驱动程序的信息和从驱动程序返回的值,指定要执行的MCI命令一个常量,如MCI_OPEN、MCI_CLOSE...
一个或一组用来指定MCI信息子选项的标志:这些标志用来确定可以得到什么类型的信息和如何执行函数。
一个确定命令附加参数:Windows MDK为使用命令消息接口发送MCI消息提供了3个核心函数。
1、mciSendCommand函数。该函数用于向MCI设备发送一个命令消息,原型为:
MCIERROR mciSendCommand(MCIDEVICEID IDDevice, UINT uMsg, DWORD fdwCommand, DWORD dwParam);
参数说明如下:
IDDevice:用来表示一个MCI设备。MCI使用MCI_OPEN消息打开一个设备时自动创建一个标识号用以唯一标识要操作的设备,以后的命令操作均使用此标识。
uMsg:表示要发出的消息,取值如下所示。
MCI_OPEN 打开一个设备
MCI_CLOSE 关闭一个设备
MCI_PLAY 播放全部或部分音频,从暂停状态恢复播放
MCI_STOP 停止播放
MCI_PAUSE 暂停播放
MCI_SEEK 改变当前位置
MCI_CUE 提示一个设备以最小的延迟开始播放或录制
MCI_RECORD 在一个设备上开始录制
MCI_SAVE 保存一个文件
MCI_INFO 查询设备信息,如产品名称等
MCI_GETDEVCAPS 查询产品特征,如设备类型等
MCI_STATUS 查询设备当前状态,如播放位置、媒体格式等
MCI_SET 设置设备参数,如时间格式、波形数据格式等
fdwCommand:消息指定标志。
dwParam:指定一个指向消息数据结构的指针。
如果mciSendCommand函数调用成功则返回0,否则返回错误代码消息。所返回的DWORD低位字是错误代码,可以将它发送到mciGetErrorString函数,已获得对错误的文本描述。若错误事设备特有的,高位包含了设备ID,否则高位为0。
MMSYSTEM.H头文件中还定义了MCI命令所需要的数据结构类型。以下是MCI命令常用的数据结构。
MCI_OPEN_PARMS MCI_OPEN命令消息参数的数据结构
MCI_PLAY_PARMS MCI_PLAY命令消息参数的数据结构
MCI_RECORD_PARMS MCI_RECORD命令消息参数的数据结构
2、mciGetDevicelID函数。当打开一个设备时,该函数用来获得此设备的ID,原型为:
MCIDEVICEID mciGetDevicelID(LPCTSTR lpszDevice);
参数lpszDevice指定要打开的MCI设备名。若函数调用成功,则返回设备的标志号,否则返回0。
3、mciGetErrorString函数。该函数用于返回一个错误代码的文本描述,原型为:
BOOL mciGetErrorString(DWORD fdwError, LPTSTR lpszErrorText, UINT cchErrorText);
参数说明如下:
fdwError:上一次mciSendCommand函数调用的返回值。
lpszErrorText:用来接收返回的文本描述的缓冲区指针。
cchErrorText:指定lpszErrorText的长度。
◆、基于字符串的MCI
命令字符串接口使用文本命令控制MCI设备。文本串中包含执行一个命令所需要的所有信息。MCI分析文本串,并把它翻译成命令消息接口中的消息和控制信息。由于加入了翻译过程,命令字符串接口的速度要慢于命令消息接口。
Windows也为字符串接口定义了3个核心操作函数。
1、mciSendString函数。该函数用于向一个MCI的设备驱动程序发送一个字符串,原型为:
MCIERROR mciSendString(LPCTSTR lpszCommand, LPTSTR lpszReturnString, UINT cchReturn, HANDLE hwndCallback);
参数说明如下:
lpszCommand:一个以NULL结尾的定义MCI控制命令的字符串,格式为:command device_name argument
lpszReturnString:一个远指针,它指向由应用程序返回的字符串缓冲区。
cchReturn:指定了缓冲区大小。
hwndCallback:用来指定接收并处理MCI向应用程序发出的MM_MCINOTIFY消息窗口的句柄。
函数成功调用,则返回0,否则返回错误代码。可以将错误代码传递给mciGetErrorString函数获得对错误的文本描述。
2、mciGetErrorString函数。前面已作了介绍,这里不再叙述。
3、mciExecute函数。实际上是mciSendString函数的简化形式,它不占用缓冲区来返回消息。如果调用失败,则显示出错信息消息框,原型为:
BOOL FAR PASCAL mciExecute(LPCTSTR lpszDevice);
参数lpszDevice与mciSendString函数的第一个参数含义相同。
使用MCI对多媒体进行操作实际上是向设备发送相应的命令。下面介绍各种常用的操作。
◆、打开多媒体设备
使用MCI_OPEN命令消息来打开设备。所有的设备对于MCI命令都需要一个指向消息命令数据结构MCI_OPEN_PARMS的指针。该结构格式如下:
typedef struct _MCI_OPEN_PARMS
{
DWORD dwCallback; //设置MCI_NOTIFY标志时的回调窗口句柄
MCIDEVICEID wDeviceID; //打开设备成功时返回的设备标识号
LPCSTR lpstrDeviceType; //指定所要打开设备类型
LPCSTR lpstrElementName; //对于复合设备,指定设备元素
LPCSTR lpstrAlias; //设备别名
} MCI_OPEN_PARMS;
简单设备和复合设备打开方式有所不同。打开简单设备时,不需要指定设备元素。可以用3种方法打开一个简单设备。
1、指定设备名。下面一段代码通过指定设备名打开一个光盘设备。
WORD wDeviceID;
MCI_OPEN_PARMS mciOpenParms;
//为MCI_OPEN消息数据结构赋值
mciOpenParms.lpstrDeviceType = "cdaudio";
//通过指定设备名打开光盘设备
if (micSendCommand(NULL, MCI_OPEN, MCI_OPEN_TYPE, (DWORD)(LPVOID)&mciOpenParms))
//调用失败的处理
else
wDeviceID = mciOpenParms.wDeviceID;
2、指定设备驱动程序。下面一段代码通过指定设备的驱动程序打开一个光盘设备。
WORD wDeviceID;
MCI_OPEN_PARMS mciOpenParms;
//为MCI_OPEN消息数据结构赋值
mciOpenParms.lpstrDeviceType = "mcicd.drv";
//通过指定设备名打开光盘设备
if (micSendCommand(NULL, MCI_OPEN, MCI_OPEN_TYPE, (DWORD)(LPVOID)&mciOpenParms))
//调用失败的处理
else
wDeviceID = mciOpenParms.wDeviceID;
3、指定设备类型参数。各个MCI设备的设备类型常量如下所示。
MCI命令能够管理的音频设备类型所对应的字符串和常量
cdaudio MCI_DEVTYPE_CD_AUDIO
waveaudio MCI_DEVTYPE_WAVEFORM_AUDIO
sequencer MCI_DEVTYPE_SEQUENCER
animation MCI_DEVTYPE_ANIMATION
dat MCI_DEVTYPE_DAT
digitalvideo MCI_DEVTYPE_DIGITAL_VIDEO
other MCI_DEVTYPE_OTHER
scanner MCI_DEVTYPE_SCANNER
vcr MCI_DEVTYPE_VCR
videodisc MCI_DEVTYPE_VIDEODISC
MPEGAudio MP3播放类型(常量不清楚,只知道字符串)
下面一段代码通过指定设备的类型参数打开一个光盘设备。
WORD wDeviceID;
MCI_OPEN_PARMS mciOpenParms;
//为MCI_OPEN消息数据结构赋值
mciOpenParms.lpstrDeviceType = (LPRSTR) MCI_DEVTYPE_CD_AUDIO;
//通过指定设备名打开光盘设备
if (micSendCommand(NULL, MCI_OPEN, MCI_OPEN_TYPE, (DWORD)(LPVOID)&mciOpenParms))
//调用失败的处理
else
wDeviceID = mciOpenParms.wDeviceID;
打开复合设备需要指定设备元素,也可以用3种方法打开一个复合设备。
1、只指定设备。该方法类似于打开简单设备,但只适合用于MCI_GETDEVCAPS命令确定设备性能。
2、同时指定设备和设备元素。该方法需要指出设备元素。举例如下:
WORD wDeviceID;
MCI_OPEN_PARMS mciOpenParms;
//为MCI_OPEN消息数据结构赋值
mciOpenParms.lpstrElementName = "c:\windows\media\chorcd.wav";
//通过指定设备元素参数打开复合设备
if (micSendCommand(NULL, MCI_OPEN, MCI_OPEN_TYPE, (DWORD)(LPVOID)&mciOpenParms))
//调用失败的处理
else
wDeviceID = mciOpenParms.wDeviceID;
3、只指定设备元素。在此方式下,MCI根据WIN.INI文件中的[mci extension]字段,从设备的扩展名确定设备。例如:
#define wPtnLength 255; //缓冲区大小
char lpstrRtnString[wPtnLength]; //指向缓冲区指针
WORD result;
result = mciSendString("open cdaudio", lpstrRtnString, wPtnLength, NULL);
//打开CD设备
if (result != 0)
mciGetErrorString(result, lpstrRtnString, wPtnLength)
//事件处理
else
//设备成功打开后事件处理
下面一段代码用来打开一个多媒体复合设备。
#define wPtnLength 255; //缓冲区大小
char lpstrRtnString[wPtnLength]; //指向缓冲区指针
WORD result;
result = mciSendString("c:\windows\media\chorcd.wav", lpstrRtnString, wPtnLength, NULL);
//打开CD设备
if (result != 0)
mciGetErrorString(result, lpstrRtnString, wPtnLength)
//事件处理
else
//设备成功打开后事件处理
◆、播放多媒体设备
在成功打开设备后,应用程序就可以通过向MCI发送MCI_PLAY或play字符串命令来播放多媒体设备。MCI_PLAY的数据结构MCI_PLAY_PARMS的格式如下:
typedef struc{
DWORD dwCallback; //设置MCI_NOTIFY标志时回调窗口句柄
DWORD dwFrom; //播放的起始位置
DWORD dwTo; //播放的结束位置
} MCI_PLAY_PARMS;
下面一段代码用来播放已打开的MCI设备。
WORD wDeviceID;
MCI_PLAY_PARMS mciPlayParams;
//为MCI_PLAY消息数据结构赋值
mciSendCommand(wDeviceID, MCI_PLAY, 0, (DWORD)(LPVOID)&mciPlayParams);
若不给MCI_PLAY_PARMS数据结构中的dwFrom和dwTo字段赋值,播放从头至尾进行。
而在使用play字符串命令时,如果play命令不加任何参数,则多媒体设备会从目前的位置播放到媒体或文件的结束。play命令支持From和To两个参数,它们分别指向起始和终止位置。实例如下:
#define wPtnLength 255; //缓冲区大小
char lpstrRtnString[wPtnLength]; //指向缓冲区指针
//播放CD从第10秒到第15秒位置
mciSendString("play cdaudio from 10000 to 15000", lpstrRtnString, wPtnLength, NULL);
◆、关闭媒体设备
应用程序在使用完一个打开的多媒体设备后,必须向MCI发送一个MCI_CLOSE消息来关闭设备。应该注意的是,在应用程序退出之前,应关闭所有的MCI设备。这时可以使用MCI_ALL_DEVICE_ID常量,只需一条命令就关闭所有的多媒体设备。下面一段代码演示了关闭所有设备。
mciSendCommand(MCI_ALL_DEVICE_ID, MCI_CLOSE, 0, NULL);
也可以使用close字符串命令关闭使用完的MCI设备。例如:
#define wPtnLength 255; //缓冲区大小
char lpstrRtnString[wPtnLength]; //指向缓冲区指针
mciSendString("close cdaudio", lpstrRtnString, wPtnLength, NULL);
与基于消息的命令一样,在退出应用程序之前,应关闭所有的设备,这时可以使用all参数,实例如下:
#define wPtnLength 255; //缓冲区大小
char lpstrRtnString[wPtnLength]; //指向缓冲区指针
mciSendString("close all", lpstrRtnString, wPtnLength, NULL);
◆、暂停多媒体播放
暂停多媒体播放可以通过向MCI发送MCI_PAUSE命令实现,实例如下:
WORD wDeviceID;
MCI_PLAY_PARMS mciPlayParam;
mciSendCommand(wDeviceID, MCI_PAUSE, NULL, (DWORD)(LPVOID)&mciPlayParam);
◆、获取和设置播放信息
在播放媒体时,很多时候需要获取播放信息,如波形音频的采样率、通道数和量化位数、CD音频文件总长度等。这时,可以通过向MCI发送MCI_STATUS命令实现。下面一段代码可以用来获取波形音频的采样率和通道数。
WORD wDeviceID;
MCI_STATUS_PARAM StatusParam;
StatusParam.dwItem = MCI_WAVE_STATUS_SAMPLESPERSEC;
mciSendCommand(wDeviceID, MCI_STATUS, MCI_WAIT | MCI_STATUS_ITTEM, &StatusParam);
DWORD samplerate = StatusParam.dwReturn; //该参数返回采样率
StatusParam.dwItem = MCI_WAVE_STATUS_CHANNLES;
mciSendCommand(wDeviceID, MCI_STATUS, MCI_WAIT | MCI_STATUS_ITTEM, &StatusParam);
DWORD channelnumber = StatusParam.dwReturn; //该参数返回通道数
也可以采用字符串命令的方式获得播放信息,实例如下:
MCIERROR mciError;
mciError = mciSendString("open waveaudio", buf, strlen(buf), NULL);
同样,在进行编程时,有时也需要对媒体设备的一些播放信息进行设置。这可以通过向已经打开的媒体设备发送MCI_SET命令实现。例如下面一段代码用来设置音频的播放格式为毫秒方式。
WORD wDeviceID;
MCI_SET_PARMS SetParam;
SetParam.dwFormat = MCI_FORMAT_MILLISECONDS;
DWORD OpenFlag = mciSendCommand(wDeviceID, MCI_SET, MCI_TIME_FORMT, &SetParam);
采用字符串命令设置媒体播放格式的代码如下:
MCIERROR mciError;
mciError = mciSendString("Set file format milliseconds", buf, strlen(buf), NULL);
◆、播放的跳转
在媒体播放过程中进行跳转首先需要声明一个MCI_SEEK_PARMS结构,并使用该结构的dwTo字段设定需要播放的位置,该位置以毫秒为单位。然后通过mciSendCommand函数向指定设备以MCI_TO为标志发送MCI_SEEK命令,如果只需要跳转到文件的开始或结束位置,可以直接使用MCI_SEEK_TO_START和MCI_SEEK_TO_END为标识发送MCI_SEEK命令。例如:
WORD wDeviceID;
int nMinute; //欲跳转的时间,以分钟为单位
MCI_SEEK_PARMS SeekParam;
SeekParam.dwTo = (nNinute*60+nSecond)*1000; //跳转的目标时间,以毫秒为单位
mciSendCommand(wDeviceID, MCI_SEEK, MCI_SEEK_TO | MCI_WAIT, (DWORD)(LPVOID)&SetParam);
下段代码通过MCI_SEEK命令使CD音频在nTrack轨道,第nMinute分钟,第nSecond秒的nFrame帧进行播放。
int nTrack, nMinute, nSecond;
WORD wDeviceID;
MCI_SEEK_PARMS SeekParam;
SeekParam.dwTo = MCI_MAKE_TWSF(nTrack, nMinute, nSecond, nFrame);
mciSendCommand(wDevice, MCI_SEEK, MCI_SEEK_TO | MCI_WAIT, (DWORD)(LPVOID)&SetParam);
◆、波形音频的录制和保存
在进行波形音频编程时,记录音频设备输入的音频信息也能实现录音功能。可以通过向打开的音频设备发送MCI_RECORD命令实现该功能。例如:
WORD wDeviceID;
MCI_RECORD_PARMS RecordParam;
RecFlag = mciSendCommand(wDeviceID, MCI_RECORD, NULL, &RecordParam);
此外,保存音频设备的声音数据wav文件可以通过向设备发送MCI_SAVE命令实现。例如:
WORD wDeviceID;
MCI_SAVE_PARMS SaveParam;
SaveParam.lpfilename = (LPCSTR) FileName;
DWORD SaveFlag = mciSendCommand(wDeviceID, MCI_SAVE, MCI_SAVE_FILE | MCI_WAIT, &SaveParam);
◆、基于消息的MCI
消息命令控制接口使用消息控制MCI设备,将消息和控制信息以数据结构的形式作为函数参数发送,并接收返回的数据,MCI直接把设备消息和控制消息发送到设备。一条基于MCI的命令包含以下3个部分。
数据结构:该结构包含可传递给MCI驱动程序的信息和从驱动程序返回的值,指定要执行的MCI命令一个常量,如MCI_OPEN、MCI_CLOSE...
一个或一组用来指定MCI信息子选项的标志:这些标志用来确定可以得到什么类型的信息和如何执行函数。
一个确定命令附加参数:Windows MDK为使用命令消息接口发送MCI消息提供了3个核心函数。
1、mciSendCommand函数。该函数用于向MCI设备发送一个命令消息,原型为:
MCIERROR mciSendCommand(MCIDEVICEID IDDevice, UINT uMsg, DWORD fdwCommand, DWORD dwParam);
参数说明如下:
IDDevice:用来表示一个MCI设备。MCI使用MCI_OPEN消息打开一个设备时自动创建一个标识号用以唯一标识要操作的设备,以后的命令操作均使用此标识。
uMsg:表示要发出的消息,取值如下所示。
MCI_OPEN 打开一个设备
MCI_CLOSE 关闭一个设备
MCI_PLAY 播放全部或部分音频,从暂停状态恢复播放
MCI_STOP 停止播放
MCI_PAUSE 暂停播放
MCI_SEEK 改变当前位置
MCI_CUE 提示一个设备以最小的延迟开始播放或录制
MCI_RECORD 在一个设备上开始录制
MCI_SAVE 保存一个文件
MCI_INFO 查询设备信息,如产品名称等
MCI_GETDEVCAPS 查询产品特征,如设备类型等
MCI_STATUS 查询设备当前状态,如播放位置、媒体格式等
MCI_SET 设置设备参数,如时间格式、波形数据格式等
fdwCommand:消息指定标志。
dwParam:指定一个指向消息数据结构的指针。
如果mciSendCommand函数调用成功则返回0,否则返回错误代码消息。所返回的DWORD低位字是错误代码,可以将它发送到mciGetErrorString函数,已获得对错误的文本描述。若错误事设备特有的,高位包含了设备ID,否则高位为0。
MMSYSTEM.H头文件中还定义了MCI命令所需要的数据结构类型。以下是MCI命令常用的数据结构。
MCI_OPEN_PARMS MCI_OPEN命令消息参数的数据结构
MCI_PLAY_PARMS MCI_PLAY命令消息参数的数据结构
MCI_RECORD_PARMS MCI_RECORD命令消息参数的数据结构
2、mciGetDevicelID函数。当打开一个设备时,该函数用来获得此设备的ID,原型为:
MCIDEVICEID mciGetDevicelID(LPCTSTR lpszDevice);
参数lpszDevice指定要打开的MCI设备名。若函数调用成功,则返回设备的标志号,否则返回0。
3、mciGetErrorString函数。该函数用于返回一个错误代码的文本描述,原型为:
BOOL mciGetErrorString(DWORD fdwError, LPTSTR lpszErrorText, UINT cchErrorText);
参数说明如下:
fdwError:上一次mciSendCommand函数调用的返回值。
lpszErrorText:用来接收返回的文本描述的缓冲区指针。
cchErrorText:指定lpszErrorText的长度。
◆、基于字符串的MCI
命令字符串接口使用文本命令控制MCI设备。文本串中包含执行一个命令所需要的所有信息。MCI分析文本串,并把它翻译成命令消息接口中的消息和控制信息。由于加入了翻译过程,命令字符串接口的速度要慢于命令消息接口。
Windows也为字符串接口定义了3个核心操作函数。
1、mciSendString函数。该函数用于向一个MCI的设备驱动程序发送一个字符串,原型为:
MCIERROR mciSendString(LPCTSTR lpszCommand, LPTSTR lpszReturnString, UINT cchReturn, HANDLE hwndCallback);
参数说明如下:
lpszCommand:一个以NULL结尾的定义MCI控制命令的字符串,格式为:command device_name argument
lpszReturnString:一个远指针,它指向由应用程序返回的字符串缓冲区。
cchReturn:指定了缓冲区大小。
hwndCallback:用来指定接收并处理MCI向应用程序发出的MM_MCINOTIFY消息窗口的句柄。
函数成功调用,则返回0,否则返回错误代码。可以将错误代码传递给mciGetErrorString函数获得对错误的文本描述。
2、mciGetErrorString函数。前面已作了介绍,这里不再叙述。
3、mciExecute函数。实际上是mciSendString函数的简化形式,它不占用缓冲区来返回消息。如果调用失败,则显示出错信息消息框,原型为:
BOOL FAR PASCAL mciExecute(LPCTSTR lpszDevice);
参数lpszDevice与mciSendString函数的第一个参数含义相同。
使用MCI对多媒体进行操作实际上是向设备发送相应的命令。下面介绍各种常用的操作。
◆、打开多媒体设备
使用MCI_OPEN命令消息来打开设备。所有的设备对于MCI命令都需要一个指向消息命令数据结构MCI_OPEN_PARMS的指针。该结构格式如下:
typedef struct _MCI_OPEN_PARMS
{
DWORD dwCallback; //设置MCI_NOTIFY标志时的回调窗口句柄
MCIDEVICEID wDeviceID; //打开设备成功时返回的设备标识号
LPCSTR lpstrDeviceType; //指定所要打开设备类型
LPCSTR lpstrElementName; //对于复合设备,指定设备元素
LPCSTR lpstrAlias; //设备别名
} MCI_OPEN_PARMS;
简单设备和复合设备打开方式有所不同。打开简单设备时,不需要指定设备元素。可以用3种方法打开一个简单设备。
1、指定设备名。下面一段代码通过指定设备名打开一个光盘设备。
WORD wDeviceID;
MCI_OPEN_PARMS mciOpenParms;
//为MCI_OPEN消息数据结构赋值
mciOpenParms.lpstrDeviceType = "cdaudio";
//通过指定设备名打开光盘设备
if (micSendCommand(NULL, MCI_OPEN, MCI_OPEN_TYPE, (DWORD)(LPVOID)&mciOpenParms))
//调用失败的处理
else
wDeviceID = mciOpenParms.wDeviceID;
2、指定设备驱动程序。下面一段代码通过指定设备的驱动程序打开一个光盘设备。
WORD wDeviceID;
MCI_OPEN_PARMS mciOpenParms;
//为MCI_OPEN消息数据结构赋值
mciOpenParms.lpstrDeviceType = "mcicd.drv";
//通过指定设备名打开光盘设备
if (micSendCommand(NULL, MCI_OPEN, MCI_OPEN_TYPE, (DWORD)(LPVOID)&mciOpenParms))
//调用失败的处理
else
wDeviceID = mciOpenParms.wDeviceID;
3、指定设备类型参数。各个MCI设备的设备类型常量如下所示。
MCI命令能够管理的音频设备类型所对应的字符串和常量
cdaudio MCI_DEVTYPE_CD_AUDIO
waveaudio MCI_DEVTYPE_WAVEFORM_AUDIO
sequencer MCI_DEVTYPE_SEQUENCER
animation MCI_DEVTYPE_ANIMATION
dat MCI_DEVTYPE_DAT
digitalvideo MCI_DEVTYPE_DIGITAL_VIDEO
other MCI_DEVTYPE_OTHER
scanner MCI_DEVTYPE_SCANNER
vcr MCI_DEVTYPE_VCR
videodisc MCI_DEVTYPE_VIDEODISC
MPEGAudio MP3播放类型(常量不清楚,只知道字符串)
下面一段代码通过指定设备的类型参数打开一个光盘设备。
WORD wDeviceID;
MCI_OPEN_PARMS mciOpenParms;
//为MCI_OPEN消息数据结构赋值
mciOpenParms.lpstrDeviceType = (LPRSTR) MCI_DEVTYPE_CD_AUDIO;
//通过指定设备名打开光盘设备
if (micSendCommand(NULL, MCI_OPEN, MCI_OPEN_TYPE, (DWORD)(LPVOID)&mciOpenParms))
//调用失败的处理
else
wDeviceID = mciOpenParms.wDeviceID;
打开复合设备需要指定设备元素,也可以用3种方法打开一个复合设备。
1、只指定设备。该方法类似于打开简单设备,但只适合用于MCI_GETDEVCAPS命令确定设备性能。
2、同时指定设备和设备元素。该方法需要指出设备元素。举例如下:
WORD wDeviceID;
MCI_OPEN_PARMS mciOpenParms;
//为MCI_OPEN消息数据结构赋值
mciOpenParms.lpstrElementName = "c:\windows\media\chorcd.wav";
//通过指定设备元素参数打开复合设备
if (micSendCommand(NULL, MCI_OPEN, MCI_OPEN_TYPE, (DWORD)(LPVOID)&mciOpenParms))
//调用失败的处理
else
wDeviceID = mciOpenParms.wDeviceID;
3、只指定设备元素。在此方式下,MCI根据WIN.INI文件中的[mci extension]字段,从设备的扩展名确定设备。例如:
#define wPtnLength 255; //缓冲区大小
char lpstrRtnString[wPtnLength]; //指向缓冲区指针
WORD result;
result = mciSendString("open cdaudio", lpstrRtnString, wPtnLength, NULL);
//打开CD设备
if (result != 0)
mciGetErrorString(result, lpstrRtnString, wPtnLength)
//事件处理
else
//设备成功打开后事件处理
下面一段代码用来打开一个多媒体复合设备。
#define wPtnLength 255; //缓冲区大小
char lpstrRtnString[wPtnLength]; //指向缓冲区指针
WORD result;
result = mciSendString("c:\windows\media\chorcd.wav", lpstrRtnString, wPtnLength, NULL);
//打开CD设备
if (result != 0)
mciGetErrorString(result, lpstrRtnString, wPtnLength)
//事件处理
else
//设备成功打开后事件处理
◆、播放多媒体设备
在成功打开设备后,应用程序就可以通过向MCI发送MCI_PLAY或play字符串命令来播放多媒体设备。MCI_PLAY的数据结构MCI_PLAY_PARMS的格式如下:
typedef struc{
DWORD dwCallback; //设置MCI_NOTIFY标志时回调窗口句柄
DWORD dwFrom; //播放的起始位置
DWORD dwTo; //播放的结束位置
} MCI_PLAY_PARMS;
下面一段代码用来播放已打开的MCI设备。
WORD wDeviceID;
MCI_PLAY_PARMS mciPlayParams;
//为MCI_PLAY消息数据结构赋值
mciSendCommand(wDeviceID, MCI_PLAY, 0, (DWORD)(LPVOID)&mciPlayParams);
若不给MCI_PLAY_PARMS数据结构中的dwFrom和dwTo字段赋值,播放从头至尾进行。
而在使用play字符串命令时,如果play命令不加任何参数,则多媒体设备会从目前的位置播放到媒体或文件的结束。play命令支持From和To两个参数,它们分别指向起始和终止位置。实例如下:
#define wPtnLength 255; //缓冲区大小
char lpstrRtnString[wPtnLength]; //指向缓冲区指针
//播放CD从第10秒到第15秒位置
mciSendString("play cdaudio from 10000 to 15000", lpstrRtnString, wPtnLength, NULL);
◆、关闭媒体设备
应用程序在使用完一个打开的多媒体设备后,必须向MCI发送一个MCI_CLOSE消息来关闭设备。应该注意的是,在应用程序退出之前,应关闭所有的MCI设备。这时可以使用MCI_ALL_DEVICE_ID常量,只需一条命令就关闭所有的多媒体设备。下面一段代码演示了关闭所有设备。
mciSendCommand(MCI_ALL_DEVICE_ID, MCI_CLOSE, 0, NULL);
也可以使用close字符串命令关闭使用完的MCI设备。例如:
#define wPtnLength 255; //缓冲区大小
char lpstrRtnString[wPtnLength]; //指向缓冲区指针
mciSendString("close cdaudio", lpstrRtnString, wPtnLength, NULL);
与基于消息的命令一样,在退出应用程序之前,应关闭所有的设备,这时可以使用all参数,实例如下:
#define wPtnLength 255; //缓冲区大小
char lpstrRtnString[wPtnLength]; //指向缓冲区指针
mciSendString("close all", lpstrRtnString, wPtnLength, NULL);
◆、暂停多媒体播放
暂停多媒体播放可以通过向MCI发送MCI_PAUSE命令实现,实例如下:
WORD wDeviceID;
MCI_PLAY_PARMS mciPlayParam;
mciSendCommand(wDeviceID, MCI_PAUSE, NULL, (DWORD)(LPVOID)&mciPlayParam);
◆、获取和设置播放信息
在播放媒体时,很多时候需要获取播放信息,如波形音频的采样率、通道数和量化位数、CD音频文件总长度等。这时,可以通过向MCI发送MCI_STATUS命令实现。下面一段代码可以用来获取波形音频的采样率和通道数。
WORD wDeviceID;
MCI_STATUS_PARAM StatusParam;
StatusParam.dwItem = MCI_WAVE_STATUS_SAMPLESPERSEC;
mciSendCommand(wDeviceID, MCI_STATUS, MCI_WAIT | MCI_STATUS_ITTEM, &StatusParam);
DWORD samplerate = StatusParam.dwReturn; //该参数返回采样率
StatusParam.dwItem = MCI_WAVE_STATUS_CHANNLES;
mciSendCommand(wDeviceID, MCI_STATUS, MCI_WAIT | MCI_STATUS_ITTEM, &StatusParam);
DWORD channelnumber = StatusParam.dwReturn; //该参数返回通道数
也可以采用字符串命令的方式获得播放信息,实例如下:
MCIERROR mciError;
mciError = mciSendString("open waveaudio", buf, strlen(buf), NULL);
同样,在进行编程时,有时也需要对媒体设备的一些播放信息进行设置。这可以通过向已经打开的媒体设备发送MCI_SET命令实现。例如下面一段代码用来设置音频的播放格式为毫秒方式。
WORD wDeviceID;
MCI_SET_PARMS SetParam;
SetParam.dwFormat = MCI_FORMAT_MILLISECONDS;
DWORD OpenFlag = mciSendCommand(wDeviceID, MCI_SET, MCI_TIME_FORMT, &SetParam);
采用字符串命令设置媒体播放格式的代码如下:
MCIERROR mciError;
mciError = mciSendString("Set file format milliseconds", buf, strlen(buf), NULL);
◆、播放的跳转
在媒体播放过程中进行跳转首先需要声明一个MCI_SEEK_PARMS结构,并使用该结构的dwTo字段设定需要播放的位置,该位置以毫秒为单位。然后通过mciSendCommand函数向指定设备以MCI_TO为标志发送MCI_SEEK命令,如果只需要跳转到文件的开始或结束位置,可以直接使用MCI_SEEK_TO_START和MCI_SEEK_TO_END为标识发送MCI_SEEK命令。例如:
WORD wDeviceID;
int nMinute; //欲跳转的时间,以分钟为单位
MCI_SEEK_PARMS SeekParam;
SeekParam.dwTo = (nNinute*60+nSecond)*1000; //跳转的目标时间,以毫秒为单位
mciSendCommand(wDeviceID, MCI_SEEK, MCI_SEEK_TO | MCI_WAIT, (DWORD)(LPVOID)&SetParam);
下段代码通过MCI_SEEK命令使CD音频在nTrack轨道,第nMinute分钟,第nSecond秒的nFrame帧进行播放。
int nTrack, nMinute, nSecond;
WORD wDeviceID;
MCI_SEEK_PARMS SeekParam;
SeekParam.dwTo = MCI_MAKE_TWSF(nTrack, nMinute, nSecond, nFrame);
mciSendCommand(wDevice, MCI_SEEK, MCI_SEEK_TO | MCI_WAIT, (DWORD)(LPVOID)&SetParam);
◆、波形音频的录制和保存
在进行波形音频编程时,记录音频设备输入的音频信息也能实现录音功能。可以通过向打开的音频设备发送MCI_RECORD命令实现该功能。例如:
WORD wDeviceID;
MCI_RECORD_PARMS RecordParam;
RecFlag = mciSendCommand(wDeviceID, MCI_RECORD, NULL, &RecordParam);
此外,保存音频设备的声音数据wav文件可以通过向设备发送MCI_SAVE命令实现。例如:
WORD wDeviceID;
MCI_SAVE_PARMS SaveParam;
SaveParam.lpfilename = (LPCSTR) FileName;
DWORD SaveFlag = mciSendCommand(wDeviceID, MCI_SAVE, MCI_SAVE_FILE | MCI_WAIT, &SaveParam);
----------------------------------------------------
mciSendCommand百科名片
MCI(Media Control Interface,媒体控制接口)向Windows程序提供了在高层次上控制媒体设备接口的能力。程序不必关心具体设备,就可以对激光唱机(CD)、视盘机、波形音频设备、视频播放设备和MIDI设备等媒体设备进行控制。
MCI(Media Control Interface,媒体控制接口)向Windows程序提供了在高层次上控制媒体设备接口的能力。程序不必关心具体设备,就可以对激光唱机(CD)、视盘机、波形音频设备、视频播放设备和MIDI设备等媒体设备进行控制。
目录
mciSendCommand
MCI简介
mciSendCommand详细
编辑本段mciSendCommand
MCI的命令消息接口,所有MCI命令消息都是通过mciSendCommand函数发送的,函数声明为: MCIERROR mciSendCommand( MCIDEVICEID wIDDevice, //设备的ID,在打开设备时不用该参数 UINT uMsg, //命令消息 DWORD fdwCommand, //命令消息的标志 DWORD dwParam //指向包含命令消息参数的结构 ); //若成功则返回0,否则返回错误码
编辑本段MCI简介
对于程序员来说,可以把MCI理解为设备面板上的一排按键,通过选择不同的按键(发送不同的MCI命令)可以让设备完成各种功能,而不必关心设备内部实现。 比如,对于play,视盘机和CD机有不同的反应(一个是播放视频,一个播放音频),而对用户来说却只需要按同一按钮。 应用程序通过向MCI发送命令来控制媒体设备。MCI命令接口分命令字符串和命令消息两种,两者具有相同的功能。命令字符串具有使用简单的特点,但是它的执行效率不如命令消息。
编辑本段mciSendCommand详细
MCI的命令消息接口提供了C语言接口,它速度更快,并且更能符合C/C++程序员的需要。 所有MCI命令消息都是通过mciSendCommand函数发送的,函数声明为: MCIERROR mciSendCommand( MCIDEVICEID wIDDevice, //设备的ID,在打开设备时不用该参数 UINT uMsg, //命令消息 DWORD fdwCommand, //命令消息的标志 DWORD dwParam //指向包含命令消息参数的结构 ); //若成功则返回0,否则返回错误码 变量wDeviceID用来保存设备的ID,系统用ID来标识不同的设备,以保证命令发给正确的对象。 void CTttView::OnMyMenu() { MCI_OPEN_PARMS mciOpen; UINT wDeviceID; mciOpen.lpstrDeviceType = "avivideo"; mciOpen.lpstrElementName = "myfolder\\clock.avi"; mciSendCommand(0, MCI_OPEN, MCI_OPEN_ELEMENT, (DWORD)&mciOpen); wDeviceID=mciOpen.wDeviceID; MCI_PLAY_PARMS mciPlay; mciSendCommand(wDeviceID, MCI_PLAY, MCI_WAIT, (DWORD)&mciPlay); ); ---- MCI可以通过mciSendCommand()和mciSendString()来完成,本文仅使用mciSendCommand()函数。 ---- 原型:DWORD mciSendCommand(UINT wDeviceID,UINT wMessage,DWORD dwParam1,DWORD dwParam2); 参数: wDeviceID:接受消息的设备ID wMessage:MCI命令消息 dwParam1:命令的标志位 dwParam2:所使用参数块的指针 ---- 返值:调用成功,返回零;否则,返回双字中的低字存放有错误信息。 二MIDI的播放控制 ---- 1. 打开设备 MCI_OPEN_PARMS OpenParms; OpenParms.lpstrDeviceType = (LPCSTR) MCI_DEVTYPE_SEQUENCER;//MIDI类型 OpenParms.lpstrElementName = (LPCSTR) Filename; OpenParms.wDeviceID = 0; mciSendCommand (NULL, MCI_OPEN, MCI_WAIT | MCI_OPEN_TYPE | MCI_OPEN_TYPE_ID | MCI_OPEN_ELEMENT, (DWORD)(LPVOID) &OpenParms) ---- MCI设备ID指明打开了哪个设备,当发送了MCI_OPEN命令时,这个值在参数块中返回——应被保存备用。 ---- 2. 关闭设备 mciSendCommand (m_wDeviceID, MCI_CLOSE, NULL, NULL); ---- 3. 播放 MCI_PLAY_PARMS PlayParms; PlayParms.dwFrom = 0; // 指定从什么地方(时间)播放 mciSendCommand (m_wDeviceID, MCI_PLAY, MCI_FROM, (DWORD)(LPVOID) &PlayParms)); ---- 4. 暂停 MCI_PLAY_PARMS PlayParms; mciSendCommand (m_wDeviceID, MCI_PAUSE, 0, (DWORD)(LPVOID) &PlayParms); ---- 5. 停止 mciSendCommand (m_wDeviceID, MCI_STOP, NULL, NULL); ---- 6. 跳跃 * 跳转到任意地方 MCI_SEEK_PARMS SeekParms; SeekParms.dwTo = (nMinute * 60 + nSecond) * 1000; //跳转的目标时间,时间单位为毫秒 mciSendCommand (m_wDeviceID, MCI_SEEK, MCI_TO | MCI_WAIT,(DWORD)(LPVOID) &SeekParms); * 跳到文件头 mciSendCommand (m_wDeviceID, MCI_SEEK, MCI_SEEK_TO_START, NULL); * 跳到文件尾 mciSendCommand (m_wDeviceID, MCI_SEEK, MCI_SEEK_TO_END, NULL); ---- 7. 查询当前信息 MCI_STATUS_PARMS StatusParms; StatusParms.dwItem = MCI_SEQ_STATUS_DIVTYPE; mciSendCommand (m_wDeviceID, MCI_STATUS, MCI_WAIT | MCI_STATUS_ITEM, (DWORD)(LPVOID) &StatusParms); 返回信息存放于StatusParms.dwReturn中。 MCI_STATUS标志 MCI_STATUS_LENGTH 获得文件长度 MCI_STATUS_MODE 获得文件播放的当前状态 MCI_STATUS_POSITION 获得文件播放的当前位置 MCI_STATUS_TIME_FORMAT 获得当前的时间格式 MCI_SEQ_STATUS_DIVTYPE 判断文件是PPQN类型还是SMPTE类型 MCI_SEQ_STATUS_TEMPO 获得当前播放速度,PQRN类型, 此值为节拍/分,SMPTE类型,此值为祯/秒 ---- 8. 设置时间格式及播放速度 MCI_SET_PARMS SetParms; SetParms.dwTimeFormat = MCI_FORMAT_MILLISECONDS; //设置时间单位为毫秒 mciSendCommand (m_wDeviceID, MCI_SET, MCI_SET_TIME_FORMAT, (DWORD)(LPVOID) &SetParms); MCI_SEQ_SET_TEMPO 设置播放速度, PQRN类型,此值为节拍/分, SMPTE类型,此值为祯/秒 第二部分 WAV文件的播放 ---- 一、原理 ---- MicroSoft API提供了三种不同的方法来实现WAV的播放: PlaySound()函数。它可以通过单行编码来播放Wave格式的声音。此函数有两个限制:必须将声音数据完整地载入物理内存;数据格式必须被所配置的某一音频驱动器支 持。根据经验,PlaySound()适用于100K以下的文件。 MCI(The Media Control Interface),与上一章播放MIDI文件相似,可以播放100K 以上的文件。 低级Wave音频设备。用这些设备可以运行完全控制Wave数据的应用文件。 ---- 二、 WAV文件播放控制 ---- 因为同样使用MCI,与上一章相同,只列出不同的部分。 ---- 1. 打开设备 ---- 将MIDI的MCI_DEVTYPE_SEQUENCER 改为"waveaudio" ---- 2. 录音 MCI_RECORD_PARMS RecordParms; mciSendCommand (m_wDeviceID, MCI_RECORD, NULL, (DWORD)(LPVOID) &RecordParms); ---- 3. 保存录音 MCI_SAVE_PARMS SaveParms; SaveParms.lpfilename = (LPCSTR) Filename; mciSendCommand (m_wDeviceID, MCI_SAVE, MCI_SAVE_FILE | MCI_WAIT, (DWORD)(LPVOID) &SaveParms); 第三部分 CD的播放 ---- CD的独特优势在于,它由作曲家设计,并由音乐厂家生产。不同的计算机播放MIDI 文件时,声音效果也不一样,但是CD的声音效果总是相同的。高品质的音频对计算机用 户产生的效果会使你感到吃惊。 我们依然采用MCI播放CD,大部分的播放控制与前两部分相同,只列出不同的部分 ---- 1. 开光驱门 mciSendCommand (m_wDeviceID, MCI_SET, MCI_SET_DOOR_OPEN, NULL); ---- 2. 关光驱门 mciSendCommand (m_wDeviceID, MCI_SET, MCI_SET_DOOR_CLOSED, NULL); ---- 3. 打开设备 将MIDI的MCI_DEVTYPE_SEQUENCER 改为MCI_DEVTYPE_CD_AUDIO ---- 4. 播放 ---- 指定播放起点必须经过MCI_MAKE_TMSF(Track,Minute,Second,Frame)转化 ---- 5. 查询当前信息 MCI_STATUS_CURRENT_TRACK 得到当前曲目 MCI_STATUS_LENGTH 得到CD或指定曲目长度 MCI_STATUS_MODE 得到驱动器的当前状态 MCI_STATUS_NUMBER_OF_TRACKS 得到CD曲目的数目 MCI_STATUS_POSITION 得到当前格式下的位置 MCI_STATUS_READY 检查设备是否就绪 MCI_STATUS_TIME_FORMAT 得到当前时间格式 MCI_STATUS_MEDIA_divSENT 检查以确认CD是否在驱动器内 MCI_CDA_STATUS_TYPE_TRACK 检查已确认某曲目是否为音频曲目 ---- 注意: 使用MCI_STATUS_LENGTH参数查询CD 及曲目长度,返回值通过调用MCI_MSF_MINUTE(),MCI_MSF_SECOND()转换为分、秒。 MCI_STATUS_POSITION参数返回值调用MCI_TMSF_TRACK(), MCI_TMSF_MINUTE(), MCI_TMSF_SECOND(),MCI_TMSF_FRAME才能得到当前的位置的道、分、秒、帧。 ---- 6. 跳跃 ---- 跳转的目标必须经过MCI_MAKE_TMSF(Track,Minute,Second,Frame)转化最好将上述三种格式分开建类,或做成动态连接库。在 Project-- >Setting-- >Link-- >Object/library modules中加入winmm.lib,源程序中包含。 ---- MCI调用简单,功能强大,可以满足日常多媒体编程的基本需要。但是,MCI一次只能播放一个文件,使用DirectSound技术可以实现八个以上WAV文件的同时播放。
------------
八、函数说明
MCI简介
mciSendCommand详细
编辑本段mciSendCommand
MCI的命令消息接口,所有MCI命令消息都是通过mciSendCommand函数发送的,函数声明为: MCIERROR mciSendCommand( MCIDEVICEID wIDDevice, //设备的ID,在打开设备时不用该参数 UINT uMsg, //命令消息 DWORD fdwCommand, //命令消息的标志 DWORD dwParam //指向包含命令消息参数的结构 ); //若成功则返回0,否则返回错误码
编辑本段MCI简介
对于程序员来说,可以把MCI理解为设备面板上的一排按键,通过选择不同的按键(发送不同的MCI命令)可以让设备完成各种功能,而不必关心设备内部实现。 比如,对于play,视盘机和CD机有不同的反应(一个是播放视频,一个播放音频),而对用户来说却只需要按同一按钮。 应用程序通过向MCI发送命令来控制媒体设备。MCI命令接口分命令字符串和命令消息两种,两者具有相同的功能。命令字符串具有使用简单的特点,但是它的执行效率不如命令消息。
编辑本段mciSendCommand详细
MCI的命令消息接口提供了C语言接口,它速度更快,并且更能符合C/C++程序员的需要。 所有MCI命令消息都是通过mciSendCommand函数发送的,函数声明为: MCIERROR mciSendCommand( MCIDEVICEID wIDDevice, //设备的ID,在打开设备时不用该参数 UINT uMsg, //命令消息 DWORD fdwCommand, //命令消息的标志 DWORD dwParam //指向包含命令消息参数的结构 ); //若成功则返回0,否则返回错误码 变量wDeviceID用来保存设备的ID,系统用ID来标识不同的设备,以保证命令发给正确的对象。 void CTttView::OnMyMenu() { MCI_OPEN_PARMS mciOpen; UINT wDeviceID; mciOpen.lpstrDeviceType = "avivideo"; mciOpen.lpstrElementName = "myfolder\\clock.avi"; mciSendCommand(0, MCI_OPEN, MCI_OPEN_ELEMENT, (DWORD)&mciOpen); wDeviceID=mciOpen.wDeviceID; MCI_PLAY_PARMS mciPlay; mciSendCommand(wDeviceID, MCI_PLAY, MCI_WAIT, (DWORD)&mciPlay); ); ---- MCI可以通过mciSendCommand()和mciSendString()来完成,本文仅使用mciSendCommand()函数。 ---- 原型:DWORD mciSendCommand(UINT wDeviceID,UINT wMessage,DWORD dwParam1,DWORD dwParam2); 参数: wDeviceID:接受消息的设备ID wMessage:MCI命令消息 dwParam1:命令的标志位 dwParam2:所使用参数块的指针 ---- 返值:调用成功,返回零;否则,返回双字中的低字存放有错误信息。 二MIDI的播放控制 ---- 1. 打开设备 MCI_OPEN_PARMS OpenParms; OpenParms.lpstrDeviceType = (LPCSTR) MCI_DEVTYPE_SEQUENCER;//MIDI类型 OpenParms.lpstrElementName = (LPCSTR) Filename; OpenParms.wDeviceID = 0; mciSendCommand (NULL, MCI_OPEN, MCI_WAIT | MCI_OPEN_TYPE | MCI_OPEN_TYPE_ID | MCI_OPEN_ELEMENT, (DWORD)(LPVOID) &OpenParms) ---- MCI设备ID指明打开了哪个设备,当发送了MCI_OPEN命令时,这个值在参数块中返回——应被保存备用。 ---- 2. 关闭设备 mciSendCommand (m_wDeviceID, MCI_CLOSE, NULL, NULL); ---- 3. 播放 MCI_PLAY_PARMS PlayParms; PlayParms.dwFrom = 0; // 指定从什么地方(时间)播放 mciSendCommand (m_wDeviceID, MCI_PLAY, MCI_FROM, (DWORD)(LPVOID) &PlayParms)); ---- 4. 暂停 MCI_PLAY_PARMS PlayParms; mciSendCommand (m_wDeviceID, MCI_PAUSE, 0, (DWORD)(LPVOID) &PlayParms); ---- 5. 停止 mciSendCommand (m_wDeviceID, MCI_STOP, NULL, NULL); ---- 6. 跳跃 * 跳转到任意地方 MCI_SEEK_PARMS SeekParms; SeekParms.dwTo = (nMinute * 60 + nSecond) * 1000; //跳转的目标时间,时间单位为毫秒 mciSendCommand (m_wDeviceID, MCI_SEEK, MCI_TO | MCI_WAIT,(DWORD)(LPVOID) &SeekParms); * 跳到文件头 mciSendCommand (m_wDeviceID, MCI_SEEK, MCI_SEEK_TO_START, NULL); * 跳到文件尾 mciSendCommand (m_wDeviceID, MCI_SEEK, MCI_SEEK_TO_END, NULL); ---- 7. 查询当前信息 MCI_STATUS_PARMS StatusParms; StatusParms.dwItem = MCI_SEQ_STATUS_DIVTYPE; mciSendCommand (m_wDeviceID, MCI_STATUS, MCI_WAIT | MCI_STATUS_ITEM, (DWORD)(LPVOID) &StatusParms); 返回信息存放于StatusParms.dwReturn中。 MCI_STATUS标志 MCI_STATUS_LENGTH 获得文件长度 MCI_STATUS_MODE 获得文件播放的当前状态 MCI_STATUS_POSITION 获得文件播放的当前位置 MCI_STATUS_TIME_FORMAT 获得当前的时间格式 MCI_SEQ_STATUS_DIVTYPE 判断文件是PPQN类型还是SMPTE类型 MCI_SEQ_STATUS_TEMPO 获得当前播放速度,PQRN类型, 此值为节拍/分,SMPTE类型,此值为祯/秒 ---- 8. 设置时间格式及播放速度 MCI_SET_PARMS SetParms; SetParms.dwTimeFormat = MCI_FORMAT_MILLISECONDS; //设置时间单位为毫秒 mciSendCommand (m_wDeviceID, MCI_SET, MCI_SET_TIME_FORMAT, (DWORD)(LPVOID) &SetParms); MCI_SEQ_SET_TEMPO 设置播放速度, PQRN类型,此值为节拍/分, SMPTE类型,此值为祯/秒 第二部分 WAV文件的播放 ---- 一、原理 ---- MicroSoft API提供了三种不同的方法来实现WAV的播放: PlaySound()函数。它可以通过单行编码来播放Wave格式的声音。此函数有两个限制:必须将声音数据完整地载入物理内存;数据格式必须被所配置的某一音频驱动器支 持。根据经验,PlaySound()适用于100K以下的文件。 MCI(The Media Control Interface),与上一章播放MIDI文件相似,可以播放100K 以上的文件。 低级Wave音频设备。用这些设备可以运行完全控制Wave数据的应用文件。 ---- 二、 WAV文件播放控制 ---- 因为同样使用MCI,与上一章相同,只列出不同的部分。 ---- 1. 打开设备 ---- 将MIDI的MCI_DEVTYPE_SEQUENCER 改为"waveaudio" ---- 2. 录音 MCI_RECORD_PARMS RecordParms; mciSendCommand (m_wDeviceID, MCI_RECORD, NULL, (DWORD)(LPVOID) &RecordParms); ---- 3. 保存录音 MCI_SAVE_PARMS SaveParms; SaveParms.lpfilename = (LPCSTR) Filename; mciSendCommand (m_wDeviceID, MCI_SAVE, MCI_SAVE_FILE | MCI_WAIT, (DWORD)(LPVOID) &SaveParms); 第三部分 CD的播放 ---- CD的独特优势在于,它由作曲家设计,并由音乐厂家生产。不同的计算机播放MIDI 文件时,声音效果也不一样,但是CD的声音效果总是相同的。高品质的音频对计算机用 户产生的效果会使你感到吃惊。 我们依然采用MCI播放CD,大部分的播放控制与前两部分相同,只列出不同的部分 ---- 1. 开光驱门 mciSendCommand (m_wDeviceID, MCI_SET, MCI_SET_DOOR_OPEN, NULL); ---- 2. 关光驱门 mciSendCommand (m_wDeviceID, MCI_SET, MCI_SET_DOOR_CLOSED, NULL); ---- 3. 打开设备 将MIDI的MCI_DEVTYPE_SEQUENCER 改为MCI_DEVTYPE_CD_AUDIO ---- 4. 播放 ---- 指定播放起点必须经过MCI_MAKE_TMSF(Track,Minute,Second,Frame)转化 ---- 5. 查询当前信息 MCI_STATUS_CURRENT_TRACK 得到当前曲目 MCI_STATUS_LENGTH 得到CD或指定曲目长度 MCI_STATUS_MODE 得到驱动器的当前状态 MCI_STATUS_NUMBER_OF_TRACKS 得到CD曲目的数目 MCI_STATUS_POSITION 得到当前格式下的位置 MCI_STATUS_READY 检查设备是否就绪 MCI_STATUS_TIME_FORMAT 得到当前时间格式 MCI_STATUS_MEDIA_divSENT 检查以确认CD是否在驱动器内 MCI_CDA_STATUS_TYPE_TRACK 检查已确认某曲目是否为音频曲目 ---- 注意: 使用MCI_STATUS_LENGTH参数查询CD 及曲目长度,返回值通过调用MCI_MSF_MINUTE(),MCI_MSF_SECOND()转换为分、秒。 MCI_STATUS_POSITION参数返回值调用MCI_TMSF_TRACK(), MCI_TMSF_MINUTE(), MCI_TMSF_SECOND(),MCI_TMSF_FRAME才能得到当前的位置的道、分、秒、帧。 ---- 6. 跳跃 ---- 跳转的目标必须经过MCI_MAKE_TMSF(Track,Minute,Second,Frame)转化最好将上述三种格式分开建类,或做成动态连接库。在 Project-- >Setting-- >Link-- >Object/library modules中加入winmm.lib,源程序中包含。 ---- MCI调用简单,功能强大,可以满足日常多媒体编程的基本需要。但是,MCI一次只能播放一个文件,使用DirectSound技术可以实现八个以上WAV文件的同时播放。
------------
八、函数说明
1、mciSendCommand函数声明
MCIERROR mciSendCommand(MCIDEVICEID IDDevice,UINT uMsg,DWORD fdwCommand,DWORD_PTP dwParam)
IDDevice:MCI设备标识符,用于接收命令消息。
uMsg:命令消息。
fdwCommand:命令消息风格。
dwParam:命令消息相关参数。
功能:发送一命令消息到指定MCI设备。函数调用成功,返回零值;否则返回零。
2、MCI_OPEN_PARMS结构声明
typedef struct{
DWORD_PTR dwCallback;
MCIDEVICED wDeviceID;
LPCTSTR lpstrDeviceType;
LPCTSTR lpstrElementName;
LPCTSTR lpstrAlias;
}MCI_OPEN_PARAMS
dwCallback:用于MCI_NOTIFY风格的窗口句柄。
wDeviceID:设备ID号。
lpstrDeviceType:设备类型名。
lpstrElementName:设备参数。
lpstrAlias:设备别名。
功能:包含MCI_OPEN信息。
3、MCI_STATUS_PARMS结构声明
typedef struct{
DWORD_PTR dwCallback;
DWORD dwReturn;
DWORD dwItem;
DWORD dwTrack;
}MCI_STATUS_PARMS
dwCallback:用于MCI_NOTIFY风格的窗口句柄。
dwReturn:包含将返回的信息。
dwItem:询问内容。
dwTrack:Track的长度。
功能:包含MCI_STATUS命令信息。
4、MCI_SET_PARMS结构声明
typedef struct{
DWORD_PTR dwCallback;
DWORD dwTimeFormat;
DWORD dwAudio;
}MCI_SET_PARMS
dwCallback:用于MCI_NOTIFY风格的窗口句柄。
dwTimeFormat:设备格式。
dwAudio:音频输出信道。
功能:包含MCI_SET命令信息。
5、MCI_PLAY_PARMS结构声明
typedef struct{
DWORD_PTR dwCallback;
DWORD dwFrom;
DWORD dwTo;
}MCI_PLAY_PARMS
dwCallback:用于MCI_NOTIFY风格的窗口句柄。
dwFrom:开始播放位置。
dwTo:结束播放位置。
功能:包含MCI_PALY命令信息。