hal: Support for FLAC 24 bit format in offload path
- Add flac in supported codecs list - Set FLAC codec specific parameters - Set fragment size based on bit width and sampling rate for flac - Configure backend to 24/16 bit based on the current usecases running Change-Id: If013078e277fd3053fba6489345803f8f58bd86d
This commit is contained in:
parent
34affc6697
commit
3ee55c65a2
|
@ -137,6 +137,10 @@ ifeq ($(strip $(AUDIO_FEATURE_ENABLED_MULTIPLE_TUNNEL)), true)
|
||||||
LOCAL_CFLAGS += -DMULTIPLE_OFFLOAD_ENABLED
|
LOCAL_CFLAGS += -DMULTIPLE_OFFLOAD_ENABLED
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(strip $(AUDIO_FEATURE_ENABLED_EXTN_FLAC_DECODER)),true)
|
||||||
|
LOCAL_CFLAGS += -DQTI_FLAC_DECODER
|
||||||
|
endif
|
||||||
|
|
||||||
LOCAL_SHARED_LIBRARIES := \
|
LOCAL_SHARED_LIBRARIES := \
|
||||||
liblog \
|
liblog \
|
||||||
libcutils \
|
libcutils \
|
||||||
|
|
|
@ -51,6 +51,16 @@
|
||||||
#define AUDIO_DEVICE_IN_FM_RX_A2DP (AUDIO_DEVICE_BIT_IN | 0x10000)
|
#define AUDIO_DEVICE_IN_FM_RX_A2DP (AUDIO_DEVICE_BIT_IN | 0x10000)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef QTI_FLAC_DECODER
|
||||||
|
#define AUDIO_FORMAT_FLAC 0x19000000UL
|
||||||
|
#define AUDIO_OFFLOAD_CODEC_FLAC_MIN_BLK_SIZE "music_offload_flac_min_blk_size"
|
||||||
|
#define AUDIO_OFFLOAD_CODEC_FLAC_MAX_BLK_SIZE "music_offload_flac_max_blk_size"
|
||||||
|
#define AUDIO_OFFLOAD_CODEC_FLAC_MIN_FRAME_SIZE "music_offload_flac_min_frame_size"
|
||||||
|
#define AUDIO_OFFLOAD_CODEC_FLAC_MAX_FRAME_SIZE "music_offload_flac_max_frame_size"
|
||||||
|
#define PCM_OUTPUT_BIT_WIDTH (CODEC_BACKEND_DEFAULT_BIT_WIDTH)
|
||||||
|
#else
|
||||||
|
#define PCM_OUTPUT_BIT_WIDTH (config->offload_info.bit_width)
|
||||||
|
#endif
|
||||||
|
|
||||||
#define MAX_LENGTH_MIXER_CONTROL_IN_INT (128)
|
#define MAX_LENGTH_MIXER_CONTROL_IN_INT (128)
|
||||||
|
|
||||||
|
|
|
@ -125,7 +125,7 @@ const char * const use_case_table[AUDIO_USECASE_MAX] = {
|
||||||
[USECASE_AUDIO_HFP_SCO] = "hfp-sco",
|
[USECASE_AUDIO_HFP_SCO] = "hfp-sco",
|
||||||
[USECASE_AUDIO_HFP_SCO_WB] = "hfp-sco-wb",
|
[USECASE_AUDIO_HFP_SCO_WB] = "hfp-sco-wb",
|
||||||
[USECASE_VOICE_CALL] = "voice-call",
|
[USECASE_VOICE_CALL] = "voice-call",
|
||||||
|
|
||||||
[USECASE_VOICE2_CALL] = "voice2-call",
|
[USECASE_VOICE2_CALL] = "voice2-call",
|
||||||
[USECASE_VOLTE_CALL] = "volte-call",
|
[USECASE_VOLTE_CALL] = "volte-call",
|
||||||
[USECASE_QCHAT_CALL] = "qchat-call",
|
[USECASE_QCHAT_CALL] = "qchat-call",
|
||||||
|
@ -209,7 +209,8 @@ static bool is_supported_format(audio_format_t format)
|
||||||
if (format == AUDIO_FORMAT_MP3 ||
|
if (format == AUDIO_FORMAT_MP3 ||
|
||||||
format == AUDIO_FORMAT_AAC ||
|
format == AUDIO_FORMAT_AAC ||
|
||||||
format == AUDIO_FORMAT_PCM_16_BIT_OFFLOAD ||
|
format == AUDIO_FORMAT_PCM_16_BIT_OFFLOAD ||
|
||||||
format == AUDIO_FORMAT_PCM_24_BIT_OFFLOAD)
|
format == AUDIO_FORMAT_PCM_24_BIT_OFFLOAD ||
|
||||||
|
format == AUDIO_FORMAT_FLAC)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -230,6 +231,9 @@ static int get_snd_codec_id(audio_format_t format)
|
||||||
case AUDIO_FORMAT_PCM_24_BIT_OFFLOAD:
|
case AUDIO_FORMAT_PCM_24_BIT_OFFLOAD:
|
||||||
id = SND_AUDIOCODEC_PCM;
|
id = SND_AUDIOCODEC_PCM;
|
||||||
break;
|
break;
|
||||||
|
case AUDIO_FORMAT_FLAC:
|
||||||
|
id = SND_AUDIOCODEC_FLAC;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
ALOGE("%s: Unsupported audio format :%x", __func__, format);
|
ALOGE("%s: Unsupported audio format :%x", __func__, format);
|
||||||
}
|
}
|
||||||
|
@ -447,6 +451,15 @@ static void check_usecases_codec_backend(struct audio_device *adev,
|
||||||
* because of the limitation that both the devices cannot be enabled
|
* because of the limitation that both the devices cannot be enabled
|
||||||
* at the same time as they share the same backend.
|
* at the same time as they share the same backend.
|
||||||
*/
|
*/
|
||||||
|
/*
|
||||||
|
* This call is to check if we need to force routing for a particular stream
|
||||||
|
* If there is a backend configuration change for the device when a
|
||||||
|
* new stream starts, then ADM needs to be closed and re-opened with the new
|
||||||
|
* configuraion. This call check if we need to re-route all the streams
|
||||||
|
* associated with the backend. Touch tone + 24 bit playback.
|
||||||
|
*/
|
||||||
|
bool force_routing = platform_check_and_set_codec_backend_cfg(adev, uc_info);
|
||||||
|
|
||||||
/* Disable all the usecases on the shared backend other than the
|
/* Disable all the usecases on the shared backend other than the
|
||||||
specified usecase */
|
specified usecase */
|
||||||
for (i = 0; i < AUDIO_USECASE_MAX; i++)
|
for (i = 0; i < AUDIO_USECASE_MAX; i++)
|
||||||
|
@ -456,7 +469,7 @@ static void check_usecases_codec_backend(struct audio_device *adev,
|
||||||
usecase = node_to_item(node, struct audio_usecase, list);
|
usecase = node_to_item(node, struct audio_usecase, list);
|
||||||
if (usecase->type != PCM_CAPTURE &&
|
if (usecase->type != PCM_CAPTURE &&
|
||||||
usecase != uc_info &&
|
usecase != uc_info &&
|
||||||
usecase->out_snd_device != snd_device &&
|
(usecase->out_snd_device != snd_device || force_routing) &&
|
||||||
usecase->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND) {
|
usecase->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND) {
|
||||||
ALOGV("%s: Usecase (%s) is active on (%s) - disabling ..",
|
ALOGV("%s: Usecase (%s) is active on (%s) - disabling ..",
|
||||||
__func__, use_case_table[usecase->id],
|
__func__, use_case_table[usecase->id],
|
||||||
|
@ -1501,6 +1514,29 @@ static int parse_compress_metadata(struct stream_out *out, struct str_parms *par
|
||||||
out->send_new_metadata = 1;
|
out->send_new_metadata = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (out->format == AUDIO_FORMAT_FLAC) {
|
||||||
|
ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_FLAC_MIN_BLK_SIZE, value, sizeof(value));
|
||||||
|
if (ret >= 0) {
|
||||||
|
out->compr_config.codec->options.flac_dec.min_blk_size = atoi(value);
|
||||||
|
out->send_new_metadata = 1;
|
||||||
|
}
|
||||||
|
ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_FLAC_MAX_BLK_SIZE, value, sizeof(value));
|
||||||
|
if (ret >= 0) {
|
||||||
|
out->compr_config.codec->options.flac_dec.max_blk_size = atoi(value);
|
||||||
|
out->send_new_metadata = 1;
|
||||||
|
}
|
||||||
|
ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_FLAC_MIN_FRAME_SIZE, value, sizeof(value));
|
||||||
|
if (ret >= 0) {
|
||||||
|
out->compr_config.codec->options.flac_dec.min_frame_size = atoi(value);
|
||||||
|
out->send_new_metadata = 1;
|
||||||
|
}
|
||||||
|
ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_FLAC_MAX_FRAME_SIZE, value, sizeof(value));
|
||||||
|
if (ret >= 0) {
|
||||||
|
out->compr_config.codec->options.flac_dec.max_frame_size = atoi(value);
|
||||||
|
out->send_new_metadata = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_SAMPLE_RATE, value, sizeof(value));
|
ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_SAMPLE_RATE, value, sizeof(value));
|
||||||
if(ret >= 0)
|
if(ret >= 0)
|
||||||
is_meta_data_params = true;
|
is_meta_data_params = true;
|
||||||
|
@ -2335,6 +2371,7 @@ static int adev_open_output_stream(struct audio_hw_device *dev,
|
||||||
out->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
|
out->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
|
||||||
out->supported_channel_masks[0] = AUDIO_CHANNEL_OUT_STEREO;
|
out->supported_channel_masks[0] = AUDIO_CHANNEL_OUT_STEREO;
|
||||||
out->handle = handle;
|
out->handle = handle;
|
||||||
|
out->bit_width = CODEC_BACKEND_DEFAULT_BIT_WIDTH;
|
||||||
|
|
||||||
/* Init use case and pcm_config */
|
/* Init use case and pcm_config */
|
||||||
if ((out->flags == AUDIO_OUTPUT_FLAG_DIRECT) &&
|
if ((out->flags == AUDIO_OUTPUT_FLAG_DIRECT) &&
|
||||||
|
@ -2409,6 +2446,7 @@ static int adev_open_output_stream(struct audio_hw_device *dev,
|
||||||
out->stream.resume = out_resume;
|
out->stream.resume = out_resume;
|
||||||
out->stream.drain = out_drain;
|
out->stream.drain = out_drain;
|
||||||
out->stream.flush = out_flush;
|
out->stream.flush = out_flush;
|
||||||
|
out->bit_width = CODEC_BACKEND_DEFAULT_BIT_WIDTH;
|
||||||
|
|
||||||
if (audio_extn_is_dolby_format(config->offload_info.format))
|
if (audio_extn_is_dolby_format(config->offload_info.format))
|
||||||
out->compr_config.codec->id =
|
out->compr_config.codec->id =
|
||||||
|
@ -2432,13 +2470,26 @@ static int adev_open_output_stream(struct audio_hw_device *dev,
|
||||||
out->compr_config.codec->ch_in =
|
out->compr_config.codec->ch_in =
|
||||||
popcount(config->channel_mask);
|
popcount(config->channel_mask);
|
||||||
out->compr_config.codec->ch_out = out->compr_config.codec->ch_in;
|
out->compr_config.codec->ch_out = out->compr_config.codec->ch_in;
|
||||||
out->compr_config.codec->format = SND_AUDIOSTREAMFORMAT_RAW;
|
out->bit_width = PCM_OUTPUT_BIT_WIDTH;
|
||||||
|
|
||||||
|
if (config->offload_info.format == AUDIO_FORMAT_AAC)
|
||||||
|
out->compr_config.codec->format = SND_AUDIOSTREAMFORMAT_RAW;
|
||||||
if (config->offload_info.format == AUDIO_FORMAT_PCM_16_BIT_OFFLOAD)
|
if (config->offload_info.format == AUDIO_FORMAT_PCM_16_BIT_OFFLOAD)
|
||||||
out->compr_config.codec->format = SNDRV_PCM_FORMAT_S16_LE;
|
out->compr_config.codec->format = SNDRV_PCM_FORMAT_S16_LE;
|
||||||
else if(config->offload_info.format == AUDIO_FORMAT_PCM_24_BIT_OFFLOAD)
|
if(config->offload_info.format == AUDIO_FORMAT_PCM_24_BIT_OFFLOAD)
|
||||||
out->compr_config.codec->format = SNDRV_PCM_FORMAT_S24_LE;
|
out->compr_config.codec->format = SNDRV_PCM_FORMAT_S24_LE;
|
||||||
|
|
||||||
|
if (out->bit_width == 24) {
|
||||||
|
out->compr_config.codec->format = SNDRV_PCM_FORMAT_S24_LE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (out->bit_width == 24 && !platform_check_24_bit_support()) {
|
||||||
|
ALOGW("24 bit support is not enabled, using 16 bit backend");
|
||||||
|
out->compr_config.codec->format = SNDRV_PCM_FORMAT_S16_LE;
|
||||||
|
}
|
||||||
|
|
||||||
|
out->compr_config.codec->options.flac_dec.sample_size = out->bit_width;
|
||||||
|
|
||||||
if (flags & AUDIO_OUTPUT_FLAG_NON_BLOCKING)
|
if (flags & AUDIO_OUTPUT_FLAG_NON_BLOCKING)
|
||||||
out->non_blocking = 1;
|
out->non_blocking = 1;
|
||||||
|
|
||||||
|
@ -3005,6 +3056,8 @@ static int adev_open(const hw_module_t *module, const char *name,
|
||||||
adev->bluetooth_nrec = true;
|
adev->bluetooth_nrec = true;
|
||||||
adev->acdb_settings = TTY_MODE_OFF;
|
adev->acdb_settings = TTY_MODE_OFF;
|
||||||
/* adev->cur_hdmi_channels = 0; by calloc() */
|
/* adev->cur_hdmi_channels = 0; by calloc() */
|
||||||
|
adev->cur_codec_backend_samplerate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
|
||||||
|
adev->cur_codec_backend_bit_width = CODEC_BACKEND_DEFAULT_BIT_WIDTH;
|
||||||
adev->snd_dev_ref_cnt = calloc(SND_DEVICE_MAX, sizeof(int));
|
adev->snd_dev_ref_cnt = calloc(SND_DEVICE_MAX, sizeof(int));
|
||||||
voice_init(adev);
|
voice_init(adev);
|
||||||
list_init(&adev->usecase_list);
|
list_init(&adev->usecase_list);
|
||||||
|
|
|
@ -188,6 +188,7 @@ struct stream_out {
|
||||||
void *offload_cookie;
|
void *offload_cookie;
|
||||||
struct compr_gapless_mdata gapless_mdata;
|
struct compr_gapless_mdata gapless_mdata;
|
||||||
int send_new_metadata;
|
int send_new_metadata;
|
||||||
|
unsigned int bit_width;
|
||||||
|
|
||||||
struct audio_device *dev;
|
struct audio_device *dev;
|
||||||
};
|
};
|
||||||
|
@ -272,6 +273,8 @@ struct audio_device {
|
||||||
bool bt_wb_speech_enabled;
|
bool bt_wb_speech_enabled;
|
||||||
|
|
||||||
int snd_card;
|
int snd_card;
|
||||||
|
unsigned int cur_codec_backend_samplerate;
|
||||||
|
unsigned int cur_codec_backend_bit_width;
|
||||||
void *platform;
|
void *platform;
|
||||||
unsigned int offload_usecases_state;
|
unsigned int offload_usecases_state;
|
||||||
void *visualizer_lib;
|
void *visualizer_lib;
|
||||||
|
|
|
@ -2041,3 +2041,10 @@ uint32_t platform_get_pcm_offload_buffer_size(audio_offload_info_t* info)
|
||||||
return fragment_size;
|
return fragment_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool platform_check_24_bit_support() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool platform_check_and_set_codec_backend_cfg(struct audio_device* adev, struct audio_usecase *usecase) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
|
@ -950,3 +950,12 @@ bool platform_listen_usecase_needs_event(audio_usecase_t uc_id)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool platform_check_24_bit_support() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool platform_check_and_set_codec_backend_cfg(struct audio_device* adev, struct audio_usecase *usecase) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -2154,6 +2154,14 @@ uint32_t platform_get_compress_offload_buffer_size(audio_offload_info_t* info)
|
||||||
fragment_size = atoi(value) * 1024;
|
fragment_size = atoi(value) * 1024;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// For FLAC use max size since it is loss less, and has sampling rates
|
||||||
|
// upto 192kHZ
|
||||||
|
if (info != NULL && !info->has_video &&
|
||||||
|
info->format == AUDIO_FORMAT_FLAC) {
|
||||||
|
fragment_size = MAX_COMPRESS_OFFLOAD_FRAGMENT_SIZE;
|
||||||
|
ALOGV("FLAC fragment size %d", fragment_size);
|
||||||
|
}
|
||||||
|
|
||||||
if (info != NULL && info->has_video && info->is_streaming) {
|
if (info != NULL && info->has_video && info->is_streaming) {
|
||||||
fragment_size = COMPRESS_OFFLOAD_FRAGMENT_SIZE_FOR_AV_STREAMING;
|
fragment_size = COMPRESS_OFFLOAD_FRAGMENT_SIZE_FOR_AV_STREAMING;
|
||||||
ALOGV("%s: offload fragment size reduced for AV streaming to %d",
|
ALOGV("%s: offload fragment size reduced for AV streaming to %d",
|
||||||
|
@ -2213,3 +2221,190 @@ uint32_t platform_get_pcm_offload_buffer_size(audio_offload_info_t* info)
|
||||||
return fragment_size;
|
return fragment_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool platform_check_24_bit_support() {
|
||||||
|
|
||||||
|
char value[PROPERTY_VALUE_MAX] = {0};
|
||||||
|
property_get("audio.offload.24bit.enable", value, "0");
|
||||||
|
if (atoi(value)) {
|
||||||
|
ALOGW("Property audio.offload.24bit.enable is set");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int platform_set_codec_backend_cfg(struct audio_device* adev,
|
||||||
|
unsigned int bit_width, unsigned int sample_rate)
|
||||||
|
{
|
||||||
|
ALOGV("platform_set_codec_backend_cfg bw %d, sr %d", bit_width, sample_rate);
|
||||||
|
|
||||||
|
int ret = 0;
|
||||||
|
if (bit_width != adev->cur_codec_backend_bit_width) {
|
||||||
|
const char * mixer_ctl_name = "SLIM_0_RX Format";
|
||||||
|
struct mixer_ctl *ctl;
|
||||||
|
ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
|
||||||
|
if (!ctl) {
|
||||||
|
ALOGE("%s: Could not get ctl for mixer command - %s",
|
||||||
|
__func__, mixer_ctl_name);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bit_width == 24) {
|
||||||
|
mixer_ctl_set_enum_by_string(ctl, "S24_LE");
|
||||||
|
} else {
|
||||||
|
mixer_ctl_set_enum_by_string(ctl, "S16_LE");
|
||||||
|
sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
|
||||||
|
}
|
||||||
|
adev->cur_codec_backend_bit_width = bit_width;
|
||||||
|
ALOGE("Backend bit width is set to %d ", bit_width);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((adev->cur_codec_backend_bit_width == CODEC_BACKEND_DEFAULT_BIT_WIDTH &&
|
||||||
|
adev->cur_codec_backend_samplerate != CODEC_BACKEND_DEFAULT_SAMPLE_RATE) ||
|
||||||
|
(adev->cur_codec_backend_samplerate < sample_rate)) {
|
||||||
|
|
||||||
|
char *rate_str = NULL;
|
||||||
|
const char * mixer_ctl_name = "SLIM_0_RX SampleRate";
|
||||||
|
struct mixer_ctl *ctl;
|
||||||
|
|
||||||
|
switch (sample_rate) {
|
||||||
|
case 8000:
|
||||||
|
rate_str = "KHZ_8";
|
||||||
|
break;
|
||||||
|
case 11025:
|
||||||
|
rate_str = "KHZ_11_025";
|
||||||
|
break;
|
||||||
|
case 16000:
|
||||||
|
rate_str = "KHZ_16";
|
||||||
|
break;
|
||||||
|
case 22050:
|
||||||
|
rate_str = "KHZ_22_05";
|
||||||
|
break;
|
||||||
|
case 32000:
|
||||||
|
rate_str = "KHZ_32";
|
||||||
|
break;
|
||||||
|
case 44100:
|
||||||
|
rate_str = "KHZ_44_1";
|
||||||
|
break;
|
||||||
|
case 48000:
|
||||||
|
rate_str = "KHZ_48";
|
||||||
|
break;
|
||||||
|
case 64000:
|
||||||
|
rate_str = "KHZ_64";
|
||||||
|
break;
|
||||||
|
case 88200:
|
||||||
|
rate_str = "KHZ_88_2";
|
||||||
|
break;
|
||||||
|
case 96000:
|
||||||
|
rate_str = "KHZ_96";
|
||||||
|
break;
|
||||||
|
case 176400:
|
||||||
|
rate_str = "KHZ_176_4";
|
||||||
|
break;
|
||||||
|
case 192000:
|
||||||
|
rate_str = "KHZ_192";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
rate_str = "KHZ_48";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
|
||||||
|
if(!ctl) {
|
||||||
|
ALOGE("%s: Could not get ctl for mixer command - %s",
|
||||||
|
__func__, mixer_ctl_name);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ALOGV("Set sample rate as rate_str = %s", rate_str);
|
||||||
|
mixer_ctl_set_enum_by_string(ctl, rate_str);
|
||||||
|
adev->cur_codec_backend_samplerate = sample_rate;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool platform_check_codec_backend_cfg(struct audio_device* adev,
|
||||||
|
struct audio_usecase* usecase,
|
||||||
|
unsigned int* new_bit_width,
|
||||||
|
unsigned int* new_sample_rate)
|
||||||
|
{
|
||||||
|
bool backend_change = false;
|
||||||
|
struct listnode *node;
|
||||||
|
struct stream_out *out = NULL;
|
||||||
|
|
||||||
|
// For voice calls use default configuration
|
||||||
|
// force routing is not required here, caller will do it anyway
|
||||||
|
if (adev->mode == AUDIO_MODE_IN_CALL ||
|
||||||
|
adev->mode == AUDIO_MODE_IN_COMMUNICATION) {
|
||||||
|
ALOGW("%s:Use default bw and sr for voice/voip calls ",__func__);
|
||||||
|
*new_bit_width = CODEC_BACKEND_DEFAULT_BIT_WIDTH;
|
||||||
|
*new_sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
|
||||||
|
backend_change = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (!backend_change) {
|
||||||
|
// go through all the offload usecases, and
|
||||||
|
// find the max bit width and samplerate
|
||||||
|
list_for_each(node, &adev->usecase_list) {
|
||||||
|
struct audio_usecase *curr_usecase;
|
||||||
|
curr_usecase = node_to_item(node, struct audio_usecase, list);
|
||||||
|
if (curr_usecase->id == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
|
||||||
|
struct stream_out *out =
|
||||||
|
(struct stream_out*) curr_usecase->stream.out;
|
||||||
|
if (out != NULL ) {
|
||||||
|
ALOGV("Offload playback running bw %d sr %d",
|
||||||
|
out->bit_width, out->sample_rate);
|
||||||
|
if (*new_bit_width < out->bit_width) {
|
||||||
|
*new_bit_width = out->bit_width;
|
||||||
|
}
|
||||||
|
if (*new_sample_rate < out->sample_rate) {
|
||||||
|
*new_sample_rate = out->sample_rate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Force routing if the expected bitwdith or samplerate
|
||||||
|
// is not same as current backend comfiguration
|
||||||
|
if ((*new_bit_width != adev->cur_codec_backend_bit_width) ||
|
||||||
|
(*new_sample_rate != adev->cur_codec_backend_samplerate)) {
|
||||||
|
backend_change = true;
|
||||||
|
ALOGW("Codec backend needs to be updated");
|
||||||
|
}
|
||||||
|
|
||||||
|
return backend_change;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool platform_check_and_set_codec_backend_cfg(struct audio_device* adev, struct audio_usecase *usecase)
|
||||||
|
{
|
||||||
|
// check if 24bit configuration is enabled first
|
||||||
|
if (!platform_check_24_bit_support()) {
|
||||||
|
ALOGW("24bit not enable, no need to check for backend change");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ALOGV("platform_check_and_set_codec_backend_cfg usecase = %d",usecase->id );
|
||||||
|
|
||||||
|
unsigned int new_bit_width, old_bit_width;
|
||||||
|
unsigned int new_sample_rate, old_sample_rate;
|
||||||
|
|
||||||
|
new_bit_width = old_bit_width = adev->cur_codec_backend_bit_width;
|
||||||
|
new_sample_rate = old_sample_rate = adev->cur_codec_backend_samplerate;
|
||||||
|
|
||||||
|
ALOGW("Codec backend bitwidth %d, samplerate %d", old_bit_width, old_sample_rate);
|
||||||
|
if (platform_check_codec_backend_cfg(adev, usecase,
|
||||||
|
&new_bit_width, &new_sample_rate)) {
|
||||||
|
platform_set_codec_backend_cfg(adev, new_bit_width, new_sample_rate);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (old_bit_width != adev->cur_codec_backend_bit_width ||
|
||||||
|
old_sample_rate != adev->cur_codec_backend_samplerate) {
|
||||||
|
ALOGW("New codec backend bit width %d, sample rate %d",
|
||||||
|
adev->cur_codec_backend_bit_width, adev->cur_codec_backend_samplerate);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
|
@ -21,6 +21,9 @@
|
||||||
#define AUDIO_PLATFORM_API_H
|
#define AUDIO_PLATFORM_API_H
|
||||||
#include <sound/voice_params.h>
|
#include <sound/voice_params.h>
|
||||||
|
|
||||||
|
#define CODEC_BACKEND_DEFAULT_BIT_WIDTH 16
|
||||||
|
#define CODEC_BACKEND_DEFAULT_SAMPLE_RATE 48000
|
||||||
|
|
||||||
void *platform_init(struct audio_device *adev);
|
void *platform_init(struct audio_device *adev);
|
||||||
void platform_deinit(void *platform);
|
void platform_deinit(void *platform);
|
||||||
const char *platform_get_snd_device_name(snd_device_t snd_device);
|
const char *platform_get_snd_device_name(snd_device_t snd_device);
|
||||||
|
@ -80,4 +83,6 @@ struct audio_offload_info_t;
|
||||||
uint32_t platform_get_compress_offload_buffer_size(audio_offload_info_t* info);
|
uint32_t platform_get_compress_offload_buffer_size(audio_offload_info_t* info);
|
||||||
uint32_t platform_get_pcm_offload_buffer_size(audio_offload_info_t* info);
|
uint32_t platform_get_pcm_offload_buffer_size(audio_offload_info_t* info);
|
||||||
|
|
||||||
|
bool platform_check_and_set_codec_backend_cfg(struct audio_device* adev, struct audio_usecase *usecase);
|
||||||
|
bool platform_check_24_bit_support();
|
||||||
#endif // AUDIO_PLATFORM_API_H
|
#endif // AUDIO_PLATFORM_API_H
|
||||||
|
|
Loading…
Reference in New Issue