Android device as a receiver for A2DP profile

29,267

Solution 1

Since Android L the BlueDriod stack does support A2DP sink, but it is disabled by default.

To enable it do the following:

/* Enable bluetooth av sink. */
#define BTA_AV_SINK_INCLUDED TRUE

in /external/bluetooth/bluedroid/include/bt_target.h. This enables sink support in the bluetooth stack.

Also you have to do this change:

<!-- Enable sink support. -->
<bool name="profile_supported_a2dp_sink">true</bool>

in /packages/apps/Bluetooth/res/values/config.xml. This enables the particular UI.

Now you can pair your devices and start streaming. Unfortunately you will hear no sound although you'll receive the packets. The reason is that there is no audio route for A2DP sink. In the commit message of this patch https://android-review.googlesource.com/#/c/98161/ you can find a sample implementation on how to fix this.

Here is a list of these changes:

Solution 2

Yes. It is possible. I have done it in JB. Android internally uses "Bluedroid" stack from Broadcomm for Bluetooth. Previously this stack did not have support for A2DP Sink Role (Which you mentioned as receiver). From Lollipop release, the A2DP Sink role profile has been added in Bluedroid. But, it is not enabled to be used by framework/upper layer (Application). You need to make changes in framework to enable it or 'use' it. You may refer to the following files and relevant files in Android source code to enable it.

audio.h - put a new audio source
audio_policy.conf - put a new input source for a2dp 'inputs'
AudioManager.java
AudioPolicyManagerBase.cpp
AudioService.java
AudioSystem.java
BluetoothA2dp.java
MediaRecorder.java
A2DPStateMachine.java

etc. and implement it (this file list is not comprehensive, but you can figure it out if you have experience in relevant field). When any stream connection is established, you will get callback in a2dp state machine and from there you have to start a thread to read the decoded PCM bytes from the 'new' audio source and send it to your media player. SBC codec to PCM decoding will be done at the 'bluedroid' sbc decoder layer.

Build it and flash it to your phone and enjoy music.

EDIT: Also, you may have make changes in A2DP SDP record in Bluedroid stack to advertise the A2DP Sink role.

Solution 3

You may-not be able to do it manually between 2 phones because to stream one device needs to be A2DP sink and other other A2DP source, Phones are typically only Source devices (Source of the stream that can stream to sink devices) , Sinks are Headsets or Bluetooth speakers.

Share:
29,267
Heewon Hwang
Author by

Heewon Hwang

Updated on July 09, 2022

Comments

  • Heewon Hwang
    Heewon Hwang almost 2 years

    Basically, what I am trying to do right now is use an android device as an A2DP receiver and when pairing established, android plays sound that is received from a transmitter. I am worrying that if I use STP profile, it may cause delay of streaming. So, I want to use A2DP but is this possible to use an android device as a receiver of A2DP? and how to do it?

  • rob
    rob over 8 years
    Do you know if this is enabled in Android 6?
  • tchelidze
    tchelidze over 7 years
    @nilo patch you posted is for android android-4.4_r1, in android L base classes (to which against patch is) is different. Ex : in file platform/external/bluetooth/bluedroid / audio_a2dp_hw/audio_a2dp_hw.c there is already struct a2dp_stream_in *input; audio_a2dp_hw.c line 87
  • Nils Schikora
    Nils Schikora about 7 years
    This is also valid for the esp-idf for ESP32 IC though I dont know if the sink functionality is implemented in the higher layers of the stack.
  • John Smith
    John Smith almost 7 years
    Can you put together a little sample code for this. I don't have "the experience in relevant field" but I can compile, and write apps. I would appreciate the feedback and even a pm.