【问题标题】:Unity Converting Microphone input into HertzUnity 将麦克风输入转换为赫兹
【发布时间】:2021-02-11 03:57:48
【问题描述】:

我正在开发一个具有一些麦克风控件的 Unity 应用程序。在某一时刻,我必须将麦克风输入转换为赫兹 (Hz) 值并将它们显示给用户。现在,我做了一些研究,并为此目的制作了以下脚本:

int amountSamples = 1024;

 void Start ()
        {
            _fSample = AudioSettings.outputSampleRate;
        }

 void Update() {
            
            if (focused && Initialized) {
                if (Microphone.IsRecording(selectedDevice) && recording) {
                    
                        spectrumData = GetSpectrumAnalysis();
                        
                        if (spectrumCurve.keys.Length <= spectrumData.Length) {
                           
                            float keyTimeValue = 0;
                            float currentHighestKeyTime = 0;

                            //create a curvefield if none exists
                            spectrumCurve = new AnimationCurve();

                            for (int t = 0; t < spectrumData.Length; t++) {
                                spectrumCurve.AddKey(1 / spectrumData.Length + t, spectrumData[t]);
                                spectrumCurve.MoveKey(1 / spectrumData.Length + t, new Keyframe(1 / spectrumData.Length + t, keyTimeValue = spectrumData[t])); //update keyframe value
                                if (keyTimeValue > currentHighestKeyTime) {
                                    currentHighestKeyTime = keyTimeValue;
                                }
                            }

                            HighestKeyTimeValue = currentHighestKeyTime;
                            float freqN = HighestKeyTimeValue;
                            float f = freqN * (_fSample / 2) / amountSamples;
                            Debug.Log(f); //hz

                        }
                    }
                }
                audioSource.volume = 1;
            }

还有 GetSpectrumAnalysis()

 public float[] GetSpectrumAnalysis ()
        {
            float[] dataSpectrum = new float[amountSamples];
            audioSource.GetSpectrumData (dataSpectrum, 0, FFTWindow.BlackmanHarris); 
            for (int i = 0; i <= dataSpectrum.Length - 1; i++)
            {

                dataSpectrum[i] = Mathf.Abs (dataSpectrum[i] * sensitivity);

            }
            return dataSpectrum;

        }

现在,使用此代码,Hz 值应该在 float f 中计算,它确实有效,但 Hz 值不太准确,例如,我得到 400-500 Hz我应该得到大约 880 Hz 的频率。同样,我得到的是 130 Hz 而不是 220 Hz,等等。所以,我有两个问题:我得到的 Hz 比我应该得到的少,而且 Hz 值跳跃太多太快,所以即使声音也不一致玩是恒定的。知道如何改进此代码吗?我哪里做错了?

编辑 检查我的答案以获得解决方案。

【问题讨论】:

    标签: c# unity3d


    【解决方案1】:

    好的,没关系,我找到了解决方案,也许这会帮助遇到此线程的人,将 GetSpectrumAnalysis 方法更改为:

    public float test() {
                float Threshold = 0.02f;
                float[] dataSpectrum = new float[amountSamples];
                audioSource.GetSpectrumData(dataSpectrum, 0, FFTWindow.BlackmanHarris); //Rectangular
                float maxV = 0;
                var maxN = 0;
                for (int i = 0; i < amountSamples; i++) {
                    if (!(dataSpectrum[i] > maxV) || !(dataSpectrum[i] > Threshold)) {
                        continue;
                    }
    
                    maxV = dataSpectrum[i];
                    maxN = i; // maxN is the index of max
                }
    
                float freqN = maxN; // pass the index to a float variable
                if (maxN > 0 && maxN < amountSamples - 1) { // interpolate index using neighbours
                    var dL = dataSpectrum[maxN - 1] / dataSpectrum[maxN];
                    var dR = dataSpectrum[maxN + 1] / dataSpectrum[maxN];
                    freqN += 0.5f * (dR * dR - dL * dL);
                }
    
                return freqN * (_fSample / 2) / amountSamples; // convert index to frequency
            }
    

    然后像这样在更新方法中调用它:

    Text.text = test().ToString("00");
    

    欲了解更多信息,请查看此主题:Unity answers

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-27
      • 2014-02-07
      • 2011-08-09
      • 1970-01-01
      • 1970-01-01
      • 2014-01-01
      相关资源
      最近更新 更多