Merge "Revert "hal: fix no sound issue in voice call"" into audio-userspace.lnx.2.1-dev
diff --git a/configs/msm8937/msm8937.mk b/configs/msm8937/msm8937.mk
index b7a7a39..3d932b0 100644
--- a/configs/msm8937/msm8937.mk
+++ b/configs/msm8937/msm8937.mk
@@ -147,9 +147,9 @@
PRODUCT_PROPERTY_OVERRIDES += \
audio.deep_buffer.media=true
-#Default pcm audio sink buffer size in msec. This is used in calculating framecount
+#QC property used when calculating client heap size in audio flinger
PRODUCT_PROPERTY_OVERRIDES += \
-media.stagefright.audio.sink=280
+audio.heap.size.multiplier=7
#enable voice path for PCM VoIP by default
PRODUCT_PROPERTY_OVERRIDES += \
diff --git a/configs/msm8953/msm8953.mk b/configs/msm8953/msm8953.mk
index 3106942..96c9a5d 100644
--- a/configs/msm8953/msm8953.mk
+++ b/configs/msm8953/msm8953.mk
@@ -148,9 +148,9 @@
PRODUCT_PROPERTY_OVERRIDES += \
audio.deep_buffer.media=true
-#Default pcm audio sink buffer size in msec. This is used in calculating framecount
+#QC property used when calculating client heap size in audio flinger
PRODUCT_PROPERTY_OVERRIDES += \
-media.stagefright.audio.sink=280
+audio.heap.size.multiplier=7
#enable voice path for PCM VoIP by default
PRODUCT_PROPERTY_OVERRIDES += \
diff --git a/configs/msm8996/msm8996.mk b/configs/msm8996/msm8996.mk
index 5b240e9..6d3fa4b 100644
--- a/configs/msm8996/msm8996.mk
+++ b/configs/msm8996/msm8996.mk
@@ -143,9 +143,9 @@
PRODUCT_PROPERTY_OVERRIDES += \
audio.deep_buffer.media=true
-#Default pcm audio sink buffer size in msec. This is used in calculating framecount
+#QC property used when calculating client heap size in audio flinger
PRODUCT_PROPERTY_OVERRIDES += \
-media.stagefright.audio.sink=280
+audio.heap.size.multiplier=7
#enable voice path for PCM VoIP by default
PRODUCT_PROPERTY_OVERRIDES += \
diff --git a/configs/msmcobalt/audio_platform_info.xml b/configs/msmcobalt/audio_platform_info.xml
index a1bd9a1..a8bce46 100644
--- a/configs/msmcobalt/audio_platform_info.xml
+++ b/configs/msmcobalt/audio_platform_info.xml
@@ -28,6 +28,9 @@
<acdb_ids>
<device name="SND_DEVICE_OUT_SPEAKER" acdb_id="15"/>
<device name="SND_DEVICE_OUT_SPEAKER_PROTECTED" acdb_id="124"/>
+ <device name="SND_DEVICE_IN_VOICE_REC_QMIC_FLUENCE" acdb_id="131"/>
+ <device name="SND_DEVICE_IN_VOICE_REC_TMIC" acdb_id="131"/>
+ <device name="SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE" acdb_id="132"/>
</acdb_ids>
<bit_width_configs>
<device name="SND_DEVICE_OUT_SPEAKER" bit_width="24"/>
diff --git a/configs/msmcobalt/msmcobalt.mk b/configs/msmcobalt/msmcobalt.mk
index 12a922c..7117bd8 100644
--- a/configs/msmcobalt/msmcobalt.mk
+++ b/configs/msmcobalt/msmcobalt.mk
@@ -152,9 +152,9 @@
PRODUCT_PROPERTY_OVERRIDES += \
audio.deep_buffer.media=true
-#Default pcm audio sink buffer size in msec. This is used in calculating framecount
+#QC property used when calculating client heap size in audio flinger
PRODUCT_PROPERTY_OVERRIDES += \
-media.stagefright.audio.sink=280
+audio.heap.size.multiplier=7
#enable voice path for PCM VoIP by default
PRODUCT_PROPERTY_OVERRIDES += \
@@ -214,3 +214,7 @@
#Disable FM a2dp concurrency
PRODUCT_PROPERTY_OVERRIDES += \
fm.a2dp.conc.disabled=true
+
+#audio becoming noisy intent broadcast delay
+PRODUCT_PROPERTY_OVERRIDES += \
+audio.noisy.broadcast.delay=600
diff --git a/configs/msmfalcon/msmfalcon.mk b/configs/msmfalcon/msmfalcon.mk
index 554f32b..509c159 100644
--- a/configs/msmfalcon/msmfalcon.mk
+++ b/configs/msmfalcon/msmfalcon.mk
@@ -137,9 +137,9 @@
PRODUCT_PROPERTY_OVERRIDES += \
audio.deep_buffer.media=true
-#Default pcm audio sink buffer size in msec. This is used in calculating framecount
+#QC property used when calculating client heap size in audio flinger
PRODUCT_PROPERTY_OVERRIDES += \
-media.stagefright.audio.sink=280
+audio.heap.size.multiplier=7
#enable voice path for PCM VoIP by default
PRODUCT_PROPERTY_OVERRIDES += \
diff --git a/hal/audio_extn/utils.c b/hal/audio_extn/utils.c
index 9542fbd..eb3213c 100644
--- a/hal/audio_extn/utils.c
+++ b/hal/audio_extn/utils.c
@@ -666,6 +666,18 @@
if ((24 == usecase->stream.out->bit_width) &&
(usecase->stream.out->devices & AUDIO_DEVICE_OUT_SPEAKER)) {
usecase->stream.out->app_type_cfg.sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
+ } else if ((snd_device == SND_DEVICE_OUT_HDMI ||
+ snd_device == SND_DEVICE_OUT_USB_HEADSET ||
+ snd_device == SND_DEVICE_OUT_DISPLAY_PORT) &&
+ (usecase->stream.out->sample_rate >= OUTPUT_SAMPLING_RATE_44100)) {
+ /*
+ * To best utlize DSP, check if the stream sample rate is supported/multiple of
+ * configured device sample rate, if not update the COPP rate to be equal to the
+ * device sample rate, else open COPP at stream sample rate
+ */
+ platform_check_and_update_copp_sample_rate(adev->platform, snd_device,
+ usecase->stream.out->sample_rate,
+ &usecase->stream.out->app_type_cfg.sample_rate);
} else if ((snd_device != SND_DEVICE_OUT_HEADPHONES_44_1 &&
usecase->stream.out->sample_rate == OUTPUT_SAMPLING_RATE_44100) ||
(usecase->stream.out->sample_rate < OUTPUT_SAMPLING_RATE_44100)) {
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 13e4ae9..bf2908f 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -796,8 +796,10 @@
audio_extn_dev_arbi_release(snd_device);
return -EINVAL;
}
- } else if (platform_can_split_snd_device(adev->platform, snd_device,
- &num_devices, new_snd_devices)) {
+ } else if (platform_split_snd_device(adev->platform,
+ snd_device,
+ &num_devices,
+ new_snd_devices) == 0) {
for (i = 0; i < num_devices; i++) {
enable_snd_device(adev, new_snd_devices[i]);
}
@@ -870,8 +872,10 @@
if (platform_can_enable_spkr_prot_on_device(snd_device) &&
audio_extn_spkr_prot_is_enabled()) {
audio_extn_spkr_prot_stop_processing(snd_device);
- } else if (platform_can_split_snd_device(adev->platform, snd_device,
- &num_devices, new_snd_devices)) {
+ } else if (platform_split_snd_device(adev->platform,
+ snd_device,
+ &num_devices,
+ new_snd_devices) == 0) {
for (i = 0; i < num_devices; i++) {
disable_snd_device(adev, new_snd_devices[i]);
}
@@ -908,6 +912,115 @@
return 0;
}
+/*
+ legend:
+ uc - existing usecase
+ new_uc - new usecase
+ d1, d11, d2 - SND_DEVICE enums
+ a1, a2 - corresponding ANDROID device enums
+ B1, B2 - backend strings
+
+case 1
+ uc->dev d1 (a1) B1
+ new_uc->dev d1 (a1), d2 (a2) B1, B2
+
+ resolution: disable and enable uc->dev on d1
+
+case 2
+ uc->dev d1 (a1) B1
+ new_uc->dev d11 (a1) B1
+
+ resolution: need to switch uc since d1 and d11 are related
+ (e.g. speaker and voice-speaker)
+ use ANDROID_DEVICE_OUT enums to match devices since SND_DEVICE enums may vary
+
+case 3
+ uc->dev d1 (a1) B1
+ new_uc->dev d2 (a2) B2
+
+ resolution: no need to switch uc
+
+case 4
+ uc->dev d1 (a1) B1
+ new_uc->dev d2 (a2) B1
+
+ resolution: disable enable uc-dev on d2 since backends match
+ we cannot enable two streams on two different devices if they
+ share the same backend. e.g. if offload is on speaker device using
+ QUAD_MI2S backend and a low-latency stream is started on voice-handset
+ using the same backend, offload must also be switched to voice-handset.
+
+case 5
+ uc->dev d1 (a1) B1
+ new_uc->dev d1 (a1), d2 (a2) B1
+
+ resolution: disable enable uc-dev on d2 since backends match
+ we cannot enable two streams on two different devices if they
+ share the same backend.
+
+case 6
+ uc->dev d1 (a1) B1
+ new_uc->dev d2 (a1) B2
+
+ resolution: no need to switch
+
+case 7
+ uc->dev d1 (a1), d2 (a2) B1, B2
+ new_uc->dev d1 (a1) B1
+
+ resolution: no need to switch
+
+*/
+static snd_device_t derive_playback_snd_device(void * platform,
+ struct audio_usecase *uc,
+ struct audio_usecase *new_uc,
+ snd_device_t new_snd_device)
+{
+ audio_devices_t a1 = uc->stream.out->devices;
+ audio_devices_t a2 = new_uc->stream.out->devices;
+
+ snd_device_t d1 = uc->out_snd_device;
+ snd_device_t d2 = new_snd_device;
+
+ // Treat as a special case when a1 and a2 are not disjoint
+ if ((a1 != a2) && (a1 & a2)) {
+ snd_device_t d3[2];
+ int num_devices = 0;
+ int ret = platform_split_snd_device(platform,
+ popcount(a1) > 1 ? d1 : d2,
+ &num_devices,
+ d3);
+ if (ret < 0) {
+ if (ret != -ENOSYS) {
+ ALOGW("%s failed to split snd_device %d",
+ __func__,
+ popcount(a1) > 1 ? d1 : d2);
+ }
+ goto end;
+ }
+
+ // NB: case 7 is hypothetical and isn't a practical usecase yet.
+ // But if it does happen, we need to give priority to d2 if
+ // the combo devices active on the existing usecase share a backend.
+ // This is because we cannot have a usecase active on a combo device
+ // and a new usecase requests one device in this combo pair.
+ if (platform_check_backends_match(d3[0], d3[1])) {
+ return d2; // case 5
+ } else {
+ return d1; // case 1
+ }
+ } else {
+ if (platform_check_backends_match(d1, d2)) {
+ return d2; // case 2, 4
+ } else {
+ return d1; // case 6, 3
+ }
+ }
+
+end:
+ return d2; // return whatever was calculated before.
+}
+
static void check_usecases_codec_backend(struct audio_device *adev,
struct audio_usecase *uc_info,
snd_device_t snd_device)
@@ -963,7 +1076,9 @@
platform_check_backends_match(snd_device, usecase->out_snd_device));
if (usecase->type != PCM_CAPTURE &&
usecase != uc_info &&
- (usecase->out_snd_device != snd_device || force_routing) &&
+ (derive_playback_snd_device(adev->platform,
+ usecase, uc_info,
+ snd_device) != usecase->out_snd_device || force_routing) &&
((usecase->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND) ||
(usecase->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) ||
(usecase->devices & AUDIO_DEVICE_OUT_USB_DEVICE) ||
diff --git a/hal/edid.c b/hal/edid.c
index 8f183d0..e889530 100644
--- a/hal/edid.c
+++ b/hal/edid.c
@@ -86,57 +86,109 @@
return format_str;
}
-static int get_edid_sf(unsigned char byte)
+static bool is_supported_sr(unsigned char sr_byte, int sampling_rate )
+{
+ int result = 0;
+
+ ALOGV("%s: sr_byte: %d, sampling_freq: %d",__func__, sr_byte, sampling_rate);
+ switch (sampling_rate) {
+ case 192000:
+ result = (sr_byte & BIT(6));
+ break;
+ case 176400:
+ result = (sr_byte & BIT(5));
+ break;
+ case 96000:
+ result = (sr_byte & BIT(4));
+ break;
+ case 88200:
+ result = (sr_byte & BIT(3));
+ break;
+ case 48000:
+ result = (sr_byte & BIT(2));
+ break;
+ case 44100:
+ result = (sr_byte & BIT(1));
+ break;
+ case 32000:
+ result = (sr_byte & BIT(0));
+ break;
+ default:
+ break;
+ }
+
+ if (result)
+ return true;
+
+ return false;
+}
+
+static unsigned char get_edid_bps_byte(unsigned char byte,
+ unsigned char format)
+{
+ if (format == 0) {
+ ALOGV("%s: not lpcm format, return 0",__func__);
+ return 0;
+ }
+ return byte;
+}
+
+static bool is_supported_bps(unsigned char bps_byte, int bps)
+{
+ int result = 0;
+
+ switch (bps) {
+ case 24:
+ ALOGV("24bit");
+ result = (bps_byte & BIT(2));
+ break;
+ case 20:
+ ALOGV("20bit");
+ result = (bps_byte & BIT(1));
+ break;
+ case 16:
+ ALOGV("16bit");
+ result = (bps_byte & BIT(0));
+ break;
+ default:
+ break;
+ }
+
+ if (result)
+ return true;
+
+ return false;
+}
+
+static int get_highest_edid_sf(unsigned char byte)
{
int nfreq = 0;
if (byte & BIT(6)) {
- ALOGV("192kHz");
+ ALOGV("Highest: 192kHz");
nfreq = 192000;
} else if (byte & BIT(5)) {
- ALOGV("176kHz");
+ ALOGV("Highest: 176kHz");
nfreq = 176000;
} else if (byte & BIT(4)) {
- ALOGV("96kHz");
+ ALOGV("Highest: 96kHz");
nfreq = 96000;
} else if (byte & BIT(3)) {
- ALOGV("88.2kHz");
+ ALOGV("Highest: 88.2kHz");
nfreq = 88200;
} else if (byte & BIT(2)) {
- ALOGV("48kHz");
+ ALOGV("Highest: 48kHz");
nfreq = 48000;
} else if (byte & BIT(1)) {
- ALOGV("44.1kHz");
+ ALOGV("Highest: 44.1kHz");
nfreq = 44100;
} else if (byte & BIT(0)) {
- ALOGV("32kHz");
+ ALOGV("Highest: 32kHz");
nfreq = 32000;
}
return nfreq;
}
-static int get_edid_bps(unsigned char byte,
- unsigned char format)
-{
- int bits_per_sample = 0;
- if (format == 1) {
- if (byte & BIT(2)) {
- ALOGV("24bit");
- bits_per_sample = 24;
- } else if (byte & BIT(1)) {
- ALOGV("20bit");
- bits_per_sample = 20;
- } else if (byte & BIT(0)) {
- ALOGV("16bit");
- bits_per_sample = 16;
- }
- } else {
- ALOGV("not lpcm format, return 0");
- return 0;
- }
- return bits_per_sample;
-}
-
static void update_channel_map(edid_audio_info* info)
{
/* HDMI Cable follows CEA standard so SAD is received in CEA
@@ -589,8 +641,8 @@
for (i = 0; i < info->audio_blocks && i < MAX_EDID_BLOCKS; i++) {
ALOGV("%s:FormatId:%d rate:%d bps:%d channels:%d", __func__,
info->audio_blocks_array[i].format_id,
- info->audio_blocks_array[i].sampling_freq,
- info->audio_blocks_array[i].bits_per_sample,
+ info->audio_blocks_array[i].sampling_freq_bitmask,
+ info->audio_blocks_array[i].bits_per_sample_bitmask,
info->audio_blocks_array[i].channels);
}
ALOGV("%s:no of audio blocks:%d", __func__, info->audio_blocks);
@@ -670,16 +722,16 @@
ALOGD("info->audio_blocks_array[i].format_id %s",
edid_format_to_str(formats[i]));
- ALOGV("Frequency Byte %d\n", frequency[i]);
- info->audio_blocks_array[i].sampling_freq = get_edid_sf(frequency[i]);
- ALOGV("info->audio_blocks_array[i].sampling_freq %d",
- info->audio_blocks_array[i].sampling_freq);
+ ALOGV("Frequency Bitmask %d\n", frequency[i]);
+ info->audio_blocks_array[i].sampling_freq_bitmask = frequency[i];
+ ALOGV("info->audio_blocks_array[i].sampling_freq_bitmask %d",
+ info->audio_blocks_array[i].sampling_freq_bitmask);
- ALOGV("BitsPerSample Byte %d\n", bitrate[i]);
- info->audio_blocks_array[i].bits_per_sample =
- get_edid_bps(bitrate[i],formats[i]);
- ALOGV("info->audio_blocks_array[i].bits_per_sample %d",
- info->audio_blocks_array[i].bits_per_sample);
+ ALOGV("BitsPerSample Bitmask %d\n", bitrate[i]);
+ info->audio_blocks_array[i].bits_per_sample_bitmask =
+ get_edid_bps_byte(bitrate[i],formats[i]);
+ ALOGV("info->audio_blocks_array[i].bits_per_sample_bitmask %d",
+ info->audio_blocks_array[i].bits_per_sample_bitmask);
}
dump_speaker_allocation(info);
dump_edid_data(info);
@@ -691,7 +743,7 @@
int i = 0;
if (info != NULL && sr != 0) {
for (i = 0; i < info->audio_blocks && i < MAX_EDID_BLOCKS; i++) {
- if (info->audio_blocks_array[i].sampling_freq == sr) {
+ if (is_supported_sr(info->audio_blocks_array[i].sampling_freq_bitmask , sr)) {
ALOGV("%s: returns true for sample rate [%d]",
__func__, sr);
return true;
@@ -715,7 +767,7 @@
if (info != NULL && bps != 0) {
for (i = 0; i < info->audio_blocks && i < MAX_EDID_BLOCKS; i++) {
- if (info->audio_blocks_array[i].bits_per_sample == bps) {
+ if (is_supported_bps(info->audio_blocks_array[i].bits_per_sample_bitmask, bps)) {
ALOGV("%s: returns true for bit width [%d]",
__func__, bps);
return true;
@@ -726,3 +778,24 @@
__func__, bps);
return false;
}
+
+int edid_get_highest_supported_sr(edid_audio_info* info)
+{
+ int sr = 0;
+ int highest_sr = 0;
+ int i;
+
+ if (info != NULL) {
+ for (i = 0; i < info->audio_blocks && i < MAX_EDID_BLOCKS; i++) {
+ sr = get_highest_edid_sf(info->audio_blocks_array[i].sampling_freq_bitmask);
+ if (sr > highest_sr)
+ highest_sr = sr;
+ }
+ }
+ else
+ ALOGE("%s: info is NULL", __func__);
+
+ ALOGV("%s: returns [%d] for highest supported sr",
+ __func__, highest_sr);
+ return highest_sr;
+}
\ No newline at end of file
diff --git a/hal/edid.h b/hal/edid.h
index 387b17e..6a82103 100644
--- a/hal/edid.h
+++ b/hal/edid.h
@@ -79,8 +79,8 @@
typedef struct edid_audio_block_info {
edid_audio_format_id format_id;
- int sampling_freq;
- int bits_per_sample;
+ int sampling_freq_bitmask;
+ int bits_per_sample_bitmask;
int channels;
} edid_audio_block_info;
@@ -100,5 +100,6 @@
bool edid_is_supported_sr(edid_audio_info* info, int sr);
bool edid_is_supported_bps(edid_audio_info* info, int bps);
+int edid_get_highest_supported_sr(edid_audio_info* info);
#endif /* EDID_H */
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
index a42f984..9416887 100644
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -70,7 +70,8 @@
#define LIB_ACDB_LOADER "libacdbloader.so"
#define CVD_VERSION_MIXER_CTL "CVD Version"
-#define MAX_COMPRESS_OFFLOAD_FRAGMENT_SIZE (256 * 1024)
+#define FLAC_COMPRESS_OFFLOAD_FRAGMENT_SIZE (256 * 1024)
+#define MAX_COMPRESS_OFFLOAD_FRAGMENT_SIZE (2 * 1024 * 1024)
#define MIN_COMPRESS_OFFLOAD_FRAGMENT_SIZE (2 * 1024)
#define COMPRESS_OFFLOAD_FRAGMENT_SIZE_FOR_AV_STREAMING (2 * 1024)
#define COMPRESS_OFFLOAD_FRAGMENT_SIZE (32 * 1024)
@@ -255,6 +256,8 @@
int metainfo_key;
int source_mic_type;
int max_mic_count;
+ bool is_dsd_supported;
+ bool is_asrc_supported;
};
static bool is_external_codec = false;
@@ -335,6 +338,7 @@
[SND_DEVICE_OUT_SPEAKER_VBAT] = "vbat-speaker",
[SND_DEVICE_OUT_SPEAKER_REVERSE] = "speaker-reverse",
[SND_DEVICE_OUT_HEADPHONES] = "headphones",
+ [SND_DEVICE_OUT_HEADPHONES_DSD] = "headphones-dsd",
[SND_DEVICE_OUT_HEADPHONES_44_1] = "headphones-44.1",
[SND_DEVICE_OUT_LINE] = "line",
[SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = "speaker-and-headphones",
@@ -444,6 +448,7 @@
[SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS] = "quad-mic",
[SND_DEVICE_IN_THREE_MIC] = "three-mic",
[SND_DEVICE_IN_HANDSET_TMIC] = "three-mic",
+ [SND_DEVICE_IN_VOICE_REC_TMIC] = "three-mic",
[SND_DEVICE_IN_UNPROCESSED_MIC] = "unprocessed-mic",
[SND_DEVICE_IN_UNPROCESSED_STEREO_MIC] = "voice-rec-dmic-ef",
[SND_DEVICE_IN_UNPROCESSED_THREE_MIC] = "three-mic",
@@ -466,6 +471,7 @@
[SND_DEVICE_OUT_SPEAKER_REVERSE] = 14,
[SND_DEVICE_OUT_LINE] = 10,
[SND_DEVICE_OUT_HEADPHONES] = 10,
+ [SND_DEVICE_OUT_HEADPHONES_DSD] = 10,
[SND_DEVICE_OUT_HEADPHONES_44_1] = 10,
[SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = 10,
[SND_DEVICE_OUT_SPEAKER_AND_LINE] = 10,
@@ -573,6 +579,7 @@
[SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS] = 129,
[SND_DEVICE_IN_THREE_MIC] = 46, /* for APSS Surround Sound Recording */
[SND_DEVICE_IN_HANDSET_TMIC] = 125, /* for 3mic recording with fluence */
+ [SND_DEVICE_IN_VOICE_REC_TMIC] = 125,
[SND_DEVICE_IN_UNPROCESSED_MIC] = 143,
[SND_DEVICE_IN_UNPROCESSED_STEREO_MIC] = 144,
[SND_DEVICE_IN_UNPROCESSED_THREE_MIC] = 145,
@@ -597,6 +604,7 @@
{TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_VBAT)},
{TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_REVERSE)},
{TO_NAME_INDEX(SND_DEVICE_OUT_HEADPHONES)},
+ {TO_NAME_INDEX(SND_DEVICE_OUT_HEADPHONES_DSD)},
{TO_NAME_INDEX(SND_DEVICE_OUT_HEADPHONES_44_1)},
{TO_NAME_INDEX(SND_DEVICE_OUT_LINE)},
{TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES)},
@@ -704,6 +712,7 @@
{TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS)},
{TO_NAME_INDEX(SND_DEVICE_IN_THREE_MIC)},
{TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_TMIC)},
+ {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_TMIC)},
{TO_NAME_INDEX(SND_DEVICE_IN_UNPROCESSED_MIC)},
{TO_NAME_INDEX(SND_DEVICE_IN_UNPROCESSED_STEREO_MIC)},
{TO_NAME_INDEX(SND_DEVICE_IN_UNPROCESSED_THREE_MIC)},
@@ -1245,12 +1254,15 @@
backend_tag_table[SND_DEVICE_IN_USB_HEADSET_MIC] = strdup("usb-headset-mic");
backend_tag_table[SND_DEVICE_IN_CAPTURE_FM] = strdup("capture-fm");
backend_tag_table[SND_DEVICE_OUT_TRANSMISSION_FM] = strdup("transmission-fm");
+ backend_tag_table[SND_DEVICE_OUT_HEADPHONES_DSD] = strdup("headphones-dsd");
backend_tag_table[SND_DEVICE_OUT_HEADPHONES_44_1] = strdup("headphones-44.1");
backend_tag_table[SND_DEVICE_OUT_VOICE_SPEAKER_VBAT] = strdup("vbat-voice-speaker");
backend_tag_table[SND_DEVICE_OUT_VOICE_SPEAKER_2_VBAT] = strdup("vbat-voice-speaker-2");
backend_tag_table[SND_DEVICE_OUT_BT_A2DP] = strdup("bt-a2dp");
backend_tag_table[SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP] = strdup("speaker-and-bt-a2dp");
+ hw_interface_table[SND_DEVICE_OUT_HEADPHONES_DSD] = strdup("SLIMBUS_2_RX");
+ hw_interface_table[SND_DEVICE_OUT_HEADPHONES_44_1] = strdup("SLIMBUS_5_RX");
hw_interface_table[SND_DEVICE_OUT_HDMI] = strdup("HDMI_RX");
hw_interface_table[SND_DEVICE_OUT_SPEAKER_AND_HDMI] = strdup("SLIMBUS_0_RX-and-HDMI_RX");
hw_interface_table[SND_DEVICE_OUT_DISPLAY_PORT] = strdup("DISPLAY_PORT_RX");
@@ -1935,6 +1947,10 @@
my_data->current_backend_cfg[DEFAULT_CODEC_BACKEND].samplerate_mixer_ctl =
strdup("SLIM_0_RX SampleRate");
+ my_data->current_backend_cfg[DSD_NATIVE_BACKEND].bitwidth_mixer_ctl =
+ strdup("SLIM_2_RX Format");
+ my_data->current_backend_cfg[DSD_NATIVE_BACKEND].samplerate_mixer_ctl =
+ strdup("SLIM_2_RX SampleRate");
my_data->current_backend_cfg[HEADPHONE_44_1_BACKEND].bitwidth_mixer_ctl =
strdup("SLIM_5_RX Format");
my_data->current_backend_cfg[HEADPHONE_44_1_BACKEND].samplerate_mixer_ctl =
@@ -2008,6 +2024,12 @@
}
}
+ if(strstr(snd_card_name, "tavil")) {
+ ALOGD("%s:DSD playback is supported", __func__);
+ my_data->is_dsd_supported = true;
+ my_data->is_asrc_supported = true;
+ platform_set_native_support(NATIVE_AUDIO_MODE_MULTIPLE_44_1);
+ }
my_data->edid_info = NULL;
return my_data;
}
@@ -2338,7 +2360,8 @@
}
int platform_set_native_support(int na_mode)
{
- if (NATIVE_AUDIO_MODE_SRC == na_mode || NATIVE_AUDIO_MODE_TRUE_44_1 == na_mode) {
+ if (NATIVE_AUDIO_MODE_SRC == na_mode || NATIVE_AUDIO_MODE_TRUE_44_1 == na_mode
+ || NATIVE_AUDIO_MODE_MULTIPLE_44_1 == na_mode) {
na_props.platform_na_prop_enabled = na_props.ui_na_prop_enabled = true;
na_props.na_mode = na_mode;
ALOGD("%s:napb: native audio playback enabled in (%s) mode v2.0", __func__,
@@ -2351,6 +2374,16 @@
return 0;
}
+bool platform_check_codec_dsd_support(void *platform)
+{
+ struct platform_data *my_data = (struct platform_data *)platform;
+ return my_data->is_dsd_supported;
+}
+bool platform_check_codec_asrc_support(void *platform)
+{
+ struct platform_data *my_data = (struct platform_data *)platform;
+ return my_data->is_asrc_supported;
+}
int platform_get_native_support()
{
@@ -2404,6 +2437,8 @@
mode = NATIVE_AUDIO_MODE_SRC;
else if (value && !strncmp(value, "true", sizeof("true")))
mode = NATIVE_AUDIO_MODE_TRUE_44_1;
+ else if (value && !strncmp(value, "multiple", sizeof("multiple")))
+ mode = NATIVE_AUDIO_MODE_MULTIPLE_44_1;
else {
mode = NATIVE_AUDIO_MODE_INVALID;
ALOGE("%s:napb:native_audio_mode in platform info xml,invalid mode string",
@@ -2514,6 +2549,9 @@
if (strncmp(backend_tag_table[snd_device], "headphones-44.1",
sizeof("headphones-44.1")) == 0)
port = HEADPHONE_44_1_BACKEND;
+ else if (strncmp(backend_tag_table[snd_device], "headphones-dsd",
+ sizeof("headphones-dsd")) == 0)
+ port = DSD_NATIVE_BACKEND;
else if (strncmp(backend_tag_table[snd_device], "headphones",
sizeof("headphones")) == 0)
port = HEADPHONE_BACKEND;
@@ -2556,7 +2594,8 @@
snd_device = usecase->in_snd_device;
acdb_dev_id = acdb_device_table[platform_get_spkr_prot_snd_device(snd_device)];
- if(!platform_can_split_snd_device(platform, snd_device, &num_devices, new_snd_device)) {
+ if (platform_split_snd_device(platform, snd_device, &num_devices,
+ new_snd_device) < 0) {
new_snd_device[0] = snd_device;
}
@@ -2858,22 +2897,21 @@
return ret;
}
-bool platform_can_split_snd_device(void *platform,
- snd_device_t snd_device,
- int *num_devices,
- snd_device_t *new_snd_devices)
+int platform_split_snd_device(void *platform,
+ snd_device_t snd_device,
+ int *num_devices,
+ snd_device_t *new_snd_devices)
{
- bool status = false;
+ int ret = -EINVAL;
struct platform_data *my_data = (struct platform_data *)platform;
-
if (NULL == num_devices || NULL == new_snd_devices) {
ALOGE("%s: NULL pointer ..", __func__);
- return false;
+ return -EINVAL;
}
/*
* If wired headset/headphones/line devices share the same backend
- * with speaker/earpiece this routine returns false.
+ * with speaker/earpiece this routine returns -EINVAL.
*/
if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES &&
!platform_check_backends_match(SND_DEVICE_OUT_SPEAKER, SND_DEVICE_OUT_HEADPHONES)) {
@@ -2887,7 +2925,7 @@
new_snd_devices[0] = SND_DEVICE_OUT_SPEAKER;
new_snd_devices[1] = SND_DEVICE_OUT_HEADPHONES;
- status = true;
+ ret = 0;
} else if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_HDMI &&
!platform_check_backends_match(SND_DEVICE_OUT_SPEAKER, SND_DEVICE_OUT_HDMI)) {
*num_devices = 2;
@@ -2900,7 +2938,7 @@
new_snd_devices[0] = SND_DEVICE_OUT_SPEAKER;
new_snd_devices[1] = SND_DEVICE_OUT_HDMI;
- status = true;
+ ret = 0;
} else if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_DISPLAY_PORT &&
!platform_check_backends_match(SND_DEVICE_OUT_SPEAKER, SND_DEVICE_OUT_DISPLAY_PORT)) {
*num_devices = 2;
@@ -2913,24 +2951,24 @@
new_snd_devices[0] = SND_DEVICE_OUT_SPEAKER;
new_snd_devices[1] = SND_DEVICE_OUT_DISPLAY_PORT;
- status = true;
+ ret = 0;
} else if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET &&
!platform_check_backends_match(SND_DEVICE_OUT_SPEAKER, SND_DEVICE_OUT_USB_HEADSET)) {
*num_devices = 2;
new_snd_devices[0] = SND_DEVICE_OUT_SPEAKER;
new_snd_devices[1] = SND_DEVICE_OUT_USB_HEADSET;
- status = true;
+ ret = 0;
} else if (SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP == snd_device) {
*num_devices = 2;
new_snd_devices[0] = SND_DEVICE_OUT_SPEAKER;
new_snd_devices[1] = SND_DEVICE_OUT_BT_A2DP;
- status = true;
+ ret = 0;
}
ALOGD("%s: snd_device(%d) num devices(%d) new_snd_devices(%d)", __func__,
snd_device, *num_devices, *new_snd_devices);
- return status;
+ return ret;
}
int platform_get_ext_disp_type(void *platform)
@@ -3134,7 +3172,8 @@
}
if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
- devices & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
+ devices & AUDIO_DEVICE_OUT_WIRED_HEADSET ||
+ devices & AUDIO_DEVICE_OUT_LINE) {
if (OUTPUT_SAMPLING_RATE_44100 == sample_rate &&
NATIVE_AUDIO_MODE_SRC == na_mode &&
!audio_extn_get_anc_enabled()) {
@@ -3155,7 +3194,16 @@
else
snd_device = SND_DEVICE_OUT_ANC_HEADSET;
}
- } else {
+ } else if (NATIVE_AUDIO_MODE_SRC == na_mode &&
+ OUTPUT_SAMPLING_RATE_44100 == sample_rate) {
+ snd_device = SND_DEVICE_OUT_HEADPHONES_44_1;
+ } else if (NATIVE_AUDIO_MODE_MULTIPLE_44_1 == na_mode &&
+ (sample_rate % OUTPUT_SAMPLING_RATE_44100 == 0) &&
+ (out->format != AUDIO_FORMAT_DSD)) {
+ snd_device = SND_DEVICE_OUT_HEADPHONES_44_1;
+ } else if (out->format == AUDIO_FORMAT_DSD) {
+ snd_device = SND_DEVICE_OUT_HEADPHONES_DSD;
+ } else {
#ifdef RECORD_PLAY_CONCURRENCY
if (use_voip_out_devices)
snd_device = SND_DEVICE_OUT_VOIP_HEADPHONES;
@@ -3369,7 +3417,7 @@
snd_device = SND_DEVICE_IN_HANDSET_QMIC;
} else if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
(my_data->source_mic_type & SOURCE_THREE_MIC)) {
- snd_device = SND_DEVICE_IN_HANDSET_TMIC;
+ snd_device = SND_DEVICE_IN_VOICE_REC_TMIC;
} else if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
(my_data->source_mic_type & SOURCE_DUAL_MIC)) {
snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE;
@@ -4217,18 +4265,21 @@
fragment_size = info->offload_buffer_size;
}
- // 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) {
- fragment_size = COMPRESS_OFFLOAD_FRAGMENT_SIZE_FOR_AV_STREAMING;
- ALOGV("%s: offload fragment size reduced for AV streaming to %d",
- __func__, fragment_size);
+ if (info != NULL && !info->has_video) {
+ if (info->is_streaming) {
+ fragment_size = COMPRESS_OFFLOAD_FRAGMENT_SIZE_FOR_AV_STREAMING;
+ ALOGV("%s: offload fragment size reduced for AV streaming to %d",
+ __func__, fragment_size);
+ } else if (info->format == AUDIO_FORMAT_FLAC) {
+ fragment_size = FLAC_COMPRESS_OFFLOAD_FRAGMENT_SIZE;
+ ALOGV("FLAC fragment size %d", fragment_size);
+ } else if (info->format == AUDIO_FORMAT_DSD) {
+ fragment_size = MAX_COMPRESS_OFFLOAD_FRAGMENT_SIZE;
+ if((property_get("audio.native.dsd.buffer.size.kb", value, "")) &&
+ atoi(value))
+ fragment_size = atoi(value) * 1024;
+ ALOGV("DSD fragment size %d", fragment_size);
+ }
}
fragment_size = ALIGN( fragment_size, 1024);
@@ -4457,6 +4508,17 @@
mixer_ctl_set_enum_by_string(ctl, "LPCM");
}
}
+ if (snd_device == SND_DEVICE_OUT_HEADPHONES || snd_device ==
+ SND_DEVICE_OUT_HEADPHONES_44_1) {
+ if (sample_rate > 48000 ||
+ (bit_width >= 24 && (sample_rate == 48000 || sample_rate == 44100))) {
+ ALOGV("%s: apply HPH HQ mode\n", __func__);
+ audio_route_apply_and_update_path(adev->audio_route, "hph-highquality-mode");
+ } else {
+ ALOGV("%s: apply HPH LP mode\n", __func__);
+ audio_route_apply_and_update_path(adev->audio_route, "hph-lowpower-mode");
+ }
+ }
return ret;
}
@@ -4500,8 +4562,12 @@
//Check EDID info for supported samplerate
if (!edid_is_supported_sr(edid_info,sample_rate)) {
- //reset to current sample rate
- sample_rate = my_data->current_backend_cfg[backend_idx].sample_rate;
+ //check to see if current BE sample rate is supported by EDID
+ //else assign the highest sample rate supported by EDID
+ if (edid_is_supported_sr(edid_info,my_data->current_backend_cfg[backend_idx].sample_rate))
+ sample_rate = my_data->current_backend_cfg[backend_idx].sample_rate;
+ else
+ sample_rate = edid_get_highest_supported_sr(edid_info);
}
//Check EDID info for supported bit width
@@ -4553,6 +4619,7 @@
bool passthrough_enabled = false;
int backend_idx = DEFAULT_CODEC_BACKEND;
struct platform_data *my_data = (struct platform_data *)adev->platform;
+ int na_mode = platform_get_native_support();
bool channels_updated = false;
backend_idx = platform_get_backend_index(snd_device);
@@ -4572,6 +4639,7 @@
__func__);
bit_width = CODEC_BACKEND_DEFAULT_BIT_WIDTH;
sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
+ channels = CODEC_BACKEND_DEFAULT_CHANNELS;
} else {
/*
* The backend should be configured at highest bit width and/or
@@ -4633,9 +4701,31 @@
ALOGD("%s:becf: afe: true napb active set rate to 44.1 khz",
__func__);
}
- } else if (OUTPUT_SAMPLING_RATE_44100 == sample_rate) {
- sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
- ALOGD("%s:becf: afe: napb not active - set (48k) default rate",
+ } else if (na_mode != NATIVE_AUDIO_MODE_MULTIPLE_44_1) {
+ /*
+ * Map native sampling rates to upper limit range
+ * if multiple of native sampling rates are not supported.
+ * This check also indicates that this is not tavil codec
+ * And 32bit/384kHz is only supported on tavil
+ * Hence reset 32b/384kHz to 24b/192kHz.
+ */
+ switch (sample_rate) {
+ case 44100:
+ sample_rate = 48000;
+ break;
+ case 88200:
+ sample_rate = 96000;
+ break;
+ case 176400:
+ case 352800:
+ case 384000:
+ sample_rate = 192000;
+ break;
+ }
+ if (bit_width > 24)
+ bit_width = 24;
+
+ ALOGD("%s:becf: afe: napb not active - set non fractional rate",
__func__);
}
} else if ((usecase->devices & AUDIO_DEVICE_OUT_SPEAKER) ||
@@ -4748,13 +4838,24 @@
/*this is populated by check_codec_backend_cfg hence set default value to false*/
backend_cfg.passthrough_enabled = false;
+ /* Set Backend sampling rate to 176.4 for DSD64 and
+ * 352.8Khz for DSD128.
+ * Set Bit Width to 16
+ */
+ if ((backend_idx == DSD_NATIVE_BACKEND) && (backend_cfg.format == AUDIO_FORMAT_DSD)) {
+ backend_cfg.bit_width = 16;
+ if (backend_cfg.sample_rate == INPUT_SAMPLING_RATE_DSD64)
+ backend_cfg.sample_rate = OUTPUT_SAMPLING_RATE_DSD64;
+ else if (backend_cfg.sample_rate == INPUT_SAMPLING_RATE_DSD128)
+ backend_cfg.sample_rate = OUTPUT_SAMPLING_RATE_DSD128;
+ }
ALOGI("%s:becf: afe: bitwidth %d, samplerate %d channels %d"
", backend_idx %d usecase = %d device (%s)", __func__, backend_cfg.bit_width,
backend_cfg.sample_rate, backend_cfg.channels, backend_idx, usecase->id,
platform_get_snd_device_name(snd_device));
- if (!platform_can_split_snd_device(adev->platform, snd_device,
- &num_devices, new_snd_devices))
+ if (platform_split_snd_device(adev->platform, snd_device,
+ &num_devices, new_snd_devices) < 0)
new_snd_devices[0] = snd_device;
for (i = 0; i < num_devices; i++) {
@@ -5016,6 +5117,29 @@
return ret;
}
+void platform_check_and_update_copp_sample_rate(void* platform, snd_device_t snd_device,
+ unsigned int stream_sr, int* sample_rate)
+{
+ struct platform_data* my_data = (struct platform_data *)platform;
+ int backend_idx = platform_get_backend_index(snd_device);
+ int device_sr = my_data->current_backend_cfg[backend_idx].sample_rate;
+ /*Check if device SR is multiple of 8K or 11.025 Khz
+ *check if the stream SR is multiple of same base, if not set
+ *copp sample rate equal to device sample rate.
+ */
+ if (!(((sample_rate_multiple(device_sr, SAMPLE_RATE_8000)) &&
+ (sample_rate_multiple(stream_sr, SAMPLE_RATE_8000))) ||
+ ((sample_rate_multiple(device_sr, SAMPLE_RATE_11025)) &&
+ (sample_rate_multiple(stream_sr, SAMPLE_RATE_11025))))) {
+ *sample_rate = device_sr;
+ } else
+ *sample_rate = stream_sr;
+
+ ALOGI("sn_device %d device sr %d stream sr %d copp sr %d", snd_device, device_sr, stream_sr
+, *sample_rate);
+
+}
+
int platform_get_edid_info(void *platform)
{
struct platform_data *my_data = (struct platform_data *)platform;
@@ -5275,24 +5399,13 @@
{
struct platform_data *my_data = (struct platform_data *)platform;
edid_audio_info *info = NULL;
- int i, ret;
+ int ret = 0;
ret = platform_get_edid_info(platform);
info = (edid_audio_info *)my_data->edid_info;
if (ret == 0 && info != NULL) {
- for (i = 0; i < info->audio_blocks && i < MAX_EDID_BLOCKS; i++) {
- /*
- * To check
- * is there any special for CONFIG_HDMI_PASSTHROUGH_CONVERT
- * & DOLBY_DIGITAL_PLUS
- */
- if (info->audio_blocks_array[i].sampling_freq == sample_rate) {
- ALOGV("%s: returns true %d", __func__, sample_rate);
- return true;
- }
- }
+ return edid_is_supported_sr(info, sample_rate);
}
- ALOGV("%s: returns false %d", __func__, sample_rate);
return false;
}
@@ -5631,16 +5744,6 @@
return;
}
-bool platform_check_codec_dsd_support(void *platform __unused)
-{
- return false;
-}
-
-bool platform_check_codec_asrc_support(void *platform __unused)
-{
- return false;
-}
-
int platform_send_audio_cal(void* platform __unused,
int acdb_dev_id __unused, int acdb_device_type __unused,
int app_type __unused, int topology_id __unused,
diff --git a/hal/msm8916/platform.h b/hal/msm8916/platform.h
index cba9068..a0ae7d0 100644
--- a/hal/msm8916/platform.h
+++ b/hal/msm8916/platform.h
@@ -88,6 +88,7 @@
SND_DEVICE_OUT_SPEAKER_VBAT,
SND_DEVICE_OUT_LINE,
SND_DEVICE_OUT_HEADPHONES,
+ SND_DEVICE_OUT_HEADPHONES_DSD,
SND_DEVICE_OUT_HEADPHONES_44_1,
SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES,
SND_DEVICE_OUT_SPEAKER_AND_LINE,
@@ -202,6 +203,7 @@
SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS,
SND_DEVICE_IN_THREE_MIC,
SND_DEVICE_IN_HANDSET_TMIC,
+ SND_DEVICE_IN_VOICE_REC_TMIC,
SND_DEVICE_IN_UNPROCESSED_MIC,
SND_DEVICE_IN_UNPROCESSED_STEREO_MIC,
SND_DEVICE_IN_UNPROCESSED_THREE_MIC,
diff --git a/hal/msm8960/platform.c b/hal/msm8960/platform.c
index e025772..33bbc2f 100644
--- a/hal/msm8960/platform.c
+++ b/hal/msm8960/platform.c
@@ -1237,12 +1237,14 @@
int platform_spkr_prot_is_wsa_analog_mode(void *adev __unused)
{
return 0;
-bool platform_can_split_snd_device(void *platform __unused,
- snd_device_t in_snd_device __unused,
- int *num_devices __unused,
- snd_device_t *out_snd_devices __unused)
+
+}
+
+int platform_can_split_snd_device(snd_device_t in_snd_device __unused,
+ int *num_devices __unused,
+ snd_device_t *out_snd_devices __unused)
{
- return false;
+ return -ENOSYS;
}
bool platform_check_backends_match(snd_device_t snd_device1 __unused,
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index e947f91..3551006 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -446,6 +446,7 @@
[SND_DEVICE_IN_VOICE_REC_QMIC_FLUENCE] = "quad-mic",
[SND_DEVICE_IN_THREE_MIC] = "three-mic",
[SND_DEVICE_IN_HANDSET_TMIC] = "three-mic",
+ [SND_DEVICE_IN_VOICE_REC_TMIC] = "three-mic",
[SND_DEVICE_IN_UNPROCESSED_MIC] = "unprocessed-mic",
[SND_DEVICE_IN_UNPROCESSED_STEREO_MIC] = "voice-rec-dmic-ef",
[SND_DEVICE_IN_UNPROCESSED_THREE_MIC] = "three-mic",
@@ -570,6 +571,7 @@
[SND_DEVICE_IN_VOICE_REC_QMIC_FLUENCE] = 125,
[SND_DEVICE_IN_THREE_MIC] = 46, /* for APSS Surround Sound Recording */
[SND_DEVICE_IN_HANDSET_TMIC] = 125, /* for 3mic recording with fluence */
+ [SND_DEVICE_IN_VOICE_REC_TMIC] = 125,
[SND_DEVICE_IN_UNPROCESSED_MIC] = 143,
[SND_DEVICE_IN_UNPROCESSED_STEREO_MIC] = 144,
[SND_DEVICE_IN_UNPROCESSED_THREE_MIC] = 145,
@@ -693,6 +695,7 @@
{TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_QMIC_FLUENCE)},
{TO_NAME_INDEX(SND_DEVICE_IN_THREE_MIC)},
{TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_TMIC)},
+ {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_TMIC)},
{TO_NAME_INDEX(SND_DEVICE_IN_UNPROCESSED_MIC)},
{TO_NAME_INDEX(SND_DEVICE_IN_UNPROCESSED_STEREO_MIC)},
{TO_NAME_INDEX(SND_DEVICE_IN_UNPROCESSED_THREE_MIC)},
@@ -2393,8 +2396,8 @@
return -EINVAL;
}
- if(!platform_can_split_snd_device(my_data, snd_device,
- &num_devices, new_snd_device)) {
+ if (platform_split_snd_device(my_data, snd_device,
+ &num_devices, new_snd_device) < 0) {
new_snd_device[0] = snd_device;
}
@@ -2697,58 +2700,58 @@
return ret;
}
-bool platform_can_split_snd_device(void *platform,
- snd_device_t snd_device,
- int *num_devices,
- snd_device_t *new_snd_devices)
+int platform_split_snd_device(void *platform,
+ snd_device_t snd_device,
+ int *num_devices,
+ snd_device_t *new_snd_devices)
{
- bool status = false;
+ int ret = -EINVAL;
struct platform_data *my_data = (struct platform_data *)platform;
if ( NULL == num_devices || NULL == new_snd_devices || NULL == my_data) {
ALOGE("%s: NULL pointer ..", __func__);
- return false;
+ return -EINVAL;
}
/*
* If wired headset/headphones/line devices share the same backend
- * with speaker/earpiece this routine returns false.
+ * with speaker/earpiece this routine returns -EINVAL.
*/
if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES &&
!platform_check_backends_match(SND_DEVICE_OUT_SPEAKER, SND_DEVICE_OUT_HEADPHONES)) {
*num_devices = 2;
new_snd_devices[0] = SND_DEVICE_OUT_SPEAKER;
new_snd_devices[1] = SND_DEVICE_OUT_HEADPHONES;
- status = true;
+ ret = 0;
} else if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_HDMI &&
!platform_check_backends_match(SND_DEVICE_OUT_SPEAKER, SND_DEVICE_OUT_HDMI)) {
*num_devices = 2;
new_snd_devices[0] = SND_DEVICE_OUT_SPEAKER;
new_snd_devices[1] = SND_DEVICE_OUT_HDMI;
- status = true;
+ ret = 0;
} else if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_DISPLAY_PORT &&
!platform_check_backends_match(SND_DEVICE_OUT_SPEAKER, SND_DEVICE_OUT_DISPLAY_PORT)) {
*num_devices = 2;
new_snd_devices[0] = SND_DEVICE_OUT_SPEAKER;
new_snd_devices[1] = SND_DEVICE_OUT_DISPLAY_PORT;
- status = true;
+ ret = 0;
} else if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET &&
!platform_check_backends_match(SND_DEVICE_OUT_SPEAKER, SND_DEVICE_OUT_USB_HEADSET)) {
*num_devices = 2;
new_snd_devices[0] = SND_DEVICE_OUT_SPEAKER;
new_snd_devices[1] = SND_DEVICE_OUT_USB_HEADSET;
- status = true;
+ ret = 0;
} else if (SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP == snd_device) {
*num_devices = 2;
new_snd_devices[0] = SND_DEVICE_OUT_SPEAKER;
new_snd_devices[1] = SND_DEVICE_OUT_BT_A2DP;
- status = true;
+ ret = 0;
}
ALOGD("%s: snd_device(%d) num devices(%d) new_snd_devices(%d)", __func__,
snd_device, *num_devices, *new_snd_devices);
- return status;
+ return ret;
}
int platform_get_ext_disp_type(void *platform)
@@ -3138,7 +3141,7 @@
snd_device = SND_DEVICE_IN_VOICE_REC_QMIC_FLUENCE;
} else if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
(my_data->source_mic_type & SOURCE_THREE_MIC)) {
- snd_device = SND_DEVICE_IN_HANDSET_TMIC;
+ snd_device = SND_DEVICE_IN_VOICE_REC_TMIC;
} else if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
(my_data->source_mic_type & SOURCE_DUAL_MIC)) {
snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE;
@@ -4562,8 +4565,12 @@
//Check EDID info for supported samplerate
if (!edid_is_supported_sr(edid_info,sample_rate)) {
- //reset to current sample rate
- sample_rate = my_data->current_backend_cfg[backend_idx].sample_rate;
+ //check to see if current BE sample rate is supported by EDID
+ //else assign the highest sample rate supported by EDID
+ if (edid_is_supported_sr(edid_info,my_data->current_backend_cfg[backend_idx].sample_rate))
+ sample_rate = my_data->current_backend_cfg[backend_idx].sample_rate;
+ else
+ sample_rate = edid_get_highest_supported_sr(edid_info);
}
//Check EDID info for supported bit width
@@ -4829,7 +4836,8 @@
backend_cfg.sample_rate, backend_cfg.channels, backend_idx, usecase->id,
platform_get_snd_device_name(snd_device));
- if (!platform_can_split_snd_device(my_data, snd_device, &num_devices, new_snd_devices))
+ if (platform_split_snd_device(my_data, snd_device, &num_devices,
+ new_snd_devices) < 0)
new_snd_devices[0] = snd_device;
for (i = 0; i < num_devices; i++) {
@@ -5299,6 +5307,32 @@
return fragment_size;
}
+void platform_check_and_update_copp_sample_rate(void* platform, snd_device_t snd_device,
+ unsigned int stream_sr, int* sample_rate)
+{
+ struct platform_data* my_data = (struct platform_data *)platform;
+ int backend_idx = platform_get_backend_index(snd_device);
+ int device_sr = my_data->current_backend_cfg[backend_idx].sample_rate;
+ /*
+ *Check if device SR is multiple of 8K or 11.025 Khz
+ *check if the stream SR is multiple of same base, if yes
+ *then have copp SR equal to stream SR, this ensures that
+ *post processing happens at stream SR, else have
+ *copp SR equal to device SR.
+ */
+ if (!(((sample_rate_multiple(device_sr, SAMPLE_RATE_8000)) &&
+ (sample_rate_multiple(stream_sr, SAMPLE_RATE_8000))) ||
+ ((sample_rate_multiple(device_sr, SAMPLE_RATE_11025)) &&
+ (sample_rate_multiple(stream_sr, SAMPLE_RATE_11025))))) {
+ *sample_rate = device_sr;
+ } else
+ *sample_rate = stream_sr;
+
+ ALOGI("sn_device %d device sr %d stream sr %d copp sr %d", snd_device, device_sr, stream_sr
+, *sample_rate);
+
+}
+
void platform_reset_edid_info(void *platform) {
ALOGV("%s:", __func__);
@@ -5347,24 +5381,13 @@
{
struct platform_data *my_data = (struct platform_data *)platform;
edid_audio_info *info = NULL;
- int i, ret;
+ int ret = 0;
ret = platform_get_edid_info(platform);
info = (edid_audio_info *)my_data->edid_info;
if (ret == 0 && info != NULL) {
- for (i = 0; i < info->audio_blocks && i < MAX_EDID_BLOCKS; i++) {
- /*
- * To check
- * is there any special for CONFIG_HDMI_PASSTHROUGH_CONVERT
- * & DOLBY_DIGITAL_PLUS
- */
- if (info->audio_blocks_array[i].sampling_freq == sample_rate) {
- ALOGV("%s: returns true %d", __func__, sample_rate);
- return true;
- }
- }
+ return edid_is_supported_sr(info, sample_rate);
}
- ALOGV("%s: returns false %d", __func__, sample_rate);
return false;
}
diff --git a/hal/msm8974/platform.h b/hal/msm8974/platform.h
index c231843..fcfe4d1 100644
--- a/hal/msm8974/platform.h
+++ b/hal/msm8974/platform.h
@@ -197,6 +197,7 @@
SND_DEVICE_IN_VOICE_REC_QMIC_FLUENCE,
SND_DEVICE_IN_THREE_MIC,
SND_DEVICE_IN_HANDSET_TMIC,
+ SND_DEVICE_IN_VOICE_REC_TMIC,
SND_DEVICE_IN_UNPROCESSED_MIC,
SND_DEVICE_IN_UNPROCESSED_STEREO_MIC,
SND_DEVICE_IN_UNPROCESSED_THREE_MIC,
diff --git a/hal/platform_api.h b/hal/platform_api.h
index 61f42de..d3cb23f 100644
--- a/hal/platform_api.h
+++ b/hal/platform_api.h
@@ -25,7 +25,9 @@
#define CODEC_BACKEND_DEFAULT_SAMPLE_RATE 48000
#define CODEC_BACKEND_DEFAULT_CHANNELS 2
#define CODEC_BACKEND_DEFAULT_TX_CHANNELS 1
-
+#define SAMPLE_RATE_8000 8000
+#define SAMPLE_RATE_11025 11025
+#define sample_rate_multiple(sr, base) ((sr % base)== 0?true:false)
enum {
NATIVE_AUDIO_MODE_SRC = 1,
@@ -147,10 +149,10 @@
int platform_get_spkr_prot_snd_device(snd_device_t snd_device);
int platform_get_vi_feedback_snd_device(snd_device_t snd_device);
int platform_spkr_prot_is_wsa_analog_mode(void *adev);
-bool platform_can_split_snd_device(void *platform,
- snd_device_t snd_device,
- int *num_devices,
- snd_device_t *new_snd_devices);
+int platform_split_snd_device(void *platform,
+ snd_device_t snd_device,
+ int *num_devices,
+ snd_device_t *new_snd_devices);
bool platform_check_backends_match(snd_device_t snd_device1, snd_device_t snd_device2);
int platform_set_sidetone(struct audio_device *adev,
@@ -187,4 +189,6 @@
unsigned char* platform_get_license(void* platform, int* size);
int platform_get_max_mic_count(void *platform);
+void platform_check_and_update_copp_sample_rate(void *platform, snd_device_t snd_device,
+ unsigned int stream_sr,int *sample_rate);
#endif // AUDIO_PLATFORM_API_H
diff --git a/policy_hal/AudioPolicyManager.cpp b/policy_hal/AudioPolicyManager.cpp
index 089efc5..3396054 100644
--- a/policy_hal/AudioPolicyManager.cpp
+++ b/policy_hal/AudioPolicyManager.cpp
@@ -1409,6 +1409,7 @@
{
bool playerDirectPCM = false; // Output request for Track created by mediaplayer
bool trackDirectPCM = false; // Output request for track created by other apps
+ bool offloadDisabled = property_get_bool("audio.offload.disable", false);
// Direct PCM is allowed only if
// In case of mediaPlayer playback
@@ -1417,6 +1418,10 @@
// In case of AudioTracks created by apps
// track offload is enabled and FLAG requested is FLAG_NONE.
+ if (offloadDisabled) {
+ ALOGI("offload disabled by audio.offload.disable=%d", offloadDisabled);
+ }
+
if (*flags == AUDIO_OUTPUT_FLAG_DIRECT_PCM) {
if (bitWidth == 24 || bitWidth == 32)
playerDirectPCM =
@@ -1431,8 +1436,10 @@
trackDirectPCM = property_get_bool("audio.offload.track.enable", true);
}
- ALOGI("%s for Direct PCM",trackDirectPCM || playerDirectPCM?"Check":"Dont check");
- return trackDirectPCM || playerDirectPCM;
+ ALOGI("Direct PCM %s for this request",
+ (!offloadDisabled && (trackDirectPCM || playerDirectPCM))?"can be enabled":"is disabled");
+
+ return (!offloadDisabled && (trackDirectPCM || playerDirectPCM));
}
status_t AudioPolicyManagerCustom::getOutputForAttr(const audio_attributes_t *attr,
@@ -1449,15 +1456,11 @@
{
audio_offload_info_t tOffloadInfo = AUDIO_INFO_INITIALIZER;
- bool offloadDisabled = property_get_bool("audio.offload.disable", false);
uint32_t bitWidth = (audio_bytes_per_sample(format) * 8);
- if (offloadDisabled) {
- ALOGI("offload disabled by audio.offload.disable=%d", offloadDisabled);
- }
- if (!offloadDisabled && (offloadInfo == NULL) &&
- tryForDirectPCM(bitWidth, &flags)) {
+ if (tryForDirectPCM(bitWidth, &flags) &&
+ (offloadInfo == NULL)) {
tOffloadInfo.sample_rate = samplingRate;
tOffloadInfo.channel_mask = channelMask;