Extract meter levels from audio file

前端 未结 2 649
醉梦人生
醉梦人生 2021-01-31 19:22

I need to extract audio meter levels from a file so I can render the levels before playing the audio. I know AVAudioPlayer can get this information while playing th

2条回答
  •  终归单人心
    2021-01-31 20:11

    First of all, this is heavy operation, so it will take some OS time and resources to accomplish this. In below example I will use standard frame rates and sampling, but you should really sample far far less if you for example only want to display bars as an indications

    OK so you don't need to play sound to analyze it. So in this i will not use AVAudioPlayer at all I assume that I will take track as URL:

        let path = Bundle.main.path(forResource: "example3.mp3", ofType:nil)!
        let url = URL(fileURLWithPath: path)
    

    Then I will use AVAudioFile to get track information into AVAudioPCMBuffer. Whenever you have it in buffer you have all information regarding your track:

    func buffer(url: URL) {
        do {
            let track = try AVAudioFile(forReading: url)
            let format = AVAudioFormat(commonFormat:.pcmFormatFloat32, sampleRate:track.fileFormat.sampleRate, channels: track.fileFormat.channelCount,  interleaved: false)
            let buffer = AVAudioPCMBuffer(pcmFormat: format!, frameCapacity: UInt32(track.length))!
            try track.read(into : buffer, frameCount:UInt32(track.length))
            self.analyze(buffer: buffer)
        } catch {
            print(error)
        }
    }
    

    As you may notice there is analyze method for it. You should have close to floatChannelData variable in your buffer. It's a plain data so you'll need to parse it. I will post a method and below explain this:

    func analyze(buffer: AVAudioPCMBuffer) {
        let channelCount = Int(buffer.format.channelCount)
        let frameLength = Int(buffer.frameLength)
        var result = Array(repeating: [Float](repeatElement(0, count: frameLength)), count: channelCount)
        for channel in 0..

    There are some calculations (heavy one) involved in it. When I was working on similar solutions couple of moths ago I came across this tutorial: https://www.raywenderlich.com/5154-avaudioengine-tutorial-for-ios-getting-started there is excelent explanation of this calculation there and also parts of the code that I pasted above and also use in my project, so I want to credit author here: Scott McAlister

提交回复
热议问题