简体   繁体   English

unity - 正弦波振荡器产生金属噪音

[英]Unity - sine wave oscillator generates metallic noise

I am trying to create a sine wave oscillator to play with audio sources.我正在尝试创建一个正弦波振荡器来播放音频源。

At first I created a simple one like this:起初我创建了一个这样的简单的:

public class FirstOscillator : MonoBehaviour
{
    public double frequency = 400.0;

    private double increment;
    private double phase;
    private double sampleRate = 48000.0;

    public float gain;

    void OnAudioFilterRead(float[] data, int channels)
    {
        increment = frequency * 2.0 * Mathf.PI / sampleRate;
        for (int i = 0; i < data.Length; i += channels)
        {
            phase += increment;
            data[i] = (float) (gain * Mathf.Sin((float) phase));

            if (channels == 2)
            {
                data[i + 1] = data[i];
            }
        }
    }
}

This works perfectly fine and generates a nice sounding sine wave.这工作得很好,并产生一个很好的正弦波。

But I decided that design-wise it would be better for my oscillators to be sort of functions for amplitude(frequency, time) , so I was trying to modify it to actually use time and extract the oscillation into a method for now:但是我决定在设计上最好让我的振荡器成为amplitude(frequency, time)的函数,所以我试图修改它以实际使用时间并将振荡提取到一种方法中:

public class SecondOscillator : MonoBehaviour, IAudioFilter
{
    public double frequency = 400.0;

    private double sampleRate = 48000.0;

    public float gain;

    public void OnAudioFilterRead(float[] data, int channels)
    {
        var time = AudioSettings.dspTime;

        for (int i = 0; i < data.Length; i += channels)
        {
            data[i] = gain * Amplitude((float)frequency, (float)(time + i / sampleRate / channels));

            if (channels == 2)
            {
                data[i + 1] = data[i];
            }

        }
    }

    private float Amplitude(float freq, float time)
    {
        return Mathf.Sin(freq * time * 2 * Mathf.PI);
    }
}

For some reason this produces weirdly sounding metallic noise, which reacts to frequency changes though.出于某种原因,这会产生听起来很奇怪的金属噪音,但它会对频率变化做出反应。 I wonder what could be the problem.我想知道可能是什么问题。

UPDATE更新

In the comments section people suggest that AudioSettings.dspTime is a number of samples, not time in seconds.在评论部分,人们建议AudioSettings.dspTime是一些样本,而不是以秒为单位的时间。 I think that's not the case so I wrote a quick script to test it:我认为情况并非如此,所以我写了一个快速脚本来测试它:

class SampleRateTest : MonoBehaviour
{
    public int sampleRate;

    public void Awake()
    {
        sampleRate = AudioSettings.outputSampleRate;
    }

    private StringBuilder sb = new StringBuilder();

    private int samplesTakenStart = 5;
    private int samplesTakenEnd = 5;

    private int loggedFrames = 5;
    private int loggedFrameIndex = 0;

    public void OnAudioFilterRead(float[] data, int channels)
    {
        var time = AudioSettings.dspTime;
        for (var index = 0; index < data.Length; index++)
        {
            if (index < samplesTakenStart || index > data.Length - samplesTakenEnd)
                sb.AppendLine($"Sample {index} time is {time}");
            else if (index == samplesTakenStart)
                sb.AppendLine("...");

            time += 1.0 / sampleRate / channels;
        }

        sb.AppendLine("End of frame " + loggedFrameIndex);

        if (loggedFrameIndex++ == loggedFrames)
            Debug.Log(sb.ToString());
    }

}

This produces the following output:这会产生以下输出:

Sample 0 time is 1196.144
Sample 1 time is 1196.14401041667
Sample 2 time is 1196.14402083333
Sample 3 time is 1196.14403125
Sample 4 time is 1196.14404166667
...
Sample 508 time is 1196.14929166661
Sample 509 time is 1196.14930208328
Sample 510 time is 1196.14931249994
Sample 511 time is 1196.14932291661
End of frame 0
Sample 0 time is 1196.14933333333
Sample 1 time is 1196.14934375
Sample 2 time is 1196.14935416667
Sample 3 time is 1196.14936458333
Sample 4 time is 1196.149375
...
Sample 508 time is 1196.15462499994
Sample 509 time is 1196.15463541661
Sample 510 time is 1196.15464583328
Sample 511 time is 1196.15465624994
End of frame 1
Sample 0 time is 1196.15466666667
Sample 1 time is 1196.15467708333
Sample 2 time is 1196.1546875
Sample 3 time is 1196.15469791667
Sample 4 time is 1196.15470833333
...
Sample 508 time is 1196.15995833328
Sample 509 time is 1196.15996874994
Sample 510 time is 1196.15997916661
Sample 511 time is 1196.15998958328
End of frame 2
Sample 0 time is 1196.16
Sample 1 time is 1196.16001041667
Sample 2 time is 1196.16002083333
Sample 3 time is 1196.16003125
Sample 4 time is 1196.16004166667
...
Sample 508 time is 1196.16529166661
Sample 509 time is 1196.16530208328
Sample 510 time is 1196.16531249994
Sample 511 time is 1196.16532291661
End of frame 3
Sample 0 time is 1196.16533333333
Sample 1 time is 1196.16534375
Sample 2 time is 1196.16535416667
Sample 3 time is 1196.16536458333
Sample 4 time is 1196.165375
...
Sample 508 time is 1196.17062499994
Sample 509 time is 1196.17063541661
Sample 510 time is 1196.17064583328
Sample 511 time is 1196.17065624994
End of frame 4
Sample 0 time is 1196.17066666667
Sample 1 time is 1196.17067708333
Sample 2 time is 1196.1706875
Sample 3 time is 1196.17069791667
Sample 4 time is 1196.17070833333
...
Sample 508 time is 1196.17595833328
Sample 509 time is 1196.17596874994
Sample 510 time is 1196.17597916661
Sample 511 time is 1196.17598958328
End of frame 5

So to me it looks like AudioSettings.dspTime is time indeed so it shouldn't be divided by sampleRate .所以在我看来AudioSettings.dspTime确实是时间,所以它不应该除以sampleRate The channels count is 2 on my system if that matters.如果重要的话,我的系统上的channels数是 2。

UPDATE 2: I also tried removing the channel-specific code and setting the project audio settings to Mono (instead of Stereo), but it didn't help so I assume the channels are not the issue here.更新 2:我还尝试删除特定于通道的代码并将项目音频设置设置为单声道(而不是立体声),但它没有帮助,所以我认为通道不是这里的问题。

Also, I created a wav demo of the sound I get .另外,我创建了我得到的声音的 wav 演示 To me it sounds more like a square than a sine.对我来说,它听起来更像是一个平方而不是一个正弦。

Oh.哦。 My.我的。 God.上帝。 The problem was I was using float values instead of double and it appears that float-pointing calculations are just not precise enough for this sort of data.问题是我使用的是float值而不是double float值,而且对于此类数据,浮点计算似乎不够精确。 Changed all my floats to doubles and it works now.将我所有的花车改为双打,现在可以使用了。

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

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