了解iPhone游戏开发中声音处理流播放文件

移动开发 iOS 游戏开发
本文主要是了解iPhone游戏开发中声音处理流播放文件,好处是可以快速的开始播放,减少读文件的过程,适合大文件特别是背景音乐的播放。

了解iPhone游戏开发中声音处理流播放文件是本文介绍的内容,流播放文件即用AudioStream 和 AudioQueue 来播放文件。好处是可以快速的开始播放,减少读文件的过程,适合大文件特别是背景音乐的播放。坏处是一次只能播放一个文件,如果要换播放文件,中间需要一定的时间。但是因为iPhone文件读取时间只有10秒,对于资源较大的文件,只能考虑这个方式了。

下面我将分享一下我在这方面的一点经验:1. 单个文件播放2. 在线文件播放

1. 单个文件播放

  1. BOOL isPlaying;    
  2. /*-------------------USED FOR LOCAL FILE--------------------*/    
  3. AudioFileID audioFile;    
  4. AudioStreamBasicDescription dataFormat;    
  5. AudioStreamPacketDescription *packetDescs;    
  6. UInt64 packetIndex;    
  7. UInt32 numPacketsToRead;    
  8. BOOL repeat;    
  9. BOOL trackClosed;    
  10. /*--------------------USED FOR PUBLIC------------------------*/    
  11. BOOL trackEnded;    
  12.     
  13. AudioQueueRef queue;    
  14. AudioQueueBufferRef buffers[NUM_QUEUE_BUFFERS];   

以上是需要定义的为单独文件播放的所需要的元素。可以定义在类里面。

2. 在线文件播放

  1. NSURL *url;    
  2. AudioFileStreamID audioFileStream; // the audio file stream parser    
  3. AudioStreamPacketDescription packetDescsQueue[kAQMaxPacketDescs]; // packet descriptions for enqueuing audio   
  4. CFReadStreamRef stream;    
  5. unsigned int fillBufferIndex; // the index of the audioQueueBuffer that is being filled    
  6. size_t bytesFilled; // how many bytes have been filled    
  7. size_t packetsFilled; // how many packets have been filled    
  8. bool inuse[kNumAQBufs]; // flags to indicate that a buffer is still in use    
  9. bool started; // flag to indicate that the queue has been started    
  10. bool failed; // flag to indicate an error occurred    
  11. bool discontinuous; // flag to trigger bug-avoidance    
  12. pthread_mutex_t mutex; // a mutex to protect the inuse flags    
  13. pthread_cond_t cond; // a condition varable for handling the inuse flags    
  14. pthread_mutex_t mutex2; // a mutex to protect the AudioQueue buffer    
  15. BOOL trackEnded;    
  16. AudioQueueRef queue;    
  17. AudioQueueBufferRef buffers[NUM_QUEUE_BUFFERS];   

利用http1.1协议播放在线文件。以上是在线文件播放所需要的参数。

  1. #define NUM_QUEUE_BUFFERS 3    
  2. #define kNumAQBufs 6 // number of audio queue buffers we allocate    
  3. #define kAQBufSize 32 * 1024 // number of bytes in each audio queue buffer    
  4. #define kAQMaxPacketDescs 512 // number of packet descriptions in our array   

这里是定义的一些参数,NUM_QUEUE_BUFFERS 用于播放本地文件,而 kNumAQBufs 用于播放在线文件。

3. 本地文件初始化

  1. - (id)initWithPath:(NSString*)path    
  2. {    
  3. UInt32 size, maxPacketSize;    
  4. char *cookie;    
  5. int i;    
  6.     
  7. if (kxxxTrackActive)    
  8. {    
  9. NSLog(@"Other music is playing.");    
  10. return nil;    
  11. }    
  12.     
  13. if (path == nil) return nil;    
  14. if(!(self = [super init])) return nil;    
  15.     
  16. // try to open up the file using the specified path    
  17. if (noErr != AudioFileOpenURL((CFURLRef)[NSURL fileURLWithPath:path], 0x01, 0, &audioFile))    
  18. {    
  19. NSLog(@"File can not be opened!");    
  20. return nil;    
  21. }    
  22.     
  23. // get the data format of the file    
  24. size = sizeof(dataFormat);    
  25. AudioFileGetProperty(audioFile, kAudioFilePropertyDataFormat, &size, &dataFormat);    
  26.     
  27. // create a new playback queue using the specified data format and buffer callback    
  28. AudioQueueNewOutput(&dataFormat, BufferCallback, self, nil, nil, 0, &queue);    
  29.     
  30. // calculate number of packets to read and allocate space for packet descriptions if needed    
  31. if (dataFormat.mBytesPerPacket == 0 || dataFormat.mFramesPerPacket == 0)    
  32. {    
  33. // Ask Core Audio to give us a conservative estimate of the largest packet    
  34. size = sizeof(maxPacketSize);    
  35. AudioFileGetProperty(audioFile, kAudioFilePropertyPacketSizeUpperBound, &size, &maxPacketSize);    
  36. if (maxPacketSize > kxxxBufferSizeBytes)    
  37. {    
  38. /*Limitation for the maximum buffer size*/    
  39. maxPacketSize = kxxxBufferSizeBytes;    
  40. NSLog(@"Size out of bounds!");    
  41. }    
  42. // calculate how many packs to read    
  43. numPacketsToRead = kxxxBufferSizeBytes / maxPacketSize;    
  44.     
  45. // will need a packet description for each packet to allocate space accordingly    
  46. packetDescs = malloc(sizeof(AudioStreamPacketDescription) * numPacketsToRead);    
  47. }    
  48. else    
  49. {    
  50. // constant bitrate    
  51. numPacketsToRead = kxxxBufferSizeBytes / dataFormat.mBytesPerPacket;    
  52.     
  53. // don't need packet descriptions for CBR data    
  54. packetDescs = nil;    
  55. }    
  56.     
  57. // see if file uses a magic cookie (a magic cookie is meta data which some formats use)    
  58. AudioFileGetPropertyInfo(audioFile, kAudioFilePropertyMagicCookieData, &size, nil);    
  59. if (size > 0)    
  60. {    
  61. // copy the cookie data from the file into the audio queue    
  62. cookie = malloc(sizeof(char) * size);    
  63. AudioFileGetProperty(audioFile, kAudioFilePropertyMagicCookieData, &size, cookie);    
  64. AudioQueueSetProperty(queue, kAudioQueueProperty_MagicCookie, cookie, size);    
  65. free(cookie);    
  66. }    
  67.     
  68. // we want to know when the playing state changes so we can properly dispose of the audio queue when it's done    
  69. AudioQueueAddPropertyListener(queue, kAudioQueueProperty_IsRunning, propertyListenerCallback, self);    
  70.     
  71. // allocate and prime buffers with some data    
  72. packetIndex = 0;    
  73. for (i = 0; i < NUM_QUEUE_BUFFERS; i++)    
  74. {    
  75. AudioQueueAllocateBuffer(queue, kxxxBufferSizeBytes, &buffers);    
  76. if ([self readPacketsIntoBuffer:buffers] == 0)    
  77. {    
  78. // this might happen if the file was so short that it needed less buffers than we planned on using    
  79. break;    
  80. }    
  81. }    
  82. repeat = NO;    
  83. trackClosed = NO;    
  84. trackEnded = NO;    
  85. kxxxTrackActive = YES;    
  86. return self;    
  87. }   

4. 在线文件初始化

  1. - (id)initWithURL:(NSURL*)newUrl    
  2. {    
  3. self = [super init];    
  4. if (self != nil)    
  5. {    
  6. url = [newUrl retain];    
  7. }    
  8. return self;    
  9. }   

算了,废话不多说了,直接上代码,等以后有时间了再逐一解释。

小结了解iPhone游戏开发中声音处理流播放文件的内容介绍完了,希望通过本文的学习能对你有所帮助!

责任编辑:zhaolei 来源: 互联网
相关推荐

2012-12-27 14:29:38

Android开发流媒体

2011-07-22 15:59:15

iPhone 声音 文件

2011-08-04 17:19:49

iPhone开发 Xcode 文档

2011-08-10 15:58:58

iPhone视频

2011-08-22 15:15:49

iPhone开发NSMutableAr排序

2011-07-18 10:53:09

2011-07-18 11:07:12

iPhone 游戏 引擎

2011-07-18 12:29:10

2011-07-18 11:23:29

iPhone 游戏 动画

2011-07-18 11:39:58

iPhone 游戏 引擎

2011-08-12 14:33:06

iPhone缓存文件

2011-07-29 13:27:48

iPhone 开发 Nib

2011-08-02 13:35:41

iOS开发 Get Post

2011-08-08 18:19:09

iPhone音频播放

2020-09-28 06:50:02

DuerOS 智能语音

2010-01-07 18:22:40

VB.NET声音播放

2011-08-09 14:42:07

iPhonePCM播放器

2011-07-08 20:32:57

iPhone midi

2011-08-01 14:34:06

iPhone 声音 音频

2011-08-02 10:36:02

iOS开发 SDK 多媒体
点赞
收藏

51CTO技术栈公众号