Build and Maintain Earbud-to-LLM Android App
EarLLM One Build & Maintain covers the Kotlin/Compose Android app connecting Bluetooth earbuds to an LLM via a voice pipeline.
Why it matters
Develop and maintain EarLLM One, an Android application that connects Bluetooth earbuds to an LLM through a voice pipeline, enabling voice-based interaction with AI models.
Outcomes
What it gets done
Develop multi-module Android app using Kotlin and Jetpack Compose.
Implement Bluetooth connectivity for earbud audio input and output.
Integrate Speech-to-Text and Text-to-Speech for voice processing.
Connect to LLM APIs for AI-powered responses.
Manage audio routing and Bluetooth SCO/BLE profiles.
Install
Add it to your toolbox
Run in your project directory:
curl -fsSL https://spark.entire.vc/get/ag-earllm-build | bash Overview
EarLLM One - Build & Maintain
Covers building and maintaining EarLLM One, a Kotlin/Compose Android app that routes Bluetooth earbud voice through an LLM and speaks back the response, including its module layout, verified Bluetooth/audio-routing facts, and voice data flow. Use when working on the EarLLM One project specifically - earbud voice capture, Bluetooth audio routing, or its LLM voice pipeline - not for general Android or voice-app work.
What it does
EarLLM One - Build & Maintain builds, maintains, and extends the EarLLM One Android project: a multi-module Kotlin + Jetpack Compose app that captures voice from Bluetooth earbuds, transcribes it, sends it to an LLM, and speaks the response back. The project lives at C:\Users\renat\earbudllm and is organized into six modules with a clear dependency graph (app depends on voice, bluetooth, and llm; voice depends on audio; all depend on core-logging): core-logging for structured logging and performance tracking, bluetooth for BT discovery/pairing/A2DP/HFP profiles, audio for SCO/BLE audio routing and headset button capture, voice for STT (SpeechRecognizer plus a Vosk stub), TTS, and the pipeline itself, llm for the LLM client interface with stub and OpenAI-compatible implementations, and app for the UI, ViewModel, foreground service, and Compose screens.
The build targets minSdk 26 / targetSdk 34 / compileSdk 34 with AGP 8.2.2, Kotlin 1.9.22, Gradle 8.5, and Compose BOM 2024.02.00, and is validated against a specific hardware pair: a Samsung Galaxy S24 Ultra (Android 14, One UI 6.1) and Xiaomi Redmi Buds 6 Pro (BT 5.3, A2DP/HFP/AVRCP, ANC, LDAC). It documents seven critical, verified technical facts that must be treated as ground truth: Bluetooth SCO is capped at 8kHz mono (16kHz mSBC on some devices) while BLE Audio supports up to 32kHz stereo and should be preferred when available; startBluetoothSco() is deprecated since Android 12 in favor of AudioManager.setCommunicationDevice()/clearCommunicationDevice() (both paths are already implemented in AudioRouteController.kt); Samsung One UI 7/8 has a known HFP corruption bug where A2DP playback corrupts the SCO link, handled via silence detection and fallback to the phone mic; Redmi Buds 6 Pro tap controls must be set to "Default" (Play/Pause) in the Xiaomi Earbuds app or button events never reach Android; Android 14+ requires the FOREGROUND_SERVICE_MICROPHONE permission and foregroundServiceType="microphone", with RECORD_AUDIO granted before startForeground(); the VOICE_COMMUNICATION audio source enables acoustic echo cancellation to stop TTS output feeding back into the STT mic; and playback (A2DP) and recording (SCO) must never run simultaneously - the correct sequence is stop playback, switch to HFP, record, switch back to A2DP, then play the response.
The voice data flow runs: headset button tap to MediaSession (HeadsetButtonController) to TapAction.RECORD_TOGGLE to VoicePipeline.toggleRecording() to VoiceCaptureController capturing 16kHz mono PCM, then SpeechToTextController.transcribe(), LlmClient.chat(), TextToSpeechController.speak(), and audio output via A2DP. For adding a feature: identify the affected module(s), read existing code first, expose state via the MutableStateFlow/StateFlow pattern, update MainViewModel.kt for UI integration, add unit tests under the module's src/test/, and update docs if behavior changes. Notes per area: audio capture (VoiceCaptureController.kt) records 16kHz mono PCM, uses hex byte values for WAV headers to avoid shell-quoting issues, and computes the VU meter via RMS to dB to a normalized 0-1 range with buffer size getMinBufferSize().coerceAtLeast(4096); Bluetooth (BluetoothController.kt) detects earbuds by name heuristics ("buds", "earbuds", "tws", "pods", "ear") and must handle both Classic and BLE Audio paths; the LLM layer keeps LlmClient.kt generic, uses StubLlmClient.kt (500ms simulated delay) for offline testing, RealLlmClient.kt with OkHttp for OpenAI-compatible APIs, and stores API keys in SecureTokenStore.kt via EncryptedSharedPreferences.
Build artifacts are regenerated with a PowerShell Compress-Archive command producing EarLLM_One_v1.0.zip; tests run via ./gradlew test --stacktrace (unit) and ./gradlew connectedAndroidTest (instrumented, device required). The Phase 2 roadmap covers real-time streaming voice conversation, a smart assistant that categorizes speech into meetings/shopping lists/memos/emails, Vosk offline STT integration (currently stubbed), wake-word detection to avoid holding SCO open continuously, and streaming TTS (noting Android's built-in TTS does not support streaming). A reference table compares STT engines: Vosk small-en (40MB, ~10% WER, streaming, best for real-time mobile), Vosk lgraph (128MB, ~8% WER, streaming, better accuracy), Whisper tiny (40MB, ~10-12% WER, batch only, best for post-utterance polish), and Android SpeechRecognizer (0MB, variable accuracy, streaming, online with no extra deps).
When to use - and when NOT to
Use this skill when the user mentions "earllm", "earbudllm", "earbud app", "voice pipeline kotlin", "bluetooth audio android", or "sco microphone". Do not use it for tasks unrelated to the EarLLM One build, when a simpler and more specific tool can handle the request, or when the user needs general-purpose assistance without this project's domain expertise. Provide clear, specific project context, review all suggestions before applying them to production code, and combine with complementary skills for a fuller picture. Do not treat the output as a substitute for environment-specific validation, testing, or expert review, and stop to ask for clarification if required inputs, permissions, safety boundaries, or success criteria are missing.
Who it's for
The developer(s) building and maintaining the EarLLM One Android app - a Kotlin/Compose Bluetooth-earbuds-to-LLM voice assistant - who need the project's module layout, hardware-specific audio-routing facts, and data flow kept consistent across changes.
Source README
Build, maintain, and extend the EarLLM One Android project - a Kotlin/Compose app that connects Bluetooth earbuds to an LLM via voice pipeline.
FAQ
Common questions
Discussion
Questions & comments ยท 0
Sign In Sign in to leave a comment.