Skip to content

Commit

Permalink
Update volume when changing soft-volume property
Browse files Browse the repository at this point in the history
  • Loading branch information
arkq committed Sep 12, 2024
1 parent 61adf95 commit 07a4be7
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 15 deletions.
16 changes: 8 additions & 8 deletions src/ba-rfcomm.c
Original file line number Diff line number Diff line change
Expand Up @@ -440,14 +440,14 @@ static int rfcomm_handler_vgm_set_cb(struct ba_rfcomm *r, const struct bt_at *at

struct ba_transport * const t_sco = r->sco;
struct ba_transport_pcm *pcm = &t_sco->sco.pcm_mic;
const int gain = r->gain_mic = atoi(at->value);
const int fd = r->fd;

/* skip update in case of software volume */
if (pcm->soft_volume)
return rfcomm_write_at(fd, AT_TYPE_RESP, NULL, "OK");

r->gain_mic = atoi(at->value);
int level = ba_transport_pcm_volume_range_to_level(r->gain_mic, HFP_VOLUME_GAIN_MAX);
int level = ba_transport_pcm_volume_range_to_level(gain, HFP_VOLUME_GAIN_MAX);

pthread_mutex_lock(&pcm->mutex);
ba_transport_pcm_volume_set(&pcm->volume[0], &level, NULL, NULL);
Expand All @@ -467,8 +467,8 @@ static int rfcomm_handler_vgm_resp_cb(struct ba_rfcomm *r, const struct bt_at *a
struct ba_transport * const t_sco = r->sco;
struct ba_transport_pcm *pcm = &t_sco->sco.pcm_mic;

r->gain_mic = atoi(at->value);
int level = ba_transport_pcm_volume_range_to_level(r->gain_mic, HFP_VOLUME_GAIN_MAX);
int gain = r->gain_mic = atoi(at->value);
int level = ba_transport_pcm_volume_range_to_level(gain, HFP_VOLUME_GAIN_MAX);

pthread_mutex_lock(&pcm->mutex);
ba_transport_pcm_volume_set(&pcm->volume[0], &level, NULL, NULL);
Expand All @@ -485,14 +485,14 @@ static int rfcomm_handler_vgs_set_cb(struct ba_rfcomm *r, const struct bt_at *at

struct ba_transport * const t_sco = r->sco;
struct ba_transport_pcm *pcm = &t_sco->sco.pcm_spk;
const int gain = r->gain_spk = atoi(at->value);
const int fd = r->fd;

/* skip update in case of software volume */
if (pcm->soft_volume)
return rfcomm_write_at(fd, AT_TYPE_RESP, NULL, "OK");

r->gain_spk = atoi(at->value);
int level = ba_transport_pcm_volume_range_to_level(r->gain_spk, HFP_VOLUME_GAIN_MAX);
int level = ba_transport_pcm_volume_range_to_level(gain, HFP_VOLUME_GAIN_MAX);

pthread_mutex_lock(&pcm->mutex);
ba_transport_pcm_volume_set(&pcm->volume[0], &level, NULL, NULL);
Expand All @@ -512,8 +512,8 @@ static int rfcomm_handler_vgs_resp_cb(struct ba_rfcomm *r, const struct bt_at *a
struct ba_transport * const t_sco = r->sco;
struct ba_transport_pcm *pcm = &t_sco->sco.pcm_spk;

r->gain_spk = atoi(at->value);
int level = ba_transport_pcm_volume_range_to_level(r->gain_spk, HFP_VOLUME_GAIN_MAX);
int gain = r->gain_spk = atoi(at->value);
int level = ba_transport_pcm_volume_range_to_level(gain, HFP_VOLUME_GAIN_MAX);

pthread_mutex_lock(&pcm->mutex);
ba_transport_pcm_volume_set(&pcm->volume[0], &level, NULL, NULL);
Expand Down
28 changes: 28 additions & 0 deletions src/ba-transport-pcm.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include "bluez-iface.h"
#include "bluez.h"
#include "dbus.h"
#include "hfp.h"
#include "io.h"
#if ENABLE_OFONO
# include "ofono.h"
Expand Down Expand Up @@ -693,6 +694,33 @@ int ba_transport_pcm_volume_update(struct ba_transport_pcm *pcm) {
return 0;
}

/**
* Get non-software PCM volume level if available. */
int ba_transport_pcm_get_hardware_volume(
const struct ba_transport_pcm *pcm) {

const struct ba_transport *t = pcm->t;

if (t->profile & BA_TRANSPORT_PROFILE_MASK_A2DP)
return t->a2dp.volume;

if (t->profile & BA_TRANSPORT_PROFILE_MASK_SCO) {

if (t->sco.rfcomm == NULL)
/* TODO: Cache volume level for oFono-based SCO */
return HFP_VOLUME_GAIN_MAX;

if (pcm == &t->sco.pcm_spk)
return t->sco.rfcomm->gain_spk;
if (pcm == &t->sco.pcm_mic)
return t->sco.rfcomm->gain_mic;

}

g_assert_not_reached();
return 0;
}

int ba_transport_pcm_get_delay(const struct ba_transport_pcm *pcm) {

const struct ba_transport *t = pcm->t;
Expand Down
3 changes: 3 additions & 0 deletions src/ba-transport-pcm.h
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,9 @@ void ba_transport_pcm_volume_set(
int ba_transport_pcm_volume_update(
struct ba_transport_pcm *pcm);

int ba_transport_pcm_get_hardware_volume(
const struct ba_transport_pcm *pcm);

int ba_transport_pcm_get_delay(
const struct ba_transport_pcm *pcm);

Expand Down
33 changes: 26 additions & 7 deletions src/bluealsa-dbus.c
Original file line number Diff line number Diff line change
Expand Up @@ -1023,18 +1023,38 @@ static bool bluealsa_pcm_set_property(const char *property, GVariant *value,
GError **error, void *userdata) {

struct ba_transport_pcm *pcm = userdata;
struct ba_transport *t = pcm->t;

const bool is_sco = t->profile & BA_TRANSPORT_PROFILE_MASK_SCO;
const int volume_max = is_sco ? HFP_VOLUME_GAIN_MAX : BLUEZ_A2DP_VOLUME_MAX;

if (strcmp(property, "SoftVolume") == 0) {
pcm->soft_volume = g_variant_get_boolean(value);
bluealsa_dbus_pcm_update(pcm, BA_DBUS_PCM_UPDATE_SOFT_VOLUME);

const bool soft_volume = g_variant_get_boolean(value);

/* In case when the software volume was just enabled, set the volume level
* to the maximum. This will prevent volume change during the transition.
* In case of disabling the software volume, we will restore the hardware
* volume level, so the volume control will indicate the correct level. */
const int volume = soft_volume ? volume_max : ba_transport_pcm_get_hardware_volume(pcm);
const int level = ba_transport_pcm_volume_range_to_level(volume, volume_max);

pthread_mutex_lock(&pcm->mutex);

debug("Setting software volume: %s", soft_volume ? "true" : "false");
pcm->soft_volume = soft_volume;

for (size_t i = 0; i < pcm->channels; i++)
ba_transport_pcm_volume_set(&pcm->volume[i], &level, NULL, NULL);

pthread_mutex_unlock(&pcm->mutex);

bluealsa_dbus_pcm_update(pcm, BA_DBUS_PCM_UPDATE_SOFT_VOLUME | BA_DBUS_PCM_UPDATE_VOLUME);
return true;
}

if (strcmp(property, "Volume") == 0) {

const bool is_sco = pcm->t->profile & BA_TRANSPORT_PROFILE_MASK_SCO;
const int max = is_sco ? HFP_VOLUME_GAIN_MAX : BLUEZ_A2DP_VOLUME_MAX;

size_t channels = 0;
const uint8_t *volume = g_variant_get_fixed_array(value, &channels, sizeof(uint8_t));

Expand All @@ -1049,11 +1069,10 @@ static bool bluealsa_pcm_set_property(const char *property, GVariant *value,
for (size_t i = 0; i < channels; i++) {

const bool muted = !!(volume[i] & 0x80);
const int level = ba_transport_pcm_volume_range_to_level(volume[i] & 0x7F, max);
const int level = ba_transport_pcm_volume_range_to_level(volume[i] & 0x7F, volume_max);

debug("Setting volume [ch=%zu]: %u [%.2f dB] [%c]",
i, volume[i] & 0x7F, 0.01 * level, muted ? 'x' : ' ');

ba_transport_pcm_volume_set(&pcm->volume[i], &level, &muted, NULL);

}
Expand Down

0 comments on commit 07a4be7

Please sign in to comment.