You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Java中播放指定频率声音?高频播放异常求助

问题根源分析

你遇到的问题是**混叠(Aliasing)**导致的,核心原因在代码的两个关键参数上:

  1. 采样率过低:代码中SAMPLE_RATE = 8000f,根据奈奎斯特采样定理,音频系统能准确还原的最高频率是采样率的一半,也就是4000Hz。当你尝试播放15000-30000Hz的高频时,这些信号会被折叠成低于4000Hz的低频,也就是你听到的“随机可听见音调”。
  2. 位深限制:8位的位深会带来较大的量化噪声,虽然不是导致混叠的直接原因,但会影响高频信号的还原精度。

另外,循环次数的计算i < msecs*8是硬编码的,只适配8000Hz采样率,换成其他采样率时会出错,需要改成基于采样率的动态计算。

修复后的代码

以下是调整后的Sound类,解决了上述问题:

import javax.sound.sampled.*;

public class Sound { 
    // 采样率设为96000Hz,足以覆盖30000Hz的高频(96000/2=48000Hz)
    public static float SAMPLE_RATE = 96000f;
    // 位深设为16位,提升音质
    public static int BIT_DEPTH = 16;

    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 {
        // 计算总样本数:采样率 * 毫秒数 / 1000
        long totalSamples = (long)(SAMPLE_RATE * msecs / 1000);
        // 16位音频用2字节存储一个样本
        byte[] buf = new byte[2];
        // 配置音频格式:采样率、位深、单声道、有符号、小端字节序
        AudioFormat af = new AudioFormat(SAMPLE_RATE, BIT_DEPTH, 1, true, false);     
        SourceDataLine sdl = AudioSystem.getSourceDataLine(af);
        sdl.open(af);
        sdl.start();

        for (long i=0; i < totalSamples; i++) {
            double angle = i / (SAMPLE_RATE / hz) * 2.0 * Math.PI;
            // 生成16位的正弦波样本(范围-32768到32767)
            short sample = (short)(Math.sin(angle) * 32767.0 * vol);
            // 将short转换为小端字节序的byte数组
            buf[0] = (byte)(sample & 0xFF);
            buf[1] = (byte)((sample >> 8) & 0xFF);
            sdl.write(buf, 0, 2);
        }

        sdl.drain();
        sdl.stop();
        sdl.close();
    }
}
额外注意事项
  • 并非所有音频设备都支持96000Hz的高采样率,如果运行报错,可以尝试将采样率降到48000Hz(同样能覆盖24000Hz的高频,接近你需要的30000Hz)。
  • 人类听觉上限通常在16000-20000Hz(随年龄增长下降),所以30000Hz的声音大部分人可能根本听不到,但修复后的代码会准确生成对应频率的信号。
  • 如果需要更稳定的高频播放,可以考虑使用Java的FloatControl来调整音量,避免直接计算样本时的溢出问题。

内容的提问来源于stack exchange,提问作者Ephestion

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 19:17:31