Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

agbyaj

macrumors newbie
Original poster
Jan 4, 2009
6
0
I've been working on my app for a few weeks, in my free time, and I've run into a snag. I can't figure out how to play a sound, at the push of a button. I know it is probably a really easy thing that I'm overlooking, but I am having a hell of a time finding the solution in Apple's documentation and elsewhere on the web. Any help can be appreciated. Right now I'm working on a test app that just focuses on the button push and the sound. Once I have that figured out, I'm just going to use that knowledge and integrate the solution into my main app. Thanks for your help.
 
I've been working on my app for a few weeks, in my free time, and I've run into a snag. I can't figure out how to play a sound, at the push of a button. I know it is probably a really easy thing that I'm overlooking, but I am having a hell of a time finding the solution in Apple's documentation and elsewhere on the web. Any help can be appreciated. Right now I'm working on a test app that just focuses on the button push and the sound. Once I have that figured out, I'm just going to use that knowledge and integrate the solution into my main app. Thanks for your help.

This should help: http://www.youtube.com/watch?v=T81kGfIGQjs

(I apologize if we aren't allowed to post links on the site, and if we aren't, someone inform me and I'll go ahead and provide an alternative way to get to that tutorial).

I hope you love little kids telling you how to do something, I know I do :)
 
^ don't use that code. It's leaking memory, plus it's unnecessarily using CFBundle/CFString/etc.

Try something like this:
Code:
void SoundFinishedPlaying(SystemSoundID soundID, void *clientData)
{
    AudioServicesDisposeSystemSoundID(soundID);
}

void PlaySound()
{
    NSURL *audioURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"sound.aif" ofType:nil]];
    SystemSoundID soundID;
    if (AudioServicesCreateSystemSoundID((CFURLRef)audioURL, &soundID) == kAudioSessionNoError)
    {
        AudioServicesAddSystemSoundCompletion(soundID, NULL, NULL, SoundFinishedPlaying, NULL);
        AudioServicesPlaySystemSound(soundID);
    }
}
 
Did not work

I followed your advice and the one that worked out the best. It compiles just fine, but won't make a sound when the button is pushed. There are three warnings: "property soundFileURLRef requires method -soundFileURLRef and setSoundFileURLRef, property soundFileObject requires method -soundFileObject". I realize that these are creator and setter methods, but I am new to Objective-C, yet I have a background in JAVA and C++. It seems like it is really hard to find any hard data on how to do anything with the SDK. I hope someone can help me out here. I've tried the youtube video before with no luck whatsoever. I think I'm just missing something small, because all the ways others have done it simply do not work for me. I appreciate the help. Is there a way I can get a little more guidance? Thank you guys. THis is the closest I've been yet.
 
Did you add the AudioToolbox framework to your project? (and not sure what code you're referring to there.)
 
I followed your advice and the one that worked out the best. It compiles just fine, but won't make a sound when the button is pushed. There are three warnings: "property soundFileURLRef requires method -soundFileURLRef and setSoundFileURLRef, property soundFileObject requires method -soundFileObject".

Sounds like you've added a property and not supplied the required accessor methods or synthesized them. Basically exactly what the compiler says.
 
FWIW, some sound files won't play in the Sim but do play on the device, and maybe vice versa. caf format is the most compatible sound file format. There's a command line tool afconvert that can convert a sound file to a more compatible format.
 
Here is my code to clarify

viewcontroller.h

#import <UIKit/UIKit.h>
#import <AudioToolbox/AudioToolbox.h>

@interface PlaySoundViewController : UIViewController {

CFURLRef soundFileURLRef;
SystemSoundID soundFileObject;

}

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

- (IBAction)playSound:(id)sender;

@end


viewcontroller.m

#import "PlaySoundViewController.h"
#import <AudioToolbox/AudioServices.h>

@implementation PlaySoundViewController


/*
// The designated initializer. Override to perform setup that is required before the view is loaded.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
// Custom initialization
}
return self;
}
*/

/*
// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView {
}
*/



// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];

//Get the main bundle for the app
CFBundleRef mainBundle;
mainBundle = CFBundleGetMainBundle();

//Get URL to the sound file to play
soundFileURLRef = CFBundleCopyResourceURL(mainBundle, CFSTR ("testFortune1"), CFSTR ("aif"), NULL);

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

//Play fortune to tap of a button
-(IBAction)playSound:(id)sender{

AudioServicesPlaySystemSound(soundFileObject);
}


/*
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
*/


- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview
// Release anything that's not essential, such as cached data
}


- (void)dealloc {
[super dealloc];

AudioServicesDisposeSystemSoundID(soundFileObject);
CFRelease(soundFileURLRef);
}



@end


What am I missing? I connected the button to the correct method in the interface builder already, but still no go.
 
You're not doing any error checking. Makes sure the objects you create are valid, make sure the audio functions return no error, etc.
 
Also, and I'm starting to feel like such a broken record saying this, please enclose your code snippets in [ CODE ][ /CODE ] tags (removing the spaces, of course). These are most easily accessed by using the # icon in the toolbar.
 
just to add something to this discussion: in playing a sound, i've noticed that the first time the sound play it lags while it's loading. i haven't tested to see if it does this on the actual device yet, but is there a way to perhaps load the sound on start up to avoid a lag?
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.