分享一段Objective-C可调用的游戏中播放音乐
2010-03-11 09:05
369 查看
首先需要引入AudioTool 这个framework
稍微底层一点的函数,我们对此进行简单的封装,以至于可以更加方便的使用。
static
GBMusicTrack
*
track;
static
NSMutableDictionary
*
trackFiles;
static
BOOL enabled_
=
TRUE;
static
BOOL musicVolume_
=
1.0f
;
//把音频文件按着名字添加到字典中
+
(
void
) addMusicTrack:(NSString
*
)filename name:(NSString
*
)name {
if
(trackFiles
==
nil) {
trackFiles
=
[[NSMutableDictionary alloc] init];
}
[trackFiles setObject:filename forKey:name];
}
//通过判断字典中是否为空,看有没有音频文件。
+
(BOOL)hasMusicTrack:(NSString
*
)name {
id obj
=
[trackFiles objectForKey:name];
if
(obj
==
nil)
return
FALSE;
else
return
TRUE;
}
//对上文提及的方法进行封装,参数是播放的名字,和是否重复播放
+
(
void
)playMusicTrack:(NSString
*
)name withRepeat:(BOOL)b {
#ifndef DEBUG_NO_SOUND
if
(
!
enabled_)
return
;
if
(trackFiles
==
nil)
return
;
if
(track
!=
nil) {
@try {
[self stopCurrentTrack];
}
@catch (NSException
*
ex) {
NSLog([ex description]);
}
}
// 这个函数initWithPath就是上文提及的,初始化方法。
//
track
=
[[GBMusicTrack alloc] initWithPath:[[NSBundle mainBundle]
pathForResource:[trackFiles objectForKey:name]
ofType:
@"
mp3
"
]];
[track setRepeat:b];
[track setVolume:musicVolume_];
// 音乐的播放
[track play];
#endif
}
- (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)
稍微底层一点的函数,我们对此进行简单的封装,以至于可以更加方便的使用。
static
GBMusicTrack
*
track;
static
NSMutableDictionary
*
trackFiles;
static
BOOL enabled_
=
TRUE;
static
BOOL musicVolume_
=
1.0f
;
//把音频文件按着名字添加到字典中
+
(
void
) addMusicTrack:(NSString
*
)filename name:(NSString
*
)name {
if
(trackFiles
==
nil) {
trackFiles
=
[[NSMutableDictionary alloc] init];
}
[trackFiles setObject:filename forKey:name];
}
//通过判断字典中是否为空,看有没有音频文件。
+
(BOOL)hasMusicTrack:(NSString
*
)name {
id obj
=
[trackFiles objectForKey:name];
if
(obj
==
nil)
return
FALSE;
else
return
TRUE;
}
//对上文提及的方法进行封装,参数是播放的名字,和是否重复播放
+
(
void
)playMusicTrack:(NSString
*
)name withRepeat:(BOOL)b {
#ifndef DEBUG_NO_SOUND
if
(
!
enabled_)
return
;
if
(trackFiles
==
nil)
return
;
if
(track
!=
nil) {
@try {
[self stopCurrentTrack];
}
@catch (NSException
*
ex) {
NSLog([ex description]);
}
}
// 这个函数initWithPath就是上文提及的,初始化方法。
//
track
=
[[GBMusicTrack alloc] initWithPath:[[NSBundle mainBundle]
pathForResource:[trackFiles objectForKey:name]
ofType:
@"
mp3
"
]];
[track setRepeat:b];
[track setVolume:musicVolume_];
// 音乐的播放
[track play];
#endif
}
相关文章推荐
- [iphone-cocos2d]分享一段Objective-C可调用的游戏中播放音乐(2)
- [iphone-cocos2d]分享一段Objective-C可调用的游戏中播放音乐(1)
- 分享一段利用JavaScript实现播放声音/音乐的例子。
- Android游戏开发教程之十五:如何实现异步音乐播放
- 用Intent 调用 打电话 发短信 播放音乐 删除软件 安装软件等操作
- 设置模式之单例模式(附上一个Objective-C编写的播放音乐的单例类)
- C#调用winmm播放音乐(.wav文件)
- Qt 游戏开发必备!用 QtMultimedia 播放 Ogg 格式音乐
- 分享一个flash播放音乐的类
- objective-c 多媒体 音乐播放
- 安卓分享音乐文件后点击可自动播放的问题
- cocos2d-js 打包app包时 调用 cc.audioEngine.playMusic(sound, loop); 不能播放音乐
- Z缓冲和深度测试以及游戏中播放音乐代码
- Android使用的webcview中带有音乐播放控件,在关闭或分享时处于界面不可见状态下,声音仍在播放的问题解决
- 分享:家园2(Homeworld 2)游戏音乐
- C#播放音乐,调用程序
- 调用winmediaplay播放音乐
- Android Service AIDL 远程调用服务之简单音乐播放实例【转载】
- 一段调用游戏call的代码
- 音乐播放(游戏中的音效)