Search code examples
swiftcore-audio

I want to implement a volume level meter in CoreAudio using Swift


I have looked into using installTap in AVAudioNode, but how can I get the volume level in real time in installTap in?

player.installTap(onBus: 0, bufferSize: 1024, format: player.outputFormat(forBus: 0)) { (buffer, when) in
    print(buffer.floatChannelData![0])
}

floatChannelData is a pointer to data but how to access real value?


Solution

  • Use floatChannelData pointer by dereferencing it and then accessing the individual samples.

    player.installTap(onBus: 0, bufferSize: 1024, format: player.outputFormat(forBus: 0)) { (buffer, when) in
        let floatData = buffer.floatChannelData![0]
        let frameCount = Int(buffer.frameLength)
        
        // Calculate the RMS volume level
        var rms: Float = 0.0
        for i in 0..<frameCount {
            let sample = floatData[i]
            rms += sample * sample
        }
        rms = sqrt(rms / Float(frameCount))
        
        // Now, 'rms' contains the RMS volume level in real-time
        print(rms)
    }
    

    The code iterates, does the math to give RMS for small chunk of time. For smoother RMS over time, accumulate and do a moving average.