Loading configs/msm8996/audio_policy.conf +6 −0 Original line number Diff line number Diff line Loading @@ -99,6 +99,12 @@ audio_hw_modules { formats AUDIO_FORMAT_PCM_16_BIT|AUDIO_FORMAT_AMR_NB|AUDIO_FORMAT_AMR_WB|AUDIO_FORMAT_QCELP|AUDIO_FORMAT_EVRC|AUDIO_FORMAT_EVRCB|AUDIO_FORMAT_EVRCWB|AUDIO_FORMAT_EVRCNW devices AUDIO_DEVICE_IN_WIRED_HEADSET|AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET|AUDIO_DEVICE_IN_FM_TUNER|AUDIO_DEVICE_IN_VOICE_CALL } float { sampling_rates 8000|11025|12000|16000|22050|24000|32000|44100|48000|96000|192000 channel_masks AUDIO_CHANNEL_IN_MONO|AUDIO_CHANNEL_IN_STEREO|AUDIO_CHANNEL_IN_FRONT_BACK formats AUDIO_FORMAT_PCM_24_BIT_PACKED devices AUDIO_DEVICE_IN_BUILTIN_MIC|AUDIO_DEVICE_IN_BACK_MIC|AUDIO_DEVICE_IN_WIRED_HEADSET } surround_sound { sampling_rates 8000|11025|12000|16000|22050|24000|32000|44100|48000 channel_masks AUDIO_CHANNEL_IN_5POINT1|AUDIO_CHANNEL_IN_MONO|AUDIO_CHANNEL_IN_STEREO|AUDIO_CHANNEL_IN_FRONT_BACK Loading hal/audio_extn/ssr.c +2 −1 Original line number Diff line number Diff line Loading @@ -344,7 +344,8 @@ int audio_extn_ssr_check_and_set_usecase(struct stream_in *in) if (audio_extn_ssr_get_enabled() && ((channel_count == 2) || (channel_count == 6)) && ((AUDIO_SOURCE_MIC == source) || (AUDIO_SOURCE_CAMCORDER == source)) && ((AUDIO_DEVICE_IN_BUILTIN_MIC == devices) || (AUDIO_DEVICE_IN_BACK_MIC == devices))) { ((AUDIO_DEVICE_IN_BUILTIN_MIC == devices) || (AUDIO_DEVICE_IN_BACK_MIC == devices)) && (in->format == AUDIO_FORMAT_PCM_16_BIT)) { ALOGD("%s: Found SSR use case starting SSR lib with channel_count :%d", __func__, channel_count); Loading hal/audio_hw.c +84 −19 Original line number Diff line number Diff line Loading @@ -751,7 +751,7 @@ static void check_usecases_codec_backend(struct audio_device *adev, } } static void check_and_route_capture_usecases(struct audio_device *adev, static void check_usecases_capture_codec_backend(struct audio_device *adev, struct audio_usecase *uc_info, snd_device_t snd_device) { Loading @@ -760,6 +760,9 @@ static void check_and_route_capture_usecases(struct audio_device *adev, bool switch_device[AUDIO_USECASE_MAX]; int i, num_uc_to_switch = 0; bool force_routing = platform_check_and_set_capture_codec_backend_cfg(adev, uc_info, snd_device); ALOGD("%s:becf: force routing %d", __func__, force_routing); /* * This function is to make sure that all the active capture usecases * are always routed to the same input sound device. Loading @@ -777,7 +780,7 @@ static void check_and_route_capture_usecases(struct audio_device *adev, usecase = node_to_item(node, struct audio_usecase, list); if (usecase->type != PCM_PLAYBACK && usecase != uc_info && usecase->in_snd_device != snd_device && (usecase->in_snd_device != snd_device || force_routing) && ((uc_info->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND) && (((usecase->devices & ~AUDIO_DEVICE_BIT_IN) & AUDIO_DEVICE_IN_ALL_CODEC_BACKEND) || (usecase->type == VOICE_CALL))) && Loading Loading @@ -1149,7 +1152,7 @@ int select_devices(struct audio_device *adev, audio_usecase_t uc_id) } if (in_snd_device != SND_DEVICE_NONE) { check_and_route_capture_usecases(adev, usecase, in_snd_device); check_usecases_capture_codec_backend(adev, usecase, in_snd_device); enable_snd_device(adev, in_snd_device); } Loading Loading @@ -1291,8 +1294,8 @@ int start_input_stream(struct stream_in *in) adev->perf_lock_opts_size); select_devices(adev, in->usecase); ALOGV("%s: Opening PCM device card_id(%d) device_id(%d), channels %d", __func__, adev->snd_card, in->pcm_device_id, in->config.channels); ALOGV("%s: Opening PCM device card_id(%d) device_id(%d), channels %d format %d", __func__, adev->snd_card, in->pcm_device_id, in->config.channels, in->config.format); unsigned int flags = PCM_IN; unsigned int pcm_open_retry_count = 0; Loading Loading @@ -1996,7 +1999,9 @@ static int check_input_parameters(uint32_t sample_rate, { int ret = 0; if ((format != AUDIO_FORMAT_PCM_16_BIT) && if (((format != AUDIO_FORMAT_PCM_16_BIT) && (format != AUDIO_FORMAT_PCM_8_24_BIT) && (format != AUDIO_FORMAT_PCM_24_BIT_PACKED) && (format != AUDIO_FORMAT_PCM_32_BIT) && (format != AUDIO_FORMAT_PCM_FLOAT)) && !voice_extn_compress_voip_is_format_supported(format) && !audio_extn_compr_cap_format_supported(format)) ret = -EINVAL; Loading @@ -2019,6 +2024,8 @@ static int check_input_parameters(uint32_t sample_rate, case 32000: case 44100: case 48000: case 96000: case 192000: break; default: ret = -EINVAL; Loading @@ -2040,9 +2047,8 @@ static size_t get_input_buffer_size(uint32_t sample_rate, size = (sample_rate * AUDIO_CAPTURE_PERIOD_DURATION_MSEC) / 1000; if (is_low_latency) size = configured_low_latency_capture_period_size; /* ToDo: should use frame_size computed based on the format and channel_count here. */ size *= sizeof(short) * channel_count; size *= audio_bytes_per_sample(format) * channel_count; /* make sure the size is multiple of 32 bytes * At 48 kHz mono 16-bit PCM: Loading Loading @@ -3033,6 +3039,7 @@ static ssize_t in_read(struct audio_stream_in *stream, void *buffer, struct audio_device *adev = in->dev; int ret = -1; int snd_scard_state = get_snd_card_state(adev); int *int_buf_stream = NULL; lock_input_stream(in); Loading Loading @@ -3069,17 +3076,31 @@ static ssize_t in_read(struct audio_stream_in *stream, void *buffer, adev->adm_request_focus(adev->adm_data, in->capture_handle); if (in->pcm) { if (audio_extn_ssr_get_stream() == in) if (audio_extn_ssr_get_stream() == in) { ret = audio_extn_ssr_read(stream, buffer, bytes); else if (audio_extn_compr_cap_usecase_supported(in->usecase)) } else if (audio_extn_compr_cap_usecase_supported(in->usecase)) { ret = audio_extn_compr_cap_read(in, buffer, bytes); else if (in->usecase == USECASE_AUDIO_RECORD_AFE_PROXY) } else if (in->usecase == USECASE_AUDIO_RECORD_AFE_PROXY) { ret = pcm_mmap_read(in->pcm, buffer, bytes); else } else { ret = pcm_read(in->pcm, buffer, bytes); if (ret < 0) if ( !ret && bytes > 0 && (in->format == AUDIO_FORMAT_PCM_8_24_BIT)) { if (bytes % 4 == 0) { /* data from DSP comes in 24_8 format, convert it to 8_24 */ int_buf_stream = buffer; for (size_t itt=0; itt < bytes/4 ; itt++) { int_buf_stream[itt] >>= 8; } } else { ALOGE("%s: !!! something wrong !!! ... data not 32 bit aligned ", __func__); ret = -EINVAL; goto exit; } } if (ret < 0) { ret = -errno; } } } if (adev->adm_abandon_focus) adev->adm_abandon_focus(adev->adm_data, in->capture_handle); Loading Loading @@ -3921,9 +3942,8 @@ static int adev_open_input_stream(struct audio_hw_device *dev, } ALOGD("%s: enter: sample_rate(%d) channel_mask(%#x) devices(%#x)\ stream_handle(%p) io_handle(%d) source(%d)",__func__, config->sample_rate, config->channel_mask, devices, &in->stream, handle, source); stream_handle(%p) io_handle(%d) source(%d) format %x",__func__, config->sample_rate, config->channel_mask, devices, &in->stream, handle, source, config->format); pthread_mutex_init(&in->lock, (const pthread_mutexattr_t *) NULL); pthread_mutex_init(&in->pre_lock, (const pthread_mutexattr_t *) NULL); Loading Loading @@ -3963,6 +3983,8 @@ static int adev_open_input_stream(struct audio_hw_device *dev, in->config = pcm_config_audio_capture; in->config.rate = config->sample_rate; in->format = config->format; in->bit_width = 16; in->sample_rate = config->sample_rate; if (in->device == AUDIO_DEVICE_IN_TELEPHONY_RX) { if (adev->mode != AUDIO_MODE_IN_CALL) { Loading @@ -3989,6 +4011,7 @@ static int adev_open_input_stream(struct audio_hw_device *dev, in->config = pcm_config_afe_proxy_record; in->config.channels = channel_count; in->config.rate = config->sample_rate; in->sample_rate = config->sample_rate; } else if (!audio_extn_ssr_check_and_set_usecase(in)) { ALOGD("%s: created surround sound session succesfully",__func__); } else if (audio_extn_compr_cap_enabled() && Loading @@ -3996,6 +4019,48 @@ static int adev_open_input_stream(struct audio_hw_device *dev, (in->dev->mode != AUDIO_MODE_IN_COMMUNICATION)) { audio_extn_compr_cap_init(in); } else { /* restrict 24 bit capture for unprocessed source only * for other sources if 24 bit requested reject 24 and set 16 bit capture only */ if (config->format == AUDIO_FORMAT_DEFAULT) { config->format = AUDIO_FORMAT_PCM_16_BIT; } else if ((config->format == AUDIO_FORMAT_PCM_FLOAT) || (config->format == AUDIO_FORMAT_PCM_32_BIT) || (config->format == AUDIO_FORMAT_PCM_24_BIT_PACKED) || (config->format == AUDIO_FORMAT_PCM_8_24_BIT)) { bool ret_error = false; in->bit_width = 24; /* 24 bit is restricted to UNPROCESSED source only,also format supported from HAL is 24_packed and 8_24 *> In case of UNPROCESSED source, for 24 bit, if format requested is other than 24_packed return error indicating supported format is 24_packed *> In case of any other source requesting 24 bit or float return error indicating format supported is 16 bit only. on error flinger will retry with supported format passed */ if ((source != AUDIO_SOURCE_UNPROCESSED) && (source != AUDIO_SOURCE_CAMCORDER)) { config->format = AUDIO_FORMAT_PCM_16_BIT; if( config->sample_rate > 48000) config->sample_rate = 48000; ret_error = true; } else if (config->format == AUDIO_FORMAT_PCM_24_BIT_PACKED) { in->config.format = PCM_FORMAT_S24_3LE; } else if (config->format == AUDIO_FORMAT_PCM_8_24_BIT) { in->config.format = PCM_FORMAT_S24_LE; } else { config->format = AUDIO_FORMAT_PCM_24_BIT_PACKED; ret_error = true; } if (ret_error) { ret = -EINVAL; goto err_open; } } in->format = config->format; in->config.channels = channel_count; frame_size = audio_stream_in_frame_size(&in->stream); buffer_size = get_input_buffer_size(config->sample_rate, Loading hal/audio_hw.h +2 −1 Original line number Diff line number Diff line Loading @@ -247,7 +247,8 @@ struct stream_in { audio_input_flags_t flags; bool is_st_session; bool is_st_session_active; int sample_rate; int bit_width; struct audio_device *dev; }; Loading hal/msm8916/platform.c +215 −0 Original line number Diff line number Diff line Loading @@ -252,6 +252,7 @@ struct platform_data { void *edid_info; bool edid_valid; codec_backend_cfg_t current_backend_cfg[MAX_CODEC_BACKENDS]; codec_backend_cfg_t current_tx_backend_cfg[MAX_CODEC_TX_BACKENDS]; char ec_ref_mixer_path[64]; char codec_version[CODEC_VERSION_MAX_LENGTH]; int hw_dep_fd; Loading Loading @@ -1809,6 +1810,11 @@ acdb_init_fail: my_data->current_backend_cfg[idx].bit_width = CODEC_BACKEND_DEFAULT_BIT_WIDTH; } my_data->current_tx_backend_cfg[DEFAULT_CODEC_BACKEND].sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE; my_data->current_tx_backend_cfg[DEFAULT_CODEC_BACKEND].bit_width = CODEC_BACKEND_DEFAULT_BIT_WIDTH; if (is_external_codec) { my_data->current_backend_cfg[DEFAULT_CODEC_BACKEND].bitwidth_mixer_ctl = strdup("SLIM_0_RX Format"); Loading @@ -1824,11 +1830,21 @@ acdb_init_fail: strdup("SLIM_6_RX Format"); my_data->current_backend_cfg[HEADPHONE_BACKEND].samplerate_mixer_ctl = strdup("SLIM_6_RX SampleRate"); my_data->current_tx_backend_cfg[DEFAULT_CODEC_BACKEND].bitwidth_mixer_ctl = strdup("SLIM_0_TX Format"); my_data->current_tx_backend_cfg[DEFAULT_CODEC_BACKEND].samplerate_mixer_ctl = strdup("SLIM_0_TX SampleRate"); } else { my_data->current_backend_cfg[DEFAULT_CODEC_BACKEND].bitwidth_mixer_ctl = strdup("MI2S_RX Format"); my_data->current_backend_cfg[DEFAULT_CODEC_BACKEND].samplerate_mixer_ctl = strdup("MI2S_RX SampleRate"); my_data->current_tx_backend_cfg[DEFAULT_CODEC_BACKEND].bitwidth_mixer_ctl = strdup("MI2S_TX Format"); my_data->current_tx_backend_cfg[DEFAULT_CODEC_BACKEND].samplerate_mixer_ctl = strdup("MI2S_TX SampleRate"); } ret = audio_extn_utils_get_codec_version(snd_card_name, Loading Loading @@ -4163,6 +4179,205 @@ bool platform_check_and_set_codec_backend_cfg(struct audio_device* adev, return ret; } /* * configures afe with bit width and Sample Rate */ int platform_set_capture_codec_backend_cfg(struct audio_device* adev, snd_device_t snd_device, unsigned int bit_width, unsigned int sample_rate, audio_format_t format) { int ret = 0; int backend_idx = DEFAULT_CODEC_BACKEND; struct platform_data *my_data = (struct platform_data *)adev->platform; ALOGI("%s:txbecf: afe: bitwidth %d, samplerate %d, backend_idx %d device (%s)", __func__, bit_width, sample_rate, backend_idx, platform_get_snd_device_name(snd_device)); if (bit_width != my_data->current_tx_backend_cfg[backend_idx].bit_width) { struct mixer_ctl *ctl = NULL; ctl = mixer_get_ctl_by_name(adev->mixer, my_data->current_tx_backend_cfg[backend_idx].bitwidth_mixer_ctl); if (!ctl) { ALOGE("%s:txbecf: afe: Could not get ctl for mixer command - %s", __func__, my_data->current_tx_backend_cfg[backend_idx].bitwidth_mixer_ctl); return -EINVAL; } if (bit_width == 24) { if (format == AUDIO_FORMAT_PCM_24_BIT_PACKED) ret = mixer_ctl_set_enum_by_string(ctl, "S24_3LE"); else ret = mixer_ctl_set_enum_by_string(ctl, "S24_LE"); } else { ret = mixer_ctl_set_enum_by_string(ctl, "S16_LE"); } if (ret < 0) { ALOGE("%s:txbecf: afe: Could not set ctl for mixer command - %s", __func__, my_data->current_tx_backend_cfg[backend_idx].bitwidth_mixer_ctl); return -EINVAL; } my_data->current_tx_backend_cfg[backend_idx].bit_width = bit_width; ALOGD("%s:txbecf: afe: %s mixer set to %d bit", __func__, my_data->current_tx_backend_cfg[backend_idx].bitwidth_mixer_ctl, bit_width); } /* * Backend sample rate configuration follows: * 16 bit record - 48khz for streams at any valid sample rate * 24 bit record - 48khz for stream sample rate less than 48khz * 24 bit record - 96khz for sample rate range of 48khz to 96khz * 24 bit record - 192khz for sample rate range of 96khz to 192 khz * Upper limit is inclusive in the sample rate range. */ // TODO: This has to be more dynamic based on policy file if (sample_rate != my_data->current_tx_backend_cfg[(int)backend_idx].sample_rate) { /* * sample rate update is needed only for hifi audio enabled platforms */ char *rate_str = NULL; struct mixer_ctl *ctl = NULL; switch (sample_rate) { case 8000: case 11025: case 16000: case 22050: case 32000: case 44100: case 48000: rate_str = "KHZ_48"; break; case 64000: case 88200: case 96000: rate_str = "KHZ_96"; break; case 176400: case 192000: rate_str = "KHZ_192"; break; default: rate_str = "KHZ_48"; break; } ctl = mixer_get_ctl_by_name(adev->mixer, my_data->current_tx_backend_cfg[backend_idx].samplerate_mixer_ctl); if (ctl < 0) { ALOGE("%s:txbecf: afe: Could not get ctl to set the Sample Rate for mixer command - %s", __func__, my_data->current_tx_backend_cfg[backend_idx].samplerate_mixer_ctl); return -EINVAL; } ALOGD("%s:txbecf: afe: %s set to %s", __func__, my_data->current_tx_backend_cfg[backend_idx].samplerate_mixer_ctl, rate_str); ret = mixer_ctl_set_enum_by_string(ctl, rate_str); if (ret < 0) { ALOGE("%s:txbecf: afe: Could not set ctl for mixer command - %s", __func__, my_data->current_tx_backend_cfg[backend_idx].samplerate_mixer_ctl); return -EINVAL; } my_data->current_tx_backend_cfg[backend_idx].sample_rate = sample_rate; } return ret; } /* * goes through all the current usecases and picks the highest * bitwidth & samplerate */ bool platform_check_capture_codec_backend_cfg(struct audio_device* adev, unsigned int* new_bit_width, unsigned int* new_sample_rate) { bool backend_change = false; unsigned int bit_width; unsigned int sample_rate; int backend_idx = DEFAULT_CODEC_BACKEND; struct platform_data *my_data = (struct platform_data *)adev->platform; bit_width = *new_bit_width; sample_rate = *new_sample_rate; ALOGI("%s:txbecf: afe: Codec selected backend: %d current bit width: %d and " "sample rate: %d",__func__,backend_idx, bit_width, sample_rate); // For voice calls use default configuration i.e. 16b/48K, only applicable to // default backend // force routing is not required here, caller will do it anyway if ((voice_is_in_call(adev) || adev->mode == AUDIO_MODE_IN_COMMUNICATION) || (!is_external_codec)) { ALOGW("%s:txbecf: afe:Use default bw and sr for voice/voip calls", __func__); bit_width = CODEC_BACKEND_DEFAULT_BIT_WIDTH; sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE; } ALOGI("%s:txbecf: afe: Codec selected backend: %d updated bit width: %d and " "sample rate: %d", __func__, backend_idx, bit_width, sample_rate); // Force routing if the expected bitwdith or samplerate // is not same as current backend comfiguration if ((bit_width != my_data->current_tx_backend_cfg[backend_idx].bit_width) || (sample_rate != my_data->current_tx_backend_cfg[backend_idx].sample_rate)) { *new_bit_width = bit_width; *new_sample_rate = sample_rate; backend_change = true; ALOGI("%s:txbecf: afe: Codec backend needs to be updated. new bit width: %d " "new sample rate: %d", __func__, *new_bit_width, *new_sample_rate); } return backend_change; } bool platform_check_and_set_capture_codec_backend_cfg(struct audio_device* adev, struct audio_usecase *usecase, snd_device_t snd_device) { unsigned int new_bit_width; unsigned int new_sample_rate; audio_format_t format = AUDIO_FORMAT_PCM_16_BIT; int backend_idx = DEFAULT_CODEC_BACKEND; int ret = 0; if(usecase->type == PCM_CAPTURE) { new_sample_rate = usecase->stream.in->sample_rate; new_bit_width = usecase->stream.in->bit_width; format = usecase->stream.in->format; } else { new_bit_width = CODEC_BACKEND_DEFAULT_BIT_WIDTH; new_sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE; } ALOGI("%s:txbecf: afe: bitwidth %d, samplerate %d" ", backend_idx %d usecase = %d device (%s)", __func__, new_bit_width, new_sample_rate, backend_idx, usecase->id, platform_get_snd_device_name(snd_device)); if (platform_check_capture_codec_backend_cfg(adev, &new_bit_width, &new_sample_rate)) { ret = platform_set_capture_codec_backend_cfg(adev, snd_device, new_bit_width, new_sample_rate, format); if(!ret) return true; } return false; } int platform_set_snd_device_backend(snd_device_t device, const char *backend_tag, const char * hw_interface) { Loading Loading
configs/msm8996/audio_policy.conf +6 −0 Original line number Diff line number Diff line Loading @@ -99,6 +99,12 @@ audio_hw_modules { formats AUDIO_FORMAT_PCM_16_BIT|AUDIO_FORMAT_AMR_NB|AUDIO_FORMAT_AMR_WB|AUDIO_FORMAT_QCELP|AUDIO_FORMAT_EVRC|AUDIO_FORMAT_EVRCB|AUDIO_FORMAT_EVRCWB|AUDIO_FORMAT_EVRCNW devices AUDIO_DEVICE_IN_WIRED_HEADSET|AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET|AUDIO_DEVICE_IN_FM_TUNER|AUDIO_DEVICE_IN_VOICE_CALL } float { sampling_rates 8000|11025|12000|16000|22050|24000|32000|44100|48000|96000|192000 channel_masks AUDIO_CHANNEL_IN_MONO|AUDIO_CHANNEL_IN_STEREO|AUDIO_CHANNEL_IN_FRONT_BACK formats AUDIO_FORMAT_PCM_24_BIT_PACKED devices AUDIO_DEVICE_IN_BUILTIN_MIC|AUDIO_DEVICE_IN_BACK_MIC|AUDIO_DEVICE_IN_WIRED_HEADSET } surround_sound { sampling_rates 8000|11025|12000|16000|22050|24000|32000|44100|48000 channel_masks AUDIO_CHANNEL_IN_5POINT1|AUDIO_CHANNEL_IN_MONO|AUDIO_CHANNEL_IN_STEREO|AUDIO_CHANNEL_IN_FRONT_BACK Loading
hal/audio_extn/ssr.c +2 −1 Original line number Diff line number Diff line Loading @@ -344,7 +344,8 @@ int audio_extn_ssr_check_and_set_usecase(struct stream_in *in) if (audio_extn_ssr_get_enabled() && ((channel_count == 2) || (channel_count == 6)) && ((AUDIO_SOURCE_MIC == source) || (AUDIO_SOURCE_CAMCORDER == source)) && ((AUDIO_DEVICE_IN_BUILTIN_MIC == devices) || (AUDIO_DEVICE_IN_BACK_MIC == devices))) { ((AUDIO_DEVICE_IN_BUILTIN_MIC == devices) || (AUDIO_DEVICE_IN_BACK_MIC == devices)) && (in->format == AUDIO_FORMAT_PCM_16_BIT)) { ALOGD("%s: Found SSR use case starting SSR lib with channel_count :%d", __func__, channel_count); Loading
hal/audio_hw.c +84 −19 Original line number Diff line number Diff line Loading @@ -751,7 +751,7 @@ static void check_usecases_codec_backend(struct audio_device *adev, } } static void check_and_route_capture_usecases(struct audio_device *adev, static void check_usecases_capture_codec_backend(struct audio_device *adev, struct audio_usecase *uc_info, snd_device_t snd_device) { Loading @@ -760,6 +760,9 @@ static void check_and_route_capture_usecases(struct audio_device *adev, bool switch_device[AUDIO_USECASE_MAX]; int i, num_uc_to_switch = 0; bool force_routing = platform_check_and_set_capture_codec_backend_cfg(adev, uc_info, snd_device); ALOGD("%s:becf: force routing %d", __func__, force_routing); /* * This function is to make sure that all the active capture usecases * are always routed to the same input sound device. Loading @@ -777,7 +780,7 @@ static void check_and_route_capture_usecases(struct audio_device *adev, usecase = node_to_item(node, struct audio_usecase, list); if (usecase->type != PCM_PLAYBACK && usecase != uc_info && usecase->in_snd_device != snd_device && (usecase->in_snd_device != snd_device || force_routing) && ((uc_info->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND) && (((usecase->devices & ~AUDIO_DEVICE_BIT_IN) & AUDIO_DEVICE_IN_ALL_CODEC_BACKEND) || (usecase->type == VOICE_CALL))) && Loading Loading @@ -1149,7 +1152,7 @@ int select_devices(struct audio_device *adev, audio_usecase_t uc_id) } if (in_snd_device != SND_DEVICE_NONE) { check_and_route_capture_usecases(adev, usecase, in_snd_device); check_usecases_capture_codec_backend(adev, usecase, in_snd_device); enable_snd_device(adev, in_snd_device); } Loading Loading @@ -1291,8 +1294,8 @@ int start_input_stream(struct stream_in *in) adev->perf_lock_opts_size); select_devices(adev, in->usecase); ALOGV("%s: Opening PCM device card_id(%d) device_id(%d), channels %d", __func__, adev->snd_card, in->pcm_device_id, in->config.channels); ALOGV("%s: Opening PCM device card_id(%d) device_id(%d), channels %d format %d", __func__, adev->snd_card, in->pcm_device_id, in->config.channels, in->config.format); unsigned int flags = PCM_IN; unsigned int pcm_open_retry_count = 0; Loading Loading @@ -1996,7 +1999,9 @@ static int check_input_parameters(uint32_t sample_rate, { int ret = 0; if ((format != AUDIO_FORMAT_PCM_16_BIT) && if (((format != AUDIO_FORMAT_PCM_16_BIT) && (format != AUDIO_FORMAT_PCM_8_24_BIT) && (format != AUDIO_FORMAT_PCM_24_BIT_PACKED) && (format != AUDIO_FORMAT_PCM_32_BIT) && (format != AUDIO_FORMAT_PCM_FLOAT)) && !voice_extn_compress_voip_is_format_supported(format) && !audio_extn_compr_cap_format_supported(format)) ret = -EINVAL; Loading @@ -2019,6 +2024,8 @@ static int check_input_parameters(uint32_t sample_rate, case 32000: case 44100: case 48000: case 96000: case 192000: break; default: ret = -EINVAL; Loading @@ -2040,9 +2047,8 @@ static size_t get_input_buffer_size(uint32_t sample_rate, size = (sample_rate * AUDIO_CAPTURE_PERIOD_DURATION_MSEC) / 1000; if (is_low_latency) size = configured_low_latency_capture_period_size; /* ToDo: should use frame_size computed based on the format and channel_count here. */ size *= sizeof(short) * channel_count; size *= audio_bytes_per_sample(format) * channel_count; /* make sure the size is multiple of 32 bytes * At 48 kHz mono 16-bit PCM: Loading Loading @@ -3033,6 +3039,7 @@ static ssize_t in_read(struct audio_stream_in *stream, void *buffer, struct audio_device *adev = in->dev; int ret = -1; int snd_scard_state = get_snd_card_state(adev); int *int_buf_stream = NULL; lock_input_stream(in); Loading Loading @@ -3069,17 +3076,31 @@ static ssize_t in_read(struct audio_stream_in *stream, void *buffer, adev->adm_request_focus(adev->adm_data, in->capture_handle); if (in->pcm) { if (audio_extn_ssr_get_stream() == in) if (audio_extn_ssr_get_stream() == in) { ret = audio_extn_ssr_read(stream, buffer, bytes); else if (audio_extn_compr_cap_usecase_supported(in->usecase)) } else if (audio_extn_compr_cap_usecase_supported(in->usecase)) { ret = audio_extn_compr_cap_read(in, buffer, bytes); else if (in->usecase == USECASE_AUDIO_RECORD_AFE_PROXY) } else if (in->usecase == USECASE_AUDIO_RECORD_AFE_PROXY) { ret = pcm_mmap_read(in->pcm, buffer, bytes); else } else { ret = pcm_read(in->pcm, buffer, bytes); if (ret < 0) if ( !ret && bytes > 0 && (in->format == AUDIO_FORMAT_PCM_8_24_BIT)) { if (bytes % 4 == 0) { /* data from DSP comes in 24_8 format, convert it to 8_24 */ int_buf_stream = buffer; for (size_t itt=0; itt < bytes/4 ; itt++) { int_buf_stream[itt] >>= 8; } } else { ALOGE("%s: !!! something wrong !!! ... data not 32 bit aligned ", __func__); ret = -EINVAL; goto exit; } } if (ret < 0) { ret = -errno; } } } if (adev->adm_abandon_focus) adev->adm_abandon_focus(adev->adm_data, in->capture_handle); Loading Loading @@ -3921,9 +3942,8 @@ static int adev_open_input_stream(struct audio_hw_device *dev, } ALOGD("%s: enter: sample_rate(%d) channel_mask(%#x) devices(%#x)\ stream_handle(%p) io_handle(%d) source(%d)",__func__, config->sample_rate, config->channel_mask, devices, &in->stream, handle, source); stream_handle(%p) io_handle(%d) source(%d) format %x",__func__, config->sample_rate, config->channel_mask, devices, &in->stream, handle, source, config->format); pthread_mutex_init(&in->lock, (const pthread_mutexattr_t *) NULL); pthread_mutex_init(&in->pre_lock, (const pthread_mutexattr_t *) NULL); Loading Loading @@ -3963,6 +3983,8 @@ static int adev_open_input_stream(struct audio_hw_device *dev, in->config = pcm_config_audio_capture; in->config.rate = config->sample_rate; in->format = config->format; in->bit_width = 16; in->sample_rate = config->sample_rate; if (in->device == AUDIO_DEVICE_IN_TELEPHONY_RX) { if (adev->mode != AUDIO_MODE_IN_CALL) { Loading @@ -3989,6 +4011,7 @@ static int adev_open_input_stream(struct audio_hw_device *dev, in->config = pcm_config_afe_proxy_record; in->config.channels = channel_count; in->config.rate = config->sample_rate; in->sample_rate = config->sample_rate; } else if (!audio_extn_ssr_check_and_set_usecase(in)) { ALOGD("%s: created surround sound session succesfully",__func__); } else if (audio_extn_compr_cap_enabled() && Loading @@ -3996,6 +4019,48 @@ static int adev_open_input_stream(struct audio_hw_device *dev, (in->dev->mode != AUDIO_MODE_IN_COMMUNICATION)) { audio_extn_compr_cap_init(in); } else { /* restrict 24 bit capture for unprocessed source only * for other sources if 24 bit requested reject 24 and set 16 bit capture only */ if (config->format == AUDIO_FORMAT_DEFAULT) { config->format = AUDIO_FORMAT_PCM_16_BIT; } else if ((config->format == AUDIO_FORMAT_PCM_FLOAT) || (config->format == AUDIO_FORMAT_PCM_32_BIT) || (config->format == AUDIO_FORMAT_PCM_24_BIT_PACKED) || (config->format == AUDIO_FORMAT_PCM_8_24_BIT)) { bool ret_error = false; in->bit_width = 24; /* 24 bit is restricted to UNPROCESSED source only,also format supported from HAL is 24_packed and 8_24 *> In case of UNPROCESSED source, for 24 bit, if format requested is other than 24_packed return error indicating supported format is 24_packed *> In case of any other source requesting 24 bit or float return error indicating format supported is 16 bit only. on error flinger will retry with supported format passed */ if ((source != AUDIO_SOURCE_UNPROCESSED) && (source != AUDIO_SOURCE_CAMCORDER)) { config->format = AUDIO_FORMAT_PCM_16_BIT; if( config->sample_rate > 48000) config->sample_rate = 48000; ret_error = true; } else if (config->format == AUDIO_FORMAT_PCM_24_BIT_PACKED) { in->config.format = PCM_FORMAT_S24_3LE; } else if (config->format == AUDIO_FORMAT_PCM_8_24_BIT) { in->config.format = PCM_FORMAT_S24_LE; } else { config->format = AUDIO_FORMAT_PCM_24_BIT_PACKED; ret_error = true; } if (ret_error) { ret = -EINVAL; goto err_open; } } in->format = config->format; in->config.channels = channel_count; frame_size = audio_stream_in_frame_size(&in->stream); buffer_size = get_input_buffer_size(config->sample_rate, Loading
hal/audio_hw.h +2 −1 Original line number Diff line number Diff line Loading @@ -247,7 +247,8 @@ struct stream_in { audio_input_flags_t flags; bool is_st_session; bool is_st_session_active; int sample_rate; int bit_width; struct audio_device *dev; }; Loading
hal/msm8916/platform.c +215 −0 Original line number Diff line number Diff line Loading @@ -252,6 +252,7 @@ struct platform_data { void *edid_info; bool edid_valid; codec_backend_cfg_t current_backend_cfg[MAX_CODEC_BACKENDS]; codec_backend_cfg_t current_tx_backend_cfg[MAX_CODEC_TX_BACKENDS]; char ec_ref_mixer_path[64]; char codec_version[CODEC_VERSION_MAX_LENGTH]; int hw_dep_fd; Loading Loading @@ -1809,6 +1810,11 @@ acdb_init_fail: my_data->current_backend_cfg[idx].bit_width = CODEC_BACKEND_DEFAULT_BIT_WIDTH; } my_data->current_tx_backend_cfg[DEFAULT_CODEC_BACKEND].sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE; my_data->current_tx_backend_cfg[DEFAULT_CODEC_BACKEND].bit_width = CODEC_BACKEND_DEFAULT_BIT_WIDTH; if (is_external_codec) { my_data->current_backend_cfg[DEFAULT_CODEC_BACKEND].bitwidth_mixer_ctl = strdup("SLIM_0_RX Format"); Loading @@ -1824,11 +1830,21 @@ acdb_init_fail: strdup("SLIM_6_RX Format"); my_data->current_backend_cfg[HEADPHONE_BACKEND].samplerate_mixer_ctl = strdup("SLIM_6_RX SampleRate"); my_data->current_tx_backend_cfg[DEFAULT_CODEC_BACKEND].bitwidth_mixer_ctl = strdup("SLIM_0_TX Format"); my_data->current_tx_backend_cfg[DEFAULT_CODEC_BACKEND].samplerate_mixer_ctl = strdup("SLIM_0_TX SampleRate"); } else { my_data->current_backend_cfg[DEFAULT_CODEC_BACKEND].bitwidth_mixer_ctl = strdup("MI2S_RX Format"); my_data->current_backend_cfg[DEFAULT_CODEC_BACKEND].samplerate_mixer_ctl = strdup("MI2S_RX SampleRate"); my_data->current_tx_backend_cfg[DEFAULT_CODEC_BACKEND].bitwidth_mixer_ctl = strdup("MI2S_TX Format"); my_data->current_tx_backend_cfg[DEFAULT_CODEC_BACKEND].samplerate_mixer_ctl = strdup("MI2S_TX SampleRate"); } ret = audio_extn_utils_get_codec_version(snd_card_name, Loading Loading @@ -4163,6 +4179,205 @@ bool platform_check_and_set_codec_backend_cfg(struct audio_device* adev, return ret; } /* * configures afe with bit width and Sample Rate */ int platform_set_capture_codec_backend_cfg(struct audio_device* adev, snd_device_t snd_device, unsigned int bit_width, unsigned int sample_rate, audio_format_t format) { int ret = 0; int backend_idx = DEFAULT_CODEC_BACKEND; struct platform_data *my_data = (struct platform_data *)adev->platform; ALOGI("%s:txbecf: afe: bitwidth %d, samplerate %d, backend_idx %d device (%s)", __func__, bit_width, sample_rate, backend_idx, platform_get_snd_device_name(snd_device)); if (bit_width != my_data->current_tx_backend_cfg[backend_idx].bit_width) { struct mixer_ctl *ctl = NULL; ctl = mixer_get_ctl_by_name(adev->mixer, my_data->current_tx_backend_cfg[backend_idx].bitwidth_mixer_ctl); if (!ctl) { ALOGE("%s:txbecf: afe: Could not get ctl for mixer command - %s", __func__, my_data->current_tx_backend_cfg[backend_idx].bitwidth_mixer_ctl); return -EINVAL; } if (bit_width == 24) { if (format == AUDIO_FORMAT_PCM_24_BIT_PACKED) ret = mixer_ctl_set_enum_by_string(ctl, "S24_3LE"); else ret = mixer_ctl_set_enum_by_string(ctl, "S24_LE"); } else { ret = mixer_ctl_set_enum_by_string(ctl, "S16_LE"); } if (ret < 0) { ALOGE("%s:txbecf: afe: Could not set ctl for mixer command - %s", __func__, my_data->current_tx_backend_cfg[backend_idx].bitwidth_mixer_ctl); return -EINVAL; } my_data->current_tx_backend_cfg[backend_idx].bit_width = bit_width; ALOGD("%s:txbecf: afe: %s mixer set to %d bit", __func__, my_data->current_tx_backend_cfg[backend_idx].bitwidth_mixer_ctl, bit_width); } /* * Backend sample rate configuration follows: * 16 bit record - 48khz for streams at any valid sample rate * 24 bit record - 48khz for stream sample rate less than 48khz * 24 bit record - 96khz for sample rate range of 48khz to 96khz * 24 bit record - 192khz for sample rate range of 96khz to 192 khz * Upper limit is inclusive in the sample rate range. */ // TODO: This has to be more dynamic based on policy file if (sample_rate != my_data->current_tx_backend_cfg[(int)backend_idx].sample_rate) { /* * sample rate update is needed only for hifi audio enabled platforms */ char *rate_str = NULL; struct mixer_ctl *ctl = NULL; switch (sample_rate) { case 8000: case 11025: case 16000: case 22050: case 32000: case 44100: case 48000: rate_str = "KHZ_48"; break; case 64000: case 88200: case 96000: rate_str = "KHZ_96"; break; case 176400: case 192000: rate_str = "KHZ_192"; break; default: rate_str = "KHZ_48"; break; } ctl = mixer_get_ctl_by_name(adev->mixer, my_data->current_tx_backend_cfg[backend_idx].samplerate_mixer_ctl); if (ctl < 0) { ALOGE("%s:txbecf: afe: Could not get ctl to set the Sample Rate for mixer command - %s", __func__, my_data->current_tx_backend_cfg[backend_idx].samplerate_mixer_ctl); return -EINVAL; } ALOGD("%s:txbecf: afe: %s set to %s", __func__, my_data->current_tx_backend_cfg[backend_idx].samplerate_mixer_ctl, rate_str); ret = mixer_ctl_set_enum_by_string(ctl, rate_str); if (ret < 0) { ALOGE("%s:txbecf: afe: Could not set ctl for mixer command - %s", __func__, my_data->current_tx_backend_cfg[backend_idx].samplerate_mixer_ctl); return -EINVAL; } my_data->current_tx_backend_cfg[backend_idx].sample_rate = sample_rate; } return ret; } /* * goes through all the current usecases and picks the highest * bitwidth & samplerate */ bool platform_check_capture_codec_backend_cfg(struct audio_device* adev, unsigned int* new_bit_width, unsigned int* new_sample_rate) { bool backend_change = false; unsigned int bit_width; unsigned int sample_rate; int backend_idx = DEFAULT_CODEC_BACKEND; struct platform_data *my_data = (struct platform_data *)adev->platform; bit_width = *new_bit_width; sample_rate = *new_sample_rate; ALOGI("%s:txbecf: afe: Codec selected backend: %d current bit width: %d and " "sample rate: %d",__func__,backend_idx, bit_width, sample_rate); // For voice calls use default configuration i.e. 16b/48K, only applicable to // default backend // force routing is not required here, caller will do it anyway if ((voice_is_in_call(adev) || adev->mode == AUDIO_MODE_IN_COMMUNICATION) || (!is_external_codec)) { ALOGW("%s:txbecf: afe:Use default bw and sr for voice/voip calls", __func__); bit_width = CODEC_BACKEND_DEFAULT_BIT_WIDTH; sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE; } ALOGI("%s:txbecf: afe: Codec selected backend: %d updated bit width: %d and " "sample rate: %d", __func__, backend_idx, bit_width, sample_rate); // Force routing if the expected bitwdith or samplerate // is not same as current backend comfiguration if ((bit_width != my_data->current_tx_backend_cfg[backend_idx].bit_width) || (sample_rate != my_data->current_tx_backend_cfg[backend_idx].sample_rate)) { *new_bit_width = bit_width; *new_sample_rate = sample_rate; backend_change = true; ALOGI("%s:txbecf: afe: Codec backend needs to be updated. new bit width: %d " "new sample rate: %d", __func__, *new_bit_width, *new_sample_rate); } return backend_change; } bool platform_check_and_set_capture_codec_backend_cfg(struct audio_device* adev, struct audio_usecase *usecase, snd_device_t snd_device) { unsigned int new_bit_width; unsigned int new_sample_rate; audio_format_t format = AUDIO_FORMAT_PCM_16_BIT; int backend_idx = DEFAULT_CODEC_BACKEND; int ret = 0; if(usecase->type == PCM_CAPTURE) { new_sample_rate = usecase->stream.in->sample_rate; new_bit_width = usecase->stream.in->bit_width; format = usecase->stream.in->format; } else { new_bit_width = CODEC_BACKEND_DEFAULT_BIT_WIDTH; new_sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE; } ALOGI("%s:txbecf: afe: bitwidth %d, samplerate %d" ", backend_idx %d usecase = %d device (%s)", __func__, new_bit_width, new_sample_rate, backend_idx, usecase->id, platform_get_snd_device_name(snd_device)); if (platform_check_capture_codec_backend_cfg(adev, &new_bit_width, &new_sample_rate)) { ret = platform_set_capture_codec_backend_cfg(adev, snd_device, new_bit_width, new_sample_rate, format); if(!ret) return true; } return false; } int platform_set_snd_device_backend(snd_device_t device, const char *backend_tag, const char * hw_interface) { Loading