Android Kotlin实现WAV音频指纹相似度对比问题求助
Android英语听读练习应用的音频指纹匹配问题
我正在开发一款“听读练习”类英语学习应用,需要对比Android文本转语音(TTS)生成的短句WAV文件与用户通过OmRecorder库录制的同一句WAV文件的指纹相似度,返回匹配分数。由于FFT实现复杂且耗时,希望借助现成库完成,目前试用musicg库但结果异常,始终返回0或固定值0.047。
调试时已确认两个音频参数一致:
音频文件参数
文件1(TTS生成)参数
chunkId: RIFF chunkSize: 53286 format: WAVE subChunk1Id: fmt subChunk1Size: 16 audioFormat: 1 channels: 1 sampleRate: 10240 byteRate: 20480 blockAlign: 2 bitsPerSample: 16 subChunk2Id: data subChunk2Size: 53250 length: 2.6000977
文件2(用户录制)参数
chunkId: RIFF chunkSize: 24378 format: WAVE subChunk1Id: fmt subChunk1Size: 16 audioFormat: 1 channels: 1 sampleRate: 10240 byteRate: 20480 blockAlign: 2 bitsPerSample: 16 subChunk2Id: data subChunk2Size: 24342 length: 1.1885742
指纹对比Kotlin代码
val w1 = Wave(this.cacheDir.toString() + "/file1.wav") val w2 = Wave(this.cacheDir.toString() + "/file2.wav") println("Wave 1 = " + w1.waveHeader) println("Wave 2 = " + w2.waveHeader) val fpsc1: FingerprintSimilarity = w1.getFingerprintSimilarity(w2) val scorec = fpsc1.score val simc = fpsc1.similarity (findViewById<View>(R.id.tvScore) as TextView).text = scorec.toString() (findViewById<View>(R.id.tvSimilarity) as TextView).text = simc.toString()
OmRecorder录制代码片段
private var recorder: Recorder? = null private fun startRecording() { if (ActivityCompat.checkSelfPermission( this, Manifest.permission.RECORD_AUDIO ) != PackageManager.PERMISSION_GRANTED ) { return } val file: String = this.cacheDir.toString() + "/file2.wav" recorder = OmRecorder.wav( PullTransport.Default( mic() ) { audioChunk -> animateVoice((audioChunk.maxAmplitude() / 200.0).toFloat()) }, File(file) ) recorder!!.startRecording() } private fun mic(): PullableSource { return PullableSource.Default( AudioRecordConfig.Default( MediaRecorder.AudioSource.MIC, AudioFormat.ENCODING_PCM_16BIT, AudioFormat.CHANNEL_IN_MONO, 8000 ) ) } private fun animateVoice(maxPeak: Float) { (findViewById<View>(R.id.microphone) as ImageView).animate().scaleX(1 + maxPeak).scaleY(1 + maxPeak).setDuration(10).start() }
可行解决方案建议
1. 优先解决音频时长对齐问题
从参数看两段音频长度差异明显(2.6s vs 1.19s),musicg的指纹匹配对时长对齐要求极高。可先做对齐处理:
- 对较短的音频补零,使其样本数与长音频一致
- 或手动提取两段音频中对应语句的有效片段,确保时间轴完全匹配后再测试
2. 替换为适配Android的音频特征匹配库
TarsosDSP库
支持Android平台,可提取MFCC、频谱特征,手动实现余弦相似度或动态时间规整(DTW)对比,性能适配移动端场景,适合短句语音的特征匹配。
结合Google ML Kit的混合方案
既然是英语短句,可采用“语音转文本+语音特征辅助”的混合评分:
- 用ML Kit语音识别将两段音频转成文本,计算文本匹配度
- 额外提取基频、短时能量等时域特征,综合得到最终发音匹配分数
3. 实现轻量级自定义匹配逻辑
如果不想依赖第三方库,可实现简单的时域特征对比:
- 提取两段音频的短时能量、过零率序列,用DTW算法计算序列距离(DTW专门处理时长不同的序列匹配)
- 优化计算量,只取关键帧特征,避免全序列遍历
4. 排查musicg库参数问题
检查musicg版本兼容性,尝试手动调整FingerprintConfiguration的窗口大小、步长等参数,默认参数可能不适合短句语音的指纹提取。
内容的提问来源于stack exchange,提问作者Diego Perez
相关产品推荐
相关产品推荐

