How to ovelap a sound with its self? - iphone

I am new to sounds in Xcode and I wish to play a sound repeatedly, whether it is playing already or not. Eg. I have three lasers which are being shot, and I wish for the laser sound to be played three times simultaneously, without waiting for each one to finish playing. How do I achieve this using AVAudioPlayer?

Do this:
AVAudioPlayer *laserSound1 = .........
laserSound1.numberOfLoops = 2; //plays three times simultaneously
[laserSound1 play];
AVAudioPlayer *laserSound2 = .........
laserSound2.numberOfLoops = 2;//plays three times simultaneously
[laserSound2 play];
AVAudioPlayer *laserSound3 = .........
laserSound3.numberOfLoops = 2;//plays three times simultaneously
[laserSound3 play];

Related

Making a timer to very slightly delay several audio channels for iPhone app?

I have 5 audio channels being operated by five AVAudioPlayer objects, and I would like to add a very small delay to each of these channels, so that when I push a button, I get this:
Start sound 1 (which lasts 10 seconds)
Start sound 2 0.25 seconds after sound 1
Start sound 3 0.25 seconds after sound 2
Start sound 4 0.25 seconds after sound 3
Start sound 5 0.25 seconds after sound 3
I tired to do this just using sleep(0.25) between each calling of [AVAudioPlayerObeject play] like this:
[audioPlayer1 play];
sleep(delay);
[audioPlayer2 play];
sleep(delay);
[audioPlayer3 play];
sleep(delay);
[audioPlayer4 play];
sleep(delay);
[audioPlayer5 play];
...where delay is a float variable set to 0.25. However, this doesn't work, and I hear all 5 sounds at once. I tried experimenting with NSTimer, but I didn't really understand how to make a separate method for the delay, and then call the method with my code.
Can someone please help me revise my code to get the desired effect? Thanks!
Keep state with an integer that identifies which sound to start...
#property(assign, nonatomic) NSInteger startSound;
Schedule a timer...
self.startSound = 0;
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:0.25 target:self selector:#selector(timerFired:) userInfo:nil repeats:YES];
When the timer fires, start a new sound. Quit after you've started 5....
- (void)timerFired:(NSTimer *)timer {
if (self.startSound < 5) {
// assume you know how to play sound N, numbered 0..4
[self playSound:self.startSound++];
} else {
[timer invalidate];
}
}
You can make the timer interval and the max count of sounds variables in this class.

How to perform operations when playing sound in iPhone?

I play a MP3 in my iPhone app using AVAudioPlayer; i need to perform some operations at certain times (say 30th seconds, 1 minute); is there a way to invoke callback functions based on mp3 playing time?
I believe the best solution is to start an NSTimer as you start the AVAudioPlayer playing. You could set the timer to fire every half second or so. Then each time your timer fires, look at the currentTime property on your audio player.
In order to do something at certain intervals, I'd suggest you kept an instance variable for the playback time from last time your timer callback was called. Then if you had passed the critical point between last callback and this, do your action.
So, in pseudocode, the timer callback:
Get the currentTime of your AVAudioPlayer
Check to see if currentTime is greater than criticalPoint
If yes, check to see if lastCurrentTime is less than criticalPoint
If yes to that too, do your action.
Set lastCurrentTime to currentTime
If you're able to use AVPlayer instead of AVAudioPlayer, you can set boundary or periodic time observers:
// File URL or URL of a media library item
AVPlayer *player = [[AVPlayer alloc] initWithURL:url];
CMTime time = CMTimeMakeWithSeconds(30.0, 600);
NSArray *times = [NSArray arrayWithObject:[NSValue valueWithCMTime:time]];
id playerObserver = [player addBoundaryTimeObserverForTimes:times queue:NULL usingBlock:^{
NSLog(#"Playback time is 30 seconds");
}];
[player play];
// remove the observer when you're done with the player:
[player removeTimeObserver:playerObserver];
AVPlayer documentation:
http://developer.apple.com/library/ios/#documentation/AVFoundation/Reference/AVPlayer_Class/Reference/Reference.html
I found this link describing a property property which seems to indicate you can get the current playback time.
If the sound is playing, currentTime is the offset of the current
playback position, measured in seconds from the start of the sound. If
the sound is not playing, currentTime is the offset of where playing
starts upon calling the play method, measured in seconds from the
start of the sound.
By setting this property you can seek to a specific point in a sound
file or implement audio fast-forward and rewind functions.
To check the time and perform your action you can simply query it:
if (avAudioPlayerObject.currentTime == 30.0) //You may need a more broad check. Double may not be able to exactly represent 30.0s
{
//Do Something
}
with multithreading your goal is simple, just do like this :
1 : in your main thread create a variable for storing time passed
2 : create new thread like "checkthread" that check each 30-20 sec(as you need)
3 : if the time passed is what you want do the callback
Yes Sure you can ...it's tricky i hope it works for you but it works for me ..
1- you play your mp3 file.
2- [self performSelector:#selector(Operation:) withObject:Object afterDelay:30];
then the function
-(void)Operation:(id)sender;
called; so you fired function after 30 second of mp3 file .. you can make many of function based on time you want..
3- there is other solution using timers
[NSTimer scheduledTimerWithTimeInterval:0 target:self selector:#selector(CheckTime:) userInfo:nil repeats:YES];
it will fire function called Check Time
-(void)CheckTime:(id)sender{
if (avAudioPlayerObject.currentTime == 30.0)
{
//Do Something
//Fire and function call such
[self performSelector:#selector(Operation:) withObject:Object]
}
}
then you can change time interval you want and repeats is for you to control repeat this action every 5 seconds or not..
Hope that helpful..
Thanks
i think ,you want to play different sound-files after 30sec then use this code :
1) all sound-files put in Array and then retrieve from document directory
2)then try this:
-(IBAction)play_sound
{
BackgroundPlayer=[[AVAudioPlayer alloc]initWithContentsOfURL:[NSURL fileURLWithPath:[[NSBundle mainBundle]pathForResource:[Arr_tone_selected objectAtIndex:j]ofType:#"mp3"]]error:NULL];
BackgroundPlayer.delegate=self;
[BackgroundPlayer play];
}
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag
{
[BackgroundPlayer stop];
j++;
[self performSelector:#selector(play_sound) withObject:Object afterDelay:30];
}

How to control play section of MPMoviePlayerController

I'm making app using MPMoviePlayerController.
I want to make special function.
What I want to function is like this.
If I play movie, player will stop after few second (ex: 30sec).
If I click play button, player has to play from 30sec to next stop point.
For me to realize this function, I've used initialPlaybackTime and endPlaybackTime option of MPMoviePlayerContrller.
But, this function didn't work like my thought.
mplayer.initialPlaybackTime = 0;
mplayer.endPlaybackTime = 10;
[mplayer play];
....
[mplayer pause];
,,,
mplayer.initialPlaybackTime = 10;
mplayer.endPlaybackTime =30;
[mplayer play];
And, mplayer is played again from 0 to 10, not from 10 to 30.
This is a little late, but for anyone who comes upon this question, it appears that endplaybacktime and initialplayback time can only be set once for an initialized mpmovieplayercontroller. If you want to reset the values you'll have to destroy your mpmovieplayercontroller instance and create a new one.
This is very disappointing, could I be wrong? I would love it if I were.
Change your code to set the currentPlaybackTime before restarting the playback. Note, the order of initializing these properties does matter.
[...]
mplayer.initialPlaybackTime = 10.0;
mplayer.endPlaybackTime = 30.0;
mplayer.currentPlaybackTime = 10.0;
[mplayer play];

How can you play a sound of a specified duration using AVAudioPlayer on iOS?

I want to play a specified duration within a sound file on IOS. I found a method in AVAudioPlayer that seeks to the begining of the playing (playAtTime:) but i cannot find a direct way to specify an end time before the end of the sound file.
Is there is a way to achieve this?
If you don't need much precision and you want to stick with AVAudioPlayer, this is one option:
- (void)playAtTime:(NSTimeInterval)time withDuration:(NSTimeInterval)duration {
NSTimeInterval shortStartDelay = 0.01;
NSTimeInterval now = player.deviceCurrentTime;
[self.audioPlayer playAtTime:now + shortStartDelay];
self.stopTimer = [NSTimer scheduledTimerWithTimeInterval:shortStartDelay + duration
target:self
selector:#selector(stopPlaying:)
userInfo:nil
repeats:NO];
}
- (void)stopPlaying:(NSTimer *)theTimer {
[self.audioPlayer pause];
}
Bear in mind that stopTimer will fire on the thread's run loop, so there will be some variability in how long the audio plays, depending on what else the app is doing at the time. If you need a higher level of precision, consider using AVPlayer instead of AVAudioPlayer. AVPlayer plays AVPlayerItem objects, which let you specify a forwardPlaybackEndTime.

iPhone: AVAudioPlayer not always playing audio on device

I have 2 views in my app, that are identical, they just load in a different array of sound files to use with their respective AVAudioPlayer.
However, ON THE DEVICE ONLY, on my second view, the sound seems to only play once after initialization, then it doesn't play until I initialize the player again.
This is my play button code:
- (IBAction)play:(id)sender {
if (((int)buttonCount % 2) == 0) {
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
self.audioPlayer.currentTime = 0;
self.audioPlayer.volume = volumeSlider.value;
[self.audioPlayer play];
[playButton setTitle:#"Stop..." forState:UIControlStateNormal];
buttonCount++;
[self fadePickerAnimation:NO];
NSLog(#"Should play");
}
else {
[self initializeSoundAfterStop:YES];
NSLog(#"Shouldn't play");
}
NSLog(#"buttoncount %i",buttonCount);
NSLog(#"What is the playing state? %i", self.audioPlayer.playing);
}
and the function it calls under the else clause:
- (void)initializeSoundAfterStop:(BOOL)addToButtonCount {
//Initialize audioPlayer once completely stopped
[self.audioPlayer stop];
[self.audioPlayer prepareToPlay];
[playButton setTitle:#"Chime!" forState:UIControlStateNormal];
if (addToButtonCount == YES) {
buttonCount++;
}}
The NSLogs in the above code output this as I continuously press the play button:
Should play
buttoncount 1
What is the playing state? 1
Shouldn't play
buttoncount 2
What is the playing state? 0
Should play
buttoncount 3
What is the playing state? 0
Shouldn't play
buttoncount 4
What is the playing state? 0
Should play
buttoncount 5
What is the playing state? 0
Shouldn't play
buttoncount 6
What is the playing state? 0
So as you can see, it gets stuck in a non-playing mode for some reason.
This method is used in exactly the same fashion in my first view, and it works without any problem. And it all works fine on the simulator, just not on my iPhone 4. Cannot figure this out. The play method of audioPlayer gets called when I setup a breakpoint, so I dunno!
Thanks!
Couldn't find out why this was happening, however, I fixed it by simply adding in my AVAdioPlayer initializer function at the top of the play IBAction.
Might not be the most graceful solution, but it works.
Just beware of memory allocation if you decide to do this.