繁体   English   中英

如何使用Audiokit根据频率调用函数

[英]How to use Audiokit to call a function based on frequency

我已经看到可以在函数中使用频率跟踪器,但我自己无法实现。 有一个可以显示频率的示例文件,但我没有找到任何在跟踪器达到某个频率时调用函数的内容。

当频率低于 40hz 时,我试图调用AKAudioPlayer.pause()函数。 我编辑了一个测试 .mp3 文件,以便音频文件中有 32hz 的部分。 我什至可以在频率跟踪器文本上看到,跟踪器正在读取 32 hz,但我没有成功让它暂停,即使我编写了依赖于此文本的函数。

是麦克风跟踪器的修改版本,用于跟踪音频文件。

我收到错误:“在解包可选值时意外发现 nil”,无论是在尝试直接使用 tracker.frequency 值形成函数时,还是在使用变量时,转换为基于 tracker.frequency 的字符串。

这让我相信跟踪器频率是我有问题的 nil 可选值,并得出结论,这就是让整个事情陷入困境的原因。 但我不知道该怎么做。 我知道有一个函数可以显示频率,但我无法重现它的成功。

在下面的代码(主要是 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() }

    }

    }

我在这里回答了一个类似的问题: AudioKit (iOS) - 添加频率/幅度变化的观察者

您必须决定如何检测此频率 - 它是否发生得很快并且需要在 DSP 代码中,或者您是否可以从 Swift 中以半规则间隔轮询频率。

我认为您不应该将 !s 添加到 AudioKit 节点定义中,因为它们可能在您期望它们时不存在,即使它看起来应该来自视图控制器生命周期。 通常,不要依赖视图控制器代码来控制音频。 也许将所有与音频相关的东西放在一个单例中并让它自行管理?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM