Create Audio Wave pragmatically according to sound frequency iOS swift


I have been working in AVAudioPlayer and I would like to draw a waveform which looks look like the first gif. I am using below code to draw waves. but I m confused how to draw same waves and waves moving with same frequency.

Here is what I am trying to do:

Gif1

The screen recording is taken from iPhone.

Gif2

Code:-

`import UIKit
import AVFoundation

class FourthViewController: UIViewController {

let audioSession = AVAudioSession.sharedInstance()
var audioEngine: AVAudioEngine!
var audioPlayer: AVPlayer!
var displayLink: CADisplayLink?

var audioBuffer = [Float]()
var visualizerView: UIView!

override func viewDidLoad() {
    super.viewDidLoad()

    setupAudioSession()
    setupAudioEngine()
    setupVisualizer()
    setupAudioPlayer()
}

func setupAudioSession() {
    do {
        try audioSession.setCategory(.playback, mode: .default)
        try audioSession.setActive(true)
    } catch {
        print("Audio session setup error: \(error.localizedDescription)")
    }
}

private func configureAudioSession() {
    do {
        try AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.playAndRecord, options: .mixWithOthers)
        try AVAudioSession.sharedInstance().setActive(true)
    } catch { }
}

func setupAudioEngine() {
    configureAudioSession()
    audioEngine = AVAudioEngine()
    let inputNode = audioEngine.inputNode

    let outputFormat = inputNode.inputFormat(forBus: 0)

    inputNode.installTap(onBus: 0, bufferSize: 1024, format: outputFormat) { buffer, _ in
        let bufferPointer = buffer.floatChannelData?[0]
        let bufferLength = Int(buffer.frameLength)

        self.audioBuffer = Array(UnsafeBufferPointer(start: bufferPointer, count: bufferLength))
    }

    do {
        try audioEngine.start()
    } catch {
        print("Audio engine start error: \(error.localizedDescription)")
    }
}

func setupVisualizer() {
    visualizerView = UIView(frame: CGRect(x: 0, y: 200, width: self.view.frame.width, height: 200))
    visualizerView.backgroundColor = UIColor.lightGray
    view.addSubview(visualizerView)
}

func setupAudioPlayer() {
    guard let audioURL = Bundle.main.url(forResource: "Song5", withExtension: "mp3") else {
        fatalError("Audio file not found")
    }

    audioPlayer = AVPlayer(url: audioURL)
    audioPlayer.play()

    displayLink = CADisplayLink(target: self, selector: #selector(updateVisualizer))
    displayLink?.add(to: .current, forMode: .common)
}

@objc func updateVisualizer() {
    guard let playerItem = audioPlayer.currentItem else { return }

    let currentTime = CMTimeGetSeconds(playerItem.currentTime())
    let duration = CMTimeGetSeconds(playerItem.duration)

    if currentTime >= duration {
        displayLink?.invalidate()
        return
    }

    let width = visualizerView.bounds.width
    let height = visualizerView.bounds.height
    let yOffset = height / 2
    let sampleWidth = width / CGFloat(audioBuffer.count)

    let path = UIBezierPath()

    for (index, sample) in audioBuffer.enumerated() {
        let x = CGFloat(index) * sampleWidth
        let y = yOffset - CGFloat(sample) * yOffset

        if index == 0 {
            path.move(to: CGPoint(x: x, y: y))
        } else {
            path.addLine(to: CGPoint(x: x, y: y))
        }
    }

    let waveformLayer = CAShapeLayer()
    waveformLayer.path = path.cgPath
    waveformLayer.strokeColor = UIColor.blue.cgColor
    waveformLayer.lineWidth = 5.0
    waveformLayer.fillColor = UIColor.clear.cgColor

    // Clear the previous drawings
    visualizerView.layer.sublayers?.forEach { $0.removeFromSuperlayer() }

    // Add the updated waveform
    visualizerView.layer.addSublayer(waveformLayer)
    }
}`

Question: How to show the same waves according to song frequency(first gif)?

Can someone please explain to me how to draw same, I’ve tried to draw these waves but no results yet.

Any help would be greatly appreciated.

Thanks in advance.

Latest articles

spot_imgspot_img

Related articles

Leave a reply

Please enter your comment!
Please enter your name here

spot_imgspot_img