文档库 最新最全的文档下载
当前位置:文档库 › C++6.0实现音频文件播放功能设计毕业论文

C++6.0实现音频文件播放功能设计毕业论文

目录

摘要…………………………………………………………………

引言…………………………………………………………………

第一章绪论…………………………………………………………

1、Visual C++程序系统设计简介……………………………

§1.1 visual c++的组织文件,工程和工作区……………………

§1.2 MFC编程特点…………………………………………

§1.3使用AppWizard …………………………………………

§1.4 VC程序调试……………………………………………第二章音频基础知识………………………………………………

1、多媒体中的音频处理技术………………………………………

2、乐器数字接口MIDI的概念………………………………………

3、常见的声音文件格式……………………………………………第三章设计思想………………………………………………………

1、设计思路…………………………………………………

2、系统结构功能…………………………………………………

第四章音频播放器的程序设计过程…………………………………

1、高层音频服务媒体控制接口MCI……………………………

2、系统模块窗体的设置………………………………………第五章结束语………………………………………………………

致谢…………………………………………………………………参考文献………………………………………………………

第一章绪论

1、Visual C++程序系统设计简介

Visual C++作为一个功能非常强大的可视化应用程序开发工具,是计算机界公认的最优秀的应用开发工具之一。Visual C++提供了一个支持可视化编程的集成开发环境:Visual Studio(又名Developer Studio)。Developer Studio是一个通用的应用程序集成开发环境,它不仅支持Visual C++,还支持Visual Basic,Visual J++,Visual InterDev等Microsoft 系列开发工具。Developer Studio包含了一个文本编辑器、资源编辑器、工程编译工具、一个增量连接器、源代码浏览器、集成调试工具,以及一套联机文档。使用Developer Studio,可以完成创建、调试、修改应用程序等的各种操作。

可视化技术和CASE技术研究的深入为我们带来了支持可视化编程特性的第三代开发工具,这一代开发工具有:Visual Basic,Visual C++,Borland C++ Builder,Delphi和用于数据库开发的PowerBuilder、Visual Foxpro等等。

其中,Visual C++是美国Microsoft公司推出的4GL软件开发工具,目前已成为国内应用最广泛的高级程序设计语言之一。同其他软件开发工具相比,Visual C++具有以下优点:

?面向对象、可视化开发:提供了面向对象的应用程序框架MFC(Microsoft Foundation Class:微软基础类库),大大简化了程序员的编程工作,提高了模块的可重用性。

Visual C++还提供了基于CASE技术的可视化软件自动生成和维护工具AppWizard、ClassWizard、Visual Studio、WizardBar等,帮助用户直观的、可视地设计程序

的用户界面,可以方便的编写和管理各种类,维护程序源代码,从而提高了开发效

率。用户可以简单而容易地使用C/C++编程。

?众多的开发商支持以及业已成为工业标准的MFC类库:MFC类库已经成为事实上的工业标准类库,得到了众多开发商和软件开发工具的支持;另外,由于众多的开发商都采用Visual C++进行软件开发,这样用Visual C++开发的程序就与别的应用软件有许多相似之处,易于学习和使用。

?Visual C++封装了Windows的API(应用程序接口)函数、USER、KERNEL、GDI函数,帮助我们弄清了许多函数的组织方法,隐去了创建、维护窗口的许多复杂的例行工

作,简化了编程。

§1.1visual c++的组织文件、工程和工作区

Visual C++作为一种程序设计语言,它同时也是一个集成开发工具,提供了软件代码自动生成和可视化的资源编辑功能。在使用Visual C++开发应用程序的过程中,系统为我们生成了大量的各种类型的文件。项目工作区是一个包含用户的所有相关项目和配置的实体。工程定义为一个配置和一组文件,用以生成最终的程序或二进制文件。一个项目工作区可以包含多个工程,这些工程既可以是同一类型的工程,也可以是由不同类型的工程(如Visual C++和Visual J++工程)。工作区现在以.dsw为后缀名(以前为.mdp),项目文件现在以.dsp (以前为.mak)为后缀名。Developer Studio提供了一个简单的对话框,用以创建项目工作区、工程、文件和其他文档。在创建工程时,可以指定一个新的项目工作区来包含它;或把新工程加入到当前打开的工作区中。在创建一个文件时,可以同时把它加入到工程中,也可以将现存的文件、文档加入到工程中。

首先要介绍的是扩展名为dsw的文件类型,这种类型的文件在VC中是级别最高的,称为Workspace文件。在VC中,应用程序是以Project的形式存在的,Project文件以.dsp 扩展名,在Workspace文件中可以包含多个Project,由Workspace文件对它们进行统一的协调和管理。与dsw类型的Workspace文件相配合的一个重要的文件类型是以opt为扩展名的文件,这个文件中包含的是在Workspace文件中要用到的本地计算机的有关配置信息,所以这个文件不能在不同的计算机上共享,当我们打开一个Workspace文件时,如果系统找不到需要的opt类型文件,就会自动地创建一个与之配合的包含本地计算机信息的opt文件。上面提到Project文件的扩展名是dsp,这个文件中存放的是一个特定的工程,也就是特定的应用程序的有关信息,每个工程都对应有一个dsp类型的文件。以clw为扩展名的文件是用来存放应用程序中用到的类和资源的信息的,这些信息是VC中的ClassWizard工具管理和使用类的信息来源。

对应每个应用程序有一个readme.txt文件,这个文件中列出了应用程序中用到的所有的文件的信息,打开并查看其中的内容就可以对应用程序的文件结构有一个基本的认识。在应用程序中大量应用的是以h和cpp为扩展名的文件,以h为扩展名的文件称为头文件。以cpp为扩展名的文件称为实现文件,一般说来h为扩展名的文件与cpp为扩展名的文件是一一对应配合使用的,在h为扩展名的文件中包含的主要是类的定义,而在cpp为扩展名的文件中包含的主要是类成员函数的实现代码。

在应用程序中经常要使用一些位图、菜单之类的资源,VC中以rc为扩展名的文件称为资源文件,其中包含了应用程序中用到的所有的windows资源,要指出的一点是rc文件可以直接在VC集成环境中以可视化的方法进行编辑和修改。

§1.2 MFC编程特点

MFC的英文全称是Microsoft Fundation Classes,即微软的基本类库,MFC的本质就是一个包含了许多微软公司已经定义好的对象的类库。我们知道,虽然我们要编写的程序在功能上是千差万别的,但从本质上来讲,都可以化归为用户界面的设计,对文件的操作,多媒体的使用,数据库的访问等等一些最主要的方面。这一点正是微软提供MFC类库最重要的原因,在这个类库中包含了一百多个程序开发过程中最常用到的对象。

⒈MFC类库概念和组成

类库是一个可以在应用中使用的相互关联的C++类的集合。有些类库随编译器提供,如Borland C++ Turbo Vision等;有的是由其他软件公司销售,如用于数据库开发的CodeBase;有的则是由用户自己开发的。比如图象处理类库完成图象显示、格式转换、量化等;串行通信类库用于支持串行口输入输出。有些情况下用户可以直接利用类库中包含的类定义应用程序所需的变量,有时则需要从类库所提供的类中派生出新的类,这依赖于类库的设计和具体的应用程序。

Microsoft提供了一个基础类库MFC,其中包含用来开发C++和C++ Windows应用程序的一组类。基础类库的核心是以C++形式封装了大部分的Windows API。类库表示窗口、对话框、设备上下文、公共GDI对象如画笔、调色板、控制框和其他标准的Windows部件。这些类提供了一个面向Windows中结构的简单的C++成员函数的接口。在进行程序设计的时候,如果类库中的某个对象能完成所需要的功能,这时我们只要简单地调用已有对象的方法就可以了。我们还可以利用面向对象技术中很重要的“继承”方法从类库中的已有对象派生出我们自己的对象,这时派生出来的对象除了具有类库中的对象的特性和功能之外,还可以由我们自己根据需要加上所需的特性和方法,产生一个更专门的,功能更为强大的对象。当然,你也可以在程序中创建全新的对象,并根据需要不断完善对象的功能。完全支持Windows

所有的函数、控件、消息、GDI基本图形函数,菜单及对话框。类的设计以及同API函数的结合相当合理。

⒉ MFC对消息的管理

Windows消息的管理包括消息发送和处理。为了支持消息发送机制,MFC提供了三个函数:SendMessage、PostMessage和SendDlgItemMessage。而消息处理则相对来说显得复杂一些。MFC采用了一种新的机制取代C语言编程时对Windows消息的Switch/Case分支,简化了Windows编程,使程序可读性、可维护性大大提高。使用与传统的Windows API同样的命名规则。进行消息处理时,不使用易产生错误switch/case语句,所有消息映射到类的成员函数,这种直接消息到方法的映射对所有的消息都适用。

它通过宏来实现消息到成员函数的映射,而且这些函数不必是虚拟的成员函数,这样不需要为消息映射函数生成一个很大的虚拟函数表(V表),节省内存。通过发送有关对象信息到文件的能力提供更好的判定支持,也可确认成员变量。支持异常错误的处理,减少了程序出错的机会。运行时确定数据对象的类型。这允许实例化时动态操作各域。有较少的代码和较快的速度。MFC库只增加了少于40k的目标代码,效率只比传统的C Windows程序低5%。可以利用与MFC紧密结合的AppWizard和ClassWizard等工具快速开发出功能强大的应用程序。另外,在使用MFC时还允许混合使用传统的函数调用。

MFC类库在提供的对象的各种属性和方法都是经过谨慎的编写和严格的测试,可靠性很高,这就保证了使用MFC类库不会影响程序的可靠性和正确性。

§1.3 使用AppWizard

Visual C++是一种功能强大的通用程序设计语言,它提供了各种向导和工具帮助我们来实现所需的功能,在一定程度上实现了软件的自动生成和可视化编程。下面就为你介绍VC 集成环境中几个最主要的开发工具的使用方法。

首先要介绍的是Appwizard(如图1)工具,这个工具的作用是帮助我们一步步地生成一个新的应用程序,并且自动生成应用程序所需的基本代码。

图1

§1.4 VC程序调试

在VC中每当建立一个工程(Project)时,VC都会自动建立两个版本:Release版本,和Debug版本,正如其字面意思所说的,Release版本是当程序完成后,准备发行时用来编译的版本,而Debug版本是用在开发过程中进行调试时所用的版本。DEBUG 版本当中,包含着MICROSOFT 格式的调试信息,不进行任何代码优化,而在RELEASE 版本对可执行程序的二进制代码进行了优化,但是其中不包含任何的调试信息。

调试,说到底就是在程序的运行过程的某一阶段观测程序的状态,而在一般情况下程序是连续运行的,所以我们必须使程序在某一地点停下来。所以我们所做的第一项工作就是设立断点。其次,再运行程序,当程序在设立断点处停下来时,再利用各种工具观察程序的状态。程序在断点停下来后,有时需要按要求控制程序的运行,以进一步观测程序的流向。为了更快更好地开发程序,我们还需要利用更高级的调试工具。在利用VC开发过程中,利用MFC 将会极大地方便应用程序的开发,所以开发人员往往是利用MFC来开发应用程序,正是这个原因Microsoft公司在MFC中提供了一些特性来帮助你进行程序的调试。

第二章音频基础知识

1.多媒体中的音频处理技术

多媒体涉及到多方面的音频处理技术,如:音频采集、语音编码/解码、文一-语转换、音乐合成、语音识别与理解、音频数据传输、音频一-视频同步、音频效果与编辑等。其中数字音频是个关键的概念,它指的是一个用来表示声音强弱的数据序列,它是由模拟声音经抽样(即每隔一个时间间隔在模拟声音波形上取一个幅度值)量化和编码(即把声音数据写成计算机的数据格式)后得到的。计算机数字CD、数字磁带(DAT)中存储的都是数字声音。模拟一-数字转换器把模拟声音变成数字声音;数字一-模拟转换器可以恢复出模拟来的声音。

一般来讲,实现计算机语音输出有两种方法:一是录音/重放,二是文一-语转换。第二种方法是基于声音合成技术的一种声音产生技术,它可用于语音合成和音乐合成。而第一种方法是最简单的音乐合成方法,曾相继产生了应用调频(FM)音乐合成技术和波形表(wavetable)音乐合成技术。

2.乐器数字接口MIDI的概念

现在我们用的最多的音频名词之一MIDI(musical instrument digital interface)是作为“乐器数字接口”的缩写出现的,并用它来泛指数字音乐的国际标准。由于它定义了计算机音乐程序、合成器及其他电子设备交换信息和电子信号的方式,所以可以解决不同电子乐器之间不兼容的问题。另外,标准的多媒体PC平台能够通过内部合成器或连接到计算机MIDI端口的外部合成器播放MIDI文件,利用MIDI文件演奏音乐,所需的存储量最少。

至于MIDI文件,是指存放MIDI信息的标准文件格式。MIDI文件中包含音符、定时和多达16个通道的演奏定义。文件包括每个通道的演奏音符信息:键通道号、音长、音量和力度(击键时,键达到最低位置的速度)。由于MDDI文件是一系列指令,而不是波形,它需要的磁盘空间非常少;并且现装载MIDI文件比波形文件容易的多。这样,在设计多媒体节目时,我们可以指定什么时候播放音乐,将有很大的灵活性。在以下几种情况下,使用MIDI 文件比使用波形音频更合适:需要播放长时间高质量音乐,如想在硬盘上存储的音乐大于4分钟,而硬盘又没有足够的存储容量;需要以音乐作背景音响效果,同时从CD-ROM中装载其它数据,如图像、文字的显示;需要以音乐作背景音响效果,同时播放波形音频或实现文一语转换,以实现音乐和语音的同时输出。

3.常见的声音文件格式

★ WAVE,扩展名为WAV:该格式记录声音的波形,故只要采样率高、采样字节长、机器速度快,利用该格式记录的声音文件能够和原声基本一致,质量非常高,但这样做的代价就是文件太大。

★ MOD,扩展名MOD、ST3、XT、S3M、FAR、669等:该格式的文件里存放乐谱和乐曲使用的各种音色样本,具有回放效果明确,音色种类无限等优点。但它也有一些致命弱点,以至于现在已经逐渐淘汰,目前只有MOD迷及一些游戏程序中尚在使用。

★ MPEG-3,扩展名MP3:现在最流行的声音文件格式,因其压缩率大,在网络可视电话通信方面应用广泛,但和CD唱片相比,音质不能令人非常满意。

★ Real Audio,扩展名RA:这种格式真可谓是网络的灵魂,强大的压缩量和极小的失真使其在众多格式中脱颖而出。和MP3相同,它也是为了解决网络传输带宽资源而设计的,因此主要目标是压缩比和容错性,其次才是音质。

★ Creative Musical Format,扩展名CMF:Creative公司的专用音乐格式,和MIDI差不多,只是音色、效果上有些特色,专用于FM声卡,但其兼容性也很差。

★ CD Audio音乐CD,扩展名CDA:唱片采用的格式,又叫“红皮书”格式,记录的是波形流,绝对的纯正、HIFI。但缺点是无法编辑,文件长度太大。

★ MIDI,扩展名MID:目前最成熟的音乐格式,实际上已经成为一种产业标准,其科学性、兼容性、复杂程度等各方面当然远远超过本文前面介绍的所有标准(除交响乐CD、Unplug CD 外,其它CD往往都是利用MIDI制作出来的),它的General MIDI就是最常见的通行标准。作为音乐工业的数据通信标准,MIDI能指挥各音乐设备的运转,而且具有统一的标准格式,能够模仿原始乐器的各种演奏技巧甚至无法演奏的效果,而且文件的长度非常小。

总之,如果有专业的音源设备,那么要听同一首曲子的HIFI程度依次是: 原声乐器演奏 > MIDI > CD唱片 > MOD > 所谓声卡上的MIDI > CMF,而MP3及RA要看它的节目源是采用MIDI、CD还是MOD了。

另外,在多媒体材料中,存储声音信息的文件格式也是需要认识的,共有:WAV文件、VOC文件、MIDI文件、RMI文件、PCM文件以及AIF文件等若干种。

★ WAV文件:Microsoft公司的音频文件格式,它来源于对声音模拟波形的采样。用不同的采样频率对声音的模拟波形进行采样可以得到一系列离散的采样点,以不同的量化位数(8位或16位)把这些采样点的值转换成二进制数,然后存入磁盘,这就产生了声音的WAV文件,即波形文件。Microsoft Sound System软件Sound Finder可以转换AIF SND和VOD文件到WAV格式。

★ VOC文件:Creative公司波形音频文件格式,也是声霸卡(sound blaster)使用的音频文件格式。每个VOC文件由文件头块(header block)和音频数据块(data block)组成。文件头包含一个标识版本号和一个指向数据块起始的指针。数据块分成各种类型的子块。如声音数据静音标识ASCII码文件重复的结果重复以及终止标志,扩展块等。

★ MIDI文件:Musical Instrument Digital Interface(乐器数字接口)的缩写。它是由世界上主要电子乐器制造厂商建立起来的一个通信标准,以规定计算机音乐程序电子合成器和其它电子设备之间交换信息与控制信号的方法。MIDI文件中包含音符定时和多达16

个通道的乐器定义,每个音符包括键通道号持续时间音量和力度等信息。所以MIDI文件记录的不是乐曲本身,而是一些描述乐曲演奏过程中的指令。

★ RMI文件:Microsoft公司的MIDI文件格式,它可以包括图片标记和文本。

★ PCM文件:模拟音频信号经模数转换(A/D变换)直接形成的二进制序列,该文件没有附加的文件头和文件结束标志。在声霸卡提供的软件中,可以利用VOC-HDR程序,为PCM 格式的音频文件加上文件头,而形成VOC格式。Windows的Convert工具可以把PCM音频格式的文件转换成Microsoft的WAV格式的文件。

★ AIF文件:Apple计算机的音频文件格式。Windows的Convert工具同样可以把AIF格式的文件换成Microsoft的WAV格式的文件。

第三章设计思想

1.设计思路

根据项目要求,概要设计如下:图2

1.建立一个MFC AppWizard(exe)工程,应

用程序类型为基本对话框;

2.为工程添加若干按钮,用来实现播放、

列表等控制功能;

3.为工程添加一个列表框,用来显示歌曲

列表;

4.添加滑块用来控制音量;

5.对面板进行布局设计,留出位置显示歌

曲播放信息等;

6.为播放器工程控件进行编程实现功能。

2.系统结构功能

本程序的系统结构功能分为四块:

歌曲列表操作功能;

播放控制功能;

音量控制功能;

面板操作功能。

关系图如下:

详细说明:

一、面板操作功能:

最小化:程序将在系统托盘显示小图标,点击图标,程序会重新显示;

关闭:程序先自动保存歌曲到List.m3u在程序同目录下,然后关闭;

拖动:鼠标按住程序面板的空白处可将程序拖动。

二、歌曲列表操作功能:

添加文件:分为添加文件和添加目录

在添加文件时,我将每首歌曲的完成路径存在一个m_FileList[]数组里,当播放的时候,实际上时从这个数组里面取得歌曲路径来播放的;同时将每首歌取得文件名一一添加到列表里面,这样列表显示的歌曲名和数组里面的路径时一一对应的。并且,用一个变量来记录列表文件总数,再添加文件时,就可以接着添加而不是覆盖。

删除文件:分为删除单个文件和清空列表

删除文件时,除了要删除列表里的条目,还要对应的删除数组里面的数据,这时候我先得到列表的索引项,然后删除数组里对应的一项就可以了,然后将数组这项后面的数据一次前移,一个简单的循环就可以解决了。同时,列表文件总数变量的值也要相应减少,这样在删除文件的时候可以保持数组和列表框始终一致。

保存列表:保存列表文件到*.m3u文件。

**补充:双击列表项,播放选中歌曲。

三、播放控制功能

播放:点击播放时,如果临时文件名变量tempname(用来存储当前播放歌曲的路径,同时可以间接判断列表有没有文件)里没有内容,说明列表为空,就会自动执行添加文件,并将第一首曲目的路径赋值给tempname,并开始播放,播放键就会变成暂停键。

暂停:点击暂停时,我先用变量记录现在播放的位置,然后停止播放,暂停键恢复成播放键,,再播放的时候,先读取记录的位置,然后从那个位置接着再播放。

停止:播放停止,但tempname仍然保留刚刚播放的歌曲路径。

前一首/下一首:用一个变量记录当前列表的索引,点前一首(下一首)时,先停止播放,该变量-1(+1),然后根据这个变量重新从数组读取路径再播放,如果是第一首(最后一首),即该变量为0(文件总数),则该变量变为文件总数(0)。如果列表文件则执行添加文件功能。

音量控制功能:

静音/恢复:静音时音量清零,同时用一个MuteFalg标记是否静音,恢复时读取滑块的值,再设置音量。

音量增/减:在非静音情况下有效。

由于MCI(高层音频服务媒体控制接口)音量设置是针对正在播放的歌曲,当播放另一首歌时又恢复到默认值,所以我在每次播放之前都先读取滑块的值,设置好音量再播放;而在播放中音量控制可以随着滑块的滚动得到的数值来改变音量。

第四章音频播放器的程序设计过程

1、高层音频服务媒体控制接口MCI

MCI(Media Control Interface)媒体控制接口是MircroSoft提供的一组多媒体设备和文件的标准接口,它的好处是可以方便地控制绝大多数多媒体设备包括音频、视频、影碟、录像等多媒体设备,而不需要知道它们的内部工作状况。但是古人云:成也萧何,败也萧何。MCI虽然看上去高大全,但对于一些高级应用来说,它是远远不够的。好比Visual C++虽然看上去无所不能,却需要程序员自己开发多媒体引擎一样。对于MCI指令集,我们将只作简单介绍,重点放在后面的波形文件混音器上。

§1.1 MCI的控制方式:

一般说来,程序员使用两个函数就可以与MCI打交道了:

(1): MCIERROR mciSendCommand(MCIDEVICEID wDeviceID, UINT uMsg, DWORD dwFlags, DWORD dwParam );

此命令字符串方式,用接近于日常生活用语的方式发送控制命令,适用于高级编程如VB、TOOLBOOK等。

(2): MCIERROR mciSendString(LPCTSTR lpszCommand,LPTSTR lpszReturnString, UINT cchReturn, HANDLE hwndCallback);

此命令消息方式,用专业语法发送控制消息,适用于VC等语言编程,此方式直接与MCI设备打交道。

对于mciSendCommand,第一个参数指定了设备标识,这个标识会在程序员打开MCI设备时由系统提供。第二个参数指定将如何控制设备,详细请查阅后面“MCI指令”一栏。第三个参数为访问标识,第四个参数一般是一个数据结构,标识程序在访问MCI时要的一些信息。

对于mciSendString,第一个参数为一串控制字符串,返回信息由系统填入第二个参数,第三个参数指明返回信息的最大长度,若对MCI装置设定了"notify"标志则需要在第四个参数填上返回窗口句柄。

举例:

mciSendCommand(DeviceID,MCI_CLOSE,NULL,NULL);//关闭一个MCI设备;

mciSendString("open aaa.avi",0,0,0); //打开文件"aaa.avi";

§1.2 MCI的设备类型:

MCI的设备类型有:

设备描述描述字符串说明

MCI_ALL_DEVICE_ID 所有设备

MCI_DEVTYPE_ANIMATION Animation 动画设备

MCI_DEVTYPE_CD_AUDIO Cdaudio CD音频

MCI_DEVTYPE_DAT Dat 数字音频

MCI_DEVTYPE_DIGITAL_VIDEO Digitalvideo 数字视频

MCI_DEVTYPE_OTHER Other 未定义设备

MCI_DEVTYPE_OVERLAY Overlay 重叠视频

MCI_DEVTYPE_SCANNER Scanner 扫描仪

MCI_DEVTYPE_SEQUENCER Sequencer MIDI 序列器

MCI_DEVTYPE_VCR Vcr 合式录像机

MCI_DEVTYPE_VIDEODISC Videodisc 激光视盘

MCI_DEVTYPE_WAVEFORM_AUDIO waveaudio Wave 音频

对于未在上面定义的MCI设备,用户可查看system.ini文件中[mci]部分,例如:[mci]

cdaudio=mcicda.drv

sequencer=mciseq.drv

waveaudio=mciwave.drv

avivideo=mciavi.drv

videodisc=mcipionr.drv

vcr=mcivisca.drv

ActiveMovie=mciqtz.drv

QTWVideo=mciqtw.drv

MPEGVideo=C:\PROGRA~1\XING\XINGMP~1\xmdrv95.dll

其中最后两句分别指明了Apple的QuickTime设备,设备名为"QTWVidio"、MPEG影像设备,设备名为"MPEGVideo"。

在MCI编程中,既可以将设备描述当设备名,也可以将描述字符串当设备名,一个极端偷懒的办法是程序员不要在程序中指定设备名,Windows将自动根据文件扩展名识别设备类型。

举个例子来说,打开一个多媒体文件有以下三种方式:

[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); 注意三种打开方式中,函数第三个参数的区别,后面会讲到这种区别。

§1.3MCI指令

MCI使用如下指令:

MCI_BREAK

设置中断键,缺省是”CTRL+BREAK"

MCI_CAPTURE

抓取当前帧并存入指定文件,仅用于数字视频

MCI_CLOSE

关闭设备

MCI_CONFIGURE

弹出配置对话框,仅用于数字视频

MCI_COPY

拷贝数据至剪贴板

MCI_CUE

延时播放或录音

MCI_CUT

删除数据

MCI_DELETE

删除数据

MCI_ESCAPE

仅用于激光视频

MCI_FREEZE

将显示定格

MCI_GETDEVCAPS

获取设备信息

MCI_INDEX

当前屏幕显示与否,仅用于VCR设备

MCI_INFO

获取字符串信息

MCI_LIST

获取输入设备数量,支持数字视频和VCR设备

MCI_LOAD

装入一个文件

取消或做一个记号,与MCI_SEEK配套MCI_MARK

取消或做一个记号,与MCI_SEEK配套MCI_MONITOR

为数字视频指定报告设备

MCI_OPEN

打开设备

MCI_PASTE

粘帖数据

MCI_PAUSE

暂停当前动作

MCI_PLAY

播放

MCI_PUT

设置源、目的和边框矩形

MCI_QUALITY

定义设备缺省质量

MCI_RECORD

开始录制

MCI_RESERVE

分配硬盘空间

MCI_RESTORE

拷贝一个bmp文件至帧缓冲

MCI_RESUME

使一个暂停设备重新启动

MCI_SAVE

保存数据

MCI_SEEK

更改媒体位置

MCI_SET

设置设备信息

MCI_SETAUDIO

设置音量

MCI_SETTIMECODE

启用或取消VCR设备的时间码

MCI_SETTUNER

设置VCR设备频道

MCI_SETVIDEO

设置video参数

MCI_SIGNAL

在工作区上设置指定空间

MCI_STATUS

获取设备信息

使播放设备跳帧

MCI_STOP

停止播放

MCI_SYSINFO

返回MCI设备信息

MCI_UNDO

取消操作

MCI_UNFREEZE

使使用MCI_UNFREEZE的视频缓冲区恢复运动

MCI_UPDATE

更新显示区域

MCI_WHERE

获取设备裁减矩形

MCI_WINDOW

指定图形设备窗口和窗口特性

其中比较常用的指令有MCI_OPEN、MCI_CLOSE、MCI_PLAY、MCI_STOP、MCI_PAUSE、MCI_STATUS等等。

§1.4 MCI处理流程

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

打开一个MCI设备。

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

最后关闭MCI设备。

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

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

1.OpenMci

首先,我们初始化一个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,告诉系统播放完后要通知自己。

3. QueryMci:

要想检测MCI播放状态,就要发送指MCI_STATUS,并标志MCI_STATUS_ ITEM,返回值在结构MCI_STATUS_PARMS的dwReturn上。

2、系统模块窗体的设置

图3

一、歌曲列表操作

1.打开文件

void CMyPlayerDlg::OnOpen()

{

static char szFileFilter[]="所有音频文件|*.mp3;*.wma;*.wav;*.mid;*.rmi|"

"Mp3文件(*.mp3)|*.mp3|"

"Wma文件(*.wma)|*.wma|"

"Wave文件(*.wav)|*.wav|"

"Mid文件(*.mid;*,rmi)|*.mid;*.rmi|"

"列表文件(*.m3u)|*.m3u|";//文件类型过滤

CFileDialog dlg(TRUE,NULL,NULL,OFN_HIDEREADONLY,szFileFilter);

dlg.m_ofn.Flags |= OFN_ALLOWMULTISELECT;

CString csfncbl;

POSITION pos=dlg.GetStartPosition();

if(dlg.DoModal()==IDOK)

{

fi=m_totalFiles;

while (pos != NULL)

{

CString strExt;

strExt = dlg.GetFileExt();

strExt.MakeLower();

if(strExt == _T("m3u"))

{//读取列表文件.m3u文件

csfncbl = dlg.GetNextPathName( pos);

ReadFromM3U(csfncbl); //读取列表函数

}

else

{//读取文件到曲目路径列表

m_FileList[fi]=dlg.GetNextPathName(pos);

if(tempname=="")

{

tempname=m_FileList[fi];

fr=fi;

OnStop();

OnPlay();

showname();

}

CString strName;

int n = m_FileList[fi].ReverseFind('\\');

int n1 = m_FileList[fi].GetLength();

if(n>0)

{

strName = m_FileList[fi].Right(n1-n-1);

}

if(strlen(strName)>35)strName=strName.Left(35) + "..."; m_list.AddString(strName);

m_list.SetCurSel(fr);

UpdateData(false);

fi++;

}

}

m_totalFiles=fi;//保存曲目总数

}

transfer();

}

2.读取列表文件.m3u文件函数

void CMyPlayerDlg::ReadFromM3U(const char * cFileName)

{

char buf[1024];

ifstream ifs(cFileName);

fi=m_totalFiles;

while (ifs.good())

{

ifs.getline(buf, 1024);

CString cs(buf);

if(!cs.IsEmpty())

{

if(tempname=="")

{

tempname=cs;

fr=fi;

OnStop();

OnPlay();

showname();

}

CString strName;

int n = cs.ReverseFind('\\');

int n1 = cs.GetLength();

if(n>0)

{

strName = cs.Right(n1-n-1);

}

m_FileList[fi]=cs;

fi++;

if(strlen(strName)>35)strName=strName.Left(35) + "...";

m_list.AddString(strName);

m_list.SetCurSel(fr);

UpdateData(false);

}

m_totalFiles=fi;

}

transfer();

}

void CMyPlayerDlg::ReadList()

{

CString m_sPath;

CString str=theApp.m_pszHelpFilePath;

m_sPath=str.Left(str.ReverseFind('\\'));

::SetCurrentDirectory(m_sPath);

CString string;

string = m_sPath +"\\List.m3u";

Read(string);

}

void CMyPlayerDlg::Read(const char * cFileName)

{

相关文档