Java播放错误的声音频率

时间:2013-01-09 04:35:12

标签: java audio frequency javasound waveform

我正在编写一个java声音应用程序,它从一个频率线性转换到另一个频率。

当我输入恒定频率(也就是第一个和最后一个频率相同)时,播放正确的频率。

然而,每当两个频率之间的差异大于零时,播放的频率从正确的值开始,但以两倍的速率递增,并以差值的两倍结束。(例如我输入500和1000;频率从500开始,到1500结束。

我原本以为我只是错误地增加频率,但是当我打印频率值时,它会打印我想要的值(例如,我输入500和1000;打印输出从500开始,到1000结束)。

我通过录制输出声音并在频谱图上查看其频率来检查可听频率的值。以下是我的代码的相关简化部分:

import java.lang.Math;
import javax.sound.sampled.*;

public class MainSpeech {

    public static void main(String[] args) throws LineUnavailableException {

        double freq; //  frequency in Hz
        int volume = 30;
        int time = 1; // in seconds
        float sampleRate = 8000.0f; // in Hz
        int numSamples = (int)(sampleRate * time); // # of samples within given time
        byte stream[] = new byte[(int)(sampleRate*1)]; // waveform values

        freq = 700;
        for (int i = 0; i < numSamples; i++) {
            freq += 0.1;
            stream[i] = (byte) (Math.sin(2*Math.PI*i*freq/sampleRate)*volume);
        }

        AudioFormat af = new AudioFormat(sampleRate, 8, 1, true, false);
        SourceDataLine sdl = AudioSystem.getSourceDataLine(af);
        sdl.open(af);
        sdl.start();
        sdl.write(stream, 0, stream.length); // play sound
        sdl.drain();
        sdl.close();
    }
}

在这个简化的片段中,频率应从700开始,并以0.1增加八千倍,以1500的频率结束,打印输出正确显示。然而,可听频率实际上在2300结束。

1 个答案:

答案 0 :(得分:3)

您在此处有错误:

2*Math.PI*i*freq/sampleRate

在这里使用i或freq,但不是两者。你所拥有的不是频率的线性变化,而是二次曲线。如果您希望它的行为如下所述,请使用

2*Math.PI*freq/sampleRate