首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >声音分析仪的振幅和频率

声音分析仪的振幅和频率
EN

Code Review用户
提问于 2017-03-08 19:30:15
回答 1查看 201关注 0票数 2

由于我是移动/面向对象编程的初学者,我遇到了一种困惑的情况,让我怀疑我是否正确地编码了.

主修班:

代码语言:javascript
复制
    class ViewController: UIViewController, SoundAnalyserDelegate{

        lazy var fontSize : SoundAnalyser = {
            return SoundAnalyser(delegate: self) 
        }()

        @IBOutlet var frequencyLabel: UILabel!
        @IBOutlet var amplitudeLabel: UILabel!
        @IBOutlet var note: UILabel!

        override func viewDidLoad() {
            super.viewDidLoad()
            soundAnalyser.start()

        }

        func setLabelAmp (_ text:String) {

            frequencyLabel.text = text

        }

        func setLabelFreq (_ text:String) {

            frequencyLabel.text = text

        }

        func setLabelNote (_ text:String) {

            frequencyLabel.text = text

        }        

第二类:

代码语言:javascript
复制
    class SoundAnalyser {

        var delegate:SoundAnalyserDelegate?

        let minimum = Double(160)
        let maximum = Double(1400)

        var mic: AKMicrophone
        var tracker: AKFrequencyTracker
        fileprivate var silence: AKBooster
        fileprivate var timer: Timer?
        fileprivate var notesArray: [(String, Double)]?

        init(delegate: SoundAnalyserDelegate){
            mic = AKMicrophone()
            tracker = AKFrequencyTracker(mic, hopSize: minimum, peakCount: maximum)
            silence = AKBooster(tracker, gain:0)
            notesArray = self.getNotesFrequencies()
            self.delegate = delegate

        }


        func tick(){
            let amp = tracker.amplitude
            let freq = tracker.frequency


            if amp > 0.05 && freq > minimum && freq < maximum{
                let readNote = notesArray![analyseCapturedSound()]

                delegate?.setLabelAmp(String(format:"%f", amp)) //Setting the text of a label from the UI

                delegate?.setLabelFreq(String(format:"%f", freq))

    //            delegate?.setLabelNote(String(format:"%f", readNote))

                print("freq:", freq," amp:", amp," NOTE: \(readNote)")
            }
        }  

我只是加入了最重要的代码来表达我想要问的问题。

摘要:类ViewController启动SoundAnalyser。在SoundAnalyser下,有一个函数可以执行来自ViewController的函数(“delegate?.setLabel.”)。我用了一个使用协议的委托类,但我不知道为什么我觉得出了问题。我是说,执行创建者的方法.是对的吗?如果不是,什么是最“好公民”的方式来实现具有相同结果的东西?

EN

回答 1

Code Review用户

回答已采纳

发布于 2017-04-15 13:15:25

这基本上是正确的。使用委托的理由是类应该通知它的委托,而不是指示它。这的一个症状是SoundAnalyser正在格式化文本,这应该是视图控制器的责任。

考虑到SoundAnalyzer在MVC模式中填充了模型的角色。该模型只负责提供数据,不应涉及重新解释数据以供显示。

如果需要在多个地方使用该功能,则可以使用helper类封装格式。

示例

SoundAnalyserDelegate:委托方法采用咨询通知或事件的形式,而不是指令。委托接收数据,而不是预先格式化的文本。如果频率和振幅总是同时变化的话,通过传递聚合对象可以进一步改进这一点(情况似乎是这样):

代码语言:javascript
复制
struct SoundAnalyserSample {
    let frequency: Double
    let amplitude: Double
}

protocol SoundAnalyserDelegate {
    func soundAnalyserSample(sample: SoundAnalyserSample)
    // ... and so on
}

SoundAnalyser:通知传递示例的委托。

代码语言:javascript
复制
func tick(){
    let amp = tracker.amplitude
    let freq = tracker.frequency

    if amp > 0.05 && freq > minimum && freq < maximum {
        let readNote = notesArray![analyseCapturedSound()]
        let sample = SoundAnalyserSample(
            frequency: freq,
            amplitude: amp
        }
        delegate?.soundAnalyserSample(sample: sample)
    }
}

ViewController:视图控制器响应发件人的通知(在本例中是声音分析器),格式化数据,并更新UI。请注意,您还需要确保UI更新发生在主队列上,这不一定是由调用方保证的。

代码语言:javascript
复制
class ViewController: UIViewController, SoundAnalyserDelegate {

    func soundAnalyserSample(sample: SoundAnalyserSample) {
        DispatchQueue.main.async {
            let frequencyText = String(format:"%f", sample.frequency)
            let amplitudeText = String(format:"%f", sample.amplitude)
            frequencyLabel.text = frequencyText
            amplitudeLabel.text = amplitudeText
        }
    }
票数 1
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/157263

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档