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,但答案如下: