How to use NSOperation and NSOperationQueue - iphone

I made an app which plays the song on clicking on the image of artist.(see image attached). Each artist image is implemented on button and on clicking this button, a function is being called which first downloads and then plays the song. I passed this method(function) in a thread but problem is that every time when I click on the image of artist(button) new threads starts running and then multiple songs gets started playing concurrently. How can I use "NSOperation and NSOperationQueue" so that only one song will run at a time . Please help.
Thanks in advance

NSOperation and NSOperationQueue aren't going to directly solve your problem.
If I were pursuing a dead simple approach, I would have a global AudioPlayer object that has a method startPlaying: whose argument is the song to play (represented however needed; URL, NSData, whatever you need).
In that method, I'd stop playing whatever is currently playing and start the new track.
If I remember correctly, I don't think you even need a thread for this; the audio APIs are generally quite adept at taking care of playback in the background.
In any case, if you do need a thread, then I'd hide that thread in my AudioPlayer object and let it take care of telling the music to stop/start playing in said thread. A queue of some kind -- operation or GCD -- could be used for that, yes.

Related

How to get notified when AVAudioPlayer loops back to the beginning?

I'm playing a sound file in a loop and need to restart an animation with it every time the loop starts from the beginning.
I couldn't find a delegate method for it in the documentation. Is there a way to get notified when the player loops around to the beginning?
My approach was to use a timer which checks current play time every few milliseconds but this sounds like a horrible solution.
No, AFAIK your solution is the only one which works. The finishedPlaying method is not called whilst looping so sampling the position is the only technique.
I'm updating some inherited code to add looping and came to this conclusion under iOS8.
You can set up a delegate for the avaudioplayer instance. Then the delegate will be notified whenever the sound has successfully finished playing. Then you can probably restart the player to play again and restart your animation. Just off the top of my head. Look here for more information.

Iphone sdk - How to play a sound during a phone call after some elapsed time?

Well I am having two issues that i can't get to work, related to audio and calls.
The first one is to play a sound during a phone call. I don't want to play continuous music or stream anything, it is just a simple and short sound that the user will hear at one time during his call.
I have read some posts claiming that this is possible, and I even have an application that does so, but I can't get it to work. My app identifies the call using CTCallCenter and print the logs but never plays the sound or plays it after the app comes to foreground again. I have the .plist property of required background mode App plays audio.
The second issue, is to play the sound after some elapsed time. NSTimers doesn't work when on background mode, nor NSThread sleep on my background process or NSOperation. So how could I play this sound after say 10 seconds of the call?
Also, this behavior has to work also when the application is already on background mode. With CTCallCenter I am only getting the event when the application is interrupted from use, but I don't see any logs when i send the app to background and then begin/receive a call
.
If anyone could point me to the right direction I'll be really grateful.
I havent done this, but NSLocalNotifcation, schedule a notification to play when you app get the call to move into the background. I would expect this to work. Interested to find out if it does.

Playing multiple sounds simultaneously with AVAudioPlayer

Could someone help me with a function that fires multiple AVAudioPlayers at the same time? Right now I am trying to get a total of twelve AVAudioPlayers to fire at once if twelve buttons are activated, but there is a delay and it sounds like someone is running their finger down a piano instead of hitting all the keys at once.
I've looked at Audio Queue Services and can't understand how to actually implement that into code, but it says it can play synchronized sounds. I'm not sure sure how to set all of it up. I'm trying to remake a Tone Grid app.
Why don't you use http://www.hollance.com/2011/02/soundbankplayer-using-openal-to-play-musical-instruments-in-your-ios-app/
There you have a polyphonic player, beautifully coded and ready to rock!
I used it in my first app a while back: http://itunes.apple.com/gb/app/chordwheel-pro/id406836326?mt=8
Are you calling the method prepareToPlay on all 12 AVAudioPlayer instances. From the docs: "Calling this method, preloads the buffers and acquires hardware, to minimize delay."
See the AVAudioPlayer class reference.

AVAudioPlayer lag when calling play

I have set up an AVAudioPlayer object in viewDidLoad, as per the Apple guidelines, calling prepareToPlay as the last line in viewDidLoad (i have tried in awakeFromNib also).
When i press my play button, there is a pause, as it would appear to load the file, then it plays.
In audioPlayerDidFinishPlaying, i reload the player with a different sound, and when clicking play for a second time, the file plays instantly.
What would cause the player to lag on the first play?
Thanks.
The delay is due to AVAudioPlayer being initialised. Please see this answer.
The audio system runs on several asynchronous software processes (audio units, OS drivers, etc.) and hardware systems (DMA, DACs, audio amp power supplies, etc.) that never really all completely finish initialization until some sound is actually played all the way out the speakers or earphones.
Here's one method to do that: Create a sound file containing a half second of silence. On app start up, while your app and view controller are still loading, use AVAudioPlayer to play this file of silence. Now when your view finishes loading, AVAudioPlayer should be ready to play subsequent non-silent sounds much faster, since some audio (silence) has already already gone all the way out to the speakers.
What kind of sound are you playing? Alerts, something longer? If alerts, I did go this way and it's much better with lags ...
create system sound with AudioServicesCreateSystemSoundID
play system sound with AudioServicesPlaySystemSound
dispose system sound with AudioServicesDisposeSystemSoundID
... you only need to store SystemSoundID for each sound you would like to play.

Multitasking: Stop Background Audio at Specific Time

I am developing an iphone app which uses background audio (on an infinite loop) to continue playing after the app has entered the background.
My problem is I want to implement a "sleep timer" which stops playback after a specified period of time.
Is this possible? I have spent an hour looking for a method to do this with no avail.
EDIT: My current thought is to use a lower level API, the Audio Queue Services, and manually re-fill the queue with another instance of the loop during the AudioQueueOutputCallback. If the timer has expired I do not fill the loop. I'm assuming this should work since the documentation says audio callbacks are still fired when an app is playing multitasking background audio. Can anyone think of a better way or a reason why this wouldn't work?
While you queue sound data on the background your app remains fully functional and running as if it was in the foreground (well almost), so yes, you should just write a timer that stops the playback at a given time and it will be fired as expected.
Now to the second question: once you stop queueing things up, your app will be "frozen" until the user manually brings it to the foreground... So what you should do is start queueing audio data from the second file before the first one is done playing, and if you DO need to pause or stop, maybe a solution is to play 0 bytes (silence)?
I'm not actually sure this would be allowed in the App Store. An app is not allowed to execute at all in the background, with the exception of VoIP apps and push notifications.