Performance optimization of waveform drawing

Viewed 1500

I'm building an app that draw the waveform of input audio data.

Here is a visual representation of how it looks:

It behaves in similar way to Apple's native VoiceMemos app. But it lacks the performance. Waveform itself is a UIScrollView subclass where I draw instances of CALayer to represent purple 'bars' and add them as a sublayers. At the beginning waveform is empty, when sound input starts I update waveform with this function:

class ScrollingWaveformPlot: UIScrollView {

  var offset: CGFloat = 0
  var normalColor: UIColor?
  var waveforms: [CALayer] = []
  var lastBarRect: CGRect?
  var kBarWidth: Int = 5

  func updateGraph(with value: Float) {

    //Create instance
    self.lastBarRect = CGRect(x: self.offset,
                              y:   self.frame.height / 2,
                              width: CGFloat(self.barWidth),
                              height: -(CGFloat)(value * 2))


    let barLayer = CALayer()
    barLayer.bounds = self.lastBarRect!
    barLayer.position = CGPoint(x: self.offset + CGFloat(self.barWidth) / 2,
                                y: self.frame.height / 2)
    barLayer.backgroundColor = self.normalColor?.cgColor

    self.layer.addSublayer(barLayer)
    self.waveforms.append(barLayer)

    self.offset += 7

  }

...

}

When last rect of purple bar reaches the middle of screen I begin to increase contentOffset.x of waveform to keep it running like Apple's VoiceMemos app.

The problem is: when bar count reaches ~500...1000 some noticeable lag of waveform begin to happen during setContentOffset.

self.inputAudioPlot.setContentOffset(CGPoint(x: CGFloat(self.offset) - CGFloat(self.view.frame.width / 2 - 7),y: 0), animated: false)

What can be optimized here? Any help appreciated.

2 Answers
Related