我已经看到可以在一个功能中使用频率跟踪器,但我不能自己把它拉下来。有一个示例文件可以显示频率,但是当跟踪器达到特定频率时,我还没有找到任何调用函数的文件。
当频率降至40hz以下时,我正试图调用AKAudioPlayer.pause()
函数。我编辑了一个测试.mp3文件,以便在音频文件中有一个32hz的部分。我甚至可以在频率跟踪器文本上看到,跟踪器正在读取32赫兹,但是我没有任何成功让它暂停,即使我写的功能依赖于这个文本。
This是麦克风跟踪器的修改版本,用于跟踪音频文件。
我收到错误:“在尝试使用tracker.frequency值直接形成函数时,以及在使用变量时转换为基于tracker.frequency的字符串时,意外发现nil在展开Optional值时”
这让我相信跟踪器频率是我有问题的零可选值,并且结论是,这就是将整个事情放在火焰中的原因。但我无法弄清楚该做些什么。我知道有一个功能可以显示频率,但我无法重现它的成功。
在下面的代码中(主要是Audiokit示例文件)我试图使用Tracker.Frequency来触发暂停功能:
import AudioKit
import AudioKitUI
import UIKit
class ViewController: UIViewController {
@IBOutlet private var frequencyLabel: UILabel!
@IBOutlet private var amplitudeLabel: UILabel!
@IBOutlet private var noteNameWithSharpsLabel: UILabel!
@IBOutlet private var noteNameWithFlatsLabel: UILabel!
@IBOutlet private var audioInputPlot: EZAudioPlot!
@IBAction func Play(_ sender: Any) {
if input.isStarted == false
{
input.play()
}
}
@IBAction func Pause(_ sender: Any)
{
if input.isStarted
{
input.pause()
}
}
var input: AKAudioPlayer!
var song = try! AKAudioFile(readFileName: "TEST.mp3")// ... the error is here
var tracker: AKFrequencyTracker!
var silence: AKBooster!
let noteFrequencies = [16.35, 17.32, 18.35, 19.45, 20.6, 21.83, 23.12, 24.5, 25.96, 27.5, 29.14, 30.87]
let noteNamesWithSharps = ["C", "C♯", "D", "D♯", "E", "F", "F♯", "G", "G♯", "A", "A♯", "B"]
let noteNamesWithFlats = ["C", "D♭", "D", "E♭", "E", "F", "G♭", "G", "A♭", "A", "B♭", "B"]
func setupPlot() {
let plot = AKNodeOutputPlot(input, frame: audioInputPlot.bounds)
plot.plotType = .rolling
plot.shouldFill = true
plot.shouldMirror = true
plot.color = UIColor.blue
audioInputPlot.addSubview(plot)
}
override func viewDidLoad() {
super.viewDidLoad()
pauseOnQueue()
AKSettings.audioInputEnabled = true
do {input = try AKAudioPlayer(file: song)}
catch {print("ERROR")}
tracker = AKFrequencyTracker(input)
silence = AKBooster(tracker, gain: 1)
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
AudioKit.output = silence
AudioKit.start()
setupPlot()
Timer.scheduledTimer(timeInterval: 0.1,
target: self,
selector: #selector(ViewController.updateUI),
userInfo: nil,
repeats: true)
}
@objc func updateUI() {
if tracker.amplitude > 0.1 {
frequencyLabel.text = String(format: "%0.1f", tracker.frequency)
var frequency = Float(tracker.frequency)
while frequency > Float(noteFrequencies[noteFrequencies.count - 1]) {
frequency /= 2.0
}
while frequency < Float(noteFrequencies[0]) {
frequency *= 2.0
}
var minDistance: Float = 10_000.0
var index = 0
for i in 0..<noteFrequencies.count {
let distance = fabsf(Float(noteFrequencies[i]) - frequency)
if distance < minDistance {
index = i
minDistance = distance
}
}
let octave = Int(log2f(Float(tracker.frequency) / frequency))
noteNameWithSharpsLabel.text = "\(noteNamesWithSharps[index])\(octave)"
noteNameWithFlatsLabel.text = "\(noteNamesWithFlats[index])\(octave)"
}
amplitudeLabel.text = String(format: "%0.2f", tracker.amplitude)
}
func pauseOnQueue() {
frequencyLabel.text = String(format: "%0.1f", tracker.frequency)
let frequency = Float(tracker.frequency)
if frequency < 50 && frequency > 20 && input.isStarted == true
{ input.pause() }
}
}
答案 0 :(得分:2)
我在这里回答了类似的问题:AudioKit (iOS) - Add observer for frequency / amplitude change
你必须决定如何检测这个频率 - 这是一个快速发生的事情,需要在DSP代码中,或者你可以从半定期的间隔轮询频率迅速的。
我认为你不应该将它们添加到AudioKit节点定义中,因为它们可能在您期望它们时不存在,即使它看起来应该是从视图控制器生命周期中看起来的。通常,不要依赖视图控制器代码来控制音频。也许把所有音频相关的东西都放在一个单独的东西中让它自己管理?