I have an app I am working on and It uses some of the hardware sensors to provide data on screen, there is a Label that updates with the number. I want a sound to play whenever the number is above 100 or something. For example, say it was reading numbers then all of the sudden it finds a good spot (or whatever), then I would like a sound to play or a light to light up. I am an absolute beginner and it would be nice if the answer would be easy for a absolute beginner to understand.
I am using the system AudioToolbox.framework for playing sounds in my simple game. I added this static function to common MyGame class:
+ (SystemSoundID) createSoundID: (NSString*)name
{
NSString *path = [NSString stringWithFormat: #"%#/%#",
[[NSBundle mainBundle] resourcePath], name];
NSURL* filePath = [NSURL fileURLWithPath: path isDirectory: NO];
SystemSoundID soundID;
AudioServicesCreateSystemSoundID((__bridge CFURLRef)filePath, &soundID);
return soundID;
}
I added the "Morse.aiff" file to project Resources and initialized it in (any) class initialization with the following:
self.mySound = [MyGame createSoundID: #"Morse.aiff"];
And then I played sound with this call:
AudioServicesPlaySystemSound(mySound);
Also, don't forget to import AudioServices.h file.
This audio toolbox can play also different sound formats.
h
#import <AVFoundation/AVFoundation.h>
#interface CMAVSound : NSObject {
AVAudioPlayer *audioPlayer;
}
- (id)initWithPath:(NSString*)fileNameWithExctension;
- (void)play;
#end
m
#import "CMAVSound.h"
#implementation CMAVSound
-(void)dealloc {
[audioPlayer release];
}
- (id)initWithPath:(NSString*)fileNameWithExctension {
if ((self = [super init])) {
NSURL *url = [NSURL fileURLWithPath:[NSString stringWithFormat:#"%#/%#", [[NSBundle mainBundle] resourcePath], fileNameWithExctension]];
NSError *error;
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
if (audioPlayer == nil) {
NSLog(#"%#", [error description]);
}
}
return self;
}
- (void)play {
[audioPlayer play];
}
#end
Check out the documentation for the AVAudioPlayer class. It allows you to play sounds clips. If you have troubles implementing that, show us some code.
If the sounds gonna up to 5 seconds and no stereo output is needed I would recommend you to do that with system sounds. It is easy and better solution then any other.
Apple sample code is provided under name SysSound
EDIT1
Or maybe tutorial could help you more
http://howtomakeiphoneapps.com/2009/08/how-to-play-a-short-sound-in-iphone-code/
Take a look at following links;
http://blog.guvenergokce.com/avaudioplayer-on-iphone-simulator/57/
http://mobileorchard.com/easy-audio-playback-with-avaudioplayer/
Here you can find list of AudioServicesPlaySystemSound
http://iphonedevwiki.net/index.php/AudioServices
Related
I managed to create this application that includes an animation in it. But I want to make it stand out and more fun by adding a .wav file that I downloaded from the web. I want the sound to play for the duration of the animation. Only started coding a month ago so any help would be deeply appreciated
You could use the AVAudioPlayer
just create a method and connect it to your button or animation
-(void) playLoopingMusicInApplication {
AVAudioPlayer *audioPlayer;
// set the pathForResource: to the name of the sound file, and ofType: to AAC preferrably.
NSString *soundFilePath = [[NSBundle mainBundle] pathForResource:#"fileName" ofType:#"WAV"];
NSURL *soundFileURL = [NSURL fileURLWithPath:soundFilePath];
player = [[AVAudioPlayer alloc] initWithContentsOfURL:soundFileURL error:nil];
player.delegate = self;
//infinite
player.numberOfLoops = -1;
[player play];
//[player release];
}
PS - You will need to get the AVFoundation framework, and the AudioToolbox framework in your project
hope this helps!
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Is it possible to play sounds without stopping iPod music?
Is there a simple way to play a sound without stopping music? I'm trying to make a metronome app if you have any suggestions they would be appreciated.
Are you talking about playing a sound without interrupting music from the iPod/Music app? If so, you need to configure your audio session category to allow mixing with the kAudioSessionProperty_OverrideCategoryMixWithOthers property.
See Is it possible to play sounds without stopping iPod music? for sample code.
Another solution: Create a player class to wrap the initialization (uses AVFoundation.framework).
Source:
#import "MyAVAudioPlayer.h"
#implementation MyAVAudioPlayer
-(id)initWithFile:(NSString*)strFile
{
NSError *err;
NSString *resourcePath = [[NSBundle mainBundle] resourcePath];
resourcePath = [resourcePath stringByAppendingString:#"/"];
resourcePath = [resourcePath stringByAppendingString:strFile];
self = [super initWithContentsOfURL:[NSURL fileURLWithPath:resourcePath]
error:&err];
if(err)
{
NSLog(#"Loading of %# Failed with reason: %#", strFile,
[err localizedDescription]);
}
else
{
NSLog(#"Loaded %#", strFile);
[self prepareToPlay];
}
return self;
}
#end
Header:
#import <AVFoundation/AVFoundation.h>
#interface MyAVAudioPlayer : AVAudioPlayer
{
}
-(id)initWithFile:(NSString*)strFile;
#end
Usage:
MyAVAudioPlayer *player = [[MyAVAudioPlayer alloc] initWithFile:#"yoursound.mp3"];
[player play]
I have an object moving around the screen and once it reaches the edges it it changes direction and plays a sound this all works fine except that when it plays the sound I freezes for about half a second is there any way of making this run smoothly with the sound and object movement?
-(void)viewDidLoader
{
NSString *path1 = [[NSBundle mainBundle] pathForResource:#"ballbounce" ofType:#"mp3"];
ballbounce = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path1] error: NULL];
[ballbounce prepareToPlay];
}
-(void) ballcollition
{
[self ballplaysound]
enemy.center = CGPointMake(enemy.center.x+pos.x,enemy.center.y+pos.y);
if (enemy.center.x > 328 || enemy.center.x < 0)
{
pos.x = -pos.x;
}
}
-(void)ballplaysound
{
if (enemy.center.x > 328 || enemy.center.x < 0 ||enemy.center.y < 0||enemy.center.y < 300)
[ballbounce play];
}
use the System Sound for sound that plays smoothly.
Original NON-ARC answer:
#import <AudioToolbox/AudioToolbox.h>
- (IBAction)soundButton:(id)sender {
NSString *soundPath = [[NSBundle mainBundle] pathForResource:#"alert" ofType:#"wav"];
SystemSoundID soundID;
AudioServicesCreateSystemSoundID((CFURLRef)[NSURL fileURLWithPath: soundPath], &soundID);
AudioServicesPlaySystemSound (soundID);
[soundPath release];
}
Updated for ARC, and turned into a utility function:
- (void)soundPlay:(NSString*)waveName {
// wavName = #"alert" without any file extension (not alert.wav)
NSString *soundPath = [[NSBundle mainBundle] pathForResource:waveName ofType: #"wav"];
SystemSoundID soundID;
AudioServicesCreateSystemSoundID((__bridge CFURLRef)[NSURL fileURLWithPath: soundPath], &soundID);
AudioServicesPlaySystemSound (soundID);
}
Use AudioServicesPlaySystemSound(): https://developer.apple.com/library/ios/#documentation/AudioToolbox/Reference/SystemSoundServicesReference/Reference/reference.html
You can gain sound "smoothness" with AVPlayer by simply converting your mp3 to caf format as explained here.
1) Create AVAudioPLayer and cache it in your apps initialization code and never call it again
also call prepare as well.
2) so the method you included should only have to call play;
3) If you still get a skip use
[ballbounce performSelectorOnMainThread:#selector(play) withObject:nil];
Since you didnt include all the code and you are clearly doing drawing - putting the play method
on the queue could let the drawing code finish without interruption.
Doing this correctly might fix you. Using AudioSystemSound is much lower overhead but you should follow the same principles of preparing any often used sounds in your app initialization and not spawning them at the exact time you need them to avoid performance issues.
I’m trying to make a small iPhone application with some buttons to play WAV sounds.
My buttons works, but I have a small latency (~ 0,5 sec).
This is my .m file :
#import "buttonSoundViewController.h"
#implementation buttonSoundViewController
//#synthesize player;
-(IBAction) playSoundA:(id)sender{
NSString *path = [[NSBundle mainBundle] pathForResource:#"a" ofType:#"wav"];
AVAudioPlayer* theAudio = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
theAudio.delegate = self;
[theAudio play];
}
-(IBAction) playSoundB:(id)sender{
NSString *path = [[NSBundle mainBundle] pathForResource:#"b" ofType:#"wav"];
AVAudioPlayer* theAudio = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
theAudio.delegate = self;
[theAudio play];
}
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag {
[player release];
}
-(void)audioPlayerDecodeErrorDidOccur:(AVAudioPlayer *)player error:(NSError *)error {
}
-(void)audioPlayerBeginInterruption:(AVAudioPlayer *)player {
}
-(void)audioPlayerEndInterruption:(AVAudioPlayer *)player {
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (void)viewDidUnload {
}
- (void)dealloc {
[audioPlayer release];
[super dealloc];
}
#end
How can I avoid this latency between playing different sounds?
Using AudioServices is indeed much quicker for small sounds (less than 30 seconds). The required code isn't very long either (but it requires some good old C).
#import <AudioToolbox/AudioServices.h>
SystemSoundID soundID = 0;
NSString* str = [[NSBundle mainBundle] pathForResource:fileName ofType:nil];
CFURLRef soundFileURL = (CFURLRef)[NSURL URLWithString:str ];
OSStatus errorCode = AudioServicesCreateSystemSoundID(soundFileURL, &soundID);
if (errorCode != 0) {
// Handle failure here
}
else
AudioServicesPlaySystemSound(soundID);
Also you can optimize your sounds (reduce their size) with the following terminal command:
afconvert mysound.caf mysoundcompressed.caf -d ima4 -f caff
You could simplify things a lot by using system sounds. Look up: AudioServicesCreateSystemSoundID in the documentation. There is also a "System Sound Services Reference Document" that talks about that and other related functions. This is a simple and efficient way to play short sounds. Not sure if it will solve your latency issues but its a good start. You may also try using some different sound file types. Perhaps there is an issue with how it was or was not compressed.
Maybe you could look at AppSoundEngine. It addresses latency and greatly simplifies using of System Sound Services, because it is objective-c wrapper for SystemSoundID and associated C functions.
You can not get acceptable latency (<10 ms) from AVAudioPlayer. System Sound Services is the way to go.
From the Apple Docs grab the SoundEffect class in project BubbleLevel
SoundEffect is a simple Objective-C wrapper around Audio Services
functions that allow the loading and playing of sound files.
Classes/SoundEffect.m
this will make playing files as easy as
SoundEffect *soundEffect = [SoundEffect soundEffectWithContentsOfFile:#""]
[soundEffect play];
it will also handle memory deallocation. AudioServicesDisposeSystemSoundID(soundID);
One simple fix would just be to do the AVAudioPlayer alloc init for the 2 sounds in your buttonSoundViewController's init method. Then those 2 audio players will already be ready to play in your button delegates.
The fastest way to play sounds is to use the RemoteIO Audio Unit, but that's a far more advanced and complicated looking API.
-(IBAction)playSound{ AVAudioPlayer *myExampleSound;
NSString *myExamplePath = [[NSBundle mainBundle] pathForResource:#"myaudiofile" ofType:#"caf"];
myExampleSound =[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:myExamplePath] error:NULL];
myExampleSound.delegate = self;
[myExampleSound play];
}
I want to play a beep sound when a button is clicked. I had used the above code. But it is taking some delay in playing the sound.
Anyone please help.
There are two sources of the delay. The first one is bigger and can be eliminated using the prepareToPlay method of AVAudioPlayer. This means you have to declare myExampleSound as a class variable and initialize it some time before you are going to need it (and of course call the prepareToPlay after initialization):
- (void) viewDidLoadOrSomethingLikeThat
{
NSString *myExamplePath = [[NSBundle mainBundle]
pathForResource:#"myaudiofile" ofType:#"caf"];
myExampleSound =[[AVAudioPlayer alloc] initWithContentsOfURL:
[NSURL fileURLWithPath:myExamplePath] error:NULL];
myExampleSound.delegate = self;
[myExampleSound prepareToPlay];
}
- (IBAction) playSound {
[myExampleSound play];
}
This should take the lag down to about 20 milliseconds, which is probably fine for your needs. If not, you’ll have to abandon AVAudioPlayer and switch to some other way of playing the sounds (like the Finch sound engine).
See also my own question about lags in AVAudioPlayer.
AudioServicesPlaySystemSound is an option. Tutorial here, sample code here.