Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d3806b72 authored by Sandeep Samdaria's avatar Sandeep Samdaria
Browse files

Apply gain to the audio track stream

Problem: While bluetooth is streaming media (with appropriate audio
focus), any other media/audio app can acquire transient audio focus
i.e. AUDIOFOCUS_GAIN_TRANSIENT and AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK
This results in bluetooth process to receive the respective LOSS
events. When it receives the AUDIOFOCUS_LOSS_TRANSIENT it sends a
pause command to the remote device. In addition, it also mutes the
stream in case the remote device rejects the pause command to ensure
no sound is made by the bluetooth process. The logic to set the gain
was broken post the lib AAudio migration resulting in bluetooth
process making additional sound on top of the other audio app.
Similarly, when other media/audio app had requested for gain_may_duck
focus, bluetooth process wasn't ducking the media sound resulting in
overlap of both the audio.

Solution: Updated the business logic to update the stream buffer
based on the gain value set by the bluetooth process. On different
transient audio focus events, different gain (in range of [0.0f,1.0f])
is set by the handler. On focus gain event, it sets back the gain to
1.0f.

Bug:254724838
Tag:#stability
Test: Tested by setting the different gain value in the code and
validating on device.

Change-Id: Iafedf759949df6e54cad7f21d64dc247712fd380
parent 4bb9810b
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -735,7 +735,7 @@ static void btif_a2dp_sink_set_focus_state_event(
}

void btif_a2dp_sink_set_audio_track_gain(float gain) {
  LOG_INFO("%s: set gain to %f", __func__, gain);
  LOG_DEBUG("%s: set gain to %f", __func__, gain);
  LockGuard lock(g_mutex);

#ifndef OS_GENERIC
+25 −4
Original line number Diff line number Diff line
@@ -23,6 +23,8 @@
#include <base/logging.h>
#include <utils/StrongPointer.h>

#include <algorithm>

#include "bt_target.h"
#include "osi/include/log.h"

@@ -34,6 +36,7 @@ typedef struct {
  int channelCount;
  float* buffer;
  size_t bufferLength;
  float gain;
} BtifAvrcpAudioTrack;

#if (DUMP_PCM_DATA == TRUE)
@@ -41,6 +44,11 @@ FILE* outputPcmSampleFile;
char outputFilename[50] = "/data/misc/bluedroid/output_sample.pcm";
#endif

// Maximum track gain that can be set.
constexpr float kMaxTrackGain = 1.0f;
// Minimum track gain that can be set.
constexpr float kMinTrackGain = 0.0f;

void* BtifAvrcpAudioTrackCreate(int trackFreq, int bitsPerSample,
                                int channelCount) {
  LOG_VERBOSE("%s Track.cpp: btCreateTrack freq %d bps %d channel %d ",
@@ -66,6 +74,7 @@ void* BtifAvrcpAudioTrackCreate(int trackFreq, int bitsPerSample,
  trackHolder->channelCount = channelCount;
  trackHolder->bufferLength =
      trackHolder->channelCount * AAudioStream_getBufferSizeInFrames(stream);
  trackHolder->gain = kMaxTrackGain;
  trackHolder->buffer = new float[trackHolder->bufferLength]();

#if (DUMP_PCM_DATA == TRUE)
@@ -137,7 +146,16 @@ void BtifAvrcpSetAudioTrackGain(void* handle, float gain) {
    LOG_INFO("%s handle is null.", __func__);
    return;
  }
  // Does nothing right now
  BtifAvrcpAudioTrack* trackHolder = static_cast<BtifAvrcpAudioTrack*>(handle);
  if (trackHolder != NULL) {
    const float clampedGain = std::clamp(gain, kMinTrackGain, kMaxTrackGain);
    if (clampedGain != gain) {
      LOG_WARN("Out of bounds gain set. Clamping the gain from :%f to %f", gain,
               clampedGain);
    }
    trackHolder->gain = clampedGain;
    LOG_INFO("Avrcp audio track gain is set to %f", trackHolder->gain);
  }
}

constexpr float kScaleQ15ToFloat = 1.0f / 32768.0f;
@@ -152,8 +170,9 @@ static size_t transcodeQ15ToFloat(uint8_t* buffer, size_t length,
                                  BtifAvrcpAudioTrack* trackHolder) {
  size_t sampleSize = sampleSizeFor(trackHolder);
  size_t i = 0;
  const float scaledGain = trackHolder->gain * kScaleQ15ToFloat;
  for (; i <= length / sampleSize; i++) {
    trackHolder->buffer[i] = ((int16_t*)buffer)[i] * kScaleQ15ToFloat;
    trackHolder->buffer[i] = ((int16_t*)buffer)[i] * scaledGain;
  }
  return i * sampleSize;
}
@@ -162,10 +181,11 @@ static size_t transcodeQ23ToFloat(uint8_t* buffer, size_t length,
                                  BtifAvrcpAudioTrack* trackHolder) {
  size_t sampleSize = sampleSizeFor(trackHolder);
  size_t i = 0;
  const float scaledGain = trackHolder->gain * kScaleQ23ToFloat;
  for (; i <= length / sampleSize; i++) {
    size_t offset = i * sampleSize;
    int32_t sample = *((int32_t*)(buffer + offset - 1)) & 0x00FFFFFF;
    trackHolder->buffer[i] = sample * kScaleQ23ToFloat;
    trackHolder->buffer[i] = sample * scaledGain;
  }
  return i * sampleSize;
}
@@ -174,8 +194,9 @@ static size_t transcodeQ31ToFloat(uint8_t* buffer, size_t length,
                                  BtifAvrcpAudioTrack* trackHolder) {
  size_t sampleSize = sampleSizeFor(trackHolder);
  size_t i = 0;
  const float scaledGain = trackHolder->gain * kScaleQ31ToFloat;
  for (; i <= length / sampleSize; i++) {
    trackHolder->buffer[i] = ((int32_t*)buffer)[i] * kScaleQ31ToFloat;
    trackHolder->buffer[i] = ((int32_t*)buffer)[i] * scaledGain;
  }
  return i * sampleSize;
}