3

I've got an app with two features. One plays an AKMetronome and allows background playback when the app is not in the foreground. The other is a tuner feature which uses AKMicrophone, which only needs to be active when the app is in the foreground. These features can be used simultaneously (a blinking metronome light while the tuner is active).

When I press the home button, the metronome keeps playing (as expected). But the active microphone for the tuner also causes the bright red "recording"-style bar across the top of the device in all other apps. I don't need the tuner to function when the app isn't open though.

How do I disable the AKMicrophone node so that this bar doesn't show up, while also keeping the AKMetronome node playing uninterrupted?

I've tried the following, all with no success:

  • Calling AudioKit.stop() in the app delegate applicationWillResignActive() method. This gets rid of the recording bar, but stops the metronome.
  • Calling stop() on the AKMicrophone node during applicationWillResignActive(). This doesn't remove the recording bar.
  • Calling stop() and disconnectOutput() on the AKMicrophone node during applicationWillResignActive(). This doesn't remove the recording bar either.

I suspect that I may need to kill the entire engine (i.e. AudioKit.stop()), remove the microphone node from the chain, and rebuild and restart the engine, all within the applicationWillResignActive method. But that'll interrupt the tempo of the AKMetronome, so I'm hoping it doesn't come to that.

John Ellmore
  • 2,209
  • 1
  • 10
  • 22

1 Answers1

2

I think you should use AudioKit for the metronome, and use a part of AudioKit called the AKMicrophoneTracker for the tuner.

http://audiokit.io/docs/Classes/AKMicrophoneTracker.html https://github.com/AudioKit/AudioKit/blob/master/AudioKit/Common/Internals/Microphone%20Tracker/AKMicrophoneTracker.swift

AudioKit uses AVAudioEngine for its signal flow while the tracker is actually a completely separate signal flow based off of EZAudio. I believe the two can be used independently.

The way you're currently tracking the microphone probably resembles this: http://audiokit.io/playgrounds/Analysis/Tracking%20Microphone%20Input/

You'll want to make it more like this:

let tracker = AKMicrophoneTracker()
tracker.start()

//: User Interface
import AudioKitUI

class LiveView: AKLiveViewController {

    var trackedAmplitudeSlider: AKSlider?
    var trackedFrequencySlider: AKSlider?

    override func viewDidLoad() {

        AKPlaygroundLoop(every: 0.1) {
            self.trackedAmplitudeSlider?.value = tracker.amplitude
            self.trackedFrequencySlider?.value = tracker.frequency
        }

        addTitle("Tracking With Microphone Tracker")

        trackedAmplitudeSlider = AKSlider(property: "Tracked Amplitude", range: 0 ... 0.8) { _ in
            // Do nothing, just for display
        }
        addView(trackedAmplitudeSlider)

        trackedFrequencySlider = AKSlider(property: "Tracked Frequency",
                                          range: 0 ... 2_400,
                                          format: "%0.3f Hz"
        ) { _ in
            // Do nothing, just for display
        }
        addView(trackedFrequencySlider)

    }
}

HTH.

Aurelius Prochazka
  • 4,510
  • 2
  • 11
  • 34
  • 1
    This looks great! I'll try this in a little bit and see if it works. Thanks! – John Ellmore Nov 15 '17 at 15:06
  • Interesting--this works great in both the playgrounds and the iOS simulator, but I'm only getting `0.0` for frequency and amplitude when testing on an actual iOS device (iPhone 7+, iOS 11.1). But I'll go ahead and mark the answer correct, since that part of the question seems to be solved. I'll open an issue on Github for the bug as well. – John Ellmore Nov 16 '17 at 04:00