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

Android如何播放指定频率及时长的蜂鸣音

Android 播放指定频率、时长蜂鸣音实现方案(基于AudioTrack)

实现原理

蜂鸣音本质是固定频率的正弦波音频,我们可以手动生成对应频率的16位PCM音频数据,再通过AudioTrack API直接播放原始PCM数据即可实现需求。

核心参数说明

  • 采样率:通用取值44100Hz,是绝大多数设备支持的标准采样率
  • 采样位深:选16位(AudioFormat.ENCODING_PCM_16BIT),兼容性最好,取值范围为-32768~32767
  • 声道:单声道(AudioFormat.CHANNEL_OUT_MONO)即可满足蜂鸣音需求,数据量更小

代码实现示例

首先封装一个通用的蜂鸣音播放工具方法:

import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;

public class BeepPlayer {
    // 通用采样率
    private static final int SAMPLE_RATE = 44100;

    /**
     * 播放指定频率和时长的蜂鸣音
     * @param frequency 蜂鸣音频率,单位Hz,比如2000就是2kHz的蜂鸣音
     * @param durationMs 播放时长,单位毫秒
     */
    public static void playBeep(int frequency, int durationMs) {
        // 计算采样点总数
        int sampleCount = SAMPLE_RATE * durationMs / 1000;
        // 生成16位PCM正弦波数据
        short[] pcmData = new short[sampleCount];
        for (int i = 0; i < sampleCount; i++) {
            // 正弦波公式,幅值取最大的32767保证音量最大
            double sample = Math.sin(2 * Math.PI * frequency * i / SAMPLE_RATE) * 32767;
            pcmData[i] = (short) sample;
        }

        // 计算AudioTrack所需的最小缓冲区大小
        int bufferSize = AudioTrack.getMinBufferSize(
                SAMPLE_RATE,
                AudioFormat.CHANNEL_OUT_MONO,
                AudioFormat.ENCODING_PCM_16BIT
        );
        // 初始化AudioTrack,使用静态模式一次性写入数据
        AudioTrack audioTrack = new AudioTrack(
                AudioManager.STREAM_MUSIC,
                SAMPLE_RATE,
                AudioFormat.CHANNEL_OUT_MONO,
                AudioFormat.ENCODING_PCM_16BIT,
                Math.max(bufferSize, pcmData.length * 2), // 16位每个采样占2字节
                AudioTrack.MODE_STATIC
        );

        // 写入PCM数据
        audioTrack.write(pcmData, 0, sampleCount);
        // 开始播放
        audioTrack.play();

        // 播放完成后释放资源
        audioTrack.setPlaybackPositionUpdateListener(new AudioTrack.OnPlaybackPositionUpdateListener() {
            @Override
            public void onMarkerReached(AudioTrack track) {
                track.release();
            }

            @Override
            public void onPeriodicNotification(AudioTrack track) {
                // 无需处理
            }
        });
        // 设置播放完成标记
        audioTrack.setNotificationMarkerPosition(sampleCount);
    }
}

调用方式

直接在子线程调用工具方法即可:

// 播放2000Hz、500毫秒的蜂鸣音
new Thread(() -> BeepPlayer.playBeep(2000, 500)).start();

注意事项

  • 不要在主线程直接调用播放方法,避免PCM数据生成逻辑阻塞UI
  • 如果需要循环播放蜂鸣音,可将AudioTrack的模式改为MODE_STREAM,循环写入PCM数据即可
  • 不需要额外申请音频权限,只要应用允许播放媒体音量即可正常工作

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.12 21:54:03