I guess I could use AVAudioPlayer
to play a sound, however, what I need is to just play a short sound and I don\'t need any loops or fine-grained control over t
Check out systemsound to play short audio file
include audiotoolbox framework
and create
systemsoundid object
NSString *soundPath = [[NSBundle mainBundle] pathForResource:file ofType:@"aiff"];
AudioServicesCreateSystemSoundID((CFURLRef)[NSURL fileURLWithPath: soundPath], &soundID);
AudioServicesPlaySystemSound (soundID);
My answer is Bill's answer, but I use it without init or dealloc and release the sound after it's played:
- (void)playSound:(NSURL *)url
SystemSoundID ssID = 0;
AudioServicesCreateSystemSoundID((CFURLRef)url, &ssID);
AudioServicesAddSystemSoundCompletion(ssID, NULL, NULL, (AudioServicesSystemSoundCompletionProc)MyAudioServicesSystemSoundCompletionProc, NULL);
AudioServicesPlaySystemSound(ssID);
//AudioServicesDisposeSystemSoundID(ssID);
}
void MyAudioServicesSystemSoundCompletionProc (SystemSoundID ssID, void *clientData) {
AudioServicesDisposeSystemSoundID(ssID);
}
import AudioToolbox
func playSoundEasy(note : String) {
var soundURL: NSURL?
var soundID: SystemSoundID = 0
let filePath = Bundle.main.path(forResource: note, ofType: "wav")
soundURL = NSURL(fileURLWithPath: filePath!)
if let url = soundURL {
AudioServicesCreateSystemSoundID(url, &soundID)
AudioServicesPlaySystemSound(soundID)
}
}
Every single one of the other answers leaks memory (unless ARC is enabled for one of the answers)... oddly, the answer originally marked as correct has a call to retainCount
for no apparent reason.
If you alloc/init
something, it needs to be released (unless you are using ARC).
If you call AudioServicesCreateSystemSoundID()
you have to dispose of the resulting sound.
See the Audio UI Sounds example.
Basically:
@interface MyClass:UI*ViewController // fixed
{
SystemSoundID mySound;
}
@implementation MyClass
- (void) viewDidLoad {
[super viewDidLoad];
AudioServicesCreateSystemSoundID(.... URL ...., &mySound);
}
- (void) playMySoundLikeRightNowReally {
AudioServicesPlaySystemSound(mySound);
}
- (void) dealloc {
AudioServicesDisposeSystemSoundID(mySound);
[super dealloc]; // only in manual retain/release, delete for ARC
}
@end
For completeness:
add AudioToolbox.framework
#import <AudioToolbox/AudioToolbox.h>
A lot of answers are confusing, and some are using the AudioToolbox
framework, different from the AVAudioFoundation
framework... here's what I did. In the .h
file, I put this code in:
@property (nonatomic, retain) AVAudioPlayer *player;
This code declares an audio player named "player." In the .m
file, under your @implementation
declaration, add @synthesize player
. This synthesizes that player
property.
In whatever function you want, tie your sound in to the player by adding this line of code, where yourSound
is the name of the sound file, and aif
is your file extension:
player = [[AVAudioPlayer alloc] initWithContentsOfURL:[[NSBundle mainBundle] URLForResource:@"yourSound" withExtension:@"aif"] error:nil]
I know the Apple Documentation says to declare a string and a NSURL, but if you combine it into one line, then you won't have to dispose of it afterwards. Also, since this is a property in your ViewController.m
file, then you won't have to keep setting that player
object to tie in with your sound.
Other answers also included using a SystemSoundID
, but that also imposes restrictions like, "the file can't be over 30 seconds long," "it has to be in a specific format," and the works. With that, it can play several sounds at a time (in case you're developing a soundboard), and it's easier to create the sounds.
To actually play your sound, insert this line (and yes, it's really this easy):
[player play]
If you use ARC, you can't manually dispose of the player, as the system will do it for you. If you're new to developing and you're using the latest version of Xcode, then you have ARC enabled. If, for some strange reason, you don't, then the code for disposing of the resources being used by player
is:
[player release]
For short sound clips (less than 30 secs), there's a SystemSounds library which is really nice.
Pros: You don't need to manage volume settings separately. The sound is played in a separate thread and loading and playing of audio clip is v fast. In short, you treat this clip as another system sound.
Cons: You can't provide a separate audio control setting. It's tied to the settings of the system sounds. You can't play more than 30 seconds. You probably can't apply any sound filters to enhance audio effect.
There are certainly more pros and cons, but these are some I could think of, off the top of my head.
use this import: <AudioToolbox/AudioToolbox.h>
Add the AudioToolbox Framework
then call the below method like [self playSound], wherever you want to play the clip.
-(void) playSound {
NSString *soundPath = [[NSBundle mainBundle] pathForResource:@"changeTrack" ofType:@"aif"];
SystemSoundID soundID;
AudioServicesCreateSystemSoundID((CFURLRef)[NSURL fileURLWithPath: soundPath], &soundID);
AudioServicesPlaySystemSound (soundID);
[soundPath release];
}