书签 分享 收藏 举报 版权申诉 / 71
上传文档赚钱

类型十一Symbian多媒体服务课件.ppt

  • 上传人(卖家):晟晟文业
  • 文档编号:4971751
  • 上传时间:2023-01-29
  • 格式:PPT
  • 页数:71
  • 大小:691.50KB
  • 【下载声明】
    1. 本站全部试题类文档,若标题没写含答案,则无答案;标题注明含答案的文档,主观题也可能无答案。请谨慎下单,一旦售出,不予退换。
    2. 本站全部PPT文档均不含视频和音频,PPT中出现的音频或视频标识(或文字)仅表示流程,实际无音频或视频文件。请谨慎下单,一旦售出,不予退换。
    3. 本页资料《十一Symbian多媒体服务课件.ppt》由用户(晟晟文业)主动上传,其收益全归该用户。163文库仅提供信息存储空间,仅对该用户上传内容的表现方式做保护处理,对上传内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知163文库(点击联系客服),我们立即给予删除!
    4. 请根据预览情况,自愿下载本文。本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
    5. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007及以上版本和PDF阅读器,压缩文件请下载最新的WinRAR软件解压。
    配套讲稿:

    如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。

    特殊限制:

    部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。

    关 键  词:
    十一 Symbian 多媒体 服务 课件
    资源描述:

    1、1第十一章第十一章多媒体服务多媒体服务 2v完成本章内容之后我们将能够:v 了解多媒体框架(MMF)v 使用MMF音频APIv 了解MMF视频概念,框架和相关API本本 章章 目目 标标3概述 本章先讲述多媒体架构,包括它的发展简史。然后,描述多媒体子系统的各个单独部分。4多媒体组件架构多媒体组件架构 在讨论多媒体的当前状态之前,先回顾Symbian OS中多媒体的发展历史。从历史上看,多媒体子系统包括用于处理下面多媒体领域的单独API:音频回放、录音和操作。静态图像解码、编码和操作。直到SymbianOS 7.0,这一切都没有发生变化,不过,对应的子系统却发生了相当大的变化。SymbianO

    2、S 7.0中的多媒体API主要是以前版本中出现的API的超集,在某些地方,同时存在新方法和遗留的方法。5多媒体组件架构多媒体组件架构 为了解释在SymbianOS 7.0中对多媒体子系统进行许多基本改进的原因,有必要回顾这操作系统以前版本中的子系统以及它们所面临的问题。这一节简要概述6.1和7.0中的Media服务器及进行更改的原因。6媒体服务器媒体服务器 在Symbian OS 6.1和7.0中,所有多媒体处理都通过媒体服务器(mediaserver)进行。这是一个标准Symbian OS服务器,是提供全部多媒体功能的单个进程。该服务器支持音频回放和录音,还支持对静止图像的编码/解码和处理。

    3、操作系统支持大量音频和图像格式,可以通过编写插件扩展这些格式。为了使用该服务器,用户可以显示实例化一个与服务器的连接,或允许客户端API自动提供一个连接。每个客户端用户将提供一个服务器的观察器类,使该服务器能够与用户应用程序或库通信传递消息。7媒体服务器媒体服务器 服务器保持一个客户端对象列表,并且并发循环处理多媒体请求。这意味着,许多不同的客户端用户可以同时使用该服务器,例如,让一个用户应用程序播放音频,同时解码用于显示的图像。尽管这听起来很理想,但产生这种行为的实际问题很复杂并且困难重重。例如,如果用户实际上希望同时使用服务器的两部分功能,让一个进程控制这两部分造成的潜伏期可能使系统实际上

    4、不可用。例如,一项处理器密集型任务(如解码图像)将阻止使用任何实时多媒体任务(如音频流式处理),音频流在设备驱动器中将非常迅速地下溢。当使用编写得很差的第三方插件(常常转换自非Symbian代码,并包含消耗大量处理器时间的冗长程序)时,情况更糟。插件框架本身就使得为之编程非常复杂,这并不会改善上述状况。8媒体服务器媒体服务器 上述各种问题,加上连接到服务器在最坏的情况下可能花费几秒钟的事实,意味着必须对此作出改进。9新时代的开始新时代的开始 Symbian开始编写全新的多媒体子系统,它将成功允许该子系统的不同功能同时使用,也提供手机制造商和第三方可以轻松扩展的轻量级框架。新系统不是只基于一个服

    5、务器,而是拆分不同的多媒体部分,以使用单独的服务器和进程。新的子系统使用多个并发多媒体线程,没有在媒体服务器中看到的任何副作用。它使用许多与媒体服务器相同的客户端API,但是使用了一个新的插件解决方案,称作ECom。这使得在电话制造过程中或出产以后,手机生产商和第三方能够编写和集成插件。10多媒体框架多媒体框架(MMF)(MMF)由于这个新的子系统如此成功,以至于很快被集成到Symbian OS 7.0中,Symbian OS 7.0只是刚刚开始它的开发生命周期。随着Symbian OS 7.0的发展进步,这个子系统演变成现在所谓的多媒体框架(MMF,MultimediaFramework)。

    6、MMF提供了在Symbian OS 7.0中能够处理多媒体的框架。这个框架本身十分轻量化,并且提供了一个基于ECom的多线程系统,它保留了从6.1到7.0中原始API的子集,还进行了很多改进。MMF的基本结构包括一个客户端API层、一个控制器框架、控制器插件和低层次子系统。图7.1显示了这个架构的概观。11多媒体框架多媒体框架(MMF)(MMF)图7.1 MMF架构 12多媒体框架多媒体框架(MMF)(MMF)在图7.1中,控制器框架可以看作是客户端/服务器层,它为MMF端控制器插件提供接口。子系统的每一部分的描述如下。13客户端客户端APIAPI 客户端API(有时也称为“应用程序API”)

    7、位于子系统中的最高抽象层。这些API为开发人员提供了MMF的基本功能。在Symbian OS 7.0中,存在用来生成正弦波音频音、音频和视频剪辑操作以及音频流的客户端API。除两种API以外,其余所有控制器框架都用来获取并控制相关的控制器插件,以执行多媒体任务。上述两种例外是音频流API和音频声音生成API,二者都不使用控制器框架,而是直接与DevSound层接口。DevSound层是一个低层API,这将在本章后续部分简短讨论。14控制器框架控制器框架 控制器框架提供了支持MMF内部多媒体插件的框架。它提供了MMF的客户API层与实际MMF控制器插件间的客户端服务器通信。它由以下几个逻辑模块构

    8、成。1.1.控制器插件解析器控制器插件解析器对于特定的应用程序,控制器插件解析器允许系统选择最佳插件。它提供了个API集,客户可以使用它们来获取插件(MMF客户端API就是其中之一)。2.2.控制器代理控制器代理控制器代理用来管理控制器框架之内的所有线程处理和线程间通信。这是标准Symbian OS客户端/服务器机制之上的一个简单层,用来提供控制器API的客户端与服务器端之间通信的方式。它不能直接使用,我们只是为了完整性而在此提及。15控制器框架控制器框架 3.3.控制器控制器APIAPI层层 控制器API层由控制器代理的客户端和服务器端的匹配类构成。应用程序(或MMF)使用客户端类(即RMM

    9、FController)来运用控制器插件的功能。服务器端类(CMMFController)是控制器插件编写者为了实现他们的插件而必须派生的类。这个类也把所有发送给控制器插件的信息解包。16控制器框架控制器框架 4.4.自定义命令自定义命令 根据设计,控制器插件API局限于非常基础的数据流操作。为了扩展该API,可以使用种自定义命令框架,它允许客户访问控制器特定的扩展。在一般情况下,MMF使用该框架为常规命令(称做“标准自定义命令”,如设置音量和获取平衡)的处理定义API。控制器插件的生产商特定API也可以使用该技术进行暴露。17控制器插件控制器插件 控制器插件为MMF提供特定的多媒体功能。控制

    10、器的基本任务是从一个或者多个源中引导数据,把数据转变成不同的格式,然后把数据传输到一个或者多个接收器。数据源一般是文件、麦克风或摄像头,而接收器一般为文件,扬声器或屏幕。控制器插件一般都支持播放和录制一种或多种多媒体格式,比如mp3或avi格式。它能够解读相关源或接收器中的原始数据,并从源中读取数据,进行必要的数据转换,然后写入接收器。控制器插件的架构略为复杂,超出了本书的讨论范围。不过,我们将简要介绍实现控制器插件的步骤,如下所述:18控制器插件控制器插件 实现MMF控制器插件的API。如上面“控制器框架”所述,所有MMF控制器插件都是由CMMFController基类派生而来。该基类提供控

    11、制器API,而且还提供诸如通过ECom插件框架实例化控制器插件的功能。在该基类中,需要重载的最基本函数集声明为纯虚函数,包括PlayL()和StopL()等函数。必须实现所有标准自定义命令集所需要的函数。这可以通过以下方式实现,先用适当的“自定义命令实现器”类派生控制器程序,然后使用CMMFController()和AddCustom CommandParserL()函数来注册这个该控制器,使其能够处理标准命令集。19控制器插件控制器插件 MMF提供了一组基类来协助编写控制器插件。这些基类包括数据源和接收器类,以及缓冲类。数据源和接收器类本身就是ECom插件,并且封装了文件、描述符、音频输入和

    12、输出的使用功能。当把数据由源传送到接收器的时候,缓冲用来存储这些数据。缓冲类 的类型有很多,但它们都是从CMMBuffer类派生而来。不同缓冲类的主要区别在如何存储数据,例如,数据是存储于描述符中,还是存储在内核端缓冲中。20控制器插件控制器插件 为了与控制器框架插件解析器一起工作,每个控制器插件(实际是每个ECom插件)均要求一个ECom插件资源文件。控制器框架插件解析器使用它标识该插件的多媒体功能,比如是否能够播放和录音,支持什么格式。21控制器插件控制器插件 可以在SDK中找到有关ECom插件的更多信息。MMF控制器插件可以具有硬件特定的源和接收器。对于所涉及的硬件,它通常是一种设计驱动

    13、器或一个自定义API,它由授权商或硬件商来实现。在Symbian OS 7.0中,惟一的例外是DevSoundAPl,它具有标准的实现,供参考音频控制器使用。22底层子系统底层子系统 在MMF架构的底层,存在许多子系统。授权商在生产新手机时可以实现这些子系统,它们一般与硬件相对应。子系统包含的内容主要取决于授权商的要求,这些层规定了手机的大部分多媒体功能。这些底层一般与第三方用户无关,不过,下面会简短介绍其中一个主要子系统DevSound。DevSoundDevSound 将Symbian OS移植到新平台时,授权商或硬件商实现CMMFDevSound类。它的API提供了MMF中音频回放和录音

    14、的最底层抽象,在音频设备驱动器之上提供了独立于硬件的层。DevSound API提供了对音频数据播放和录音的支持、对播放音频音的支持以及对音量、对平衡等音频硬件属性修改的支持。23底层子系统底层子系统 另外,DevSound包括一种在同时使用声音硬件的不同客户间进行仲裁的方式。这种仲裁层处理声音的优先级(在客户API中设置),它的单个优先级层由授权商定义。典型用法是在中断低优先级客户(如MP3播放器)时,决定DevSound处理高优先级客户(如电话铃声)的方式。也可以包含“优先级首选”的使用,它可以按请求优先级的同样方式来请求,用于决定高优先级声音挂起时,对低优先级声音如何处理。例如,可以选择

    15、终止低优先级的声音,或与高优先级声音进行混音。24使用使用MMFMMF 观察器模式观察器模式 在开始前,有必要提一下整个MMF的通用设计模式,即所谓的“观察器模式(observer pattern)”。使用观察器类可以为API用户提供反馈。这些类是作为“混合”类而实现,并定义了组观察器纯虚函数。该模式不局限于MMF,而广泛应用于Symbian OS。在第4章可以看到利用观察器类向控件报告重要事件的例子。为使用MMF客户API,你需要创建一个派生自相关观察器类的对象,提供其虚函数的实现,并将该对象的一个引用传递给MMF客户实用程序。正如下述实例所示,常常从观察器类派生MMF客户本身。25使用使用

    16、MMFMMF 在MMF中,观察器函数的通常用途是通知实用程序的创建、或者特定范围内操作的开始或结束,并提供错误码和状态信息。值得注意的是,观察器模式依赖于活动对象的使用,也就是说活动规划器必须一直运行,以便客户API能够正常工作,因为它处于标准GUI应用程序中。26使用音频使用音频 MMF音频API可用于处理简单的音调产生、音频剪辑处理(播放、录制和转换)以及音频流化(播放和录音)。当初次在软件中使用音频时,可能难以理解实际发生的事情以及声音是如何保存的。图7.3说明了一些基本概念。图7.3 模数转换和数模转换27使用音频使用音频 1.1.模数转换模数转换 将音频转换为数字形式的第一步,通常是

    17、模拟到数字的转换。这是通过所谓的“模数转换器”或“ADC”的微型芯片实现的。例如,在用麦克风录音时,麦克风将声音波形转换为电子信号,然后在ADC阶段将电子信号转换为二进制数据?二进制数据就可以被处理,并存入内存或保存到文件中。2.2.数模转换数模转换 相反的处理称为数模转换。在这一步,音频数据的二进制序列通过所谓的“数模转换器”或“DAC”的微型芯片进行转换。这些芯片输出模拟电子信号,然后电子信号再通过扬声器等硬件转变为声音波形。28使用音频使用音频 3.3.数字音频格式数字音频格式 所有数字音频均以特定格式存储,该格式描述音频的各个细节。此信息包括音频录制的取样速率(ADC的每秒取样个数)、

    18、通道个数以及是否将音频编码为要求分离解码阶段的状态。未压缩的音频称为脉冲编码调制(PCM,PulseCodeModulation),在任一给定时刻,将音频取样直接度量为已知音频信号的振幅。例如,一个50Hz正弦波的数字PCM取样看起来如图7.4所示。在此图中,使用了16位PCM编码格式。这也就意味着,数字音频取样将以16位存储,该值的范围为32768+32767。这些值对应正弦波的波谷和波峰。图上的每个点对应需要保存的取样。29使用音频使用音频 图7.4 正弦波的数字取样 以PCM音频格式存储,这些取样不需要再进行任何处理,因此每个取样将占用16位或两个字节。音频数据如何以其他格式存储,依赖于

    19、应用到信号上的附加处理。比如,压缩信号的音频数据可能包含所使用的转换系数。30使用音频使用音频 4.4.音频剪辑音频剪辑 剪辑可以看做是音频或视频的一个“包”。它有明确定义的开始和结束,并且通常将描述其格式的信息一起打包,如取样速率和编码方式。剪辑通常包含在文件或描述符中,尽管某些客户API也允许将URL看做剪辑。5.5.音频流音频流 音频流由音频数据的连续流组成,它没有明确定义的开始和结束。音频数据流可以是大小不等的间断块。例如,从因特网上获取流的RealAudio。31播放音调播放音调 音调播放器实用工具类CMdaAudioToneUtility在mdaaudiotoneplayer.h中

    20、定义。它提供播放单独的单声道正弦波音调、用户自定义双音(Nokia6600手机不提供)、双音多频(DTMF)或音调序列的能力。在典型应用程序中,DTMF用于在打电话期间模仿电话按键,音调序列文件用于产生铃声。希望使用音调播放器实用工具的客户,必须先从MMdaAudioToneObserver派生一个观察器类,MMdaAudioToneObserver的类定义显示如下:32播放音调播放音调 class MMdaAudioToneObserver Public:virtual void MatoPrepareComplete(Tint aError)=0;virtual void MatoPlay

    21、Complete(TInt aError)=0;通过调用NewL()函数创建的音调播放器实用工具,向观察器类提供一个引用作为参数。然后需要以下两个步骤来播放音调。33播放音调播放音调 (1)调用适当的“预备”函数预备待播放的音调。客户通过观察器的MatoPrepareComplete()函数获知预备工作已完成。如果预备工作成功完成,则以错误值KEnNone调用该函数,否则将报告相应的错误码,例如,当设备不支持音调回放时,错误码为KErrNotSupported。(2)如果预备成功,客户就可以开始播放音调,或者针对该音调执行其他处理,比如设置音量。如果发生错误,则决不可以调用这些函数,因为底层子

    22、系统没有正确初始化。通过调用观察器的MatoPlayComplete()函数,客户可以知道何时音调播放完成。这组事件对于三种音调播放API是通用的。惟一不同的是,作为参数传递给相关“预备”函数的数据。34播放音调播放音调 audi04例程演示了如何使用音调播放实用工具,并播放3秒2600Hz的音调。按照前面所描述的观察器模式,应用程序的引擎类实现了音频音调观察器的函数。如下所示:class CAudio4Engine :public CBase,public MMdaAudioToneObserver public:/从MMdaAudioToneObserver void MatoPrepar

    23、eComplete(TInt aError);void MatoPlayComplete(TInt aError);35播放音调播放音调应用程序引擎的ConstructL()很简单:void CAudio4Engine:ConstructL()iUtility=CMdaAudioToneUtility:NewL (*this);iUtility-PrepareToPlayTone(KFrequency,TTimeIntervalMicroSeconds(KDuration);36播放音调播放音调 它首先通过调用NewL()函数创建CMdaAudioToneUtility的一个实例,并传递自身的

    24、一个引月作为观察器。然后调用实用工具的PrepareToPlayTone()函数预备音调,并传递以赫兹为单位的音调频率和以微秒为单位的音调持续时间。在该例中,KFrequency和KDuration的值为2600和3000000。需要注意的是,在任一给定时刻,只能存在一个预备的音调。如果再次调用PrepareToPlayTone(),则新的音调将取代原先的那个音调。当音调实用工具预备好音调以后,它调用MatoPrepareComplete():37播放音调播放音调void CAudio4Engine:MatoPrepareComplete(TintaError)if(aError=KErrNo

    25、ne)iUtility-SetVolume (iUtility-MaxVolume ();iState=EReady;如果预备成功,传递给该函数的错误码为KErrNone。任何其他值都表明个错误。例如,如果声音设备已经被一个更高优先级的进程使用,则该值为KErrlnUse。38播放音调播放音调 有重要的一点需要注意,音调实用工具预备音调和调用MatoPrepareComplete()的时间没有定义。在有些设备上可能立即发生,而在另外一些设备上则可能存在非常明显的延迟,因此,不要使用单个音调播放API来播放由一系列音调组成的曲子。这种情况下,应该使用音调序列API来代替。现在音调已准备好,客户可

    26、以调用Play()来播放它了:void CAudio4Engine:PlayL()iUtility-Play();iState=EPlaying;39播放音调播放音调 当音调播放完以后,将调用MatoPlayComplete()函数:void CAudio4Engine:MatoPlayComplete (TInt/*aError*/)iState=EReady;回放成功的话,会传递错误码KErrNone给该函数。在该例中,忽略了错误码,但在真正的应用程序中,却要注意可能由于试图再次开始播放音调所造成的错误。通过多次调用P1ay()函数而不必调用 PrepareToPlayTone(),可以重

    27、复播放音调。然而,如果想播放不同类型的音调,则必须另外再调用PrepareToPlayTone()。40播放音调播放音调 注意一个有趣的地方,音频实用工具不像后面将看到的其他许多实用工具,它没有Stop()函数。作为代替,可以使用CancelPlay()函数停止一个已开始播放的音调:void CAudio4Engine:StopL()iUtility-CancelPlay();在完成播放以前取消音调,会阻止对观察器的MatoPlayComplete()函数的调用。使用完音调实用工具之后,通过简单地销毁音调发生器对象,就可以完成音频设备的所有必要的清除工作。41播放音调播放音调 该实例演示了如何

    28、播放单个正弦波音调音调,不过播放双音、DTMF音和音调序列的原理相同。对于每种音调,都有一个对应的“预备”函数,一旦预备好,就可以利用Play()和CancelPlay()来播放音调和停止音调。在每一种情形中,都会调用上述的相同的观察器函数。作为导引,下面列出用于其他音调类型的“预备”函数的信息:双音具有同一持续时间的两个音调频率。DTMF对包含DTMF音调列表的描述符的引用。来自文件的序列对音调序列文件的文件名的引用。来自描述符的序列对包含音调序列的描述符的引用。固定序列引用通过硬编码预定义音调序列的整数。42播放音调播放音调 Symbian OS不指定用于定义音调序列的格式,因此,通常手机

    29、与手机之间的格式会不同。DTMF音调序列通常由包含0123456789#*字符集中字符的文本串指定,但该格式也可以由设备指定。请参考特定手机的SDK,获得特定手机所使用的准确格式的详细信息。43播放剪辑播放剪辑 音频播放器实用工具CMdaAudioPlayerUtility定义在mdaaudiosampleplayer.h中,它提供播放取样音频数据的能力。取样音频数据可由文件(如WAV文件)或描述符(TDes8或TDesC8)提供,或者也可以定位于特定的URL地址。音频播放器实用工具提供标准的功能,用于播放和停止播放音频数据,以及设置音量和平衡等等。它还提供许多更高级的操作,如音量倾斜、重复设

    30、置、元数据处理和传递定制命令到当前MMF控制器。元数据是包含在音频剪辑中的非音频数据。例如,WAV文件可以包含该文件何时创建、以及由谁创建的信息。44播放剪辑播放剪辑 在决定使用哪个实用工具来播放剪辑时,可以选择音频播放器或音频记录器(描述见下一节),记录器包含播放和录制剪辑两种功能。通常会使用音频记录器实用工具,它提供最为灵活的选择,不过使用音频播放器实用工具是播放剪辑的最简单方法。希望使用音频播放器实用工具的客户,必须首先从MMdaAudioPlayerCa!lback类中派生一个观察器类,MMdaAudioPlayerCallback类的定义如下:45播放剪辑播放剪辑 class MMd

    31、aAudioPlayerCallbackpublic:virtual void MapcInitComplete(TInt aError,constTTimeIntervalMicroSeconds&aDuration)=0;virtual void MapcPlayComplete(TInt aError)=0;创建音频播放器实用工具的标准方式是使用NewL()函数,该函数同样将一个引用传递给观察器类。与音调播放实用工具一样,播放剪辑也分为两个不连续的阶段。46播放剪辑播放剪辑 (1)剪辑必须使用下面介绍的相应“打开”函数来打开。调用观察器的MapclnitComplete()函数表示这一阶

    32、段完成。如果剪辑成功打开,则以错误码KErrNone调用该函数,但是如果剪辑格式不可识别,则错误码为KErrNotSupported。(2)如果剪辑成功打开,则客户既可以开始播放剪辑,也可以处理设置,如音量。当剪辑完成播放时,调用观察器的MapcPlayComplete()函数。对于播放三种可能来源中的每一种音频,这组事件都是通用的,惟一的不同是传递给相应“打开”函数的数据传递给OpenFileL()的是一个文件名,传递给OpenDesL()的是一个描述符,而传递给OpenUrlL()的是一个URL。47播放剪辑播放剪辑 使用OpenUrlL()函数,也可以指定一个因特网接入点ID。这将指示控

    33、制器使用特定的接入点代替其默认接入点。有关此参数类型的更多信息,请参考mmfurlh中的CMMFUrlSink类。如果知道了音频实用工具只是用于处理某一特定类型的剪辑时,就可以通过使用NewDesPlayerL()、NewDesPlayerReadOnlyL()或NewFilePlayerL()函数中的一个来创建一个实例,代替调用NewL()。另外要为这些函数提供包含音频数据本身或者音频剪辑文件名的描述符。这些函数封装了播放器实用工具的实例化和打开阶段,所以在完成时,它们会尝试打开提供的剪辑,并以相应的错误码调用观察器的MapclnitComplete()函数。48播放剪辑播放剪辑 实例aud

    34、i01说明了如何打开一个WAV文件并播放它。利用实用工具的NewFilePlayerL()函数,应用程序引擎的SetFileL()函数创建音频播放器实用工具类的一个实例,创建它的明确目的就是播放一个单独的文件:void CAudiolEngine:SetFileL(constTDesC&aFileName)if(iUtility)delete iUtility;iUtility=CMdaAudioPlayerUtility:NewFilePlayerL(aFileName,*this);49播放剪辑播放剪辑 引擎本身派生于观察器类。NewFilePiayerL()不仅创建实用工具,而且尝试打开

    35、剪辑、导致调用观察器的MapclnitComplete()函数、传递错误码和音频剪辑的持续时间。void CAudiolEngine:MapcInitComplete(TIntaError,const TTimeIntervalMicroSeconds&/*aDuration*/)if (aError=KErrNone)iState=EReady;iAppUiUpdateViewL();50播放剪辑播放剪辑 在该例中,持续时间被忽略,但在真正的应用程序中可能会用到,比如显示剪辑的剩余播放时间。有一点很重要,在没有调用错误码为KErrNone的MapclnitComplete()之前,不要调用P

    36、lay()、SetVolume()或SetRepeats()之类的函数,否则会发生严重错误。在使用这些函数时,这种错误是最常犯的错误。确保不发生这种错误的一个有效方法,是从MapclnitComplete()函数中直接调用Play()。如果剪辑已经成功打开,就可以使用Play()函数播放它。void CAudiolEngine:PlayL()iUtility-Play();iState=EPlaying;51播放剪辑播放剪辑 当剪辑播放完时,调用MapcPlayComplete()函数。void CAudiolEngine:MapcPlayComplete(Tint/*aError*/)iSt

    37、ate=EReady;成功的回放会导致调用错误码为KErrNone的MapcPlayComplete()函数。如同前面的例子,忽略错误码。例如,更实际的应用程序对KErrlnUse错误的响应,可能会是再次尝试播放剪辑。52播放剪辑播放剪辑 播放完成之后,可以通过再次调用Play()重放剪辑,而不必调用“打开”函数。在播放新剪辑之前,必须通过调用实用工具的Close()函数关闭当前剪辑,并利用相应的“打开”函数打开新的剪辑。如果像这个例子中一样,创建了用于播放指定剪辑类型的实用工具,那么为了播放不同类型的数据,必须要创建一个新实例。播放剪辑以前,可以通过SetPlayWindow()函数设置个“

    38、播放窗口”,并以微秒为单位提供窗口的开始和结束时间。完成后,播放就要受限于窗口中的剪辑部分。默认情况下,播放窗口为剪辑的整个长度。在播放剪辑时,可以利用实用工具的Stop()和Pause()函数停止播放。Stop()函数把剪辑的位置复位到当前播放窗口的开始,而不是复位到整个剪辑的开始。53录制剪辑录制剪辑 定义在mdaaudiosampleeditor.h中的音频记录器实用工具CMdaAudioRecorderUtility派生自CMdaAudioClipUtility。它包含CMdaAudioPlayerUtility所提供的功能超集,增加了录制和播放剪辑的功能。与播放器实用工具一样,音频数

    39、据可以在文件(如WAV文件)、描述符(TDes8或TDesC8)或远程URL中进行处理。如前所述,当播放或录制剪辑时,通常会选择使用这个类。除了提供播放、录制、停止、设置音量、设置平衡等基本功能外,该类还允许从当前剪辑中裁剪数据,从当前读/写位置到数据的开头或结尾进行处理。与播放器实用工具一样,该类还提供许多更高级的操作,如音量倾斜、重复设置、元数据处理和传递定制命令给当前MMF控制器。54录制剪辑录制剪辑 除有一个例外(后面会解释),音频记录器实用工具的播放功能与播放器实用工具的功能样,所以这里将着重介绍录制功能。与使用其他实用工具一样,希望使用音频记录器实用工具的客户,必须首先从MmdaO

    40、bjectStateChangeObserver派生一个观察器类,以下是MMdaObjectStateChangeObserver的类定义:class MMdaObjectStateChangeObserver public:virtual void MoscoStateChangeEvent(CBase*aObject,TInt aPreviousState,TInt aCurrentState,TInt aErrorCode)=0;55录制剪辑录制剪辑 使用这个观察器类比使用播放器和音调实用工具的观察器类稍微复杂一点。只要记录器实用工具对象的状态发生变化,就会调用MoscoStateCha

    41、ngeEvent(),并传递一个指向实用工具对象本身的指针、以前状态和当前状态以及一个错误码。因为提供了对象指针,观察器就能够观察不止一个实用工具对象。记录器实用工具可能的操作状态在CMdaAudioClipUtility父类中枚举,如下所示:56录制剪辑录制剪辑 使用这个观察器类比使用播放器和音调实用工具的观察器类稍微复杂一点。只要记录器实用工具对象的状态发生变化,就会调用MoscoStateChangeEvent(),并传递一个指向实用工具对象本身的指针、以前状态和当前状态以及一个错误码。因为提供了对象指针,观察器就能够观察不止一个实用工具对象。记录器实用工具可能的操作状态在CMdaAud

    42、ioClipUtility父类中枚举,如下所示:enum TState ENotReady=0 EOpen,EPlaying,ERecording ;57录制剪辑录制剪辑 音频记录器实用工具利用NewL()函数创建,通常,该函数以观察器的引用为参数。然后,音频的录制按照与使用播放器实用工具进行播放的相似步骤进行。(1)必须使用相应的“打开”函数打开剪辑。在完成时,调用观察器的MoscoStateChangeEvent()函数,以EOpen的当前状态和一个错误码为参数,如果剪辑打开成功,该错误码是KErrNone。(2)如果成功打开,则客户既可以开始录制剪辑,也可以处理设置。与播放器实用工具样,

    43、当发生错误的状态时,不能调用这些函数。在开始录制剪辑时,调用观察器的MoscoStateChangeEvent()函数,以当前状态ERecording为参数进行调用。当完成录制剪辑时,再次调用观察器的MoscoStateChangeEvent()函数。如果录制被一个Stop()调用中断,则错误码为KErrNone;如果剪辑录制达到用户定义的限定长度,则错误码为KErrEof;如果发生其他错误情况,则会是其他错误码。58录制剪辑录制剪辑 与使用播放器实用工具一样,对于三种音频记录剪辑类型,这组事件都是通用的,惟一的不同也是传递给相应“打开”函数的数据。与剪辑播放实用工具相比,这里有更多种类的“打

    44、开”函数。其中有些函数采用一个TMdaClipFormat参数(该数据结构将在后面音频转换的章节中作简要介绍),有些允许调用者选择特定的控制器插件,而不是由MMF架构选择它认为适用的插件。最后,记录器实用工具提供了一些接受媒体服务器遗留参数的“打开函数。通常,如果作为参数提供给“打开”函数的目标文件并不存在,则创建该文件,并使用特定的文件扩展名作为使用格式的线索。59录制剪辑录制剪辑 audi02例程演示了记录器和转换实用工具的使用,并且直接使用了7.6节所描述的控制器框架。本节着眼于使用记录器实用工具打开一个WAV文件并进行录制。60录制剪辑录制剪辑 在实例audi02的引擎中,Constr

    45、uctL()函数创建音频记录器实用工具类的个实例,使用的是现在已经变得熟悉的模式,表明引擎本身就是实用工具的观察器:void CAudio2Engine:ConstructL()delete iUtility;iUtility=NULL;iUtility=CMdaAudioRecorderUtility:NewL(*this);iUtility-OpenFileL(KFileName);61录制剪辑录制剪辑 创建了实用工具之后,ConstructL()打开用于录制的文件,这会引起观察器的MoscoState ChangeEvent()函数被调用,并以EOpen的当前状态及一个错误码KErrNo

    46、ne为参数。void CAudio2Engine:MoscoStateChangeEvent(CBase*aObject,TInt aPreviousState,TInt aCurrentState,TInt aErrorCode)if(aErrorCode!=KErrNone)/消息 iState=ENotReady;return;62录制剪辑录制剪辑 if(aObject=iUtility)switch(aCurrentState)case CMdaAudioClipUtility:EOpen:iState=EReady;break;case CMdaAudioClipUtility:ER

    47、ecording:iState=ERecording;break;case CMdaAudioClipUtility:EPlaying:iState=EPlaying;break;default:;63录制剪辑录制剪辑 else/必须为转换器 在该例中,MoscoStateChangeEvent()所报告的状态用于维护一个内部状态机。任何错误都会使内部状态置为ENotReady,该状态用于表示实用工具类不可用。64录制剪辑录制剪辑 在开始录制之前,可能会使用如下函数设置一或多个录制参数:SetDestinationDataTypeL0。SetDestinationFormat()。SetDes

    48、tinationBitRate()。SetDestinationSampleRateL()。SetDestinationNumberOfChannels()。SetMaxWriteLength()。目标数据类型是作为TFourCC提供的,它规定使用MmfFourCC.h中所定义的正确编码方法。65录制剪辑录制剪辑 作为mmfFormatlmplemetationUIDs.hrh中定义的一种UID而指定目标格式,并决定文件的数据头部和结构类型。有意思的是,写长度的最大值是以千字节为单位设置,而不是所期望的以微秒为单位。其余函数的参数通常都为整数,并且它们的含义不言自明。66录制剪辑录制剪辑 以上

    49、列出的几乎所有函数,都可以通过实用工具的各种GetSupportedXxxL()函数,来查询实用工具以确定适用的参数。这里面惟一的例外是设置写长度的最大值。不过,RecordTimeAvailable()函数可以以微秒为单位,返回当前剪辑可用于录制的最大时间。如果剪辑已经成功打开,可以使用Record()函数开始录制,这会再次导致以ERecording状态为参数调用观察器的MoscoStateChangeEvent()函数。void CAudio2Engine:StartRecordingL()iUtility-SetAudioDeviceMode(CMdaAudioRecorderUtili

    50、ty:EDefault);iUtility-RecordL();67录制剪辑录制剪辑 调用Record()以前,例程调用SetAudioDeviceMode(),该函数用于指定录制和播放声音的设备。在一般手机上,既可以从手机的麦克风录制,也可以从当前的电话通话中录制,并且可以通过手机的耳机或主扬声器播放。例程指定了默认的来源,这样通常就会在有通话时从电话通话中录制,没有通话时从手机的麦克风录制。MdaAudioSampleEditor.h中定义了可用的模式,并在Symbian OS的SDK文档中进行了论述。假如成功地开始了录制,可以通过调用实用工具的Stop()函数来停止录制:68录制剪辑录制

    展开阅读全文
    提示  163文库所有资源均是用户自行上传分享,仅供网友学习交流,未经上传用户书面授权,请勿作他用。
    关于本文
    本文标题:十一Symbian多媒体服务课件.ppt
    链接地址:https://www.163wenku.com/p-4971751.html

    Copyright@ 2017-2037 Www.163WenKu.Com  网站版权所有  |  资源地图   
    IPC备案号:蜀ICP备2021032737号  | 川公网安备 51099002000191号


    侵权投诉QQ:3464097650  资料上传QQ:3464097650
       


    【声明】本站为“文档C2C交易模式”,即用户上传的文档直接卖给(下载)用户,本站只是网络空间服务平台,本站所有原创文档下载所得归上传人所有,如您发现上传作品侵犯了您的版权,请立刻联系我们并提供证据,我们将在3个工作日内予以改正。

    163文库