【问题标题】:AudioKit output changes to ear speakersAudioKit 输出更改为耳机
【发布时间】:2020-06-06 20:45:26
【问题描述】:

我在我的应用程序中实现了 AudioKit "MICROPHONE ANALYSIS" 示例 https://audiokit.io/examples/MicrophoneAnalysis/

我想分析麦克风输入频率,然后在确定的频率附近播放正确的音符。

通常声音输出是连接到我的 iPhone 的扬声器或蓝牙设备,但在实施“麦克风分析”示例后,声音输出变为 iPhone 顶部的小扬声器,通常在您获得称呼。 如何像以前一样切换到“普通”扬声器或连接的蓝牙设备?

var mic: AKMicrophone!
var tracker: AKFrequencyTracker!
var silence: AKBooster!


func initFrequencyTracker() {
        AKSettings.audioInputEnabled = true
        mic = AKMicrophone()
        tracker = AKFrequencyTracker(mic)
        silence = AKBooster(tracker, gain: 0)
    }

    func deinitFrequencyTracker() {
        plotTimer.invalidate()
        do {
            try AudioKit.stop()
            AudioKit.output = nil
        } catch {
            print(error)
        }
    }

    func initPlotTimer() {
        AudioKit.output = silence
        do {
            try AudioKit.start()
        } catch {
            AKLog("AudioKit did not start!")
        }
        setupPlot()
        plotTimer = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(updatePlotUI), userInfo: nil, repeats: true)
    }

    func setupPlot() {
        let plot = AKNodeOutputPlot(mic, frame: audioInputPlot.bounds)
        plot.translatesAutoresizingMaskIntoConstraints = false
        plot.alpha = 0.3
        plot.plotType = .rolling
        plot.shouldFill = true
        plot.shouldCenterYAxis = false
        plot.shouldMirror = true
        plot.color = UIColor(named: uiFarbe)
        audioInputPlot.addSubview(plot)

        // Pin the AKNodeOutputPlot to the audioInputPlot
        var constraints = [plot.leadingAnchor.constraint(equalTo: audioInputPlot.leadingAnchor)]
        constraints.append(plot.trailingAnchor.constraint(equalTo: audioInputPlot.trailingAnchor))
        constraints.append(plot.topAnchor.constraint(equalTo: audioInputPlot.topAnchor))
        constraints.append(plot.bottomAnchor.constraint(equalTo: audioInputPlot.bottomAnchor))
        constraints.forEach { $0.isActive = true }
    }

    @objc func updatePlotUI() {
        if tracker.amplitude > 0.1 {
            let trackerFrequency = Float(tracker.frequency)

            guard trackerFrequency < 7_000 else {
                // This is a bit of hack because of modern Macbooks giving super high frequencies
                return
            }

            var frequency = trackerFrequency
            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(trackerFrequency / frequency))

            frequencyLabel.text = String(format: "%0.1f", tracker.frequency)

            if frequencyTranspose(note: notesToTanspose[index]) != droneLabel.text {
                note = frequencyTranspose(note: notesToTanspose[index])
                droneLabel.text = note
                DispatchQueue.main.asyncAfter(deadline: .now() + 0.03, execute: {
                    self.prepareSinglePlayerFirstForStart(note: self.note)
                    self.startSinglePlayer()
                })
            }
        }
    }

    func frequencyTranspose(note: String) -> String {
        var indexNote = notesToTanspose.firstIndex(of: note)!
        let chosenInstrument = UserDefaults.standard.object(forKey: "whichInstrument") as! String
        if chosenInstrument == "Bb" {
            if indexNote + 2 >= notesToTanspose.count {
                indexNote -= 12
            }
            return notesToTanspose[indexNote + 2]
        } else if chosenInstrument == "Eb" {
            if indexNote - 3 < 0 {
                indexNote += 12
            }
            return notesToTanspose[indexNote - 3]
        } else {
            return note
        }
    }

【问题讨论】:

    标签: audiokit


    【解决方案1】:

    控制会话设置是一种很好的做法,因此首先在您的应用程序中创建一个方法以在初始化期间处理该问题。

    接下来,有一个我设置类别和所需选项的示例:

    func start() {
        do {
            let session = AVAudioSession.sharedInstance()
            try session.setCategory(.playAndRecord, options: .defaultToSpeaker)
            try session.setActive(true, options: .notifyOthersOnDeactivation)
            try session.overrideOutputAudioPort(AVAudioSession.PortOverride.speaker)
            try AudioKit.start()
        } catch {
          // your error handler
        }
    }
    

    您可以调用start 方法,在该方法中调用initPlotTimer 中的AudioKit.Start()。

    上面的示例使用AVAudioSession,我相信这是AKSettings 包装的(请随时编辑我的答案,以免误导未来的读者,因为我没有查看 AudioKit 源代码片刻)。

    既然 AVAudioSession 已公开,让我们坚持使用 AudioKit 提供的方法,因为这就是您要处理的。

    这是另一个使用AKSettings的例子:

    func start() {
            do {
                AKSettings.channelCount = 2
                AKSettings.ioBufferDuration = 0.002
                AKSettings.audioInputEnabled = true
                AKSettings.bufferLength = .medium
                AKSettings.defaultToSpeaker = true
                // check docs for other options and settings
    
                try AKSettings.setSession(category: .playAndRecord, with: [.defaultToSpeaker, .allowBluetooth])
                try AudioKit.start()
            } catch {
                // your handler
            }
    }
    

    请记住,您不必将其称为 start,或运行 AudioKit 的 start 方法,我只是公开初始化阶段,以使其对您和其他用例可读。

    参考:

    https://developer.apple.com/documentation/avfoundation/avaudiosession/categoryoptions

    https://audiokit.io/docs/Classes/AKSettings.html

    【讨论】:

    • 好的,很乐意为您提供帮助!在这个社区中,首先将答案设置为有用并接受答案@lololarumpel 是一个很好的做法
    • 哇...谢谢您的回答!我在 initFrequencyTracker() 中添加了 `AKSettings.defaultToSpeaker = true AKSettings.allowAirPlay = true AKSettings.useBluetooth = true `,并且这样做了。声音现在从扬声器或蓝牙设备中发出,但有时声音中有一些“裂痕”。在我实现 AudioKit 之前,这并没有发生。你也可以在这里帮忙吗?
    • @lololarumpel 你可以提出一个新问题,我相信你会得到帮助;请记住,在 StackOverflow 中,您可以提出问题以获得答案。
    • 抱歉删除它...我不得不重新输入它:-)
    • 好的。如何将答案设置为有用并接受答案?抱歉,我对 StackOverFlow 还很陌生。
    猜你喜欢
    • 2012-12-15
    • 2017-12-11
    • 1970-01-01
    • 1970-01-01
    • 2017-05-20
    • 2013-05-27
    • 2015-01-15
    • 2015-09-26
    • 2018-02-25
    相关资源
    最近更新 更多