Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Correctly Destroy ToneUnit after Tone Fades Out?

I'm generating tones on iPhone using AudioUnits based on Matt Gallagher's classic example. In order to avoid the chirps and clicks at the beginning/end, I'm fading the amplitude in/out in the RenderTone callback. I'd like to destroy the ToneUnit at the end of the fade out, that is, after the amplitude reaches zero. The only way I can think to do this is to call an instance method from within the callback:

    if (PlayerState == FADING_OUT) {
        amplitude -= stepsize;
        if (amplitude <= 0) {
            amplitude = 0;
            PlayerState = OFF;
            [viewController destroyToneUnit];
        }
    }

Unfortunately this is more challenging that I had thought. For one thing, I still get the click at the end that the fadeout was supposed to eliminate. For another, I get this log notice:

<AURemoteIO::IOThread> Someone is deleting an AudioConverter while it is in use.

What does this message mean and why am I getting it?

How should I kill the ToneUnit? I suspect that the click occurs because RenderTone and destroyToneUnit run on different threads. How can I get these synchronized?


In case it's helpful, here's my destroyToneUnit instance method:

- (void) destroyToneUnit {
    AudioOutputUnitStop(toneUnit);
    AudioUnitUninitialize(toneUnit);
    AudioComponentInstanceDispose(toneUnit);
    toneUnit = nil;
}

If I NSLog messages right before and right after AudioUnitUninitialize(toneUnit);, the notice appears between them.

like image 394
JohnK Avatar asked May 01 '13 21:05

JohnK


1 Answers

I also ran into the same issue. When I called the destroyToneUnit from the main thread, the warning went away.

[viewController performSelectorOnMainThread:@selector(destroyToneUnit) withObject:nil waitUntilDone:NO];
like image 64
ssk Avatar answered Sep 28 '22 02:09

ssk