您如何使用 StdAudio 编写在 Java 中播放和弦的方法?
How do you write a method that plays chords in Java using StdAudio?
我目前正在编写一种演奏和弦的方法,但我 运行 遇到了一些麻烦。我能够发出声音,但我得到的只是白噪音的片段。我在下面列出了我的方法。
public static void playChord(double duration, double... frequencies) {
final int sliceCount = (int) (StdAudio.SAMPLE_RATE * duration);
final double[] slices = new double[sliceCount + 1];
double freqTotal=0;
for (int i = 0; i <= sliceCount; i++) {
for (int j=0; j<frequencies.length;j++) {
frequencies[j] +=frequencies[j];
freqTotal=frequencies[j];
}
slices[i] = Math.sin(2 * Math.PI * i * freqTotal/StdAudio.SAMPLE_RATE);
}
StdAudio.play(slices);
}
这里有两个问题:
首先是您在每个样本上用 frequencies[j] += frequencies[j]
行踩踏频率阵列。假设 frequencies[0] == 100
。在生成第一个样本之前,它将变为 200。即使频率数组的长度仅为 1,也不会产生正弦波。
第二个问题是您组合多个频率的概念是错误的。假设频率数组有两个元素 100 和 200。如果第一个问题得到解决,您实际上会计算一个 300 Hz 的正弦波。那是因为您在错误的级别将它们加在一起,所以您正在计算 'sin(2*pii(100+200)/2) 即 sin(2*pi*i*300/2)
.
相反,你需要做这样的事情:
for (int i = 0; i < sliceCount; i++)
{
for (int j = 0 ; j < frequencies.length; j++)
{
slices[i] += Math.sin(2*Math.PI*i*frequencies[i]/StdAudio.SAMPLE_RATE);
}
slices[i] /= frequencies.length; // renormalize to between -1 and 1
}
我目前正在编写一种演奏和弦的方法,但我 运行 遇到了一些麻烦。我能够发出声音,但我得到的只是白噪音的片段。我在下面列出了我的方法。
public static void playChord(double duration, double... frequencies) {
final int sliceCount = (int) (StdAudio.SAMPLE_RATE * duration);
final double[] slices = new double[sliceCount + 1];
double freqTotal=0;
for (int i = 0; i <= sliceCount; i++) {
for (int j=0; j<frequencies.length;j++) {
frequencies[j] +=frequencies[j];
freqTotal=frequencies[j];
}
slices[i] = Math.sin(2 * Math.PI * i * freqTotal/StdAudio.SAMPLE_RATE);
}
StdAudio.play(slices);
}
这里有两个问题:
首先是您在每个样本上用 frequencies[j] += frequencies[j]
行踩踏频率阵列。假设 frequencies[0] == 100
。在生成第一个样本之前,它将变为 200。即使频率数组的长度仅为 1,也不会产生正弦波。
第二个问题是您组合多个频率的概念是错误的。假设频率数组有两个元素 100 和 200。如果第一个问题得到解决,您实际上会计算一个 300 Hz 的正弦波。那是因为您在错误的级别将它们加在一起,所以您正在计算 'sin(2*pii(100+200)/2) 即 sin(2*pi*i*300/2)
.
相反,你需要做这样的事情:
for (int i = 0; i < sliceCount; i++)
{
for (int j = 0 ; j < frequencies.length; j++)
{
slices[i] += Math.sin(2*Math.PI*i*frequencies[i]/StdAudio.SAMPLE_RATE);
}
slices[i] /= frequencies.length; // renormalize to between -1 and 1
}