Simple Process Analysis of Bluetooth headsets

Source: Internet
Author: User

I recently focused on Bluetooth headsets and made a simple process analysis.
After decoding, the audio data is written to the device in AudioFlinger. Here we mainly look at the android_audio_h1_c and liba2dp. c In AudioFlinger, AudioPolicyManager, external/bluetooth/bluez/audio.

There is a device connection judgment in AudioPolicyManager.
Status_t AudioPolicyManagerBase: setDeviceConnectionState (AudioSystem: audio_devices device,
AudioSystem: device_connection_state state,
Const char * device_address)
{
# Ifdef WITH_A2DP
// Handle A2DP device connection
If (AudioSystem: isA2dpDevice (device )){
Status_t status = handleA2dpConnection (device, device_address); // The Bluetooth connection is executed here.
If (status! = NO_ERROR ){
MAvailableOutputDevices & = ~ Device;
Return status;
}
} Else
# Endif
}
.....
Status_t AudioPolicyManagerBase: handleA2dpConnection (AudioSystem: audio_devices device,
Const char * device_address)
{
...............
MA2dpOutput = mpClientInterface-> openOutput (& outputDesc-> mDevice,
& OutputDesc-> mSamplingRate,
& OutputDesc-> mFormat,
& OutputDesc-> mChannels,
& OutputDesc-> mLatency,
OutputDesc-> mFlags );
If (mA2dpOutput ){
// Add A2DP output descriptor
AddOutput (mA2dpOutput, outputDesc );

// TODO: configure audio effect output stage here

// Set initial stream volume for A2DP device
ApplyStreamVolumes (mA2dpOutput, device );
If (a2dpUsedForSonification ()){
MDuplicatedOutput = mpClientInterface-> openDuplicateOutput (mA2dpOutput, mHardwareOutput );
}
If (mDuplicatedOutput! = 0 |
! A2dpUsedForSonification ()){
// If both A2DP and duplicated outputs are open, send device address to A2DP hardware
// Interface
AudioParameter param;
Param. add (String8 ("a2dp_sink_address"), String8 (device_address ));
MpClientInterface-> setParameters (mA2dpOutput, param. toString ());
MA2dpDeviceAddress = String8 (device_address, MAX_DEVICE_ADDRESS_LEN );

If (a2dpUsedForSonification ()){
// Add duplicated output descriptor
AudioOutputDescriptor * dupOutputDesc = new AudioOutputDescriptor ();
DupOutputDesc-> mOutput1 = mOutputs. valueFor (mHardwareOutput );
DupOutputDesc-> mOutput2 = mOutputs. valueFor (mA2dpOutput );
DupOutputDesc-> mSamplingRate = outputDesc-> mSamplingRate;
DupOutputDesc-> mFormat = outputDesc-> mFormat;
DupOutputDesc-> mChannels = outputDesc-> mChannels;
DupOutputDesc-> mLatency = outputDesc-> mLatency;
AddOutput (mDuplicatedOutput, dupOutputDesc );
ApplyStreamVolumes (mDuplicatedOutput, device );
}
} Else {
.........
}
For Bluetooth playback, mDuplicatedOutput and a2dpUsedForSonification are both 0, and only addOutput (mA2dpOutput, outputDesc) is executed. The process is similar to that of speaker and microphone.
For both Bluetooth and speaker or microphone, use the mpClientInterface> openDuplicateOutput (mA2dpOutput, mHardwareOutput). Note that the first parameter is mA2dpOutput and Bluetooth, the second parameter is mHardwareOutput, speaker, mic, and other output devices.

Next, let's look at the openDuplicateOutput function. Defined in AudioFlinger. cpp
Int AudioFlinger: openDuplicateOutput (int output1, int output2)
{
Mutex: Autolock _ l (mLock );
MixerThread * thread1 = checkMixerThread_l (output1 );
MixerThread * thread2 = checkMixerThread_l (output2 );

If (thread1 = NULL | thread2 = NULL ){
LOGW ("openDuplicateOutput () wrong output mixer type for output % d or % d", output1, output2 );
Return 0;
}

Int id = nextUniqueId ();
DuplicatingThread * thread = new DuplicatingThread (this, thread1, id );
Thread-> addOutputTrack (thread2 );
MPlaybackThreads. add (id, thread );
// Define y client processes of the new output creation
Thread-> audioConfigChanged_l (AudioSystem: OUTPUT_OPENED );
Return id;
}
This function enables two threads, one for Bluetooth and the other for mHardwareOutput, to enable simultaneous playback of the two threads, such as incoming calls, text messages, and alarm sounds.
Pause here first, and then
Static const char * audio_interfaces [] = {
"Primary ",
"A2dp ",
"Usb ",
};
4.0 of the Code has three audio interfaces: primary, codec, speaker, mic, etc., a2dp, Bluetooth, and usb.
Void AudioFlinger: onFirstRef ()
{
Int rc = 0;

Mutex: Autolock _ l (mLock );

/* TODO: move all this work into an Init () function */
MHardwareStatus = AUDIO_HW_IDLE;

For (size_t I = 0; I <ARRAY_SIZE (audio_interfaces); I ++ ){
Const hw_module_t * mod;
Audio_hw_device_t * dev;

Rc = load_audio_interface (audio_interfaces [I], & mod, & dev); // load the interface. so file
If (rc)
Continue;

LOGI ("Loaded % s audio interface from % s (% s)", audio_interfaces [I],
Mod-> name, mod-> id );
MAudioHwDevs. push (dev );
.........
}
The audio interface is traversed here.
Void AudioFlinger: RecordThread: onFirstRef ()
{
Run (mName, PRIORITY_URGENT_AUDIO );
}
Int AudioFlinger: openOutput (uint32_t * pDevices,
Uint32_t * pSamplingRate,
Uint32_t * pFormat,
Uint32_t * pChannels,
Uint32_t * pLatencyMs,
Uint32_t flags ){

......
OutHwDev = findSuitableHwDev_l (* pDevices); // gets the valid audio interface device
If (outHwDev = NULL)
Return 0;
// Obtain the parameter information in the interface. so Library
Status = outHwDev-> open_output_stream (outHwDev, * pDevices, (int *) & format,
& Channels, & samplingRate, & outStream );
LOGV ("openOutput () openOutputStream returned output % p, SamplingRate % d, Format % d, Channels % x, status % d ",
OutStream,
SamplingRate,
Format,
Channels,
Status );

MHardwareStatus = AUDIO_HW_IDLE;
If (outStream! = NULL ){
AudioStreamOut * output = new AudioStreamOut (outHwDev, outStream); // create the output of such a device
........
}
OutHwDev-> open_output_stream comes from the interface functions in Bluetooth audio.
Look at android_audio_h1_c.
Static int adev_open (const hw_module_t * module, const char * name,
Hw_device_t ** device)
{
Struct adev_a2dp * adev;
Int ret;

If (strcmp (name, AUDIO_HARDWARE_INTERFACE )! = 0)
Return-EINVAL;

Adev = calloc (1, sizeof (struct adev_a2dp ));
If (! Adev)
Return-ENOMEM;

Adev-> bt_enabled = true;
Adev-> suincluded = false;
Pthread_mutex_init (& adev-> lock, NULL );
Adev-> output = NULL;

Adev-> device. common. tag = HARDWARE_DEVICE_TAG;
Adev-> device. common. version = 0;
Adev-> device. common. module = (struct hw_module_t *) module;
Adev-> device. common. close = adev_close;

Adev-> device. get_supported_devices = adev_get_supported_devices;
Adev-> device. init_check = adev_init_check;
Adev-> device. set_voice_volume = adev_set_voice_volume;
Adev-> device. set_master_volume = adev_set_master_volume;
Adev-> device. set_mode = adev_set_mode;
Adev-> device. set_mic_mute = adev_set_mic_mute;
Adev-> device. get_mic_mute = adev_get_mic_mute;
Adev-> device. set_parameters = adev_set_parameters;
Adev-> device. get_parameters = adev_get_parameters;
Adev-> device. get_input_buffer_size = adev_get_input_buffer_size;
Adev-> device. open_output_stream = adev_open_output_stream;
Adev-> device. close_output_stream = adev_close_output_stream;
Adev-> device. open_input_stream = adev_open_input_stream;
Adev-> device. close_input_stream = adev_close_input_stream;
Adev-> device. dump = adev_dump;

* Device = & adev-> device. common;

Return 0;

Err_str_parms_create:
Free (adev );
Return ret;
}
In this way, the parameters required in AudioFlinger are set here. Then, perform the init, config, start, and stop operations on the Bluetooth audio. Including Bluetooth reading and writing.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.