【发布时间】:2022-07-23 03:19:20
【问题描述】:
我目前正在尝试做一些与以下问题非常相似(或可能相同)的事情:
Getting variable frequency ranges with androids visualizer class
但是,所选答案有一些错误,而且我根本不是 DSP/音频专家,我正在学习中。
我的目标是将我从 Android Visualizer 类获得的 FFT 分解为频带。具体来说,这些乐队:
- 0Hz - 400Hz
- 400Hz - 900Hz
- 900Hz - 1500Hz
- 1500Hz - 2300Hz
- 2300Hz - 3400Hz
- 3400Hz - 5000Hz
- 5000Hz - 7300Hz
- 7300Hz - 12000Hz
我在班级顶部有以下代码:
private val targetEndpoints = listOf(0f, 400f, 900f, 1500f, 2300f, 3400f, 5000f, 7300f, 12000f)
private const val CAPTURE_SIZE = 1024
然后,在我试图在MediaPlayer 中获取当前曲目的频段的方法中:
val mp = mediaPlayer!!
val audioSessionId = mp.getAudioSessionId()
val visualizer: Visualizer = Visualizer(audioSessionId)
val captureSizeRange = Visualizer.getCaptureSizeRange().let { it[0]..it[1] }
val captureSize = CAPTURE_SIZE.coerceIn(captureSizeRange)
val captureRate: Int = Visualizer.getMaxCaptureRate()
val isWaveFormRequested: Boolean = false
val isFFTRequested: Boolean = true
visualizer.setCaptureSize(captureSize)
val frequencyOrdinalRanges: List<IntProgression> =
targetEndpoints.zipWithNext { a, b ->
val startOrdinal = 1 + (captureSize * a / samplingRate).toInt()
val endOrdinal = (captureSize * b / samplingRate).toInt()
startOrdinal downTo endOrdinal
}
现在事情对我来说有点模糊,因为就像我说的,我不是音频专家。
frequencyOrdinalRanges 是一个 List 和 IntProgressions 去 1 -> 0
对于我正在使用的音频文件:
captureSize = 1024
samplingRate = 44100000
有了这些数字和我的频段,几乎可以保证startOrdinal 永远为 1,endOrdinal 永远为 0。
所以我的frequencyOrdinalRanges 看起来像这样:
[1 downTo 0 step 1, 1 downTo 0 step 1, 1 downTo 0 step 1, 1 downTo 0 step 1, 1 downTo 0 step 1, 1 downTo 0 step 1, 1 downTo 0 step 1]
那么我就有了一个捕获率为 20000 毫赫兹的 Listener:
visualizer.setDataCaptureListener(listener, captureRate, isWaveFormRequested, isFFTRequested)
上述调用的值如下:
captureRate = 2000 // in milihertz
isWaveFormRequested = false
isFFTRequested = true
侦听器对象的onFftDataCapture 如下所示:
override fun onFftDataCapture(visualizer: Visualizer, bytes: ByteArray, samplingRate: Int) {
var output = DoubleArray(frequencyOrdinalRanges.size)
for ((i, ordinalRange) in frequencyOrdinalRanges.withIndex()) {
var logMagnitudeSum = 0.0
for (k in ordinalRange) {
val fftIndex = k * 2
val currentByte = bytes[fftIndex].toDouble()
val nextByte = bytes[fftIndex + 1].toDouble()
val hypot = Math.hypot(currentByte, nextByte)
val logHypot = Math.log10(hypot)
logMagnitudeSum += logHypot
val result = (logMagnitudeSum / (ordinalRange.last - ordinalRange.first + 1)).toDouble()
output[i] = result
}
// do something else with output
}
现在onFftDataCapture 面临的问题是这一行:
val hypot = Math.hypot(currentByte, nextByte)
它的计算结果通常为 0,从而使下面的行计算为 -Infinity 并最终给我一个充满 Infinity 值的数组,我无法用它做任何事情。
这让我相信我做错了什么,但我不确定要做什么或如何解决它。
这个答案看起来或多或少是我想要做的,但话又说回来,我不是音频分析方面的专家,所以所有更精细的细节完全让我无法理解。
The way to extract 10-band equalization information from mp3 format
谁能告诉我我做错了什么?或者我错过了什么?
【问题讨论】:
标签: android kotlin audio signal-processing fft