【问题标题】:Retrieving frequency ranges from android visualizer FFT从 android Visualizer FFT 检索频率范围
【发布时间】:2022-07-23 03:19:20
【问题描述】:

我目前正在尝试做一些与以下问题非常相似(或可能相同)的事情:

Getting variable frequency ranges with androids visualizer class

但是,所选答案有一些错误,而且我根本不是 DSP/音频专家,我正在学习中。

我的目标是将我从 Android Visualizer 类获得的 FFT 分解为频带。具体来说,这些乐队:

  1. 0Hz - 400Hz
  2. 400Hz - 900Hz
  3. 900Hz - 1500Hz
  4. 1500Hz - 2300Hz
  5. 2300Hz - 3400Hz
  6. 3400Hz - 5000Hz
  7. 5000Hz - 7300Hz
  8. 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 是一个 ListIntProgressions 去 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


    【解决方案1】:

    我的代码的问题非常愚蠢...我在 milihertz 中使用 samplingRate...该公式期望采样率以赫兹为单位。

    samplingRate 除以 1000 可以解决问题。

    这会变成:

       val samplingRateInHz = samplingRate / 1000
       val frequencyOrdinalRanges: List<IntRange> =
            targetEndpoints.zipWithNext { a, b ->
              val startOrdinal = 1 + (captureSize * a / samplingRateInHz).toInt()
              val endOrdinal = (captureSize * b / samplingRateInHz).toInt()
              startOrdinal..endOrdinal
            }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-12
      • 2014-05-04
      • 2011-05-04
      • 2015-07-16
      • 2012-06-10
      • 1970-01-01
      相关资源
      最近更新 更多