ios开发中文教程全收录iphonei pad1.18gb iphone实战ch_第1页
ios开发中文教程全收录iphonei pad1.18gb iphone实战ch_第2页
ios开发中文教程全收录iphonei pad1.18gb iphone实战ch_第3页
ios开发中文教程全收录iphonei pad1.18gb iphone实战ch_第4页
ios开发中文教程全收录iphonei pad1.18gb iphone实战ch_第5页
已阅读5页,还剩16页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、声音和到目前为止,说上一章中的山峰图像,但是编程的焦点主要集中在文本上。没错,只使用了最简单的方式。显示过UIImage,比如实际上能提供更丰富、更引人入胜的体验。照相机、麦克风、完善的库和扬声器是详细介绍图内置在中的一些工具。本章这些特性作为多常规内容来介绍。像,并简要介绍更复杂介绍。对于更复杂的器以及在上声音。超出了本书范畴。处理,图像编辑的留到下一章介绍指引你去参考相关的大量Apple的库时再做。18.1图像介绍已经几次涉及图像使用,最早出现在第12章中,在第一个SDK例子中包含了图像。还总是在 erfaceBuilder中创建UIImageView,将其附加到文件名,且无需考虑细节。现

2、在要考虑细节了。要来看Xcode中可用的一些选项,而不是依赖于 erface Builder的高度抽象。 深入到细节中,你会发现使用图像的过程分为两步。首先是将数据加载到UIImage中,然后通过一些方式使用UIImage。可通过两种主要的方式来使用UIImage,如图18-1所示。图18-1 图像可以显示在UIImageView或UIView中本节来探讨比较简单的使用UIImageView来显示图像的方法,18.2节将探讨更为复杂的将图像绘制到UIView后层的方式。本章内容和操作图像使用照相机:图像和声音第 18章 18.1图像介绍27318.1.1加载UIImageUIImage类提供7

3、种不同的方式创建图像实例。其中的4个工厂方法可能最容易使用,参见表18-1。还有一些与之等同的init方法,你可以根据自己的喜好来使用。表18-1用于创建UIImage的工厂方法工厂方法概述imageNamed:imageWithCGImage: imageWithContentsOfFile:基于主包(main bundle)中的文件创建UIImage从Quartz 2D对象创建UIImage,这与initWithCGImage:相同从你指定的完整文件路径创建UIImage,跟第16章中initWithContentsOfFile:相同从NSData创建UIImage,这与initWithD

4、ata:相同的一样,这与imageWithData:图像数据可以是几种文件类型,包括BMP、CUR、GIF、JPEG、PNG和TIFF。本书中使用得最多的是JPEG(因为它们比较小)和PNG(因为它们在硬件上好看,且被加速)。也可以从Quartz 2D对象创建UIImage,这是的基本图形程序包,下一章将会介绍。创建UIImage时有一个隐含的限制:图像不应该大于10241024。只要将图像导入程序中,就可以显示了。如果只愿意使用UIKit的简单方法,就会想要使用UIImageView类来显示图像。18.1.2绘制UIImageView在显示时已经在程序中使用过UIImageView。现在要来

5、其工作的细节。有两种方式初始化UIImageView。首先,可以使用initWithImage:方法,它允许你传递一个UIImage,如下所示:另外,也可以使用基本的initWithFrame:方法,并手动修改对象的属性。表18-2展示了一些属性和方法,你对UIImageView做表18-2工作时很可能会用到它们。18UIImageView的一些属性和方法方法或属性类型概述animationDuration animationImages animationRepeatCount imagestartAnimatingstopAnimating属性属性属性属性方法方法指定多长时间运行一次动画循

6、环识别图像的NSArray,以加载到UIImageView中指定运行多少次动画循环识别单个图像,以加载到UIImageView中开启动画停止动画274第 18 章:图像和声音要加载普通图像,可以使用image属性,但是几乎没有理由使用它而不使用initWithImage:方法除非你在动态改变图像。如果想要创建一组图像作为动画,那么有必要利用其他UIImage- View方法和属性。可以将一组图像加载到UIImageView中,它们应该多长时间完成一次动画循环及运行的次数,并在你觉得合适的时候开始和停止循环。代码18-1中展示了一个简单的例子。加载图像创建UIView开启动画你可能想要手动加载图

7、像,而不是通过 erface Builder进行加载,其中一个主要原因是为了利用UIImageView的动画功能。18.1.3在 UIKit 中修改图像已经介绍了如何以编程方式创建图像并将它们加载到图像视图中。很显然,接下来的事情就是开始修改图像。不幸的是,在处理UIImageView时只有有限的能力修改图像。可以基于视图的一些简单操作,做一些改变。例如,如果你调整UIImageView的大小,则它将自动调整其包含的的大小。同样,通过设置UIImageView的框而不是整个屏幕,来决定在哪里绘制UIImageView。你甚至可以通过使用多个UIImageView来分层多个图像。这一切很快就会变

8、得笨重,而且你不能做任何更有趣的事情,比如说通过混合或alpha透明选项来变换图像或修改它们的堆放形式。要做这类工作(并开始堆放,而不只是堆放视代码18-1 UIImageView允许动画循环图像18.2利用 Core Graphics 绘制简单图像275图),需要了解Core Graphics。UIImage提供一些简单的方式Core Graphics功能,无需去往Core Graphics框架(或者了解上下文或者其底层的其他复杂情况)。这里将简要介绍这些内容,但是Core Graphics基本上要等到下一章才介绍,那时主要介绍整个的Quartz 2D图形引擎。18.2利用 Core Gra

9、phics 绘制简单图像尽管不能具有变换和其他复杂功能的整个Core Graphics库,但是UIImage类却包含5个简单的方法,可以充分利用Core Graphics的工作方式。表18-3中描述了这些方法。表18-3用于绘制UIImage的实例方法方法概述drawAsPatternInRect:在矩形中绘制图像,不缩放,但是在必要时平铺drawAtPodrawAtPo:blendMode:alpha:利用CGPo作为左上角,绘制完整的不缩放的图像drawAtPo:的一种更复杂的形式在CGRect中绘制完整的图像,适当地缩放drawInRect:的一种更复杂的形式drawInRect:dra

10、wInRect:blendMode:alpha:问题是,这些方法不能用作viewDidLoad:的一部分或者通常用来加载对象的任何其他方法的一部分。这是因为它们依赖于图形上下文而工作。下一章更详细地谈论上下文,但是图形上下文其实就是你所绘制的东西要到达的目标,比如说窗口、PDF文件或者。在上,UIView自动创建图形上下文作为其CALayer的一部分,CALayer是与每个UIView相关的Core Animation层。可以通过为UIView(或者更确切地说,为你已经创建的新的子类)编写drawRect:方法来Core Animation层。要做这种类型的工作,通常必须获得一个特殊的上下文变

11、量,UIView方法替你去做这件事,这样事情就变得简单了。代码18-2展示了如何使用该方法拼合一些。18注意,drawAtPo:方法让你可以完成更复杂的事情,比如说混合(使用类似于Photoshop的选项,比如颜色减淡和强光)和让变得有些透明。这里使用的是普通混合,但是只有50%的(因此使用drawAtPo:方法)。其余代码很标准。使用这些单个绘图命令代码18-2 UIView的drawRect:允许你使用较低级别的绘图命令276第 18 章:图像和声音非常简单,比费力去创建多个UIImageView对象简单多了(可能还更为高效)。的Core Graphics框架之前,在深入研究还有好多事情不

12、能做,但是现在已经得到一些控件,已经足够满足大多数常见的多下一章。需求了。如果需要的控件,请直接跳转到谈论过很多有关图像的话题,但是一直假设你是从项目的包加载图像。而如果你想让用户来选择呢?这就是下一节的。18.3可以使用SDK从的库或相机卷。也可以允许用户拍摄新。这都是用UIImagckerController完成的,它是另一个模式控制器,负责管理一个相当复杂的图形界面,无需你的干预。图18-2显示了它的样子。图18-2 图像选取器是另一个供你使用的预编程的控制器18.3.1使用图像选取器通过创建对象、设置一些变量并将它呈现为模式视图控制器来加载UIImagckerController。默认

13、情况下,图像选取器控制器将允许用户(以及有选择性地编辑)他们的库中的:一旦创建了图像选取器控制器,你就需要有其委托来响应以下两个方法的委托响应:image-PickerController:didFinishPickingImage:editingInfo: 和imagckerController-18.3277DidCancel:。对于第一个方法,你应该解散模式视图控制器,并适当地响应用户的而对于第二个方法,则只需要解散控制器。选择。总之,图像选取器控制器很容易使用,因为你主要是对被选中的了一个使用它的完整例子。做出反应。下一节给出18.3.2拍照前面提到过,UIImagckerContro

14、ller具有三个可能的源,由以下常量表示:UIImagUIImagckerControllerSourceTypePhotoLibrary,库中的一个。ckerControllerSourceTypeSavedPhotosAlbum,相机卷中的一个。UIImagckerControllerSourceTypeCamera,照相机拍摄的新。应该总是确保,在启动图像选取器控制器之前,源是可用的,尽管这对于照相机来说最重要。可以用isSourceTypeAvailable:类方法确定源的存在:一旦验证了源的存在,你就可以告诉图像选取器,结合sourceType属性一起使用这个源。例如,要使用照相机,

15、可以这样做:注意,一个程序中拍摄的必须将它们保存到那里(只在该程序中可用。如果你想要这些进入相册,那么程序马上就会到)。在测试期间曾几次让它停下来。起码这意味着,以的经验,照相机是很占用资源的你在使用照相机的时候需要考虑保存程序的状态,因为使用照相机会导致内存不够用。18.4节中的例子中就会用到照相机。18.3.3保存到相册你可能希望将新保存到相册,或者希望将程序创建的图形存放到相册。不管出于哪种情况,都使用UIImageWriteToSavedPhotosAlbum函数。该函数具有4个变量:第一个列出图像,其他三个一个可选的异步通知函数,以在完成保存时调用。通常可以像下面这样调用该函数:18

16、如果你想要利用异步通知,请查阅UIKit函数参考,那里解释了该函数,或者也可以参考下一章的例子。可以使用该函数将UIView的CALayer保存到相册,例如,相册允许你保存那些你以前直接写到CALayer的绘图命令。这也同样依赖于图形上下文,下一章么做这件事:会解释,但是这里要展示怎278第 18 章:图像和声音为了该函数正确工作,你必须到Quartz Core框架。现在已经介绍了图像的所有基本知识,可以将它们组合到本章的“大”例子中了,这个例子是一个程序,它拼合多个,首先是利用UIImagckerController选择这些,然后利用UIImageView允许它们移动,最后将它们绘制到一个C

17、ALayer中以便保存。18.4拼合:一个图像例子拼合(collage)程序依赖于三个对象。跟往常一样,collageViewController完成大部分工作。它写出到collageView对象,该对象主要作为一个CALayer存在。最后,你将有一个tempImageView对象,它是用户在图像被选中但是没有放置之前临时放置图像的地方。18.4.1拼合视图控制器拼合视图控制器建立在一些 erface Builder对象之上,这些对象是:视图控制器本身;一个叫做myTools的工具,它在编程过程中将被填充;collageView UIView类,它作为自己的类文件而存在,并作为self.vie

18、w 到程序中。你还需要向项目中添加Quartz Core框架,因为你将使用刚才的保存技巧。代码18-3展示了完整的视图控制器,这是整个程序中作用最大的文件。代码18-3 视图控制器负责大部分的拼合任务18.4拼合:一个图像例子279设置对象激活图像选取器18280第 18 章:图像和声音激活照相机响应图像选择响应选取器取消调整大小将添加到CALayer18.4拼合:一个图像例子281保存拼合伸缩图像代码有点长,但是很容易理解。一开始是viewDidLoad:,它设置UIToolBar。早就赞美过 erface Builder,但是也,在创建更加动态的项目时,它可能会以胜任。这里就是这种情况。你

19、不能在 erface Builder中有效地填充UIToolBar,因为你将基于程序的状态改变它。你要在sav上放置按钮以调用三个方法:choosc:、takc:(当照相机可用时)和c:。choosc:和takc:是类似的方法。它们都调用图像选取器控制器,但是第一个方法库,第二个方法让用户拍摄新。这些模式控制器的非凡之处在于,从你创建选取器18到用户选择当用户选择或者取消,这期间无需你做任何事情。时,imagckerControl:didFinishPickingImage:editingInfo会被调用 ,将控制返回给程序。这里你要做以下4件事情。解散模式视图控制器。查看交给你的,调整大小,

20、以填满四分之一或更少的屏幕。将图像实例化为一个tempImageView对象,该对象是UIImageView的子类。改变,以便有一个Done按钮可用,还有一个滑块。此时,用户能够做以下3件事情。使用UITouch移动图像视图(图像视图包括在tempImageView类中,因为这是触摸发生的282第 18 章:图像和声音地方,就像使用滑块改变在第14章中看到的一样)。大小。单击Done按钮接受图像大小和位置。产生的最终结果如图18-3所示。注意,如果用户取消了图像选取器,那么你的imageP-ickerControllerDidCancel:方器 。正确地关闭模式控制UISlider 被挂接到r

21、escalc: 方法。它重新绘制 UIImageView的框,这将在自动调整大小。同时,Done按钮激活finishPic:方法 。这会发送一个特殊的addPic: at:消息给collageView。CALayer绘制就是在collageView中完成的,马上就会返回来介绍它。finishPic: 也解散UISlider和tempImageView,并重新设置置。回到初始设还有一个还没介绍的按钮:Save。它激活初始savc:方法 ,该方法将CALayer保存到库。注意,该是UIView的中。图18-3 使用拼合程序同时显示很多方法在执行过程中会临时隐藏。由于子视图,如果不这样做的话,它会被

22、包含在最后一个方法scaleImage: 是设置每个图像以填充大约四分之一屏幕的工具。代码中有两个不确定的部分:tempImageView中的方法(它们允许用户移动UIImageView)和collageView中的方法(它们稍后将图像绘制到CALayer中)。18.4.2拼合临时图像视图tempImageView类只有一个目的:截取UITouch。UITouch表示用户想要将新图像移动到拼合的不同部分。代码很简单,如代码18-4所示。代码18-4 临时图像可通过触摸被移动18.4拼合:一个图像例子283确定在视图中的位置计算整置这类似于你在第14章中编写的触摸代码,无需做的解释。回想一下,l

23、ocationInView:应用程序的全局坐标系统。仿真器)上时,结果有时会超出边界,给出视图坐标系统内的一个CGPo在测试中发现,当运行在,需要转换成(而不是所以你在移动临时图像视图之前,需要仔细检查坐标。18.4.3拼合视图最后,具有了collageView本身,它是背景UIView,需要响应addPic:at:消息并用drawRect:绘制到CALayer上。代码18-5展示了做这件事的代码。保存到数组中18代码18-5 一旦设置一个图像,背景视图就会管理低级别的绘制284第 18 章:图像和声音绘制到CALayer上该代码分为两部分。addPic:at:方法 将其信息保存到一个实例变量

24、中,将myPics词典添加到NSMutableArray。注意,你必须将值转换为NSNumber,以便可以将它们放置到词典中。该方法然后在视图上调用setNeedsDisplay。应该从来不直接调用drawRect:。相反,当想要它执行时,可调用setNeedsDisplay方法,其他所有事情都不用你操心。drawRect:后来很快就被调用 。它到的技术将每个图像绘制到CALayer上。整个NSMutableArray,将之分解,并用前面学习还没有展示头文件和未更改的应用程序委托,但是这是编写完整的拼合程序都需要的重要内容。18.4.4扩展这个例子这是较长的例子之一,但是仍然需要进行一些扩展,

25、才能变成功能全面的应用程序。首先,它对内存有点不友好。如果能文件名,而不是到处使用UIImage,那么可能会更好。此外,CALayer所来自的NSArray应该保存到文件,以便在内存不够时不会丢失。但是程序只要存在就应该工作得很好。程序应该变得更加可用。裁剪的选项很好,但是可能需要Core Graphics函数。一个在锁定之后移动的选项相对简单:你可以在collageView中测试触摸,并向后NSArray,以找到用户正在触摸哪个对象。将它重新实例化为UIImageView很简单。不管怎样,已经展示了所有这些图形基本要素如何一起工作,现在开始介绍多的另外两种主要类型:音频和。18.5使用 Me

26、dia Player 框架音频和都比图像更加复杂。幸运的是,有一个高级别框架Media Player允许你18.5使用 Media Player 框架285音频和。如果你不需要音频或紧密地集成到应用程序的其余部分中,那么它是一个很好的选择对于通常工作得很好,但是对于音频是一个不太理想的选择。Media Player框架包含两个类:MPMoviePlayerController和MPVolumeView。它们管理整个页面的音频或要使用任何一个MediaPlayer h头文件。器,无需你控制其如何工作,但是让你很容易音频或文件。器类,你都应该向你的项目添加Media Player框架和MediaP

27、layer/器类器,你需要用将要调用的文件的URL字符串初始化一个MPMoviePlayer-18.5.1为了使用Controller对象。这可能是任何 mp3、.mp4、.mov或.3gp文件,或者是支持的任何其他东西。启动器的方式有两种,可以立即(这会导致后再启动。的转盘旋转得快一点,当它做好准备时),或者等到接收了文件已加载有三个,表18-4中描述了它们。使用器时你需要注意表18-4 告诉你器正在做什么通知概述MPMoviePlayerContentPreloadDidFinishNotification文件已加载重放完成MPMoviePlaylaybackDidFinishNotifi

28、cation(续)通知概述MPMoviePlayerScalingModeDidChangeNotification器的缩放模式改变1. 调用代码器18-6显示了器的一个简单调用。该程序的构造开始于erface Builder中,包括一个UITextField(用于URL的输入)、一个UILabel(用于IndicatorView(在加载期间展示活动)。它依赖于通知来状态和错误)和一个UIActivity-器是如何工作的。准备文本字段18解散键盘代码18-6器的一个简单调用286第 18 章:图像和声音加载文件设置器启动器请求通知安抚用户在加载完成时开始在完成时刷新屏幕你的项目开始很简单,就是

29、设置UITextField。这涉及设置Return键法textFieldShouldReturn: ,前面已经这么做过好几次了。和编写它的主委托方项目是从文本字段真正开始的。当文本数据被输入时,chooseFile:方法被调用 ,就是该方法加载器。假设你被传递一个URL(因为它简单,曾经使用过,尽管马上就会讨论本地文件),将之转换成NSURL,然后创建器 。有少量的属性可以设置来指定器如何工作 ,这些属性都列出在类参。你使用前面看到的过程到器中 。让用户知道你怎样进行处理是个不错的主意,所以最后几行代码更新状态信息并启动一个活动指示器,表示正在进行处理中 。一旦文件被加载,movieDidLo

30、ad:方法就会被通知 。它清除你的更新信息,然后器开始。跟面章节中看到的模式视图控制器一样,此时由器负责,直到其额外回来之前无需你操心任何事情。在本例中,当它完成之后 ,你做一些最后的清除。2. 从文件加载如果你愿意从文件而不是从互联网加载,你就可以包含文件作为包的一部分。使用在第16章中方法创建NSURL:的方法,创建一个到这些本地文件的路径,并且用fileURLWithPath:工厂18.5使用 Media Player 框架287在编写本书时,加载文件比从互联网加载更为可靠。从互联网加载时,音乐文件偶尔会无缘由地被破坏,流似乎根本不能工作。期望这些问题很快得到纠正,可能就在本书之际。器还

31、支持另一个功能:你可以允许用户在器之外设置音量。18.5.2音量视图通过调用MPVolumeView条目,你可以允许用户调整音量,调用方法如下:你不需要做任何工作,当用户更改音量控件时,系统音量将立即更改。如果你愿意使用另外的方法,有三个一般函数可用来调用音量警报。参见表18-5。表18-5用警报设置音量函数概述MPVolumeSettingsAlertShow MPVolumeSettingsAlertHideMPVolumeSettingsAlertIsVisible显示音量警报隐藏音量警报返回一个布尔值,以显示音量警报的状态在一起,而一旦你加载了Media Player注意,这些是函数,

32、不是方法。它们不与任何类框架,则这些函数通常是可用的。警告在编写本书时,音量控制在仿真器中不起作用。18.5.3更好地集成器最大到程序中。器是,它调用一个单独的屏幕。因此,很难用它将音乐或直接集成18对于音乐来说,这个问题目前还难以一下子就解决了。如图18-4所示,当音乐时,屏幕被一个大的QuickTime标志占据着。希望,SDK的未来版本能够给予你选项,来定义播放声音时的背景(或者更好一点,允许你保持在普通视图中,从而能够真正集成音频功能)。器的288第 18 章:图像和声音图 18-4是控件,因为当你将用作cut scene时,不希望用户操作对于来说,最大它。通过将MPMoviePlaye

33、rController的movieControlMode属性设置为 MPMovieControl-ModeVolumeOnly(这只允许使用音量控件)或者MPMovieControlModeHidden(这不允许用户任何控件),可以解决这个问题。有了这种隐藏控件的能力,器应该成了你显示所需要的工具,但是它还是不能使用音频,迫使你去寻求另外的方法。不幸的是,还没有高级别的框架用于音频,所以你自己必须做不少的工作。大量具体的细节由于比较复杂,超出了本书范畴,但是器之外的处理音频所用最简单方法开始介绍。从18.6手动没有用于是,Celestial是对外部的开发声音音频的高级别框架这种说法并不完全正确

34、。确实有,叫做Celestial。不幸的上的很多“私有框架”之一,这意味着它已在Apple,但是还没有方法,因为私有框架可用。决定在本书中不用来私有框架的随时可能改变,使用它们会让程序很容易受到OS升级的影响。相反,供的框架。需要依靠Apple提有很多提供的框架!的Core Audio系统包含半打以上的框架,让你可以在低级别音频文件。这些框架包括Audio Queue Servi、Audio File Stream Servi、Audio FileServi&、OpenAL、Audio SesServi等。要深入了解这些框架,请参考Apple参考库的“Audio”部分,从“Getting St

35、arted wiudio &” 和“Core Audio Overview”开始。这些框架都足够老了,还没有脱离Core Foundation,所以你必须依赖于从这些较老的编程风格中学到的经验。只简要介绍音频。于更复杂的Audio Queue Servi提供一些关于如何简单声音和振动的例子,但是对,概述过程,并将你引向关于该的Apple扩展。简单声音18.6.1System Sound Servi是一个C接口,它让你。它是Audio Toolbox简单声音和振动。框架的一部分,在AudioToolbox/AudioServi.h中18.6手动声音289该接口只可以用来30秒以下的.aif、.c

36、af或.wav格式的短音频文件。要使用System SoundServi,则从文件创建一个系统声音ID,可选地为声音完成时创建一个回调,并启动它。表18-6展示了主要的函数。表18-6System Sound Servi的主要函数函数参数概述AudioServiAudioServi AudioServiceCreateSystemSoundIDURL、&从URL创建声音完成时删除声音DiseSystemSoundIDpletion、run loop、run loop mode、routine、data为声音完成一个回调AudioServiAudioServiRePlaySystemSoundp

37、letion完成时删除回调声音有一些额外的函数处理系统声音属性,可以在System Sound Servi代码18-7展示了如何使用最重要的函数。参找到这些函数。准备URL创建声音添加回调18声音清除声音器一样,启用System Sound Servi接口首先是构建一个到文件的路径(使用在跟第16章中学到的知识),然后将其转换成一个URL。完成之后,就可以创建系统声音了 ,这代码18-7 Audio Toolbox支持简短音频的290第 18 章:图像和声音要求将NSURL *桥接到CFURLRef并传递一个指向系统声音ID的指针。添加回调函数是可选的 ,但是如果你想要在声音完成时发生一些事情

38、,则一定要这么做。一旦有了系统声音ID,这里做的一样。就很简单了 ,但是你应该检查系统声音ID创建得是否正确,跟跟平常一样,完成之后应该清空内存。这就是本例中回调函数所做的事情 。18.6.2振动System Sound Servi接口中还隐含着一个很酷的小特性,你可以使用它来振动用户的。这通过传递一个预先定义的系统声音ID来实现,如代码18-8所示。对于有时难以使用的音频系统来说,这是它本身的简易之处。的音频工作,不幸的是,就只有这些了。现在已经介绍了所有容易结束之前,下面要概述不满足System Sound Servi接口要求的音频文件(可能是太长了,也可能是文件类型不符)时的操作步骤。复

39、杂长于30秒18.6.3要,需要依赖于Audio Queue Servi支持的有限音频类型之外其他类型。它将允许你较长,播放System Sound Servi,甚至声音。Apple提供两组极好的关于Audio Queue Servi的代码,你可以过来自己使用,所以这里就不赘述了。“Apple Queue ServiProgramming Guide”提供了一个全面的例子,介绍如何在过程化的面向C的环境中编写器。“SpeakHere”示例代码展示了如何使用最初面象的Objective-C代码执行类似的任务。器出现在AudioPlayer m文件中。为了阐述Apple的示例代码,表18-7列出了

40、复杂声音需要遵循的标准步骤。它依赖于如下这些。音频文件ID类似于前面遇到过的系统声音ID,它指向文件的音频内容。音频队列包含大量缓冲区通常至少包含3个。这些缓冲区被填充了音频内容(通常来自文件),一次填充一个,然后被分派给器(通常是扬声器)。音频队列缓冲区是通过队列传递的单个声音单元。每个音频队列缓冲区具有用户设置的大小。你在用数据填充这些缓冲区时会给它们编制队列,然后它们会按队列进行。音频队列回调是一个特殊的函数,被调用来处理音频队列。回调发生在数据被拖入音频队列时。它需要填充缓冲区,然后将它们编制队列。定制音频结构是一个用户创建的结构,其中包含回调需要知道的所有关于音频文件状态代码18-8 振需要一行代码18.6手动声音291和队列状态的数据。它作为函数调用的一部分被传递给回调。图18-5以图形方式描述了这些概念。音频缓冲区队列回调输入输出缓冲区缓冲区缓冲区图18-5 音频从输入设备移动到输出设备以便进行重放的管道图有了这些定义之后,应该就能

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论