AudioKit: Trying to record audio from microphone to file but nothing being recorded

Viewed 966

I'm having a problem with recording audio from the microphone of my test device to a .caf file in Swift, XCode 9.4.1 using the latest version of AudioKit. In a simple test whereby I send the audio straight from the microphone to the output via an AKBooster, it works just fine and I can hear the mic input coming out of the speakers. I'm more or less following this example, although again using a booster node instead of an oscillator.

The following is my code:

class MicrophoneHandler
{
    var microphone : AKMicrophone!
    var booster : AKBooster!
    var mixer : AKMixer!
    var recorder : AKNodeRecorder!
    var file : AKAudioFile!
    var player : AKAudioPlayer!

    init()
    {   
        setupMicrophone()

        microphone = AKMicrophone()
        booster = AKBooster(microphone)                  // Stereo amplifier for microphone
        mixer = AKMixer(booster)
        file = try! AKAudioFile()                        // File to store recorder output

        player = try? AKAudioPlayer(file: file)          // Player to play back recorded audio file
        //player.looping = true

        recorder = try? AKNodeRecorder(node: mixer, file: file)

        try? recorder.record()
        sleep(5)
        let dur = String(format: "%0.3f seconds", recorder.recordedDuration)
        print("Stopped. (\(dur) recorded)")
        recorder.stop()

        //file.exportAsynchronously(name: "Test", baseDir: .documents, exportFormat: .caf){ [weak self] _, _ in
        //}

        //player.play()
        //AudioKit.output = player!

        //try? AudioKit.start()
    }

    func setupMicrophone()
    {
        // Function to initialise microphone settings
        // Adapted from AudioKit example code found here:
        // https://audiokit.io/examples/MicrophoneAnalysis

        AKSettings.bufferLength = .medium
        AKSettings.ioBufferDuration = 0.002 // TODO experiment with this to control latency

        do
        {
            try AKSettings.setSession(category: .playAndRecord, with: .allowBluetoothA2DP) // Set session type & allow streaming to Bluetooth devices
        } catch
        {
            AKLog("Could not set session category.")
        }

        AKSettings.defaultToSpeaker = true // Output to speaker when audio input is enabled
    }
}

I have commented out the export code as the problem doesn't appear to be here. The console displays the following:

AKMicrophone.swift:init():45:Mixer inputs 8
AKAudioPlayer.swift:updatePCMBuffer():533:AKAudioPlayer Warning:  "BF848EC0-94F8-4E39-A211-784B001CED72.caf" is an empty file
2018-11-16 17:49:16.936169+0000 VoxBox[2258:6984570] Audio files cannot be non-interleaved. Ignoring setting AVLinearPCMIsNonInterleaved YES.
AKNodeRecorder.swift:record():104:AKNodeRecorder: recording
Stopped. (0.000 seconds recorded)

As you can see, the recorder appears not to be recording to file for some reason. To my mind, my code should

  1. Initialise the microphone (including settings)
  2. Route the microphone input through a booster followed by a mixer (mixing with an FX bank will happen later)
  3. Create an empty .caf audio file to be written to
  4. Set up a player to play this file when the time comes
  5. Set up a recorder to record the output of the mixer node to the audio file
  6. Record 5 seconds of microphone input to the audio file

Yet for some reason nothing is being recorded. Clearly I am missing something or have misunderstood how the AKNodeRecorder works in this regard. I have read as many StackOverflow questions on similar topics as I can, had a dig through the AudioKit documentation and read a couple of examples from the AudioKit site, but nothing seems to address my particular problem.

Any help would be much appreciated.

0 Answers
Related