AVFoundation AVAudioPlayer stop is pausing - Objective-C - ios

It's fairly hard to show code for this as it is not noticeable in the code. I have some actions like -(IBAction)PlaySound1:(id)sender; and -(IBAction)PlaySound2:(id)sender; and audio files. I have the sounds working all fine. I also have -(void)Stop;. When Play sound 1 is pressed it calls the method Stop and stops sound 2. and the same with sound 2.
The problem I am encountering is when you play sound 1 and stop sound 2, when you play sound 2 it starts from where it left off.
Inside my (void) I have [PlaySound1 stop] //and [PlaySound2 stop]
If anyone could help that would be great. If something was unclear, just comment on this and I'll try and explain it better.
Thanks :)

Stopping an AVAudioPlayer does not reset the play head.
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.
To resume playback from the start set the currentTime property to 0.0 before calling play.
example -
playSound2.currentTime = 0.0;
[playSound2 play];

Related

How can I pause SCNAudioPlayer playback in ARKit?

I'm trying to implement a play/pause button for positional audio attached to a node in an ARKit scene. I want the user to be able to pause the audio, then resume it from the paused point at a later time. So removeAudioPlayer() is no good, as this resets the audio back to the start when it is reattached.
The only pause method associated with SCNAudioPlayers that I can find is buried deep down in:
myAudioPlayer.audioNode?.engine?.pause()
But this doesn't seem to have any effect. Strangely
myAudioPlayer.audioNode?.engine?.stop()
Does stop the audio from playing, but then you can't start it again afterwards!
My code for creating the audioPlayer is as follows:
audioSource = SCNAudioSource(fileNamed: "audio.caf")!
audioSource.loops = false
audioSource.isPositional = true
audioSource.shouldStream = false
audioSource.load()
// then a bit later...
audioPlayer = SCNAudioPlayer(source: audioSource)
myARNode.addAudioPlayer(audioPlayer)
Notice that no 'play' method is needed. The audio just starts playing as soon as you attach it to the node. And the lack of straight play() and pause() methods as top-level properties of SCNAudioPlayer makes me wonder if it's possible at all. This seems slightly crazy however, as it's a pretty rudimentary aspect of working with audio.
Does anyone know if this can be done?
Thanks in advance.
To stop audio engine use 2 sec delay. Pause doesn't work here (I'm using Xcode 12.2).
DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
player.audioNode?.engine?.stop()
}

Playing short sound with SystemSound or AVAudioPlayer on iOS

Creating custom spinner for iOS and for each rotation change need to play sound. Sound itself is 0.5 sec. According to Apple's documentation I used SystemSound to play it but now I can't control volume with hardware buttons cause audio context is Volume(media) and as I understood SystemSound works in different context, Ringer.
I tried to use AVAudioPlayer but there is a small delay when sound is attaching to the player and this glitches UI(small delay so spinner doesn't rotate smoothly).
Any ideas how this can be solved ?
I was thinking about somehow programmaticaly change this context by triggering controls that are working with systemSound, but no luck.
EDITED:
I've made sure that have only 1 instance of AVAudioPlayer and didn;t stop playing sound but paused it and only after spinner finished rotating then stop and dispose, but still same result

Audio Start Delay For The First Time - ios Swift

I am creating an application with five buttons. When I click on each button each audio will play. It is working. Now my problem is when I click first button audio play with 1 second delay(App stuck for 1 second) and play. Next time clicks a button audio play without any delay. What could be the issue here?
I am using the following code to play an audio
var currentAudio = try? AVAudioPlayer(contentsOfURL: NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("sample_audio", ofType: "mp3")!));
currentAudio!.stop()
currentAudio!.currentTime = 0
currentAudio!.play();
Please someone help me to finds this issue.
You could use AVAudioPlayer's .prepareToPlay() method to preload the player's buffers, it will increase AVAudioPlayer's performance (faster start).
The idea is to prepare the player some time before actually playing it:
currentAudio?.prepareToPlay()
then later, in your play function, it will start immediately:
currentAudio?.play()

iOS AVAudioPlayer play sound again

Hey I have a couple of AVAudioPlayers containing one sound each. If I press the same button a couple of times, it should repeat the sound from the beginning. If I press another button afterwards, the running sound shall be stopped in order to "make room" for the new one.
The code I am using for that:
-(void) plays:(int)p{ // p is the index of the sound being triggered
if([players[p] isPlaying])
{ // setting the time back to 0 makes
players[p].currentTime = 0.0; // the player automatically play again
}
else
{
[players[p] play]; // if not playing, start playing
}
if(last!=p)
{ // if the last sound is different from the current
[players[last] stop]; // stop the last one
players[last].currentTime = 0.0;} // put its position back to 0
last=p; // set the 'last' variable
}
However, hitting the same button again ends up in a little delay (maybe 20ms) in which no sound is heard. This is the time, the AVAudioPlayer seems to need to "rewind" the track in order to play it again. One Idea to get around this would be to create multiple objects of AVAudioPlayer for each sound but that'd make some awful code! Any ideas on how to make this process quicker?
Thanks, Alex
EDIT: playing 2 different sounds works perfectly fine, I can't hear any delay in between them as I prepareToPlay all the sounds beforehand.
I know how to eliminate the 20ms gap, but first consider if you want to.
Imagine if you jumped immediately from the mid-point of the sound file to the beginning with no gap at all. Better yet, download Audacity and hear how it sounds. Because of the discontinuity, you are going to get an unpleasant crackling or pop sound. Perhaps that 1 fiftieth of a second of silence actually sounds better than immediately restarting.
If you want an uninterrupted audio stream, you're going to have to put away the easy AVAudioPlayer interface and build an AUGraph. Of course, this means learning a complex audio interface and learning all about audio formats. And then you have to figure out what data you're going to stuff into your audio stream.
How would you make your loop sounds nice? You might try fading out at the touch point, and then fading back in. Or you could search for the zero crossings at the beginning and end of your loop (zero crossings are the place where the value of your sound wave is 0. They happen all the time in a mono output, but might be harder to find if your output is stereo.) In the end will this sound nicer than the 20 ms of silence? Get out Audacity and experiment with looping before you enter the long road of learning the AUGraph interace.
To the same song, how about stopping it, then prepareToPlay and play?

Playing sound effect just before AVAudioRecorder

I am recording audio with AVAudioRecorder. I want to however play a short sound before the recording starts. I am doing this with AudioServicesCreatSystemSoundId. I notice that I need to pause the thread after calling the sound effect or else it will start playing, then get interrupted by the AVAudioRecord record call and then finish playing after the recording has been stoped again.
So I have something like this:
AudioServicesCreateSystemSoundID((__bridge CFURLRef) pathURL, &audioEffect);
AudioServicesPlaySystemSound(audioEffect);
[NSThread sleepForTimeInterval:0.7];
[_audioRecorder record];
The problem is that one notices the delay. I know there are apps out there (like i.e. Voxer) that make the sound without delaying the actual recording. I tried splitting of the first two lines in a block, but that didn't help. How do they do it?
Thanks
For low latency (no noticeable start delay) audio recording, use a pre-started RemoteIO Audio Unit instead of the AVAudioRecorder API.

Resources