Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/378.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java蜂鸣音:产生某些特定频率的声音_Java_Audio_Javasound_Beep - Fatal编程技术网

Java蜂鸣音:产生某些特定频率的声音

Java蜂鸣音:产生某些特定频率的声音,java,audio,javasound,beep,Java,Audio,Javasound,Beep,我正在尝试使用Java生成beep。我找到了答案 我用那个答案的密码来发出嘟嘟声。代码是: 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,

我正在尝试使用Java生成beep。我找到了答案

我用那个答案的密码来发出嘟嘟声。代码是:

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); 
    }
}
import javax.sound.sampled.*;
公共级音响
{
公共静态浮动采样率=8000f;
公共静态无效音调(整数赫兹,整数毫秒)
抛出LineUnavailableException
{
音调(赫兹,毫秒,1.0);
}
公共静态无效音(整数赫兹,整数毫秒,双音量)
抛出LineUnavailableException
{
字节[]buf=新字节[1];
AudioFormat af=新的AudioFormat(采样率,8,1,真,假);
SourceDataLine sdl=AudioSystem.getSourceDataLine(af);
开放式(af);
sdl.start();
对于(int i=0;i
main
方法中,我使用
Sound.tone(150001000)产生频率15000 Hz的声音播放1000 ms

但是,如果我将其更改为:

  • Sound.tone(11000)
  • Sound.tone(199991000)
从科学上讲,这是不可能的

  • 在第一种情况下,声音应该是次声,而我应该无法感知它
  • 在第二种情况下,我应该仍然听不到声音,因为随着年龄的增长,听力会下降,而与我年龄相仿的人应该只能听到大约16000 Hz的声音
此外,我听不到:

  • Sound.tone(01000)(有点像预期的那样)
  • Sound.tone(200001000)
那么,我怎样才能产生某些特定频率的声音呢?
我在网上搜索了一下,但没有找到任何关于它的信息

此编辑之前给出的答案解释了为什么会出现这种情况,但没有给出我想要的答案。

刚刚在我的扬声器前面用吉他调谐器重新检查过-您提供的方法对于低频是准确的

但是,如果声音太低,你可能会听到泛音或“口吃”声,因为扬声器的次声效果不太好(至少我听到了)

频率上,您的代码计算得不太好-采样率为每秒8000个采样,您将快速为更高频率创建“无效”音调-正弦波振荡将意外地与采样率对齐。所以你会得到一些你能听到的高频(基本上是因为你的样本总是碰到一些非零值)或者听不到(你所有的样本都发生在波穿过零点的时候)

检查此环路(扬声器打开时):

绝对沉默,而且

  Sound.tone(8001,500);

产生一种非常时髦的声音。

您所经历的是一种称为锯齿的现象。您可能在视频中看到过这样的例子,其中一个旋转的轮子似乎旋转缓慢,甚至是反向旋转。这是因为轮子旋转的次数仅略多于或少于每个视频帧完整旋转次数的倍数。同样,如果车轮每帧旋转的圈数精确,它将显示为静止。这称为锯齿的原因是无法知道它实际旋转了多少圈

音频采样具有相同的伪影,被称为奈奎斯特采样定理,该定理基本上表明您只能表示采样率(奈奎斯特频率)的一半以下的频率。超过该频率时,音调开始向下折叠(例如向后)

在8kHz采样率下,从0Hz到4kHz的频率将很好地回放(4kHz正弦波每个周期将有2个采样)。超过4kHz时,频率将开始向后折叠,这样4001Hz将听到3999,5000Hz将听到3000Hz,最终8000Hz将听到0Hz(因此静音).超过8kHz时,它将再次开始折叠,以便8001Hz为1Hz,依此类推


关键在于你需要选择一个至少是你计划播放的最高频率两倍的采样率。

但我当然听不到次声,根据这个程序我显然可以听到次声。@SureshAtta我建议用耳朵代替眼睛。@Arc676我想你误解了我的问题。如果计算机不是人我被设计成产生红外线/超声波,那么我如何能用这个程序听到它。我的意思是说,如果我写
sound.tone(101000),我能听到声音
,应该是次声。可能你的硬件不能产生如此低或如此高的频率,也不会引发任何异常,相反,它会尝试播放尽可能接近你传递给硬件的值。这些值可能是人耳可闻的。使用麦克风并对t进行频率分析如何他录制了声音。如果你手边有一部智能手机,你最喜欢的应用商店里应该有一款应用。这取决于你想用它做什么。20-3000赫兹的频率范围可能足够提醒用户了。对于更高的采样率,尽管角度计算似乎也无效。你必须多考虑一下这一点。怎么办简,你能从正弦波中得到泛音吗?我在计算中没有看到任何东西会导致播放开始/停止(口吃)。即使使用整数除法,角度的前进看起来也会很平滑。如果我继续留在这个线程中,我可能会成为一名声音工程师!但采样率达到40000仍然不能解决问题。我可以
  Sound.tone(8000,500);   
  Sound.tone(8001,500);