Java 应用处理语音,难点往往不只是调用识别模型:录音格式、静音片段、多人对话、唤醒词和音频质量都可能影响最终结果。mica-voice 1.0.2 基于已发布到 Maven Central 的 mica-sherpa-onnx 全平台 fat jar,为这些能力提供统一封装,并提供纯 Java 门面、Spring Boot Starter 等接入方式。
七类能力,解决的是不同问题
mica-voice 覆盖 ASR(语音识别)、TTS(语音合成)、声纹识别、VAD(语音活动检测)、说话人分离、关键词唤醒(KWS)和音频降噪。它们不必全部出现在同一条请求链路里。
例如,会议转写可以关注「降噪 → VAD → 说话人分离 → ASR」;语音助手则可能从「关键词唤醒 → VAD → ASR → 业务处理 → TTS」起步。声纹识别用于判断声音身份,不等同于把一段多人录音拆分并标记说话人的说话人分离。设计接口时,把这两件事分开,后续才容易调整模型和权限策略。
统一封装的价值在于减少 Java 侧对底层推理组件的重复适配;它不会自动消除模型文件、音频格式、延迟和部署环境带来的差异。选择纯 Java 门面还是框架 Starter,应以现有应用结构为准。
接入前,先检查音频输入
来源摘要没有给出 mica-voice 的具体 Maven 坐标或方法签名,下面不猜测它的调用 API。可以先运行一个只依赖 JDK 的输入检查器:它验证 WAV 是否为单声道、16 kHz、16-bit 小端 PCM,并按 20 毫秒输出每帧的 RMS。这只是接入前的格式与能量检查,不是 mica-voice 的 VAD 实现。实际模型接受什么格式,应以所选模型及项目文档为准。
将以下内容保存为 VoiceInputCheck.java,使用 JDK 17 或更新版本运行:
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import java.io.File;
public class VoiceInputCheck {
public static void main(String[] args) throws Exception {
if (args.length != 1) {
System.err.println("用法: java VoiceInputCheck.java input.wav");
System.exit(2);
}
try (AudioInputStream stream = AudioSystem.getAudioInputStream(new File(args[0]))) {
AudioFormat format = stream.getFormat();
boolean supported = format.getEncoding().equals(AudioFormat.Encoding.PCM_SIGNED)
&& format.getSampleRate() == 16000f
&& format.getChannels() == 1
&& format.getSampleSizeInBits() == 16
&& !format.isBigEndian();
if (!supported) {
throw new IllegalArgumentException("示例仅接受 16 kHz、单声道、16-bit 小端 PCM WAV;实际模型要求请另行核对。收到: " + format);
}
byte[] audio = stream.readAllBytes();
int bytesPerFrame = 320 * 2; // 20 ms × 16000 samples/s × 2 bytes/sample
System.out.println("音频字节数: " + audio.length);
for (int offset = 0, index = 0; offset + bytesPerFrame <= audio.length;
offset += bytesPerFrame, index++) {
double sum = 0;
for (int i = offset; i < offset + bytesPerFrame; i += 2) {
int sample = (short) ((audio[i] & 0xff) | (audio[i + 1] << 8));
double normalized = sample / 32768.0;
sum += normalized * normalized;
}
System.out.printf("frame=%d rms=%.4f%n", index, Math.sqrt(sum / 320));
}
}
}
}
java VoiceInputCheck.java input.wav
运行前把 input.wav 换成自己的录音。若格式不符,应在进入实际推理链路前完成转换;不要把示例中的 RMS 阈值随意当成 VAD,也不要据此判断说话人身份。
从单项能力开始,而不是一次接满
更稳妥的试点是先选一条可测量的链路。例如做语音转写时,先准备一批包含静音、噪声和多人交谈的录音,验证输入格式与 ASR 输出;随后加入 VAD,比较处理时长和漏识别情况;确实需要区分发言人时,再评估说话人分离。需要在 Java 服务中接入时,再根据项目实际依赖与文档选择纯 Java 门面或 Spring Boot Starter。
上线检查可以聚焦四件事:模型文件如何分发,目标操作系统与架构能否运行,长音频的内存和延迟是否可接受,以及录音和声纹数据如何获得授权并安全保存。「一行代码接入」可以缩短接口调用代码,但生产可用性仍要靠真实音频和目标部署环境验证。