Merge "pal: add stereo-channel volume setting"
diff --git a/session/inc/PayloadBuilder.h b/session/inc/PayloadBuilder.h
index 183e8df..0228668 100644
--- a/session/inc/PayloadBuilder.h
+++ b/session/inc/PayloadBuilder.h
@@ -200,6 +200,9 @@
void payloadVolumeConfig(uint8_t** payload, size_t* size,
uint32_t miid,
struct pal_volume_data * data);
+ void payloadMultichVolumemConfig(uint8_t** payload, size_t* size,
+ uint32_t miid,
+ struct pal_volume_data * data);
int payloadCustomParam(uint8_t **alsaPayload, size_t *size,
uint32_t *customayload, uint32_t customPayloadSize,
uint32_t moduleInstanceId, uint32_t dspParamId);
diff --git a/session/src/PayloadBuilder.cpp b/session/src/PayloadBuilder.cpp
index f23578e..4a07e3f 100644
--- a/session/src/PayloadBuilder.cpp
+++ b/session/src/PayloadBuilder.cpp
@@ -441,8 +441,14 @@
uint8_t* payloadInfo = NULL;
size_t payloadSize = 0, padBytes = 0;
- PAL_VERBOSE(LOG_TAG,"volume sent:%f \n",(voldata->volume_pair[0].vol));
- voldB = (voldata->volume_pair[0].vol);
+ if (voldata->no_of_volpair == 1) {
+ voldB = (voldata->volume_pair[0].vol);
+ } else {
+ voldB = (voldata->volume_pair[0].vol + voldata->volume_pair[1].vol)/2;
+ PAL_DBG(LOG_TAG,"volume sent left:%f , right: %f \n",(voldata->volume_pair[0].vol),
+ (voldata->volume_pair[1].vol));
+ }
+ PAL_VERBOSE(LOG_TAG,"volume sent:%f \n",voldB);
vol = (long)(voldB * (PLAYBACK_VOLUME_MAX*1.0));
payloadSize = sizeof(struct apm_module_param_data_t) +
sizeof(struct volume_ctrl_master_gain_t);
@@ -467,6 +473,51 @@
PAL_DBG(LOG_TAG, "payload %pK size %zu", *payload, *size);
}
+void PayloadBuilder::payloadMultichVolumemConfig(uint8_t** payload, size_t* size,
+ uint32_t miid, struct pal_volume_data* voldata)
+{
+ const uint32_t PLAYBACK_MULTI_VOLUME_GAIN = 1 << 28;
+ struct apm_module_param_data_t* header = nullptr;
+ volume_ctrl_multichannel_gain_t *volConf = nullptr;
+ int numChannels;
+ uint8_t* payloadInfo = NULL;
+ size_t payloadSize = 0, padBytes = 0;
+
+ numChannels = voldata->no_of_volpair;
+ payloadSize = sizeof(struct apm_module_param_data_t) +
+ sizeof(struct volume_ctrl_multichannel_gain_t) +
+ numChannels * sizeof(volume_ctrl_channels_gain_config_t);
+ padBytes = PAL_PADDING_8BYTE_ALIGN(payloadSize);
+ payloadInfo = (uint8_t*) calloc(1, payloadSize + padBytes);
+ if (!payloadInfo) {
+ PAL_ERR(LOG_TAG, "payloadInfo malloc failed %s", strerror(errno));
+ return;
+ }
+ header = (struct apm_module_param_data_t*)payloadInfo;
+ header->module_instance_id = miid;
+ header->param_id = PARAM_ID_VOL_CTRL_MULTICHANNEL_GAIN;
+ header->error_code = 0x0;
+ header->param_size = payloadSize - sizeof(struct apm_module_param_data_t);
+ volConf = (volume_ctrl_multichannel_gain_t *) (payloadInfo + sizeof(struct apm_module_param_data_t));
+ volConf->num_config = numChannels;
+ PAL_DBG(LOG_TAG, "num_config %d", numChannels);
+ /*
+ * Only L/R channel setting is supported. No need to convert channel_mask to channel_map.
+ * If other channel types support, the conversion is needed.
+ */
+ for (uint32_t i = 0; i < numChannels; i++) {
+ volConf->gain_data[i].channel_mask_lsb = (1 << voldata->volume_pair[i].channel_mask);
+ volConf->gain_data[i].channel_mask_msb = 0;
+ volConf->gain_data[i].gain = (uint32_t)((voldata->volume_pair[i].vol) * (PLAYBACK_MULTI_VOLUME_GAIN * 1.0));
+ }
+ PAL_DBG(LOG_TAG, "header params IID:%x param_id:%x error_code:%d param_size:%d",
+ header->module_instance_id, header->param_id,
+ header->error_code, header->param_size);
+ *size = payloadSize + padBytes;
+ *payload = payloadInfo;
+ PAL_DBG(LOG_TAG, "payload %pK size %zu", *payload, *size);
+}
+
void PayloadBuilder::payloadVolumeCtrlRamp(uint8_t** payload, size_t* size,
uint32_t miid, uint32_t ramp_period_ms)
{
@@ -3182,6 +3233,7 @@
}
long voldB = 0;
+ float vol = 0;
struct pal_volume_data *voldata = NULL;
voldata = (struct pal_volume_data *)calloc(1, (sizeof(uint32_t) +
(sizeof(struct pal_channel_vol_kv) * (0xFFFF))));
@@ -3196,9 +3248,17 @@
goto error_1;
}
- PAL_VERBOSE(LOG_TAG,"volume sent:%f \n",(voldata->volume_pair[0].vol));
+ if (voldata->no_of_volpair == 1) {
+ vol = (voldata->volume_pair[0].vol);
+ } else {
+ vol = (voldata->volume_pair[0].vol + voldata->volume_pair[1].vol)/2;
+ PAL_VERBOSE(LOG_TAG,"volume sent left:%f , right: %f \n",(voldata->volume_pair[0].vol),
+ (voldata->volume_pair[1].vol));
+ }
+
/*scaling the volume by PLAYBACK_VOLUME_MAX factor*/
- voldB = (long)((voldata->volume_pair[0].vol) * (PLAYBACK_VOLUME_MAX*1.0));
+ voldB = (long)(vol * (PLAYBACK_VOLUME_MAX*1.0));
+ PAL_VERBOSE(LOG_TAG,"volume sent:%f \n",voldB);
switch (static_cast<uint32_t>(tag)) {
case TAG_STREAM_VOLUME:
diff --git a/session/src/SessionAlsaCompress.cpp b/session/src/SessionAlsaCompress.cpp
index eac0cb3..e6b9e9e 100644
--- a/session/src/SessionAlsaCompress.cpp
+++ b/session/src/SessionAlsaCompress.cpp
@@ -2182,7 +2182,12 @@
goto exit;
}
- builder->payloadVolumeConfig(&alsaParamData, &alsaPayloadSize, miid, vdata);
+ if (vdata->no_of_volpair == 2 && sAttr.out_media_config.ch_info.channels == 2) {
+ builder->payloadMultichVolumemConfig(&alsaParamData, &alsaPayloadSize, miid, vdata);
+ } else {
+ builder->payloadVolumeConfig(&alsaParamData, &alsaPayloadSize, miid, vdata);
+ }
+
if (alsaPayloadSize) {
status = SessionAlsaUtils::setMixerParameter(mixer, device,
alsaParamData, alsaPayloadSize);