如何在java中播放已知频率的声音

How to play a known frequency sound in java

提问人:Ephestion 提问时间:8/22/2023 最后编辑:SamEphestion 更新时间:8/22/2023 访问量:60

问:

我在这里或网上找到了一段代码,并一直在使用它来播放声音。问题在于,对于超出人类范围甚至更高人类范围的频率,似乎将声音频率替换为可听频率。换句话说,它不是非常准确的音高频率,而是突然播放我们可以听到的随机音调。我感兴趣的范围是 15,000Hz 到 30,000Hz。我不完全理解这段代码,希望得到一些帮助。

public static void tone(int hz, int msecs, double vol) throws LineUnavailableException {        
    byte[] buf = new byte[1];
    AudioFormat af = new AudioFormat(SAMPLE_RATE,8,1,true,false);     
    SourceDataLine sdl = AudioSystem.getSourceDataLine(af);
    sdl.open(af);
    sdl.start();
    for (int i=0; i < msecs*8; i++) {
          double angle = i / (SAMPLE_RATE / hz) * 2.0 * Math.PI;
          buf[0] = (byte)(Math.sin(angle) * 127.0 * vol);
          sdl.write(buf,0,1);
    }
    sdl.drain();
    sdl.stop();
    sdl.close();
}

我所做的是制作一个带有按钮的表单,它调用一个声音类

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
    // TODO add your handling code here:
    try{     
       Sound.tone(15000,2000,1);
    }catch(Exception ex){System.out.println(ex);}   
}        

声音类代码为:

import javax.sound.sampled.*;

public class Sound { 
    public static float SAMPLE_RATE = 8000f;

    public static void tone(int hz, int msecs) throws LineUnavailableException {
        tone(hz, msecs, 1.0);
    }

    public static void tone(int hz, int msecs, double vol) throws LineUnavailableException {
    
        byte[] buf = new byte[1];
        AudioFormat af = new AudioFormat(SAMPLE_RATE,8,1,true,false);     
        SourceDataLine sdl = AudioSystem.getSourceDataLine(af);
        sdl.open(af);
        sdl.start();
        for (int i=0; i < msecs*8; i++) {
            double angle = i / (SAMPLE_RATE / hz) * 2.0 * Math.PI;
            buf[0] = (byte)(Math.sin(angle) * 127.0 * vol);
            sdl.write(buf,0,1);
        }
        sdl.drain();
        sdl.stop();
        sdl.close();
    }
}
Java Spring JavaSound

评论

0赞 Andy Turner 8/22/2023
“换句话说,它不是非常准确的音高频率,而是突然播放我们可以听到的随机音调”你知道 en.wikipedia.org/wiki/Aliasing 吗?
1赞 tgdavies 8/22/2023
正如@AndyTurner所说,在 8KHz 采样率下,您只能再现 4KHz 以下的频率。
0赞 greg-449 8/22/2023
另请注意,许多扬声器不会设计为输出如此高的频率。
1赞 Phil Freihofner 8/22/2023
正如 @AndyTurner 所说,问题肯定是混叠。如果您选择 44100 的采样率,您可以更高。这将使你达到22K以上,这对我们人类来说是听不到的。44100 FPS 非常常见,如果还有 16 位分辨率而不是 8 位分辨率,以及立体声而不是单声道,则称为“CD 质量”。Java 支持此格式。

答: 暂无答案