首先需要引入AudioTool 这个framework
代码
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;
}
- (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;
{
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(!(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);
// 创建一个新的队列,使用的是指定的特殊数据类型和回调缓存。
{
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/