UnderstandingIPhoneSound processing in Game DevelopmentStream playback FileIs the content of this article,Stream playback FileUse AudioStream and AudioQueue for playback.File. The advantage is that you can quickly start playing and reduce reading.FileSuitable for largeFileEspecially for playing background music. The disadvantage is that only one video can be played at a time.FileIf you want to change the playback modeFileIt takes some time in the middle. But because of the iPhone'sFileThe read time is only 10 seconds.FileYou can only consider this method.
I will share my experience in this area: 1. Single file playback 2. Online file playback
1. Play a single file
- BOOL isPlaying;
- /*-------------------USED FOR LOCAL FILE--------------------*/
- AudioFileID audioFile;
- AudioStreamBasicDescription dataFormat;
- AudioStreamPacketDescription *packetDescs;
- UInt64 packetIndex;
- UInt32 numPacketsToRead;
- BOOL repeat;
- BOOL trackClosed;
- /*--------------------USED FOR PUBLIC------------------------*/
- BOOL trackEnded;
-
- AudioQueueRef queue;
- AudioQueueBufferRef buffers[NUM_QUEUE_BUFFERS];
The preceding elements must be defined as the elements required for playing a single file. It can be defined in the class.
2. Online file playback
- NSURL *url;
- AudioFileStreamID audioFileStream; // the audio file stream parser
- AudioStreamPacketDescription packetDescsQueue[kAQMaxPacketDescs]; // packet descriptions for enqueuing audio
- CFReadStreamRef stream;
- unsigned int fillBufferIndex; // the index of the audioQueueBuffer that is being filled
- size_t bytesFilled; // how many bytes have been filled
- size_t packetsFilled; // how many packets have been filled
- bool inuse[kNumAQBufs]; // flags to indicate that a buffer is still in use
- bool started; // flag to indicate that the queue has been started
- bool failed; // flag to indicate an error occurred
- bool discontinuous; // flag to trigger bug-avoidance
- pthread_mutex_t mutex; // a mutex to protect the inuse flags
- pthread_cond_t cond; // a condition varable for handling the inuse flags
- pthread_mutex_t mutex2; // a mutex to protect the AudioQueue buffer
- BOOL trackEnded;
- AudioQueueRef queue;
- AudioQueueBufferRef buffers[NUM_QUEUE_BUFFERS];
Use http1.1 to play online files. The preceding parameters are required for online file playback.
- #define NUM_QUEUE_BUFFERS 3
- #define kNumAQBufs 6 // number of audio queue buffers we allocate
- #define kAQBufSize 32 * 1024 // number of bytes in each audio queue buffer
- #define kAQMaxPacketDescs 512 // number of packet descriptions in our array
Here are some defined parameters. NUM_QUEUE_BUFFERS is used to play a local file, while kNumAQBufs is used to play an online file.
3. Local file Initialization
- - (id)initWithPath:(NSString*)path
- {
- UInt32 size, maxPacketSize;
- char *cookie;
- int i;
-
- if (kxxxTrackActive)
- {
- NSLog(@"Other music is playing.");
- return nil;
- }
-
- if (path == nil) return nil;
- if(!(self = [super init])) return nil;
-
- // try to open up the file using the specified path
- if (noErr != AudioFileOpenURL((CFURLRef)[NSURL fileURLWithPath:path], 0x01, 0, &audioFile))
- {
- NSLog(@"File can not be opened!");
- return nil;
- }
-
- // get the data format of the file
- size = sizeof(dataFormat);
- AudioFileGetProperty(audioFile, kAudioFilePropertyDataFormat, &size, &dataFormat);
-
- // create a new playback queue using the specified data format and buffer callback
- AudioQueueNewOutput(&dataFormat, BufferCallback, self, nil, nil, 0, &queue);
-
- // calculate number of packets to read and allocate space for packet descriptions if needed
- if (dataFormat.mBytesPerPacket == 0 || dataFormat.mFramesPerPacket == 0)
- {
- // Ask Core Audio to give us a conservative estimate of the largest packet
- size = sizeof(maxPacketSize);
- AudioFileGetProperty(audioFile, kAudioFilePropertyPacketSizeUpperBound, &size, &maxPacketSize);
- if (maxPacketSize > kxxxBufferSizeBytes)
- {
- /*Limitation for the maximum buffer size*/
- maxPacketSize = kxxxBufferSizeBytes;
- NSLog(@"Size out of bounds!");
- }
- // calculate how many packs to read
- numPacketsToRead = kxxxBufferSizeBytes / maxPacketSize;
-
- // will need a packet description for each packet to allocate space accordingly
- packetDescs = malloc(sizeof(AudioStreamPacketDescription) * numPacketsToRead);
- }
- else
- {
- // constant bitrate
- numPacketsToRead = kxxxBufferSizeBytes / dataFormat.mBytesPerPacket;
-
- // don't need packet descriptions for CBR data
- packetDescs = nil;
- }
-
- // see if file uses a magic cookie (a magic cookie is meta data which some formats use)
- AudioFileGetPropertyInfo(audioFile, kAudioFilePropertyMagicCookieData, &size, nil);
- if (size > 0)
- {
- // copy the cookie data from the file into the audio queue
- cookie = malloc(sizeof(char) * size);
- AudioFileGetProperty(audioFile, kAudioFilePropertyMagicCookieData, &size, cookie);
- AudioQueueSetProperty(queue, kAudioQueueProperty_MagicCookie, cookie, size);
- free(cookie);
- }
-
- // we want to know when the playing state changes so we can properly dispose of the audio queue when it's done
- AudioQueueAddPropertyListener(queue, kAudioQueueProperty_IsRunning, propertyListenerCallback, self);
-
- // allocate and prime buffers with some data
- packetIndex = 0;
- for (i = 0; i < NUM_QUEUE_BUFFERS; i++)
- {
- AudioQueueAllocateBuffer(queue, kxxxBufferSizeBytes, &buffers);
- if ([self readPacketsIntoBuffer:buffers] == 0)
- {
- // this might happen if the file was so short that it needed less buffers than we planned on using
- break;
- }
- }
- repeat = NO;
- trackClosed = NO;
- trackEnded = NO;
- kxxxTrackActive = YES;
- return self;
- }
4. OnlineFileInitialization
- - (id)initWithURL:(NSURL*)newUrl
- {
- self = [super init];
- if (self != nil)
- {
- url = [newUrl retain];
- }
- return self;
- }
Forget it. If you don't talk much about it, go directly to the code and explain it one by one later.
SummaryIPhoneSound processing in Game DevelopmentStream playback FileI hope this article will help you!