简体   繁体   English

您如何编写使用StdAudio在Java中弹奏和弦的方法?

[英]How do you write a method that plays chords in Java using StdAudio?

I am currently writing a method that plays chords but I ran into a bit of trouble. 我目前正在编写一种演奏和弦的方法,但遇到了一些麻烦。 I am able to produce sound but all I get are snippets of white noise. 我能够发出声音,但是我得到的只是白噪声的片段。 I have listed my method below. 我在下面列出了我的方法。

    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);
        }

There are two issues here: 这里有两个问题:

The first is that you are stomping on your frequencies array with the frequencies[j] += frequencies[j] line on each and every sample. 第一个是您在每个样本上都使用frequencies[j] += frequencies[j]线踩踏频率阵列。 Assume frequencies[0] == 100 . 假设frequencies[0] == 100 Before you generate the first sample it is going to change to 200. Even if the length of the frequencies array was only 1 then this is not going to produce a sine wave. 在生成第一个样本之前,它将变为200。即使频率数组的长度仅为1,也不会产生正弦波。

Issue number two is that your concept of combining multiple frequencies is wrong. 第二个问题是您组合多个频率的概念是错误的。 Assume the frequencies array has two elements of 100 and 200. If the first problem were fixed you would actually compute a single sine at 300 Hz. 假设频率数组有两个元素100和200。如果解决了第一个问题,您实际上将计算出一个300 Hz的正弦。 That's because you are adding them together at the wrong level so you are computing 'sin(2*pi i (100+200)/2) which is sin(2*pi*i*300/2) . 那是因为您以错误的级别将它们加在一起,所以您正在计算的是'sin(2 * pi i (100 + 200)/ 2),即sin(2*pi*i*300/2)

Instead you need to do something like this: 相反,您需要执行以下操作:

 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
 }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM