Search code examples
audiobluetoothandroid-bluetoothbluetooth-lowenergy

Can anyone explain how voice commands works via Bluetooth remote(Nexus player remote) in Android(Nexus player)?


Can anyone please elaborate following questions?

  1. How bluetooth stack handles audio data?
  2. How audio commands are processed?
  3. Did we need any service to process audio data?

Thanks in advance.


Solution

  • Basically, voice commands over BLE require:

    • some audio codec for reducing required bandwidth (ADPCM and SBC are common, OPUS is emerging),
    • some audio streaming method through BLE,
    • decoding and getting the audio stream from BLE daemon to a command processing framework.

    In the android world, command processing framework is google sauce (closed) that most easily gets its audio from an ALSA device. What is left to be done is getting audio from the remote to an ALSA device.

    So for audio streaming, either you:

    • use a custom L2CAP channel or a custom GATT service, this requires a custom android service app and/or modifications to Bluedroid to handle those, it will need a way to inject audio stream as ALSA, most probably with a "loop" audio device driver,
    • declare audio as custom HID reports, this way, Bluedroid injects them back to the kernel, then add a custom HID driver that processes these reports and exposes an audio device.

    Audio over BLE is not standard, so all implementations do not do the actual same thing. In Nexus Player case, implementation uses HID: It streams an ADPCM audio stream, chunked in HID reports. There is a special HID driver "hid-atv-remote.c" in Android linux kernel that exposes an ALSA device in addition to input device. Bluedroid has no information about audio, all it does is forwarding HID reports from BLE to UHID.