Playing sound on a button click - iphone

I'm facing a very strange issue, my requirement is to play a sound on the button click and this is my code:
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *path=[[NSBundle mainBundle] pathForResource:#"button-3" ofType:#"mp3"];
tapSound=[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL]];
[tapSound prepareToPlay];
tapSound.delegate=self;
//creating the button in view did load and button is declared in .h
btn=[UIButton buttonWithType:UIButtonTypeCustom];
btn.frame=CGRectMake(x, y, 58,58);
[btn addTarget:self action:#selector(btnClkd:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
}
//click method
-(void)btnClkd:(UIButton*)sender
{
[tapSound play];
}
But when I run the code and click the button my app gets crashed and got this error: "Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIButton play]: unrecognized selector sent to instance 0x758c790' "
But if I play the sound anywhere else but not on the click of the button then it get played without any issue.I dont know why this is happening? Please help me

Do this:
-(void)btnClkd:(UIButton*)sender
{
NSString *path=[[NSBundle mainBundle] pathForResource:#"button-3" ofType:#"mp3"];
tapSound = nil;
tapSound=[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL]];
[tapSound prepareToPlay];
tapSound.delegate=self;
[tapSound play];
}

Try this one . Add in your .h file
.h file
#import <AVFoundation/AVFoundation.h>
#import <AudioUnit/AudioUnit.h>
AVAudioPlayer *player1;
#property(nonatomic ,retain)AVAudioPlayer *player1;
in your .m file
#synthesize player1;
- (void)viewDidLoad
{
[super viewDidLoad];
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSString *soundFilePath = [[NSBundle mainBundle] pathForResource:#"button-3" ofType:#"mp3"];
NSURL *fileURL = [[NSURL alloc] initFileURLWithPath:soundFilePath];
AVAudioPlayer *audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:fileURL error:nil];
[fileURL release];
self.player1 = audioPlayer;
[audioPlayer release];
[self.player1 prepareToPlay];
[self.player1 setDelegate:self];
[pool release];
//creating the button in view did load and button is declared in .h
btn=[UIButton buttonWithType:UIButtonTypeCustom];
btn.frame=CGRectMake(x, y, 58,58);
[btn addTarget:self action:#selector(btnClkd:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
}
-(void)btnClkd:(UIButton*)sender {
[self.player1 play];
}

Related

UIButtons event Touch up Inside not work properly?

My question is little abmigious ,thats why I posted all my code,so I request to every one please test all this code before giving me the Answer.Thanx
In my application i create all UIButtons programmatically and then save all these UIButtons in NSMutableArray. Here is my code:-
-(void)button:(id)sender
{
int btnn = 0;
int spacex = 152;
int spacey=20;
int k=0;
saveBtn = [[NSMutableArray alloc] init];
for (int i=0; i<48; i++)
{
if (btnn>6)
{
spacey=spacey+25;
spacex = 152;
btnn = 0;
}
else
{
btnn++ ;
k++;
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
btn.frame = CGRectMake(spacex, spacey, 25.0, 25.0);
int idx;
idx = arc4random()%[arr count];
NSString* titre1 = [arr objectAtIndex:idx];
[btn setTitle: titre1 forState: UIControlStateNormal];
[btn setTitleColor: [UIColor yellowColor] forState: UIControlStateNormal];
[btn.titleLabel setFont:[UIFont fontWithName:#"TimesNewRomanPS-BoldMT" size:22.0]];
spacex = spacex + 25;
btn.tag=k;
[btn addTarget:self action:#selector(aMethod:)forControlEvents:UIControlEventTouchUpInside];
[saveBtn addObject:btn];
[self.view addSubview:btn];
}
}
}
Now in (aMethod:) I add click sound on Each UIButton TouchUpInside event. Here is my code.
- (void)aMethod:(id)sender
{
NSString *path = [[NSBundle mainBundle] pathForResource:#"button-17" ofType:#"wav"];
AVAudioPlayer* theAudio=[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
theAudio.delegate=self;
[theAudio play];
}
Every thing work fine in start of my application , but continiously clicking the UIButtons approximatilly after 100 clicks i hear no sound of click and when i click on Next UIButtons touchup inside event its crash.Can any body help me in this issue.Thanx
app due to uncaught exception NSInternalInconsistencyException, reason: Could not load NIB in bundle: NSBundle </Users/moon/Library/Application Support/iPhone Simulator/4.1/Applications/3E14E5D6-4D1B-4DAC-A2B9-07667E99C399/soundtesting.app‌​> (loaded) with name secondclass
Ah, yes. What we have here is a failure to understand log messages. Your UIButton, which I can only assume pushes a new view onto the stack, is referencing a NIB that simply doesn't exist. It's a naming issue, not a button issue. Most likely, I would check for any calls to -initWithNibName: and see if your NIB really is named "secondclass.". Remember, iOS file names are CaSe SeNsITive.
//.h
...
#property (nonatomic, retain) AVAudioPlayer * player;
//.m
-(void)viewDidLoad
{
NSString *path = [[NSBundle mainBundle] pathForResource:#"button-17" ofType:#"wav"];
player=[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
player.delegate=self;
//in MRC, use [path release];
}
-(void)someMethod:(id)sender
{
[player play];
}
The reason might me memory leak for playing same audio these many times it may fill memory use this code for playing audio
- (id)initWithNibName:(NSString*)nibName bundle:(NSBundle*)nibBundleOrNil
{
if (self = [super initWithNibName:nibName bundle:nibBundleOrNil]) {
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"button-17" ofType:#"wav"];
theAudio = [AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:filePath] error:NULL];
}
return self;
}
- (IBAction)playSound
{
[theAudio play];
}
- (void)dealloc
{
[theAudio release];
[super dealloc];
}
You have a memory issue. When you do :
- (void)aMethod:(id)sender
{
NSString *path = [[NSBundle mainBundle] pathForResource:#"button-17" ofType:#"wav"];
AVAudioPlayer* theAudio=[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
theAudio.delegate=self;
[theAudio play];
}
1/ path is never released
2/ theAudio is never release
So you need to release theAudio in delegate method :
– audioPlayerDidFinishPlaying:successfully:
And you need to release path like this :
- (void)aMethod:(id)sender
{
NSString *path = [[NSBundle mainBundle] pathForResource:#"button-17" ofType:#"wav"];
AVAudioPlayer* theAudio=[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
theAudio.delegate=self;
[theAudio play];
[path release];
}
I think your problem should be solved.
I test your code . Changes in your aMethod following code. Though this I can get tag value.
- (void)aMethod:(id)sender
{
UIButton *btn=(UIButton *)sender;
NSLog(#"\n\n\nselectedbutton tag === %d \n\n\n",btn.tag );
NSString *path = [[NSBundle mainBundle] pathForResource:#"button-17" ofType:#"wav"];
NSURL *url = [[NSURL alloc] initFileURLWithPath:path];
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:NULL];
audioPlayer.delegate = self;
[audioPlayer prepareToPlay];
[audioPlayer play];
}

Adjusting the size the volume, using the same uislider but for multiple sounds

I have 10 sounds in a view. And one uislider
This is the code for 1 of the sounds.
- (IBAction)oneSound:(id)sender; {
SystemSoundID soundID;
NSString *path = [[NSBundle mainBundle] pathForResource:#"1" ofType:#"mp3"];
AudioServicesCreateSystemSoundID((CFURLRef)[NSURL fileURLWithPath:path],&soundID);
AudioServicesPlaySystemSound (soundID);
if (oneAudio) [oneAudio release];
NSError *error = nil;
oneAudio = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:&error];
if (error)
NSLog(#"%#",[error localizedDescription]);
oneAudio.delegate = self;
[oneAudio play];
}
- (void)viewDidLoad {
[volumeSlider addTarget:self action:#selector(updateVolume) forControlEvents:UIControlEventValueChanged];
[super viewDidLoad];
}
-(void)updateVolume {
[oneAudio, twoAudio, threeAudio, fourAudio, fiveAudio, sixAudio, sevenAudio, eightAudio, nineAudio, tenAudio, elevenAudio, twelveAudio, thirteenAudio, fourteenAudio, fifthteenAudio, sixteenAudio setVolume:volumeSlider.value];
}
This is the current method I've tried and it doesn't work. Thanks for the help
In updateVolume you can't call on multiple instances by listing them like that. What you should do is put all of these audio players into an array and loop through each and setVolume on each object in the array.

How to make a Custom UIButton to toggle a Sound On/Off

i am an n00b and seeking help.
Now i can start a Soundfile with Following code:
- (void)addButtonSpeaker {
UIButton *buttonSpeaker = [UIButton buttonWithType:UIButtonTypeCustom];
[buttonSpeaker setFrame:CGRectMake(650, 930, 63, 66)];
[buttonSpeaker setBackgroundImage:[UIImage imageNamed:#"buttonLesen.png"]
forState:UIControlStateNormal];
[buttonSpeaker addTarget:self action:#selector(playAudio)
forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:buttonSpeaker];
}
- (void)playAudio {
NSString *path = [[NSBundle mainBundle] pathForResource:#"Vorwort" ofType:#"mp3"];
AVAudioPlayer* theAudio = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL
fileURLWithPath:path] error:NULL];
self.audioPlayer = theAudio;
[theAudio release];
[theAudio play];
}
With the same Button i would like to stop and play the sound.
Maybe i am searching for the wrong thing, but i can´t find the proper information on the web.
It would be really helpful if someone could give me a LINK to a tutorial or something like this.
thanks in advance
Planky
Create the AVAudioPlayer player object on loadView or somewhere.
- (void)loadView {
// Some code here
NSString *path = [[NSBundle mainBundle] pathForResource:#"Vorwort" ofType:#"mp3"];
AVAudioPlayer* theAudio = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
self.audioPlayer = theAudio;
[theAudio release];
// Some code here
}
Then inside the button's action(change the action name to toggleAudio as others suggested), you can get the property isPlaying to see whether audio is playing or not, and do the respective actions.
- (void)toggleAudio { // original name is playAudio
if ([self.audioPlayer isPlaying]) {
[self.audioPlayer pause];
// Or, [self.audioPlayer stop];
} else {
[self.audioPlayer play];
}
}

iOS - How to stop background music when changing views

How to stop background music when changing views? I have no clue. If i press a button which takes me to a new view, there is new background music. But the old background music (which goes in an infinite loop) keeps on going. Please help! also sample some code please, here is mine:
- (void)viewDidLoad {
NSString *path = [[NSBundle mainBundle] pathForResource:#"MathMusic2" ofType:#"wav"];
AVAudioPlayer* theAudio= [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
theAudio.delegate = self;
[theAudio play];
theAudio.numberOfLoops = -1;
[super viewDidLoad];
}
I just need to know how to make the background music from the new view stop playing. And vice versa when i press the back button from the new view
Create a property for the AVAudioPlayer *theAudio so you can access the audioPlayer from any point in your class.
Header file of viewController
...
AVAudioPlayer *theAudio;
...
#property (nonatomic, retain) AVAudioPlayer *theAudio;
Implentation file of viewController
...
#synthesize theAudio;
...
- (void)viewDidLoad {
NSString *path = [[NSBundle mainBundle] pathForResource:#"MathMusic2" ofType:#"wav"];
self.theAudio= [[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL]] autorelease];
theAudio.delegate = self;
[theAudio play];
theAudio.numberOfLoops = -1;
[super viewDidLoad];
}
If viewWillDisappear is called you can then just stop the audio with
- (void)viewWillDisappear
{
[theAudio stop];
}
it gaves errors in here :
"theAudio.delegate = self;" as something like assigning to id...
its yellow anyway..
still when i change view and go to another class music not stoping....

code to play sound programmatically using a button on the iphone

I am trying to figure out how to hook up a button to play a sound programmatically without using IB. I have the code to play the sound, but have no way of hooking the button up to play the sound? any help?
here is my code that I'm using:
- (void)playSound
{
NSString *path = [[NSBundle mainBundle] pathForResource:#"boing_1" ofType:#"wav"];
AVAudioPlayer* myAudio = [[AVAudioPlayer alloc]
initWithContentsOfURL:[NSURL fileURLWithPath:path error:NULL]];
myAudio.delegate = self;
myAudio.volume = 2.0;
myAudio.numberOfLoops = 1;
[myAudio play];
}
[button addTarget:self action:#selector(playSound) forControlEvents:UIControlEventTouchUpInside];
UIButton inherits its target/action methods from UIControl.
To hook up the button, make your playSound method the handler for the button's UIControlEventTouchUpInside event. Assuming this is in a view controller, you might want to put this in the viewDidLoad method:
[button addTarget:self action:#selector(playSound) forControlEvents:UIControlEventTouchUpInside];
FYI, you're leaking memory because you're alloc-ing an object but never release-ing it.
You should create a new AVAudioPlayer member for the class to avoid this.
#interface MyViewController : ...
{
...
AVAudioPlayer* myAudio;
...
}
- (void)playSound
{
NSString *path = [[NSBundle mainBundle] pathForResource:#"boing_1" ofType:#"wav"];
[myAudio release];
myAudio = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path error:NULL]];
myAudio.delegate = self;
myAudio.volume = 2.0;
myAudio.numberOfLoops = 1;
[myAudio play];
}
Don't forget to put [myAudio release] in your dealloc method.
(I did this without declaring myAudio as a #property, but that's not strictly necessary)