首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用TarsosDSP修复Kotlin中的“抖动”基音检测

使用TarsosDSP修复Kotlin中的“抖动”基音检测
EN

Stack Overflow用户
提问于 2020-11-11 08:15:41
回答 1查看 143关注 0票数 1

我正在写一个乐器调谐器应用程序(现在从吉他开始)。对于基音检测,我使用的是TarsosDSP。它确实正确地检测到了音高,但它是相当不稳定的-例如,我将在我的吉他上敲击(正确调整的)D弦,它正确地将其识别为D,但过了片刻,它很快就会在一堆随机的音符中循环。我不确定如何最好地解决这个问题。下面是我的代码,它负责检测音高:

代码语言:javascript
复制
val dispatcher: AudioDispatcher = AudioDispatcherFactory.fromDefaultMicrophone(44100, 4096, 3072)
val pdh = PitchDetectionHandler { res, _ ->
            val pitchInHz: Float = res.pitch
            runOnUiThread { processing.closestNote(pitchInHz)}
        }
val pitchProcessor: AudioProcessor =
            PitchProcessor(PitchProcessor.PitchEstimationAlgorithm.FFT_YIN,
                44100F, 4096, pdh)
dispatcher.addAudioProcessor(pitchProcessor)

val audioThread = Thread(dispatcher, "Audio Thread")
        audioThread.start() 

然后,我编写了一个函数,该函数用于检测与当前音高最接近的音符。此外,我试图通过编写一个函数来获得“不那么不稳定”的结果,该函数应该找到以hz为单位的最接近的音调,然后将该结果用于closestNote函数,我认为这样可能会得到更少的不同结果(即使它应该是相同的,我也没有注意到任何差异)。下面是两个函数:

代码语言:javascript
复制
...
private val allNotes = arrayOf("A", "A#", "B", "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#")
private val concertPitch = 440
...
/** detects closest note in A = 440hz with with equal temperament formula:
 * pitch(i) = pitch(0) * 2^(i/12)
 * therefore formula to derive interval between two pitches:
 * i = 12 * log2 * (pitch(i)/pitch(o))
 */

   fun closestNote(pitchInHz: Float) {
        (myCallback as MainActivity).noteSize() //adjusts the font size of note
        if (pitchInHz != -1F) {
            val roundHz = closestPitch(pitchInHz)
            val i = (round(log2(roundHz / concertPitch) * 12)).toInt()
            val closestNote = allNotes[(i % 12 + 12) % 12]
            myCallback?.updateNote(closestNote) // updates note text
        }
    }
    private fun closestPitch(pitchInHz: Float): Float {
        val i = (round(log2(pitchInHz / concertPitch) * 12)).toInt()
        val closestPitch = concertPitch * 2.toDouble().pow(i.toDouble() / 12)
        return closestPitch.toFloat()
    }

你知道怎样才能得到更一致的结果吗?谢谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-11-13 05:17:00

我自己解决了这个问题: TarsosDSP计算每个音符播放的概率。我设置了我的closestNote函数,只在概率大于0.91时更新文本(我发现这个值可以提供“稳定性”,就文本而言,在命中字符串后不会改变,并且仍然可以正确地识别音符,而不会多次命中字符串/太用力,我还用一个未插入插头的、非中空的电吉他进行了测试)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64778670

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档