首先需要引入AudioTool 這個framework
代碼
- (id)initWithPath:(NSString *)path
{
UInt32 size, maxPacketSize;
char *cookie;
int i;
if (gThereIsAnActiveTrack)
{
NSLog(@"*** WARNING *** GBMusicTrack only plays one track at a time! You must close the previously running track"
" before you can play another. Requested track was: %@", [path lastPathComponent]);
return nil;
}
//路徑不存在的話返回空
if (path == nil) return nil; // 初始化
if(!(self = [super init])) return nil;
// 通過指定的路徑開啟音樂 if (noErr != AudioFileOpenURL((CFURLRef)[NSURL fileURLWithPath:path], 0x01, 0, &audioFile))
{
NSLog(@"*** Error *** GBMusicTrack - initWithPath: could not open audio file. Path given was: %@", path);
return nil;
}
// 得到檔案的資料類型
size = sizeof(dataFormat);
AudioFileGetProperty(audioFile, kAudioFilePropertyDataFormat, &size, &dataFormat);
// 建立一個新的隊列,使用的是指定的特殊資料類型和回調緩衝。
AudioQueueNewOutput(&dataFormat, BufferCallback, self, nil, nil, 0, &queue);
// 如果需要的話讀取包的大小並且分配所需要的空間
if (dataFormat.mBytesPerPacket == 0 || dataFormat.mFramesPerPacket == 0)
{
// since we didn't get sizes to work with, then this must be VBR data (Variable BitRate), so
// we'll have to ask Core Audio to give us a conservative estimate of the largest packet we are
// likely to read with kAudioFilePropertyPacketSizeUpperBound
size = sizeof(maxPacketSize);
AudioFileGetProperty(audioFile, kAudioFilePropertyPacketSizeUpperBound, &size, &maxPacketSize);
if (maxPacketSize > gBufferSizeBytes)
{
maxPacketSize = gBufferSizeBytes;
NSLog(@"*** Warning *** GBMusicTrack - initWithPath: had to limit packet size requested for file: %@", [path lastPathComponent]);
}
numPacketsToRead = gBufferSizeBytes / maxPacketSize;
//給包的描述分配空間
packetDescs = malloc(sizeof(AudioStreamPacketDescription) * numPacketsToRead);
}
else
{
// 對於CBR 資料 (Constant BitRate), 使用合適的資料填充到混村中
numPacketsToRead = gBufferSizeBytes / dataFormat.mBytesPerPacket;
// 這種包的描述不需要
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出來放到音頻隊列中
cookie = malloc(sizeof(char) * size);
AudioFileGetProperty(audioFile, kAudioFilePropertyMagicCookieData, &size, cookie);
AudioQueueSetProperty(queue, kAudioQueueProperty_MagicCookie, cookie, size);
free(cookie);
}
AudioQueueAddPropertyListener(queue, kAudioQueueProperty_IsRunning, propertyListenerCallback, self);
// 給特定的緩衝分配資料
packetIndex = 0;
for (i = 0; i < NUM_QUEUE_BUFFERS; i++)
{
AudioQueueAllocateBuffer(queue, gBufferSizeBytes, &buffers[i]);
if ([self readPacketsIntoBuffer:buffers[i]] == 0)
{
// 檢查讀取到緩衝中的包的大小
break;
}
}
repeat = NO;
trackClosed = NO;
trackEnded = NO;
gThereIsAnActiveTrack = YES;
return self;
}
// Created by Jake Peterson (AnotherJake) on 7/6/08.
// Copyright 2008 Jake Peterson. All rights reserved.
防盜加個連結:
作者:Alexliu(alex dotNet Learning)
出處:http://alexliu.cnblogs.com/