Как реализовать beat‑детекцию в Android‑приложении
В Android‑приложении можно использовать TarsosDSP, Essentia или FFT‑подход для beat‑детекции, а затем вызывать VibrationEffect и обновлять UI‑элементы.
I want to build an Android app that listens to a music track, detects each beat—say, in a waltz—and then triggers a vibration and a visual cue for every beat to help deaf users. What techniques or libraries can I use for beat detection, and how should I implement the vibration and display logic?
A beat‑tracking app for Android can be built by combining a real‑time audio analysis library (e.g., TarsosDSP, Essentia, or a lightweight FFT‑based approach) with Android’s vibration API (VibrationEffect) and a simple UI callback. The audio stream is analyzed frame‑by‑frame, onsets are detected, and a beat‑estimator produces timestamps that trigger vibrate() and visual updates on the main thread.
Содержание
- Выбор подхода к детекции барабана
- Либрари для обработки аудио
- Интеграция в Android‑приложение
- Вибрация и визуальный отклик
- Оптимизация производительности и батареи
- Полный пример кода
- Дополнительные ресурсы
Выбор подхода к детекции барабана
Beat detection обычно делится на два этапа:
- Определение onsets – моменты, когда начинается новый музыкальный сегмент.
- Синтез beat‑tracker – интерпретация onsets в ритмическую структуру (бит‑план).
Для простого приложения подойдёт onset‑based подход, потому что он более лёгок в реализации и быстрее. Если нужна более точная синхронизация с музыкой, можно использовать beat‑root‑подобные алгоритмы, которые анализируют временные паттерны.
Либрари для обработки аудио
| Библиотека | Ключевые возможности | Пример использования |
|---|---|---|
| TarsosDSP | Onset detection, BeatRoot‑style beat tracking, MFCC, Constant‑Q | OnsetDetector + BeatTrack |
| Essentia (Java‑порт) | Расширенные алгоритмы аудио‑анализа, включая beat‑tracking | BeatTracker |
| FFmpeg + aubio (JNI) | Быстрый DSP, аудио‑фичи, beat‑tracker | aubio::tempo |
| TwelveTone (коробковая реализация) | Минимальный набор для onsets | TwelveToneOnsetDetector |
TarsosDSP считается самым простым для Android, так как не требует нативных библиотек и уже включает PercussionOnsetDetector, который хорошо работает с ритмичными треками.
Согласно GitHub‑репозиторию TarsosDSP, библиотека поддерживает как спектральные, так и временные методы детекции.
Интеграция в Android‑приложение
-
Получение аудио‑стрима
- Для записи с микрофона используйте
AudioRecord. - Для воспроизведения локального файла –
MediaPlayer+AudioTrackс передачей PCM‑данных вTarsosDSP.
- Для записи с микрофона используйте
-
Создание потока обработки
kotlinval dispatcher = AudioDispatcherFactory.fromDefaultMicrophone(44100, 1024, 512) val onsetDetector = PercussionOnsetDetector(44100, 1024) { timestamp -> // callback on each detected onset } dispatcher.addAudioProcessor(onsetDetector) Thread(dispatcher, "Audio Dispatcher").start() -
Beat‑tracker
kotlinval beatTracker = BeatTrack(44100) dispatcher.addAudioProcessor(beatTracker) beatTracker.setOnBeatListener { beatTime -> // UI update + vibration } -
Передача сигнала в UI‑поток
kotlinrunOnUiThread { triggerVibration() updateVisualCue() }
Вибрация и визуальный отклик
Вибрация
private fun triggerVibration() {
val vibrator = getSystemService(Context.VIBRATOR_SERVICE) as? Vibrator ?: return
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val effect = VibrationEffect.createOneShot(50, VibrationEffect.DEFAULT_AMPLITUDE)
vibrator.vibrate(effect)
} else {
@Suppress("DEPRECATION")
vibrator.vibrate(50) // deprecated after API 26
}
}
- Частота: 50 – 100 мс обычно достаточно для восприятия, но можно подстроить под конкретный ритм.
- Параметры:
VibrationEffectпозволяет задавать амплитуду и сложные паттерны (waveform).
Визуальный сигнал
private fun updateVisualCue() {
val pulseView = findViewById<View>(R.id.pulseView)
pulseView.animate()
.scaleX(1.5f).scaleY(1.5f)
.setDuration(100)
.withEndAction { pulseView.scaleX = 1f; pulseView.scaleY = 1f }
.start()
}
- Используйте простую анимацию увеличения/сжатия или меняющийся цвет для мгновенного визуального отклика.
- Для более сложных эффектов можно подключить
CanvasилиSurfaceView.
Оптимизация производительности и батареи
| Мера | Зачем | Как реализовать |
|---|---|---|
| Использовать AudioRecord с объёмом 1024 | Снижает задержку до ~23 мс | AudioDispatcherFactory.fromDefaultMicrophone(44100, 1024, 512) |
| Параллельный поток для DSP | Не блокирует UI | Thread(dispatcher) |
| Ограничить частоту обновлений UI | Сохраняет ресурсы | Handler.postDelayed с 100 мс |
| Выключать микрофон после завершения | Экономит батарею | audioRecord.stop() |
Примечание
Если приложение будет работать в фоновом режиме, убедитесь, что вы запрашиваете разрешения RECORD_AUDIO и VIBRATE, а также используете ForegroundService для постоянной аудио‑обработки.
Полный пример кода
class BeatVibratorActivity : AppCompatActivity() {
private lateinit var dispatcher: AudioDispatcher
private val sampleRate = 44100
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_beat_vibrator)
startBeatDetection()
}
private fun startBeatDetection() {
dispatcher = AudioDispatcherFactory.fromDefaultMicrophone(sampleRate, 1024, 512)
val beatTracker = BeatTrack(sampleRate).apply {
setOnBeatListener { beatTime ->
runOnUiThread {
triggerVibration()
updateVisualCue()
}
}
}
dispatcher.addAudioProcessor(beatTracker)
Thread(dispatcher, "Audio Dispatcher").start()
}
private fun triggerVibration() {
val vibrator = getSystemService(Context.VIBRATOR_SERVICE) as? Vibrator ?: return
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val effect = VibrationEffect.createOneShot(50, VibrationEffect.DEFAULT_AMPLITUDE)
vibrator.vibrate(effect)
} else {
@Suppress("DEPRECATION")
vibrator.vibrate(50)
}
}
private fun updateVisualCue() {
val pulse = findViewById<View>(R.id.pulseView)
pulse.animate()
.scaleX(1.4f).scaleY(1.4f)
.setDuration(70)
.withEndAction { pulse.scaleX = 1f; pulse.scaleY = 1f }
.start()
}
override fun onDestroy() {
dispatcher.stop()
super.onDestroy()
}
}
Итоги:
- TarsosDSP обеспечивает быстрый и надёжный алгоритм детекции beat‑a.
- Android VibrationEffect позволяет создавать точные вибрационные сигналы.
- Синхронизация callback‑ов с UI‑потоком гарантирует мгновенный визуальный отклик.
Дополнительные ресурсы
- TarsosDSP GitHub – исходный код и примеры.
- Android Developers – Vibrator – официальная документация.
- Essentia – Beat Tracker – описание алгоритма.
- FFmpeg + Aubio – Tempo Detection – быстрый нативный вариант.
Эти материалы помогут вам быстро приступить к разработке, настроить параметры под ваш музыкальный материал и предоставить инклюзивный ритмический опыт для глухих пользователей.