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])
}
}