【问题标题】:Read microphone decibels and pitch/frequency读取麦克风分贝和音高/频率
【发布时间】:2019-04-01 12:04:24
【问题描述】:

我正在尝试制作一个游戏,在该游戏中,当听到足够响亮的声音时,我的角色会开枪(在 Unity 中)。但是我不知道如何开始。

感谢您的帮助!

【问题讨论】:

    标签: c# unity3d audio triggers microphone


    【解决方案1】:

    您可以通过使用AudioSource.GetOutputData 函数检索当前正在播放的麦克风的输出数据块来获取麦克风的分贝数。要从此数据中获取 dB,您需要对数据样本求和,然后计算 RMS。这是您可以使用20 * Mathf.Log10 (RMS / refVal) 计算 dB 的 RMS 值。

    Unity's post 上有一个关于此的完整示例。您可以阅读以获取更多信息,下面的代码基于此:

    public float rmsVal;
    public float dbVal;
    public float pitchVal;
    
    private const int QSamples = 1024;
    private const float RefValue = 0.1f;
    private const float Threshold = 0.02f;
    
    float[] _samples;
    private float[] _spectrum;
    private float _fSample;
    
    void Start()
    {
        _samples = new float[QSamples];
        _spectrum = new float[QSamples];
        _fSample = AudioSettings.outputSampleRate;
    }
    
    void Update()
    {
        AnalyzeSound();
    
        Debug.Log("RMS: " + rmsVal.ToString("F2"));
        Debug.Log(dbVal.ToString("F1") + " dB");
        Debug.Log(pitchVal.ToString("F0") + " Hz");
    }
    
    void AnalyzeSound()
    {
        GetComponent<AudioSource>().GetOutputData(_samples, 0); // fill array with samples
        int i;
        float sum = 0;
        for (i = 0; i < QSamples; i++)
        {
            sum += _samples[i] * _samples[i]; // sum squared samples
        }
        rmsVal = Mathf.Sqrt(sum / QSamples); // rms = square root of average
        dbVal = 20 * Mathf.Log10(rmsVal / RefValue); // calculate dB
        if (dbVal < -160) dbVal = -160; // clamp it to -160dB min
                                        // get sound spectrum
        GetComponent<AudioSource>().GetSpectrumData(_spectrum, 0, FFTWindow.BlackmanHarris);
        float maxV = 0;
        var maxN = 0;
        for (i = 0; i < QSamples; i++)
        { // find max 
            if (!(_spectrum[i] > maxV) || !(_spectrum[i] > Threshold))
                continue;
    
            maxV = _spectrum[i];
            maxN = i; // maxN is the index of max
        }
        float freqN = maxN; // pass the index to a float variable
        if (maxN > 0 && maxN < QSamples - 1)
        { // interpolate index using neighbours
            var dL = _spectrum[maxN - 1] / _spectrum[maxN];
            var dR = _spectrum[maxN + 1] / _spectrum[maxN];
            freqN += 0.5f * (dR * dR - dL * dL);
        }
        pitchVal = freqN * (_fSample / 2) / QSamples; // convert index to frequency
    }
    

    【讨论】:

    • 非常感谢!
    猜你喜欢
    • 2023-03-30
    • 1970-01-01
    • 2011-11-03
    • 1970-01-01
    • 2018-02-05
    • 1970-01-01
    • 1970-01-01
    • 2019-05-20
    • 1970-01-01
    相关资源
    最近更新 更多