Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/290.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 创建正弦音频信号时出现奇怪的小故障_C#_Audio_Wave_Trigonometry - Fatal编程技术网

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

C# 创建正弦音频信号时出现奇怪的小故障,c#,audio,wave,trigonometry,C#,Audio,Wave,Trigonometry,今天我看了一下波形格式,创建了一个小型波形发生器。我创建的正弦声音如下所示: 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]; fo

今天我看了一下波形格式,创建了一个小型波形发生器。我创建的正弦声音如下所示:

 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));
    }
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));
    }
MakeInt16WaveData如下所示:

 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));
    }
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));
    }
这就像预期的一样!现在我想像这样从一个频率跳到另一个频率:

 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));
    }
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才能得到正确的输出。这里可能有什么问题?这是音频问题还是我的代码中有bug

谢谢

TaW编辑:我冒昧地在图表中添加了数据截图,以说明问题,第一个是0.5系数,第二个是1.0,第三和第四个是2.0和5.0:

编辑:这里有一个例子,从200到100赫兹的猛扑: 调试值: 波显然不是以100赫兹结束的
挖掘我生锈的数学,我想可能是因为:

从频率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
其中的给予或接受类似于正弦公式中的术语


请注意,通过将恒定部分S/2移出环路,可以获得效率。

从200赫兹到0赫兹播放的声音是什么意思?这是否意味着你通过环路观察到赫兹的值,在某个点它变成了零?另外,您使用的长度是多少?将hzDelta乘以0.5将使hz从200增加到150。@pixartist:我没有解释,但可能这些插图可以帮助其他人看到这个问题。。请随意删除,如果你介意我的编辑。。!谢谢你,陶@Jaket,不,该值的行为与预期一致,它以hzEnd结尾。仍然播放的声音在hzStart+hzDelta*2结束。我真的很困惑!我又添加了两张图片来说明这个问题。似乎在~4 hz处结束的正弦可能为0,但答案如下: