I created class for handling sounds. But I've problem to stop sound? I can't send variable from playSound to stopSound AudioServicesDisposeSystemSoundID(soundID).
How to handle this? I really don't want instantiate it or I've to?
#implementation SoundPlayer
+(void)playSound:(NSString *)filename ofType:(NSString *)extension {
SystemSoundID soundID;
NSString *soundFile = [[NSBundle mainBundle] pathForResource:filename ofType:extension];
AudioServicesCreateSystemSoundID((__bridge CFURLRef)[NSURL fileURLWithPath:soundFile], &soundID);
AudioServicesPlaySystemSound(soundID); // error - soundID is undeclared
}
+(void)stopSound
{
AudioServicesDisposeSystemSoundID(soundID);
}
#end
You'll either have to pass the id to stopSound (the same as when you play sound), or else if your audio player only plays 1 sound at a time, store the soundID as a static param on the class when you play.
You can create soundID as ivar, something like:
#interface SoundPlayer(){
SystemSoundID soundID;
}
#end
Other way use it as global variable
Related
I'm trying to play an audio file in the background of my app and it isn't playing. The code that I have is:
SystemSoundID SoundID;
NSString *soundFile = [[NSBundle mainBundle] pathForResource:#"HoHey" ofType:#"mp3"];
AudioServicesCreateSystemSoundID((__bridge CFURLRef)[NSURL fileURLWithPath:soundFile], &SoundID);
AudioServicesPlaySystemSound(SoundID);
NSLog(#"%# is playing\n", soundFile);
The NSLog displays "HoHey.mp3 is playing" but I can't hear it playing. My volume is turned up btw because I hear my videos play when I play them. Any ideas?
You likely have an error somewhere along the way. Try code that looks like this:
SystemSoundID soundID;
NSString *soundFile = [[NSBundle mainBundle] pathForResource:#"HoHey" ofType:#"mp3"];
if(soundFile)
{
OSStatus status = AudioServicesCreateSystemSoundID((__bridge CFURLRef)[NSURL fileURLWithPath:soundFile], &soundID);
if(status == noErr)
{
AudioServicesPlaySystemSound(soundID);
NSLog(#"%# is playing\n", soundFile);
} else {
NSLog( #"no sound id created; error status code is %d", status);
}
} else {
NSLog( #"couldn't find sound file... is it really in your app bundle?");
}
P.S., don't capitalize Objective-C variable names (e.g. "soundID" instead of "SoundID").
I have a UIButton in a nib (xib) that id like to play a sound when touched, what protocol needs to be followed to make this happen?
** overhauled question** Throughout my time here on Stack Overflow, i've learned a lot, and not just about what i'm usually needing help with (Objective-C, xCode), but with how Stack Overflow works. I find it to be a vast wealth of information and support and i've looked at how i've asked this question before and it made absolutely no sense at all. To help future users, i've edited what I was originally asking for, in a way others can understand like Naveen did below. Apologies
Add this framework
AudioToolBox framework
Include this header file .h file
#include <AudioToolbox/AudioToolbox.h>
CFURLRef soundFileURLRef;
SystemSoundID soundFileObject;
Add this code in viewdidLoad
NSURL *tapSound = [[NSBundle mainBundle] URLForResource: #"Voice035"
withExtension: #"amr"];
// Store the URL as a CFURLRef instance
self.soundFileURLRef = (CFURLRef) [tapSound retain];
// Create a system sound object representing the sound file.
AudioServicesCreateSystemSoundID (
soundFileURLRef,
&soundFileObject
);
On Button Tap, Call this method
AudioServicesPlayAlertSound (soundFileObject);
Do release in dealloc
AudioServicesDisposeSystemSoundID (soundFileObject);
CFRelease (soundFileURLRef);
For more info : http://developer.apple.com/library/ios/#documentation/AudioToolbox/Reference/SystemSoundServicesReference/Reference/reference.html#//apple_ref/c/func/AudioServicesCreateSystemSoundID
I would say, create an 'Observer' class that plays the sound that all buttons are connected to. I'll give an example below, It is a singleton class. It's written on a whim, and not tested but gives you an idea.
//SoundObserver.h
#include <AVFoundation/AVFoundation.h>
#interface SoundObserver {
AVAudioPlayer *audioPlayer;
}
-(void)playSound;
+(SoundObserver*)sharedInstance;
#property (nonatomic, retain) AVAudioPlayer *audioPlayer;
#end
//SoundObserver.m
static SoundObserver *instance = nil;
#implementation SoundObserver
-(id)init {
self = [super init];
if(self) {
//Get path to file.
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"sound"
ofType:#"wav"];
// filePath to URL
NSURL *fileURL = [[NSURL alloc] initFileURLWithPath:filePath];
//Initialize the AVAudioPlayer.
self.audioPlayer = [[AVAudioPlayer alloc]
initWithContentsOfURL:fileURL error:nil];
// Preloads buffer and prepare for use.
[self.audioPlayer prepareToPlay];
[filePath release];
[fileURL release];
}
}
+(SoundObserver*)sharedInstance {
#synchronized(self) {
if (instance == nil)
instance = [[self alloc] init];
}
return instance;
}
-(void)playSound {
//make sure the audio resets to beginning each activation.
[self.audioPlayer play];
}
-(void)dealloc {
//Clean up
[self.audioPlayer release];
self.audioPlayer = nil;
[super dealloc];
}
// User example.
In applicationDidFinishLaunching:
[SoundObserver sharedInstance];
From here you can connect all buttons to the same function, or call it from anywhere in the App that #import's SoundObserver.h
-(IBOutlet)buttonClick:(id)sender {
[[SoundObserver sharedInstance] playSound];
}
i'm new in Objective C, i'm developing an app that play sound on touch event of an uibutton.
When i touch the button, it change is image and audio starts to playing. When audio is finish to play, i want to put the original image of uibutton. How can i do that? How can i catch the event of the audio that is finish?
i'm using that code:
- (SystemSoundID) createSoundID: (NSString*)name
{
NSString *path = [NSString stringWithFormat: #"%#/%#",
[[NSBundle mainBundle] resourcePath], name];
NSURL* filePath = [NSURL fileURLWithPath: path isDirectory: NO];
SystemSoundID soundID;
AudioServicesCreateSystemSoundID((CFURLRef)filePath, &soundID);
return soundID;
}
In
viewDidLoad
i call
freq = [self createSoundID: #"freq.wav"];
and in function that is called on button's touch i use:
AudioServicesPlaySystemSound(freq);
How can i do? Thank you!
Not sure if it's possible with the AudioService API but you can use AVAudioPlayer instead and assign a delegate that implements the AVAudioPlayerDelegate protocol and does something when audioPlayerDidFinishPlaying:successfully: is called.
Remember to add the AVFoundation framework.
Example:
In your interface definition:
#import <AVFoundation/AVFoundation.h>
...
#inteface SomeViewController : UIViewController <AVAudioPlayerDelegate>
...
#propety(nonatomic, retain) AVAudioPlayer *player;
In your implementation:
#synthesize player;
...
// in some viewDidLoad or init method
self.player = [[[AVAudioPlayer alloc] initWithContentsOfURL:soundUrl error:NULL] autorelease];
self.player.delegate = self;
...
- (void)pressButton:(id)sender {
// set play image
[self.player stop];
self.player.currentTime = 0;
[self.player play];
}
...
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag {
// set finish image
}
...
# in some dealloc or viewDidUnload method
self.player = nil;
It is possible with the AudioService API, you want to use AudioServicesAddSystemSoundCompletion.
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
i'm new with the iphone and objective c, so far, I have been able to code some small examples.
i would like to play a sound and, continue with rest of the code when the sample finishes playing, i.e:
printf("hello");
playASound["file.wav"];
printf("world");
actually i'm getting: print hello, play the file and print world at the same time
but
what i want is: print hello, play the file, print world...
so, the question is how do i get it?
thanks
btw. here is the playASound code:
-(void) playASound: (NSString *) file {
//Get the filename of the sound file:
NSString *path = [NSString stringWithFormat:#"%#/%#",
[[NSBundle mainBundle] resourcePath],
file];
SystemSoundID soundID;
//Get a URL for the sound file
NSURL *filePath = [NSURL fileURLWithPath:path isDirectory:NO];
AudioServicesCreateSystemSoundID((CFURLRef)filePath, &soundID);
//play the file
AudioServicesPlaySystemSound(soundID);
}
From the documentation:
Discussion This function plays a short
sound (30 seconds or less in
duration). Because sound might play
for several seconds, this function is
executed asynchronously. To know when
a sound has finished playing, call the
AudioServicesAddSystemSoundCompletion
function to register a callback
function.
So you'll need to break up your function into two pieces: a function that calls PlayASound and prints "Hello", and a function that is called by the system when the sound is finished playing and prints "World".
// Change PlayASound to return the SystemSoundID it created
-(SystemSoundID) playASound: (NSString *) file {
//Get the filename of the sound file:
NSString *path = [NSString stringWithFormat:#"%#/%#",
[[NSBundle mainBundle] resourcePath],
file];
SystemSoundID soundID;
//Get a URL for the sound file
NSURL *filePath = [NSURL fileURLWithPath:path isDirectory:NO];
AudioServicesCreateSystemSoundID((CFURLRef)filePath, &soundID);
//play the file
AudioServicesPlaySystemSound(soundID);
return soundID;
}
-(void)startSound
{
printf("Hello");
SystemSoundID id = [self playASound:#"file.wav"];
AudioServicesAddSystemSoundCompletion (
id,
NULL,
NULL,
endSound,
NULL
);
}
void endSound (
SystemSoundID ssID,
void *clientData
)
{
printf("world\n");
}
See also docs for AudioServicesAddSystemSoundCompletion and AudioServicesSystemSoundCompletionProc.