|
| 1 | +// Copyright AudioKit. All Rights Reserved. Revision History at http://github.com/AudioKit/AudioKit/ |
| 2 | + |
| 3 | +import AVFAudio |
| 4 | +import CAudioKitEX |
| 5 | + |
| 6 | +/// A class to measure the proportion of buffer time |
| 7 | +/// audio unit is spending in its render block |
| 8 | +/// It can be used to measure CPU usage of the whole audio chain |
| 9 | +/// by attaching it to `AVAudioEngine.outputNode`, |
| 10 | +/// as well as any other audio unit. |
| 11 | +public class RenderMeasurer { |
| 12 | + private let renderMeasurer = akRenderMeasurerCreate() |
| 13 | + private let node: AUAudioUnit |
| 14 | + private let token: Int |
| 15 | + private let timebaseRatio: Double |
| 16 | + |
| 17 | + public init(node: AUAudioUnit) { |
| 18 | + self.node = node |
| 19 | + var timebase = mach_timebase_info_data_t(numer: 0, denom: 0) |
| 20 | + let status = mach_timebase_info(&timebase) |
| 21 | + assert(status == 0) |
| 22 | + timebaseRatio = Double(timebase.numer) / Double(timebase.denom) |
| 23 | + let observer = akRenderMeasurerCreateObserver(renderMeasurer) |
| 24 | + self.token = node.token(byAddingRenderObserver: observer!) |
| 25 | + } |
| 26 | + |
| 27 | + deinit { |
| 28 | + node.removeRenderObserver(token) |
| 29 | + } |
| 30 | + |
| 31 | + /// Returns the proportion of buffer time |
| 32 | + /// audio unit is spending in its render block |
| 33 | + /// This is usually number between 0 - 1, but |
| 34 | + /// it can be higher in case of dropouts |
| 35 | + public func usage() -> Double { |
| 36 | + let sampleRate = node.outputBusses[0].format.sampleRate |
| 37 | + let currentUsage = akRenderMeasurerGetUsage(renderMeasurer) |
| 38 | + return Double(currentUsage) * timebaseRatio * sampleRate / 1_000_000_000 |
| 39 | + } |
| 40 | +} |
0 commit comments