创建正弦音频信号时出现奇怪的故障

时间:2014-11-21 21:04:28

标签: c# audio wave sine

我今天看了一下波形,并创建了一个小波发生器。我创造了这样的正弦声音:

 public static Wave GetSine(double length, double hz)
    {
        int bitRate = 44100;
        int l = (int)(bitRate * length);
        double f = 1.0 / bitRate;
        Int16[] data = new Int16[l];
        for (int i = 0; i < l; i++)
        {
            data[i] = (Int16)(Math.Sin(hz * i * f * Math.PI * 2) * Int16.MaxValue);
        }
        return new Wave(false, Wave.MakeInt16WaveData(data));
    }

MakeInt16WaveData如下所示:

public static byte[] MakeInt16WaveData(Int16[] ints)
    {
        int s = sizeof(Int16);
        byte[] buf = new byte[s * ints.Length];
        for(int i = 0; i < ints.Length; i++)
        {
            Buffer.BlockCopy(BitConverter.GetBytes(ints[i]), 0, buf, i * s, s);
        }
        return buf;
    }

这按预期工作!现在我想从一个频率猛扑到另一个频率:

public static Wave GetSineSwoop(double length, double hzStart, double hzEnd)
    {
        int bitRate = 44100;
        int l = (int)(bitRate * length);
        double f = 1.0 / bitRate;
        Int16[] data = new Int16[l];
        double hz;
        double hzDelta = hzEnd - hzStart;
        for (int i = 0; i < l; i++)
        {
            hz = hzStart + ((double)i / l) * hzDelta * 0.5; // why *0.5 ?
            data[i] = (Int16)(Math.Sin(hz * i * f * Math.PI * 2) * Int16.MaxValue);
        }
        return new Wave(false, Wave.MakeInt16WaveData(data));
    }

现在,当我从200赫兹到100赫兹时,声音从200赫兹到0赫兹。出于某种原因,我不得不将delta乘以0.5以获得正确的输出。这可能是什么问题?这是音频还是我的代码中有错误?

由于

由TaW编辑:我冒昧地在图表中添加数据截图来说明问题,第一个是0.5因子,第二个是1.0和第三个&amp;第二名是2.0和5.0:

enter image description here enter image description here enter image description here enter image description here

编辑:这是一个例子,从200到100赫兹猛扑: 调试值: Debug values 波浪显然不会以100赫兹结束 The resulting sine wave clearly does not end at 100 hz

1 个答案:

答案 0 :(得分:0)

挖出我生锈的数学,我认为可能是因为:

从频率F1到F2的L步,你的频率为

Fi = F1 + i * ( F2 - F1 ) / L

( F2 - F1 ) / L = S

Fi = F1 + i * S

现在要了解我们的进展情况,我们需要i以上的积分,这将是

I(Fi) = i * F1 + 1/2 * i ^ 2 * S

哪个给出或类似于sine公式中的术语。

请注意,您可以通过将常量部分(S/2)移出循环来获得效率。