最初,我使用C#在windows控制台中制作歌曲的项目使用了Console.Beep(freq,time);,但是它的不可靠性导致了desyncs。
我改为使用哔哔声类。问题是,当播放一个基线时,每个音符的末尾都有一个可听到的点击。这是一个示例。用一个音符它不坏,但对许多连续的音符,它是无法忍受的。
即使在我用wave编辑器打开它的时候,无论我把它裁剪在哪里,它都会被点击。
如果不将任何大型库安装到我的C#控制台项目中,我如何才能摆脱这种单击呢?
发布于 2017-07-25 21:43:36
你试过在声音开始的时候把振幅放大,然后在结束时再下降。所以,修改beep类的内部循环,它读.
for (int T = 0; T < Samples; T++)
{
short Sample = System.Convert.ToInt16(A * Math.Sin(DeltaFT * T));
BW.Write(Sample);
BW.Write(Sample);
}可以修改成这样
for (int T=0; T < Samples; T++)
{
double AmpRamp = 1.0D;
if (T<1000) {
AmpRamp = ((double) T) / 1000.0D;
} else if (T > Samples - 1000) {
AmpRamp = ((double) (Samples - T)) / 1000.0D;
}
short Sample = System.Convert.ToInt16(A*AmpRamp*Math.Sin(DeltaFT * T));
BW.Write(Sample);
BW.Write(Sample);
}这提高了前1000个样本的振幅,然后在最后1000个样本中降低了振幅,但是你可能不得不改变斜坡的样本数。
发布于 2017-07-25 14:46:04
这是有点难以解释为什么不深入数字信号处理理论,但基本上,点击是因为你的信号有非常突然的开始和停止,转化为高频成分,可以听到的‘点击’。
如果你淡入和淡出你的信号的第10%和最后10%(使用例如奥迪),你会发现点击消失。
发布于 2017-07-25 21:06:42
Update:我将留下答案,因为基本想法仍然有效,但我同意适用于淡出的解决方案。除了解决点击问题,这也是向应用ADSR包络曲线迈出的第一步,这将使纯粹的正弦波听起来更有趣,即使不加任何暗示。
问题在于Beep类。它不小心结束在零交叉,即在一个完整的正弦波。
纠正这种情况的最自然的方法是控制它创建的样本的数量。
不确定这种计算:
double xx = 2 * Math.PI / Frequency;
Samples = (int)( (int)(Samples * xx) / xx);或者,您可以在数据创建后截断它们。
你可以试试这种相当粗俗的方法:
..
MS.Seek(0, SeekOrigin.Begin);
byte[] bytes = MS.ToArray();
Array.Reverse(bytes);
int z = 0;
for (int i = 0; i < bytes.Length; i+=4)
{
int v = bytes[i] + bytes[i+1] + bytes[i+2] + bytes[i+3];
if (v == 0) { z = i; break; }
}
MS.SetLength(bytes.Length - z);
..这会在流中找到最后一次过零,即在4的倍数上开始(或者更确切地说是结束)的最后4个零。
我相信纠正这种情况的其他方法不会那么麻烦,但它应该适用于初学者。
https://stackoverflow.com/questions/45306180
复制相似问题