views:

599

answers:

3

I'm using the following to play an m4a file:

NSString *path = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent: fileName];
SystemSoundID soundID;
NSURL *filePath = [NSURL fileURLWithPath:path isDirectory:NO];
AudioServicesCreateSystemSoundID((CFURLRef)filePath, &soundID);
AudioServicesPlaySystemSound(soundID);

It works fine on the simulator but I hear nothing on the device. Sounds files I'm using all stay in the bundle. Here is what filePath looks like from the device:

file://localhost/var/mobile/Applications/418945F3-3711-4B4D-BC65-0D78993C77FB/African%20Adventure.app/Switch%201.m4a

Is there an issue with the file path or any thing different I need to do for the device?

A: 

Start by error-checking your returns. Is filePath nil? Do either of the AudioServices functions return an error? The most likely cause is case-sensitivity. The iPhone filesystem is case sensitive while the Mac is not. But the first step in debugging is to look at the errors the system is providing.

Rob Napier
filePath isn't nil. It has the value I posted in the OP. I don't see any errors occurring.
You've checked the OSStatus results, and both are noErr?
Rob Napier
How do I check OSStatus results?
AudioServicesCreateSystemSoundID() and AudioServicesPlaySystemSound() return a result code of type OSStatus (all audio functions do). If it returns 0 (noErr), then it was successful. Otherwise, it's a negative number indicating the error. They're documented here: http://developer.apple.com/iphone/library/documentation/AudioToolbox/Reference/SystemSoundServicesReference/Reference/reference.html
Rob Napier
Thanks. AudioServicesCreateSystemSoundID does return 0 but AudioServicesPlaySystemSound is a void.
Try pulling SysSound and see if it works for you. If it does, then look for how your code is different: http://developer.apple.com/iphone/library/samplecode/SysSound/
Rob Napier
Thanks. I got that project up and running on the device with sound. I put in my m4a file and it doesn't play. Seems AudioServices doesn't like m4a files.
A: 

The simulator uses regular QuickTime for playback, so it's easy to have media assets which work in the sim, but fail on the device due to missing / unsupported codecs. The test is if you can play the file at all on the device, eg through Safari or the iPod app.

James Turner
The sounds do play on the iPhone's iPod.
iTunes recodes the sound so that it can play on the device, try playing via Safari.
Henri Watson
A: 

You might want to use the AVAudioPlayer instead of AudioServices.

The following code will take an audio file (.m4a) and play the audio file 1 time. Don't forget to release "audioPlayer" when you're done with it.

NSString *urlAddress = [[NSBundle mainBundle] pathForResource:@"filename" ofType:@"m4a"];

NSURL *url = [NSURL fileURLWithPath:urlAddress];
NSError *error;

AVAudioPlayer *audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
audioPlayer.numberOfLoops = 0;

if (audioPlayer == nil)
{
  NSLog([error description]);
}
else
{
  [audioPlayer play];
}

Hope this example helps you with playing audio on the actual device. It might also be a good idea to increase the device audio when the file is playing.

Note: You will need to add the AVFoundation framework to your project if you have not already done so. As well as import the header file.

#import <AVFoundation/AVFoundation.h>

Update:

From Apple's Core Audio Overview Document

Audio Session Services

Audio Session Services lets you manage audio sessions in your application—coordinating the audio behavior in your application with background applications on an iPhone or iPod touch. Audio Session Services consists of a subset of the functions, data types, and constants declared in the AudioServices.h header file in AudioToolbox.framework.

The AVAudioPlayer Class

The AVAudioPlayer class provides a simple Objective-C interface for playing sounds. If your application does not require stereo positioning or precise synchronization, and if you are not playing audio captured from a network stream, Apple recommends that you use this class for playback. This class is declared in the AVAudioPlayer.h header file in AVFoundation.framework.

Tammen Bruccoleri
Thanks. I will try it. Why would AudioServices fail to play sounds? Or, why use one over the other?
I'm using AVAudioPlayer now on a user event basis (i.e. button click). I release if not nil, create the instance, and play. Seems as though there is a small delay since I'm creating an instance each time. Is there a more efficient way?