减少Java中产生纯音的谐波
我试图在Java中开发一种静态方法来生成纯音。
在开始时,它似乎很容易,但是当我尝试将双阵列写入扬声器时,我会欣赏太多的谐波。
我用一个频谱分析仪(sonometer)对它进行测试,然后,我也在图形中绘制了数组结果。 当我完成它时,我已经看到了这个问题:
这是关于波形,它已经中断了。 我想平滑这个数组,但我不知道该怎么做。
这是代码:
/**
* Genera un tono puro.
* @param bufferSize Tamaño del buffer.
* @param fs Frecuencia de muestreo.
* @param f0 Frecuencia central.
* @return El tono puro.
*/
public static double[] generateTone(int bufferSize, int fs, int f0) {
double[] tone = new double[bufferSize]; // Tono
double angle; // Ángulo del tono
// Sólo hace falta recorrer la mitad del array, ya que hay simetría:
for (int i = 0; i < tone.length / 2; i++) {
angle = 2 * Math.PI * f0 * i / fs; // Calculamos la variación del ángulo
// Tenemos que conseguir que la señal sea menos abrupta para reducir al máximo los armónicos):
tone[2 * i + 1] = tone[2 * i] = Math.sin(angle); // Aprovechamos la simetría
}
return tone;
} // getSinus()
将相同的值写入两个连续的位置会在波形中引入一个步骤。 任何与平滑正弦曲线的偏差都会增加谐波。 如果你想要一个纯音,不要这样做。 如果你想这样做,不要期望纯音。
你需要计算'bufferLength'的每个值的角度和正弦值,而不是每个第二个值。 你所做的实质上是采用插值进行欠采样。 我没有看到任何“对称性”。
我并不确定,但是我认为我对@EJP的说法感到困惑:我需要逐步获得每个价值。 对称性对于信号的质量来说是一种快速但更差的方法。
这是新的代码:
/**
* Genera un tono puro.
* @param bufferSize Tamaño del buffer.
* @param fs Frecuencia de muestreo.
* @param f0 Frecuencia central.
* @return El tono puro.
*/
public static double[] generateTone(int bufferSize, int fs, int f0) {
double[] tone = new double[bufferSize]; // Tono
double angle; // Ángulo del tono
for (int i = 0; i < tone.length; i++) {
angle = 2 * Math.PI * f0 * i / fs; // Calculamos la variación del ángulo
tone[i] = Math.sin(angle); // Cada muestra se obtiene a partir del seno del ángulo
}
return tone;
} // generateTone()
链接地址: http://www.djcxy.com/p/77187.html