Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AVAudioSession setActive error when deallocating AEAudioController #132

Closed
jeremywhuff opened this issue Feb 4, 2015 · 17 comments
Closed

Comments

@jeremywhuff
Copy link

This occurs when I need to change the sample rate that the audio controller is running at, so I stop and release the current audio controller, then create and start a new one at the new sample rate.

  1. Create a new AEAudioController
  2. Call start on the audio controller
  3. After it's been running for a bit, trigger an event to do the following steps sequentially
  4. Stop the audio controller
  5. Release the audio controller (for instance with ARC, _audioController = nil)
  6. Create a new AEAudioController
  7. Call start on the new audio controller

BUG: After running for a second or two, the error appears in the console:

"14:22:10.507 ERROR: [0x3bea99dc] AVAudioSession.mm:646: -[AVAudioSession setActive:withOptions:error:]: Deactivating an audio session that has running I/O. All I/O should be stopped or paused prior to deactivating the audio session."

This occurs due to the stop statement in the dealloc function. If I omit step 4, then the first audio controller never gets deallocated. So I fixed this by subclassing AEAudioController and adding the function:

  • (void) stop {
    if(self.running) [super stop];
    }
@andreasapptitude
Copy link

I have seen something very similar... When running two AEAudioControllers at the same time, then stopping one of them. It seems like TAAE is not geared for this kind of operation. It would make stuff easier for me, though, so I'll try to subclass AEAudioController, and have a stop method that can be explicitly told to leave the AudioSession alone. Sketchy, I know :)

@andreasapptitude
Copy link

For those interested... It worked like a charm. I didn't subclass, though - I just added a stopAndLeaveAudioSessionAlone method to the AEAudioController to check the idea out. In this method, I removed the if ( !_interrupted ) statement. Easy piecy, but a more elegant solution would be nice... Also, one that stays with me when I get the next TAAE ;)

@michaeltyson
Copy link
Collaborator

Definitely a bad idea to create two instances - that's a recipe for disaster, as TAAE is in no way designed for that. Just use one.

Sent from my iPhone

On 7 May 2015, at 3:20 am, andreasapptitude notifications@github.com wrote:

For those interested... It worked like a charm. I didn't subclass, though - I just added a stopAndLeaveAudioSessionAlone method to the AEAudioController to check the idea out. In this method, I removed the if ( !_interrupted ) statement. Easy piecy, but a more elegant solution would be nice... Also, one that stays with me when I get the next TAAE ;)


Reply to this email directly or view it on GitHub.

@jeremywhuff
Copy link
Author

Would it make sense to include the "if(self.running) [super stop]; " line in TAAE? It seems reasonable to allow shutting down AEAudioController and creating a new one with a new audio description.

@andreasapptitude
Copy link

@michaeltyson I agree completely! If TAAE was designed to be applied the way I do it, I wouldn't have to hack it like this - just piling up information and findings.

... How about warning people against allocating multiple instances - at runtime? There's nothing in the AEController doc, or the "getting started" guide as far as I can tl:dr...

@michaeltyson
Copy link
Collaborator

Good idea @andreasapptitude ; done in SHA ff4bf8d

@michaeltyson
Copy link
Collaborator

The new updateWithAudioDescription... method should take care of this for now, I think.

@andreasapptitude
Copy link

Terrific - only, now I have to rewrite stuff in my project ;)

Funny how you use two '_'s to denote a static variable. I do the same, is it actually a "standard"?

@michaeltyson
Copy link
Collaborator

Interesting! I have no idea when I started doing that...

@warpling
Copy link

Would it be worth adding a semaphore that blocks initialization until dealloc completes?

I'm running into a rare bug where a lazily loaded view that creates a TAAE instance can be presented/dismissed/presented in quick succession and cause a second TAAE instance to be instantiated before the old one has finished deallocing (resulting in the new NSAssert added in ff4bf8d to trigger).

I know I should probably share one instance across the app, but I've been paranoid of other audio libraries clobbering TAAE if I leave a shared instance around so I re-create it before each use to be sure.

@michaeltyson
Copy link
Collaborator

Probably not; better to wait in dealloc I'd say

@warpling
Copy link

I'm not sure what you mean. Dealloc gets called asynchronously when the system wants, no? So there's no way of externally knowing when exactly the previous instance has been dealloc'd?

@michaeltyson
Copy link
Collaborator

Oh, whoops, I had a different issue in mind. In this case, probably better to do something like maintain a static integer that increments on init, and decrements during dealloc, and only deactivate the audio session in dealloc when that integer == 0

@warpling
Copy link

warpling commented Aug 4, 2015

(Lost track of this one!) The issue is activating while a session is active I think, so I guess init should only init once the integer == 0. For now I'll look into storing one copy of TAAE in AppDelegate though?

@michaeltyson
Copy link
Collaborator

Yeah, that could probably do it. That won't help if there's external code using the audio session, though, of course. Ideally, AVAudioSession would be adapted to keep a 'user' count, rather than being on or off and having various audio stuff competing over that state. Not much we can do about that though =)

@manuiLeaf
Copy link

How to dealloc the AEAudioController instance?

@warpling
Copy link

@manuiLeaf with ARC you can't explicitly dealloc an AEAudioController instance, but by stopping it and removing all references to it, it should get dealloc'd

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants