Loading hal/audio_hw.c +160 −40 Original line number Diff line number Diff line Loading @@ -60,6 +60,8 @@ #define COMPRESS_OFFLOAD_PLAYBACK_LATENCY 96 #define COMPRESS_PLAYBACK_VOLUME_MAX 0x2000 #define PROXY_OPEN_RETRY_COUNT 100 #define PROXY_OPEN_WAIT_TIME 20 #define USECASE_AUDIO_PLAYBACK_PRIMARY USECASE_AUDIO_PLAYBACK_DEEP_BUFFER Loading Loading @@ -102,6 +104,37 @@ struct pcm_config pcm_config_audio_capture = { .format = PCM_FORMAT_S16_LE, }; #define AFE_PROXY_CHANNEL_COUNT 2 #define AFE_PROXY_SAMPLING_RATE 48000 #define AFE_PROXY_PLAYBACK_PERIOD_SIZE 768 #define AFE_PROXY_PLAYBACK_PERIOD_COUNT 4 struct pcm_config pcm_config_afe_proxy_playback = { .channels = AFE_PROXY_CHANNEL_COUNT, .rate = AFE_PROXY_SAMPLING_RATE, .period_size = AFE_PROXY_PLAYBACK_PERIOD_SIZE, .period_count = AFE_PROXY_PLAYBACK_PERIOD_COUNT, .format = PCM_FORMAT_S16_LE, .start_threshold = AFE_PROXY_PLAYBACK_PERIOD_SIZE, .stop_threshold = INT_MAX, .avail_min = AFE_PROXY_PLAYBACK_PERIOD_SIZE, }; #define AFE_PROXY_RECORD_PERIOD_SIZE 768 #define AFE_PROXY_RECORD_PERIOD_COUNT 4 struct pcm_config pcm_config_afe_proxy_record = { .channels = AFE_PROXY_CHANNEL_COUNT, .rate = AFE_PROXY_SAMPLING_RATE, .period_size = AFE_PROXY_RECORD_PERIOD_SIZE, .period_count = AFE_PROXY_RECORD_PERIOD_COUNT, .format = PCM_FORMAT_S16_LE, .start_threshold = AFE_PROXY_RECORD_PERIOD_SIZE, .stop_threshold = INT_MAX, .avail_min = AFE_PROXY_RECORD_PERIOD_SIZE, }; const char * const use_case_table[AUDIO_USECASE_MAX] = { [USECASE_AUDIO_PLAYBACK_DEEP_BUFFER] = "deep-buffer-playback", [USECASE_AUDIO_PLAYBACK_LOW_LATENCY] = "low-latency-playback", Loading Loading @@ -132,6 +165,9 @@ const char * const use_case_table[AUDIO_USECASE_MAX] = { [USECASE_INCALL_MUSIC_UPLINK2] = "incall_music_uplink2", [USECASE_AUDIO_SPKR_CALIB_RX] = "spkr-rx-calib", [USECASE_AUDIO_SPKR_CALIB_TX] = "spkr-vi-record", [USECASE_AUDIO_PLAYBACK_AFE_PROXY] = "afe-proxy-playback", [USECASE_AUDIO_RECORD_AFE_PROXY] = "afe-proxy-record", }; Loading Loading @@ -375,7 +411,6 @@ int disable_snd_device(struct audio_device *adev, /* exit usb capture thread */ if(SND_DEVICE_IN_USB_HEADSET_MIC == snd_device) audio_extn_usb_stop_capture(); if (snd_device == SND_DEVICE_OUT_SPEAKER && audio_extn_spkr_prot_is_enabled()) { audio_extn_spkr_prot_stop_processing(); Loading Loading @@ -661,14 +696,14 @@ int select_devices(struct audio_device *adev, audio_usecase_t uc_id) usecase->devices = usecase->stream.in->device; out_snd_device = SND_DEVICE_NONE; if (in_snd_device == SND_DEVICE_NONE) { audio_devices_t out_device = AUDIO_DEVICE_NONE; if ((adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION || (adev->mode == AUDIO_MODE_IN_COMMUNICATION && adev->active_input->source == AUDIO_SOURCE_MIC)) && adev->primary_output && !adev->primary_output->standby) { in_snd_device = platform_get_input_snd_device(adev->platform, adev->primary_output->devices); } else { in_snd_device = platform_get_input_snd_device(adev->platform, AUDIO_DEVICE_NONE); out_device = adev->primary_output->devices; } else if(usecase->id == USECASE_AUDIO_RECORD_AFE_PROXY) { out_device = AUDIO_DEVICE_OUT_TELEPHONY_TX; } in_snd_device = platform_get_input_snd_device(adev->platform, out_device); } } } Loading Loading @@ -812,17 +847,34 @@ int start_input_stream(struct stream_in *in) 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); in->pcm = pcm_open(adev->snd_card, in->pcm_device_id, PCM_IN, &in->config); if (in->pcm && !pcm_is_ready(in->pcm)) { __func__, adev->snd_card, in->pcm_device_id, in->config.channels); unsigned int flags = PCM_IN; unsigned int pcm_open_retry_entry_count = 0; if (in->usecase == USECASE_AUDIO_RECORD_AFE_PROXY) { flags |= PCM_MMAP | PCM_NOIRQ; pcm_open_retry_entry_count = PROXY_OPEN_RETRY_COUNT; } while(1) { in->pcm = pcm_open(adev->snd_card, in->pcm_device_id, flags, &in->config); if (in->pcm == NULL || !pcm_is_ready(in->pcm)) { ALOGE("%s: %s", __func__, pcm_get_error(in->pcm)); if (in->pcm != NULL) { pcm_close(in->pcm); in->pcm = NULL; } if (pcm_open_retry_entry_count-- == 0) { ret = -EIO; goto error_open; } usleep(PROXY_OPEN_WAIT_TIME * 1000); continue; } break; } ALOGV("%s: exit", __func__); return ret; Loading Loading @@ -1150,16 +1202,32 @@ int start_output_stream(struct stream_out *out) ALOGV("%s: Opening PCM device card_id(%d) device_id(%d)", __func__, 0, out->pcm_device_id); if (out->usecase != USECASE_AUDIO_PLAYBACK_OFFLOAD) { out->pcm = pcm_open(adev->snd_card, out->pcm_device_id, PCM_OUT | PCM_MONOTONIC, &out->config); unsigned int flags = PCM_OUT; unsigned int pcm_open_retry_count = 0; if (out->usecase == USECASE_AUDIO_PLAYBACK_AFE_PROXY) { flags |= PCM_MMAP | PCM_NOIRQ; pcm_open_retry_count = PROXY_OPEN_RETRY_COUNT; } else flags |= PCM_MONOTONIC; while (1) { out->pcm = pcm_open(adev->snd_card, out->pcm_device_id, flags, &out->config); if (out->pcm && !pcm_is_ready(out->pcm)) { ALOGE("%s: %s", __func__, pcm_get_error(out->pcm)); if (out->pcm != NULL) { pcm_close(out->pcm); out->pcm = NULL; } if (pcm_open_retry_count-- == 0) { ret = -EIO; goto error_open; } usleep(PROXY_OPEN_WAIT_TIME * 1000); continue; } break; } } else { out->pcm = NULL; out->compr = compress_open(adev->snd_card, Loading Loading @@ -1397,6 +1465,10 @@ static int parse_compress_metadata(struct stream_out *out, struct str_parms *par return 0; } static bool output_drives_call(struct audio_device *adev, struct stream_out *out) { return out == adev->primary_output || out == adev->voice_tx_output; } static int out_set_parameters(struct audio_stream *stream, const char *kvpairs) { Loading Loading @@ -1431,6 +1503,13 @@ static int out_set_parameters(struct audio_stream *stream, const char *kvpairs) val = AUDIO_DEVICE_OUT_SPEAKER; } if ((adev->mode == AUDIO_MODE_NORMAL) && voice_is_in_call(adev) && output_drives_call(adev, out)) { ret = voice_stop_call(adev); adev->current_call_output = NULL; } /* * select_devices() call below switches all the usecases on the same * backend to the new device. Refer to check_usecases_codec_backend() in Loading @@ -1456,20 +1535,14 @@ static int out_set_parameters(struct audio_stream *stream, const char *kvpairs) select_devices(adev, out->usecase); if ((adev->mode == AUDIO_MODE_IN_CALL) && !voice_is_in_call(adev) && (out == adev->primary_output)) { output_drives_call(adev, out)) { adev->current_call_output = out; if (!voice_is_in_call(adev)) ret = voice_start_call(adev); } else if ((adev->mode == AUDIO_MODE_IN_CALL) && voice_is_in_call(adev) && (out == adev->primary_output)) { else voice_update_devices_for_all_voice_usecases(adev); } } if ((adev->mode == AUDIO_MODE_NORMAL) && voice_is_in_call(adev) && (out == adev->primary_output)) { ret = voice_stop_call(adev); } pthread_mutex_unlock(&adev->lock); Loading Loading @@ -1629,6 +1702,9 @@ static ssize_t out_write(struct audio_stream_out *stream, const void *buffer, if (out->muted) memset((void *)buffer, 0, bytes); ALOGVV("%s: writing buffer (%d bytes) to pcm device", __func__, bytes); if (out->usecase == USECASE_AUDIO_PLAYBACK_AFE_PROXY) ret = pcm_mmap_write(out->pcm, (void *)buffer, bytes); else ret = pcm_write(out->pcm, (void *)buffer, bytes); if (ret == 0) out->written += bytes / (out->config.channels * sizeof(short)); Loading Loading @@ -1923,7 +1999,7 @@ static int in_set_parameters(struct audio_stream *stream, const char *kvpairs) err = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value)); if (err >= 0) { val = atoi(value); if ((in->device != val) && (val != 0)) { if (((int)in->device != val) && (val != 0)) { in->device = val; /* If recording is in progress, change the tx device to new device */ if (!in->standby) Loading Loading @@ -1991,6 +2067,8 @@ static ssize_t in_read(struct audio_stream_in *stream, void *buffer, ret = audio_extn_ssr_read(stream, buffer, bytes); 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) ret = pcm_mmap_read(in->pcm, buffer, bytes); else ret = pcm_read(in->pcm, buffer, bytes); } Loading Loading @@ -2238,6 +2316,28 @@ static int adev_open_output_stream(struct audio_hw_device *dev, goto error_open; } #endif } else if (out->devices == AUDIO_DEVICE_OUT_TELEPHONY_TX) { if (config->sample_rate == 0) config->sample_rate = AFE_PROXY_SAMPLING_RATE; if (config->sample_rate != 48000 && config->sample_rate != 16000 && config->sample_rate != 8000) { config->sample_rate = AFE_PROXY_SAMPLING_RATE; ret = -EINVAL; goto error_open; } out->sample_rate = config->sample_rate; out->config.rate = config->sample_rate; if (config->format == AUDIO_FORMAT_DEFAULT) config->format = AUDIO_FORMAT_PCM_16_BIT; if (config->format != AUDIO_FORMAT_PCM_16_BIT) { config->format = AUDIO_FORMAT_PCM_16_BIT; ret = -EINVAL; goto error_open; } out->format = config->format; out->usecase = USECASE_AUDIO_PLAYBACK_AFE_PROXY; out->config = pcm_config_afe_proxy_playback; adev->voice_tx_output = out; } else if (out->flags & AUDIO_OUTPUT_FLAG_FAST) { out->usecase = USECASE_AUDIO_PLAYBACK_LOW_LATENCY; out->config = pcm_config_low_latency; Loading Loading @@ -2572,7 +2672,27 @@ static int adev_open_input_stream(struct audio_hw_device *dev, in->config.rate = config->sample_rate; in->format = config->format; if (channel_count == 6) { if (in->device == AUDIO_DEVICE_IN_TELEPHONY_RX) { if (config->sample_rate == 0) config->sample_rate = AFE_PROXY_SAMPLING_RATE; if (config->sample_rate != 48000 && config->sample_rate != 16000 && config->sample_rate != 8000) { config->sample_rate = AFE_PROXY_SAMPLING_RATE; ret = -EINVAL; goto err_open; } if (config->format == AUDIO_FORMAT_DEFAULT) config->format = AUDIO_FORMAT_PCM_16_BIT; if (config->format != AUDIO_FORMAT_PCM_16_BIT) { config->format = AUDIO_FORMAT_PCM_16_BIT; ret = -EINVAL; goto err_open; } in->usecase = USECASE_AUDIO_RECORD_AFE_PROXY; in->config = pcm_config_afe_proxy_record; in->config.channels = channel_count; in->config.rate = config->sample_rate; } else if (channel_count == 6) { if(audio_extn_ssr_get_enabled()) { if(audio_extn_ssr_init(adev, in)) { ALOGE("%s: audio_extn_ssr_init failed", __func__); Loading hal/audio_hw.h +7 −1 Original line number Diff line number Diff line Loading @@ -98,6 +98,10 @@ typedef enum { USECASE_AUDIO_SPKR_CALIB_RX, USECASE_AUDIO_SPKR_CALIB_TX, USECASE_AUDIO_PLAYBACK_AFE_PROXY, USECASE_AUDIO_RECORD_AFE_PROXY, AUDIO_USECASE_MAX } audio_usecase_t; Loading Loading @@ -177,7 +181,7 @@ struct stream_in { int standby; int source; int pcm_device_id; int device; audio_devices_t device; audio_channel_mask_t channel_mask; audio_usecase_t usecase; bool enable_aec; Loading Loading @@ -218,6 +222,8 @@ struct audio_device { audio_devices_t out_device; struct stream_in *active_input; struct stream_out *primary_output; struct stream_out *voice_tx_output; struct stream_out *current_call_output; bool bluetooth_nrec; bool screen_off; int *snd_dev_ref_cnt; Loading hal/msm8960/platform.h +3 −0 Original line number Diff line number Diff line Loading @@ -118,4 +118,7 @@ enum { #define AUDIO_CAPTURE_PERIOD_DURATION_MSEC 20 #define AUDIO_CAPTURE_PERIOD_COUNT 2 #define AFE_PROXY_PLAYBACK_PCM_DEVICE 7 #define AFE_PROXY_RECORD_PCM_DEVICE 8 #endif // QCOM_AUDIO_PLATFORM_H hal/msm8974/platform.c +18 −2 Original line number Diff line number Diff line Loading @@ -165,6 +165,11 @@ static const int pcm_device_table[AUDIO_USECASE_MAX][2] = { INCALL_MUSIC_UPLINK2_PCM_DEVICE}, [USECASE_AUDIO_SPKR_CALIB_RX] = {SPKR_PROT_CALIB_RX_PCM_DEVICE, -1}, [USECASE_AUDIO_SPKR_CALIB_TX] = {-1, SPKR_PROT_CALIB_TX_PCM_DEVICE}, [USECASE_AUDIO_PLAYBACK_AFE_PROXY] = {AFE_PROXY_PLAYBACK_PCM_DEVICE, AFE_PROXY_RECORD_PCM_DEVICE}, [USECASE_AUDIO_RECORD_AFE_PROXY] = {AFE_PROXY_PLAYBACK_PCM_DEVICE, AFE_PROXY_RECORD_PCM_DEVICE}, }; /* Array to store sound devices */ Loading @@ -186,6 +191,7 @@ static const char * const device_table[SND_DEVICE_MAX] = { [SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES] = "voice-tty-full-headphones", [SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES] = "voice-tty-vco-headphones", [SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET] = "voice-tty-hco-handset", [SND_DEVICE_OUT_VOICE_TX] = "voice-tx", [SND_DEVICE_OUT_AFE_PROXY] = "afe-proxy", [SND_DEVICE_OUT_USB_HEADSET] = "usb-headphones", [SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET] = "speaker-and-usb-headphones", Loading Loading @@ -229,6 +235,7 @@ static const char * const device_table[SND_DEVICE_MAX] = { [SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC] = "voice-tty-full-headset-mic", [SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC] = "voice-tty-vco-handset-mic", [SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC] = "voice-tty-hco-headset-mic", [SND_DEVICE_IN_VOICE_RX] = "voice-rx", [SND_DEVICE_IN_VOICE_REC_MIC] = "voice-rec-mic", [SND_DEVICE_IN_VOICE_REC_MIC_NS] = "voice-rec-mic", [SND_DEVICE_IN_VOICE_REC_DMIC_STEREO] = "voice-rec-dmic-ef", Loading Loading @@ -260,6 +267,7 @@ static int acdb_device_table[SND_DEVICE_MAX] = { [SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES] = 17, [SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES] = 17, [SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET] = 37, [SND_DEVICE_OUT_VOICE_TX] = 45, [SND_DEVICE_OUT_AFE_PROXY] = 0, [SND_DEVICE_OUT_USB_HEADSET] = 0, [SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET] = 14, Loading Loading @@ -302,6 +310,7 @@ static int acdb_device_table[SND_DEVICE_MAX] = { [SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC] = 16, [SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC] = 36, [SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC] = 16, [SND_DEVICE_IN_VOICE_RX] = 44, [SND_DEVICE_IN_VOICE_REC_MIC] = 4, [SND_DEVICE_IN_VOICE_REC_MIC_NS] = 107, [SND_DEVICE_IN_VOICE_REC_DMIC_STEREO] = 34, Loading Loading @@ -662,6 +671,10 @@ void platform_add_backend_name(char *mixer_path, snd_device_t snd_device) strlcat(mixer_path, " hdmi", MIXER_PATH_MAX_LENGTH); else if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_HDMI) strcat(mixer_path, " speaker-and-hdmi"); else if (snd_device == SND_DEVICE_OUT_VOICE_TX) strlcat(mixer_path, " afe-proxy", MIXER_PATH_MAX_LENGTH); else if (snd_device == SND_DEVICE_IN_VOICE_RX) strlcat(mixer_path, " afe-proxy", MIXER_PATH_MAX_LENGTH); else if (snd_device == SND_DEVICE_OUT_AFE_PROXY) strlcat(mixer_path, " afe-proxy", MIXER_PATH_MAX_LENGTH); else if (snd_device == SND_DEVICE_OUT_USB_HEADSET) Loading Loading @@ -1080,7 +1093,9 @@ snd_device_t platform_get_output_snd_device(void *platform, audio_devices_t devi snd_device = SND_DEVICE_OUT_ANC_HANDSET; else snd_device = SND_DEVICE_OUT_VOICE_HANDSET; } } else if (devices & AUDIO_DEVICE_OUT_TELEPHONY_TX) snd_device = SND_DEVICE_OUT_VOICE_TX; if (snd_device != SND_DEVICE_NONE) { goto exit; } Loading Loading @@ -1212,7 +1227,8 @@ snd_device_t platform_get_input_snd_device(void *platform, audio_devices_t out_d snd_device = SND_DEVICE_IN_VOICE_SPEAKER_MIC; set_echo_reference(adev, true); } } } else if (out_device & AUDIO_DEVICE_OUT_TELEPHONY_TX) snd_device = SND_DEVICE_IN_VOICE_RX; } else if (source == AUDIO_SOURCE_CAMCORDER) { if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC || in_device & AUDIO_DEVICE_IN_BACK_MIC) { Loading hal/msm8974/platform.h +5 −0 Original line number Diff line number Diff line Loading @@ -60,6 +60,7 @@ enum { SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES, SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES, SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET, SND_DEVICE_OUT_VOICE_TX, SND_DEVICE_OUT_AFE_PROXY, SND_DEVICE_OUT_USB_HEADSET, SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET, Loading Loading @@ -113,6 +114,7 @@ enum { SND_DEVICE_IN_VOICE_REC_MIC_NS, SND_DEVICE_IN_VOICE_REC_DMIC_STEREO, SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE, SND_DEVICE_IN_VOICE_RX, SND_DEVICE_IN_USB_HEADSET_MIC, SND_DEVICE_IN_CAPTURE_FM, SND_DEVICE_IN_AANC_HANDSET_MIC, Loading Loading @@ -223,6 +225,9 @@ enum { #define VOWLAN_CALL_PCM_DEVICE 36 #endif #define AFE_PROXY_PLAYBACK_PCM_DEVICE 7 #define AFE_PROXY_RECORD_PCM_DEVICE 8 #ifdef PLATFORM_MSM8x26 #define HFP_SCO_RX 28 #define HFP_ASM_RX_TX 29 Loading Loading
hal/audio_hw.c +160 −40 Original line number Diff line number Diff line Loading @@ -60,6 +60,8 @@ #define COMPRESS_OFFLOAD_PLAYBACK_LATENCY 96 #define COMPRESS_PLAYBACK_VOLUME_MAX 0x2000 #define PROXY_OPEN_RETRY_COUNT 100 #define PROXY_OPEN_WAIT_TIME 20 #define USECASE_AUDIO_PLAYBACK_PRIMARY USECASE_AUDIO_PLAYBACK_DEEP_BUFFER Loading Loading @@ -102,6 +104,37 @@ struct pcm_config pcm_config_audio_capture = { .format = PCM_FORMAT_S16_LE, }; #define AFE_PROXY_CHANNEL_COUNT 2 #define AFE_PROXY_SAMPLING_RATE 48000 #define AFE_PROXY_PLAYBACK_PERIOD_SIZE 768 #define AFE_PROXY_PLAYBACK_PERIOD_COUNT 4 struct pcm_config pcm_config_afe_proxy_playback = { .channels = AFE_PROXY_CHANNEL_COUNT, .rate = AFE_PROXY_SAMPLING_RATE, .period_size = AFE_PROXY_PLAYBACK_PERIOD_SIZE, .period_count = AFE_PROXY_PLAYBACK_PERIOD_COUNT, .format = PCM_FORMAT_S16_LE, .start_threshold = AFE_PROXY_PLAYBACK_PERIOD_SIZE, .stop_threshold = INT_MAX, .avail_min = AFE_PROXY_PLAYBACK_PERIOD_SIZE, }; #define AFE_PROXY_RECORD_PERIOD_SIZE 768 #define AFE_PROXY_RECORD_PERIOD_COUNT 4 struct pcm_config pcm_config_afe_proxy_record = { .channels = AFE_PROXY_CHANNEL_COUNT, .rate = AFE_PROXY_SAMPLING_RATE, .period_size = AFE_PROXY_RECORD_PERIOD_SIZE, .period_count = AFE_PROXY_RECORD_PERIOD_COUNT, .format = PCM_FORMAT_S16_LE, .start_threshold = AFE_PROXY_RECORD_PERIOD_SIZE, .stop_threshold = INT_MAX, .avail_min = AFE_PROXY_RECORD_PERIOD_SIZE, }; const char * const use_case_table[AUDIO_USECASE_MAX] = { [USECASE_AUDIO_PLAYBACK_DEEP_BUFFER] = "deep-buffer-playback", [USECASE_AUDIO_PLAYBACK_LOW_LATENCY] = "low-latency-playback", Loading Loading @@ -132,6 +165,9 @@ const char * const use_case_table[AUDIO_USECASE_MAX] = { [USECASE_INCALL_MUSIC_UPLINK2] = "incall_music_uplink2", [USECASE_AUDIO_SPKR_CALIB_RX] = "spkr-rx-calib", [USECASE_AUDIO_SPKR_CALIB_TX] = "spkr-vi-record", [USECASE_AUDIO_PLAYBACK_AFE_PROXY] = "afe-proxy-playback", [USECASE_AUDIO_RECORD_AFE_PROXY] = "afe-proxy-record", }; Loading Loading @@ -375,7 +411,6 @@ int disable_snd_device(struct audio_device *adev, /* exit usb capture thread */ if(SND_DEVICE_IN_USB_HEADSET_MIC == snd_device) audio_extn_usb_stop_capture(); if (snd_device == SND_DEVICE_OUT_SPEAKER && audio_extn_spkr_prot_is_enabled()) { audio_extn_spkr_prot_stop_processing(); Loading Loading @@ -661,14 +696,14 @@ int select_devices(struct audio_device *adev, audio_usecase_t uc_id) usecase->devices = usecase->stream.in->device; out_snd_device = SND_DEVICE_NONE; if (in_snd_device == SND_DEVICE_NONE) { audio_devices_t out_device = AUDIO_DEVICE_NONE; if ((adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION || (adev->mode == AUDIO_MODE_IN_COMMUNICATION && adev->active_input->source == AUDIO_SOURCE_MIC)) && adev->primary_output && !adev->primary_output->standby) { in_snd_device = platform_get_input_snd_device(adev->platform, adev->primary_output->devices); } else { in_snd_device = platform_get_input_snd_device(adev->platform, AUDIO_DEVICE_NONE); out_device = adev->primary_output->devices; } else if(usecase->id == USECASE_AUDIO_RECORD_AFE_PROXY) { out_device = AUDIO_DEVICE_OUT_TELEPHONY_TX; } in_snd_device = platform_get_input_snd_device(adev->platform, out_device); } } } Loading Loading @@ -812,17 +847,34 @@ int start_input_stream(struct stream_in *in) 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); in->pcm = pcm_open(adev->snd_card, in->pcm_device_id, PCM_IN, &in->config); if (in->pcm && !pcm_is_ready(in->pcm)) { __func__, adev->snd_card, in->pcm_device_id, in->config.channels); unsigned int flags = PCM_IN; unsigned int pcm_open_retry_entry_count = 0; if (in->usecase == USECASE_AUDIO_RECORD_AFE_PROXY) { flags |= PCM_MMAP | PCM_NOIRQ; pcm_open_retry_entry_count = PROXY_OPEN_RETRY_COUNT; } while(1) { in->pcm = pcm_open(adev->snd_card, in->pcm_device_id, flags, &in->config); if (in->pcm == NULL || !pcm_is_ready(in->pcm)) { ALOGE("%s: %s", __func__, pcm_get_error(in->pcm)); if (in->pcm != NULL) { pcm_close(in->pcm); in->pcm = NULL; } if (pcm_open_retry_entry_count-- == 0) { ret = -EIO; goto error_open; } usleep(PROXY_OPEN_WAIT_TIME * 1000); continue; } break; } ALOGV("%s: exit", __func__); return ret; Loading Loading @@ -1150,16 +1202,32 @@ int start_output_stream(struct stream_out *out) ALOGV("%s: Opening PCM device card_id(%d) device_id(%d)", __func__, 0, out->pcm_device_id); if (out->usecase != USECASE_AUDIO_PLAYBACK_OFFLOAD) { out->pcm = pcm_open(adev->snd_card, out->pcm_device_id, PCM_OUT | PCM_MONOTONIC, &out->config); unsigned int flags = PCM_OUT; unsigned int pcm_open_retry_count = 0; if (out->usecase == USECASE_AUDIO_PLAYBACK_AFE_PROXY) { flags |= PCM_MMAP | PCM_NOIRQ; pcm_open_retry_count = PROXY_OPEN_RETRY_COUNT; } else flags |= PCM_MONOTONIC; while (1) { out->pcm = pcm_open(adev->snd_card, out->pcm_device_id, flags, &out->config); if (out->pcm && !pcm_is_ready(out->pcm)) { ALOGE("%s: %s", __func__, pcm_get_error(out->pcm)); if (out->pcm != NULL) { pcm_close(out->pcm); out->pcm = NULL; } if (pcm_open_retry_count-- == 0) { ret = -EIO; goto error_open; } usleep(PROXY_OPEN_WAIT_TIME * 1000); continue; } break; } } else { out->pcm = NULL; out->compr = compress_open(adev->snd_card, Loading Loading @@ -1397,6 +1465,10 @@ static int parse_compress_metadata(struct stream_out *out, struct str_parms *par return 0; } static bool output_drives_call(struct audio_device *adev, struct stream_out *out) { return out == adev->primary_output || out == adev->voice_tx_output; } static int out_set_parameters(struct audio_stream *stream, const char *kvpairs) { Loading Loading @@ -1431,6 +1503,13 @@ static int out_set_parameters(struct audio_stream *stream, const char *kvpairs) val = AUDIO_DEVICE_OUT_SPEAKER; } if ((adev->mode == AUDIO_MODE_NORMAL) && voice_is_in_call(adev) && output_drives_call(adev, out)) { ret = voice_stop_call(adev); adev->current_call_output = NULL; } /* * select_devices() call below switches all the usecases on the same * backend to the new device. Refer to check_usecases_codec_backend() in Loading @@ -1456,20 +1535,14 @@ static int out_set_parameters(struct audio_stream *stream, const char *kvpairs) select_devices(adev, out->usecase); if ((adev->mode == AUDIO_MODE_IN_CALL) && !voice_is_in_call(adev) && (out == adev->primary_output)) { output_drives_call(adev, out)) { adev->current_call_output = out; if (!voice_is_in_call(adev)) ret = voice_start_call(adev); } else if ((adev->mode == AUDIO_MODE_IN_CALL) && voice_is_in_call(adev) && (out == adev->primary_output)) { else voice_update_devices_for_all_voice_usecases(adev); } } if ((adev->mode == AUDIO_MODE_NORMAL) && voice_is_in_call(adev) && (out == adev->primary_output)) { ret = voice_stop_call(adev); } pthread_mutex_unlock(&adev->lock); Loading Loading @@ -1629,6 +1702,9 @@ static ssize_t out_write(struct audio_stream_out *stream, const void *buffer, if (out->muted) memset((void *)buffer, 0, bytes); ALOGVV("%s: writing buffer (%d bytes) to pcm device", __func__, bytes); if (out->usecase == USECASE_AUDIO_PLAYBACK_AFE_PROXY) ret = pcm_mmap_write(out->pcm, (void *)buffer, bytes); else ret = pcm_write(out->pcm, (void *)buffer, bytes); if (ret == 0) out->written += bytes / (out->config.channels * sizeof(short)); Loading Loading @@ -1923,7 +1999,7 @@ static int in_set_parameters(struct audio_stream *stream, const char *kvpairs) err = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value)); if (err >= 0) { val = atoi(value); if ((in->device != val) && (val != 0)) { if (((int)in->device != val) && (val != 0)) { in->device = val; /* If recording is in progress, change the tx device to new device */ if (!in->standby) Loading Loading @@ -1991,6 +2067,8 @@ static ssize_t in_read(struct audio_stream_in *stream, void *buffer, ret = audio_extn_ssr_read(stream, buffer, bytes); 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) ret = pcm_mmap_read(in->pcm, buffer, bytes); else ret = pcm_read(in->pcm, buffer, bytes); } Loading Loading @@ -2238,6 +2316,28 @@ static int adev_open_output_stream(struct audio_hw_device *dev, goto error_open; } #endif } else if (out->devices == AUDIO_DEVICE_OUT_TELEPHONY_TX) { if (config->sample_rate == 0) config->sample_rate = AFE_PROXY_SAMPLING_RATE; if (config->sample_rate != 48000 && config->sample_rate != 16000 && config->sample_rate != 8000) { config->sample_rate = AFE_PROXY_SAMPLING_RATE; ret = -EINVAL; goto error_open; } out->sample_rate = config->sample_rate; out->config.rate = config->sample_rate; if (config->format == AUDIO_FORMAT_DEFAULT) config->format = AUDIO_FORMAT_PCM_16_BIT; if (config->format != AUDIO_FORMAT_PCM_16_BIT) { config->format = AUDIO_FORMAT_PCM_16_BIT; ret = -EINVAL; goto error_open; } out->format = config->format; out->usecase = USECASE_AUDIO_PLAYBACK_AFE_PROXY; out->config = pcm_config_afe_proxy_playback; adev->voice_tx_output = out; } else if (out->flags & AUDIO_OUTPUT_FLAG_FAST) { out->usecase = USECASE_AUDIO_PLAYBACK_LOW_LATENCY; out->config = pcm_config_low_latency; Loading Loading @@ -2572,7 +2672,27 @@ static int adev_open_input_stream(struct audio_hw_device *dev, in->config.rate = config->sample_rate; in->format = config->format; if (channel_count == 6) { if (in->device == AUDIO_DEVICE_IN_TELEPHONY_RX) { if (config->sample_rate == 0) config->sample_rate = AFE_PROXY_SAMPLING_RATE; if (config->sample_rate != 48000 && config->sample_rate != 16000 && config->sample_rate != 8000) { config->sample_rate = AFE_PROXY_SAMPLING_RATE; ret = -EINVAL; goto err_open; } if (config->format == AUDIO_FORMAT_DEFAULT) config->format = AUDIO_FORMAT_PCM_16_BIT; if (config->format != AUDIO_FORMAT_PCM_16_BIT) { config->format = AUDIO_FORMAT_PCM_16_BIT; ret = -EINVAL; goto err_open; } in->usecase = USECASE_AUDIO_RECORD_AFE_PROXY; in->config = pcm_config_afe_proxy_record; in->config.channels = channel_count; in->config.rate = config->sample_rate; } else if (channel_count == 6) { if(audio_extn_ssr_get_enabled()) { if(audio_extn_ssr_init(adev, in)) { ALOGE("%s: audio_extn_ssr_init failed", __func__); Loading
hal/audio_hw.h +7 −1 Original line number Diff line number Diff line Loading @@ -98,6 +98,10 @@ typedef enum { USECASE_AUDIO_SPKR_CALIB_RX, USECASE_AUDIO_SPKR_CALIB_TX, USECASE_AUDIO_PLAYBACK_AFE_PROXY, USECASE_AUDIO_RECORD_AFE_PROXY, AUDIO_USECASE_MAX } audio_usecase_t; Loading Loading @@ -177,7 +181,7 @@ struct stream_in { int standby; int source; int pcm_device_id; int device; audio_devices_t device; audio_channel_mask_t channel_mask; audio_usecase_t usecase; bool enable_aec; Loading Loading @@ -218,6 +222,8 @@ struct audio_device { audio_devices_t out_device; struct stream_in *active_input; struct stream_out *primary_output; struct stream_out *voice_tx_output; struct stream_out *current_call_output; bool bluetooth_nrec; bool screen_off; int *snd_dev_ref_cnt; Loading
hal/msm8960/platform.h +3 −0 Original line number Diff line number Diff line Loading @@ -118,4 +118,7 @@ enum { #define AUDIO_CAPTURE_PERIOD_DURATION_MSEC 20 #define AUDIO_CAPTURE_PERIOD_COUNT 2 #define AFE_PROXY_PLAYBACK_PCM_DEVICE 7 #define AFE_PROXY_RECORD_PCM_DEVICE 8 #endif // QCOM_AUDIO_PLATFORM_H
hal/msm8974/platform.c +18 −2 Original line number Diff line number Diff line Loading @@ -165,6 +165,11 @@ static const int pcm_device_table[AUDIO_USECASE_MAX][2] = { INCALL_MUSIC_UPLINK2_PCM_DEVICE}, [USECASE_AUDIO_SPKR_CALIB_RX] = {SPKR_PROT_CALIB_RX_PCM_DEVICE, -1}, [USECASE_AUDIO_SPKR_CALIB_TX] = {-1, SPKR_PROT_CALIB_TX_PCM_DEVICE}, [USECASE_AUDIO_PLAYBACK_AFE_PROXY] = {AFE_PROXY_PLAYBACK_PCM_DEVICE, AFE_PROXY_RECORD_PCM_DEVICE}, [USECASE_AUDIO_RECORD_AFE_PROXY] = {AFE_PROXY_PLAYBACK_PCM_DEVICE, AFE_PROXY_RECORD_PCM_DEVICE}, }; /* Array to store sound devices */ Loading @@ -186,6 +191,7 @@ static const char * const device_table[SND_DEVICE_MAX] = { [SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES] = "voice-tty-full-headphones", [SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES] = "voice-tty-vco-headphones", [SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET] = "voice-tty-hco-handset", [SND_DEVICE_OUT_VOICE_TX] = "voice-tx", [SND_DEVICE_OUT_AFE_PROXY] = "afe-proxy", [SND_DEVICE_OUT_USB_HEADSET] = "usb-headphones", [SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET] = "speaker-and-usb-headphones", Loading Loading @@ -229,6 +235,7 @@ static const char * const device_table[SND_DEVICE_MAX] = { [SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC] = "voice-tty-full-headset-mic", [SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC] = "voice-tty-vco-handset-mic", [SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC] = "voice-tty-hco-headset-mic", [SND_DEVICE_IN_VOICE_RX] = "voice-rx", [SND_DEVICE_IN_VOICE_REC_MIC] = "voice-rec-mic", [SND_DEVICE_IN_VOICE_REC_MIC_NS] = "voice-rec-mic", [SND_DEVICE_IN_VOICE_REC_DMIC_STEREO] = "voice-rec-dmic-ef", Loading Loading @@ -260,6 +267,7 @@ static int acdb_device_table[SND_DEVICE_MAX] = { [SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES] = 17, [SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES] = 17, [SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET] = 37, [SND_DEVICE_OUT_VOICE_TX] = 45, [SND_DEVICE_OUT_AFE_PROXY] = 0, [SND_DEVICE_OUT_USB_HEADSET] = 0, [SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET] = 14, Loading Loading @@ -302,6 +310,7 @@ static int acdb_device_table[SND_DEVICE_MAX] = { [SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC] = 16, [SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC] = 36, [SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC] = 16, [SND_DEVICE_IN_VOICE_RX] = 44, [SND_DEVICE_IN_VOICE_REC_MIC] = 4, [SND_DEVICE_IN_VOICE_REC_MIC_NS] = 107, [SND_DEVICE_IN_VOICE_REC_DMIC_STEREO] = 34, Loading Loading @@ -662,6 +671,10 @@ void platform_add_backend_name(char *mixer_path, snd_device_t snd_device) strlcat(mixer_path, " hdmi", MIXER_PATH_MAX_LENGTH); else if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_HDMI) strcat(mixer_path, " speaker-and-hdmi"); else if (snd_device == SND_DEVICE_OUT_VOICE_TX) strlcat(mixer_path, " afe-proxy", MIXER_PATH_MAX_LENGTH); else if (snd_device == SND_DEVICE_IN_VOICE_RX) strlcat(mixer_path, " afe-proxy", MIXER_PATH_MAX_LENGTH); else if (snd_device == SND_DEVICE_OUT_AFE_PROXY) strlcat(mixer_path, " afe-proxy", MIXER_PATH_MAX_LENGTH); else if (snd_device == SND_DEVICE_OUT_USB_HEADSET) Loading Loading @@ -1080,7 +1093,9 @@ snd_device_t platform_get_output_snd_device(void *platform, audio_devices_t devi snd_device = SND_DEVICE_OUT_ANC_HANDSET; else snd_device = SND_DEVICE_OUT_VOICE_HANDSET; } } else if (devices & AUDIO_DEVICE_OUT_TELEPHONY_TX) snd_device = SND_DEVICE_OUT_VOICE_TX; if (snd_device != SND_DEVICE_NONE) { goto exit; } Loading Loading @@ -1212,7 +1227,8 @@ snd_device_t platform_get_input_snd_device(void *platform, audio_devices_t out_d snd_device = SND_DEVICE_IN_VOICE_SPEAKER_MIC; set_echo_reference(adev, true); } } } else if (out_device & AUDIO_DEVICE_OUT_TELEPHONY_TX) snd_device = SND_DEVICE_IN_VOICE_RX; } else if (source == AUDIO_SOURCE_CAMCORDER) { if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC || in_device & AUDIO_DEVICE_IN_BACK_MIC) { Loading
hal/msm8974/platform.h +5 −0 Original line number Diff line number Diff line Loading @@ -60,6 +60,7 @@ enum { SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES, SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES, SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET, SND_DEVICE_OUT_VOICE_TX, SND_DEVICE_OUT_AFE_PROXY, SND_DEVICE_OUT_USB_HEADSET, SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET, Loading Loading @@ -113,6 +114,7 @@ enum { SND_DEVICE_IN_VOICE_REC_MIC_NS, SND_DEVICE_IN_VOICE_REC_DMIC_STEREO, SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE, SND_DEVICE_IN_VOICE_RX, SND_DEVICE_IN_USB_HEADSET_MIC, SND_DEVICE_IN_CAPTURE_FM, SND_DEVICE_IN_AANC_HANDSET_MIC, Loading Loading @@ -223,6 +225,9 @@ enum { #define VOWLAN_CALL_PCM_DEVICE 36 #endif #define AFE_PROXY_PLAYBACK_PCM_DEVICE 7 #define AFE_PROXY_RECORD_PCM_DEVICE 8 #ifdef PLATFORM_MSM8x26 #define HFP_SCO_RX 28 #define HFP_ASM_RX_TX 29 Loading