我正在尝试使用Java生成蜂鸣声.我在SO上找到了这个答案.
我正在使用该答案的代码来产生哔哔声.代码是:
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(); } public static void main(String[] args) throws Exception { Sound.tone(15000,1000); } }
在该main
方法中,我Sound.tone(15000,1000);
用来产生频率为15000Hz的声音来播放1000ms
但是,如果我将其更改为:我可以听到声音:
Sound.tone(1,1000);
,.
Sound.tone(19999,1000);
科学地说,这是不可能的.
在第一种情况下,声音应该是次声的,我不应该能够察觉它.
在第二种情况下,我仍然无法听到声音,因为随着年龄的增长,听觉能力趋于下降,而我这个年龄的人应该只能听到大约16000赫兹的声音.
此外,我听不到:
Sound.tone(0,1000);
(有点像预期的那样)
Sound.tone(20000,1000);
那么,我怎样才能产生某些特定频率的声音?
我在互联网上搜索,但找不到任何关于它的信息.
在此编辑之前给出的答案解释了为什么会发生,但是没有给出我想要的答案.
您遇到的是一种称为混叠的现象.您可能已经在视频中看到了这样的示例,其中旋转轮似乎缓慢旋转或甚至反向旋转.这是因为车轮仅旋转了略多于或小于每个视频帧完整匝数的倍数.同样,如果车轮每帧旋转一个精确的圈数,它将显得静止不动.这称为混叠的原因是无法知道它实际旋转了多少圈.
音频采样具有相同的伪像,被称为奈奎斯特采样定理,它基本上表明您只能表示高达采样率(奈奎斯特频率)一半的频率.超出此频率,音调开始向下折叠(例如向后转).
在8kHz采样率下,0Hz至4kHz的频率将恢复正常(4 kHz正弦波每个周期将有2个样本).超过4kHz时,频率将开始向后折叠,以便听到4001Hz为3999,5000Hz为3000Hz,最终为8000Hz为0Hz(因此为静音).超过8kHz时,它将再次开始折叠,使8001Hz为1Hz,依此类推.
关键的一点是,您需要选择一个至少是您计划播放的最高频率的两倍的采样率.