在播放另一个之前停止声音

时间:2012-02-11 21:08:29

标签: objective-c ios cocoa-touch

我知道之前已经问过这个,但我不明白这些回应。我正在制作一个音板,当你点击其中一个按钮播放声音时,我希望那个已播放的音响停止。我知道我需要添加AudioServicesDisposeSystemSoundID(soundID);,但我在哪里添加它?这是我的代码:

- (IBAction)beyond:(id)sender {
    CFBundleRef mainBundle = CFBundleGetMainBundle();
    CFURLRef soundFileURLRef;
    soundFileURLRef =  CFBundleCopyResourceURL(mainBundle, (CFStringRef) @"beyond" ,CFSTR ("wav") , NULL);
    UInt32 soundID;
    AudioServicesCreateSystemSoundID(soundFileURLRef, &soundID);
    AudioServicesPlaySystemSound(soundID);
   }

- (IBAction)Years:(id)sender {
    CFBundleRef mainBundle = CFBundleGetMainBundle();
    CFURLRef soundFileURLRef;
    soundFileURLRef =  CFBundleCopyResourceURL(mainBundle, (CFStringRef) @"years" ,CFSTR ("wav") , NULL);
    UInt32 soundID;
    AudioServicesCreateSystemSoundID(soundFileURLRef, &soundID);
    AudioServicesPlaySystemSound(soundID);
   }

3 个答案:

答案 0 :(得分:1)

这里的问题是你将soundID定义为方法中的局部变量,而不是作为类中的实例变量。使用实例变量时,可以稍后从类中的任何方法访问它。

答案 1 :(得分:1)

如同不经意地说的那样。您需要创建一个实例变量(或ivar),以便多个方法可以引用同一个变量。正如您所知,AudioServicesDisposeSystemSoundID()会停止当前播放的SystemSoundID。一旦你声明了一个ivar,你就不需要在每个方法中声明变量。所以合乎逻辑的结论是。

@implementation ViewControllerClassNameHere{
    SystemSoundID soundID;
}
- (IBAction)beyond:(id)sender {
    AudioServicesDisposeSystemSoundID(soundID);
    CFBundleRef mainBundle = CFBundleGetMainBundle();
    CFURLRef soundFileURLRef;
    soundFileURLRef =  CFBundleCopyResourceURL(mainBundle, (CFStringRef) @"beyond" ,CFSTR ("wav") , NULL);
    AudioServicesCreateSystemSoundID(soundFileURLRef, &soundID);
    AudioServicesPlaySystemSound(soundID);
}
- (IBAction)Years:(id)sender {
    AudioServicesDisposeSystemSoundID(soundID);
    CFBundleRef mainBundle = CFBundleGetMainBundle();
    CFURLRef soundFileURLRef;
    soundFileURLRef =  CFBundleCopyResourceURL(mainBundle, (CFStringRef) @"years" ,CFSTR ("wav") , NULL);
    AudioServicesCreateSystemSoundID(soundFileURLRef, &soundID);
    AudioServicesPlaySystemSound(soundID);
}

在创建CFRelease()后,您也可能(肯定)希望CFURLRef复制SystemSoundID(因此您不会泄漏内存)。事实上,您可以考虑制作CFURLRef的ivars,以免不断复制它们。您也可能希望在AudioServicesDisposeSystemSoundID(soundID);中致电dealloc

答案 2 :(得分:1)

之前回答: Stopping sound in Xcode

但我可以重复我的回答。

总结一下,停止声音文件的句子是:

AudioServicesDisposeSystemSoundID (soundFileObject);

解释(重要的是要理解):

我有一个包含18种不同声音文件的表视图。当用户选择一行必须发出相应的文件时,当选择另一行时,它必须停止前一个声音并播放其他声音。

所有这些都是必要的:

1)在“建立阶段”中添加到项目“AudioToolbox.framework”,在“Link Binary with Libraries”中

2)在头文件中(在我的项目中调用“GenericTableView.h”)添加以下句子:

#include <AudioToolbox/AudioToolbox.h>

CFURLRef soundFileURLRef;
SystemSoundID soundFileObject;

@property (readwrite) CFURLRef soundFileURLRef;
@property (readonly) SystemSoundID soundFileObject;

3)在实现文件中(在我的项目中调用“GenericTableView.m”)添加以下句子:

@synthesize soundFileURLRef;
@synthesize soundFileObject;

在你的“行动”实施中或在我的情况下,在:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
//
// That is the question: a way to STOP sound file
//
// -----------------------------------------------------------------------
// Very important to STOP the sound file
AudioServicesDisposeSystemSoundID (soundFileObject);

// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------


// In my project "rowText" is a field that save the name of the 
// corresponding sound (depending on row selected)
// It can be a string, @"Alarm Clock Bell" in example

// Create the URL for the source audio file.
// URLForResource:withExtension: method is new in iOS 4.0.
NSURL *soundURL = [[NSBundle mainBundle] URLForResource:rowText withExtension:@"caf"];

// Store the URL as a CFURLRef instance
self.soundFileURLRef = (CFURLRef) [soundURL retain];

// Create a system sound object representing the sound file.
AudioServicesCreateSystemSoundID (soundFileURLRef,&soundFileObject);

AudioServicesPlaySystemSound (soundFileObject);

[soundURL release];
}

4)最后,在同一个工具文件中(在我的项目中它调用“GenericTableView.m”):

- (void)dealloc {
[super dealloc];

AudioServicesDisposeSystemSoundID (soundFileObject);
//CFRelease (soundFileURLRef);
}

我必须发表评论“CFRelease(soundFileURLRef)”,因为当用户离开表格视图时,应用程序意外结束。

所有这些代码都是Apple的比例。在此链接中,您甚至可以找到直接在iPhone模拟器中测试的示例代码。

https://developer.apple.com/library/ios/samplecode/SysSound/Introduction/Intro.html#//apple_ref/doc/uid/DTS40008018-Intro-DontLinkElementID_2