How do I cycle through several sounds using one action? - iphone

Right now I have a single sound playing from one action, button press, accelerometer, etc..
I would like to know how I can cycle through several sounds (I'm using 3 sounds for my project) from a single action that the user initiates.
I am currently using the code shown below and it serves it's purpose for playing a single sound for each user action. I have not used NSArray in a project before, so if your including it please include any details.
NSURL *url = [NSURL fileURLWithPath: [NSString stringWithFormat:#"%#/Jet.wav", [[NSBundle mainBundle] resourcePath]]];
NSError *error;
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
audioPlayer.numberOfLoops = 0;
if (audioPlayer == nil)
NSLog(#"%#", [error description]);
else
[audioPlayer play];

If you are only using 3 sounds then you can get away with just using a C array of NSString's but if you need a dynamic amount of sounds then you should change to using an NSArray
// .m
NSString *MySounds[3] = {
#"sound1.wav",
#"sound2.wav",
#"sound3.wav",
};
#implementation ...
Then in your method you need to add a little extra logic
- (void)playSound;
{
NSString *path = [NSString stringWithFormat:#"%#/%#", [[NSBundle mainBundle] resourcePath], [self nextSoundName]];
NSURL *url = [NSURL fileURLWithPath:path];
NSError *error;
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
audioPlayer.numberOfLoops = 0;
if (audioPlayer == nil) {
NSLog(#"%#", [error description]);
} else {
[audioPlayer play];
}
}
- (NSString *)nextSoundName;
{
static NSInteger currentIndex = -1;
if (++currentIndex > 2) {
currentIndex = 0;
}
return MySounds[currentIndex];
}

-(IBAction)playSound:(UIButton *)sender{
NSURL *url = [NSURL fileURLWithPath: [NSString stringWithFormat:#"%#/%#", [[NSBundle mainBundle] resourcePath], [MySounds objectAtIndex:[sender tag]]]];
NSError *error;
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
audioPlayer.numberOfLoops = 0;
if (audioPlayer == nil)
NSLog(#"%#", [error description]);
else
[audioPlayer play];
}
Here you can use single action buttons for all buttons. Just you need to do is set the tags to button. Use array as described by Paul

Related

Audio file not play from server

I am playing audio file from server but it is not playing if i play local file then it plays here is my code.
//NSURL *url = [NSURL fileURLWithPath:[NSString stringWithFormat:#"%#/audiofile.mp3", [[NSBundle mainBundle] resourcePath]]];
NSURL *url = [NSURL URLWithString:#"http://celeritas-solutions.com/pah_brd_v1/productivo/1.mp3"];
NSError *error;
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
audioPlayer.numberOfLoops = -1;
if (audioPlayer == nil)
NSLog([error description]);
else
[audioPlayer play];
Try to use MPMoviePlayerController instead of AVAudioPlayer
NSURL *url = [NSURL URLWithString:#"http://celeritas-solutions.com/pah_brd_v1/productivo/1.mp3"];
mv = [[MPMoviePlayerController alloc] initWithContentURL:url];
mv.movieSourceType = MPMovieSourceTypeUnknown;
[self.view addSubview:mv.view];
[mv play];
Use this code to solve your problem...
NSData *_objectData = [NSData dataWithContentsOfURL:[NSURL URLWithString:http://celeritas-solutions.com/pah_brd_v1/productivo/1.mp3]];
NSError *error;
audioPlayer = [[AVAudioPlayer alloc] initWithData:_objectData error:&error];
audioPlayer.numberOfLoops = 0;
audioPlayer.volume = 1.0f;
[audioPlayer prepareToPlay];
if (audioPlayer == nil)
NSLog([error description]);
else
[audioPlayer play];

mixing of five songs in iphone sdk

In my app I have five buttons and every button have five songs. In the main view there is a star (contains five ends) in the view. When the user drags the button to the end of the star it should play the song. Link this same has four and we want to mix those songs into a file like a ringtone saved it in to a tmp directory. I had tried a lot for this but I'm unable to get an answer to the problem.
The code I'm using is:
- (void) doAudioCallback: (NSTimer *)timer {
NSString *resName1 = #"drum1.aif";
NSString *resName2 = #"drum2.aif";
NSString *resPath1 = [[NSBundle mainBundle] pathForResource:resName1 ofType:nil];
NSString *resPath2 = [[NSBundle mainBundle] pathForResource:resName2 ofType:nil];
NSString *tmpDir = NSTemporaryDirectory();
NSString *tmpFilename = #"MixedoftwoSongs.aif";
NSString *tmpPath = [tmpDir stringByAppendingPathComponent:tmpFilename];
OSStatus status;
if (status == OSSTATUS_MIX_WOULD_CLIP) {
} else {
NSURL *url = [NSURL fileURLWithPath:tmpPath];
NSData *urlData = [NSData dataWithContentsOfURL:url];
NSLog(#"wrote mix file of size %d : %#", [urlData length], tmpPath);
AVAudioPlayer *avAudioObj = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
self.avAudio = avAudioObj;
[avAudioObj prepareToPlay];
[avAudioObj play];
}
}
I think you have to use Perform Selector to delay your each audio
[self performSelector:#selector(yourmethod) withObject:nil afterDelay:0.5];

using slider change the volume in AVAudioPlayer in iphone sdk

I am using this code
NSURL *url = [NSURL fileURLWithPath:[NSString stringWithFormat:#"%#/audiofile.mp3", [[NSBundle mainBundle] resourcePath]]];
NSError *error;
player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
player.numberOfLoops = -1;
if (player == nil)
NSLog(#"%#",[error description]);
else
[player play];
but i want to change the volume so how can i get the volume detail?
Set up your UISlider. Register it to receive the ValueChanged events in IB or programmatically. Set its min value to 0 and max to 100. And that should be it.
- (void)sliderValueChanged:(UISlider *)slider {
myPlayer.volume = slider.value / 100.0;
}

iOS 5.0 AVAudioPlayer Error loading audio clip: The operation couldn’t be completed. (OSStatus error -50.)

So I'm trying to test out the audio player on the iPhone, and I went off Troy Brant's iOS book. I have the Core Audio, Core Foundation, AudioToolbox, and AVFoundation frameworks added to my project. The error message I get is in the subject field. I read like 20 pages of Google search results before resorting to asking here! /sigh. Thanks if you can help. Here's my code, pretty much verbatim out of his book:
NSString *soundFilePath = [[NSBundle mainBundle] pathForResource:#"Yonah" ofType:#"caf"];
NSLog(#"%#", soundFilePath);
NSURL *fileURL = [NSURL URLWithString:soundFilePath];
NSError *error;
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:fileURL error:&error];
if (!error)
{
audioPlayer.delegate = self;
//audioPlayer.numberOfLoops = -1;
[audioPlayer play];
}
else
{
NSLog(#"Error loading audio clip: %#", [error localizedDescription]);
}
EDIT: Holy Shinto. I figured out what it was. I changed
NSURL *fileURL = [NSURL URLWithString:soundFilePath];
to
NSURL *fileURL = [NSURL fileURLWithPath:soundFilePath];
to the latter and I was getting a weird error, weirder than the one in the subject BUT I googled that and I changed my OS input device from my webcam to my internal microphone and guess what, it worked under the fileURLWithPath method. I'll be. Damned.
try this one- convert your url into NSdata
NSString* resourcePath = self.audioStr; //your url
NSData *_objectData = [NSData dataWithContentsOfURL:[NSURL URLWithString:resourcePath]];
NSError *error = [[NSError alloc] init];
NSLog(#"url is %#",resourcePath);
audioPlayer = [[AVAudioPlayer alloc] initWithData:_objectData error:&error];
audioPlayer.numberOfLoops = 0;
if (error)
{
NSLog(#"Error in audioPlayer: %#",
[error localizedDescription]);
} else {
audioPlayer.delegate = self;
[audioPlayer prepareToPlay];
}`
Try to read the audio file with something like this:
audioPlayer_ = [[AVAudioPlayer alloc] initWithContentsOfURL:
[NSURL fileURLWithPath:[NSString stringWithString:soundFilePath_]]
error:&error];

How to stop the sound - Cocoa Touch

I have a sound looped, its a rect button, once the user presses the button the sound loops and plays. I want it so once the user has pressed the same button again, the sound stops playing.
This is the code
- (IBAction)threeSound:(id)sender; {
NSString *path = [[NSBundle mainBundle] pathForResource:#"3" ofType:#"wav"];
if (threeAudio) [threeAudio release];
NSError *error = nil;
threeAudio = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:&error];
if (error)
NSLog(#"%#",[error localizedDescription]);
threeAudio.numberOfLoops = -1;
threeAudio.delegate = self;
[threeAudio play];
}
Thanks
Pretty straight forward...
- (IBAction)threeSound:(id)sender; {
if (threeAudio && threeAudio.playing) {
[threeAudio stop];
[threeAudio release];
threeAudio = nil;
return;
}
NSString *path = [[NSBundle mainBundle] pathForResource:#"3" ofType:#"wav"];
if (threeAudio) [threeAudio release];
NSError *error = nil;
threeAudio = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:&error];
if (error)
NSLog(#"%#",[error localizedDescription]);
threeAudio.numberOfLoops = -1;
threeAudio.delegate = self;
[threeAudio play];
}
You should separate those two processes
into this
`- (void)initSound {
NSString *path = [[NSBundle mainBundle] pathForResource:#"3" ofType:#"wav"];
NSError *error = nil;
threeAudio = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:&error];
if (error)
NSLog(#"%#",[error localizedDescription]);
threeAudio.numberOfLoops = -1;
threeAudio.delegate = self;
[threeAudio prepareToPlay];
[threeAudio play];
}
-(IBAction)threeSound:(id)sender:(UIButton *)sender{
if (sender.selected) {
[threeAudio pause];
} else {
threeAudio.currentTime = 0;
[threeAudio play];
}
sender.selected = !sender.selected;
}`
Note that initSound needs to be called at some point, if you want to start the sound with the button only.. then add
if (!threeAudio) {
[self initSound];
}
at the beggining of the IBAction
Thats my advice ;)