dmrschmidt / DSWaveformImage

Generate waveform images from audio files on iOS, macOS & visionOS in Swift. Native SwiftUI & UIKit views.
MIT License
1.04k stars 113 forks source link

WaveformLiveView is slower than example project #24

Closed drewg233 closed 2 years ago

drewg233 commented 2 years ago

Not sure if I am doing something wrong here, but my WaveformLiveView is much slower than the example projects. Mine is using all Swift and I followed what the sample project is doing.

https://user-images.githubusercontent.com/6364990/139720379-6dc3bd3f-a465-41af-a71c-01b37e3c4304.mov

https://user-images.githubusercontent.com/6364990/139720320-769e8c0d-2272-4ea7-b4ec-63bb21d3bf76.mov

import UIKit
import DSWaveformImage
import AVFoundation

class ViewController: UIViewController, AVAudioRecorderDelegate {

    @IBOutlet weak var recordButton: UIButton!
    @IBOutlet weak var waveformView: WaveformLiveView!

    var recordingSession: AVAudioSession!
    var audioRecorder: AVAudioRecorder!
    var timer: Timer?

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.

        waveformView.configuration = waveformView.configuration.with(
            style: .striped(.init(color: .red, width: 3, spacing: 3))
        )

        recordingSession = AVAudioSession.sharedInstance()

        do {
            try recordingSession.setCategory(.playAndRecord, mode: .default)
            try recordingSession.setActive(true)
            recordingSession.requestRecordPermission() { [unowned self] allowed in
                DispatchQueue.main.async {
                    if allowed {
                        createRecorder()
                        recordButton.isHidden = false
                    } else {
                        // failed to record!
                        recordButton.isHidden = true
                    }
                }
            }
        } catch {
            // failed to record!
        }
    }

    func createRecorder() {
        let audioFilename = getDocumentsDirectory().appendingPathComponent("recording.m4a")

        let settings = [
            AVFormatIDKey: Int(kAudioFormatMPEG4AAC),
            AVSampleRateKey: 44100,
            AVNumberOfChannelsKey: 1,
        ]

        do {
            audioRecorder = try AVAudioRecorder(url: audioFilename, settings: settings)
            audioRecorder.isMeteringEnabled = true
            audioRecorder.delegate = self
            audioRecorder.prepareToRecord()
        } catch {
            finishRecording(success: false)
        }
    }

    @IBAction func record(_ sender: Any) {
        if audioRecorder.isRecording {
            finishRecording(success: true)
            return
        }

        recordButton.setTitle("Tap to Stop", for: .normal)
        audioRecorder.record()
        timer = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(ViewController.updateAmplitude), userInfo: nil, repeats: true)
    }

    func getDocumentsDirectory() -> URL {
        let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
        return paths[0]
    }

    func finishRecording(success: Bool) {
        timer?.invalidate()
        timer = nil
        audioRecorder.stop()
        audioRecorder = nil

        if success {
            recordButton.setTitle("Tap to Re-record", for: .normal)
        } else {
            recordButton.setTitle("Tap to Record", for: .normal)
        }
    }

    @objc private func updateAmplitude() {
        audioRecorder.updateMeters()

        print("current power: \(audioRecorder.averagePower(forChannel: 0)) dB")

        let currentAmplitude = 1 - pow(10, (audioRecorder.averagePower(forChannel: 0) / 20))
        waveformView.add(samples: [currentAmplitude, currentAmplitude, currentAmplitude])
    }
}
dmrschmidt commented 2 years ago

Hey @drewg233, I would guess that is due to the slower timer interval of just 0.1s as opposed to 0.01s in the example. See https://github.com/dmrschmidt/DSWaveformImage/blob/e0f4caa6a8c1bb168df8d4194b46d6bd12d5878e/DSWaveformImageExample/SCAudioManager.m#L68

let me know if this helped.

drewg233 commented 2 years ago

Oh geez. Thats embarrassing! Yup that fixes it. Thank you for your response.

dmrschmidt commented 2 years ago

😄 no worries at all. Aren’t 99% of all coding mistakes like this? :) I’m glad I could help.