我希望标题不会太误导......:)
我播放系统声音并将SoundCompletion-Callback添加到其中:
AudioServicesAddSystemSoundCompletion(soundID, NULL, NULL, completionCallback, (__bridge_retained void *)self);
而«self»是一个简单的NSObject
在完成回调中,我尝试再次调用播放程序:
我必须将__bridge_transfer和__bridge_retained添加到强制转换,否则会出现错误,崩溃或其他意外行为。
但尽管如此,整个事情仍无效。
我存储要在NSMutableArray中播放的声音,抓取数组的第一个条目并播放它,添加声音完成并希望发生的事情。 但是 - 使用所有保留传输的东西,NSMutableArray在第二次调用时为空......
以下是代码:
static void completionCallback (SystemSoundID mySSID, void *myself) {
NSLog(@"Audio callback");
AudioServicesRemoveSystemSoundCompletion (mySSID);
AudioServicesDisposeSystemSoundID(mySSID);
[(__bridge_transfer Speaker *)myself speakCharacter];
CFRelease(myself); // I heard I need this?
}
-(void)speakCharacter{
if([sounds count] > 0){
NSString *soundToPlay = [sounds objectAtIndex:0];
[sounds removeObjectAtIndex:0];
NSLog(@"TxtToSpeak %@", soundToPlay);
CFURLRef soundFileURLRef;
NSURL *path = [[NSBundle mainBundle] URLForResource:[soundToPlay uppercaseString] withExtension:@"aif"];
soundFileURLRef = (__bridge CFURLRef)path;
SystemSoundID soundID;
AudioServicesCreateSystemSoundID(soundFileURLRef, &soundID);
AudioServicesAddSystemSoundCompletion(soundID, NULL, NULL, completionCallback, (__bridge_retained void *)self);
AudioServicesPlaySystemSound (soundID);
}
}
[编辑] - 回答我自己的问题:
总是很高兴自己找到它:)。
原来,我几乎就在那里。
设置回调的调用如下:
AudioServicesAddSystemSoundCompletion(soundID, NULL, NULL, completionCallback, (__bridge_retained void *)self);
然后,在回调函数中,我这样做:
myClass *theClass = (__bridge myClass *)myself;
CFRelease(myself);
[theClass playNextSound]; // The routine that plays the sounds
它有效......
答案 0 :(得分:8)
我无法回答我自己的问题,因为我对StackOverflow太快了 - 所以为了完成这个,我再次添加答案:)
原来,我几乎就在那里。
设置回调的调用如下:
AudioServicesAddSystemSoundCompletion(soundID, NULL, NULL, completionCallback, (__bridge_retained void *)self);
然后,在回调函数中,我这样做:
myClass *theClass = (__bridge myClass *)myself;
CFRelease(myself);
[theClass playNextSound]; // The routine that plays the sounds
它有效......
答案 1 :(得分:4)
对于任何需要额外帮助的人... 我得到了Swissdude在普通视图控制器中工作的答案:
注意:(你不能使用CFRelease(我自己))
·H
#import <UIKit/UIKit.h>
#import <AudioToolbox/AudioToolbox.h>
@interface MYVIEWCONTROLLERNAME : UIViewController
@property SystemSoundID mySentenceAudio;
@end
的.m
#import "MYVIEWCONTROLLERNAME.h"
@interface MYVIEWCONTROLLERNAME ()
{
int myLetterCount;
int myWordLength;
}
@end
@implementation MYVIEWCONTROLLERNAME
@synthesize mySentenceAudio;
#pragma mark - Click Action
- (IBAction)SpellButtonPress:(UIButton *)sender {
[self AudioDataAndPlayerLoader];
myLetterCount = 0;
}
# pragma mark - Audio Data
-(void) AudioDataAndPlayerLoader {
NSString*myWord = @"apple";
myWordLength = myWord.length;
NSArray*wordArray= [self stringToLetterArray:myWord];
if (myWordLength > myLetterCount) {
NSString* myLetter = [wordArray objectAtIndex:myLetterCount];
[self playMySound:myLetter];
}
}
- (NSArray*)stringToLetterArray:(NSString*)string {
NSUInteger characterCount = [string length];
NSMutableArray *temparray = [NSMutableArray arrayWithCapacity:[string length]];
for (int i = 0; i<characterCount; i++)
{
[temparray addObject:[string substringWithRange:NSMakeRange (i,1)]];
}
return [temparray copy];
}
#pragma mark - Audio Loop
- (void) myAudioLoopCheck {
myLetterCount++;
NSLog(@"Audio Looped");
if (myWordLength > myLetterCount) {
[self performSelector:@selector(AudioDataAndPlayerLoader) withObject:nil afterDelay:.2];
}
else {
NSLog(@"Done");
myLetterCount = 0;
}
}
#pragma mark - Audio Player
- (void) playMySound: (NSString*)soundTitle{
NSString* SOUNDPATH = [[NSBundle mainBundle]
pathForResource:soundTitle
ofType:@"m4a"
inDirectory:@"audio/abc/"];
if (SOUNDPATH != nil) {
CFURLRef baseURL = (__bridge_retained CFURLRef) [[NSURL alloc] initFileURLWithPath:SOUNDPATH];
AudioServicesCreateSystemSoundID (baseURL, &mySentenceAudio);
AudioServicesPlaySystemSound(mySentenceAudio);
CFRelease(baseURL);
AudioServicesAddSystemSoundCompletion (mySentenceAudio,NULL,NULL,theAudioServicesSystemSoundCompletionProc,(__bridge void*)self);
}
else {
}
}
#pragma mark - Audio Player Callback
static void theAudioServicesSystemSoundCompletionProc (SystemSoundID mySentenceAudio, void *myself) {
NSLog(@"Audio callback");
AudioServicesRemoveSystemSoundCompletion (mySentenceAudio);
AudioServicesDisposeSystemSoundID(mySentenceAudio);
MYVIEWCONTROLLERNAME *theClass = (__bridge MYVIEWCONTROLLERNAME *)myself;
[theClass myAudioLoopCheck];
}
// life cycle code...