Xcode pre-load many audio files into one AVAudioPLayer? - ios

I managed to load an audio file onto a player and play it via the following method:
- (void) play:(NSString*)loop{
NSString* resourcePath = [[NSBundle mainBundle] pathForResource:loop
ofType:#"mp3"];
player = [[AVAudioPlayer alloc] initWithContentsOfURL:
[NSURL fileURLWithPath:resourcePath]];
player.delegate = self;
[player play];
player.numberOfLoops = 1;
player.currentTime = 0;
player.volume = 1.0;
}
}
(I removed a couple of lines in this post but the method itself works great)
The problem here is, that the sound only gets loaded when the method play() is being called which results in a little delay in between the button click that calls the method and the player actually playing it.
I have about 200 sounds in my app and one way would be to load each sound in its own AVAudioPLayer in the viewDidLoad, but I doubt that this is considered good code.
On Android, I am using the SoundPool for this concern and it works great but I don't think there is an equivalent for this on iOS.

I now managed to do it via AudioServicesPlaySystemSound()
I use a method that loads all the sounds in a giant array
- (void)prepSounds{
NSString *soundPath =
[[NSBundle mainBundle] pathForResource:#"bl3"
ofType:#"mp3"];
NSURL *soundPathURL = [NSURL fileURLWithPath:soundPath];
AudioServicesCreateSystemSoundID(
(__bridge CFURLRef)soundPathURL, &soundID[0]);
AudioServicesPlaySystemSound(soundID[0]);
}
where soundID[] is an array of SystemSoundID declared in the header.
Now, I can just easily fire the sound via AudioServicesPlaySystemSound(soundID[0]) where 0 relates to the first sound I loaded. The latency is close to 0 (I would guess 5ms)
However, this only works for sounds no longer than about 30 seconds.
If you need any assistance with that, just comment here, I'm glad to help.

Related

Simply Playing A Sound in iOS

I'm trying to play a sound when a button is clicked. First, I imported the AudioToolbox in the header file, then added the code into the IBAction that fires when the button is pressed, like so:
- (void)viewDidLoad {
[super viewDidLoad];
}
- (IBAction)button1:(id)sender {
NSString *soundPath = [[NSBundle mainBundle] pathForResource:#"mySong" ofType:#"wav"];
SystemSoundID soundID;
AudioServicesCreateSystemSoundID((__bridge CFURLRef)[NSURL fileURLWithPath:soundPath], &soundID);
AudioServicesPlaySystemSound (soundID);
}
I even threw an NSLog in the method to make sure it's firing. It is. I also but in a foo path in the string to see if it would crash, it did. I made sure that I dragged and dropped the short sound file into the app as well. Tested my speakers, tested audio on the device simulator by going to youtube on the simulator, everything. I can't figure out what I'm doing wrong.
When I changed the code to this:
- (IBAction)button1:(id)sender {
AVAudioPlayer *testAudioPlayer;
// *** Implementation... ***
// Load the audio data
NSString *soundFilePath = [[NSBundle mainBundle] pathForResource:#"3" ofType:#"wav"];
NSData *sampleData = [[NSData alloc] initWithContentsOfFile:soundFilePath];
NSError *audioError = nil;
// Set up the audio player
testAudioPlayer = [[AVAudioPlayer alloc] initWithData:sampleData error:&audioError];
if(audioError != nil) {
NSLog(#"An audio error occurred: \"%#\"", audioError);
}
else {
[testAudioPlayer setNumberOfLoops: -1];
[testAudioPlayer play];
}}
I get the error: WARNING: 137: Error '!dat' trying to set the (null) audio devices' sample rate
Hi as per you question can you please check whether you audio file is present in you project folder.It might happen that u have forgotten to checkmark "copy item if needed" so it might not be there in your project file.
You can also play sounds provided in device. Visit the below link it will be helpful.
https://github.com/TUNER88/iOSSystemSoundsLibrary
I've tested your code and it working fine and not getting crashed. Here's what I did.
As said in #matt's comment, sound playback fails in the Simulator. I had this problem when trying to play back a video.
The funny part is that sound plays just fine for the same video inside the Photos app.

Audio wont play in objective c

I have the following code that used to work to play a sound in my project however after iv done some playing around over the past few weeks on other aspects of the project it dose not seem to play.
The audio file is in the main directory and works in preview.
Any ideas?
//playsound
AVAudioPlayer *showsound;
NSString *audiopath = [[NSBundle mainBundle] pathForResource:#"mouse1" ofType:#"wav"];
NSURL *audiourl = [NSURL fileURLWithPath:audiopath];
showsound = [[AVAudioPlayer alloc]initWithContentsOfURL:audiourl error:Nil];
[showsound play];
It's because after the line showsound play your method comes to an end and showsound (your AVAudioPlayer) is released. Hence there is nothing to do any playing any more. Solution: retain it! (For example, set an instance variable to hold on to it.)

How to manage UIButton click sound iOS

I am using the following code to get a sound on button click.And it works perfect. The problem is this sound is not getting reduced if i reduce the volume on the phone. I want to manage button click sound as per the volume button. I am not using input view.
SystemSoundID soundID;
NSString *soundPath = [[NSBundle mainBundle] pathForResource:#"sound1" ofType:#"mp3"];
NSURL *soundUrl = [NSURL fileURLWithPath:soundPath];
AudioServicesCreateSystemSoundID ((CFURLRef) CFBridgingRetain(soundUrl) , &soundID);
AudioServicesPlaySystemSound(soundID);
As Duncan C suggests, try AVAudioPlayer:
Import AVFoundation.framework.
Replace your code snippet with:
NSString *soundPath = [[NSBundle mainBundle] pathForResource:#"sound1" ofType:#"mp3"];
NSURL *soundUrl = [NSURL fileURLWithPath:soundPath];
AVAudioPlayer *player = [[AVAudioPlayer alloc] initWithContentsOfURL:soundUrl error:nil];
[player play];
What I do is to create an AVAudioPlayer for my button sound and play that. AVAudioPlayer honors the system volume.
I've created a separate IBAction method that plays the sound, and then I link my buttons to both actions. That way it's easy to turn the sound on and off simply by linking the action. If you always want sounds to play then you might want to put a call to a sound play method directly in your IBAction methods.
Check Click here that might help you.

AVAudioPlayer working fine in 5.0, issues in 4.0-4.3.5

I have an app which plays and controls music across different ViewControllers. To do this, I created two instances of AVAudioPLayer in the app delegate's DidFinishLaunchingMethod:
NSString *path = [[NSBundle mainBundle] pathForResource:#"minnie1" ofType:#"mp3"];
NSURL *path1 = [[NSURL alloc] initFileURLWithPath:path];
menuLoop =[[AVAudioPlayer alloc] initWithContentsOfURL:path1 error:NULL];
[menuLoop setDelegate:self];
menuLoop.numberOfLoops = -1;
[menuLoop play];
NSString *path2 = [[NSBundle mainBundle] pathForResource:#"minnie2" ofType:#"mp3"];
NSURL *path3 = [[NSURL alloc] initFileURLWithPath:path2];
gameLoop=[[AVAudioPlayer alloc] initWithContentsOfURL:path3 error:NULL];
gameLoop.numberOfLoops = -1;
[gameLoop setDelegate:self];
[gameLoop prepareToPlay];
After this I call it in various viewControllers, to stop or restart using code like:
- (IBAction)playGameLoop{
NSLog(#"Begin playGameLoop");
FPAppDelegate *app = (FPAppDelegate *)[[UIApplication sharedApplication] delegate];
if ([FPAVManager audioEnabled] == NO){
//DO NOTHING
}
else {
if (app.gameLoop.playing ==YES ) {
//DO NOTHING
}
else { [app.gameLoop play];
NSLog(#"End playGameLoop");
}
}
The audio files play fine the first time and they stop when asked to stop. Though, on iOS4 devices, they won't start replaying when called again.
Thanks!
From the docs:
Calling this method [stop] or allowing a sound to finish playing,
undoes the setup performed upon calling the play or prepareToPlay
methods.
The stop method does not reset the value of the currentTime property
to 0. In other words, if you call stop during playback and then call
play, playback resumes at the point where it left off.
Where you are looping the sounds, I would expect to be able to call stop and then call play. But I have fuzzy recollection of running into this myself. I found that calling pause, rather than stop, was a better solution. Especially since I could then call play again to resume play. Calling stop always seemed to require calling prepareToPlay again before calling play, at least in my experience.
It's possible that there were some changes in the API implemetation between iOS4.x and iOS5, too. You should check the API diffs on the Developer web site to be sure.

How to make a single button loop through multiple sound files, one at a time, in xcode?

First of all, I am a super xcode and objective-C noob. I have taken 2 college level Java classes, so I have an idea of what I want to do, I just can't accomplish it in xcode!
What I need to make happen is this: Push button1, play sound1. Push button1, play sound2. Push button1, play sound3. Push button1, play sound1. Et cetera.
What I am thinking is making a counter by saying
i=0
play sound
i++
then once i=4, make i=0 again and so on.
My sound player looks like this:
- (void) playSound:(NSString*) filename {
NSURL *url = [NSURL fileURLWithPath: [NSString stringWithFormat: filename, [[NSBundle mainBundle] resourcePath]]];
NSError *error;
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error: &error];
audioPlayer.numberOfLoops = 0;
[audioPlayer play];
}
Any idea will be greatly appreciated! Don't be afraid to make it extremely simple, like I said I am really unexperienced
whenever you are calling playsound method.. you are passing a filename.
so before calling the method update i(or any variable you have as count) .
and then make a switch statements and call the appropriate filename for the variable value....OR you can name the files like filename1,filename2,filename3 and just pass the the filename with i in the method and skip the switch.

Resources