Merge "policy_hal: Null check for output profile types"
diff --git a/audiod/AudioDaemon.cpp b/audiod/AudioDaemon.cpp
index 6c8d991..6105635 100644
--- a/audiod/AudioDaemon.cpp
+++ b/audiod/AudioDaemon.cpp
@@ -48,7 +48,7 @@
void AudioDaemon::onFirstRef() {
ALOGV("Start audiod daemon");
- run("AudioDaemon", PRIORITY_AUDIO);
+ run("AudioDaemon", PRIORITY_URGENT_AUDIO);
}
void AudioDaemon::binderDied(const wp<IBinder>& who)
diff --git a/hal/Android.mk b/hal/Android.mk
index bc17a57..0ec3e3d 100644
--- a/hal/Android.mk
+++ b/hal/Android.mk
@@ -126,6 +126,9 @@
endif
endif
+ifeq ($(strip $(AUDIO_FEATURE_ENABLED_MULTIPLE_TUNNEL)), true)
+ LOCAL_CFLAGS += -DMULTIPLE_OFFLOAD_ENABLED
+endif
LOCAL_SHARED_LIBRARIES := \
liblog \
diff --git a/hal/audio_extn/audio_extn.c b/hal/audio_extn/audio_extn.c
index d0caccb..3776652 100644
--- a/hal/audio_extn/audio_extn.c
+++ b/hal/audio_extn/audio_extn.c
@@ -52,6 +52,8 @@
#define AUDIO_PARAMETER_KEY_WFD "wfd_channel_cap"
#define AUDIO_PARAMETER_CAN_OPEN_PROXY "can_open_proxy"
#define AUDIO_PARAMETER_CUSTOM_STEREO "stereo_as_dual_mono"
+/* Query offload playback instances count */
+#define AUDIO_PARAMETER_OFFLOAD_NUM_ACTIVE "offload_num_active"
#ifndef FM_ENABLED
#define audio_extn_fm_set_parameters(adev, parms) (0)
@@ -424,6 +426,30 @@
#endif /* AFE_PROXY_ENABLED */
+static int get_active_offload_usecases(const struct audio_device *adev,
+ struct str_parms *query,
+ struct str_parms *reply)
+{
+ int ret, count = 0;
+ char value[32]={0};
+ struct listnode *node;
+ struct audio_usecase *usecase;
+
+ ALOGV("%s", __func__);
+ ret = str_parms_get_str(query, AUDIO_PARAMETER_OFFLOAD_NUM_ACTIVE, value,
+ sizeof(value));
+ if (ret >= 0) {
+ list_for_each(node, &adev->usecase_list) {
+ usecase = node_to_item(node, struct audio_usecase, list);
+ if (is_offload_usecase(usecase->id))
+ count++;
+ }
+ ALOGV("%s, number of active offload usecases: %d", __func__, count);
+ str_parms_add_int(reply, AUDIO_PARAMETER_OFFLOAD_NUM_ACTIVE, count);
+ }
+ return ret;
+}
+
void audio_extn_set_parameters(struct audio_device *adev,
struct str_parms *parms)
{
@@ -444,6 +470,7 @@
char *kv_pairs = NULL;
audio_extn_get_afe_proxy_parameters(query, reply);
audio_extn_get_fluence_parameters(adev, query, reply);
+ get_active_offload_usecases(adev, query, reply);
kv_pairs = str_parms_to_str(reply);
ALOGD_IF(kv_pairs != NULL, "%s: returns %s", __func__, kv_pairs);
diff --git a/hal/audio_extn/compress_capture.c b/hal/audio_extn/compress_capture.c
index 0a2de36..6559582 100644
--- a/hal/audio_extn/compress_capture.c
+++ b/hal/audio_extn/compress_capture.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013 - 2014, The Linux Foundation. All rights reserved.
* Not a Contribution.
*
* Copyright (C) 2013 The Android Open Source Project
diff --git a/hal/audio_extn/fm.c b/hal/audio_extn/fm.c
index 35b20b8..0c5bb07 100644
--- a/hal/audio_extn/fm.c
+++ b/hal/audio_extn/fm.c
@@ -122,11 +122,11 @@
}
/* 2. Get and set stream specific mixer controls */
- disable_audio_route(adev, uc_info, true);
+ disable_audio_route(adev, uc_info);
/* 3. Disable the rx and tx devices */
- disable_snd_device(adev, uc_info->out_snd_device, false);
- disable_snd_device(adev, uc_info->in_snd_device, true);
+ disable_snd_device(adev, uc_info->out_snd_device);
+ disable_snd_device(adev, uc_info->in_snd_device);
list_remove(&uc_info->list);
free(uc_info);
@@ -229,9 +229,10 @@
ALOGD("%s: FM usecase", __func__);
if (val != 0) {
if(val & AUDIO_DEVICE_OUT_FM
- && fmmod.is_fm_running == false)
+ && fmmod.is_fm_running == false) {
+ adev->primary_output->devices = val & ~AUDIO_DEVICE_OUT_FM;
fm_start(adev);
- else if (!(val & AUDIO_DEVICE_OUT_FM)
+ } else if (!(val & AUDIO_DEVICE_OUT_FM)
&& fmmod.is_fm_running == true)
fm_stop(adev);
}
diff --git a/hal/audio_extn/hfp.c b/hal/audio_extn/hfp.c
index ed253c2..add4a7c 100644
--- a/hal/audio_extn/hfp.c
+++ b/hal/audio_extn/hfp.c
@@ -1,5 +1,5 @@
/* hfp.c
-Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
@@ -245,11 +245,11 @@
}
/* 2. Get and set stream specific mixer controls */
- disable_audio_route(adev, uc_info, true);
+ disable_audio_route(adev, uc_info);
/* 3. Disable the rx and tx devices */
- disable_snd_device(adev, uc_info->out_snd_device, false);
- disable_snd_device(adev, uc_info->in_snd_device, true);
+ disable_snd_device(adev, uc_info->out_snd_device);
+ disable_snd_device(adev, uc_info->in_snd_device);
list_remove(&uc_info->list);
free(uc_info);
diff --git a/hal/audio_extn/spkr_protection.c b/hal/audio_extn/spkr_protection.c
index 6c0eec0..ce673ea 100644
--- a/hal/audio_extn/spkr_protection.c
+++ b/hal/audio_extn/spkr_protection.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013 - 2014, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -227,8 +227,8 @@
uc_info_rx->out_snd_device = SND_DEVICE_OUT_SPEAKER_PROTECTED;
pthread_mutex_lock(&adev->lock);
disable_rx = true;
- enable_snd_device(adev, SND_DEVICE_OUT_SPEAKER_PROTECTED, true);
- enable_audio_route(adev, uc_info_rx, true);
+ enable_snd_device(adev, SND_DEVICE_OUT_SPEAKER_PROTECTED);
+ enable_audio_route(adev, uc_info_rx);
pthread_mutex_unlock(&adev->lock);
pcm_dev_rx_id = platform_get_pcm_device_id(uc_info_rx->id, PCM_PLAYBACK);
@@ -257,8 +257,8 @@
pthread_mutex_lock(&adev->lock);
disable_tx = true;
- enable_snd_device(adev, SND_DEVICE_IN_CAPTURE_VI_FEEDBACK, true);
- enable_audio_route(adev, uc_info_tx, true);
+ enable_snd_device(adev, SND_DEVICE_IN_CAPTURE_VI_FEEDBACK);
+ enable_audio_route(adev, uc_info_tx);
pthread_mutex_unlock(&adev->lock);
pcm_dev_tx_id = platform_get_pcm_device_id(uc_info_tx->id, PCM_CAPTURE);
@@ -336,12 +336,12 @@
handle.pcm_tx = NULL;
pthread_mutex_lock(&adev->lock);
if (disable_rx) {
- disable_snd_device(adev, SND_DEVICE_OUT_SPEAKER_PROTECTED, true);
- disable_audio_route(adev, uc_info_rx, true);
+ disable_snd_device(adev, SND_DEVICE_OUT_SPEAKER_PROTECTED);
+ disable_audio_route(adev, uc_info_rx);
}
if (disable_tx) {
- disable_snd_device(adev, SND_DEVICE_IN_CAPTURE_VI_FEEDBACK, true);
- disable_audio_route(adev, uc_info_tx, true);
+ disable_snd_device(adev, SND_DEVICE_IN_CAPTURE_VI_FEEDBACK);
+ disable_audio_route(adev, uc_info_tx);
}
pthread_mutex_unlock(&adev->lock);
@@ -598,7 +598,7 @@
}
ALOGV("%s: snd_device(%d: %s)", __func__, snd_device,
platform_get_snd_device_name(SND_DEVICE_OUT_SPEAKER_PROTECTED));
- audio_route_apply_path(adev->audio_route,
+ audio_route_apply_and_update_path(adev->audio_route,
platform_get_snd_device_name(SND_DEVICE_OUT_SPEAKER_PROTECTED));
pthread_mutex_lock(&handle.mutex_spkr_prot);
@@ -610,8 +610,8 @@
uc_info_tx.out_snd_device = SND_DEVICE_NONE;
handle.pcm_tx = NULL;
- enable_snd_device(adev, SND_DEVICE_IN_CAPTURE_VI_FEEDBACK, true);
- enable_audio_route(adev, &uc_info_tx, true);
+ enable_snd_device(adev, SND_DEVICE_IN_CAPTURE_VI_FEEDBACK);
+ enable_audio_route(adev, &uc_info_tx);
pcm_dev_tx_id = platform_get_pcm_device_id(uc_info_tx.id, PCM_CAPTURE);
if (pcm_dev_tx_id < 0) {
@@ -642,8 +642,8 @@
if (handle.pcm_tx)
pcm_close(handle.pcm_tx);
handle.pcm_tx = NULL;
- disable_snd_device(adev, SND_DEVICE_IN_CAPTURE_VI_FEEDBACK, true);
- disable_audio_route(adev, &uc_info_tx, true);
+ disable_snd_device(adev, SND_DEVICE_IN_CAPTURE_VI_FEEDBACK);
+ disable_audio_route(adev, &uc_info_tx);
} else
handle.spkr_processing_state = SPKR_PROCESSING_IN_PROGRESS;
pthread_mutex_unlock(&handle.mutex_spkr_prot);
@@ -667,12 +667,12 @@
if (handle.pcm_tx)
pcm_close(handle.pcm_tx);
handle.pcm_tx = NULL;
- disable_snd_device(adev, SND_DEVICE_IN_CAPTURE_VI_FEEDBACK, true);
- disable_audio_route(adev, &uc_info_tx, true);
+ disable_snd_device(adev, SND_DEVICE_IN_CAPTURE_VI_FEEDBACK);
+ disable_audio_route(adev, &uc_info_tx);
}
handle.spkr_processing_state = SPKR_PROCESSING_IN_IDLE;
pthread_mutex_unlock(&handle.mutex_spkr_prot);
- audio_route_reset_path(adev->audio_route,
+ audio_route_reset_and_update_path(adev->audio_route,
platform_get_snd_device_name(SND_DEVICE_OUT_SPEAKER_PROTECTED));
ALOGV("%s: Exit", __func__);
}
diff --git a/hal/audio_extn/usb.c b/hal/audio_extn/usb.c
index 281b445..0240d7c 100644
--- a/hal/audio_extn/usb.c
+++ b/hal/audio_extn/usb.c
@@ -580,6 +580,11 @@
usbmod->proxy_card = 0;
usbmod->proxy_device_id = AFE_PROXY_PLAYBACK_DEVICE;
usbmod->adev = (struct audio_device*)adev;
+
+ pthread_mutex_init(&usbmod->usb_playback_lock,
+ (const pthread_mutexattr_t *) NULL);
+ pthread_mutex_init(&usbmod->usb_record_lock,
+ (const pthread_mutexattr_t *) NULL);
}
void audio_extn_usb_deinit()
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 2f67784..97fb87a 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -107,6 +107,16 @@
[USECASE_AUDIO_PLAYBACK_LOW_LATENCY] = "low-latency-playback",
[USECASE_AUDIO_PLAYBACK_MULTI_CH] = "multi-channel-playback",
[USECASE_AUDIO_PLAYBACK_OFFLOAD] = "compress-offload-playback",
+#ifdef MULTIPLE_OFFLOAD_ENABLED
+ [USECASE_AUDIO_PLAYBACK_OFFLOAD2] = "compress-offload-playback2",
+ [USECASE_AUDIO_PLAYBACK_OFFLOAD3] = "compress-offload-playback3",
+ [USECASE_AUDIO_PLAYBACK_OFFLOAD4] = "compress-offload-playback4",
+ [USECASE_AUDIO_PLAYBACK_OFFLOAD5] = "compress-offload-playback5",
+ [USECASE_AUDIO_PLAYBACK_OFFLOAD6] = "compress-offload-playback6",
+ [USECASE_AUDIO_PLAYBACK_OFFLOAD7] = "compress-offload-playback7",
+ [USECASE_AUDIO_PLAYBACK_OFFLOAD8] = "compress-offload-playback8",
+ [USECASE_AUDIO_PLAYBACK_OFFLOAD9] = "compress-offload-playback9",
+#endif
[USECASE_AUDIO_RECORD] = "audio-record",
[USECASE_AUDIO_RECORD_COMPRESS] = "audio-record-compress",
[USECASE_AUDIO_RECORD_LOW_LATENCY] = "low-latency-record",
@@ -134,6 +144,19 @@
[USECASE_AUDIO_SPKR_CALIB_TX] = "spkr-vi-record",
};
+static const audio_usecase_t offload_usecases[] = {
+ USECASE_AUDIO_PLAYBACK_OFFLOAD,
+#ifdef MULTIPLE_OFFLOAD_ENABLED
+ USECASE_AUDIO_PLAYBACK_OFFLOAD2,
+ USECASE_AUDIO_PLAYBACK_OFFLOAD3,
+ USECASE_AUDIO_PLAYBACK_OFFLOAD4,
+ USECASE_AUDIO_PLAYBACK_OFFLOAD5,
+ USECASE_AUDIO_PLAYBACK_OFFLOAD6,
+ USECASE_AUDIO_PLAYBACK_OFFLOAD7,
+ USECASE_AUDIO_PLAYBACK_OFFLOAD8,
+ USECASE_AUDIO_PLAYBACK_OFFLOAD9,
+#endif
+};
#define STRING_TO_ENUM(string) { #string, string }
@@ -215,8 +238,7 @@
}
int enable_audio_route(struct audio_device *adev,
- struct audio_usecase *usecase,
- bool update_mixer)
+ struct audio_usecase *usecase)
{
snd_device_t snd_device;
char mixer_path[MIXER_PATH_MAX_LENGTH];
@@ -237,18 +259,14 @@
#endif
strcpy(mixer_path, use_case_table[usecase->id]);
platform_add_backend_name(mixer_path, snd_device);
- ALOGV("%s: apply mixer path: %s", __func__, mixer_path);
- audio_route_apply_path(adev->audio_route, mixer_path);
- if (update_mixer)
- audio_route_update_mixer(adev->audio_route);
-
+ ALOGV("%s: apply mixer and update path: %s", __func__, mixer_path);
+ audio_route_apply_and_update_path(adev->audio_route, mixer_path);
ALOGV("%s: exit", __func__);
return 0;
}
int disable_audio_route(struct audio_device *adev,
- struct audio_usecase *usecase,
- bool update_mixer)
+ struct audio_usecase *usecase)
{
snd_device_t snd_device;
char mixer_path[MIXER_PATH_MAX_LENGTH];
@@ -263,18 +281,14 @@
snd_device = usecase->out_snd_device;
strcpy(mixer_path, use_case_table[usecase->id]);
platform_add_backend_name(mixer_path, snd_device);
- ALOGV("%s: reset mixer path: %s", __func__, mixer_path);
- audio_route_reset_path(adev->audio_route, mixer_path);
- if (update_mixer)
- audio_route_update_mixer(adev->audio_route);
-
+ ALOGV("%s: reset and update mixer path: %s", __func__, mixer_path);
+ audio_route_reset_and_update_path(adev->audio_route, mixer_path);
ALOGV("%s: exit", __func__);
return 0;
}
int enable_snd_device(struct audio_device *adev,
- snd_device_t snd_device,
- bool update_mixer)
+ snd_device_t snd_device)
{
char device_name[DEVICE_NAME_MAX_SIZE] = {0};
@@ -296,20 +310,6 @@
return 0;
}
- /* Set BT sample rate before enabling the devices. Adding sample rate mixer
- * control in use-case does not work because rate update takes place after
- * AFE port open due to the limitation of mixer control order execution.
- */
- if ((snd_device == SND_DEVICE_OUT_BT_SCO) ||
- (snd_device == SND_DEVICE_IN_BT_SCO_MIC)) {
- audio_route_apply_path(adev->audio_route, BT_SCO_SAMPLE_RATE);
- audio_route_update_mixer(adev->audio_route);
- } else if ((snd_device == SND_DEVICE_OUT_BT_SCO_WB) ||
- (snd_device == SND_DEVICE_IN_BT_SCO_MIC_WB)) {
- audio_route_apply_path(adev->audio_route, BT_SCO_WB_SAMPLE_RATE);
- audio_route_update_mixer(adev->audio_route);
- }
-
/* start usb playback thread */
if(SND_DEVICE_OUT_USB_HEADSET == snd_device ||
SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET == snd_device)
@@ -329,24 +329,23 @@
} else {
ALOGV("%s: snd_device(%d: %s)", __func__,
snd_device, device_name);
+ /* due to the possibility of calibration overwrite between listen
+ and audio, notify listen hal before audio calibration is sent */
+ audio_extn_listen_update_status(snd_device,
+ LISTEN_EVENT_SND_DEVICE_BUSY);
if (platform_send_audio_calibration(adev->platform, snd_device) < 0) {
adev->snd_dev_ref_cnt[snd_device]--;
+ audio_extn_listen_update_status(snd_device,
+ LISTEN_EVENT_SND_DEVICE_FREE);
return -EINVAL;
}
- audio_extn_listen_update_status(snd_device,
- LISTEN_EVENT_SND_DEVICE_BUSY);
-
- audio_route_apply_path(adev->audio_route, device_name);
+ audio_route_apply_and_update_path(adev->audio_route, device_name);
}
- if (update_mixer)
- audio_route_update_mixer(adev->audio_route);
-
return 0;
}
int disable_snd_device(struct audio_device *adev,
- snd_device_t snd_device,
- bool update_mixer)
+ snd_device_t snd_device)
{
char device_name[DEVICE_NAME_MAX_SIZE] = {0};
@@ -384,10 +383,7 @@
audio_extn_spkr_prot_is_enabled()) {
audio_extn_spkr_prot_stop_processing();
} else
- audio_route_reset_path(adev->audio_route, device_name);
-
- if (update_mixer)
- audio_route_update_mixer(adev->audio_route);
+ audio_route_reset_and_update_path(adev->audio_route, device_name);
audio_extn_listen_update_status(snd_device,
LISTEN_EVENT_SND_DEVICE_FREE);
@@ -429,29 +425,28 @@
ALOGV("%s: Usecase (%s) is active on (%s) - disabling ..",
__func__, use_case_table[usecase->id],
platform_get_snd_device_name(usecase->out_snd_device));
- disable_audio_route(adev, usecase, false);
+ disable_audio_route(adev, usecase);
switch_device[usecase->id] = true;
num_uc_to_switch++;
}
}
if (num_uc_to_switch) {
- /* Make sure all the streams are de-routed before disabling the device */
- audio_route_update_mixer(adev->audio_route);
+ /* All streams have been de-routed. Disable the device */
/* Make sure the previous devices to be disabled first and then enable the
selected devices */
list_for_each(node, &adev->usecase_list) {
usecase = node_to_item(node, struct audio_usecase, list);
if (switch_device[usecase->id]) {
- disable_snd_device(adev, usecase->out_snd_device, true);
+ disable_snd_device(adev, usecase->out_snd_device);
}
}
list_for_each(node, &adev->usecase_list) {
usecase = node_to_item(node, struct audio_usecase, list);
if (switch_device[usecase->id]) {
- enable_snd_device(adev, snd_device, true);
+ enable_snd_device(adev, snd_device);
}
}
@@ -462,7 +457,7 @@
/* Update the out_snd_device only before enabling the audio route */
if (switch_device[usecase->id] ) {
usecase->out_snd_device = snd_device;
- enable_audio_route(adev, usecase, false);
+ enable_audio_route(adev, usecase);
}
}
}
@@ -498,29 +493,28 @@
ALOGV("%s: Usecase (%s) is active on (%s) - disabling ..",
__func__, use_case_table[usecase->id],
platform_get_snd_device_name(usecase->in_snd_device));
- disable_audio_route(adev, usecase, false);
+ disable_audio_route(adev, usecase);
switch_device[usecase->id] = true;
num_uc_to_switch++;
}
}
if (num_uc_to_switch) {
- /* Make sure all the streams are de-routed before disabling the device */
- audio_route_update_mixer(adev->audio_route);
+ /* All streams have been de-routed. Disable the device */
/* Make sure the previous devices to be disabled first and then enable the
selected devices */
list_for_each(node, &adev->usecase_list) {
usecase = node_to_item(node, struct audio_usecase, list);
if (switch_device[usecase->id]) {
- disable_snd_device(adev, usecase->in_snd_device, true);
+ disable_snd_device(adev, usecase->in_snd_device);
}
}
list_for_each(node, &adev->usecase_list) {
usecase = node_to_item(node, struct audio_usecase, list);
if (switch_device[usecase->id]) {
- enable_snd_device(adev, snd_device, true);
+ enable_snd_device(adev, snd_device);
}
}
@@ -531,7 +525,7 @@
/* Update the in_snd_device only before enabling the audio route */
if (switch_device[usecase->id] ) {
usecase->in_snd_device = snd_device;
- enable_audio_route(adev, usecase, false);
+ enable_audio_route(adev, usecase);
}
}
}
@@ -698,13 +692,13 @@
/* Disable current sound devices */
if (usecase->out_snd_device != SND_DEVICE_NONE) {
- disable_audio_route(adev, usecase, true);
- disable_snd_device(adev, usecase->out_snd_device, true);
+ disable_audio_route(adev, usecase);
+ disable_snd_device(adev, usecase->out_snd_device);
}
if (usecase->in_snd_device != SND_DEVICE_NONE) {
- disable_audio_route(adev, usecase, true);
- disable_snd_device(adev, usecase->in_snd_device, true);
+ disable_audio_route(adev, usecase);
+ disable_snd_device(adev, usecase->in_snd_device);
}
/* Applicable only on the targets that has external modem.
@@ -720,12 +714,12 @@
if (out_snd_device != SND_DEVICE_NONE) {
if (usecase->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND)
check_usecases_codec_backend(adev, usecase, out_snd_device);
- enable_snd_device(adev, out_snd_device, false);
+ enable_snd_device(adev, out_snd_device);
}
if (in_snd_device != SND_DEVICE_NONE) {
check_and_route_capture_usecases(adev, usecase, in_snd_device);
- enable_snd_device(adev, in_snd_device, false);
+ enable_snd_device(adev, in_snd_device);
}
if (usecase->type == VOICE_CALL || usecase->type == VOIP_CALL)
@@ -733,12 +727,10 @@
out_snd_device,
in_snd_device);
- audio_route_update_mixer(adev->audio_route);
-
usecase->in_snd_device = in_snd_device;
usecase->out_snd_device = out_snd_device;
- enable_audio_route(adev, usecase, true);
+ enable_audio_route(adev, usecase);
/* Applicable only on the targets that has external modem.
* Enable device command should be sent to modem only after
@@ -773,10 +765,10 @@
voice_check_and_stop_incall_rec_usecase(adev, in);
/* 1. Disable stream specific mixer controls */
- disable_audio_route(adev, uc_info, true);
+ disable_audio_route(adev, uc_info);
/* 2. Disable the tx device */
- disable_snd_device(adev, uc_info->in_snd_device, true);
+ disable_snd_device(adev, uc_info->in_snd_device);
list_remove(&uc_info->list);
free(uc_info);
@@ -874,6 +866,51 @@
}
}
+bool is_offload_usecase(audio_usecase_t uc_id)
+{
+ unsigned int i;
+ for (i = 0; i < sizeof(offload_usecases)/sizeof(offload_usecases[0]); i++) {
+ if (uc_id == offload_usecases[i])
+ return true;
+ }
+ return false;
+}
+
+static audio_usecase_t get_offload_usecase(struct audio_device *adev)
+{
+ audio_usecase_t ret = USECASE_AUDIO_PLAYBACK_OFFLOAD;
+ unsigned int i, num_usecase = sizeof(offload_usecases)/sizeof(offload_usecases[0]);
+ char value[PROPERTY_VALUE_MAX] = {0};
+
+ property_get("audio.offload.multiple.enabled", value, NULL);
+ if (!(atoi(value) || !strncmp("true", value, 4)))
+ num_usecase = 1; /* If prop is not set, limit the num of offload usecases to 1 */
+
+ ALOGV("%s: num_usecase: %d", __func__, num_usecase);
+ for (i = 0; i < num_usecase; i++) {
+ if (!(adev->offload_usecases_state & (0x1<<i))) {
+ adev->offload_usecases_state |= 0x1 << i;
+ ret = offload_usecases[i];
+ break;
+ }
+ }
+ ALOGV("%s: offload usecase is %d", __func__, ret);
+ return ret;
+}
+
+static void free_offload_usecase(struct audio_device *adev,
+ audio_usecase_t uc_id)
+{
+ unsigned int i;
+ for (i = 0; i < sizeof(offload_usecases)/sizeof(offload_usecases[0]); i++) {
+ if (offload_usecases[i] == uc_id) {
+ adev->offload_usecases_state &= ~(0x1<<i);
+ break;
+ }
+ }
+ ALOGV("%s: free offload usecase %d", __func__, uc_id);
+}
+
static void *offload_thread_loop(void *context)
{
struct stream_out *out = (struct stream_out *) context;
@@ -1021,7 +1058,7 @@
"no change in HDMI channels", __func__);
ret = false;
break;
- } else if (usecase->id == USECASE_AUDIO_PLAYBACK_OFFLOAD &&
+ } else if (is_offload_usecase(usecase->id) &&
popcount(usecase->stream.out->channel_mask) > 2) {
ALOGD("%s: multi-channel(%x) compress offload playback is active, "
"no change in HDMI channels", __func__, usecase->stream.out->channel_mask);
@@ -1060,7 +1097,7 @@
usecase = node_to_item(node, struct audio_usecase, list);
if (usecase->type == PCM_PLAYBACK &&
usecase->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
- disable_audio_route(adev, usecase, true);
+ disable_audio_route(adev, usecase);
}
}
@@ -1072,7 +1109,7 @@
usecase = node_to_item(node, struct audio_usecase, list);
if (usecase->type == PCM_PLAYBACK &&
usecase->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
- enable_audio_route(adev, usecase, true);
+ enable_audio_route(adev, usecase);
}
}
@@ -1094,7 +1131,7 @@
return -EINVAL;
}
- if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
+ if (is_offload_usecase(out->usecase)) {
if (adev->visualizer_stop_output != NULL)
adev->visualizer_stop_output(out->handle, out->pcm_device_id);
if (adev->offload_effects_stop_output != NULL)
@@ -1102,10 +1139,10 @@
}
/* 1. Get and set stream specific mixer controls */
- disable_audio_route(adev, uc_info, true);
+ disable_audio_route(adev, uc_info);
/* 2. Disable the rx device */
- disable_snd_device(adev, uc_info->out_snd_device, true);
+ disable_snd_device(adev, uc_info->out_snd_device);
list_remove(&uc_info->list);
free(uc_info);
@@ -1144,7 +1181,7 @@
/* This must be called before adding this usecase to the list */
if (out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
- if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
+ if (is_offload_usecase(out->usecase))
check_and_set_hdmi_channels(adev, out->compr_config.codec->ch_in);
else
check_and_set_hdmi_channels(adev, out->config.channels);
@@ -1156,7 +1193,7 @@
ALOGV("%s: Opening PCM device card_id(%d) device_id(%d)",
__func__, 0, out->pcm_device_id);
- if (out->usecase != USECASE_AUDIO_PLAYBACK_OFFLOAD) {
+ if (!is_offload_usecase(out->usecase)) {
out->pcm = pcm_open(adev->snd_card,
out->pcm_device_id,
PCM_OUT | PCM_MONOTONIC, &out->config);
@@ -1274,7 +1311,7 @@
{
struct stream_out *out = (struct stream_out *)stream;
- if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
+ if (is_offload_usecase(out->usecase))
return out->compr_config.fragment_size;
else if(out->usecase == USECASE_COMPRESS_VOIP_CALL)
return voice_extn_compress_voip_out_get_buffer_size(out);
@@ -1320,7 +1357,7 @@
if (!out->standby) {
pthread_mutex_lock(&adev->lock);
out->standby = true;
- if (out->usecase != USECASE_AUDIO_PLAYBACK_OFFLOAD) {
+ if (!is_offload_usecase(out->usecase)) {
if (out->pcm) {
pcm_close(out->pcm);
out->pcm = NULL;
@@ -1487,7 +1524,7 @@
audio_extn_set_parameters(adev, parms);
pthread_mutex_unlock(&adev->lock);
}
- if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
+ if (is_offload_usecase(out->usecase)) {
pthread_mutex_lock(&out->lock);
parse_compress_metadata(out, parms);
pthread_mutex_unlock(&out->lock);
@@ -1546,7 +1583,7 @@
{
struct stream_out *out = (struct stream_out *)stream;
- if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
+ if (is_offload_usecase(out->usecase))
return COMPRESS_OFFLOAD_PLAYBACK_LATENCY;
return (out->config.period_count * out->config.period_size * 1000) /
@@ -1563,7 +1600,7 @@
/* only take left channel into account: the API is for stereo anyway */
out->muted = (left == 0.0f);
return 0;
- } else if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
+ } else if (is_offload_usecase(out->usecase)) {
char mixer_ctl_name[128];
struct audio_device *adev = out->dev;
struct mixer_ctl *ctl;
@@ -1610,7 +1647,7 @@
}
}
- if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
+ if (is_offload_usecase(out->usecase)) {
ALOGD("copl(%x): writing buffer (%d bytes) to compress device", (unsigned int)out, bytes);
if (out->send_new_metadata) {
ALOGD("copl(%x):send new gapless metadata", (unsigned int)out);
@@ -1660,7 +1697,7 @@
{
struct stream_out *out = (struct stream_out *)stream;
*dsp_frames = 0;
- if ((out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) && (dsp_frames != NULL)) {
+ if (is_offload_usecase(out->usecase) && (dsp_frames != NULL)) {
pthread_mutex_lock(&out->lock);
if (out->compr != NULL) {
compress_get_tstamp(out->compr, (unsigned long *)dsp_frames,
@@ -1699,7 +1736,7 @@
pthread_mutex_lock(&out->lock);
- if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
+ if (is_offload_usecase(out->usecase)) {
if (out->compr != NULL) {
compress_get_tstamp(out->compr, &dsp_frames,
&out->sample_rate);
@@ -1753,7 +1790,7 @@
struct stream_out *out = (struct stream_out *)stream;
int status = -ENOSYS;
ALOGV("%s", __func__);
- if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
+ if (is_offload_usecase(out->usecase)) {
ALOGD("copl(%x):pause compress driver", (unsigned int)out);
pthread_mutex_lock(&out->lock);
if (out->compr != NULL && out->offload_state == OFFLOAD_STATE_PLAYING) {
@@ -1770,7 +1807,7 @@
struct stream_out *out = (struct stream_out *)stream;
int status = -ENOSYS;
ALOGV("%s", __func__);
- if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
+ if (is_offload_usecase(out->usecase)) {
ALOGD("copl(%x):resume compress driver", (unsigned int)out);
status = 0;
pthread_mutex_lock(&out->lock);
@@ -1788,7 +1825,7 @@
struct stream_out *out = (struct stream_out *)stream;
int status = -ENOSYS;
ALOGV("%s", __func__);
- if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
+ if (is_offload_usecase(out->usecase)) {
pthread_mutex_lock(&out->lock);
if (type == AUDIO_DRAIN_EARLY_NOTIFY)
status = send_offload_cmd_l(out, OFFLOAD_CMD_PARTIAL_DRAIN);
@@ -1803,7 +1840,7 @@
{
struct stream_out *out = (struct stream_out *)stream;
ALOGV("%s", __func__);
- if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
+ if (is_offload_usecase(out->usecase)) {
ALOGD("copl(%x):calling compress flush", (unsigned int)out);
pthread_mutex_lock(&out->lock);
stop_compressed_output_l(out);
@@ -2166,7 +2203,7 @@
out->compr_config.codec = (struct snd_codec *)
calloc(1, sizeof(struct snd_codec));
- out->usecase = USECASE_AUDIO_PLAYBACK_OFFLOAD;
+ out->usecase = get_offload_usecase(adev);
if (config->offload_info.channel_mask)
out->channel_mask = config->offload_info.channel_mask;
else if (config->channel_mask) {
@@ -2321,9 +2358,9 @@
else
out_standby(&stream->common);
- if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
+ if (is_offload_usecase(out->usecase)) {
destroy_offload_callback_thread(out);
-
+ free_offload_usecase(adev, out->usecase);
if (out->compr_config.codec != NULL)
free(out->compr_config.codec);
}
@@ -2530,6 +2567,8 @@
in = (struct stream_in *)calloc(1, sizeof(struct stream_in));
+ pthread_mutex_init(&in->lock, (const pthread_mutexattr_t *) NULL);
+
in->stream.common.get_sample_rate = in_get_sample_rate;
in->stream.common.set_sample_rate = in_set_sample_rate;
in->stream.common.get_buffer_size = in_get_buffer_size;
@@ -2664,6 +2703,8 @@
adev = calloc(1, sizeof(struct audio_device));
+ pthread_mutex_init(&adev->lock, (const pthread_mutexattr_t *) NULL);
+
adev->device.common.tag = HARDWARE_DEVICE_TAG;
adev->device.common.version = AUDIO_DEVICE_API_VERSION_2_0;
adev->device.common.module = (struct hw_module_t *)module;
@@ -2699,7 +2740,7 @@
voice_init(adev);
list_init(&adev->usecase_list);
adev->cur_wfd_channels = 2;
-
+ adev->offload_usecases_state = 0;
/* Loads platform specific libraries dynamically */
adev->platform = platform_init(adev);
if (!adev->platform) {
diff --git a/hal/audio_hw.h b/hal/audio_hw.h
index 4a32602..3115f1a 100644
--- a/hal/audio_hw.h
+++ b/hal/audio_hw.h
@@ -65,7 +65,17 @@
USECASE_AUDIO_PLAYBACK_LOW_LATENCY,
USECASE_AUDIO_PLAYBACK_MULTI_CH,
USECASE_AUDIO_PLAYBACK_OFFLOAD,
-
+#ifdef MULTIPLE_OFFLOAD_ENABLED
+ USECASE_AUDIO_PLAYBACK_OFFLOAD2,
+ USECASE_AUDIO_PLAYBACK_OFFLOAD3,
+ USECASE_AUDIO_PLAYBACK_OFFLOAD4,
+ USECASE_AUDIO_PLAYBACK_OFFLOAD5,
+ USECASE_AUDIO_PLAYBACK_OFFLOAD6,
+ USECASE_AUDIO_PLAYBACK_OFFLOAD7,
+ USECASE_AUDIO_PLAYBACK_OFFLOAD8,
+ USECASE_AUDIO_PLAYBACK_OFFLOAD9,
+#endif
+
/* FM usecase */
USECASE_AUDIO_PLAYBACK_FM,
@@ -234,7 +244,7 @@
int snd_card;
void *platform;
-
+ unsigned int offload_usecases_state;
void *visualizer_lib;
int (*visualizer_start_output)(audio_io_handle_t, int);
int (*visualizer_stop_output)(audio_io_handle_t, int);
@@ -246,20 +256,20 @@
int select_devices(struct audio_device *adev,
audio_usecase_t uc_id);
int disable_audio_route(struct audio_device *adev,
- struct audio_usecase *usecase,
- bool update_mixer);
+ struct audio_usecase *usecase);
int disable_snd_device(struct audio_device *adev,
- snd_device_t snd_device,
- bool update_mixer);
+ snd_device_t snd_device);
int enable_snd_device(struct audio_device *adev,
- snd_device_t snd_device,
- bool update_mixer);
+ snd_device_t snd_device);
+
int enable_audio_route(struct audio_device *adev,
- struct audio_usecase *usecase,
- bool update_mixer);
+ struct audio_usecase *usecase);
+
struct audio_usecase *get_usecase_from_list(struct audio_device *adev,
audio_usecase_t uc_id);
+bool is_offload_usecase(audio_usecase_t uc_id);
+
#define LITERAL_TO_STRING(x) #x
#define CHECK(condition) LOG_ALWAYS_FATAL_IF(!(condition), "%s",\
__FILE__ ":" LITERAL_TO_STRING(__LINE__)\
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
index c6ba144..4a4e408 100644
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -1634,9 +1634,8 @@
str_parms_del(parms, AUDIO_PARAMETER_KEY_BTSCO);
my_data->btsco_sample_rate = val;
if (val == SAMPLE_RATE_16KHZ) {
- audio_route_apply_path(my_data->adev->audio_route,
+ audio_route_apply_and_update_path(my_data->adev->audio_route,
"bt-sco-wb-samplerate");
- audio_route_update_mixer(my_data->adev->audio_route);
}
}
diff --git a/hal/msm8960/platform.c b/hal/msm8960/platform.c
index ed1a781..70e0b9e 100644
--- a/hal/msm8960/platform.c
+++ b/hal/msm8960/platform.c
@@ -193,20 +193,14 @@
#define DEEP_BUFFER_PLATFORM_DELAY (29*1000LL)
#define LOW_LATENCY_PLATFORM_DELAY (13*1000LL)
-static int set_echo_reference(struct mixer *mixer, const char* ec_ref)
+static void set_echo_reference(struct audio_device *adev, bool enable)
{
- struct mixer_ctl *ctl;
- const char *mixer_ctl_name = "EC_REF_RX";
+ if (enable)
+ audio_route_apply_and_update_path(adev->audio_route, "echo-reference");
+ else
+ audio_route_reset_and_update_path(adev->audio_route, "echo-reference");
- ctl = mixer_get_ctl_by_name(mixer, mixer_ctl_name);
- if (!ctl) {
- ALOGE("%s: Could not get ctl for mixer cmd - %s",
- __func__, mixer_ctl_name);
- return -EINVAL;
- }
- ALOGV("Setting EC Reference: %s", ec_ref);
- mixer_ctl_set_enum_by_string(ctl, ec_ref);
- return 0;
+ ALOGV("Setting EC Reference: %d", enable);
}
void *platform_init(struct audio_device *adev)
@@ -748,9 +742,9 @@
} else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
snd_device = SND_DEVICE_IN_HEADSET_MIC_AEC;
}
- set_echo_reference(adev->mixer, "SLIM_RX");
+ set_echo_reference(adev, true);
} else
- set_echo_reference(adev->mixer, "NONE");
+ set_echo_reference(adev, false);
}
} else if (source == AUDIO_SOURCE_DEFAULT) {
goto exit;
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index 5315e78..923a085 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -50,15 +50,15 @@
#define COMPRESS_OFFLOAD_FRAGMENT_SIZE (32 * 1024)
/* Used in calculating fragment size for pcm offload */
-#define PCM_OFFLOAD_BUFFER_DURATION_FOR_AV 2000 /* 2 secs */
-#define PCM_OFFLOAD_BUFFER_DURATION_FOR_AV_STREAMING 100 /* 100 millisecs */
+#define PCM_OFFLOAD_BUFFER_DURATION_FOR_AV 1000 /* 1 sec */
+#define PCM_OFFLOAD_BUFFER_DURATION_FOR_AV_STREAMING 80 /* 80 millisecs */
/* MAX PCM fragment size cannot be increased further due
* to flinger's cblk size of 1mb,and it has to be a multiple of
* 24 - lcm of channels supported by DSP
*/
#define MAX_PCM_OFFLOAD_FRAGMENT_SIZE (240 * 1024)
-#define MIN_PCM_OFFLOAD_FRAGMENT_SIZE (32 * 1024)
+#define MIN_PCM_OFFLOAD_FRAGMENT_SIZE (4 * 1024)
#define ALIGN( num, to ) (((num) + (to-1)) & (~(to-1)))
/*
@@ -139,6 +139,24 @@
MULTIMEDIA2_PCM_DEVICE},
[USECASE_AUDIO_PLAYBACK_OFFLOAD] =
{PLAYBACK_OFFLOAD_DEVICE, PLAYBACK_OFFLOAD_DEVICE},
+#ifdef MULTIPLE_OFFLOAD_ENABLED
+ [USECASE_AUDIO_PLAYBACK_OFFLOAD2] =
+ {PLAYBACK_OFFLOAD_DEVICE2, PLAYBACK_OFFLOAD_DEVICE2},
+ [USECASE_AUDIO_PLAYBACK_OFFLOAD3] =
+ {PLAYBACK_OFFLOAD_DEVICE3, PLAYBACK_OFFLOAD_DEVICE3},
+ [USECASE_AUDIO_PLAYBACK_OFFLOAD4] =
+ {PLAYBACK_OFFLOAD_DEVICE4, PLAYBACK_OFFLOAD_DEVICE4},
+ [USECASE_AUDIO_PLAYBACK_OFFLOAD5] =
+ {PLAYBACK_OFFLOAD_DEVICE5, PLAYBACK_OFFLOAD_DEVICE5},
+ [USECASE_AUDIO_PLAYBACK_OFFLOAD6] =
+ {PLAYBACK_OFFLOAD_DEVICE6, PLAYBACK_OFFLOAD_DEVICE6},
+ [USECASE_AUDIO_PLAYBACK_OFFLOAD7] =
+ {PLAYBACK_OFFLOAD_DEVICE7, PLAYBACK_OFFLOAD_DEVICE7},
+ [USECASE_AUDIO_PLAYBACK_OFFLOAD8] =
+ {PLAYBACK_OFFLOAD_DEVICE8, PLAYBACK_OFFLOAD_DEVICE8},
+ [USECASE_AUDIO_PLAYBACK_OFFLOAD9] =
+ {PLAYBACK_OFFLOAD_DEVICE9, PLAYBACK_OFFLOAD_DEVICE9},
+#endif
[USECASE_AUDIO_RECORD] = {AUDIO_RECORD_PCM_DEVICE, AUDIO_RECORD_PCM_DEVICE},
[USECASE_AUDIO_RECORD_COMPRESS] = {COMPRESS_CAPTURE_DEVICE, COMPRESS_CAPTURE_DEVICE},
[USECASE_AUDIO_RECORD_LOW_LATENCY] = {LOWLATENCY_PCM_DEVICE,
@@ -418,20 +436,14 @@
#define DEEP_BUFFER_PLATFORM_DELAY (29*1000LL)
#define LOW_LATENCY_PLATFORM_DELAY (13*1000LL)
-static int set_echo_reference(struct mixer *mixer, const char* ec_ref)
+static void set_echo_reference(struct audio_device *adev, bool enable)
{
- struct mixer_ctl *ctl;
- const char *mixer_ctl_name = "EC_REF_RX";
+ if (enable)
+ audio_route_apply_and_update_path(adev->audio_route, "echo-reference");
+ else
+ audio_route_reset_and_update_path(adev->audio_route, "echo-reference");
- ctl = mixer_get_ctl_by_name(mixer, mixer_ctl_name);
- if (!ctl) {
- ALOGE("%s: Could not get ctl for mixer cmd - %s",
- __func__, mixer_ctl_name);
- return -EINVAL;
- }
- ALOGV("Setting EC Reference: %s", ec_ref);
- mixer_ctl_set_enum_by_string(ctl, ec_ref);
- return 0;
+ ALOGV("Setting EC Reference: %d", enable);
}
static struct csd_data *open_csd_client(bool i2s_ext_modem)
@@ -1426,7 +1438,7 @@
} else if (my_data->fluence_type == FLUENCE_NONE ||
my_data->fluence_in_voice_call == false) {
snd_device = SND_DEVICE_IN_HANDSET_MIC;
- set_echo_reference(adev->mixer, EC_REF_RX);
+ set_echo_reference(adev, true);
} else {
snd_device = SND_DEVICE_IN_VOICE_DMIC;
adev->acdb_settings |= DMIC_FLAG;
@@ -1503,7 +1515,7 @@
} else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
snd_device = SND_DEVICE_IN_HEADSET_MIC_FLUENCE;
}
- set_echo_reference(adev->mixer, EC_REF_RX);
+ set_echo_reference(adev, true);
} else if (adev->active_input->enable_aec) {
if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
if (my_data->fluence_type & FLUENCE_DUAL_MIC &&
@@ -1524,7 +1536,7 @@
} else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
snd_device = SND_DEVICE_IN_HEADSET_MIC_FLUENCE;
}
- set_echo_reference(adev->mixer, EC_REF_RX);
+ set_echo_reference(adev, true);
} else if (adev->active_input->enable_ns) {
if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
if (my_data->fluence_type & FLUENCE_DUAL_MIC &&
@@ -1545,9 +1557,9 @@
} else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
snd_device = SND_DEVICE_IN_HEADSET_MIC_FLUENCE;
}
- set_echo_reference(adev->mixer, "NONE");
+ set_echo_reference(adev, false);
} else
- set_echo_reference(adev->mixer, "NONE");
+ set_echo_reference(adev, false);
}
} else if (source == AUDIO_SOURCE_MIC) {
if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC &&
@@ -1555,7 +1567,7 @@
if(my_data->fluence_type & FLUENCE_DUAL_MIC &&
my_data->fluence_in_audio_rec) {
snd_device = SND_DEVICE_IN_HANDSET_DMIC;
- set_echo_reference(adev->mixer, EC_REF_RX);
+ set_echo_reference(adev, true);
}
}
} else if (source == AUDIO_SOURCE_FM_RX ||
@@ -2004,16 +2016,23 @@
} else if (info->has_video && info->is_streaming) {
fragment_size = (PCM_OFFLOAD_BUFFER_DURATION_FOR_AV_STREAMING
* info->sample_rate
- * bits_per_sample
+ * (bits_per_sample >> 3)
* popcount(info->channel_mask))/1000;
} else if (info->has_video) {
fragment_size = (PCM_OFFLOAD_BUFFER_DURATION_FOR_AV
* info->sample_rate
- * bits_per_sample
+ * (bits_per_sample >> 3)
* popcount(info->channel_mask))/1000;
}
+ char value[PROPERTY_VALUE_MAX] = {0};
+ if((property_get("audio.offload.pcm.buffer.size", value, "")) &&
+ atoi(value)) {
+ fragment_size = atoi(value) * 1024;
+ ALOGV("Using buffer size from sys prop %d", fragment_size);
+ }
+
fragment_size = ALIGN( fragment_size, 1024);
if(fragment_size < MIN_PCM_OFFLOAD_FRAGMENT_SIZE)
diff --git a/hal/msm8974/platform.h b/hal/msm8974/platform.h
index f86faf6..ba89c1b 100644
--- a/hal/msm8974/platform.h
+++ b/hal/msm8974/platform.h
@@ -196,6 +196,20 @@
#define SPKR_PROT_CALIB_TX_PCM_DEVICE 25
#endif
#define PLAYBACK_OFFLOAD_DEVICE 9
+
+#ifdef MULTIPLE_OFFLOAD_ENABLED
+#ifdef PLATFORM_APQ8084
+#define PLAYBACK_OFFLOAD_DEVICE2 17
+#define PLAYBACK_OFFLOAD_DEVICE3 18
+#define PLAYBACK_OFFLOAD_DEVICE4 34
+#define PLAYBACK_OFFLOAD_DEVICE5 35
+#define PLAYBACK_OFFLOAD_DEVICE6 36
+#define PLAYBACK_OFFLOAD_DEVICE7 37
+#define PLAYBACK_OFFLOAD_DEVICE8 38
+#define PLAYBACK_OFFLOAD_DEVICE9 39
+#endif
+#endif
+
#define COMPRESS_VOIP_CALL_PCM_DEVICE 3
#ifdef PLATFORM_MSM8610
diff --git a/hal/voice.c b/hal/voice.c
index ac067a3..62d01db 100644
--- a/hal/voice.c
+++ b/hal/voice.c
@@ -88,11 +88,11 @@
}
/* 2. Get and set stream specific mixer controls */
- disable_audio_route(adev, uc_info, true);
+ disable_audio_route(adev, uc_info);
/* 3. Disable the rx and tx devices */
- disable_snd_device(adev, uc_info->out_snd_device, false);
- disable_snd_device(adev, uc_info->in_snd_device, true);
+ disable_snd_device(adev, uc_info->out_snd_device);
+ disable_snd_device(adev, uc_info->in_snd_device);
list_remove(&uc_info->list);
free(uc_info);
diff --git a/hal/voice_extn/compress_voip.c b/hal/voice_extn/compress_voip.c
index 47ac2c8..deb3172 100644
--- a/hal/voice_extn/compress_voip.c
+++ b/hal/voice_extn/compress_voip.c
@@ -305,11 +305,11 @@
}
/* 2. Get and set stream specific mixer controls */
- disable_audio_route(adev, uc_info, true);
+ disable_audio_route(adev, uc_info);
/* 3. Disable the rx and tx devices */
- disable_snd_device(adev, uc_info->out_snd_device, false);
- disable_snd_device(adev, uc_info->in_snd_device, true);
+ disable_snd_device(adev, uc_info->out_snd_device);
+ disable_snd_device(adev, uc_info->in_snd_device);
list_remove(&uc_info->list);
free(uc_info);
diff --git a/hal_mpq/Android.mk b/hal_mpq/Android.mk
deleted file mode 100644
index 1cb7e60..0000000
--- a/hal_mpq/Android.mk
+++ /dev/null
@@ -1,59 +0,0 @@
-ifeq ($(strip $(BOARD_USES_ALSA_AUDIO)),true)
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_ARM_MODE := arm
-
-AUDIO_PLATFORM := $(TARGET_BOARD_PLATFORM)
-
-LOCAL_SRC_FILES := \
- audio_hw.c \
- audio_stream_out.c \
- audio_bitstream_sm.c \
- $(AUDIO_PLATFORM)/hw_info.c \
- $(AUDIO_PLATFORM)/platform.c
-
-ifneq ($(strip $(AUDIO_FEATURE_DISABLED_ANC_HEADSET)),true)
- LOCAL_CFLAGS += -DANC_HEADSET_ENABLED
-endif
-
-ifneq ($(strip $(AUDIO_FEATURE_DISABLED_PROXY_DEVICE)),true)
- LOCAL_CFLAGS += -DAFE_PROXY_ENABLED
-endif
-
-
-ifdef MULTIPLE_HW_VARIANTS_ENABLED
- LOCAL_CFLAGS += -DHW_VARIANTS_ENABLED
- LOCAL_SRC_FILES += $(AUDIO_PLATFORM)/hw_info.c
-endif
-
-LOCAL_SHARED_LIBRARIES := \
- liblog \
- libcutils \
- libtinyalsa \
- libtinycompress \
- libaudioroute \
- libdl
-
-LOCAL_C_INCLUDES := \
- external/tinyalsa/include \
- external/tinycompress/include \
- $(call include-path-for, audio-route) \
- $(call include-path-for, audio-effects) \
- $(LOCAL_PATH)/$(AUDIO_PLATFORM)
-
-
-LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
-LOCAL_ADDITIONAL_DEPENDENCIES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
-
-LOCAL_MODULE := audio.primary.$(TARGET_BOARD_PLATFORM)
-
-LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
-
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_SHARED_LIBRARY)
-
-endif
diff --git a/hal_mpq/audio_bitstream_sm.c b/hal_mpq/audio_bitstream_sm.c
deleted file mode 100644
index d2e4e6e..0000000
--- a/hal_mpq/audio_bitstream_sm.c
+++ /dev/null
@@ -1,485 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
- * Not a Contribution.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <errno.h>
-#include <stdarg.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <dlfcn.h>
-#include <math.h>
-
-#define LOG_TAG "AudioBitstreamStateMachine"
-#define LOG_NDEBUG 0
-#define LOG_NDDEBUG 0
-#include <utils/Log.h>
-
-#include <cutils/properties.h>
-#include "audio_hw.h"
-#include "platform_api.h"
-#include <platform.h>
-// ----------------------------------------------------------------------------
-
-/*
-Initialize all input and output pointers
-Allocate twice the max buffer size of input and output for sufficient buffering
-*/
-int audio_bitstream_init(struct audio_bitstream_sm *bstream, int buffering_factor)
-{
- bstream->buffering_factor = buffering_factor;
- bstream->buffering_factor_cnt = 0;
- bstream->inp_buf_size = SAMPLES_PER_CHANNEL *
- MAX_INPUT_CHANNELS_SUPPORTED*
- (bstream->buffering_factor+1);
- bstream->inp_buf = (char *)malloc( bstream->inp_buf_size);
-
- // multiplied by 2 to convert to bytes
- if(bstream->inp_buf != NULL) {
- bstream->inp_buf_curr_ptr = bstream->inp_buf;
- bstream->inp_buf_write_ptr = bstream->inp_buf;
- } else {
- ALOGE("MS11 input buffer not allocated");
- bstream->inp_buf_size = 0;
- return 0;
- }
-
- bstream->enc_out_buf_size = SAMPLES_PER_CHANNEL * MAX_INPUT_CHANNELS_SUPPORTED*
- FACTOR_FOR_BUFFERING;
- bstream->enc_out_buf =(char *)malloc(bstream->enc_out_buf_size);
-
- if(bstream->enc_out_buf) {
- bstream->enc_out_buf_write_ptr = bstream->enc_out_buf;
- } else {
- ALOGE("MS11 Enc output buffer not allocated");
- bstream->enc_out_buf_size = 0;
- return 0;
- }
- bstream->pcm_2_out_buf_size = SAMPLES_PER_CHANNEL*STEREO_CHANNELS *
- FACTOR_FOR_BUFFERING;
- bstream->pcm_2_out_buf =(char *)malloc(bstream->pcm_2_out_buf_size);
- if(bstream->pcm_2_out_buf) {
- bstream->pcm_2_out_buf_write_ptr = bstream->pcm_2_out_buf;
- } else {
- ALOGE("MS11 PCM2Ch output buffer not allocated");
- bstream->pcm_2_out_buf_size = 0;
- return 0;
- }
- bstream->pcm_mch_out_buf_size = SAMPLES_PER_CHANNEL * MAX_OUTPUT_CHANNELS_SUPPORTED *
- FACTOR_FOR_BUFFERING;
-
- bstream->pcm_mch_out_buf =(char *)malloc(bstream->pcm_mch_out_buf_size);
- if(bstream->pcm_mch_out_buf) {
- bstream->pcm_mch_out_buf_write_ptr = bstream->pcm_mch_out_buf;
- } else {
- ALOGE("MS11 PCMMCh output buffer not allocated");
- bstream->pcm_mch_out_buf_size = 0;
- return 0;
- }
- bstream->passt_out_buf_size =SAMPLES_PER_CHANNEL *
- MAX_INPUT_CHANNELS_SUPPORTED *
- FACTOR_FOR_BUFFERING;
- bstream->passt_out_buf =(char *)malloc(bstream->passt_out_buf_size);
- if(bstream->passt_out_buf) {
- bstream->passt_out_buf_write_ptr = bstream->passt_out_buf;
- } else {
- ALOGE("MS11 Enc output buffer not allocated");
- bstream->passt_out_buf_size = 0;
- return 0;
- }
- return 1;
-}
-
-/*
-Free the allocated memory
-*/
-int audio_bitstream_close(struct audio_bitstream_sm *bstream)
-{
- if(bstream->inp_buf != NULL) {
- free(bstream->inp_buf);
- bstream->inp_buf = NULL;
- }
- if(bstream->enc_out_buf != NULL) {
- free(bstream->enc_out_buf);
- bstream->enc_out_buf = NULL;
- }
- if(bstream->pcm_2_out_buf != NULL) {
- free(bstream->pcm_2_out_buf);
- bstream->pcm_2_out_buf = NULL;
- }
- if(bstream->pcm_mch_out_buf != NULL) {
- free(bstream->pcm_mch_out_buf);
- bstream->pcm_mch_out_buf = NULL;
- }
- if(bstream->passt_out_buf != NULL) {
- free(bstream->passt_out_buf);
- bstream->passt_out_buf = NULL;
- }
- bstream->buffering_factor = 1;
- bstream->buffering_factor_cnt = 0;
- return 0;
-}
-
-/*
-Reset the buffer pointers to start for. This will be help in flush and close
-*/
-void audio_bitstream_reset_ptr( struct audio_bitstream_sm *bstream)
-{
- bstream->inp_buf_curr_ptr = bstream->inp_buf_write_ptr = bstream->inp_buf;
- bstream->enc_out_buf_write_ptr = bstream->enc_out_buf;
- bstream->pcm_2_out_buf_write_ptr = bstream->pcm_2_out_buf;
- bstream->pcm_mch_out_buf_write_ptr = bstream->pcm_mch_out_buf;
- bstream->passt_out_buf_write_ptr = bstream->passt_out_buf;
- bstream->buffering_factor_cnt = 0;
-}
-
-/*
-Reset the output buffer pointers to start for port reconfiguration
-*/
-void audio_bitstream_reset_output_bitstream_ptr(
- struct audio_bitstream_sm *bstream)
-{
- bstream->enc_out_buf_write_ptr = bstream->enc_out_buf;
- bstream->pcm_2_out_buf_write_ptr = bstream->pcm_2_out_buf;
- bstream->pcm_mch_out_buf_write_ptr = bstream->pcm_mch_out_buf;
- bstream->passt_out_buf_write_ptr = bstream->passt_out_buf;
-}
-
-/*
-Copy the bitstream/pcm from Player to internal buffer.
-The incoming bitstream is appended to existing bitstream
-*/
-void audio_bitstream_copy_to_internal_buffer(
- struct audio_bitstream_sm *bstream,
- char *buf_ptr, size_t bytes)
-{
- // flush the input buffer if input is not consumed
- if( (bstream->inp_buf_write_ptr+bytes) > (bstream->inp_buf+bstream->inp_buf_size) ) {
- ALOGE("Input bitstream is not consumed");
- return;
- }
-
- memcpy(bstream->inp_buf_write_ptr, buf_ptr, bytes);
- bstream->inp_buf_write_ptr += bytes;
- if(bstream->buffering_factor_cnt < bstream->buffering_factor)
- bstream->buffering_factor_cnt++;
-}
-
-/*
-Append zeros to the bitstream, so that the entire bitstream in ADIF is pushed
-out for decoding
-*/
-void audio_bitstream_append_silence_internal_buffer(
- struct audio_bitstream_sm *bstream,
- uint32_t bytes, unsigned char value)
-{
- int32_t bufLen = SAMPLES_PER_CHANNEL*MAX_INPUT_CHANNELS_SUPPORTED*
- (bstream->buffering_factor+1);
- uint32_t i = 0;
- if( (bstream->inp_buf_write_ptr+bytes) > (bstream->inp_buf+bufLen) ) {
- bytes = bufLen + bstream->inp_buf - bstream->inp_buf_write_ptr;
- }
- for(i=0; i< bytes; i++)
- *bstream->inp_buf_write_ptr++ = value;
- if(bstream->buffering_factor_cnt < bstream->buffering_factor)
- bstream->buffering_factor_cnt++;
-}
-
-/*
-Flags if sufficient bitstream is available to proceed to decode based on
-the threshold
-*/
-int audio_bitstream_sufficient_buffer_to_decode(
- struct audio_bitstream_sm *bstream,
- int min_bytes_to_decode)
-{
- int proceed_decode = 0;
- if( (bstream->inp_buf_write_ptr -\
- bstream->inp_buf_curr_ptr) > min_bytes_to_decode)
- proceed_decode = 1;
- return proceed_decode;
-}
-
-/*
-Gets the start address of the bitstream buffer. This is used for start of decode
-*/
-char* audio_bitstream_get_input_buffer_ptr(
- struct audio_bitstream_sm *bstream)
-{
- return bstream->inp_buf_curr_ptr;
-}
-
-/*
-Gets the writePtr of the bitstream buffer. This is used for calculating length of
-bitstream
-*/
-char* audio_bitstream_get_input_buffer_write_ptr(
- struct audio_bitstream_sm *bstream)
-{
- return bstream->inp_buf_write_ptr;
-}
-
-int audio_bitstream_set_input_buffer_ptr(
- struct audio_bitstream_sm *bstream, int bytes)
-{
- if(((bstream->inp_buf_curr_ptr + bytes) <=
- (bstream->inp_buf + bstream->inp_buf_size)) &&
- ((bstream->inp_buf_curr_ptr + bytes) >= bstream->inp_buf))
-
- bstream->inp_buf_curr_ptr += bytes;
- else {
- ALOGE("Invalid input buffer size %d bytes", bytes);
- return -EINVAL;
- }
-
- return 0;
-}
-
-int audio_bitstream_set_input_buffer_write_ptr(
- struct audio_bitstream_sm *bstream, int bytes)
-{
- if(((bstream->inp_buf_write_ptr + bytes) <=
- (bstream->inp_buf + bstream->inp_buf_size)) &&
- ((bstream->inp_buf_write_ptr + bytes) >= bstream->inp_buf))
-
- bstream->inp_buf_write_ptr += bytes;
- else {
- ALOGE("Invalid input buffer size %d bytes", bytes);
- return -EINVAL;
- }
-
- return 0;
-}
-
-/*
-Get the output buffer start pointer to start rendering the pcm sampled to driver
-*/
-char* audio_bitstream_get_output_buffer_ptr(
- struct audio_bitstream_sm *bstream,
- int format)
-{
- switch(format) {
- case PCM_MCH_OUT:
- return bstream->pcm_mch_out_buf;
- case PCM_2CH_OUT:
- return bstream->pcm_2_out_buf;
- case COMPRESSED_OUT:
- return bstream->enc_out_buf;
- case TRANSCODE_OUT:
- return bstream->passt_out_buf;
- default:
- return NULL;
- }
-}
-
-/*
-Output the pointer from where the next PCM samples can be copied to buffer
-*/
-char* audio_bitstream_get_output_buffer_write_ptr(
- struct audio_bitstream_sm *bstream,
- int format)
-{
- switch(format) {
- case PCM_MCH_OUT:
- return bstream->pcm_mch_out_buf_write_ptr;
- case PCM_2CH_OUT:
- return bstream->pcm_2_out_buf_write_ptr;
- case COMPRESSED_OUT:
- return bstream->enc_out_buf_write_ptr;
- case TRANSCODE_OUT:
- return bstream->passt_out_buf_write_ptr;
- default:
- return NULL;
- }
-}
-
-/*
-Provides the bitstream size available in the internal buffer
-*/
-size_t audio_bitstream_get_size(struct audio_bitstream_sm *bstream)
-{
- return (bstream->inp_buf_write_ptr-bstream->inp_buf_curr_ptr);
-}
-
-/*
-After decode, the residue bitstream in the buffer is moved to start, so as to
-avoid circularity constraints
-*/
-void audio_bitstream_copy_residue_to_start(
- struct audio_bitstream_sm *bstream,
- size_t bytes_consumed_in_decode)
-{
- size_t remaining_curr_valid_bytes = bstream->inp_buf_write_ptr -
- (bytes_consumed_in_decode+bstream->inp_buf_curr_ptr);
- size_t remainingTotalBytes = bstream->inp_buf_write_ptr -
- (bytes_consumed_in_decode+bstream->inp_buf);
- if(bstream->buffering_factor_cnt == bstream->buffering_factor) {
- memcpy(bstream->inp_buf, bstream->inp_buf+bytes_consumed_in_decode, remainingTotalBytes);
- bstream->inp_buf_write_ptr = bstream->inp_buf+remainingTotalBytes;
- bstream->inp_buf_curr_ptr = bstream->inp_buf_write_ptr-remaining_curr_valid_bytes;
- } else {
- bstream->inp_buf_curr_ptr += bytes_consumed_in_decode;
- }
-}
-
-/*
-Remaing samples less than the one period size required for the pcm driver
-is moved to start of the buffer
-*/
-void audio_bitstream_copy_residue_output_start(
- struct audio_bitstream_sm *bstream,
- int format,
- size_t samplesRendered)
-{
- size_t remaining_bytes;
- switch(format) {
- case PCM_MCH_OUT:
- remaining_bytes = bstream->pcm_mch_out_buf_write_ptr-\
- (bstream->pcm_mch_out_buf+samplesRendered);
- memcpy(bstream->pcm_mch_out_buf,
- bstream->pcm_mch_out_buf+samplesRendered,
- remaining_bytes);
- bstream->pcm_mch_out_buf_write_ptr = \
- bstream->pcm_mch_out_buf + remaining_bytes;
- break;
- case PCM_2CH_OUT:
- remaining_bytes = bstream->pcm_2_out_buf_write_ptr-\
- (bstream->pcm_2_out_buf+samplesRendered);
- memcpy(bstream->pcm_2_out_buf,
- bstream->pcm_2_out_buf+samplesRendered,
- remaining_bytes);
- bstream->pcm_2_out_buf_write_ptr = \
- bstream->pcm_2_out_buf + remaining_bytes;
- break;
- case COMPRESSED_OUT:
- remaining_bytes = bstream->enc_out_buf_write_ptr-\
- (bstream->enc_out_buf+samplesRendered);
- memcpy(bstream->enc_out_buf,
- bstream->enc_out_buf+samplesRendered,
- remaining_bytes);
- bstream->enc_out_buf_write_ptr = \
- bstream->enc_out_buf + remaining_bytes;
- break;
- case TRANSCODE_OUT:
- remaining_bytes = bstream->passt_out_buf_write_ptr-\
- (bstream->passt_out_buf+samplesRendered);
- memcpy(bstream->passt_out_buf,
- bstream->passt_out_buf+samplesRendered,
- remaining_bytes);
- bstream->passt_out_buf_write_ptr = \
- bstream->passt_out_buf + remaining_bytes;
- break;
- default:
- break;
- }
-}
-
-/*
-The write pointer is updated after the incoming PCM samples are copied to the
-output buffer
-*/
-void audio_bitstream_set_output_buffer_write_ptr(
- struct audio_bitstream_sm *bstream,
- int format, size_t output_pcm_sample)
-{
- int alloc_bytes;
- switch(format) {
- case PCM_MCH_OUT:
- alloc_bytes = SAMPLES_PER_CHANNEL*\
- MAX_OUTPUT_CHANNELS_SUPPORTED*FACTOR_FOR_BUFFERING;
- if (bstream->pcm_mch_out_buf + alloc_bytes >\
- bstream->pcm_mch_out_buf_write_ptr + output_pcm_sample)
- bstream->pcm_mch_out_buf_write_ptr += output_pcm_sample;
- break;
- case PCM_2CH_OUT:
- alloc_bytes = SAMPLES_PER_CHANNEL*STEREO_CHANNELS*FACTOR_FOR_BUFFERING;
- if(bstream->pcm_2_out_buf + alloc_bytes > \
- bstream->pcm_2_out_buf_write_ptr + output_pcm_sample)
- bstream->pcm_2_out_buf_write_ptr += output_pcm_sample;
- break;
- case COMPRESSED_OUT:
- alloc_bytes = SAMPLES_PER_CHANNEL*\
- MAX_INPUT_CHANNELS_SUPPORTED*FACTOR_FOR_BUFFERING;
- if (bstream->enc_out_buf + alloc_bytes > \
- bstream->enc_out_buf_write_ptr + output_pcm_sample)
- bstream->enc_out_buf_write_ptr += output_pcm_sample;
- break;
- case TRANSCODE_OUT:
- alloc_bytes = SAMPLES_PER_CHANNEL*\
- MAX_INPUT_CHANNELS_SUPPORTED*FACTOR_FOR_BUFFERING;
- if (bstream->passt_out_buf + alloc_bytes > \
- bstream->passt_out_buf_write_ptr + output_pcm_sample)
- bstream->passt_out_buf_write_ptr += output_pcm_sample;
- break;
- default:
- break;
- }
-}
-
-/*
-Flags if sufficient samples are available to render to PCM driver
-*/
-int audio_bitstream_sufficient_sample_to_render(
- struct audio_bitstream_sm *bstream,
- int format, int mid_size_reqd)
-{
- int status = 0;
- char *buf_ptr = NULL, *buf_write_ptr = NULL;
- switch(format) {
- case PCM_MCH_OUT:
- buf_ptr = bstream->pcm_mch_out_buf;
- buf_write_ptr = bstream->pcm_mch_out_buf_write_ptr;
- break;
- case PCM_2CH_OUT:
- buf_ptr = bstream->pcm_2_out_buf;
- buf_write_ptr = bstream->pcm_2_out_buf_write_ptr;
- break;
- case COMPRESSED_OUT:
- buf_ptr = bstream->enc_out_buf;
- buf_write_ptr = bstream->enc_out_buf_write_ptr;
- break;
- case TRANSCODE_OUT:
- buf_ptr = bstream->passt_out_buf;
- buf_write_ptr = bstream->passt_out_buf_write_ptr;
- break;
- default:
- break;
- }
- if( (buf_write_ptr-buf_ptr) >= mid_size_reqd )
- status = 1;
- return status;
-}
-
-void audio_bitstream_start_input_buffering_mode(
- struct audio_bitstream_sm *bstream)
-{
- bstream->buffering_factor_cnt = 0;
-}
-
-void audio_bitstream_stop_input_buffering_mode(
- struct audio_bitstream_sm *bstream)
-{
- size_t remaining_curr_valid_bytes = \
- bstream->inp_buf_write_ptr - bstream->inp_buf_curr_ptr;
- bstream->buffering_factor_cnt = bstream->buffering_factor;
- memcpy(bstream->inp_buf,
- bstream->inp_buf_curr_ptr,
- remaining_curr_valid_bytes);
- bstream->inp_buf_curr_ptr = bstream->inp_buf;
- bstream->inp_buf_write_ptr = bstream->inp_buf + remaining_curr_valid_bytes;
-}
diff --git a/hal_mpq/audio_bitstream_sm.h b/hal_mpq/audio_bitstream_sm.h
deleted file mode 100644
index db03bf5..0000000
--- a/hal_mpq/audio_bitstream_sm.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
- * Not a Contribution.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef QCOM_AUDIO_BITSTRM_SM_H
-#define QCOM_AUDIO_BITSTRM_SM_H
-int audio_bitstream_init(struct audio_bitstream_sm *bstream, int buffering_factor);
-int audio_bitstream_close(struct audio_bitstream_sm *bstream);
-int audio_bitstream_with_buffering_factor(struct audio_bitstream_sm *bstream,
- int in_buffering_factor);
-void audio_bitstream_reset_ptr( struct audio_bitstream_sm *bstream);
-void audio_bitstream_reset_output_bitstream_ptr(
- struct audio_bitstream_sm *bstream);
-void audio_bitstream_copy_to_internal_buffer(
- struct audio_bitstream_sm *bstream,
- char *buf_ptr, size_t bytes);
-void audio_bitstream_append_silence_internal_buffer(
- struct audio_bitstream_sm *bstream,
- uint32_t bytes, unsigned char value);
-int audio_bitstream_sufficient_buffer_to_decode(
- struct audio_bitstream_sm *bstream,
- int min_bytes_to_decode);
-char* audio_bitstream_get_input_buffer_ptr(
- struct audio_bitstream_sm *bstream);
-char* audio_bitstream_get_input_buffer_write_ptr(
- struct audio_bitstream_sm *bstream);
-char* audio_bitstream_get_output_buffer_ptr(
- struct audio_bitstream_sm *bstream,
- int format);
-char* audio_bitstream_get_output_buffer_write_ptr(
- struct audio_bitstream_sm *bstream,
- int format);
-size_t audio_bitstream_get_size(struct audio_bitstream_sm *bstream);
-void audio_bitstream_copy_residue_to_start(
- struct audio_bitstream_sm *bstream,
- size_t bytes_consumed_in_decode);
-void audio_bitstream_copy_residue_output_start(
- struct audio_bitstream_sm *bstream,
- int format,
- size_t samplesRendered);
-void audio_bitstream_set_output_buffer_write_ptr(
- struct audio_bitstream_sm *bstream,
- int format, size_t output_pcm_sample);
-int audio_bitstream_sufficient_sample_to_render(
- struct audio_bitstream_sm *bstream,
- int format, int mid_size_reqd);
-void audio_bitstream_start_input_buffering_mode(
- struct audio_bitstream_sm *bstream);
-void audio_bitstream_stop_input_buffering_mode(
- struct audio_bitstream_sm *bstream);
-#endif
diff --git a/hal_mpq/audio_hw.c b/hal_mpq/audio_hw.c
deleted file mode 100644
index fb83245..0000000
--- a/hal_mpq/audio_hw.c
+++ /dev/null
@@ -1,1240 +0,0 @@
-/*
- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
- * Not a Contribution.
- *
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "audio_hw_primary"
-/*#define LOG_NDEBUG 0*/
-/*#define VERY_VERY_VERBOSE_LOGGING*/
-#ifdef VERY_VERY_VERBOSE_LOGGING
-#define ALOGVV ALOGV
-#else
-#define ALOGVV(a...) do { } while(0)
-#endif
-
-#include <errno.h>
-#include <pthread.h>
-#include <stdint.h>
-#include <sys/time.h>
-#include <stdlib.h>
-#include <math.h>
-#include <dlfcn.h>
-#include <sys/resource.h>
-#include <sys/prctl.h>
-
-#include <cutils/log.h>
-#include <cutils/str_parms.h>
-#include <cutils/properties.h>
-#include <cutils/atomic.h>
-
-#include <hardware/audio_effect.h>
-#include <audio_effects/effect_aec.h>
-#include <audio_effects/effect_ns.h>
-#include "audio_hw.h"
-#include "platform_api.h"
-#include <platform.h>
-
-struct pcm_config pcm_config_audio_capture = {
- .channels = 2,
- .period_count = AUDIO_CAPTURE_PERIOD_COUNT,
- .format = PCM_FORMAT_S16_LE,
-};
-
-static struct audio_device *adev = NULL;
-static pthread_mutex_t adev_init_lock;
-static unsigned int audio_device_ref_count;
-
-static int set_voice_volume_l(struct audio_device *adev, float volume);
-
-int enable_audio_route(struct audio_device *adev,
- struct audio_usecase *usecase,
- bool update_mixer)
-{
- snd_device_t snd_device;
- char mixer_path[MIXER_PATH_MAX_LENGTH];
-
- if (usecase == NULL)
- return -EINVAL;
-
- ALOGV("%s: enter: usecase(%d)", __func__, usecase->id);
-
- if (usecase->type == PCM_CAPTURE)
- snd_device = usecase->in_snd_device;
- else
- snd_device = usecase->out_snd_device;
-
- strlcpy(mixer_path, use_case_table[usecase->id], sizeof(mixer_path));
- platform_add_backend_name(mixer_path, snd_device);
- ALOGV("%s: apply mixer path: %s", __func__, mixer_path);
- audio_route_apply_path(adev->audio_route, mixer_path);
- if (update_mixer)
- audio_route_update_mixer(adev->audio_route);
-
- ALOGV("%s: exit", __func__);
- return 0;
-}
-
-int disable_audio_route(struct audio_device *adev,
- struct audio_usecase *usecase,
- bool update_mixer)
-{
- snd_device_t snd_device;
- char mixer_path[MIXER_PATH_MAX_LENGTH];
-
- if (usecase == NULL)
- return -EINVAL;
-
- ALOGV("%s: enter: usecase(%d)", __func__, usecase->id);
- if (usecase->type == PCM_CAPTURE)
- snd_device = usecase->in_snd_device;
- else
- snd_device = usecase->out_snd_device;
- strlcpy(mixer_path, use_case_table[usecase->id], sizeof(mixer_path));
- platform_add_backend_name(mixer_path, snd_device);
- ALOGV("%s: reset mixer path: %s", __func__, mixer_path);
- audio_route_reset_path(adev->audio_route, mixer_path);
- if (update_mixer)
- audio_route_update_mixer(adev->audio_route);
-
- ALOGV("%s: exit", __func__);
- return 0;
-}
-
-int enable_snd_device(struct audio_device *adev,
- snd_device_t snd_device,
- bool update_mixer)
-{
- char device_name[DEVICE_NAME_MAX_SIZE] = {0};
-
- if (snd_device < SND_DEVICE_MIN ||
- snd_device >= SND_DEVICE_MAX) {
- ALOGE("%s: Invalid sound device %d", __func__, snd_device);
- return -EINVAL;
- }
-
- adev->snd_dev_ref_cnt[snd_device]++;
-
- if(platform_get_snd_device_name_extn(adev->platform, snd_device, device_name) < 0 ) {
- ALOGE("%s: Invalid sound device returned", __func__);
- return -EINVAL;
- }
- if (adev->snd_dev_ref_cnt[snd_device] > 1) {
- ALOGV("%s: snd_device(%d: %s) is already active",
- __func__, snd_device, device_name);
- return 0;
- }
-
- {
- ALOGV("%s: snd_device(%d: %s)", __func__,
- snd_device, device_name);
- if (platform_send_audio_calibration(adev->platform, snd_device) < 0) {
- adev->snd_dev_ref_cnt[snd_device]--;
- return -EINVAL;
- }
- audio_route_apply_path(adev->audio_route, device_name);
- }
- if (update_mixer)
- audio_route_update_mixer(adev->audio_route);
-
- return 0;
-}
-
-int disable_snd_device(struct audio_device *adev,
- snd_device_t snd_device,
- bool update_mixer)
-{
- char device_name[DEVICE_NAME_MAX_SIZE] = {0};
-
- if (snd_device < SND_DEVICE_MIN ||
- snd_device >= SND_DEVICE_MAX) {
- ALOGE("%s: Invalid sound device %d", __func__, snd_device);
- return -EINVAL;
- }
- if (adev->snd_dev_ref_cnt[snd_device] <= 0) {
- ALOGE("%s: device ref cnt is already 0", __func__);
- return -EINVAL;
- }
-
- adev->snd_dev_ref_cnt[snd_device]--;
-
- if(platform_get_snd_device_name_extn(adev->platform, snd_device, device_name) < 0) {
- ALOGE("%s: Invalid sound device returned", __func__);
- return -EINVAL;
- }
-
- if (adev->snd_dev_ref_cnt[snd_device] == 0) {
- ALOGV("%s: snd_device(%d: %s)", __func__,
- snd_device, device_name);
- audio_route_reset_path(adev->audio_route, device_name);
-
- if (update_mixer)
- audio_route_update_mixer(adev->audio_route);
- }
-
- return 0;
-}
-
-static void check_usecases_codec_backend(struct audio_device *adev,
- struct audio_usecase *uc_info,
- snd_device_t snd_device)
-{
- struct listnode *node;
- struct audio_usecase *usecase;
- bool switch_device[AUDIO_USECASE_MAX];
- int i, num_uc_to_switch = 0;
-
- /*
- * This function is to make sure that all the usecases that are active on
- * the hardware codec backend are always routed to any one device that is
- * handled by the hardware codec.
- * For example, if low-latency and deep-buffer usecases are currently active
- * on speaker and out_set_parameters(headset) is received on low-latency
- * output, then we have to make sure deep-buffer is also switched to headset,
- * because of the limitation that both the devices cannot be enabled
- * at the same time as they share the same backend.
- */
- /* Disable all the usecases on the shared backend other than the
- specified usecase */
- for (i = 0; i < AUDIO_USECASE_MAX; i++)
- switch_device[i] = false;
-
- list_for_each(node, &adev->usecase_list) {
- usecase = node_to_item(node, struct audio_usecase, list);
- if (usecase->type == PCM_PLAYBACK &&
- usecase != uc_info &&
- usecase->out_snd_device != snd_device &&
- usecase->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND) {
- ALOGV("%s: Usecase (%s) is active on (%s) - disabling ..",
- __func__, use_case_table[usecase->id],
- platform_get_snd_device_name(usecase->out_snd_device));
- disable_audio_route(adev, usecase, false);
- switch_device[usecase->id] = true;
- num_uc_to_switch++;
- }
- }
-
- if (num_uc_to_switch) {
- /* Make sure all the streams are de-routed before disabling the device */
- audio_route_update_mixer(adev->audio_route);
-
- list_for_each(node, &adev->usecase_list) {
- usecase = node_to_item(node, struct audio_usecase, list);
- if (switch_device[usecase->id]) {
- disable_snd_device(adev, usecase->out_snd_device, false);
- }
- }
-
- list_for_each(node, &adev->usecase_list) {
- usecase = node_to_item(node, struct audio_usecase, list);
- if (switch_device[usecase->id]) {
- enable_snd_device(adev, snd_device, false);
- }
- }
- /* Make sure new snd device is enabled before re-routing the streams */
- audio_route_update_mixer(adev->audio_route);
-
- /* Re-route all the usecases on the shared backend other than the
- specified usecase to new snd devices */
- list_for_each(node, &adev->usecase_list) {
- usecase = node_to_item(node, struct audio_usecase, list);
- /* Update the out_snd_device only before enabling the audio route */
- if (switch_device[usecase->id] ) {
- usecase->out_snd_device = snd_device;
- enable_audio_route(adev, usecase, false);
- }
- }
-
- audio_route_update_mixer(adev->audio_route);
- }
-}
-
-static void check_and_route_capture_usecases(struct audio_device *adev,
- struct audio_usecase *uc_info,
- snd_device_t snd_device)
-{
- struct listnode *node;
- struct audio_usecase *usecase;
- bool switch_device[AUDIO_USECASE_MAX];
- int i, num_uc_to_switch = 0;
-
- /*
- * This function is to make sure that all the active capture usecases
- * are always routed to the same input sound device.
- * For example, if audio-record and voice-call usecases are currently
- * active on speaker(rx) and speaker-mic (tx) and out_set_parameters(earpiece)
- * is received for voice call then we have to make sure that audio-record
- * usecase is also switched to earpiece i.e. voice-dmic-ef,
- * because of the limitation that two devices cannot be enabled
- * at the same time if they share the same backend.
- */
- for (i = 0; i < AUDIO_USECASE_MAX; i++)
- switch_device[i] = false;
-
- list_for_each(node, &adev->usecase_list) {
- usecase = node_to_item(node, struct audio_usecase, list);
- if (usecase->type == PCM_CAPTURE &&
- usecase != uc_info &&
- usecase->in_snd_device != snd_device) {
- ALOGV("%s: Usecase (%s) is active on (%s) - disabling ..",
- __func__, use_case_table[usecase->id],
- platform_get_snd_device_name(usecase->in_snd_device));
- disable_audio_route(adev, usecase, false);
- switch_device[usecase->id] = true;
- num_uc_to_switch++;
- }
- }
-
- if (num_uc_to_switch) {
- /* Make sure all the streams are de-routed before disabling the device */
- audio_route_update_mixer(adev->audio_route);
-
- list_for_each(node, &adev->usecase_list) {
- usecase = node_to_item(node, struct audio_usecase, list);
- if (switch_device[usecase->id]) {
- disable_snd_device(adev, usecase->in_snd_device, false);
- enable_snd_device(adev, snd_device, false);
- }
- }
-
- /* Make sure new snd device is enabled before re-routing the streams */
- audio_route_update_mixer(adev->audio_route);
-
- /* Re-route all the usecases on the shared backend other than the
- specified usecase to new snd devices */
- list_for_each(node, &adev->usecase_list) {
- usecase = node_to_item(node, struct audio_usecase, list);
- /* Update the in_snd_device only before enabling the audio route */
- if (switch_device[usecase->id] ) {
- usecase->in_snd_device = snd_device;
- enable_audio_route(adev, usecase, false);
- }
- }
-
- audio_route_update_mixer(adev->audio_route);
- }
-}
-
-static int disable_all_usecases_of_type(struct audio_device *adev,
- usecase_type_t usecase_type,
- bool update_mixer)
-{
- struct audio_usecase *usecase;
- struct listnode *node;
- int ret = 0;
-
- list_for_each(node, &adev->usecase_list) {
- usecase = node_to_item(node, struct audio_usecase, list);
- if (usecase->type == usecase_type) {
- ALOGV("%s: usecase id %d", __func__, usecase->id);
- ret = disable_audio_route(adev, usecase, update_mixer);
- if (ret) {
- ALOGE("%s: Failed to disable usecase id %d",
- __func__, usecase->id);
- }
- }
- }
-
- return ret;
-}
-
-static int enable_all_usecases_of_type(struct audio_device *adev,
- usecase_type_t usecase_type,
- bool update_mixer)
-{
- struct audio_usecase *usecase;
- struct listnode *node;
- int ret = 0;
-
- list_for_each(node, &adev->usecase_list) {
- usecase = node_to_item(node, struct audio_usecase, list);
- if (usecase->type == usecase_type) {
- ALOGV("%s: usecase id %d", __func__, usecase->id);
- ret = enable_audio_route(adev, usecase, update_mixer);
- if (ret) {
- ALOGE("%s: Failed to enable usecase id %d",
- __func__, usecase->id);
- }
- }
- }
-
- return ret;
-}
-
-static audio_usecase_t get_voice_usecase_id_from_list(struct audio_device *adev)
-{
- struct audio_usecase *usecase;
- struct listnode *node;
-
- list_for_each(node, &adev->usecase_list) {
- usecase = node_to_item(node, struct audio_usecase, list);
- if (usecase->type == VOICE_CALL) {
- ALOGV("%s: usecase id %d", __func__, usecase->id);
- return usecase->id;
- }
- }
- return USECASE_INVALID;
-}
-
-struct audio_usecase *get_usecase_from_list(struct audio_device *adev,
- audio_usecase_t uc_id)
-{
- struct audio_usecase *usecase;
- struct listnode *node;
-
- list_for_each(node, &adev->usecase_list) {
- usecase = node_to_item(node, struct audio_usecase, list);
- if (usecase->id == uc_id)
- return usecase;
- }
- return NULL;
-}
-
-int select_devices(struct audio_device *adev, audio_usecase_t uc_id)
-{
- snd_device_t out_snd_device = SND_DEVICE_NONE;
- snd_device_t in_snd_device = SND_DEVICE_NONE;
- struct audio_usecase *usecase = NULL;
- struct audio_usecase *vc_usecase = NULL;
- struct audio_usecase *voip_usecase = NULL;
- struct listnode *node;
- int status = 0;
-
- usecase = get_usecase_from_list(adev, uc_id);
- if (usecase == NULL) {
- ALOGE("%s: Could not find the usecase(%d)", __func__, uc_id);
- return -EINVAL;
- }
-
- if ((usecase->type == VOICE_CALL) ||
- (usecase->type == VOIP_CALL)) {
- out_snd_device = platform_get_output_snd_device(adev->platform,
- usecase->stream.out->devices);
- in_snd_device = platform_get_input_snd_device(adev->platform, usecase->stream.out->devices);
- usecase->devices = usecase->stream.out->devices;
- } else {
- /*
- * If the voice call is active, use the sound devices of voice call usecase
- * so that it would not result any device switch. All the usecases will
- * be switched to new device when select_devices() is called for voice call
- * usecase. This is to avoid switching devices for voice call when
- * check_usecases_codec_backend() is called below.
- */
- if (usecase->type == PCM_PLAYBACK) {
- usecase->devices = usecase->stream.out->devices;
- in_snd_device = SND_DEVICE_NONE;
- if (out_snd_device == SND_DEVICE_NONE) {
- out_snd_device = platform_get_output_snd_device(adev->platform,
- usecase->stream.out->devices);
- if (usecase->stream.out == adev->primary_output &&
- adev->active_input &&
- adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION) {
- select_devices(adev, adev->active_input->usecase);
- }
- }
- } else if (usecase->type == PCM_CAPTURE) {
- usecase->devices = usecase->stream.in->device;
- out_snd_device = SND_DEVICE_NONE;
- if (in_snd_device == SND_DEVICE_NONE) {
- if (adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION &&
- 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);
- }
- }
- }
- }
-
- if (out_snd_device == usecase->out_snd_device &&
- in_snd_device == usecase->in_snd_device) {
- return 0;
- }
-
- ALOGD("%s: out_snd_device(%d: %s) in_snd_device(%d: %s)", __func__,
- out_snd_device, platform_get_snd_device_name(out_snd_device),
- in_snd_device, platform_get_snd_device_name(in_snd_device));
-
- /*
- * Limitation: While in call, to do a device switch we need to disable
- * and enable both RX and TX devices though one of them is same as current
- * device.
- */
- if (usecase->type == VOICE_CALL || usecase->type == VOIP_CALL) {
- status = platform_switch_voice_call_device_pre(adev->platform);
- disable_all_usecases_of_type(adev, VOICE_CALL, true);
- }
-
- /* Disable current sound devices */
- if (usecase->out_snd_device != SND_DEVICE_NONE) {
- disable_audio_route(adev, usecase, true);
- disable_snd_device(adev, usecase->out_snd_device, false);
- }
-
- if (usecase->in_snd_device != SND_DEVICE_NONE) {
- disable_audio_route(adev, usecase, true);
- disable_snd_device(adev, usecase->in_snd_device, false);
- }
-
- /* Enable new sound devices */
- if (out_snd_device != SND_DEVICE_NONE) {
- if (usecase->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND)
- check_usecases_codec_backend(adev, usecase, out_snd_device);
- enable_snd_device(adev, out_snd_device, false);
- }
-
- if (in_snd_device != SND_DEVICE_NONE) {
- check_and_route_capture_usecases(adev, usecase, in_snd_device);
- enable_snd_device(adev, in_snd_device, false);
- }
-
- if (usecase->type == VOICE_CALL || usecase->type == VOIP_CALL)
- status = platform_switch_voice_call_device_post(adev->platform,
- out_snd_device,
- in_snd_device);
-
- audio_route_update_mixer(adev->audio_route);
-
- usecase->in_snd_device = in_snd_device;
- usecase->out_snd_device = out_snd_device;
-
- if (usecase->type == VOICE_CALL || usecase->type == VOIP_CALL)
- enable_all_usecases_of_type(adev, usecase->type, true);
- else
- enable_audio_route(adev, usecase, true);
-
- /* Applicable only on the targets that has external modem.
- * Enable device command should be sent to modem only after
- * enabling voice call mixer controls
- */
- if (usecase->type == VOICE_CALL)
- status = platform_switch_voice_call_usecase_route_post(adev->platform,
- out_snd_device,
- in_snd_device);
-
- return status;
-}
-
-static int stop_input_stream(struct stream_in *in)
-{
- int i, ret = 0;
- struct audio_usecase *uc_info;
- struct audio_device *adev = in->dev;
-
- adev->active_input = NULL;
-
- ALOGV("%s: enter: usecase(%d: %s)", __func__,
- in->usecase, use_case_table[in->usecase]);
- uc_info = get_usecase_from_list(adev, in->usecase);
- if (uc_info == NULL) {
- ALOGE("%s: Could not find the usecase (%d) in the list",
- __func__, in->usecase);
- return -EINVAL;
- }
-
- /* 1. Disable stream specific mixer controls */
- disable_audio_route(adev, uc_info, true);
-
- /* 2. Disable the tx device */
- disable_snd_device(adev, uc_info->in_snd_device, true);
-
- list_remove(&uc_info->list);
- free(uc_info);
-
- ALOGV("%s: exit: status(%d)", __func__, ret);
- return ret;
-}
-
-int start_input_stream(struct stream_in *in)
-{
- /* 1. Enable output device and stream routing controls */
- int ret = 0;
- struct audio_usecase *uc_info;
- struct audio_device *adev = in->dev;
-
- in->usecase = platform_update_usecase_from_source(in->source,in->usecase);
- ALOGV("%s: enter: usecase(%d)", __func__, in->usecase);
-
- in->pcm_device_id = platform_get_pcm_device_id(in->usecase, PCM_CAPTURE);
- if (in->pcm_device_id < 0) {
- ALOGE("%s: Could not find PCM device id for the usecase(%d)",
- __func__, in->usecase);
- ret = -EINVAL;
- goto error_config;
- }
-
- adev->active_input = in;
- uc_info = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase));
- uc_info->id = in->usecase;
- uc_info->type = PCM_CAPTURE;
- uc_info->stream.in = in;
- uc_info->devices = in->device;
- uc_info->in_snd_device = SND_DEVICE_NONE;
- uc_info->out_snd_device = SND_DEVICE_NONE;
-
- list_add_tail(&adev->usecase_list, &uc_info->list);
- select_devices(adev, in->usecase);
-
- ALOGV("%s: Opening PCM device card_id(%d) device_id(%d), channels %d",
- __func__, SOUND_CARD, in->pcm_device_id, in->config.channels);
- in->pcm = pcm_open(SOUND_CARD, in->pcm_device_id,
- PCM_IN, &in->config);
- if (in->pcm && !pcm_is_ready(in->pcm)) {
- ALOGE("%s: %s", __func__, pcm_get_error(in->pcm));
- pcm_close(in->pcm);
- in->pcm = NULL;
- ret = -EIO;
- goto error_open;
- }
- ALOGV("%s: exit", __func__);
- return ret;
-
-error_open:
- stop_input_stream(in);
-
-error_config:
- adev->active_input = NULL;
- ALOGD("%s: exit: status(%d)", __func__, ret);
-
- return ret;
-}
-
-static int check_input_parameters(uint32_t sample_rate,
- audio_format_t format,
- int channel_count)
-{
- int ret = 0;
-
- if ((format != AUDIO_FORMAT_PCM_16_BIT)) ret = -EINVAL;
-
- switch (channel_count) {
- case 1:
- case 2:
- case 6:
- break;
- default:
- ret = -EINVAL;
- }
-
- switch (sample_rate) {
- case 8000:
- case 11025:
- case 12000:
- case 16000:
- case 22050:
- case 24000:
- case 32000:
- case 44100:
- case 48000:
- break;
- default:
- ret = -EINVAL;
- }
-
- return ret;
-}
-
-static size_t get_input_buffer_size(uint32_t sample_rate,
- audio_format_t format,
- int channel_count)
-{
- size_t size = 0;
-
- if (check_input_parameters(sample_rate, format, channel_count) != 0)
- return 0;
-
- size = (sample_rate * AUDIO_CAPTURE_PERIOD_DURATION_MSEC) / 1000;
- /* ToDo: should use frame_size computed based on the format and
- channel_count here. */
- size *= sizeof(short) * channel_count;
-
- /* make sure the size is multiple of 64 */
- size += 0x3f;
- size &= ~0x3f;
-
- return size;
-}
-
-/** audio_stream_in implementation **/
-static uint32_t in_get_sample_rate(const struct audio_stream *stream)
-{
- struct stream_in *in = (struct stream_in *)stream;
-
- return in->config.rate;
-}
-
-static int in_set_sample_rate(struct audio_stream *stream, uint32_t rate)
-{
- return -ENOSYS;
-}
-
-static size_t in_get_buffer_size(const struct audio_stream *stream)
-{
- struct stream_in *in = (struct stream_in *)stream;
-
- return in->config.period_size * audio_stream_frame_size(stream);
-}
-
-static uint32_t in_get_channels(const struct audio_stream *stream)
-{
- struct stream_in *in = (struct stream_in *)stream;
-
- return in->channel_mask;
-}
-
-static audio_format_t in_get_format(const struct audio_stream *stream)
-{
- struct stream_in *in = (struct stream_in *)stream;
-
- return in->format;
-}
-
-static int in_set_format(struct audio_stream *stream, audio_format_t format)
-{
- return -ENOSYS;
-}
-
-static int in_standby(struct audio_stream *stream)
-{
- struct stream_in *in = (struct stream_in *)stream;
- struct audio_device *adev = in->dev;
- int status = 0;
- ALOGV("%s: enter", __func__);
-
- if (in->usecase == USECASE_COMPRESS_VOIP_CALL) {
- /* Ignore standby in case of voip call because the voip input
- * stream is closed in adev_close_input_stream()
- */
- ALOGV("%s: Ignore Standby in VOIP call", __func__);
- return status;
- }
-
- pthread_mutex_lock(&in->lock);
- if (!in->standby) {
- in->standby = true;
- if (in->pcm) {
- pcm_close(in->pcm);
- in->pcm = NULL;
- }
- pthread_mutex_lock(&adev->lock);
- status = stop_input_stream(in);
- pthread_mutex_unlock(&adev->lock);
- }
- pthread_mutex_unlock(&in->lock);
- ALOGV("%s: exit: status(%d)", __func__, status);
- return status;
-}
-
-static int in_dump(const struct audio_stream *stream, int fd)
-{
- return 0;
-}
-
-static int in_set_parameters(struct audio_stream *stream, const char *kvpairs)
-{
- struct stream_in *in = (struct stream_in *)stream;
- struct audio_device *adev = in->dev;
- struct str_parms *parms;
- char *str;
- char value[32];
- int ret, val = 0;
-
- ALOGV("%s: enter: kvpairs=%s", __func__, kvpairs);
- parms = str_parms_create_str(kvpairs);
-
- ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_INPUT_SOURCE, value, sizeof(value));
-
- pthread_mutex_lock(&in->lock);
- pthread_mutex_lock(&adev->lock);
- if (ret >= 0) {
- val = atoi(value);
- /* no audio source uses val == 0 */
- if ((in->source != val) && (val != 0)) {
- in->source = val;
- }
- }
-
- ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value));
- if (ret >= 0) {
- val = atoi(value);
- if ((in->device != val) && (val != 0)) {
- in->device = val;
- /* If recording is in progress, change the tx device to new device */
- if (!in->standby)
- ret = select_devices(adev, in->usecase);
- }
- }
-
- pthread_mutex_unlock(&adev->lock);
- pthread_mutex_unlock(&in->lock);
-
- str_parms_destroy(parms);
- ALOGV("%s: exit: status(%d)", __func__, ret);
- return ret;
-}
-
-static char* in_get_parameters(const struct audio_stream *stream,
- const char *keys)
-{
- struct stream_in *in = (struct stream_in *)stream;
- struct str_parms *query = str_parms_create_str(keys);
- char *str;
- char value[256];
- struct str_parms *reply = str_parms_create();
- ALOGV("%s: enter: keys - %s", __func__, keys);
-
- str = str_parms_to_str(reply);
- str_parms_destroy(query);
- str_parms_destroy(reply);
-
- ALOGV("%s: exit: returns - %s", __func__, str);
- return str;
-}
-
-static int in_set_gain(struct audio_stream_in *stream, float gain)
-{
- return 0;
-}
-
-static ssize_t in_read(struct audio_stream_in *stream, void *buffer,
- size_t bytes)
-{
- struct stream_in *in = (struct stream_in *)stream;
- struct audio_device *adev = in->dev;
- int i, ret = -1;
-
- pthread_mutex_lock(&in->lock);
- if (in->standby) {
- pthread_mutex_lock(&adev->lock);
- ret = start_input_stream(in);
- pthread_mutex_unlock(&adev->lock);
- if (ret != 0) {
- goto exit;
- }
- in->standby = 0;
- }
-
- if (in->pcm) {
- ret = pcm_read(in->pcm, buffer, bytes);
- }
-
-exit:
- pthread_mutex_unlock(&in->lock);
-
- if (ret != 0) {
- in_standby(&in->stream.common);
- ALOGV("%s: read failed - sleeping for buffer duration", __func__);
- usleep(bytes * 1000000 / audio_stream_frame_size(&in->stream.common) /
- in_get_sample_rate(&in->stream.common));
- }
- return bytes;
-}
-
-static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream)
-{
- return 0;
-}
-
-static int add_remove_audio_effect(const struct audio_stream *stream,
- effect_handle_t effect,
- bool enable)
-{
- struct stream_in *in = (struct stream_in *)stream;
- int status = 0;
-
- return 0;
-}
-
-static int in_add_audio_effect(const struct audio_stream *stream,
- effect_handle_t effect)
-{
- ALOGV("%s: effect %p", __func__, effect);
- return add_remove_audio_effect(stream, effect, true);
-}
-
-static int in_remove_audio_effect(const struct audio_stream *stream,
- effect_handle_t effect)
-{
- ALOGV("%s: effect %p", __func__, effect);
- return add_remove_audio_effect(stream, effect, false);
-}
-
-static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
-{
- struct audio_device *adev = (struct audio_device *)dev;
- struct str_parms *parms;
- char *str;
- char value[32];
- int val;
- int ret;
-
- ALOGD("%s: enter: %s", __func__, kvpairs);
-
- pthread_mutex_lock(&adev->lock);
- parms = str_parms_create_str(kvpairs);
-
- platform_set_parameters(adev->platform, parms);
-
- ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_BT_NREC, value, sizeof(value));
- if (ret >= 0) {
- /* When set to false, HAL should disable EC and NS
- * But it is currently not supported.
- */
- if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0)
- adev->bluetooth_nrec = true;
- else
- adev->bluetooth_nrec = false;
- }
-
- ret = str_parms_get_str(parms, "screen_state", value, sizeof(value));
- if (ret >= 0) {
- if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0)
- adev->screen_off = false;
- else
- adev->screen_off = true;
- }
-
- ret = str_parms_get_int(parms, "rotation", &val);
- if (ret >= 0) {
- bool reverse_speakers = false;
- switch(val) {
- // FIXME: note that the code below assumes that the speakers are in the correct placement
- // relative to the user when the device is rotated 90deg from its default rotation. This
- // assumption is device-specific, not platform-specific like this code.
- case 270:
- reverse_speakers = true;
- break;
- case 0:
- case 90:
- case 180:
- break;
- default:
- ALOGE("%s: unexpected rotation of %d", __func__, val);
- }
- if (adev->speaker_lr_swap != reverse_speakers) {
- adev->speaker_lr_swap = reverse_speakers;
- // only update the selected device if there is active pcm playback
- struct audio_usecase *usecase;
- struct listnode *node;
- list_for_each(node, &adev->usecase_list) {
- usecase = node_to_item(node, struct audio_usecase, list);
- if (usecase->type == PCM_PLAYBACK) {
- select_devices(adev, usecase->id);
- break;
- }
- }
- }
- }
-
- str_parms_destroy(parms);
-
- pthread_mutex_unlock(&adev->lock);
- ALOGV("%s: exit with code(%d)", __func__, ret);
- return ret;
-}
-
-static char* adev_get_parameters(const struct audio_hw_device *dev,
- const char *keys)
-{
- struct audio_device *adev = (struct audio_device *)dev;
- struct str_parms *reply = str_parms_create();
- struct str_parms *query = str_parms_create_str(keys);
- char *str;
-
- pthread_mutex_lock(&adev->lock);
-
- platform_get_parameters(adev->platform, query, reply);
- str = str_parms_to_str(reply);
- str_parms_destroy(query);
- str_parms_destroy(reply);
-
- pthread_mutex_unlock(&adev->lock);
- ALOGV("%s: exit: returns - %s", __func__, str);
- return str;
-}
-
-static int adev_init_check(const struct audio_hw_device *dev)
-{
- return 0;
-}
-
-static int adev_set_voice_volume(struct audio_hw_device *dev, float volume)
-{
- int ret = 0;
- return ret;
-}
-
-static int adev_set_master_volume(struct audio_hw_device *dev, float volume)
-{
- return -ENOSYS;
-}
-
-static int adev_get_master_volume(struct audio_hw_device *dev,
- float *volume)
-{
- return -ENOSYS;
-}
-
-static int adev_set_master_mute(struct audio_hw_device *dev, bool muted)
-{
- return -ENOSYS;
-}
-
-static int adev_get_master_mute(struct audio_hw_device *dev, bool *muted)
-{
- return -ENOSYS;
-}
-
-static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode)
-{
- struct audio_device *adev = (struct audio_device *)dev;
- pthread_mutex_lock(&adev->lock);
- if (adev->mode != mode) {
- ALOGD("%s mode %d\n", __func__, mode);
- adev->mode = mode;
- }
- pthread_mutex_unlock(&adev->lock);
- return 0;
-}
-
-static int adev_set_mic_mute(struct audio_hw_device *dev, bool state)
-{
- int ret = 0;
-
- return ret;
-}
-
-static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state)
-{
- return 0;
-}
-
-static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev,
- const struct audio_config *config)
-{
- int channel_count = popcount(config->channel_mask);
-
- return get_input_buffer_size(config->sample_rate, config->format, channel_count);
-}
-
-static int adev_open_input_stream(struct audio_hw_device *dev,
- audio_io_handle_t handle,
- audio_devices_t devices,
- struct audio_config *config,
- struct audio_stream_in **stream_in)
-{
- struct audio_device *adev = (struct audio_device *)dev;
- struct stream_in *in;
- int ret = 0, buffer_size, frame_size;
- int channel_count = popcount(config->channel_mask);
-
- ALOGV("%s: enter", __func__);
- *stream_in = NULL;
- if (check_input_parameters(config->sample_rate, config->format, channel_count) != 0)
- return -EINVAL;
-
- in = (struct stream_in *)calloc(1, sizeof(struct stream_in));
-
- in->stream.common.get_sample_rate = in_get_sample_rate;
- in->stream.common.set_sample_rate = in_set_sample_rate;
- in->stream.common.get_buffer_size = in_get_buffer_size;
- in->stream.common.get_channels = in_get_channels;
- in->stream.common.get_format = in_get_format;
- in->stream.common.set_format = in_set_format;
- in->stream.common.standby = in_standby;
- in->stream.common.dump = in_dump;
- in->stream.common.set_parameters = in_set_parameters;
- in->stream.common.get_parameters = in_get_parameters;
- in->stream.common.add_audio_effect = in_add_audio_effect;
- in->stream.common.remove_audio_effect = in_remove_audio_effect;
- in->stream.set_gain = in_set_gain;
- in->stream.read = in_read;
- in->stream.get_input_frames_lost = in_get_input_frames_lost;
-
- in->device = devices;
- in->source = AUDIO_SOURCE_DEFAULT;
- in->dev = adev;
- in->standby = 1;
- in->channel_mask = config->channel_mask;
-
- /* Update config params with the requested sample rate and channels */
- in->usecase = USECASE_AUDIO_RECORD;
- in->config = pcm_config_audio_capture;
- in->config.rate = config->sample_rate;
- in->format = config->format;
-
- {
- in->config.channels = channel_count;
- frame_size = audio_stream_frame_size((struct audio_stream *)in);
- buffer_size = get_input_buffer_size(config->sample_rate,
- config->format,
- channel_count);
- in->config.period_size = buffer_size / frame_size;
- }
-
- *stream_in = &in->stream;
- ALOGV("%s: exit", __func__);
- return ret;
-
-err_open:
- free(in);
- *stream_in = NULL;
- return ret;
-}
-
-static void adev_close_input_stream(struct audio_hw_device *dev,
- struct audio_stream_in *stream)
-{
- int ret;
- struct stream_in *in = (struct stream_in *)stream;
- ALOGV("%s", __func__);
-
- in_standby(&stream->common);
-
- free(stream);
-
- return;
-}
-
-static int adev_dump(const audio_hw_device_t *device, int fd)
-{
- return 0;
-}
-
-static int adev_close(hw_device_t *device)
-{
- struct audio_device *adev = (struct audio_device *)device;
-
- if (!adev)
- return 0;
-
- pthread_mutex_lock(&adev_init_lock);
-
- if ((--audio_device_ref_count) == 0) {
- audio_route_free(adev->audio_route);
- free(adev->snd_dev_ref_cnt);
- platform_deinit(adev->platform);
- free(device);
- adev = NULL;
- }
- pthread_mutex_unlock(&adev_init_lock);
- return 0;
-}
-
-static int adev_open(const hw_module_t *module, const char *name,
- hw_device_t **device)
-{
- int i, ret;
-
- ALOGD("%s: enter", __func__);
- if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0) return -EINVAL;
-
- pthread_mutex_lock(&adev_init_lock);
- if (audio_device_ref_count != 0){
- *device = &adev->device.common;
- audio_device_ref_count++;
- ALOGD("%s: returning existing instance of adev", __func__);
- ALOGD("%s: exit", __func__);
- pthread_mutex_unlock(&adev_init_lock);
- return 0;
- }
-
- adev = calloc(1, sizeof(struct audio_device));
-
- adev->device.common.tag = HARDWARE_DEVICE_TAG;
- adev->device.common.version = AUDIO_DEVICE_API_VERSION_2_0;
- adev->device.common.module = (struct hw_module_t *)module;
- adev->device.common.close = adev_close;
-
- adev->device.init_check = adev_init_check;
- adev->device.set_voice_volume = adev_set_voice_volume;
- adev->device.set_master_volume = adev_set_master_volume;
- adev->device.get_master_volume = adev_get_master_volume;
- adev->device.set_master_mute = adev_set_master_mute;
- adev->device.get_master_mute = adev_get_master_mute;
- adev->device.set_mode = adev_set_mode;
- adev->device.set_mic_mute = adev_set_mic_mute;
- adev->device.get_mic_mute = adev_get_mic_mute;
- adev->device.set_parameters = adev_set_parameters;
- adev->device.get_parameters = adev_get_parameters;
- adev->device.get_input_buffer_size = adev_get_input_buffer_size;
- adev->device.open_output_stream = adev_open_output_stream;
- adev->device.close_output_stream = adev_close_output_stream;
- adev->device.open_input_stream = adev_open_input_stream;
- adev->device.close_input_stream = adev_close_input_stream;
- adev->device.dump = adev_dump;
-
- /* Set the default route before the PCM stream is opened */
- adev->mode = AUDIO_MODE_NORMAL;
- adev->active_input = NULL;
- adev->primary_output = NULL;
- adev->out_device = AUDIO_DEVICE_NONE;
- adev->bluetooth_nrec = true;
- adev->acdb_settings = TTY_MODE_OFF;
- /* adev->cur_hdmi_channels = 0; by calloc() */
- adev->snd_dev_ref_cnt = calloc(SND_DEVICE_MAX, sizeof(int));
- list_init(&adev->usecase_list);
-
- /* Loads platform specific libraries dynamically */
- adev->platform = platform_init(adev);
- if (!adev->platform) {
- free(adev->snd_dev_ref_cnt);
- free(adev);
- ALOGE("%s: Failed to init platform data, aborting.", __func__);
- *device = NULL;
- return -EINVAL;
- }
-
- if (access(VISUALIZER_LIBRARY_PATH, R_OK) == 0) {
- adev->visualizer_lib = dlopen(VISUALIZER_LIBRARY_PATH, RTLD_NOW);
- if (adev->visualizer_lib == NULL) {
- ALOGE("%s: DLOPEN failed for %s", __func__, VISUALIZER_LIBRARY_PATH);
- } else {
- ALOGV("%s: DLOPEN successful for %s", __func__, VISUALIZER_LIBRARY_PATH);
- adev->visualizer_start_output =
- (int (*)(audio_io_handle_t))dlsym(adev->visualizer_lib,
- "visualizer_hal_start_output");
- adev->visualizer_stop_output =
- (int (*)(audio_io_handle_t))dlsym(adev->visualizer_lib,
- "visualizer_hal_stop_output");
- }
- }
- *device = &adev->device.common;
-
- audio_device_ref_count++;
- pthread_mutex_unlock(&adev_init_lock);
-
- ALOGV("%s: exit", __func__);
- return 0;
-}
-
-static struct hw_module_methods_t hal_module_methods = {
- .open = adev_open,
-};
-
-struct audio_module HAL_MODULE_INFO_SYM = {
- .common = {
- .tag = HARDWARE_MODULE_TAG,
- .module_api_version = AUDIO_MODULE_API_VERSION_0_1,
- .hal_api_version = HARDWARE_HAL_API_VERSION,
- .id = AUDIO_HARDWARE_MODULE_ID,
- .name = "MPQ Audio HAL",
- .author = "The Linux Foundation",
- .methods = &hal_module_methods,
- },
-};
diff --git a/hal_mpq/audio_hw.h b/hal_mpq/audio_hw.h
deleted file mode 100644
index 7814d95..0000000
--- a/hal_mpq/audio_hw.h
+++ /dev/null
@@ -1,384 +0,0 @@
-/*
- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
- * Not a contribution.
- *
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef QCOM_AUDIO_HW_H
-#define QCOM_AUDIO_HW_H
-
-#include <cutils/list.h>
-#include <hardware/audio.h>
-#include <tinyalsa/asoundlib.h>
-#include <tinycompress/tinycompress.h>
-#include "sound/compress_params.h"
-#include <audio_route/audio_route.h>
-
-#define VISUALIZER_LIBRARY_PATH "/system/lib/soundfx/libqcomvisualizer.so"
-
-/* Flags used to initialize acdb_settings variable that goes to ACDB library */
-#define DMIC_FLAG 0x00000002
-#define QMIC_FLAG 0x00000004
-#define TTY_MODE_OFF 0x00000010
-#define TTY_MODE_FULL 0x00000020
-#define TTY_MODE_VCO 0x00000040
-#define TTY_MODE_HCO 0x00000080
-#define TTY_MODE_CLEAR 0xFFFFFF0F
-
-#define ACDB_DEV_TYPE_OUT 1
-#define ACDB_DEV_TYPE_IN 2
-
-#define MAX_SUPPORTED_CHANNEL_MASKS 2
-#define DEFAULT_HDMI_OUT_CHANNELS 2
-
-typedef int snd_device_t;
-#include <platform.h>
-
-/* These are the supported use cases by the hardware.
- * Each usecase is mapped to a specific PCM device.
- * Refer to pcm_device_table[].
- */
-typedef enum {
- USECASE_INVALID = -1,
- /* Playback usecases */
- USECASE_AUDIO_PLAYBACK_DEEP_BUFFER = 0,
- USECASE_AUDIO_PLAYBACK_LOW_LATENCY,
- USECASE_AUDIO_PLAYBACK_MULTI_CH,
- USECASE_AUDIO_PLAYBACK_FM,
- USECASE_AUDIO_PLAYBACK_OFFLOAD,
- USECASE_AUDIO_PLAYBACK_OFFLOAD1,
- USECASE_AUDIO_PLAYBACK_OFFLOAD2,
- USECASE_AUDIO_PLAYBACK_OFFLOAD3,
- /* Capture usecases */
- USECASE_AUDIO_RECORD,
- USECASE_AUDIO_RECORD_COMPRESS,
- USECASE_AUDIO_RECORD_LOW_LATENCY,
- USECASE_AUDIO_RECORD_FM_VIRTUAL,
-
- /* Voice usecase */
- USECASE_VOICE_CALL,
-
- /* Voice extension usecases */
- USECASE_VOICE2_CALL,
- USECASE_VOLTE_CALL,
- USECASE_QCHAT_CALL,
- USECASE_COMPRESS_VOIP_CALL,
-
- USECASE_INCALL_REC_UPLINK,
- USECASE_INCALL_REC_DOWNLINK,
- USECASE_INCALL_REC_UPLINK_AND_DOWNLINK,
-
- USECASE_INCALL_MUSIC_UPLINK,
- USECASE_INCALL_MUSIC_UPLINK2,
-
- USECASE_AUDIO_SPKR_CALIB_RX,
- USECASE_AUDIO_SPKR_CALIB_TX,
- AUDIO_USECASE_MAX
-} audio_usecase_t;
-
-typedef enum {
- DEEP_BUFFER_PLAYBACK_STREAM = 0,
- LOW_LATENCY_PLAYBACK_STREAM,
- MCH_PCM_PLAYBACK_STREAM,
- OFFLOAD_PLAYBACK_STREAM,
- LOW_LATENCY_RECORD_STREAM,
- RECORD_STREAM,
- VOICE_CALL_STREAM
-} audio_usecase_stream_type_t;
-
-#define STRING_TO_ENUM(string) { #string, string }
-struct string_to_enum {
- const char *name;
- uint32_t value;
-};
-
-static const struct string_to_enum out_channels_name_to_enum_table[] = {
- STRING_TO_ENUM(AUDIO_CHANNEL_OUT_STEREO),
- STRING_TO_ENUM(AUDIO_CHANNEL_OUT_5POINT1),
- STRING_TO_ENUM(AUDIO_CHANNEL_OUT_7POINT1),
-};
-
-#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
-
-/*
- * tinyAlsa library interprets period size as number of frames
- * one frame = channel_count * sizeof (pcm sample)
- * so if format = 16-bit PCM and channels = Stereo, frame size = 2 ch * 2 = 4 bytes
- * DEEP_BUFFER_OUTPUT_PERIOD_SIZE = 1024 means 1024 * 4 = 4096 bytes
- * We should take care of returning proper size when AudioFlinger queries for
- * the buffer size of an input/output stream
- */
-
-enum {
- OFFLOAD_CMD_EXIT, /* exit compress offload thread loop*/
- OFFLOAD_CMD_DRAIN, /* send a full drain request to DSP */
- OFFLOAD_CMD_PARTIAL_DRAIN, /* send a partial drain request to DSP */
- OFFLOAD_CMD_WAIT_FOR_BUFFER, /* wait for buffer released by DSP */
-};
-
-enum {
- OFFLOAD_STATE_IDLE,
- OFFLOAD_STATE_PLAYING,
- OFFLOAD_STATE_PAUSED,
-};
-
-struct offload_cmd {
- struct listnode node;
- int cmd;
- int data[];
-};
-
-struct alsa_handle {
-
- struct listnode list;
-//Parameters of the stream
- struct pcm *pcm;
- struct pcm_config config;
-
- struct compress *compr;
- struct compr_config compr_config;
-
- struct stream_out *out;
-
- audio_usecase_t usecase;
- int device_id;
- unsigned int sample_rate;
- audio_channel_mask_t channel_mask;
- audio_format_t input_format;
- audio_format_t output_format;
- audio_devices_t devices;
-
- route_format_t route_format;
- int decoder_type;
-
- bool cmd_pending ;
-};
-
-struct stream_out {
- struct audio_stream_out stream;
- pthread_mutex_t lock; /* see note below on mutex acquisition order */
- pthread_cond_t cond;
- /* TODO remove this */
- /*
- struct pcm_config config;
- struct compr_config compr_config;
- struct pcm *pcm;
- struct compress *compr;
- */
- int standby;
- int pcm_device_id;
- unsigned int sample_rate;
- audio_channel_mask_t channel_mask;
- audio_format_t format;
- audio_devices_t devices;
- audio_output_flags_t flags;
- audio_usecase_t usecase;
- /* Array of supported channel mask configurations. +1 so that the last entry is always 0 */
- audio_channel_mask_t supported_channel_masks[MAX_SUPPORTED_CHANNEL_MASKS + 1];
- bool muted;
- uint64_t written; /* total frames written, not cleared when entering standby */
- audio_io_handle_t handle;
-
- int non_blocking;
- int playback_started;
- int offload_state;
- pthread_cond_t offload_cond;
- pthread_t offload_thread;
- struct listnode offload_cmd_list;
- bool offload_thread_blocked;
-
- stream_callback_t offload_callback;
- void *offload_cookie;
- struct compr_gapless_mdata gapless_mdata;
- int send_new_metadata;
-
- struct audio_device *dev;
-
- /*devices configuration */
- int left_volume;
- int right_volume;
- audio_usecase_stream_type_t uc_strm_type;
- int hdmi_format;
- int spdif_format;
- int* device_formats; //TODO:Needs to come from AudioRutingManager
- struct audio_config *config;
-
- /* list of the session handles */
- struct listnode session_list;
-
- /* /MS11 instance */
- int use_ms11_decoder;
- void *ms11_decoder;
- struct compr_config compr_config;
-
- int channels;
-
- /* Buffering utility */
- struct audio_bitstream_sm *bitstrm;
-
- int buffer_size;
- int decoder_type;
- bool dec_conf_set;
- uint32_t min_bytes_req_to_dec;
- bool is_m11_file_mode;
- void *dec_conf_buf;
- int32_t dec_conf_bufLength;
- bool first_bitstrm_buf;
-
- bool open_dec_route;
- int dec_format_devices;
- bool open_dec_mch_route;
- int dec_mch_format_devices;
- bool open_passt_route;
- int passt_format_devices;
- bool sw_open_trans_route;
- int sw_trans_format_devices;
- bool hw_open_trans_route;
- int hw_trans_format_devices;
- bool channel_status_set;
- unsigned char channel_status[24];
- int route_audio_to_a2dp;
- int is_ms11_file_playback_mode;
- char * write_temp_buf;
- struct output_metadata output_meta_data;
-};
-
-struct stream_in {
- struct audio_stream_in stream;
- pthread_mutex_t lock; /* see note below on mutex acquisition order */
- struct pcm_config config;
- struct pcm *pcm;
- int standby;
- int source;
- int pcm_device_id;
- int device;
- audio_channel_mask_t channel_mask;
- audio_usecase_t usecase;
- bool enable_aec;
- bool enable_ns;
- audio_format_t format;
-
- struct audio_device *dev;
-};
-
-typedef enum {
- PCM_PLAYBACK,
- PCM_CAPTURE,
- VOICE_CALL,
- VOIP_CALL
-} usecase_type_t;
-
-union stream_ptr {
- struct stream_in *in;
- struct stream_out *out;
-};
-
-struct audio_usecase {
- struct listnode list;
- audio_usecase_t id;
- usecase_type_t type;
- audio_devices_t devices;
- snd_device_t out_snd_device;
- snd_device_t in_snd_device;
- union stream_ptr stream;
- struct alsa_handle *handle;
-};
-
-struct audio_device {
- struct audio_hw_device device;
- pthread_mutex_t lock; /* see note below on mutex acquisition order */
- struct mixer *mixer;
- audio_mode_t mode;
- audio_devices_t out_device;
- struct stream_in *active_input;
- struct stream_out *primary_output;
- bool bluetooth_nrec;
- bool screen_off;
- int *snd_dev_ref_cnt;
- struct listnode usecase_list;
- struct audio_route *audio_route;
- int acdb_settings;
- bool speaker_lr_swap;
- unsigned int cur_hdmi_channels;
-
- void *platform;
-
- void *visualizer_lib;
- int (*visualizer_start_output)(audio_io_handle_t);
- int (*visualizer_stop_output)(audio_io_handle_t);
-};
-
-static 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",
- [USECASE_AUDIO_PLAYBACK_MULTI_CH] = "multi-channel-playback",
- [USECASE_AUDIO_PLAYBACK_OFFLOAD] = "compress-offload-playback",
- [USECASE_AUDIO_PLAYBACK_OFFLOAD1] = "compress-offload-playback1",
- [USECASE_AUDIO_PLAYBACK_OFFLOAD2] = "compress-offload-playback2",
- [USECASE_AUDIO_PLAYBACK_OFFLOAD3] = "compress-offload-playback3",
- [USECASE_AUDIO_RECORD] = "audio-record",
- [USECASE_AUDIO_RECORD_COMPRESS] = "audio-record-compress",
- [USECASE_AUDIO_RECORD_LOW_LATENCY] = "low-latency-record",
- [USECASE_AUDIO_RECORD_FM_VIRTUAL] = "fm-virtual-record",
- [USECASE_AUDIO_PLAYBACK_FM] = "play-fm",
- [USECASE_VOICE_CALL] = "voice-call",
-
- [USECASE_VOICE2_CALL] = "voice2-call",
- [USECASE_VOLTE_CALL] = "volte-call",
- [USECASE_QCHAT_CALL] = "qchat-call",
- [USECASE_COMPRESS_VOIP_CALL] = "compress-voip-call",
- [USECASE_INCALL_REC_UPLINK] = "incall-rec-uplink",
- [USECASE_INCALL_REC_DOWNLINK] = "incall-rec-downlink",
- [USECASE_INCALL_REC_UPLINK_AND_DOWNLINK] = "incall-rec-uplink-and-downlink",
- [USECASE_INCALL_MUSIC_UPLINK] = "incall_music_uplink",
- [USECASE_INCALL_MUSIC_UPLINK2] = "incall_music_uplink2",
- [USECASE_AUDIO_SPKR_CALIB_RX] = "spkr-rx-calib",
- [USECASE_AUDIO_SPKR_CALIB_TX] = "spkr-vi-record",
-};
-
-
-int adev_open_output_stream(struct audio_hw_device *dev,
- audio_io_handle_t handle,
- audio_devices_t devices,
- audio_output_flags_t flags,
- struct audio_config *config,
- struct audio_stream_out **stream_out);
-
-void adev_close_output_stream(struct audio_hw_device *dev,
- struct audio_stream_out *stream);
-
-int select_devices(struct audio_device *adev,
- audio_usecase_t uc_id);
-int disable_audio_route(struct audio_device *adev,
- struct audio_usecase *usecase,
- bool update_mixer);
-int disable_snd_device(struct audio_device *adev,
- snd_device_t snd_device,
- bool update_mixer);
-int enable_snd_device(struct audio_device *adev,
- snd_device_t snd_device,
- bool update_mixer);
-int enable_audio_route(struct audio_device *adev,
- struct audio_usecase *usecase,
- bool update_mixer);
-struct audio_usecase *get_usecase_from_list(struct audio_device *adev,
- audio_usecase_t uc_id);
-/*
- * NOTE: when multiple mutexes have to be acquired, always take the
- * stream_in or stream_out mutex first, followed by the audio_device mutex.
- */
-
-#endif // QCOM_AUDIO_HW_H
diff --git a/hal_mpq/audio_stream_out.c b/hal_mpq/audio_stream_out.c
deleted file mode 100644
index 454b1d6..0000000
--- a/hal_mpq/audio_stream_out.c
+++ /dev/null
@@ -1,2898 +0,0 @@
-/* audio_stream_out.c
- **
- ** Copyright 2008-2009 Wind River Systems
- ** Copyright (c) 2011-2013, The Linux Foundation. All rights reserved
- ** Not a Contribution, Apache license notifications and license are retained
- ** for attribution purposes only.
- **
- ** Licensed under the Apache License, Version 2.0 (the "License");
- ** you may not use this file except in compliance with the License.
- ** You may obtain a copy of the License at
- **
- ** http://www.apache.org/licenses/LICENSE-2.0
- **
- ** Unless required by applicable law or agreed to in writing, software
- ** distributed under the License is distributed on an "AS IS" BASIS,
- ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ** See the License for the specific language governing permissions and
- ** limitations under the License.
- */
-
-#define LOG_TAG "audio_stream_out"
-/*#define LOG_NDEBUG 0*/
-/*#define VERY_VERY_VERBOSE_LOGGING*/
-#ifdef VERY_VERY_VERBOSE_LOGGING
-#define ALOGVV ALOGV
-#else
-#define ALOGVV(a...) do { } while(0)
-#endif
-
-#include <errno.h>
-#include <pthread.h>
-#include <stdint.h>
-#include <sys/time.h>
-#include <stdlib.h>
-#include <math.h>
-#include <dlfcn.h>
-#include <sys/resource.h>
-#include <sys/prctl.h>
-
-#include <cutils/log.h>
-#include <cutils/str_parms.h>
-#include <cutils/properties.h>
-#include <cutils/atomic.h>
-#include <cutils/sched_policy.h>
-
-#include <system/thread_defs.h>
-#include "audio_hw.h"
-#include "platform_api.h"
-#include <platform.h>
-
-#include "sound/compress_params.h"
-#include "audio_bitstream_sm.h"
-
-//TODO: enable sw_decode if required
-#define USE_SWDECODE 0
-
-#if USE_SWDECODE
-#include "SoftMS11.h"
-#endif
-
-#define COMPRESS_OFFLOAD_FRAGMENT_SIZE (32 * 1024)
-#define COMPRESS_OFFLOAD_NUM_FRAGMENTS 4
-/* ToDo: Check and update a proper value in msec */
-#define COMPRESS_OFFLOAD_PLAYBACK_LATENCY 96
-#define COMPRESS_PLAYBACK_VOLUME_MAX 0x2000
-#define STRING_LENGTH_OF_INTEGER 12
-
-static int send_offload_cmd_l(struct stream_out* out, int command);
-static int get_snd_codec_id(audio_format_t format);
-
-struct pcm_config pcm_config_deep_buffer = {
- .channels = 2,
- .rate = DEFAULT_OUTPUT_SAMPLING_RATE,
- .period_size = DEEP_BUFFER_OUTPUT_PERIOD_SIZE,
- .period_count = DEEP_BUFFER_OUTPUT_PERIOD_COUNT,
- .format = PCM_FORMAT_S16_LE,
- .start_threshold = DEEP_BUFFER_OUTPUT_PERIOD_SIZE / 4,
- .stop_threshold = INT_MAX,
- .avail_min = DEEP_BUFFER_OUTPUT_PERIOD_SIZE / 4,
-};
-
-struct pcm_config pcm_config_low_latency = {
- .channels = 2,
- .rate = DEFAULT_OUTPUT_SAMPLING_RATE,
- .period_size = LOW_LATENCY_OUTPUT_PERIOD_SIZE,
- .period_count = LOW_LATENCY_OUTPUT_PERIOD_COUNT,
- .format = PCM_FORMAT_S16_LE,
- .start_threshold = LOW_LATENCY_OUTPUT_PERIOD_SIZE / 4,
- .stop_threshold = INT_MAX,
- .avail_min = LOW_LATENCY_OUTPUT_PERIOD_SIZE / 4,
-};
-
-struct pcm_config pcm_config_hdmi_multi = {
- .channels = HDMI_MULTI_DEFAULT_CHANNEL_COUNT, /* changed when the stream is opened */
- .rate = DEFAULT_OUTPUT_SAMPLING_RATE, /* changed when the stream is opened */
- .period_size = HDMI_MULTI_PERIOD_SIZE,
- .period_count = HDMI_MULTI_PERIOD_COUNT,
- .format = PCM_FORMAT_S16_LE,
- .start_threshold = 0,
- .stop_threshold = INT_MAX,
- .avail_min = 0,
-};
-
-inline int nextMultiple(int n, int m) {
- return ((n/m) + 1) * m;
-}
-
-/*******************************************************************************
-Description: check for MS11 supported formats
-*******************************************************************************/
-//TODO: enable sw_decode if required
-#if USE_SWDECODE
-int is_ms11_supported_fromats(int format)
-{
- ALOGVV("is_ms11_supported_fromats");
- int main_format = format & AUDIO_FORMAT_MAIN_MASK;
- if(((main_format == AUDIO_FORMAT_AAC) ||
- (main_format == AUDIO_FORMAT_HE_AAC_V1) ||
- (main_format == AUDIO_FORMAT_HE_AAC_V2) ||
- (main_format == AUDIO_FORMAT_AC3) ||
- (main_format == AUDIO_FORMAT_AC3_PLUS) ||
- (main_format == AUDIO_FORMAT_EAC3))) {
- return 1;
- } else {
- return 0;
- }
-}
-#endif
-
-/*******************************************************************************
-Description: check if ac3 can played as pass through without MS11 decoder
-*******************************************************************************/
-//TODO: enable sw_decode if required
-#if USE_SWDECODE
-int can_ac3_passthrough_without_ms11(struct stream_out *out, int format)
-{
- ALOGVV("can_ac3_passthrough_without_ms11");
- int main_format = format & AUDIO_FORMAT_MAIN_MASK;
- if(main_format == AUDIO_FORMAT_AC3) {
- if(((out->hdmi_format == COMPRESSED) ||
- (out->hdmi_format == AUTO_DEVICE_FORMAT) ||
- (out->hdmi_format == COMPRESSED_CONVERT_EAC3_AC3) ||
- (out->hdmi_format == COMPRESSED_CONVERT_ANY_AC3)) &&
- ((out->spdif_format == COMPRESSED) ||
- (out->spdif_format == AUTO_DEVICE_FORMAT) ||
- (out->spdif_format == COMPRESSED_CONVERT_EAC3_AC3) ||
- (out->spdif_format == COMPRESSED_CONVERT_ANY_AC3))) {
- return 1;
- }
- }
- return 0;
-}
-#endif
-
-/*******************************************************************************
-Description: get levels of buffering, interms of number of buffers
-*******************************************************************************/
-int get_buffering_factor(struct stream_out *out)
-{
- ALOGVV("get_buffering_factor");
- if((out->format == AUDIO_FORMAT_PCM_16_BIT) ||
- (out->format == AUDIO_FORMAT_PCM_24_BIT))
- return 1;
- else
- return NUM_OF_PERIODS;
-}
-
-/*******************************************************************************
-Description: get the buffer size based on format and device format type
-*******************************************************************************/
-void get_fragment_size_and_format(struct stream_out *out, int routeFormat, int *fragment_size,
- int *fragment_count, int *format)
-{
- ALOGV("get_fragment_size_and_format");
-
- int frame_size = 0;
- *format = out->format;
- *fragment_count = NUM_OF_PERIODS;
- switch(out->format) {
- case AUDIO_FORMAT_PCM_16_BIT:
- frame_size = PCM_16_BITS_PER_SAMPLE * out->channels;
- /*TODO: do we need below calculation */
- *fragment_size = nextMultiple(((frame_size * out->sample_rate * TIME_PER_BUFFER)/1000) + MIN_SIZE_FOR_METADATA , frame_size * 32);
- break;
- case AUDIO_FORMAT_PCM_24_BIT:
- frame_size = PCM_24_BITS_PER_SAMPLE * out->channels;
- *fragment_size = nextMultiple(((frame_size * out->sample_rate * TIME_PER_BUFFER)/1000) + MIN_SIZE_FOR_METADATA, frame_size * 32);
- break;
- case AUDIO_FORMAT_AAC:
- case AUDIO_FORMAT_HE_AAC_V1:
- case AUDIO_FORMAT_HE_AAC_V2:
- case AUDIO_FORMAT_AAC_ADIF:
- case AUDIO_FORMAT_AC3:
- case AUDIO_FORMAT_AC3_DM:
- case AUDIO_FORMAT_EAC3:
- case AUDIO_FORMAT_EAC3_DM:
- if(routeFormat == ROUTE_UNCOMPRESSED_MCH) {
- frame_size = PCM_16_BITS_PER_SAMPLE * out->channels;
- *fragment_size = nextMultiple(AC3_PERIOD_SIZE * out->channels + MIN_SIZE_FOR_METADATA, frame_size * 32);
- *format = AUDIO_FORMAT_PCM_16_BIT;
- } else if(routeFormat == ROUTE_UNCOMPRESSED) {
- frame_size = PCM_16_BITS_PER_SAMPLE * 2;
- *fragment_size = nextMultiple(AC3_PERIOD_SIZE * 2 + MIN_SIZE_FOR_METADATA, frame_size * 32);
- *format = AUDIO_FORMAT_PCM_16_BIT;
- } else {
- *fragment_size = PERIOD_SIZE_COMPR;
- }
- break;
- case AUDIO_FORMAT_DTS:
- case AUDIO_FORMAT_DTS_LBR:
- case AUDIO_FORMAT_MP3:
- case AUDIO_FORMAT_WMA:
- case AUDIO_FORMAT_WMA_PRO:
- case AUDIO_FORMAT_MP2:
- *fragment_size = PERIOD_SIZE_COMPR;
- break;
- default:
- *fragment_size = PERIOD_SIZE_COMPR;
- *format = out->format;
- }
-
- /*TODO: remove this if fragement count needs to be decided based on the format*/
- *fragment_count = COMPRESS_OFFLOAD_NUM_FRAGMENTS;
- fragment_size = COMPRESS_OFFLOAD_FRAGMENT_SIZE;
-
- ALOGV("fragment_size: %d, fragment_count: %d", *fragment_size, *fragment_count);
- return;
-}
-
-/*******************************************************************************
-Description: buffer length updated to player
-*******************************************************************************/
-int get_buffer_length(struct stream_out *out)
-{
- /* TODO: Do we need below */
- ALOGV("get_buffer_length");
- int buffer_size = COMPRESS_OFFLOAD_FRAGMENT_SIZE;
- switch(out->format) {
- case AUDIO_FORMAT_PCM_16_BIT:
- buffer_size = ((PCM_16_BITS_PER_SAMPLE * out->channels * out->sample_rate * TIME_PER_BUFFER)/1000);
- break;
- case AUDIO_FORMAT_PCM_24_BIT:
- buffer_size = ((PCM_24_BITS_PER_SAMPLE * out->channels * out->sample_rate * TIME_PER_BUFFER)/1000);
- break;
- case AUDIO_FORMAT_AAC:
- case AUDIO_FORMAT_HE_AAC_V1:
- case AUDIO_FORMAT_HE_AAC_V2:
- case AUDIO_FORMAT_AAC_ADIF:
- buffer_size = AAC_BLOCK_PER_CHANNEL_MS11 * out->channels;
- break;
- case AUDIO_FORMAT_AC3:
- case AUDIO_FORMAT_AC3_DM:
- case AUDIO_FORMAT_EAC3:
- case AUDIO_FORMAT_EAC3_DM:
- buffer_size = AC3_BUFFER_SIZE;
- break;
- case AUDIO_FORMAT_DTS:
- case AUDIO_FORMAT_DTS_LBR:
- case AUDIO_FORMAT_MP3:
- case AUDIO_FORMAT_WMA:
- case AUDIO_FORMAT_WMA_PRO:
- case AUDIO_FORMAT_MP2:
- buffer_size = COMPR_INPUT_BUFFER_SIZE;
- break;
- default:
- buffer_size = COMPRESS_OFFLOAD_FRAGMENT_SIZE;
- }
-
- /*TODO: remove this if fragement count needs to be decided based on the format*/
- buffer_size = COMPRESS_OFFLOAD_FRAGMENT_SIZE;
- return buffer_size;
-}
-
-/* TODO: Uncomment this when enabling A2DP
- TODO: add support for the 24 bit playback*/
-#if 0
-/*******************************************************************************
-Description: fix up devices for supporting A2DP playback
-*******************************************************************************/
-void fixUpDevicesForA2DPPlayback(struct stream_out *out)
-{
- ALOGVV("fixUpDevicesForA2DPPlayback");
- if(out->devices & AUDIO_DEVICE_OUT_ALL_A2DP) {
- out->route_audio_to_a2dp = 1;
- out->devices &= ~AUDIO_DEVICE_OUT_ALL_A2DP;
- //TODO: add spdif and proxy
- //out->devices &= ~AUDIO_DEVICE_OUT_SPDIF;
- //out->devices |= AudioSystem::DEVICE_OUT_PROXY;
- }
-}
-#endif
-
-/*******************************************************************************
-Description: open temp buffer so that meta data mode can be updated properly
-*******************************************************************************/
-int open_temp_buf_for_metadata(struct stream_out *out)
-{
- ALOGV("%s", __func__);
- if (out->write_temp_buf == NULL) {
- /*Max Period size which is exposed by the compr driver
- The value needs to be modified when the period size is modified*/
- out->write_temp_buf = (char *) malloc(PLAYBACK_MAX_PERIOD_SIZE);
- if (out->write_temp_buf == NULL) {
- ALOGE("Memory allocation of temp buffer to write pcm to driver failed");
- return -EINVAL;
- }
- }
- return 0;
-}
-
-/*******************************************************************************
-Description: get index of handle based on device handle device
-*******************************************************************************/
-struct alsa_handle * get_handle_based_on_devices(struct stream_out *out, int handleDevices)
-{
- ALOGVV("get_handle_based_on_devices");
- struct listnode *node;
- struct alsa_handle *handle = NULL;
-
- list_for_each(node, &out->session_list) {
- handle = node_to_item(node, struct alsa_handle, list);
- if(handle->devices & handleDevices)
- break;
- }
- return handle;
-}
-
-void reset_out_parameters(struct stream_out *out) {
-
- out->hdmi_format = UNCOMPRESSED;
- out->spdif_format = UNCOMPRESSED;
- out->decoder_type = UNCOMPRESSED ;
- out->dec_conf_set = false;
- out->min_bytes_req_to_dec = 0;
- out->is_m11_file_mode = false;
- out->dec_conf_bufLength = 0;
- out->first_bitstrm_buf = false;
- out->open_dec_route = false;
- out->dec_format_devices = AUDIO_DEVICE_NONE;
- out->open_dec_mch_route = false;
- out->dec_mch_format_devices =AUDIO_DEVICE_NONE;
- out->open_passt_route = false;
- out->passt_format_devices = AUDIO_DEVICE_NONE;
- out->sw_open_trans_route = false;
- out->sw_trans_format_devices = AUDIO_DEVICE_NONE;
- out->hw_open_trans_route =false ;
- out->hw_trans_format_devices = AUDIO_DEVICE_NONE;
- out->channel_status_set = false;
- out->route_audio_to_a2dp = false;
- out->is_ms11_file_playback_mode = false;
- out->write_temp_buf = NULL;
- return;
-}
-
-struct alsa_handle *get_alsa_handle() {
-
- struct alsa_handle *handle;
- handle = (struct alsa_handle *)calloc(1, sizeof(struct alsa_handle));
- if(handle == NULL) {
- ALOGE("%s calloc failed for handle", __func__);
- } else {
- ALOGE("%s handle is 0x%x", __func__,(uint32_t)handle);
- }
-
- return handle;
-}
-
-void free_alsa_handle(struct alsa_handle *handle) {
-
- if(handle == NULL) {
- ALOGE("%s Invalid handle", __func__);
- }
- free(handle);
-
- return;
-}
-
-
-struct alsa_handle *get_handle_by_route_format(struct stream_out *out,
- int route_format)
-{
- struct listnode *node;
- struct alsa_handle *handle = NULL;
- ALOGV("%s",__func__);
- list_for_each(node, &out->session_list) {
- handle = node_to_item(node, struct alsa_handle, list);
- if(handle->route_format & route_format) {
- ALOGV("%s found handle %x",__func__,(uint32_t)handle);
- break;
- }
- }
-
- return handle;
-}
-
-/*******************************************************************************
-Description: get the format index
-*******************************************************************************/
-int get_format_index(int format)
-{
- ALOGVV("get_format_index");
- int idx = 0,i;
- for(i=0; i<NUM_SUPPORTED_CODECS; i++) {
- if(format == format_index[i][0]) {
- idx = format_index[i][1];
- break;
- }
- }
- return idx;
-}
-
-int get_compress_available_space(struct alsa_handle *handle)
-{
- uint32_t ret;
- size_t avail = 0;
- struct timespec tstamp;
- ret = compress_get_hpointer(handle->compr,&avail, &tstamp);
- if(ret!=0) {
- ALOGE("cannot get available space\n");
- } else
- ret = (int)avail;
- return ret;
-}
-
-
-/*******************************************************************************
-Description: validate if the decoder requires configuration to be set as first
- buffer
-*******************************************************************************/
-int is_decoder_config_required(struct stream_out *out)
-{
- ALOGVV("is_decoder_config_required");
- int main_format = out->format & AUDIO_FORMAT_MAIN_MASK;
- uint32_t i;
- if(!out->is_ms11_file_playback_mode)
- return 0;
- for(i=0; i<sizeof(decodersRequireConfig)/sizeof(int); i++)
- if(main_format == decodersRequireConfig[i])
- return 1;
- return 0;
-}
-
-/*******************************************************************************
-Description: query if input buffering mode require
-*******************************************************************************/
-int is_input_buffering_mode_reqd(struct stream_out *out)
-{
- ALOGVV("is_input_buffering_mode_reqd");
- if((out->decoder_type == SW_PASSTHROUGH) ||
- (out->decoder_type == DSP_PASSTHROUGH))
- return 1;
- else
- return 0;
-}
-
-
-
-/*******************************************************************************
-Description: update use case and routing flags
-*******************************************************************************/
-void update_decode_type_and_routing_states(struct stream_out *out)
-{
- ALOGV("%s", __func__);
-
- int format_index = get_format_index(out->format);
- int decodeType, idx;
-
- out->open_dec_route = false;
- out->open_dec_mch_route = false;
- out->open_passt_route = false;
- out->sw_open_trans_route = false;
- out->hw_open_trans_route = false;
- out->dec_format_devices = out->devices;
- out->dec_mch_format_devices = AUDIO_DEVICE_NONE;
- out->passt_format_devices = AUDIO_DEVICE_NONE;
- out->sw_trans_format_devices = AUDIO_DEVICE_NONE;
- out->hw_trans_format_devices = AUDIO_DEVICE_NONE;
- out->decoder_type = 0;
-
-//TODO: enable sw_decode if required
-#if USE_SWDECODE
- if(is_ms11_supported_fromats(out->format))
- out->use_ms11_decoder = true;
-#endif
-
- ALOGV("format_index: %d devices %x", format_index,out->devices);
- if(out->devices & AUDIO_DEVICE_OUT_SPDIF) {
- decodeType = usecase_docode_hdmi_spdif[NUM_STATES_FOR_EACH_DEVICE_FMT*format_index]
- [out->spdif_format];
- ALOGV("SPDIF: decoderType: %d", decodeType);
- out->decoder_type = decodeType;
- for(idx=0; idx<NUM_DECODE_PATH; idx++) {
- if(route_to_driver[idx][DECODER_TYPE_IDX] == decodeType) {
- switch(route_to_driver[idx][ROUTE_FORMAT_IDX]) {
- case ROUTE_UNCOMPRESSED:
- ALOGVV("ROUTE_UNCOMPRESSED");
- ALOGVV("SPDIF opened with stereo decode");
- out->open_dec_route = true;
- break;
- case ROUTE_UNCOMPRESSED_MCH:
- ALOGVV("ROUTE_UNCOMPRESSED_MCH");
- ALOGVV("SPDIF opened with multichannel decode");
- out->open_dec_mch_route = true;
- out->dec_format_devices &= ~AUDIO_DEVICE_OUT_SPDIF;
- out->dec_mch_format_devices |= AUDIO_DEVICE_OUT_SPDIF;
- break;
- case ROUTE_COMPRESSED:
- ALOGVV("ROUTE_COMPRESSED");
- out->open_passt_route = true;
- out->dec_format_devices &= ~AUDIO_DEVICE_OUT_SPDIF;
- out->passt_format_devices = AUDIO_DEVICE_OUT_SPDIF;
- break;
- case ROUTE_DSP_TRANSCODED_COMPRESSED:
- ALOGVV("ROUTE_DSP_TRANSCODED_COMPRESSED");
- out->hw_open_trans_route = true;
- out->hw_trans_format_devices = AUDIO_DEVICE_OUT_SPDIF;
- break;
- case ROUTE_SW_TRANSCODED_COMPRESSED:
- ALOGVV("ROUTE_SW_TRANSCODED_COMPRESSED");
- out->sw_open_trans_route = true;
- out->dec_format_devices &= ~AUDIO_DEVICE_OUT_SPDIF;
- out->sw_trans_format_devices = AUDIO_DEVICE_OUT_SPDIF;
- break;
- default:
- ALOGW("INVALID ROUTE for SPDIF, decoderType %d, routeFormat %d",
- decodeType, route_to_driver[idx][ROUTE_FORMAT_IDX]);
- break;
- }
- }
- }
- }
- if(out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
- decodeType = usecase_docode_hdmi_spdif[NUM_STATES_FOR_EACH_DEVICE_FMT*format_index]
- [out->hdmi_format];
- ALOGV("HDMI: decoderType: %d", decodeType);
- out->decoder_type |= decodeType;
- for(idx=0; idx<NUM_DECODE_PATH; idx++) {
- if(route_to_driver[idx][DECODER_TYPE_IDX] == decodeType) {
- switch(route_to_driver[idx][ROUTE_FORMAT_IDX]) {
- case ROUTE_UNCOMPRESSED:
- ALOGVV("ROUTE_UNCOMPRESSED");
- ALOGVV("HDMI opened with stereo decode");
- out->open_dec_route = true;
- break;
- case ROUTE_UNCOMPRESSED_MCH:
- ALOGVV("ROUTE_UNCOMPRESSED_MCH");
- ALOGVV("HDMI opened with multichannel decode");
- out->open_dec_mch_route = true;
- out->dec_format_devices &= ~AUDIO_DEVICE_OUT_AUX_DIGITAL;
- out->dec_mch_format_devices |= AUDIO_DEVICE_OUT_AUX_DIGITAL;
- break;
- case ROUTE_COMPRESSED:
- ALOGVV("ROUTE_COMPRESSED");
- out->open_passt_route = true;
- out->dec_format_devices &= ~AUDIO_DEVICE_OUT_AUX_DIGITAL;
- out->passt_format_devices |= AUDIO_DEVICE_OUT_AUX_DIGITAL;
- break;
- case ROUTE_DSP_TRANSCODED_COMPRESSED:
- ALOGVV("ROUTE_DSP_TRANSCODED_COMPRESSED");
- out->hw_open_trans_route = true;
- out->hw_trans_format_devices |= AUDIO_DEVICE_OUT_AUX_DIGITAL;
- break;
- case ROUTE_SW_TRANSCODED_COMPRESSED:
- ALOGVV("ROUTE_SW_TRANSCODED_COMPRESSED");
- out->sw_open_trans_route = true;
- out->dec_format_devices &= ~AUDIO_DEVICE_OUT_AUX_DIGITAL;
- out->sw_trans_format_devices |= AUDIO_DEVICE_OUT_AUX_DIGITAL;
- break;
- default:
- ALOGW("INVALID ROUTE for HDMI, decoderType %d, routeFormat %d",
- decodeType, route_to_driver[idx][ROUTE_FORMAT_IDX]);
- break;
- }
- }
- }
- }
- if(out->devices & ~(AUDIO_DEVICE_OUT_AUX_DIGITAL |
- AUDIO_DEVICE_OUT_SPDIF)) {
- decodeType = usecase_decode_format[NUM_STATES_FOR_EACH_DEVICE_FMT*format_index];
- ALOGV("Other Devices: decoderType: %d", decodeType);
- out->decoder_type |= decodeType;
- for(idx=0; idx<NUM_DECODE_PATH; idx++) {
- if(route_to_driver[idx][DECODER_TYPE_IDX] == decodeType) {
- switch(route_to_driver[idx][ROUTE_FORMAT_IDX]) {
- case ROUTE_UNCOMPRESSED:
- ALOGVV("ROUTE_UNCOMPRESSED");
- ALOGVV("Other Devices opened with stereo decode");
- out->open_dec_route = true;
- break;
- case ROUTE_UNCOMPRESSED_MCH:
- ALOGVV("ROUTE_UNCOMPRESSED_MCH");
- ALOGVV("Other Devices opened with multichannel decode");
- out->open_dec_mch_route = true;
- out->dec_format_devices &= ~(out->devices &
- ~(AUDIO_DEVICE_OUT_SPDIF |
- AUDIO_DEVICE_OUT_AUX_DIGITAL));
- out->dec_mch_format_devices |= (out->devices &
- ~(AUDIO_DEVICE_OUT_SPDIF |
- AUDIO_DEVICE_OUT_AUX_DIGITAL));
- break;
- default:
- ALOGW("INVALID ROUTE for Other Devices, decoderType %d, routeFormat %d",
- decodeType, route_to_driver[idx][ROUTE_FORMAT_IDX]);
- break;
- }
- }
- }
- }
-}
-
-/*******************************************************************************
-Description: update handle states
-*******************************************************************************/
-int update_alsa_handle_state(struct stream_out *out)
-{
- ALOGV("%s", __func__);
-
- struct alsa_handle *handle = NULL;
- struct listnode *node;
-
- if(out->open_dec_route) {
- if((handle = get_alsa_handle())== NULL)
- goto error;
- list_add_tail(&out->session_list, &handle->list);
- handle->route_format = ROUTE_UNCOMPRESSED;
- handle->devices = out->dec_format_devices;
- handle->usecase = platform_get_usecase(USECASE_AUDIO_PLAYBACK_OFFLOAD);
- handle->out = out;
- handle->cmd_pending = false;
- ALOGD("open_dec_route: routeformat: %d, devices: 0x%x: "
- ,handle->route_format, handle->devices);
- }
- if(out->open_dec_mch_route) {
- if((handle = get_alsa_handle())== NULL)
- goto error;
- list_add_tail(&out->session_list, &handle->list);
- handle->route_format = ROUTE_UNCOMPRESSED_MCH;
- handle->devices = out->dec_mch_format_devices;
- handle->usecase = platform_get_usecase(USECASE_AUDIO_PLAYBACK_OFFLOAD);
- handle->out = out;
- handle->cmd_pending = false;
- ALOGD("OpenMCHDecodeRoute: routeformat: %d, devices: 0x%x: "
- ,handle->route_format, handle->devices);
- }
- if(out->open_passt_route) {
- if((handle = get_alsa_handle())== NULL)
- goto error;
- list_add_tail(&out->session_list, &handle->list);
- handle->route_format = ROUTE_COMPRESSED;
- handle->devices = out->passt_format_devices;
- handle->usecase = platform_get_usecase(USECASE_AUDIO_PLAYBACK_OFFLOAD);
- handle->out = out;
- handle->cmd_pending = false;
- ALOGD("open_passt_route: routeformat: %d, devices: 0x%x: "
- ,handle->route_format, handle->devices);
- }
- if(out->sw_open_trans_route) {
- if((handle = get_alsa_handle())== NULL)
- goto error;
- handle->route_format = ROUTE_SW_TRANSCODED_COMPRESSED;
- handle->devices = out->sw_trans_format_devices;
- handle->usecase = platform_get_usecase(USECASE_AUDIO_PLAYBACK_OFFLOAD);
- handle->out = out;
- handle->cmd_pending = false;
- ALOGD("OpenTranscodeRoute: routeformat: %d, devices: 0x%x: "
- ,handle->route_format, handle->devices);
- }
- if(out->hw_open_trans_route) {
- if((handle = get_alsa_handle())== NULL)
- goto error;
- handle->route_format = ROUTE_DSP_TRANSCODED_COMPRESSED;
- handle->devices = out->hw_trans_format_devices;
- handle->usecase = platform_get_usecase(USECASE_AUDIO_PLAYBACK_OFFLOAD);
- handle->out = out;
- handle->cmd_pending = false;
- ALOGD("OpenTranscodeRoute: routeformat: %d, devices: 0x%x: "
- ,handle->route_format, handle->devices);
- }
-
-return 0;
-
-error:
- list_for_each(node, &out->session_list) {
- handle = node_to_item(node, struct alsa_handle, list);
- free_alsa_handle(handle);
- }
-
- return -ENOMEM;
-}
-
-/*******************************************************************************
-Description: setup input path
-*******************************************************************************/
-int allocate_internal_buffers(struct stream_out *out)
-{
- ALOGV("%s",__func__);
- int ret = 0;
- int main_format = out->format & AUDIO_FORMAT_MAIN_MASK;
-
- /*
- setup the bitstream state machine
- */
- out->bitstrm = ( struct audio_bitstream_sm *)calloc(1,
- sizeof(struct audio_bitstream_sm));
- if(!audio_bitstream_init(out->bitstrm, get_buffering_factor(out))) {
- ALOGE("%s Unable to allocate bitstream buffering for MS11",__func__);
- free(out->bitstrm);
- out->bitstrm = NULL;
- return -EINVAL;
- }
-
- if(is_input_buffering_mode_reqd(out))
- audio_bitstream_start_input_buffering_mode(out->bitstrm);
-
- /*
- setup the buffering data required for decode to start
- AAC_ADIF would require worst case frame size before decode starts
- other decoder formats handles the partial data, hence threshold is zero.
- */
-
- if(main_format == AUDIO_FORMAT_AAC_ADIF)
- out->min_bytes_req_to_dec = AAC_BLOCK_PER_CHANNEL_MS11*out->channels-1;
- else
- out->min_bytes_req_to_dec = 0;
-
- ret = open_temp_buf_for_metadata(out);
- if(ret < 0) {
- free(out->bitstrm);
- out->bitstrm = NULL;
- }
- out->buffer_size = get_buffer_length(out);
-
- return ret;
-}
-
-/*******************************************************************************
-Description: setup input path
-*******************************************************************************/
-int free_internal_buffers(struct stream_out *out)
-{
- if(out->bitstrm) {
- free(out->bitstrm);
- out->bitstrm = NULL;
- }
-
- if(out->write_temp_buf) {
- free(out->write_temp_buf);
- out->write_temp_buf = NULL;
- }
-
- if(out->dec_conf_buf) {
- free(out->dec_conf_buf);
- out->dec_conf_buf = NULL;
- }
- return 0;
-}
-
-/*******************************************************************************
-Description: open MS11 instance
-*******************************************************************************/
-//TODO: enable sw_decode if required
-#if USE_SWDECODE
-static int open_ms11_instance(struct stream_out *out)
-{
- ALOGV("openMS11Instance");
- int32_t formatMS11;
- int main_format = out->format & AUDIO_FORMAT_MAIN_MASK;
- out->ms11_decoder = get_soft_ms11();
- if(!out->ms11_decoder) {
- ALOGE("Could not resolve all symbols Required for MS11");
- return -EINVAL;
- }
- /*
- MS11 created
- */
- if(initialize_ms11_function_pointers(out->ms11_decoder) == false) {
- ALOGE("Could not resolve all symbols Required for MS11");
- free_soft_ms11(out->ms11_decoder);
- return -EINVAL;
- }
- /*
- update format
- */
- if((main_format == AUDIO_FORMAT_AC3) ||
- (main_format == AUDIO_FORMAT_EAC3)) {
- /*TODO: who wil setCOMPRESSED_CONVERT_AC3_ASSOC */
- if (out->spdif_format == COMPRESSED_CONVERT_AC3_ASSOC)
- formatMS11 = FORMAT_DOLBY_DIGITAL_PLUS_MAIN_ASSOC;
- else
- formatMS11 = FORMAT_DOLBY_DIGITAL_PLUS_MAIN;
- } else
- formatMS11 = FORMAT_DOLBY_PULSE_MAIN;
- /*
- set the use case to the MS11 decoder and open the stream for decoding
- */
- if(ms11_set_usecase_and_open_stream_with_mode(out->ms11_decoder,
- formatMS11, out->channels, out->sample_rate,
- out->is_m11_file_mode)) {
- ALOGE("SetUseCaseAndOpen MS11 failed");
- free_soft_ms11(out->ms11_decoder);
- return EINVAL;
- }
- if(is_decoder_config_required(out) && out->dec_conf_buf && out->dec_conf_bufLength) {
- if(ms11_set_aac_config(out->ms11_decoder, (unsigned char *)out->dec_conf_buf,
- out->dec_conf_bufLength) == true) {
- out->dec_conf_set = true;
- }
- }
-
- return 0;
-}
-#endif
-/*******************************************************************************
-Description: copy input to internal buffer
-*******************************************************************************/
-void copy_bitstream_internal_buffer(struct audio_bitstream_sm *bitstrm,
- char *buffer, size_t bytes)
-{
- // copy bitstream to internal buffer
- audio_bitstream_copy_to_internal_buffer(bitstrm, (char *)buffer, bytes);
-#ifdef DEBUG
- dumpInputOutput(INPUT, buffer, bytes, 0);
-#endif
-}
-
-/*******************************************************************************
-Description: set decoder config
-*******************************************************************************/
-//TODO: enable sw_decode if required
-#if USE_SWDECODE
-int setDecodeConfig(struct stream_out *out, char *buffer, size_t bytes)
-{
- ALOGV("%s ", __func__);
-
- int main_format = out->format & AUDIO_FORMAT_MAIN_MASK;
- if(!out->dec_conf_set) {
- if(main_format == AUDIO_FORMAT_AAC ||
- main_format == AUDIO_FORMAT_HE_AAC_V1 ||
- main_format == AUDIO_FORMAT_AAC_ADIF ||
- main_format == AUDIO_FORMAT_HE_AAC_V2) {
- if(out->ms11_decoder != NULL) {
- if(ms11_set_aac_config(out->ms11_decoder,(unsigned char *)buffer,
- bytes) == false) {
- ALOGE("AAC decoder config fail");
- return 0;
- }
- }
- }
-
- out->dec_conf_bufLength = bytes;
- if(out->dec_conf_buf)
- free(out->dec_conf_buf);
-
- out->dec_conf_buf = malloc(out->dec_conf_bufLength);
- memcpy(out->dec_conf_buf,
- buffer,
- out->dec_conf_bufLength);
- out->dec_conf_set = true;
- }
- out->dec_conf_set = true;
- return bytes;
-}
-#endif
-
-//TODO: enable sw_decode if required
-#if USE_SWDECODE
-int validate_sw_free_space(struct stream_out* out, int bytes_consumed_in_decode, int *pcm_2ch_len,
- int *pcm_mch_len, int *passthru_len, int *transcode_len, bool *wait_for_write_done) {
-
- struct alsa_handle *handle = NULL;
- char *bufPtr;
- int copy_output_buffer_size;
-
- *pcm_2ch_len = *pcm_mch_len = *passthru_len = *transcode_len = *wait_for_write_done = 0;
-
- if(out->decoder_type & SW_DECODE) {
- bufPtr = audio_bitstream_get_output_buffer_write_ptr(out->bitstrm,
- PCM_2CH_OUT);
- /*TODO: there is chance of illegale access if ms11 output exceeds bitstream
- output buffer boudary */
- copy_output_buffer_size = ms11_copy_output_from_ms11buf(out->ms11_decoder,
- PCM_2CH_OUT,
- bufPtr);
- handle = get_handle_by_route_format(out, ROUTE_UNCOMPRESSED);
- if(handle == NULL) {
- ALOGE("%s Invalid handle", __func__);
- return -EINVAL;
- }
- if(get_compress_available_space(handle) < copy_output_buffer_size) {
- handle->cmd_pending = true;
- *wait_for_write_done = true;
- }
- *pcm_2ch_len = copy_output_buffer_size;
-
- }
- if(out->decoder_type & SW_DECODE_MCH) {
- bufPtr=audio_bitstream_get_output_buffer_write_ptr(out->bitstrm,
- PCM_MCH_OUT);
- copy_output_buffer_size = ms11_copy_output_from_ms11buf(out->ms11_decoder,
- PCM_MCH_OUT,
- bufPtr);
- handle = get_handle_by_route_format(out, ROUTE_UNCOMPRESSED_MCH);
- if(handle == NULL) {
- ALOGE("%s Invalid handle", __func__);
- return -EINVAL;
- }
-
- if(get_compress_available_space(handle) < copy_output_buffer_size) {
- handle->cmd_pending = true;
- *wait_for_write_done = true;
- }
- *pcm_mch_len = copy_output_buffer_size;
- }
- if(out->decoder_type & SW_PASSTHROUGH) {
- bufPtr = audio_bitstream_get_output_buffer_write_ptr(out->bitstrm, COMPRESSED_OUT);
- copy_output_buffer_size = bytes_consumed_in_decode;
- memcpy(bufPtr, audio_bitstream_get_input_buffer_ptr(out->bitstrm), copy_output_buffer_size);
-
- handle = get_handle_by_route_format(out, ROUTE_COMPRESSED);
- if(handle == NULL) {
- ALOGE("%s Invalid handle", __func__);
- return -EINVAL;
- }
-
- if(get_compress_available_space(handle) < copy_output_buffer_size) {
- handle->cmd_pending = true;
- *wait_for_write_done = true;
- }
- *passthru_len = copy_output_buffer_size;
- }
- if(out->decoder_type & SW_TRANSCODE) {
- bufPtr = audio_bitstream_get_output_buffer_write_ptr(out->bitstrm,
- TRANSCODE_OUT);
- copy_output_buffer_size = ms11_copy_output_from_ms11buf(out->bitstrm,
- COMPRESSED_OUT,
- bufPtr);
- handle = get_handle_by_route_format(out, ROUTE_SW_TRANSCODED_COMPRESSED);
- if(handle == NULL) {
- ALOGE("%s Invalid handle", __func__);
- return -EINVAL;
- }
- if(get_compress_available_space(handle) < copy_output_buffer_size) {
- handle->cmd_pending = true;
- *wait_for_write_done = true;
- }
- *transcode_len = copy_output_buffer_size;
- }
- return 0;
-}
-#endif
-
-int validate_hw_free_space(struct stream_out *out, int bytes_consumed_in_decode, int *pcm_2ch_len,
- int *pcm_mch_len, int *passthru_len, int *transcode_len, bool *wait_for_write_done) {
-
- struct alsa_handle *handle = NULL;
- char *bufPtr;
- int copy_output_buffer_size;
- *pcm_2ch_len = *pcm_mch_len = *passthru_len = *transcode_len = *wait_for_write_done = 0;
- if(out->decoder_type & DSP_DECODE) {
- ALOGVV("DSP_DECODE");
- bufPtr = audio_bitstream_get_output_buffer_write_ptr(out->bitstrm,
- PCM_MCH_OUT);
- copy_output_buffer_size = bytes_consumed_in_decode;
- memcpy(bufPtr, audio_bitstream_get_input_buffer_ptr(out->bitstrm),
- copy_output_buffer_size);
- ALOGVV("%s bytes_consumed %d out bufPtr %x, pcm_mch_out_buf_size%d",
- __func__,bytes_consumed_in_decode,bufPtr,
- out->bitstrm->pcm_mch_out_buf_size);
- handle = get_handle_by_route_format(out, ROUTE_UNCOMPRESSED);/*TODO: revisit */
- if(handle == NULL) {
- ALOGE("%s Invalid handle", __func__);
- return -EINVAL;
- }
- if(get_compress_available_space(handle) < copy_output_buffer_size) {
- handle->cmd_pending = true;
- *wait_for_write_done = true;
- /*reset input buffer pointer as flinger will resend the data back */
- audio_bitstream_set_input_buffer_write_ptr(out->bitstrm,
- -copy_output_buffer_size);
- *pcm_mch_len = copy_output_buffer_size;
- }
- else
- *pcm_mch_len = copy_output_buffer_size;
- }
- if(out->decoder_type & DSP_PASSTHROUGH) {
- ALOGVV("DSP_PASSTHROUGH");
- bufPtr = audio_bitstream_get_output_buffer_write_ptr(out->bitstrm, COMPRESSED_OUT);
- copy_output_buffer_size = bytes_consumed_in_decode;
- memcpy(bufPtr, audio_bitstream_get_input_buffer_ptr(out->bitstrm), copy_output_buffer_size);
- handle = get_handle_by_route_format(out, ROUTE_COMPRESSED);
- if(handle == NULL) {
- ALOGE("%s Invalid handle", __func__);
- return -EINVAL;
- }
- if(get_compress_available_space(handle) < copy_output_buffer_size) {
- handle->cmd_pending = true;
- *wait_for_write_done = true;
- *passthru_len = copy_output_buffer_size;
- /*reset input buffer pointer as flinger will resend the data back */
- audio_bitstream_set_input_buffer_ptr(out->bitstrm, -copy_output_buffer_size);
- }
- else
- *passthru_len = copy_output_buffer_size;
- }
- /*TODO: handle DSP Transcode usecase */
- return 0;
-}
-
-int update_bitstrm_pointers(struct stream_out *out, int pcm_2ch_len,
- int pcm_mch_len, int passthru_len, int transcode_len) {
-
- if(out->decoder_type & SW_DECODE) {
- audio_bitstream_set_output_buffer_write_ptr(out->bitstrm, PCM_2CH_OUT,
- pcm_2ch_len);
-
- }
- if(out->decoder_type & SW_DECODE_MCH || out->decoder_type & DSP_DECODE) {
- audio_bitstream_set_output_buffer_write_ptr(out->bitstrm, PCM_MCH_OUT, pcm_mch_len);
- }
- if(out->decoder_type & SW_PASSTHROUGH || out->decoder_type & DSP_PASSTHROUGH) {
- audio_bitstream_set_output_buffer_write_ptr(out->bitstrm, COMPRESSED_OUT, passthru_len);
- }
- if(out->decoder_type & SW_TRANSCODE) {
- audio_bitstream_set_output_buffer_write_ptr(out->bitstrm,
- TRANSCODE_OUT,
- transcode_len);
- }
- return 0;
-}
-
-/*TODO correct it */
-static int configure_compr(struct stream_out *out,
- struct alsa_handle *handle) {
- handle->compr_config.codec = (struct snd_codec *)
- calloc(1, sizeof(struct snd_codec));
- handle->compr_config.codec->id =
- get_snd_codec_id(out->format); /*TODO: correct this based on format*/
- handle->compr_config.fragment_size = COMPRESS_OFFLOAD_FRAGMENT_SIZE;
- handle->compr_config.fragments = COMPRESS_OFFLOAD_NUM_FRAGMENTS;
- handle->compr_config.codec->sample_rate =
- compress_get_alsa_rate(out->sample_rate);
- handle->compr_config.codec->bit_rate = out->compr_config.codec->bit_rate;
- handle->compr_config.codec->ch_in =
- popcount(out->channel_mask);
- handle->compr_config.codec->ch_out = handle->compr_config.codec->ch_in;
- handle->compr_config.codec->format = out->compr_config.codec->format;
- memcpy(&handle->compr_config.codec->options,
- &out->compr_config.codec->options,
- sizeof(union snd_codec_options));
- return 0;
-}
-
-/*TODO: do we need to apply volume at the session open*/
-static int set_compress_volume(struct alsa_handle *handle, float left, float right)
-{
-
- struct audio_device *adev = handle->out->dev;
- struct mixer_ctl *ctl;
- int volume[2];
-
- char mixer_ctl_name[MIXER_PATH_MAX_LENGTH];
- ALOGV("%s:setting volume l %f r %f ", __func__, left, right);
-
- memset(mixer_ctl_name, 0, sizeof(mixer_ctl_name));
- snprintf(mixer_ctl_name, sizeof(mixer_ctl_name),
- "Compress Playback %d Volume", handle->device_id);
-
- ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
- if (!ctl) {
- ALOGE("%s: Could not get ctl for mixer cmd - %s",
- __func__, mixer_ctl_name);
- return -EINVAL;
- }
- volume[0] = (int)(left * (float) COMPRESS_PLAYBACK_VOLUME_MAX);
- volume[1] = (int)(right * (float) COMPRESS_PLAYBACK_VOLUME_MAX);
- mixer_ctl_set_array(ctl, volume, sizeof(volume)/sizeof(volume[0]));
-
- return 0;
-
-}
-
-/*******************************************************************************
-Description: software decode handling
-*******************************************************************************/
-//TODO: enable sw_decode if required
-#if USE_SWDECODE
-static int sw_decode(struct stream_out *out,
- char *buffer,
- size_t bytes,
- size_t *bytes_consumed,
- bool *continueDecode)
-{
- /* bytes pending to be decoded in current buffer*/
- bool wait_for_write_done = false;
- int bytes_pending_for_decode = 0;
- /* bytes consumed in current write buffer */
- int total_bytes_consumed = 0;
- size_t copyBytesMS11 = 0;
- size_t bytes_consumed_in_decode = 0;
- size_t copy_output_buffer_size = 0;
- uint32_t outSampleRate = out->sample_rate;
- uint32_t outChannels = out->channels;
- char * bufPtr;
- int pcm_2ch_len, pcm_mch_len, passthru_len, transcode_len;
- struct alsa_handle *handle = NULL;
-
- ALOGVV("sw Decode");
- // eos handling
- if(bytes == 0) {
- if(out->format == AUDIO_FORMAT_AAC_ADIF)
- audio_bitstream_append_silence_internal_buffer(out->bitstrm,
- out->min_bytes_req_to_dec,0x0);
- else
- return false;
- }
- /*
- check for sync word, if present then configure MS11 for fileplayback mode
- OFF. This is specifically done to handle Widevine usecase, in which the
- ADTS HEADER is not stripped off by the Widevine parser
- */
- if(out->first_bitstrm_buf == true) {
- uint16_t uData = (*((char *)buffer) << 8) + *((char *)buffer + 1) ;
- if(ADTS_HEADER_SYNC_RESULT == (uData & ADTS_HEADER_SYNC_MASK)) {
- ALOGD("Sync word found hence configure MS11 in file_playback Mode OFF");
- free_soft_ms11(out->ms11_decoder);
- out->is_m11_file_mode = false;
- open_ms11_instance(out);
- }
- out->first_bitstrm_buf = false;
- }
- //decode
- if(out->decoder_type == SW_PASSTHROUGH) {
- /*TODO: check if correct */
- bytes_consumed_in_decode = audio_bitstream_get_size(out->bitstrm);
- } else {
- if(audio_bitstream_sufficient_buffer_to_decode(out->bitstrm,
- out->min_bytes_req_to_dec) == true) {
- bufPtr = audio_bitstream_get_input_buffer_ptr(out->bitstrm);
- copyBytesMS11 = audio_bitstream_get_size(out->bitstrm);
- ms11_copy_bitstream_to_ms11_inpbuf(out->ms11_decoder, bufPtr,copyBytesMS11);
- bytes_consumed_in_decode = ms11_stream_decode(out->ms11_decoder,
- &outSampleRate, &outChannels);
- }
- }
-
- if((out->sample_rate != outSampleRate) || (out->channels != outChannels)) {
- ALOGD("Change in sample rate. New sample rate: %d", outSampleRate);
- out->sample_rate = outSampleRate;
- out->channels = outChannels;
- handle = get_handle_by_route_format(out, ROUTE_UNCOMPRESSED);
- if(handle !=NULL) {
- configure_compr(out, handle);
- handle->compr = compress_open(SOUND_CARD, handle->device_id,
- COMPRESS_IN, &handle->compr_config);
- if (handle->compr && !is_compress_ready(handle->compr)) {
- ALOGE("%s: %s", __func__, compress_get_error(handle->compr));
- compress_close(handle->compr);
- handle->compr = NULL;
- }
- if (out->offload_callback)
- compress_nonblock(handle->compr, out->non_blocking);
-
- set_compress_volume(handle, out->left_volume, out->right_volume);
- }
-
- handle = get_handle_by_route_format(out, ROUTE_UNCOMPRESSED_MCH);
- if(handle !=NULL) {
- configure_compr(out, handle);
- handle->compr = compress_open(SOUND_CARD, handle->device_id,
- COMPRESS_IN, &handle->compr_config);
- if (handle->compr && !is_compress_ready(handle->compr)) {
- ALOGE("%s: %s", __func__, compress_get_error(handle->compr));
- compress_close(handle->compr);
- handle->compr = NULL;
- }
- if (out->offload_callback)
- compress_nonblock(handle->compr, out->non_blocking);
- set_compress_volume(handle, out->left_volume, out->right_volume);
- out->channel_status_set = false;
- }
- }
-
-
- validate_sw_free_space(out, bytes_consumed_in_decode, &pcm_2ch_len, &pcm_mch_len,
- &passthru_len, &transcode_len, &wait_for_write_done);
-
- if(wait_for_write_done && out->non_blocking) {
- send_offload_cmd_l(out, OFFLOAD_CMD_WAIT_FOR_BUFFER);
- *continueDecode = false;
- *bytes_consumed = 0;
- return 0;
- } else {
- update_bitstrm_pointers(out, pcm_2ch_len, pcm_mch_len,
- passthru_len, transcode_len);
- audio_bitstream_copy_residue_to_start(out->bitstrm, bytes_consumed_in_decode);
- *bytes_consumed = bytes_consumed_in_decode;
- }
-
- copy_output_buffer_size = pcm_2ch_len + pcm_mch_len + passthru_len + transcode_len;
- if(copy_output_buffer_size &&
- audio_bitstream_sufficient_buffer_to_decode(out->bitstrm, out->min_bytes_req_to_dec) == true) {
- *continueDecode = true;
- return 0;
- }
- return 0;
-}
-#endif
-
-/*******************************************************************************
-Description: dsp decode handling
-*******************************************************************************/
-static bool dsp_decode(struct stream_out *out, char *buffer, size_t bytes,
- size_t *bytes_consumed, bool *continueDecode)
-{
- char *bufPtr;
- size_t bytes_consumed_in_decode = 0;
-
- bool wait_for_write_done = false;
- int pcm_2ch_len, pcm_mch_len, passthru_len, transcode_len;
-
- ALOGVV("dsp_decode");
- // decode
- {
- bytes_consumed_in_decode = audio_bitstream_get_size(out->bitstrm);
- }
- // handle change in sample rate
- {
- }
- //TODO: check if the copy of the buffers can be avoided
- /* can be removed as its not required for dsp decode usecase */
- *continueDecode = false;
- validate_hw_free_space(out, bytes_consumed_in_decode, &pcm_2ch_len, &pcm_mch_len,
- &passthru_len, &transcode_len, &wait_for_write_done);
-
- if(wait_for_write_done && out->non_blocking) {
- send_offload_cmd_l(out, OFFLOAD_CMD_WAIT_FOR_BUFFER);
- *bytes_consumed = 0;
- return 0;
- } else {
- update_bitstrm_pointers(out, pcm_2ch_len, pcm_mch_len,
- passthru_len, transcode_len);
- audio_bitstream_copy_residue_to_start(out->bitstrm, bytes_consumed_in_decode);
- *bytes_consumed = bytes_consumed_in_decode;
- ALOGV("%s bytes_consumed_in_decode =%d",__func__,bytes_consumed_in_decode);
- }
-
- return 0;
-}
-
-static bool decode(struct stream_out *out, char * buffer, size_t bytes,
- size_t *bytes_consumed, bool *continuedecode)
-{
- ALOGV("decode");
- bool continueDecode = false;
- int ret = 0;
-
- // TODO: enable software decode if required
- /*if (out->use_ms11_decoder) {
- ret = sw_decode(out, buffer, bytes,
- bytes_consumed, continuedecode);
-
- // set channel status
- // Set the channel status after first frame decode/transcode
- //TODO: set the SPDIF channel status bits
- if(out->channel_status_set == false)
- setSpdifchannel_status(
- audio_bitstream_get_output_buffer_ptr(out->bitstrm, COMPRESSED_OUT),
- bytes, AUDIO_PARSER_CODEC_AC3);
-
- } else */{
- ret = dsp_decode(out, buffer, bytes,
- bytes_consumed, continuedecode);
- // set channel status
- // Set the channel status after first frame decode/transcode
- //TODO: set the SPDIF channel status bits
-/* if(out->channel_status_set == false)
- setSpdifchannel_status(
- audio_bitstream_get_output_buffer_ptr(out->bitstrm, COMPRESSED_OUT),
- bytes, AUDIO_PARSER_CODEC_DTS);
-*/
- }
- return ret;
-}
-
-/*******************************************************************************
-Description: fixup sample rate and channel info based on format
-*******************************************************************************/
-void fixupSampleRateChannelModeMS11Formats(struct stream_out *out)
-{
- ALOGV("fixupSampleRateChannelModeMS11Formats");
- int main_format = out->format & AUDIO_FORMAT_MAIN_MASK;
- int subFormat = out->format & AUDIO_FORMAT_SUB_MASK;
-/*
-NOTE: For AAC, the output of MS11 is 48000 for the sample rates greater than
- 24000. The samples rates <= 24000 will be at their native sample rate
- For AC3, the PCM output is at its native sample rate if the decoding is
- single decode usecase for MS11.
-*/
- if(main_format == AUDIO_FORMAT_AAC ||
- main_format == AUDIO_FORMAT_HE_AAC_V1 ||
- main_format == AUDIO_FORMAT_HE_AAC_V2 ||
- main_format == AUDIO_FORMAT_AAC_ADIF) {
- out->sample_rate = out->sample_rate > 24000 ? 48000 : out->sample_rate;
- out->channels = 6;
- } else if (main_format == AUDIO_FORMAT_AC3 ||
- main_format == AUDIO_FORMAT_EAC3) {
- /* transcode AC3/EAC3 44.1K to 48K AC3 for non dual-mono clips */
- if (out->sample_rate == 44100 &&
- (subFormat != AUDIO_FORMAT_DOLBY_SUB_DM) &&
- (out->spdif_format == COMPRESSED ||
- out->spdif_format == AUTO_DEVICE_FORMAT ||
- out->spdif_format == COMPRESSED_CONVERT_EAC3_AC3) &&
- (out->hdmi_format == UNCOMPRESSED ||
- out->hdmi_format == UNCOMPRESSED_MCH)) {
- out->sample_rate = 48000;
- out->spdif_format = COMPRESSED_CONVERT_AC3_ASSOC;
- } else if (out->sample_rate == 44100) {
- out->spdif_format = UNCOMPRESSED;
- }
- out->channels = 6;
- }
- ALOGD("ms11 format fixup: out->spdif_format %d, out->hdmi_format %d",
- out->spdif_format, out->hdmi_format);
-}
-
-static bool is_supported_format(audio_format_t format)
-{
- switch (format) {
- case AUDIO_FORMAT_PCM_16_BIT:
- case AUDIO_FORMAT_MP3:
- case AUDIO_FORMAT_AAC:
- case AUDIO_FORMAT_WMA:
- case AUDIO_FORMAT_WMA_PRO:
- case AUDIO_FORMAT_MP2:
- return true;
- default:
- ALOGE("%s: Unsupported audio format: %x", __func__, format);
- break;
- }
-
- return false;
-}
-
-static int get_snd_codec_id(audio_format_t format)
-{
- int id = 0;
-
- switch (format) {
- case AUDIO_FORMAT_PCM_16_BIT:
- id = SND_AUDIOCODEC_PCM;
- break;
- case AUDIO_FORMAT_MP3:
- id = SND_AUDIOCODEC_MP3;
- break;
- case AUDIO_FORMAT_AAC:
- id = SND_AUDIOCODEC_AAC;
- break;
- case AUDIO_FORMAT_WMA:
- id = SND_AUDIOCODEC_WMA;
- break;
- case AUDIO_FORMAT_WMA_PRO:
- id = SND_AUDIOCODEC_WMA_PRO;
- break;
- case AUDIO_FORMAT_MP2:
- id = SND_AUDIOCODEC_MP2;
- break;
- default:
- ALOGE("%s: Unsupported audio format %x", __func__, format);
- }
-
- return id;
-}
-
-/* must be called with hw device mutex locked */
-static int read_hdmi_channel_masks(struct stream_out *out)
-{
- int ret = 0;
- int channels = platform_edid_get_max_channels(out->dev->platform);
-
- switch (channels) {
- /*
- * Do not handle stereo output in Multi-channel cases
- * Stereo case is handled in normal playback path
- */
- case 6:
- ALOGV("%s: HDMI supports 5.1", __func__);
- out->supported_channel_masks[0] = AUDIO_CHANNEL_OUT_5POINT1;
- break;
- case 8:
- ALOGV("%s: HDMI supports 5.1 and 7.1 channels", __func__);
- out->supported_channel_masks[0] = AUDIO_CHANNEL_OUT_5POINT1;
- out->supported_channel_masks[1] = AUDIO_CHANNEL_OUT_7POINT1;
- break;
- default:
- ALOGE("HDMI does not support multi channel playback");
- ret = -ENOSYS;
- break;
- }
- return ret;
-}
-
-/* must be called with out->lock locked */
-static int send_offload_cmd_l(struct stream_out* out, int command)
-{
- struct offload_cmd *cmd = (struct offload_cmd *)calloc(1, sizeof(struct offload_cmd));
-
- ALOGVV("%s %d", __func__, command);
-
- cmd->cmd = command;
- list_add_tail(&out->offload_cmd_list, &cmd->node);
- pthread_cond_signal(&out->offload_cond);
- return 0;
-}
-
-/* must be called iwth out->lock locked */
-static void stop_compressed_output_l(struct stream_out *out)
-{
- struct listnode *node;
- struct alsa_handle *handle;
- bool is_compr_out = false;
-
- ALOGV("%s", __func__);
- out->offload_state = OFFLOAD_STATE_IDLE;
- out->playback_started = 0;
- out->send_new_metadata = 1;
- list_for_each(node, &out->session_list) {
- handle = node_to_item(node, struct alsa_handle, list);
- if (handle->compr != NULL) {
- compress_stop(handle->compr);
- is_compr_out = true;
- }
- }
- if (is_compr_out) {
- while (out->offload_thread_blocked)
- pthread_cond_wait(&out->cond, &out->lock);
- }
-}
-
-static void *offload_thread_loop(void *context)
-{
- struct stream_out *out = (struct stream_out *) context;
- struct listnode *item;
- struct listnode *node;
- struct alsa_handle *handle;
-
- out->offload_state = OFFLOAD_STATE_IDLE;
- out->playback_started = 0;
-
- setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_AUDIO);
- set_sched_policy(0, SP_FOREGROUND);
- prctl(PR_SET_NAME, (unsigned long)"Offload Callback", 0, 0, 0);
-
- ALOGV("%s", __func__);
- pthread_mutex_lock(&out->lock);
- for (;;) {
- struct offload_cmd *cmd = NULL;
- stream_callback_event_t event;
- bool send_callback = false;
-
- ALOGVV("%s offload_cmd_list %d out->offload_state %d",
- __func__, list_empty(&out->offload_cmd_list),
- out->offload_state);
- if (list_empty(&out->offload_cmd_list)) {
- ALOGV("%s SLEEPING", __func__);
- pthread_cond_wait(&out->offload_cond, &out->lock);
- ALOGV("%s RUNNING", __func__);
- continue;
- }
-
- item = list_head(&out->offload_cmd_list);
- cmd = node_to_item(item, struct offload_cmd, node);
- list_remove(item);
-
- ALOGVV("%s STATE %d CMD %d",
- __func__, out->offload_state, cmd->cmd);
-
- if (cmd->cmd == OFFLOAD_CMD_EXIT) {
- free(cmd);
- break;
- }
-
- if (list_empty(&out->session_list)) {
- ALOGE("%s: Compress handle is NULL", __func__);
- pthread_cond_signal(&out->cond);
- continue;
- }
- out->offload_thread_blocked = true;
- pthread_mutex_unlock(&out->lock);
- send_callback = false;
- switch(cmd->cmd) {
- case OFFLOAD_CMD_WAIT_FOR_BUFFER:
- list_for_each(node, &out->session_list) {
- handle = node_to_item(node, struct alsa_handle, list);
- if (handle->compr && handle->cmd_pending) {
- compress_wait(handle->compr, -1);
- handle->cmd_pending = false;
- }
- }
- send_callback = true;
- event = STREAM_CBK_EVENT_WRITE_READY;
- break;
- case OFFLOAD_CMD_PARTIAL_DRAIN:
- list_for_each(node, &out->session_list) {
- handle = node_to_item(node, struct alsa_handle, list);
- if (handle->compr) {
- compress_next_track(handle->compr);
- compress_partial_drain(handle->compr);
- }
- }
- send_callback = true;
- event = STREAM_CBK_EVENT_DRAIN_READY;
- break;
- case OFFLOAD_CMD_DRAIN:
- list_for_each(node, &out->session_list) {
- handle = node_to_item(node, struct alsa_handle, list);
- if (handle->compr) {
- compress_drain(handle->compr);
- }
- }
- send_callback = true;
- event = STREAM_CBK_EVENT_DRAIN_READY;
- break;
- default:
- ALOGE("%s unknown command received: %d", __func__, cmd->cmd);
- break;
- }
- pthread_mutex_lock(&out->lock);
- out->offload_thread_blocked = false;
- pthread_cond_signal(&out->cond);
- if (send_callback) {
- out->offload_callback(event, NULL, out->offload_cookie);
- }
- free(cmd);
- }
-
- pthread_cond_signal(&out->cond);
- while (!list_empty(&out->offload_cmd_list)) {
- item = list_head(&out->offload_cmd_list);
- list_remove(item);
- free(node_to_item(item, struct offload_cmd, node));
- }
- pthread_mutex_unlock(&out->lock);
-
- return NULL;
-}
-
-static int create_offload_callback_thread(struct stream_out *out)
-{
- pthread_cond_init(&out->offload_cond, (const pthread_condattr_t *) NULL);
- list_init(&out->offload_cmd_list);
- pthread_create(&out->offload_thread, (const pthread_attr_t *) NULL,
- offload_thread_loop, out);
- return 0;
-}
-
-static int destroy_offload_callback_thread(struct stream_out *out)
-{
- pthread_mutex_lock(&out->lock);
- stop_compressed_output_l(out);
- send_offload_cmd_l(out, OFFLOAD_CMD_EXIT);
-
- pthread_mutex_unlock(&out->lock);
- pthread_join(out->offload_thread, (void **) NULL);
- pthread_cond_destroy(&out->offload_cond);
-
- return 0;
-}
-
-static bool allow_hdmi_channel_config(struct audio_device *adev)
-{
- struct listnode *node;
- struct audio_usecase *usecase;
- bool ret = true;
-
- list_for_each(node, &adev->usecase_list) {
- usecase = node_to_item(node, struct audio_usecase, list);
- if (usecase->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
- /*
- * If voice call is already existing, do not proceed further to avoid
- * disabling/enabling both RX and TX devices, CSD calls, etc.
- * Once the voice call done, the HDMI channels can be configured to
- * max channels of remaining use cases.
- */
- if (usecase->id == USECASE_VOICE_CALL) {
- ALOGD("%s: voice call is active, no change in HDMI channels",
- __func__);
- ret = false;
- break;
- } else if (usecase->id == USECASE_AUDIO_PLAYBACK_MULTI_CH) {
- ALOGD("%s: multi channel playback is active, "
- "no change in HDMI channels", __func__);
- ret = false;
- break;
- }
- }
- }
- return ret;
-}
-
-static int check_and_set_hdmi_channels(struct audio_device *adev,
- unsigned int channels)
-{
- struct listnode *node;
- struct audio_usecase *usecase;
-
- /* Check if change in HDMI channel config is allowed */
- if (!allow_hdmi_channel_config(adev))
- return 0;
-
- if (channels == adev->cur_hdmi_channels) {
- ALOGD("%s: Requested channels are same as current", __func__);
- return 0;
- }
-
- platform_set_hdmi_channels(adev->platform, channels);
- adev->cur_hdmi_channels = channels;
-
- /*
- * Deroute all the playback streams routed to HDMI so that
- * the back end is deactivated. Note that backend will not
- * be deactivated if any one stream is connected to it.
- */
- list_for_each(node, &adev->usecase_list) {
- usecase = node_to_item(node, struct audio_usecase, list);
- if (usecase->type == PCM_PLAYBACK &&
- usecase->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
- disable_audio_route(adev, usecase, true);
- }
- }
-
- /*
- * Enable all the streams disabled above. Now the HDMI backend
- * will be activated with new channel configuration
- */
- list_for_each(node, &adev->usecase_list) {
- usecase = node_to_item(node, struct audio_usecase, list);
- if (usecase->type == PCM_PLAYBACK &&
- usecase->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
- enable_audio_route(adev, usecase, true);
- }
- }
-
- return 0;
-}
-
-static int stop_output_stream(struct stream_out *out, struct alsa_handle *handle)
-{
- int i, ret = 0;
- struct audio_usecase *uc_info;
- struct audio_device *adev = out->dev;
-
- ALOGV("%s: enter: usecase(%d: %s)", __func__,
- handle->usecase, use_case_table[handle->usecase]);
- uc_info = get_usecase_from_list(adev, handle->usecase);
- if (uc_info == NULL) {
- ALOGE("%s: Could not find the usecase (%d) in the list",
- __func__, handle->usecase);
- return -EINVAL;
- }
-
- if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD &&
- adev->visualizer_stop_output != NULL)
- adev->visualizer_stop_output(out->handle);
-
- /* 1. Get and set stream specific mixer controls */
- disable_audio_route(adev, uc_info, true);
-
- /* 2. Disable the rx device */
- disable_snd_device(adev, uc_info->out_snd_device, true);
-
- list_remove(&uc_info->list);
- free(uc_info);
-
- /* Must be called after removing the usecase from list */
- if (out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL)
- check_and_set_hdmi_channels(adev, DEFAULT_HDMI_OUT_CHANNELS);
-
- ALOGV("%s: exit: status(%d)", __func__, ret);
- return ret;
-}
-
-int start_output_stream(struct stream_out *out, struct alsa_handle *handle)
-{
- int ret = 0;
- struct audio_usecase *uc_info;
- struct audio_device *adev = out->dev;
-
- ALOGV("%s: enter: usecase(%d: %s) devices(%#x)",
- __func__, handle->usecase, use_case_table[handle->usecase], handle->devices);
- handle->device_id = platform_get_pcm_device_id(handle->usecase, PCM_PLAYBACK);
- if (handle->device_id < 0) {
- ALOGE("%s: Invalid PCM device id(%d) for the usecase(%d)",
- __func__, handle->device_id, handle->usecase);
- ret = -EINVAL;
- goto error_config;
- }
-
- uc_info = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase));
- uc_info->id = handle->usecase;
- uc_info->handle = handle;
- uc_info->type = PCM_PLAYBACK;
- uc_info->stream.out = out;
- uc_info->devices = handle->devices;
- uc_info->in_snd_device = SND_DEVICE_NONE;
- uc_info->out_snd_device = SND_DEVICE_NONE;
-
- /* This must be called before adding this usecase to the list */
- if (out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL)
- check_and_set_hdmi_channels(adev, handle->config.channels);
-
- list_add_tail(&adev->usecase_list, &uc_info->list);
-
- select_devices(adev, handle->usecase);
-
- ALOGV("%s: Opening PCM device card_id(%d) device_id(%d)",
- __func__, 0, handle->device_id);
- if (out->uc_strm_type != OFFLOAD_PLAYBACK_STREAM) {
- handle->compr = NULL;
- handle->pcm = pcm_open(SOUND_CARD, handle->device_id,
- PCM_OUT | PCM_MONOTONIC, &handle->config);
- if (handle->pcm && !pcm_is_ready(handle->pcm)) {
- ALOGE("%s: %s", __func__, pcm_get_error(handle->pcm));
- pcm_close(handle->pcm);
- handle->pcm = NULL;
- ret = -EIO;
- goto error_open;
- }
- } else {
- handle->pcm = NULL;
- configure_compr(out, handle);
- handle->compr = compress_open(SOUND_CARD, handle->device_id,
- COMPRESS_IN, &handle->compr_config);
- if (handle->compr && !is_compress_ready(handle->compr)) {
- ALOGE("%s: %s", __func__, compress_get_error(handle->compr));
- compress_close(handle->compr);
- handle->compr = NULL;
- ret = -EIO;
- goto error_open;
- }
- if (out->offload_callback)
- compress_nonblock(handle->compr, out->non_blocking);
-
- if (adev->visualizer_start_output != NULL)
- adev->visualizer_start_output(out->handle);
- }
- ALOGV("%s: exit", __func__);
- return 0;
-error_open:
- stop_output_stream(out, handle);
-error_config:
- return ret;
-}
-
-static uint32_t out_get_sample_rate(const struct audio_stream *stream)
-{
- struct stream_out *out = (struct stream_out *)stream;
-
- return out->sample_rate;
-}
-
-static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate)
-{
- return -ENOSYS;
-}
-
-static size_t out_get_buffer_size(const struct audio_stream *stream)
-{
- struct stream_out *out = (struct stream_out *)stream;
-
- /*if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
- return out->compr_config.fragment_size;
- */
- return (size_t)out->buffer_size;
-
- //return out->config.period_size * audio_stream_frame_size(stream);
-}
-
-static uint32_t out_get_channels(const struct audio_stream *stream)
-{
- struct stream_out *out = (struct stream_out *)stream;
-
- return out->channel_mask;
-}
-
-static audio_format_t out_get_format(const struct audio_stream *stream)
-{
- struct stream_out *out = (struct stream_out *)stream;
-
- return out->format;
-}
-
-static int out_set_format(struct audio_stream *stream, audio_format_t format)
-{
- return -ENOSYS;
-}
-
-static int out_standby(struct audio_stream *stream)
-{
- struct stream_out *out = (struct stream_out *)stream;
- struct audio_device *adev = out->dev;
- struct listnode *node;
- struct alsa_handle *handle;
-
- ALOGV("%s: enter: usecase(%d: %s)", __func__,
- out->usecase, use_case_table[out->usecase]);
- if (out->usecase == USECASE_COMPRESS_VOIP_CALL) {
- /* Ignore standby in case of voip call because the voip output
- * stream is closed in adev_close_output_stream()
- */
- ALOGV("%s: Ignore Standby in VOIP call", __func__);
- return 0;
- }
-
- pthread_mutex_lock(&out->lock);
- pthread_mutex_lock(&adev->lock);
- if (!out->standby) {
- out->standby = true;
- stop_compressed_output_l(out);
- out->gapless_mdata.encoder_delay = 0;
- out->gapless_mdata.encoder_padding = 0;
-
- list_for_each(node, &out->session_list) {
- handle = node_to_item(node, struct alsa_handle, list);
- if (handle->compr != NULL) {
- compress_close(handle->compr);
- handle->compr = NULL;
- } else if (handle->pcm) {
- pcm_close(handle->pcm);
- handle->pcm = NULL;
- }
- stop_output_stream(out, handle);
- }
- }
- pthread_mutex_unlock(&adev->lock);
- pthread_mutex_unlock(&out->lock);
- ALOGV("%s: exit", __func__);
- return 0;
-}
-
-static int out_dump(const struct audio_stream *stream, int fd)
-{
- return 0;
-}
-
-static int parse_compress_metadata(struct stream_out *out, struct str_parms *parms)
-{
- int ret = 0;
- char value[32];
- struct compr_gapless_mdata tmp_mdata;
- bool gapless_meta_set = true;
-
- if (!out || !parms) {
- return -EINVAL;
- }
-
- ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_DELAY_SAMPLES, value, sizeof(value));
- if (ret >= 0) {
- tmp_mdata.encoder_delay = atoi(value); //whats a good limit check?
- } else {
- gapless_meta_set = false;
- }
-
- ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_PADDING_SAMPLES, value, sizeof(value));
- if (ret >= 0) {
- tmp_mdata.encoder_padding = atoi(value);
- } else {
- gapless_meta_set = false;
- }
-
- if (gapless_meta_set) {
- out->gapless_mdata = tmp_mdata;
- out->send_new_metadata = 1;
- ALOGV("%s new encoder delay %u and padding %u", __func__,
- out->gapless_mdata.encoder_delay, out->gapless_mdata.encoder_padding);
- }
-
- if(out->format == AUDIO_FORMAT_WMA || out->format == AUDIO_FORMAT_WMA_PRO) {
- ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_WMA_FORMAT_TAG, value, sizeof(value));
- if (ret >= 0) {
- out->compr_config.codec->format = atoi(value);
- }
- ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_WMA_BLOCK_ALIGN, value, sizeof(value));
- if (ret >= 0) {
- out->compr_config.codec->options.wma.super_block_align = atoi(value);
- }
- ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_WMA_BIT_PER_SAMPLE, value, sizeof(value));
- if (ret >= 0) {
- out->compr_config.codec->options.wma.bits_per_sample = atoi(value);
- }
- ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_WMA_CHANNEL_MASK, value, sizeof(value));
- if (ret >= 0) {
- out->compr_config.codec->options.wma.channelmask = atoi(value);
- }
- ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_WMA_ENCODE_OPTION, value, sizeof(value));
- if (ret >= 0) {
- out->compr_config.codec->options.wma.encodeopt = atoi(value);
- }
- ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_WMA_ENCODE_OPTION1, value, sizeof(value));
- if (ret >= 0) {
- out->compr_config.codec->options.wma.encodeopt1 = atoi(value);
- }
- ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_WMA_ENCODE_OPTION2, value, sizeof(value));
- if (ret >= 0) {
- out->compr_config.codec->options.wma.encodeopt2 = atoi(value);
- }
- ALOGV("WMA params: fmt %x, balgn %x, sr %d, chmsk %x, encop %x, op1 %x, op2 %x",
- out->compr_config.codec->format,
- out->compr_config.codec->options.wma.super_block_align,
- out->compr_config.codec->options.wma.bits_per_sample,
- out->compr_config.codec->options.wma.channelmask,
- out->compr_config.codec->options.wma.encodeopt,
- out->compr_config.codec->options.wma.encodeopt1,
- out->compr_config.codec->options.wma.encodeopt2);
- }
- return 0;
-}
-
-static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
-{
- struct stream_out *out = (struct stream_out *)stream;
- struct audio_device *adev = out->dev;
- struct audio_usecase *usecase;
- struct listnode *node;
- struct str_parms *parms;
- char value[32];
- int ret, val = 0;
- bool select_new_device = false;
-
- ALOGD("%s: enter: kvpairs: %s", __func__, kvpairs);
- parms = str_parms_create_str(kvpairs);
- ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value));
- if (ret >= 0) {
- val = atoi(value);
- pthread_mutex_lock(&out->lock);
- pthread_mutex_lock(&adev->lock);
-
- /*
- * When HDMI cable is unplugged the music playback is paused and
- * the policy manager sends routing=0. But the audioflinger
- * continues to write data until standby time (3sec).
- * As the HDMI core is turned off, the write gets blocked.
- * Avoid this by routing audio to speaker until standby.
- */
- if (out->devices == AUDIO_DEVICE_OUT_AUX_DIGITAL &&
- val == AUDIO_DEVICE_NONE) {
- val = AUDIO_DEVICE_OUT_SPEAKER;
- }
-
- /*
- * select_devices() call below switches all the usecases on the same
- * backend to the new device. Refer to check_usecases_codec_backend() in
- * the select_devices(). But how do we undo this?
- *
- * For example, music playback is active on headset (deep-buffer usecase)
- * and if we go to ringtones and select a ringtone, low-latency usecase
- * will be started on headset+speaker. As we can't enable headset+speaker
- * and headset devices at the same time, select_devices() switches the music
- * playback to headset+speaker while starting low-lateny usecase for ringtone.
- * So when the ringtone playback is completed, how do we undo the same?
- *
- * We are relying on the out_set_parameters() call on deep-buffer output,
- * once the ringtone playback is ended.
- * NOTE: We should not check if the current devices are same as new devices.
- * Because select_devices() must be called to switch back the music
- * playback to headset.
- */
- if (val != 0) {
- out->devices = val;
-
- if (!out->standby)
- select_devices(adev, out->usecase);
- }
-//TODO:
-//Get the device and device format mapping from the RoutingManager.
-//Decide which streams need to be derouted and which need to opened/closed
-//Update the respective device in each of the handles
-#if 0
- if (out->uc_strm_type == OFFLOAD_PLAYBACK_STREAM) {
-
- /* TODO get format form routing manager */
- update_decode_type_and_routing_states(out);
-
- if(is_input_buffering_mode_reqd(out))
- audio_bitstream_start_input_buffering_mode(out->bitstrm);
- else
- audio_bitstream_stop_input_buffering_mode(out->bitstrm);
- /*
- For the runtime format change, close the device first to avoid any
- concurrent PCM + Compressed sessions on the same device.
- */
- close_handles_for_device_switch(out);
- if(!out->mopen_dec_route)
- handleCloseForDeviceSwitch(ROUTE_UNCOMPRESSED);
-
- if(!out->mopen_dec_mch_route)
- handleCloseForDeviceSwitch(ROUTE_UNCOMPRESSED_MCH);
-
- if(!out->mopen_passt_route)
- handleCloseForDeviceSwitch(ROUTE_COMPRESSED);
-
- if(!msw_open_trans_route)
- handleCloseForDeviceSwitch(ROUTE_SW_TRANSCODED_COMPRESSED);
-
- if(!mhw_open_trans_route)
- handleCloseForDeviceSwitch(ROUTE_DSP_TRANSCODED_COMPRESSED);
-
- if(out->mopen_dec_route)
- handleSwitchAndOpenForDeviceSwitch(mdec_format_devices,
- ROUTE_UNCOMPRESSED);
- if(out->mopen_dec_mch_route)
- handleSwitchAndOpenForDeviceSwitch(mdec_mch_format_devices,
- ROUTE_UNCOMPRESSED_MCH);
- if(out->mopen_passt_route)
- handleSwitchAndOpenForDeviceSwitch(mpasst_format_devices,
- ROUTE_COMPRESSED);
- if(out->msw_open_trans_route)
- handleSwitchAndOpenForDeviceSwitch(msw_trans_format_devices,
- ROUTE_SW_TRANSCODED_COMPRESSED);
- if(out->mhw_open_trans_route)
- handleSwitchAndOpenForDeviceSwitch(mhw_trans_format_devices,
- ROUTE_DSP_TRANSCODED_COMPRESSED);
- }
-#endif
-
- pthread_mutex_unlock(&adev->lock);
- pthread_mutex_unlock(&out->lock);
- }
-
- if (out->uc_strm_type == OFFLOAD_PLAYBACK_STREAM) {
- ret = parse_compress_metadata(out, parms);
- }
-
- str_parms_destroy(parms);
- ALOGV("%s: exit: code(%d)", __func__, ret);
- return ret;
-}
-
-static char* out_get_parameters(const struct audio_stream *stream, const char *keys)
-{
- struct stream_out *out = (struct stream_out *)stream;
- struct str_parms *query = str_parms_create_str(keys);
- char *str;
- char value[256];
- struct str_parms *reply = str_parms_create();
- size_t i, j;
- int ret;
- bool first = true;
- ALOGV("%s: enter: keys - %s", __func__, keys);
- ret = str_parms_get_str(query, AUDIO_PARAMETER_STREAM_SUP_CHANNELS, value, sizeof(value));
- if (ret >= 0) {
- value[0] = '\0';
- i = 0;
- while (out->supported_channel_masks[i] != 0) {
- for (j = 0; j < ARRAY_SIZE(out_channels_name_to_enum_table); j++) {
- if (out_channels_name_to_enum_table[j].value == out->supported_channel_masks[i]) {
- if (!first) {
- strlcat(value, "|", sizeof(value));
- }
- strlcat(value, out_channels_name_to_enum_table[j].name, sizeof(value));
- first = false;
- break;
- }
- }
- i++;
- }
- str_parms_add_str(reply, AUDIO_PARAMETER_STREAM_SUP_CHANNELS, value);
- str = str_parms_to_str(reply);
- }
- str_parms_destroy(query);
- str_parms_destroy(reply);
- ALOGV("%s: exit: returns - %s", __func__, str);
- return str;
-}
-
-static uint32_t out_get_latency(const struct audio_stream_out *stream)
-{
- struct stream_out *out = (struct stream_out *)stream;
- struct listnode *item;
- struct alsa_handle *handle;
-
- //TODO: decide based on the clip properties
- if (out->uc_strm_type == OFFLOAD_PLAYBACK_STREAM)
- return COMPRESS_OFFLOAD_PLAYBACK_LATENCY;
-
- item = list_head(&out->session_list);
- handle = node_to_item(item, struct alsa_handle, list);
- if(!handle) {
- ALOGE("%s: error pcm handle NULL", __func__);
- return -EINVAL;
- }
-
- return (handle->config.period_count * handle->config.period_size * 1000) /
- (handle->config.rate);
-}
-
-static int out_set_volume(struct audio_stream_out *stream, float left,
- float right)
-{
- struct stream_out *out = (struct stream_out *)stream;
- struct listnode *node;
- struct alsa_handle *handle;
- struct audio_device *adev = out->dev;
- int ret = -ENOSYS;
- ALOGV("%s:setting volume l %f r %f ", __func__, left, right);
- pthread_mutex_lock(&out->lock);
- list_for_each(node, &out->session_list) {
- handle = node_to_item(node, struct alsa_handle, list);
- if (handle->pcm && (out->usecase == USECASE_AUDIO_PLAYBACK_MULTI_CH)){
- /* only take left channel into account: the API is for stereo anyway */
- out->muted = (left == 0.0f);
- ret = 0;
- } else if (handle->compr) {
-
- out->left_volume = left;
- out->right_volume = right;
-
- ret = set_compress_volume(handle, left, right);
- }
- }
- pthread_mutex_unlock(&out->lock);
-
- return ret;
-}
-
-static int write_data(struct stream_out *out, struct alsa_handle *handle,
- const void *buffer, int bytes) {
-
- int ret = 0;
- if (out->uc_strm_type == OFFLOAD_PLAYBACK_STREAM) {
- ALOGV("%s: writing buffer (%d bytes) to compress device", __func__, bytes);
-
- ret = compress_write(handle->compr, buffer, bytes);
- ALOGV("%s: writing buffer (%d bytes) to compress device returned %d",
- __func__, bytes, ret);
- /* TODO:disnable this if ms12 */
-
- if (ret >= 0 && ret < (ssize_t)bytes) {
- handle->cmd_pending = true;
- send_offload_cmd_l(out, OFFLOAD_CMD_WAIT_FOR_BUFFER);
- }
- return ret;
- } else {
- if (handle->pcm) {
- if (out->muted)
- memset((void *)buffer, 0, bytes);
- ALOGV("%s: writing buffer (%d bytes) to pcm device", __func__, bytes);
- ret = pcm_write(handle->pcm, (void *)buffer, bytes);
- }
- }
-
- if (ret != 0) {
- if ((handle && handle->pcm))
- ALOGE("%s: error %d - %s", __func__, ret, pcm_get_error(handle->pcm));
- out_standby(&out->stream.common);
- usleep(bytes * 1000000 / audio_stream_frame_size(&out->stream.common) /
- out_get_sample_rate(&out->stream.common));
- }
- return bytes;
-}
-
-/*******************************************************************************
-Description: render
-*******************************************************************************/
-size_t render_offload_data(struct stream_out *out, const void *buffer, size_t bytes)
-{
- int ret =0;
- uint32_t renderedPcmBytes = 0;
- int fragment_size;
- uint32_t availableSize;
- int bytes_to_write = bytes;
- int renderType;
- /*int metadataLength = sizeof(out->output_meta_data);*/
- struct listnode *node;
- struct alsa_handle *handle;
-
- ALOGV("%s", __func__);
-
- list_for_each(node, &out->session_list) {
- handle = node_to_item(node, struct alsa_handle, list);
- if (out->send_new_metadata) {
- ALOGVV("send new gapless metadata");
- compress_set_gapless_metadata(handle->compr, &out->gapless_mdata);
- }
-
- switch(handle->route_format) {
- case ROUTE_UNCOMPRESSED:
- ALOGVV("ROUTE_UNCOMPRESSED");
- renderType = PCM_2CH_OUT;
- break;
- case ROUTE_UNCOMPRESSED_MCH:
- ALOGVV("ROUTE_UNCOMPRESSED_MCH");
- renderType = PCM_MCH_OUT;
- break;
- case ROUTE_COMPRESSED:
- ALOGVV("ROUTE_COMPRESSED");
- renderType = COMPRESSED_OUT;
- break;
- case ROUTE_SW_TRANSCODED_COMPRESSED:
- ALOGVV("ROUTE_SW_TRANSCODED_COMPRESSED");
- renderType = TRANSCODE_OUT;
- break;
- case ROUTE_DSP_TRANSCODED_COMPRESSED:
- ALOGVV("ROUTE_DSP_TRANSCODED_COMPRESSED");
- continue;
- default:
- continue;
- };
-
- fragment_size = handle->compr_config.fragment_size;
- /*TODO handle timestamp case */
-#if USE_SWDECODE
- while(audio_bitstream_sufficient_sample_to_render(out->bitstrm,
- renderType, 1) == true) {
- availableSize = audio_bitstream_get_output_buffer_write_ptr(out->bitstrm, renderType) -
- audio_bitstream_get_output_buffer_ptr(out->bitstrm, renderType);
- buffer = audio_bitstream_get_output_buffer_ptr(out->bitstrm, renderType);
- bytes_to_write = availableSize;
-
- TODO: meta data is only neded for TS mode
- out->output_meta_data.metadataLength = metadataLength;
- out->output_meta_data.bufferLength = (availableSize >=
- (fragment_size - metadataLength)) ?
- fragment_size - metadataLength :
- availableSize;
- bytes_to_write = metadataLength +out->output_meta_data.bufferLength;
- out->output_meta_data.timestamp = 0;
- memcpy(out->write_temp_buf, &out->output_meta_data, metadataLength);
- memcpy(out->write_temp_buf+metadataLength,
- audio_bitstream_get_output_buffer_ptr(out->bitstrm, renderType),
- out->output_meta_data.bufferLength);
- ret = write_data(out, handle, out->write_temp_buf, bytes_to_write);
-#endif
-
- ret = write_data(out, handle, buffer, bytes_to_write);
- ALOGD("write_data returned with %d", ret);
- if(ret < 0) {
- ALOGE("write_data returned ret < 0");
- return ret;
- } else {
- if (!out->playback_started) {
- compress_start(handle->compr);
- }
- /*TODO:Do we need this
- if(renderType == ROUTE_UNCOMPRESSED ||
- (renderType == ROUTE_UNCOMPRESSED_MCH && !out->open_dec_route)) {
- mFrameCount++;
- renderedPcmBytes += out->output_meta_data.bufferLength;
- }*/
- renderedPcmBytes += ret;
-#if USE_SWDECODE
- /*iTODO: enable for MS11
- audio_bitstream_copy_residue_output_start(out->bitstrm, renderType,
- bytes_to_write);
- TODO:what if ret<bytes_to_write*/
-#endif
- }
-#if USE_SWDECODE
- }
-#endif
- }
- out->playback_started = 1;
- out->offload_state = OFFLOAD_STATE_PLAYING;
- out->send_new_metadata = 0;
- return renderedPcmBytes;
-}
-
-size_t render_pcm_data(struct stream_out *out, const void *buffer, size_t bytes)
-{
- ALOGV("%s", __func__);
- size_t ret = 0;
- struct listnode *node;
- struct alsa_handle *handle;
- list_for_each(node, &out->session_list) {
- handle = node_to_item(node, struct alsa_handle, list);
- ALOGV("%s handle is 0x%x", __func__,(uint32_t)handle);
- ret = write_data(out, handle, buffer, bytes);
- }
- return ret;
-}
-
-static ssize_t out_write(struct audio_stream_out *stream, const void *buffer,
- size_t bytes)
-{
- struct stream_out *out = (struct stream_out *)stream;
- struct audio_device *adev = out->dev;
- ssize_t ret = 0;
- struct listnode *node;
- bool continueDecode;
- struct alsa_handle *handle;
- size_t bytes_consumed;
- size_t total_bytes_consumed = 0;
-
- ALOGV("%s bytes =%d", __func__, bytes);
-
- pthread_mutex_lock(&out->lock);
-
-//TODO: handle a2dp
-/* if (mRouteAudioToA2dp &&
- mA2dpUseCase == AudioHardwareALSA::USECASE_NONE) {
- a2dpRenderingControl(A2DP_RENDER_SETUP);
- }
-*/
- /* TODO: meta data comes in set_parameter it will be passed in compre_open
- for all format exxce ms11 format
- and for ms11 it will be set sdecode fucntion while opneing ms11 instance
- hence below piece of code is no required*/
- /*
- if(!out->dec_conf_set && is_decoder_config_required(out)) {
- if (setDecodeConfig(out, (char *)buffer, bytes))
- ALOGD("decoder configuration set");
- }
- */
-
- if (out->standby) {
- out->standby = false;
- list_for_each(node, &out->session_list) {
- handle = node_to_item(node, struct alsa_handle, list);
- pthread_mutex_lock(&adev->lock);
- ret = start_output_stream(out, handle);
- pthread_mutex_unlock(&adev->lock);
- /* ToDo: If use case is compress offload should return 0 */
- if (ret != 0) {
- out->standby = true;
- goto exit;
- }
- }
- }
-
- if (out->uc_strm_type == OFFLOAD_PLAYBACK_STREAM) {
-#if USE_SWDECODE
- //TODO: Enable for MS11
- copy_bitstream_internal_buffer(out->bitstrm, (char *)buffer, bytes);
- //DO check if timestamp mode handle partial buffer
- do {
-
- bytes_consumed = 0;
- ret = decode(out, (char *)buffer, bytes, &bytes_consumed, &continueDecode);
- if(ret < 0)
- goto exit;
- /*TODO: check for return size from write when ms11 is removed*/
- render_offload_data(out, continueDecode);
- total_bytes_consumed += bytes_consumed;
-
- } while(continueDecode == true);
-#endif
-#if 0
- ALOGVV("%s: writing buffer (%d bytes) to compress device", __func__, bytes);
- if (out->send_new_metadata) {
- ALOGVV("send new gapless metadata");
- compress_set_gapless_metadata(out->compr, &out->gapless_mdata);
- out->send_new_metadata = 0;
- }
-
- ret = compress_write(out->compr, buffer, bytes);
- ALOGVV("%s: writing buffer (%d bytes) to compress device returned %d", __func__, bytes, ret);
- if (ret >= 0 && ret < (ssize_t)bytes) {
- send_offload_cmd_l(out, OFFLOAD_CMD_WAIT_FOR_BUFFER);
- }
- if (!out->playback_started) {
- compress_start(out->compr);
- out->playback_started = 1;
- out->offload_state = OFFLOAD_STATE_PLAYING;
- }
- pthread_mutex_unlock(&out->lock);
- return ret;
- } else {
- if (out->pcm) {
- if (out->muted)
- memset((void *)buffer, 0, bytes);
- ALOGVV("%s: writing buffer (%d bytes) to pcm device", __func__, bytes);
- ret = pcm_write(out->pcm, (void *)buffer, bytes);
- if (ret == 0)
- out->written += bytes / (out->config.channels * sizeof(short));
- }
- }
-
-exit:
- pthread_mutex_unlock(&out->lock);
-
- if (ret != 0) {
- if (out->pcm)
- ALOGE("%s: error %d - %s", __func__, ret, pcm_get_error(out->pcm));
- out_standby(&out->stream.common);
- usleep(bytes * 1000000 / audio_stream_frame_size(&out->stream.common) /
- out_get_sample_rate(&out->stream.common));
- }
- return bytes;
-#endif
- ret = render_offload_data(out, buffer, bytes);
- total_bytes_consumed = ret;
- } else {
- ret = render_pcm_data(out, buffer, bytes);
- total_bytes_consumed = ret;
- }
-
-exit:
- pthread_mutex_unlock(&out->lock);
- ALOGV("total_bytes_consumed %d",total_bytes_consumed);
- return total_bytes_consumed;
-}
-
-static int out_get_render_position(const struct audio_stream_out *stream,
- uint32_t *dsp_frames)
-{
- struct listnode *node;
- struct alsa_handle *handle;
- struct stream_out *out = (struct stream_out *)stream;
- struct audio_device *adev = out->dev;
- *dsp_frames = 0;
- ALOGV("%s", __func__);
- pthread_mutex_lock(&out->lock);
- if ((out->uc_strm_type == OFFLOAD_PLAYBACK_STREAM) && (dsp_frames != NULL)) {
- list_for_each(node, &out->session_list) {
- handle = node_to_item(node, struct alsa_handle, list);
- if ((handle && handle->compr &&
- handle->route_format != ROUTE_DSP_TRANSCODED_COMPRESSED)){
- compress_get_tstamp(handle->compr, (unsigned long *)dsp_frames,
- &out->sample_rate);
- ALOGV("%s rendered frames %d sample_rate %d",
- __func__, *dsp_frames, out->sample_rate);
- }
- pthread_mutex_unlock(&out->lock);
- return 0;
- }
- }
- else {
- pthread_mutex_unlock(&out->lock);
- return -EINVAL;
- }
- return 0;
-#if 0
- struct stream_out *out = (struct stream_out *)stream;
- *dsp_frames = 0;
- if ((out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) && (dsp_frames != NULL)) {
- pthread_mutex_lock(&out->lock);
- if (out->compr != NULL) {
- compress_get_tstamp(out->compr, (unsigned long *)dsp_frames,
- &out->sample_rate);
- ALOGVV("%s rendered frames %d sample_rate %d",
- __func__, *dsp_frames, out->sample_rate);
- }
- pthread_mutex_unlock(&out->lock);
- return 0;
- } else
- return -EINVAL;
-#endif
-}
-
-static int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
-{
- return 0;
-}
-
-static int out_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
-{
- return 0;
-}
-
-static int out_get_next_write_timestamp(const struct audio_stream_out *stream,
- int64_t *timestamp)
-{
- return -EINVAL;
-}
-
-static int out_get_presentation_position(const struct audio_stream_out *stream,
- uint64_t *frames, struct timespec *timestamp)
-{
- struct listnode *node;
- struct alsa_handle *handle;
- struct stream_out *out = (struct stream_out *)stream;
- struct audio_device *adev = out->dev;
- *frames = 0;
- ALOGV("%s", __func__);
- pthread_mutex_lock(&out->lock);
- if ((frames != NULL)) {
- list_for_each(node, &out->session_list) {
- handle = node_to_item(node, struct alsa_handle, list);
- if ((handle && handle->compr &&
- handle->route_format != ROUTE_DSP_TRANSCODED_COMPRESSED)){
- compress_get_tstamp(handle->compr, (unsigned long *)frames,
- &out->sample_rate);
- clock_gettime(CLOCK_MONOTONIC, timestamp);
- ALOGV("%s rendered frames %d sample_rate %d",
- __func__, *frames, out->sample_rate);
- }
- else if (handle->pcm) {
- size_t avail;
- if (pcm_get_htimestamp(handle->pcm, &avail, timestamp) == 0) {
- size_t kernel_buffer_size = handle->config.period_size * handle->config.period_count;
- int64_t signed_frames = out->written - kernel_buffer_size + avail;
- // This adjustment accounts for buffering after app processor.
- // It is based on estimated DSP latency per use case, rather than exact.
- signed_frames -=
- (platform_render_latency(handle->usecase) * out->sample_rate / 1000000LL);
-
- // It would be unusual for this value to be negative, but check just in case ...
- if (signed_frames >= 0) {
- *frames = signed_frames;
- }
- }
- }
-
- }
- }
- pthread_mutex_unlock(&out->lock);
- return -EINVAL;
-#if 0
- struct stream_out *out = (struct stream_out *)stream;
- int ret = -1;
- unsigned long dsp_frames;
-
- pthread_mutex_lock(&out->lock);
-
- if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
- if (out->compr != NULL) {
- compress_get_tstamp(out->compr, &dsp_frames,
- &out->sample_rate);
- ALOGVV("%s rendered frames %ld sample_rate %d",
- __func__, dsp_frames, out->sample_rate);
- *frames = dsp_frames;
- ret = 0;
- /* this is the best we can do */
- clock_gettime(CLOCK_MONOTONIC, timestamp);
- }
- } else {
- if (out->pcm) {
- size_t avail;
- if (pcm_get_htimestamp(out->pcm, &avail, timestamp) == 0) {
- size_t kernel_buffer_size = out->config.period_size * out->config.period_count;
- int64_t signed_frames = out->written - kernel_buffer_size + avail;
- // This adjustment accounts for buffering after app processor.
- // It is based on estimated DSP latency per use case, rather than exact.
- signed_frames -=
- (platform_render_latency(out->usecase) * out->sample_rate / 1000000LL);
-
- // It would be unusual for this value to be negative, but check just in case ...
- if (signed_frames >= 0) {
- *frames = signed_frames;
- ret = 0;
- }
- }
- }
- }
-
- pthread_mutex_unlock(&out->lock);
-
- return ret;
-#endif
-}
-
-static int out_set_callback(struct audio_stream_out *stream,
- stream_callback_t callback, void *cookie)
-{
- struct stream_out *out = (struct stream_out *)stream;
-
- ALOGV("%s", __func__);
- pthread_mutex_lock(&out->lock);
- out->offload_callback = callback;
- out->offload_cookie = cookie;
- pthread_mutex_unlock(&out->lock);
- return 0;
-}
-
-static int out_pause(struct audio_stream_out* stream)
-{
- struct listnode *node;
- struct alsa_handle *handle;
- struct stream_out *out = (struct stream_out *)stream;
- int status = -ENOSYS;
- ALOGV("%s", __func__);
- pthread_mutex_lock(&out->lock);
- list_for_each(node, &out->session_list) {
- handle = node_to_item(node, struct alsa_handle, list);
- if (handle->compr != NULL && out->offload_state ==
- OFFLOAD_STATE_PLAYING) {
- status = compress_pause(handle->compr);
- out->offload_state = OFFLOAD_STATE_PAUSED;
- }
- }
- pthread_mutex_unlock(&out->lock);
- return status;
-}
-
-static int out_resume(struct audio_stream_out* stream)
-{
- struct listnode *node;
- struct alsa_handle *handle;
- struct stream_out *out = (struct stream_out *)stream;
- int status = -ENOSYS;
- ALOGV("%s", __func__);
- pthread_mutex_lock(&out->lock);
- list_for_each(node, &out->session_list) {
- handle = node_to_item(node, struct alsa_handle, list);
- status = 0;
- if (handle->compr != NULL && out->offload_state ==
- OFFLOAD_STATE_PAUSED) {
- status = compress_resume(handle->compr);
- out->offload_state = OFFLOAD_STATE_PLAYING;
- }
- }
- pthread_mutex_unlock(&out->lock);
- return status;
-}
-
-static int out_drain(struct audio_stream_out* stream, audio_drain_type_t type )
-{
- struct listnode *node;
- struct alsa_handle *handle;
- struct stream_out *out = (struct stream_out *)stream;
- int status = -ENOSYS;
- ALOGV("%s", __func__);
- pthread_mutex_lock(&out->lock);
- list_for_each(node, &out->session_list) {
- handle = node_to_item(node, struct alsa_handle, list);
- status = 0;
- if (handle->compr != NULL) {
- if (type == AUDIO_DRAIN_EARLY_NOTIFY)
- status = send_offload_cmd_l(out, OFFLOAD_CMD_PARTIAL_DRAIN);
- else
- status = send_offload_cmd_l(out, OFFLOAD_CMD_DRAIN);
- }
- }
- pthread_mutex_unlock(&out->lock);
- return status;
-}
-
-static int out_flush(struct audio_stream_out* stream)
-{
- struct listnode *node;
- struct alsa_handle *handle;
- struct stream_out *out = (struct stream_out *)stream;
- int status = -ENOSYS;
- ALOGV("%s", __func__);
- pthread_mutex_lock(&out->lock);
- list_for_each(node, &out->session_list) {
- handle = node_to_item(node, struct alsa_handle, list);
- status = 0;
- if (handle->compr != NULL) {
- stop_compressed_output_l(out);
- }
- }
- pthread_mutex_unlock(&out->lock);
- return status;
-}
-
-int adev_open_output_stream(struct audio_hw_device *dev,
- audio_io_handle_t handle,
- audio_devices_t devices,
- audio_output_flags_t flags,
- struct audio_config *config,
- struct audio_stream_out **stream_out)
-{
- struct audio_device *adev = (struct audio_device *)dev;
- struct stream_out *out;
- struct alsa_handle *device_handle = NULL;
- int i, ret, channels;
- struct listnode *item;
-
- ALOGV("%s: enter: sample_rate(%d) channel_mask(%#x) devices(%#x) flags(%#x)",
- __func__, config->sample_rate, config->channel_mask, devices, flags);
- *stream_out = NULL;
- out = (struct stream_out *)calloc(1, sizeof(struct stream_out));
-
- if (devices == AUDIO_DEVICE_NONE)
- devices = AUDIO_DEVICE_OUT_SPEAKER;
- list_init(&out->session_list);
-
- reset_out_parameters(out);
- out->flags = flags;
- out->devices = devices;
- out->dev = adev;
- out->format = config->format;
- out->sample_rate = config->sample_rate;
- out->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
- out->supported_channel_masks[0] = AUDIO_CHANNEL_OUT_STEREO;
- out->config = config;
- out->handle = handle;
-
-//*TODO: get hdmi/spdif format/channels from routing manager and intialize out->spdif_format & out->hdmi_format*/
- /* Init use case and pcm_config */
- out->hdmi_format = UNCOMPRESSED;
- out->spdif_format = UNCOMPRESSED;
- out->stream.common.get_sample_rate = out_get_sample_rate;
- out->stream.common.set_sample_rate = out_set_sample_rate;
- out->stream.common.get_buffer_size = out_get_buffer_size;
- out->stream.common.get_channels = out_get_channels;
- out->stream.common.get_format = out_get_format;
- out->stream.common.set_format = out_set_format;
- out->stream.common.standby = out_standby;
- out->stream.common.dump = out_dump;
- out->stream.common.set_parameters = out_set_parameters;
- out->stream.common.get_parameters = out_get_parameters;
- out->stream.common.add_audio_effect = out_add_audio_effect;
- out->stream.common.remove_audio_effect = out_remove_audio_effect;
- out->stream.get_latency = out_get_latency;
- out->stream.set_volume = out_set_volume;
- out->stream.write = out_write;
- out->stream.get_render_position = out_get_render_position;
- out->stream.get_next_write_timestamp = out_get_next_write_timestamp;
- out->stream.get_presentation_position = out_get_presentation_position;
-
- out->standby = 1;
- /* out->muted = false; by calloc() */
- /* out->written = 0; by calloc() */
-
- pthread_mutex_init(&out->lock, (const pthread_mutexattr_t *) NULL);
- pthread_cond_init(&out->cond, (const pthread_condattr_t *) NULL);
-
- if (out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {
- ALOGE("%s: Usecase is OFFLOAD", __func__);
- if (config->offload_info.version != AUDIO_INFO_INITIALIZER.version ||
- config->offload_info.size != AUDIO_INFO_INITIALIZER.size) {
- ALOGE("%s: Unsupported Offload information", __func__);
- ret = -EINVAL;
- goto error_open;
- }
-
- if (!is_supported_format(config->offload_info.format)) {
- ALOGE("%s: Unsupported audio format", __func__);
- ret = -EINVAL;
- goto error_open;
- }
- out->compr_config.codec = (struct snd_codec *)
- calloc(1, sizeof(struct snd_codec));
- //Session/clip config.
- out->format = config->offload_info.format;
- out->sample_rate = config->offload_info.sample_rate;
- out->compr_config.codec->id =
- get_snd_codec_id(config->offload_info.format);
- out->compr_config.fragment_size = COMPRESS_OFFLOAD_FRAGMENT_SIZE;
- out->compr_config.fragments = COMPRESS_OFFLOAD_NUM_FRAGMENTS;
- out->compr_config.codec->sample_rate =
- compress_get_alsa_rate(config->offload_info.sample_rate);
- out->compr_config.codec->bit_rate =
- config->offload_info.bit_rate;
- out->compr_config.codec->ch_in =
- popcount(config->channel_mask);
- out->compr_config.codec->ch_out = out->compr_config.codec->ch_in;
-
- if (config->offload_info.channel_mask)
- out->channel_mask = config->offload_info.channel_mask;
- else if (config->channel_mask)
- out->channel_mask = config->channel_mask;
- out->uc_strm_type = OFFLOAD_PLAYBACK_STREAM;
-
- //Initialize the handles
- /* ------------------------------------------------------------------------
- Update use decoder type and routing flags and corresponding states
- decoderType will cache the decode types such as decode/passthrough/transcode
- and in s/w or dsp. Besides, the states to open decode/passthrough/transcode
- handles with the corresponding devices and device formats are updated
- -------------------------------------------------------------------------*/
- update_decode_type_and_routing_states(out);
-
- /* ------------------------------------------------------------------------
- Update rxHandle states
- Based on the states, we open the driver and store the handle at appropriate
- index
- -------------------------------------------------------------------------*/
- update_alsa_handle_state(out);
-
- /* ------------------------------------------------------------------------
- setup routing
- -------------------------------------------------------------------------*/
- ret = allocate_internal_buffers(out);
- if(ret < 0) {
- ALOGE("%s:Error %d",__func__, ret);
- goto error_handle;
- }
-
- //Callbacks
- out->stream.set_callback = out_set_callback;
- out->stream.pause = out_pause;
- out->stream.resume = out_resume;
- out->stream.drain = out_drain;
- out->stream.flush = out_flush;
-
- if (flags & AUDIO_OUTPUT_FLAG_NON_BLOCKING)
- out->non_blocking = 1;
-
- out->send_new_metadata = 1;
- create_offload_callback_thread(out);
- ALOGV("%s: offloaded output offload_info version %04x bit rate %d",
- __func__, config->offload_info.version,
- config->offload_info.bit_rate);
- } else { //if (out->flags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER) {
- ALOGE("%s: Usecase is DEEP_BUFFER", __func__);
- if((device_handle = get_alsa_handle())== NULL)
- goto error_handle;
- list_add_tail(&out->session_list, &device_handle->list);
- device_handle->usecase = USECASE_AUDIO_PLAYBACK_DEEP_BUFFER;
- device_handle->config = pcm_config_deep_buffer;
- device_handle->out = out;
- device_handle->cmd_pending = false;
- out->sample_rate = device_handle->config.rate;
- out->uc_strm_type = DEEP_BUFFER_PLAYBACK_STREAM;
- out->buffer_size = device_handle->config.period_size *
- audio_stream_frame_size(&out->stream.common);
- }/* else {
- if((device_handle = get_alsa_handle())== NULL)
- goto error_handle;
- list_add_tail(&out->session_list, &device_handle->list);
- device_handle->usecase = USECASE_AUDIO_PLAYBACK_LOW_LATENCY;
- device_handle->config = pcm_config_low_latency;
- device_handle->sample_rate = device_handle->config.rate;
- device_handle->out = out;
- device_handle->cmd_pending = false;
- out->uc_strm_type = LOW_LATENCY_PLAYBACK_STREAM;
- out->buffer_size = device_handle->config.period_size *
- audio_stream_frame_size(&out->stream.common);
- }*/
-
- if (flags & AUDIO_OUTPUT_FLAG_PRIMARY) {
- ALOGE("%s: Usecase is primary ", __func__);
- if(adev->primary_output == NULL)
- adev->primary_output = out;
- else {
- ALOGE("%s: Primary output is already opened", __func__);
- ret = -EEXIST;
- goto error_open;
- }
- }
-
- /* Check if this usecase is already existing */
- pthread_mutex_lock(&adev->lock);
- if (out->uc_strm_type != OFFLOAD_PLAYBACK_STREAM) {
- if (get_usecase_from_list(adev, device_handle->usecase) != NULL) {
- ALOGE("%s: Usecase (%d) is already present", __func__,
- device_handle->usecase);
- pthread_mutex_unlock(&adev->lock);
- ret = -EEXIST;
- goto error_open;
- }
- }
- pthread_mutex_unlock(&adev->lock);
-
-
- /* out->muted = false; by calloc() */
-
-
- config->format = out->stream.common.get_format(&out->stream.common);
- config->channel_mask = out->stream.common.get_channels(&out->stream.common);
- config->sample_rate = out->stream.common.get_sample_rate(&out->stream.common);
-
- *stream_out = &out->stream;
- ALOGV("%s: exit", __func__);
- return 0;
-
-error_handle:
- ret = -EINVAL;
- ALOGE("%s: exit: error handle %d", __func__, ret);
- while (!list_empty(&out->session_list)) {
- item = list_head(&out->session_list);
- list_remove(item);
- device_handle = node_to_item(item, struct alsa_handle, list);
- platform_free_usecase(device_handle->usecase);
- free_alsa_handle(device_handle);
- }
-
-error_open:
- free(out);
- *stream_out = NULL;
- ALOGD("%s: exit: ret %d", __func__, ret);
- return ret;
-}
-
-void adev_close_output_stream(struct audio_hw_device *dev,
- struct audio_stream_out *stream)
-{
- struct stream_out *out = (struct stream_out *)stream;
- struct audio_device *adev = out->dev;
- struct listnode *item;
- struct alsa_handle *handle;
-
- ALOGV("%s", __func__);
-
- out_standby(&stream->common);
- if (out->uc_strm_type == OFFLOAD_PLAYBACK_STREAM) {
- destroy_offload_callback_thread(out);
-
- while (!list_empty(&out->session_list)) {
- item = list_head(&out->session_list);
- list_remove(item);
- handle = node_to_item(item, struct alsa_handle, list);
- if(handle->compr_config.codec != NULL)
- free(handle->compr_config.codec);
- platform_free_usecase(handle->usecase);
- free_alsa_handle(handle);
- }
- free(out->compr_config.codec);
- }
-
- free_internal_buffers(out);
- pthread_cond_destroy(&out->cond);
- pthread_mutex_destroy(&out->lock);
- free(stream);
- ALOGV("%s: exit", __func__);
-}
diff --git a/hal_mpq/mpq8092/hw_info.c b/hal_mpq/mpq8092/hw_info.c
deleted file mode 100644
index 2a0231f..0000000
--- a/hal_mpq/mpq8092/hw_info.c
+++ /dev/null
@@ -1,325 +0,0 @@
-/*
- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- * * Neither the name of The Linux Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#define LOG_TAG "hardware_info"
-/*#define LOG_NDEBUG 0*/
-#define LOG_NDDEBUG 0
-
-#include <stdlib.h>
-#include <dlfcn.h>
-#include <cutils/log.h>
-#include <cutils/str_parms.h>
-#include "audio_hw.h"
-#include "platform.h"
-#include "platform_api.h"
-
-
-struct hardware_info {
- char name[HW_INFO_ARRAY_MAX_SIZE];
- char type[HW_INFO_ARRAY_MAX_SIZE];
- /* variables for handling target variants */
- uint32_t num_snd_devices;
- char dev_extn[HW_INFO_ARRAY_MAX_SIZE];
- snd_device_t *snd_devices;
-};
-
-#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
-
-#define LITERAL_TO_STRING(x) #x
-#define CHECK(condition) LOG_ALWAYS_FATAL_IF(!(condition), "%s",\
- __FILE__ ":" LITERAL_TO_STRING(__LINE__)\
- " ASSERT_FATAL(" #condition ") failed.")
-
-static const snd_device_t tabla_cdp_variant_devices[] = {
- SND_DEVICE_OUT_SPEAKER,
- SND_DEVICE_OUT_HEADPHONES,
- SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES,
-};
-
-static const snd_device_t taiko_fluid_variant_devices[] = {
- SND_DEVICE_OUT_SPEAKER,
- SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES,
- SND_DEVICE_OUT_SPEAKER_AND_ANC_HEADSET,
-};
-
-static const snd_device_t taiko_CDP_variant_devices[] = {
- SND_DEVICE_OUT_SPEAKER,
- SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES,
- SND_DEVICE_OUT_SPEAKER_AND_ANC_HEADSET,
- SND_DEVICE_IN_QUAD_MIC,
-};
-
-static const snd_device_t taiko_liquid_variant_devices[] = {
- SND_DEVICE_OUT_SPEAKER,
- SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES,
- SND_DEVICE_OUT_SPEAKER_AND_ANC_HEADSET,
- SND_DEVICE_IN_SPEAKER_MIC,
- SND_DEVICE_IN_HEADSET_MIC,
- SND_DEVICE_IN_VOICE_DMIC,
- SND_DEVICE_IN_VOICE_SPEAKER_DMIC,
- SND_DEVICE_IN_VOICE_REC_DMIC_STEREO,
- SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE,
- SND_DEVICE_IN_QUAD_MIC,
- SND_DEVICE_IN_HANDSET_STEREO_DMIC,
- SND_DEVICE_IN_SPEAKER_STEREO_DMIC,
-};
-
-static const snd_device_t taiko_DB_variant_devices[] = {
- SND_DEVICE_OUT_SPEAKER,
- SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES,
- SND_DEVICE_OUT_SPEAKER_AND_ANC_HEADSET,
- SND_DEVICE_IN_SPEAKER_MIC,
- SND_DEVICE_IN_HEADSET_MIC,
- SND_DEVICE_IN_QUAD_MIC,
-};
-
-static const snd_device_t tapan_lite_variant_devices[] = {
- SND_DEVICE_OUT_SPEAKER,
- SND_DEVICE_OUT_HEADPHONES,
- SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES,
- SND_DEVICE_OUT_VOICE_HEADPHONES,
- SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES,
- SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES,
-};
-
-static const snd_device_t tapan_skuf_variant_devices[] = {
- SND_DEVICE_OUT_SPEAKER,
- SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES,
- SND_DEVICE_OUT_SPEAKER_AND_ANC_HEADSET,
- /*SND_DEVICE_OUT_SPEAKER_AND_ANC_FB_HEADSET,*/
-};
-
-static const snd_device_t tapan_lite_skuf_variant_devices[] = {
- SND_DEVICE_OUT_SPEAKER,
- SND_DEVICE_OUT_HEADPHONES,
- SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES,
- SND_DEVICE_OUT_VOICE_HEADPHONES,
- SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES,
- SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES,
-};
-
-static const snd_device_t helicon_skuab_variant_devices[] = {
- SND_DEVICE_OUT_SPEAKER,
- SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES,
- SND_DEVICE_OUT_SPEAKER_AND_ANC_HEADSET,
-};
-
-static void update_hardware_info_8092(struct hardware_info *hw_info, const char *snd_card_name)
-{
- if (!strcmp(snd_card_name, "mpq8092-tabla-cdp-snd-card")) {
- strlcpy(hw_info->type, "cdp", sizeof(hw_info->type));
- strlcpy(hw_info->name, "mpq8092", sizeof(hw_info->name));
- hw_info->snd_devices = NULL;
- hw_info->num_snd_devices = 0;
- strlcpy(hw_info->dev_extn, "", sizeof(hw_info->dev_extn));
- } else {
- ALOGW("%s: Not an 8084 device", __func__);
- }
-}
-
-static void update_hardware_info_8084(struct hardware_info *hw_info, const char *snd_card_name)
-{
- if (!strcmp(snd_card_name, "apq8084-taiko-mtp-snd-card")) {
- strlcpy(hw_info->type, "mtp", sizeof(hw_info->type));
- strlcpy(hw_info->name, "apq8084", sizeof(hw_info->name));
- hw_info->snd_devices = NULL;
- hw_info->num_snd_devices = 0;
- strlcpy(hw_info->dev_extn, "", sizeof(hw_info->dev_extn));
- } else if (!strcmp(snd_card_name, "apq8084-taiko-cdp-snd-card")) {
- strlcpy(hw_info->type, " cdp", sizeof(hw_info->type));
- strlcpy(hw_info->name, "apq8084", sizeof(hw_info->name));
- hw_info->snd_devices = (snd_device_t *)taiko_CDP_variant_devices;
- hw_info->num_snd_devices = ARRAY_SIZE(taiko_CDP_variant_devices);
- strlcpy(hw_info->dev_extn, "", sizeof(hw_info->dev_extn));
- } else if (!strcmp(snd_card_name, "apq8084-taiko-liquid-snd-card")) {
- strlcpy(hw_info->type , " liquid", sizeof(hw_info->type));
- strlcpy(hw_info->name, "apq8084", sizeof(hw_info->type));
- hw_info->snd_devices = (snd_device_t *)taiko_liquid_variant_devices;
- hw_info->num_snd_devices = ARRAY_SIZE(taiko_liquid_variant_devices);
- strlcpy(hw_info->dev_extn, "", sizeof(hw_info->dev_extn));
- } else {
- ALOGW("%s: Not an 8084 device", __func__);
- }
-}
-
-static void update_hardware_info_8974(struct hardware_info *hw_info, const char *snd_card_name)
-{
- if (!strcmp(snd_card_name, "msm8974-taiko-mtp-snd-card")) {
- strlcpy(hw_info->type, " mtp", sizeof(hw_info->type));
- strlcpy(hw_info->name, "msm8974", sizeof(hw_info->name));
- hw_info->snd_devices = NULL;
- hw_info->num_snd_devices = 0;
- strlcpy(hw_info->dev_extn, "", sizeof(hw_info->dev_extn));
- } else if (!strcmp(snd_card_name, "msm8974-taiko-cdp-snd-card")) {
- strlcpy(hw_info->type, " cdp", sizeof(hw_info->type));
- strlcpy(hw_info->name, "msm8974", sizeof(hw_info->name));
- hw_info->snd_devices = (snd_device_t *)taiko_CDP_variant_devices;
- hw_info->num_snd_devices = ARRAY_SIZE(taiko_CDP_variant_devices);
- strlcpy(hw_info->dev_extn, "-cdp", sizeof(hw_info->dev_extn));
- } else if (!strcmp(snd_card_name, "msm8974-taiko-fluid-snd-card")) {
- strlcpy(hw_info->type, " fluid", sizeof(hw_info->type));
- strlcpy(hw_info->name, "msm8974", sizeof(hw_info->name));
- hw_info->snd_devices = (snd_device_t *) taiko_fluid_variant_devices;
- hw_info->num_snd_devices = ARRAY_SIZE(taiko_fluid_variant_devices);
- strlcpy(hw_info->dev_extn, "-fluid", sizeof(hw_info->dev_extn));
- } else if (!strcmp(snd_card_name, "msm8974-taiko-liquid-snd-card")) {
- strlcpy(hw_info->type, " liquid", sizeof(hw_info->type));
- strlcpy(hw_info->name, "msm8974", sizeof(hw_info->name));
- hw_info->snd_devices = (snd_device_t *)taiko_liquid_variant_devices;
- hw_info->num_snd_devices = ARRAY_SIZE(taiko_liquid_variant_devices);
- strlcpy(hw_info->dev_extn, "-liquid", sizeof(hw_info->dev_extn));
- } else if (!strcmp(snd_card_name, "apq8074-taiko-db-snd-card")) {
- strlcpy(hw_info->type, " dragon-board", sizeof(hw_info->type));
- strlcpy(hw_info->name, "msm8974", sizeof(hw_info->name));
- hw_info->snd_devices = (snd_device_t *)taiko_DB_variant_devices;
- hw_info->num_snd_devices = ARRAY_SIZE(taiko_DB_variant_devices);
- strlcpy(hw_info->dev_extn, "-DB", sizeof(hw_info->dev_extn));
- } else {
- ALOGW("%s: Not an 8974 device", __func__);
- }
-}
-
-static void update_hardware_info_8610(struct hardware_info *hw_info, const char *snd_card_name)
-{
- if (!strcmp(snd_card_name, "msm8x10-snd-card")) {
- strlcpy(hw_info->type, "", sizeof(hw_info->type));
- strlcpy(hw_info->name, "msm8x10", sizeof(hw_info->name));
- hw_info->snd_devices = NULL;
- hw_info->num_snd_devices = 0;
- strlcpy(hw_info->dev_extn, "", sizeof(hw_info->dev_extn));
- } else if (!strcmp(snd_card_name, "msm8x10-skuab-snd-card")) {
- strlcpy(hw_info->type, "skuab", sizeof(hw_info->type));
- strlcpy(hw_info->name, "msm8x10", sizeof(hw_info->name));
- hw_info->snd_devices = (snd_device_t *)helicon_skuab_variant_devices;
- hw_info->num_snd_devices = ARRAY_SIZE(helicon_skuab_variant_devices);
- strlcpy(hw_info->dev_extn, "-skuab", sizeof(hw_info->dev_extn));
- } else if (!strcmp(snd_card_name, "msm8x10-skuaa-snd-card")) {
- strlcpy(hw_info->type, " skuaa", sizeof(hw_info->type));
- strlcpy(hw_info->name, "msm8x10", sizeof(hw_info->name));
- hw_info->snd_devices = NULL;
- hw_info->num_snd_devices = 0;
- strlcpy(hw_info->dev_extn, "", sizeof(hw_info->dev_extn));
- } else {
- ALOGW("%s: Not an 8x10 device", __func__);
- }
-}
-
-static void update_hardware_info_8226(struct hardware_info *hw_info, const char *snd_card_name)
-{
- if (!strcmp(snd_card_name, "msm8226-tapan-snd-card")) {
- strlcpy(hw_info->type, "", sizeof(hw_info->type));
- strlcpy(hw_info->name, "msm8226", sizeof(hw_info->name));
- hw_info->snd_devices = NULL;
- hw_info->num_snd_devices = 0;
- strlcpy(hw_info->dev_extn, "", sizeof(hw_info->dev_extn));
- } else if (!strcmp(snd_card_name, "msm8226-tapan9302-snd-card")) {
- strlcpy(hw_info->type, "tapan_lite", sizeof(hw_info->type));
- strlcpy(hw_info->name, "msm8226", sizeof(hw_info->name));
- hw_info->snd_devices = (snd_device_t *)tapan_lite_variant_devices;
- hw_info->num_snd_devices = ARRAY_SIZE(tapan_lite_variant_devices);
- strlcpy(hw_info->dev_extn, "-lite", sizeof(hw_info->dev_extn));
- } else if (!strcmp(snd_card_name, "msm8226-tapan-skuf-snd-card")) {
- strlcpy(hw_info->type, " skuf", sizeof(hw_info->type));
- strlcpy(hw_info->name, "msm8226", sizeof(hw_info->name));
- hw_info->snd_devices = (snd_device_t *) tapan_skuf_variant_devices;
- hw_info->num_snd_devices = ARRAY_SIZE(tapan_skuf_variant_devices);
- strlcpy(hw_info->dev_extn, "-skuf", sizeof(hw_info->dev_extn));
- } else if (!strcmp(snd_card_name, "msm8226-tapan9302-skuf-snd-card")) {
- strlcpy(hw_info->type, " tapan9302-skuf", sizeof(hw_info->type));
- strlcpy(hw_info->name, "msm8226", sizeof(hw_info->name));
- hw_info->snd_devices = (snd_device_t *)tapan_lite_skuf_variant_devices;
- hw_info->num_snd_devices = ARRAY_SIZE(tapan_lite_skuf_variant_devices);
- strlcpy(hw_info->dev_extn, "-skuf-lite", sizeof(hw_info->dev_extn));
- } else {
- ALOGW("%s: Not an 8x26 device", __func__);
- }
-}
-
-void *hw_info_init(const char *snd_card_name)
-{
- struct hardware_info *hw_info;
-
- hw_info = malloc(sizeof(struct hardware_info));
-
- if(strstr(snd_card_name, "mpq8092") ||
- strstr(snd_card_name, "mpq8092")) {
- ALOGV("8092 - variant soundcard");
- update_hardware_info_8092(hw_info, snd_card_name);
- } else if(strstr(snd_card_name, "msm8974") ||
- strstr(snd_card_name, "apq8074")) {
- ALOGV("8974 - variant soundcard");
- update_hardware_info_8974(hw_info, snd_card_name);
- } else if(strstr(snd_card_name, "msm8226")) {
- ALOGV("8x26 - variant soundcard");
- update_hardware_info_8226(hw_info, snd_card_name);
- } else if(strstr(snd_card_name, "msm8x10")) {
- ALOGV("8x10 - variant soundcard");
- update_hardware_info_8610(hw_info, snd_card_name);
- } else if(strstr(snd_card_name, "apq8084")) {
- ALOGV("8084 - variant soundcard");
- update_hardware_info_8084(hw_info, snd_card_name);
- } else {
- ALOGE("%s: Unsupported target %s:",__func__, snd_card_name);
- free(hw_info);
- hw_info = NULL;
- }
-
- return hw_info;
-}
-
-void hw_info_deinit(void *hw_info)
-{
- struct hardware_info *my_data = (struct hardware_info*) hw_info;
-
- if(!my_data)
- free(my_data);
-}
-
-void hw_info_append_hw_type(void *hw_info, snd_device_t snd_device,
- char *device_name)
-{
- struct hardware_info *my_data = (struct hardware_info*) hw_info;
- uint32_t i = 0;
-
- snd_device_t *snd_devices =
- (snd_device_t *) my_data->snd_devices;
-
- if(snd_devices != NULL) {
- for (i = 0; i < my_data->num_snd_devices; i++) {
- if (snd_device == (snd_device_t)snd_devices[i]) {
- ALOGV("extract dev_extn device %d, extn = %s",
- (snd_device_t)snd_devices[i], my_data->dev_extn);
- CHECK(strlcat(device_name, my_data->dev_extn,
- DEVICE_NAME_MAX_SIZE) < DEVICE_NAME_MAX_SIZE);
- break;
- }
- }
- }
- ALOGD("%s : device_name = %s", __func__,device_name);
-}
diff --git a/hal_mpq/mpq8092/platform.c b/hal_mpq/mpq8092/platform.c
deleted file mode 100644
index 6c50034..0000000
--- a/hal_mpq/mpq8092/platform.c
+++ /dev/null
@@ -1,1325 +0,0 @@
-/*
- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
- * Not a Contribution.
- *
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "msm8974_platform"
-/*#define LOG_NDEBUG 0*/
-#define LOG_NDDEBUG 0
-
-#include <stdlib.h>
-#include <dlfcn.h>
-#include <cutils/log.h>
-#include <cutils/properties.h>
-#include <cutils/str_parms.h>
-#include <audio_hw.h>
-#include <platform_api.h>
-#include "platform.h"
-
-#define MIXER_XML_PATH "/system/etc/mixer_paths.xml"
-#define MIXER_XML_PATH_AUXPCM "/system/etc/mixer_paths_auxpcm.xml"
-#define LIB_ACDB_LOADER "libacdbloader.so"
-#define AUDIO_DATA_BLOCK_MIXER_CTL "HDMI EDID"
-
-/*
- * This file will have a maximum of 38 bytes:
- *
- * 4 bytes: number of audio blocks
- * 4 bytes: total length of Short Audio Descriptor (SAD) blocks
- * Maximum 10 * 3 bytes: SAD blocks
- */
-#define MAX_SAD_BLOCKS 10
-#define SAD_BLOCK_SIZE 3
-
-/* EDID format ID for LPCM audio */
-#define EDID_FORMAT_LPCM 1
-
-/* Retry for delay in FW loading*/
-#define RETRY_NUMBER 10
-#define RETRY_US 500000
-
-#define SAMPLE_RATE_8KHZ 8000
-#define SAMPLE_RATE_16KHZ 16000
-
-#define AUDIO_PARAMETER_KEY_FLUENCE_TYPE "fluence"
-#define AUDIO_PARAMETER_KEY_BTSCO "bt_samplerate"
-#define AUDIO_PARAMETER_KEY_SLOWTALK "st_enable"
-
-struct audio_block_header
-{
- int reserved;
- int length;
-};
-
-/* Audio calibration related functions */
-typedef void (*acdb_deallocate_t)();
-typedef int (*acdb_init_t)();
-typedef void (*acdb_send_audio_cal_t)(int, int);
-typedef void (*acdb_send_voice_cal_t)(int, int);
-
-struct platform_data {
- struct audio_device *adev;
- bool fluence_in_spkr_mode;
- bool fluence_in_voice_call;
- bool fluence_in_voice_rec;
- bool fluence_in_audio_rec;
- int fluence_type;
- int btsco_sample_rate;
- bool slowtalk;
- /* Audio calibration related functions */
- void *acdb_handle;
- acdb_init_t acdb_init;
- acdb_deallocate_t acdb_deallocate;
- acdb_send_audio_cal_t acdb_send_audio_cal;
- acdb_send_voice_cal_t acdb_send_voice_cal;
-
- void *hw_info;
- struct csd_data *csd;
-};
-
-static int pcm_device_table[AUDIO_USECASE_MAX][4] = {
- [USECASE_AUDIO_PLAYBACK_DEEP_BUFFER] = {USECASE_AUDIO_PLAYBACK_DEEP_BUFFER,
- DEEP_BUFFER_PCM_DEVICE,
- DEEP_BUFFER_PCM_DEVICE, 0},
- [USECASE_AUDIO_PLAYBACK_LOW_LATENCY] = {USECASE_AUDIO_PLAYBACK_LOW_LATENCY,
- LOWLATENCY_PCM_DEVICE,
- LOWLATENCY_PCM_DEVICE, 0},
- [USECASE_AUDIO_PLAYBACK_MULTI_CH] = {USECASE_AUDIO_PLAYBACK_MULTI_CH,
- MULTIMEDIA2_PCM_DEVICE,
- MULTIMEDIA2_PCM_DEVICE, 0},
- [USECASE_AUDIO_PLAYBACK_MULTI_CH] = {USECASE_AUDIO_PLAYBACK_MULTI_CH,
- MULTI_CHANNEL_PCM_DEVICE,
- MULTI_CHANNEL_PCM_DEVICE, 0},
- [USECASE_AUDIO_PLAYBACK_OFFLOAD] =
- {USECASE_AUDIO_PLAYBACK_OFFLOAD, PLAYBACK_OFFLOAD_DEVICE1,
- PLAYBACK_OFFLOAD_DEVICE1, 0},
- [USECASE_AUDIO_PLAYBACK_OFFLOAD1] = {USECASE_AUDIO_PLAYBACK_OFFLOAD,
- PLAYBACK_OFFLOAD_DEVICE2,
- PLAYBACK_OFFLOAD_DEVICE2, 0},
- [USECASE_AUDIO_PLAYBACK_OFFLOAD2] = {USECASE_AUDIO_PLAYBACK_OFFLOAD,
- PLAYBACK_OFFLOAD_DEVICE3,
- PLAYBACK_OFFLOAD_DEVICE3, 0},
- [USECASE_AUDIO_PLAYBACK_OFFLOAD3] = {USECASE_AUDIO_PLAYBACK_OFFLOAD,
- PLAYBACK_OFFLOAD_DEVICE4,
- PLAYBACK_OFFLOAD_DEVICE4, 0},
- [USECASE_AUDIO_RECORD] = {USECASE_AUDIO_RECORD, AUDIO_RECORD_PCM_DEVICE,
- AUDIO_RECORD_PCM_DEVICE, 0},
- [USECASE_AUDIO_RECORD_COMPRESS] = {USECASE_AUDIO_RECORD_COMPRESS, COMPRESS_CAPTURE_DEVICE,
- COMPRESS_CAPTURE_DEVICE, 0},
- [USECASE_AUDIO_RECORD_LOW_LATENCY] = {USECASE_AUDIO_RECORD_LOW_LATENCY,
- LOWLATENCY_PCM_DEVICE,
- LOWLATENCY_PCM_DEVICE, 0},
- /* [USECASE_AUDIO_RECORD_FM_VIRTUAL] = {,
- MULTIMEDIA2_PCM_DEVICE},
- [USECASE_AUDIO_PLAYBACK_FM] = {FM_PLAYBACK_PCM_DEVICE, FM_CAPTURE_PCM_DEVICE},
- [USECASE_VOICE_CALL] = {VOICE_CALL_PCM_DEVICE, VOICE_CALL_PCM_DEVICE},
- [USECASE_VOICE2_CALL] = {VOICE2_CALL_PCM_DEVICE, VOICE2_CALL_PCM_DEVICE},
- [USECASE_VOLTE_CALL] = {VOLTE_CALL_PCM_DEVICE, VOLTE_CALL_PCM_DEVICE},
- [USECASE_QCHAT_CALL] = {QCHAT_CALL_PCM_DEVICE, QCHAT_CALL_PCM_DEVICE},
- [USECASE_COMPRESS_VOIP_CALL] = {COMPRESS_VOIP_CALL_PCM_DEVICE, COMPRESS_VOIP_CALL_PCM_DEVICE},
- [USECASE_INCALL_REC_UPLINK] = {AUDIO_RECORD_PCM_DEVICE,
- AUDIO_RECORD_PCM_DEVICE},
- [USECASE_INCALL_REC_DOWNLINK] = {AUDIO_RECORD_PCM_DEVICE,
- AUDIO_RECORD_PCM_DEVICE},
- [USECASE_INCALL_REC_UPLINK_AND_DOWNLINK] = {AUDIO_RECORD_PCM_DEVICE,
- AUDIO_RECORD_PCM_DEVICE},
- [USECASE_INCALL_MUSIC_UPLINK] = {INCALL_MUSIC_UPLINK_PCM_DEVICE,
- INCALL_MUSIC_UPLINK_PCM_DEVICE},
- [USECASE_INCALL_MUSIC_UPLINK2] = {INCALL_MUSIC_UPLINK2_PCM_DEVICE,
- 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},
-*/
-};
-
-/* Array to store sound devices */
-static const char * const device_table[SND_DEVICE_MAX] = {
- [SND_DEVICE_NONE] = "none",
- /* Playback sound devices */
- [SND_DEVICE_OUT_HANDSET] = "handset",
- [SND_DEVICE_OUT_SPEAKER] = "speaker",
- [SND_DEVICE_OUT_SPEAKER_REVERSE] = "speaker-reverse",
- [SND_DEVICE_OUT_HEADPHONES] = "headphones",
- [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = "speaker-and-headphones",
- [SND_DEVICE_OUT_VOICE_HANDSET] = "voice-handset",
- [SND_DEVICE_OUT_VOICE_SPEAKER] = "voice-speaker",
- [SND_DEVICE_OUT_VOICE_HEADPHONES] = "voice-headphones",
- [SND_DEVICE_OUT_HDMI] = "hdmi",
- [SND_DEVICE_OUT_SPEAKER_AND_HDMI] = "speaker-and-hdmi",
- [SND_DEVICE_OUT_BT_SCO] = "bt-sco-headset",
- [SND_DEVICE_OUT_BT_SCO_WB] = "bt-sco-headset-wb",
- [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_AFE_PROXY] = "afe-proxy",
- [SND_DEVICE_OUT_USB_HEADSET] = "usb-headphones",
- [SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET] = "speaker-and-usb-headphones",
- [SND_DEVICE_OUT_TRANSMISSION_FM] = "transmission-fm",
- [SND_DEVICE_OUT_ANC_HEADSET] = "anc-headphones",
- [SND_DEVICE_OUT_ANC_FB_HEADSET] = "anc-fb-headphones",
- [SND_DEVICE_OUT_VOICE_ANC_HEADSET] = "voice-anc-headphones",
- [SND_DEVICE_OUT_VOICE_ANC_FB_HEADSET] = "voice-anc-fb-headphones",
- [SND_DEVICE_OUT_SPEAKER_AND_ANC_HEADSET] = "speaker-and-anc-headphones",
- [SND_DEVICE_OUT_ANC_HANDSET] = "anc-handset",
- [SND_DEVICE_OUT_SPEAKER_PROTECTED] = "speaker-protected",
- [SND_DEVICE_OUT_SPDIF] = "spdif",
-
- /* Capture sound devices */
- [SND_DEVICE_IN_HANDSET_MIC] = "handset-mic",
- [SND_DEVICE_IN_HANDSET_MIC_AEC] = "handset-mic",
- [SND_DEVICE_IN_HANDSET_MIC_NS] = "handset-mic",
- [SND_DEVICE_IN_HANDSET_MIC_AEC_NS] = "handset-mic",
- [SND_DEVICE_IN_HANDSET_DMIC] = "dmic-endfire",
- [SND_DEVICE_IN_HANDSET_DMIC_AEC] = "dmic-endfire",
- [SND_DEVICE_IN_HANDSET_DMIC_NS] = "dmic-endfire",
- [SND_DEVICE_IN_HANDSET_DMIC_AEC_NS] = "dmic-endfire",
- [SND_DEVICE_IN_SPEAKER_MIC] = "speaker-mic",
- [SND_DEVICE_IN_SPEAKER_MIC_AEC] = "speaker-mic",
- [SND_DEVICE_IN_SPEAKER_MIC_NS] = "speaker-mic",
- [SND_DEVICE_IN_SPEAKER_MIC_AEC_NS] = "speaker-mic",
- [SND_DEVICE_IN_SPEAKER_DMIC] = "speaker-dmic-endfire",
- [SND_DEVICE_IN_SPEAKER_DMIC_AEC] = "speaker-dmic-endfire",
- [SND_DEVICE_IN_SPEAKER_DMIC_NS] = "speaker-dmic-endfire",
- [SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS] = "speaker-dmic-endfire",
- [SND_DEVICE_IN_HEADSET_MIC] = "headset-mic",
- [SND_DEVICE_IN_HEADSET_MIC_FLUENCE] = "headset-mic",
- [SND_DEVICE_IN_VOICE_SPEAKER_MIC] = "voice-speaker-mic",
- [SND_DEVICE_IN_VOICE_HEADSET_MIC] = "voice-headset-mic",
- [SND_DEVICE_IN_HDMI_MIC] = "hdmi-mic",
- [SND_DEVICE_IN_BT_SCO_MIC] = "bt-sco-mic",
- [SND_DEVICE_IN_BT_SCO_MIC_WB] = "bt-sco-mic-wb",
- [SND_DEVICE_IN_CAMCORDER_MIC] = "camcorder-mic",
- [SND_DEVICE_IN_VOICE_DMIC] = "voice-dmic-ef",
- [SND_DEVICE_IN_VOICE_SPEAKER_DMIC] = "voice-speaker-dmic-ef",
- [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_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",
- [SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE] = "voice-rec-dmic-ef-fluence",
- [SND_DEVICE_IN_USB_HEADSET_MIC] = "usb-headset-mic",
- [SND_DEVICE_IN_CAPTURE_FM] = "capture-fm",
- [SND_DEVICE_IN_AANC_HANDSET_MIC] = "aanc-handset-mic",
- [SND_DEVICE_IN_QUAD_MIC] = "quad-mic",
- [SND_DEVICE_IN_HANDSET_STEREO_DMIC] = "handset-stereo-dmic-ef",
- [SND_DEVICE_IN_SPEAKER_STEREO_DMIC] = "speaker-stereo-dmic-ef",
- [SND_DEVICE_IN_CAPTURE_VI_FEEDBACK] = "vi-feedback",
-};
-
-/* ACDB IDs (audio DSP path configuration IDs) for each sound device */
-static const int acdb_device_table[SND_DEVICE_MAX] = {
- [SND_DEVICE_NONE] = -1,
- [SND_DEVICE_OUT_HANDSET] = 7,
- [SND_DEVICE_OUT_SPEAKER] = 14,
- [SND_DEVICE_OUT_SPEAKER_REVERSE] = 14,
- [SND_DEVICE_OUT_HEADPHONES] = 10,
- [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = 10,
- [SND_DEVICE_OUT_VOICE_HANDSET] = 7,
- [SND_DEVICE_OUT_VOICE_SPEAKER] = 14,
- [SND_DEVICE_OUT_VOICE_HEADPHONES] = 10,
- [SND_DEVICE_OUT_HDMI] = 18,
- [SND_DEVICE_OUT_SPEAKER_AND_HDMI] = 14,
- [SND_DEVICE_OUT_BT_SCO] = 22,
- [SND_DEVICE_OUT_BT_SCO_WB] = 39,
- [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_AFE_PROXY] = 0,
- [SND_DEVICE_OUT_USB_HEADSET] = 0,
- [SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET] = 14,
- [SND_DEVICE_OUT_TRANSMISSION_FM] = 0,
- [SND_DEVICE_OUT_ANC_HEADSET] = 26,
- [SND_DEVICE_OUT_ANC_FB_HEADSET] = 27,
- [SND_DEVICE_OUT_VOICE_ANC_HEADSET] = 26,
- [SND_DEVICE_OUT_VOICE_ANC_FB_HEADSET] = 27,
- [SND_DEVICE_OUT_SPEAKER_AND_ANC_HEADSET] = 26,
- [SND_DEVICE_OUT_ANC_HANDSET] = 103,
- [SND_DEVICE_OUT_SPEAKER_PROTECTED] = 101,
- [SND_DEVICE_OUT_SPDIF] = 18,
-
- [SND_DEVICE_IN_HANDSET_MIC] = 4,
- [SND_DEVICE_IN_HANDSET_MIC_AEC] = 106,
- [SND_DEVICE_IN_HANDSET_MIC_NS] = 107,
- [SND_DEVICE_IN_HANDSET_MIC_AEC_NS] = 108,
- [SND_DEVICE_IN_HANDSET_DMIC] = 41,
- [SND_DEVICE_IN_HANDSET_DMIC_AEC] = 109,
- [SND_DEVICE_IN_HANDSET_DMIC_NS] = 110,
- [SND_DEVICE_IN_HANDSET_DMIC_AEC_NS] = 111,
- [SND_DEVICE_IN_SPEAKER_MIC] = 11,
- [SND_DEVICE_IN_SPEAKER_MIC_AEC] = 112,
- [SND_DEVICE_IN_SPEAKER_MIC_NS] = 113,
- [SND_DEVICE_IN_SPEAKER_MIC_AEC_NS] = 114,
- [SND_DEVICE_IN_SPEAKER_DMIC] = 43,
- [SND_DEVICE_IN_SPEAKER_DMIC_AEC] = 115,
- [SND_DEVICE_IN_SPEAKER_DMIC_NS] = 116,
- [SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS] = 117,
- [SND_DEVICE_IN_HEADSET_MIC] = 8,
- [SND_DEVICE_IN_HEADSET_MIC_FLUENCE] = 47,
- [SND_DEVICE_IN_VOICE_SPEAKER_MIC] = 11,
- [SND_DEVICE_IN_VOICE_HEADSET_MIC] = 8,
- [SND_DEVICE_IN_HDMI_MIC] = 4,
- [SND_DEVICE_IN_BT_SCO_MIC] = 21,
- [SND_DEVICE_IN_BT_SCO_MIC_WB] = 38,
- [SND_DEVICE_IN_CAMCORDER_MIC] = 4,
- [SND_DEVICE_IN_VOICE_DMIC] = 41,
- [SND_DEVICE_IN_VOICE_SPEAKER_DMIC] = 43,
- [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_REC_MIC] = 4,
- [SND_DEVICE_IN_VOICE_REC_MIC_NS] = 107,
- [SND_DEVICE_IN_VOICE_REC_DMIC_STEREO] = 34,
- [SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE] = 41,
- [SND_DEVICE_IN_USB_HEADSET_MIC] = 44,
- [SND_DEVICE_IN_CAPTURE_FM] = 0,
- [SND_DEVICE_IN_AANC_HANDSET_MIC] = 104,
- [SND_DEVICE_IN_QUAD_MIC] = 46,
- [SND_DEVICE_IN_HANDSET_STEREO_DMIC] = 34,
- [SND_DEVICE_IN_SPEAKER_STEREO_DMIC] = 35,
- [SND_DEVICE_IN_CAPTURE_VI_FEEDBACK] = 102,
-};
-
-#define DEEP_BUFFER_PLATFORM_DELAY (29*1000LL)
-#define LOW_LATENCY_PLATFORM_DELAY (13*1000LL)
-
-static int set_echo_reference(struct mixer *mixer, const char* ec_ref)
-{
- struct mixer_ctl *ctl;
- const char *mixer_ctl_name = "EC_REF_RX";
-
- ctl = mixer_get_ctl_by_name(mixer, mixer_ctl_name);
- if (!ctl) {
- ALOGE("%s: Could not get ctl for mixer cmd - %s",
- __func__, mixer_ctl_name);
- return -EINVAL;
- }
- ALOGV("Setting EC Reference: %s", ec_ref);
- mixer_ctl_set_enum_by_string(ctl, ec_ref);
- return 0;
-}
-
-static struct csd_data *open_csd_client()
-{
- struct csd_data *csd = calloc(1, sizeof(struct csd_data));
-
- csd->csd_client = dlopen(LIB_CSD_CLIENT, RTLD_NOW);
- if (csd->csd_client == NULL) {
- ALOGE("%s: DLOPEN failed for %s", __func__, LIB_CSD_CLIENT);
- goto error;
- } else {
- ALOGV("%s: DLOPEN successful for %s", __func__, LIB_CSD_CLIENT);
-
- csd->deinit = (deinit_t)dlsym(csd->csd_client,
- "csd_client_deinit");
- if (csd->deinit == NULL) {
- ALOGE("%s: dlsym error %s for csd_client_deinit", __func__,
- dlerror());
- goto error;
- }
- csd->disable_device = (disable_device_t)dlsym(csd->csd_client,
- "csd_client_disable_device");
- if (csd->disable_device == NULL) {
- ALOGE("%s: dlsym error %s for csd_client_disable_device",
- __func__, dlerror());
- goto error;
- }
- csd->enable_device = (enable_device_t)dlsym(csd->csd_client,
- "csd_client_enable_device");
- if (csd->enable_device == NULL) {
- ALOGE("%s: dlsym error %s for csd_client_enable_device",
- __func__, dlerror());
- goto error;
- }
- csd->start_voice = (start_voice_t)dlsym(csd->csd_client,
- "csd_client_start_voice");
- if (csd->start_voice == NULL) {
- ALOGE("%s: dlsym error %s for csd_client_start_voice",
- __func__, dlerror());
- goto error;
- }
- csd->stop_voice = (stop_voice_t)dlsym(csd->csd_client,
- "csd_client_stop_voice");
- if (csd->stop_voice == NULL) {
- ALOGE("%s: dlsym error %s for csd_client_stop_voice",
- __func__, dlerror());
- goto error;
- }
- csd->volume = (volume_t)dlsym(csd->csd_client,
- "csd_client_volume");
- if (csd->volume == NULL) {
- ALOGE("%s: dlsym error %s for csd_client_volume",
- __func__, dlerror());
- goto error;
- }
- csd->mic_mute = (mic_mute_t)dlsym(csd->csd_client,
- "csd_client_mic_mute");
- if (csd->mic_mute == NULL) {
- ALOGE("%s: dlsym error %s for csd_client_mic_mute",
- __func__, dlerror());
- goto error;
- }
- csd->slow_talk = (slow_talk_t)dlsym(csd->csd_client,
- "csd_client_slow_talk");
- if (csd->slow_talk == NULL) {
- ALOGE("%s: dlsym error %s for csd_client_slow_talk",
- __func__, dlerror());
- goto error;
- }
- csd->start_playback = (start_playback_t)dlsym(csd->csd_client,
- "csd_client_start_playback");
- if (csd->start_playback == NULL) {
- ALOGE("%s: dlsym error %s for csd_client_start_playback",
- __func__, dlerror());
- goto error;
- }
- csd->stop_playback = (stop_playback_t)dlsym(csd->csd_client,
- "csd_client_stop_playback");
- if (csd->stop_playback == NULL) {
- ALOGE("%s: dlsym error %s for csd_client_stop_playback",
- __func__, dlerror());
- goto error;
- }
- csd->start_record = (start_record_t)dlsym(csd->csd_client,
- "csd_client_start_record");
- if (csd->start_record == NULL) {
- ALOGE("%s: dlsym error %s for csd_client_start_record",
- __func__, dlerror());
- goto error;
- }
- csd->stop_record = (stop_record_t)dlsym(csd->csd_client,
- "csd_client_stop_record");
- if (csd->stop_record == NULL) {
- ALOGE("%s: dlsym error %s for csd_client_stop_record",
- __func__, dlerror());
- goto error;
- }
- csd->init = (init_t)dlsym(csd->csd_client, "csd_client_init");
-
- if (csd->init == NULL) {
- ALOGE("%s: dlsym error %s for csd_client_init",
- __func__, dlerror());
- goto error;
- } else {
- csd->init();
- }
- }
- return csd;
-
-error:
- free(csd);
- csd = NULL;
- return csd;
-}
-
-void close_csd_client(struct csd_data *csd)
-{
- if (csd != NULL) {
- csd->deinit();
- dlclose(csd->csd_client);
- free(csd);
- csd = NULL;
- }
-}
-
-void *platform_init(struct audio_device *adev)
-{
- char platform[PROPERTY_VALUE_MAX];
- char baseband[PROPERTY_VALUE_MAX];
- char value[PROPERTY_VALUE_MAX];
- struct platform_data *my_data;
- int retry_num = 0;
- const char *snd_card_name;
-
- adev->mixer = mixer_open(MIXER_CARD);
-
- while (!adev->mixer && retry_num < RETRY_NUMBER) {
- usleep(RETRY_US);
- adev->mixer = mixer_open(MIXER_CARD);
- retry_num++;
- }
-
- if (!adev->mixer) {
- ALOGE("Unable to open the mixer, aborting.");
- return NULL;
- }
-
- adev->audio_route = audio_route_init(MIXER_CARD, MIXER_XML_PATH);
-
- if (!adev->audio_route) {
- ALOGE("%s: Failed to init audio route controls, aborting.", __func__);
- return NULL;
- }
-
- my_data = calloc(1, sizeof(struct platform_data));
-
- snd_card_name = mixer_get_name(adev->mixer);
- my_data->hw_info = hw_info_init(snd_card_name);
- if (!my_data->hw_info) {
- ALOGE("%s: Failed to init hardware info", __func__);
- }
-
- my_data->adev = adev;
- my_data->btsco_sample_rate = SAMPLE_RATE_8KHZ;
- my_data->fluence_in_spkr_mode = false;
- my_data->fluence_in_voice_call = false;
- my_data->fluence_in_voice_rec = false;
- my_data->fluence_in_audio_rec = false;
- my_data->fluence_type = FLUENCE_NONE;
-
- property_get("ro.qc.sdk.audio.fluencetype", value, "");
- if (!strncmp("fluencepro", value, sizeof("fluencepro"))) {
- my_data->fluence_type = FLUENCE_QUAD_MIC | FLUENCE_DUAL_MIC;
- } else if (!strncmp("fluence", value, sizeof("fluence"))) {
- my_data->fluence_type = FLUENCE_DUAL_MIC;
- } else {
- my_data->fluence_type = FLUENCE_NONE;
- }
-
- if (my_data->fluence_type != FLUENCE_NONE) {
- property_get("persist.audio.fluence.voicecall",value,"");
- if (!strncmp("true", value, sizeof("true"))) {
- my_data->fluence_in_voice_call = true;
- }
-
- property_get("persist.audio.fluence.voicerec",value,"");
- if (!strncmp("true", value, sizeof("true"))) {
- my_data->fluence_in_voice_rec = true;
- }
-
- property_get("persist.audio.fluence.audiorec",value,"");
- if (!strncmp("true", value, sizeof("true"))) {
- my_data->fluence_in_audio_rec = true;
- }
-
- property_get("persist.audio.fluence.speaker",value,"");
- if (!strncmp("true", value, sizeof("true"))) {
- my_data->fluence_in_spkr_mode = true;
- }
- }
-
- my_data->acdb_handle = dlopen(LIB_ACDB_LOADER, RTLD_NOW);
- if (my_data->acdb_handle == NULL) {
- ALOGE("%s: DLOPEN failed for %s", __func__, LIB_ACDB_LOADER);
- } else {
- ALOGV("%s: DLOPEN successful for %s", __func__, LIB_ACDB_LOADER);
- my_data->acdb_deallocate = (acdb_deallocate_t)dlsym(my_data->acdb_handle,
- "acdb_loader_deallocate_ACDB");
- my_data->acdb_send_audio_cal = (acdb_send_audio_cal_t)dlsym(my_data->acdb_handle,
- "acdb_loader_send_audio_cal");
- if (!my_data->acdb_send_audio_cal)
- ALOGW("%s: Could not find the symbol acdb_send_audio_cal from %s",
- __func__, LIB_ACDB_LOADER);
- my_data->acdb_send_voice_cal = (acdb_send_voice_cal_t)dlsym(my_data->acdb_handle,
- "acdb_loader_send_voice_cal");
- my_data->acdb_init = (acdb_init_t)dlsym(my_data->acdb_handle,
- "acdb_loader_init_ACDB");
- if (my_data->acdb_init == NULL)
- ALOGE("%s: dlsym error %s for acdb_loader_init_ACDB", __func__, dlerror());
- else
- my_data->acdb_init();
- }
-
- /* If platform is apq8084 and baseband is MDM, load CSD Client specific
- * symbols. Voice call is handled by MDM and apps processor talks to
- * MDM through CSD Client
- */
- property_get("ro.board.platform", platform, "");
- property_get("ro.baseband", baseband, "");
- if (!strncmp("apq8084", platform, sizeof("apq8084")) &&
- !strncmp("mdm", baseband, sizeof("mdm"))) {
- my_data->csd = open_csd_client();
- }
-
- return my_data;
-}
-
-void platform_deinit(void *platform)
-{
- struct platform_data *my_data = (struct platform_data *)platform;
-
- hw_info_deinit(my_data->hw_info);
- close_csd_client(my_data->csd);
-
- free(platform);
-}
-
-const char *platform_get_snd_device_name(snd_device_t snd_device)
-{
- if (snd_device >= SND_DEVICE_MIN && snd_device < SND_DEVICE_MAX)
- return device_table[snd_device];
- else
- return "";
-}
-
-int platform_get_snd_device_name_extn(void *platform, snd_device_t snd_device,
- char *device_name)
-{
- struct platform_data *my_data = (struct platform_data *)platform;
-
- if (snd_device >= SND_DEVICE_MIN && snd_device < SND_DEVICE_MAX) {
- strlcpy(device_name, device_table[snd_device], DEVICE_NAME_MAX_SIZE);
- hw_info_append_hw_type(my_data->hw_info, snd_device, device_name);
- } else {
- strlcpy(device_name, "", DEVICE_NAME_MAX_SIZE);
- return -EINVAL;
- }
-
- return 0;
-}
-
-void platform_add_backend_name(char *mixer_path, snd_device_t snd_device)
-{
- if (snd_device == SND_DEVICE_IN_BT_SCO_MIC)
- strlcat(mixer_path, " bt-sco", MIXER_PATH_MAX_LENGTH);
- else if (snd_device == SND_DEVICE_IN_BT_SCO_MIC_WB)
- strlcat(mixer_path, " bt-sco-wb", MIXER_PATH_MAX_LENGTH);
- else if(snd_device == SND_DEVICE_OUT_BT_SCO)
- strlcat(mixer_path, " bt-sco", MIXER_PATH_MAX_LENGTH);
- else if(snd_device == SND_DEVICE_OUT_BT_SCO_WB)
- strlcat(mixer_path, " bt-sco-wb", MIXER_PATH_MAX_LENGTH);
- else if (snd_device == SND_DEVICE_OUT_HDMI)
- strlcat(mixer_path, " hdmi", MIXER_PATH_MAX_LENGTH);
- else if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_HDMI)
- strlcat(mixer_path, " speaker-and-hdmi", 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)
- strlcat(mixer_path, " usb-headphones", MIXER_PATH_MAX_LENGTH);
- else if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET)
- strlcat(mixer_path, " speaker-and-usb-headphones",
- MIXER_PATH_MAX_LENGTH);
- else if (snd_device == SND_DEVICE_IN_USB_HEADSET_MIC)
- strlcat(mixer_path, " usb-headset-mic", MIXER_PATH_MAX_LENGTH);
- else if (snd_device == SND_DEVICE_IN_CAPTURE_FM)
- strlcat(mixer_path, " capture-fm", MIXER_PATH_MAX_LENGTH);
- else if (snd_device == SND_DEVICE_OUT_TRANSMISSION_FM)
- strlcat(mixer_path, " transmission-fm", MIXER_PATH_MAX_LENGTH);
- else if (snd_device == SND_DEVICE_OUT_SPDIF)
- strlcat(mixer_path, " spdif", MIXER_PATH_MAX_LENGTH);
-}
-
-int platform_get_pcm_device_id(audio_usecase_t usecase, int device_type)
-{
- int device_id;
- if (device_type == PCM_PLAYBACK)
- device_id = pcm_device_table[usecase][1];
- else
- device_id = pcm_device_table[usecase][2];
- return device_id;
-}
-
-audio_usecase_t platform_get_usecase(
- audio_usecase_stream_type_t uc_type)
-{
- int i = 0;
- for(i =0;i<AUDIO_USECASE_MAX; i++)
- if((pcm_device_table[i][0] == (int)uc_type) &&
- (pcm_device_table[i][3] == 0)) {
- pcm_device_table[i][3] = 1;
- break;
- }
-
- if(i == AUDIO_USECASE_MAX)
- return -EINVAL;
- else
- return (audio_usecase_t)i;
-}
-
-int platform_free_usecase(audio_usecase_t uc_id)
-{
- if(uc_id >= AUDIO_USECASE_MAX) {
- ALOGV("%s: enter: invalid usecase(%d)", __func__, uc_id);
- return -EINVAL;
- }
- pcm_device_table[uc_id][3] = 0;
- return 0;
-}
-
-int platform_send_audio_calibration(void *platform, snd_device_t snd_device)
-{
- struct platform_data *my_data = (struct platform_data *)platform;
- int acdb_dev_id, acdb_dev_type;
-
- acdb_dev_id = acdb_device_table[snd_device];
- if (acdb_dev_id < 0) {
- ALOGE("%s: Could not find acdb id for device(%d)",
- __func__, snd_device);
- return -EINVAL;
- }
- if (my_data->acdb_send_audio_cal) {
- ("%s: sending audio calibration for snd_device(%d) acdb_id(%d)",
- __func__, snd_device, acdb_dev_id);
- if (snd_device >= SND_DEVICE_OUT_BEGIN &&
- snd_device < SND_DEVICE_OUT_END)
- acdb_dev_type = ACDB_DEV_TYPE_OUT;
- else
- acdb_dev_type = ACDB_DEV_TYPE_IN;
- my_data->acdb_send_audio_cal(acdb_dev_id, acdb_dev_type);
- }
- return 0;
-}
-
-int platform_switch_voice_call_device_pre(void *platform)
-{
- struct platform_data *my_data = (struct platform_data *)platform;
- int ret = 0;
-
- if (my_data->csd != NULL &&
- my_data->adev->mode == AUDIO_MODE_IN_CALL) {
- /* This must be called before disabling mixer controls on APQ side */
- ret = my_data->csd->disable_device();
- if (ret < 0) {
- ALOGE("%s: csd_client_disable_device, failed, error %d",
- __func__, ret);
- }
- }
- return ret;
-}
-
-int platform_switch_voice_call_device_post(void *platform,
- snd_device_t out_snd_device,
- snd_device_t in_snd_device)
-{
- struct platform_data *my_data = (struct platform_data *)platform;
- int acdb_rx_id, acdb_tx_id;
-
- if (my_data->acdb_send_voice_cal == NULL) {
- ALOGE("%s: dlsym error for acdb_send_voice_call", __func__);
- } else {
- acdb_rx_id = acdb_device_table[out_snd_device];
- acdb_tx_id = acdb_device_table[in_snd_device];
-
- if (acdb_rx_id > 0 && acdb_tx_id > 0)
- my_data->acdb_send_voice_cal(acdb_rx_id, acdb_tx_id);
- else
- ALOGE("%s: Incorrect ACDB IDs (rx: %d tx: %d)", __func__,
- acdb_rx_id, acdb_tx_id);
- }
-
- return 0;
-}
-
-int platform_switch_voice_call_usecase_route_post(void *platform,
- snd_device_t out_snd_device,
- snd_device_t in_snd_device)
-{
- struct platform_data *my_data = (struct platform_data *)platform;
- int acdb_rx_id, acdb_tx_id;
- int ret = 0;
-
- acdb_rx_id = acdb_device_table[out_snd_device];
- acdb_tx_id = acdb_device_table[in_snd_device];
-
- if (my_data->csd != NULL) {
- if (acdb_rx_id > 0 && acdb_tx_id > 0) {
- ret = my_data->csd->enable_device(acdb_rx_id, acdb_tx_id,
- my_data->adev->acdb_settings);
- if (ret < 0) {
- ALOGE("%s: csd_enable_device, failed, error %d",
- __func__, ret);
- }
- } else {
- ALOGE("%s: Incorrect ACDB IDs (rx: %d tx: %d)", __func__,
- acdb_rx_id, acdb_tx_id);
- }
- }
- return ret;
-}
-
-int platform_start_voice_call(void *platform, uint32_t vsid)
-{
- struct platform_data *my_data = (struct platform_data *)platform;
- int ret = 0;
-
- if (my_data->csd != NULL) {
- ret = my_data->csd->start_voice(vsid);
- if (ret < 0) {
- ALOGE("%s: csd_start_voice error %d\n", __func__, ret);
- }
- }
- return ret;
-}
-
-int platform_stop_voice_call(void *platform, uint32_t vsid)
-{
- struct platform_data *my_data = (struct platform_data *)platform;
- int ret = 0;
-
- if (my_data->csd != NULL) {
- ret = my_data->csd->stop_voice(vsid);
- if (ret < 0) {
- ALOGE("%s: csd_stop_voice error %d\n", __func__, ret);
- }
- }
- return ret;
-}
-
-int platform_set_voice_volume(void *platform, int volume)
-{
- struct platform_data *my_data = (struct platform_data *)platform;
- struct audio_device *adev = my_data->adev;
- struct mixer_ctl *ctl;
- const char *mixer_ctl_name = "Voice Rx Gain";
- int vol_index = 0, ret = 0;
- uint32_t set_values[ ] = {0,
- ALL_SESSION_VSID,
- DEFAULT_VOLUME_RAMP_DURATION_MS};
-
- // Voice volume levels are mapped to adsp volume levels as follows.
- // 100 -> 5, 80 -> 4, 60 -> 3, 40 -> 2, 20 -> 1 0 -> 0
- // But this values don't changed in kernel. So, below change is need.
- vol_index = (int)percent_to_index(volume, MIN_VOL_INDEX, MAX_VOL_INDEX);
- set_values[0] = vol_index;
-
- ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
- if (!ctl) {
- ALOGE("%s: Could not get ctl for mixer cmd - %s",
- __func__, mixer_ctl_name);
- return -EINVAL;
- }
- ALOGV("Setting voice volume index: %d", set_values[0]);
- mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
-
- if (my_data->csd != NULL) {
- ret = my_data->csd->volume(ALL_SESSION_VSID, volume);
- if (ret < 0) {
- ALOGE("%s: csd_volume error %d", __func__, ret);
- }
- }
- return ret;
-}
-
-int platform_set_mic_mute(void *platform, bool state)
-{
- struct platform_data *my_data = (struct platform_data *)platform;
- struct audio_device *adev = my_data->adev;
- struct mixer_ctl *ctl;
- const char *mixer_ctl_name = "Voice Tx Mute";
- int ret = 0;
- uint32_t set_values[ ] = {0,
- ALL_SESSION_VSID,
- DEFAULT_VOLUME_RAMP_DURATION_MS};
-
- set_values[0] = state;
- ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
- if (!ctl) {
- ALOGE("%s: Could not get ctl for mixer cmd - %s",
- __func__, mixer_ctl_name);
- return -EINVAL;
- }
- ALOGV("Setting voice mute state: %d", state);
- mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
-
- if (my_data->csd != NULL) {
- ret = my_data->csd->mic_mute(ALL_SESSION_VSID, state);
- if (ret < 0) {
- ALOGE("%s: csd_mic_mute error %d", __func__, ret);
- }
- }
- return ret;
-}
-
-snd_device_t platform_get_output_snd_device(void *platform, audio_devices_t devices)
-{
- struct platform_data *my_data = (struct platform_data *)platform;
- struct audio_device *adev = my_data->adev;
- audio_mode_t mode = adev->mode;
- snd_device_t snd_device = SND_DEVICE_NONE;
-
- audio_channel_mask_t channel_mask = (adev->active_input == NULL) ?
- AUDIO_CHANNEL_IN_MONO : adev->active_input->channel_mask;
- int channel_count = popcount(channel_mask);
-
- ALOGV("%s: enter: output devices(%#x)", __func__, devices);
- if (devices == AUDIO_DEVICE_NONE ||
- devices & AUDIO_DEVICE_BIT_IN) {
- ALOGV("%s: Invalid output devices (%#x)", __func__, devices);
- goto exit;
- }
-
- if (popcount(devices) == 2) {
- if (devices == (AUDIO_DEVICE_OUT_WIRED_HEADPHONE |
- AUDIO_DEVICE_OUT_SPEAKER)) {
- snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES;
- } else if (devices == (AUDIO_DEVICE_OUT_WIRED_HEADSET |
- AUDIO_DEVICE_OUT_SPEAKER)) {
- snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES;
- } else if (devices == (AUDIO_DEVICE_OUT_AUX_DIGITAL |
- AUDIO_DEVICE_OUT_SPEAKER)) {
- snd_device = SND_DEVICE_OUT_SPEAKER_AND_HDMI;
- } else if (devices == (AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET |
- AUDIO_DEVICE_OUT_SPEAKER)) {
- snd_device = SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET;
- } else {
- ALOGE("%s: Invalid combo device(%#x)", __func__, devices);
- goto exit;
- }
- if (snd_device != SND_DEVICE_NONE) {
- goto exit;
- }
- }
-
- if (popcount(devices) != 1) {
- ALOGE("%s: Invalid output devices(%#x)", __func__, devices);
- goto exit;
- }
-
- if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
- devices & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
- snd_device = SND_DEVICE_OUT_HEADPHONES;
- } else if (devices & AUDIO_DEVICE_OUT_SPEAKER) {
- if (adev->speaker_lr_swap)
- snd_device = SND_DEVICE_OUT_SPEAKER_REVERSE;
- else
- snd_device = SND_DEVICE_OUT_SPEAKER;
- } else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) {
- if (my_data->btsco_sample_rate == SAMPLE_RATE_16KHZ)
- snd_device = SND_DEVICE_OUT_BT_SCO_WB;
- else
- snd_device = SND_DEVICE_OUT_BT_SCO;
- } else if (devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
- snd_device = SND_DEVICE_OUT_HDMI ;
- } else if (devices & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET ||
- devices & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET) {
- snd_device = SND_DEVICE_OUT_USB_HEADSET;
- } else if (devices & AUDIO_DEVICE_OUT_FM_TX) {
- snd_device = SND_DEVICE_OUT_TRANSMISSION_FM;
- } else if (devices & AUDIO_DEVICE_OUT_EARPIECE) {
- snd_device = SND_DEVICE_OUT_HANDSET;
- } else if (devices & AUDIO_DEVICE_OUT_SPDIF) {
- snd_device = SND_DEVICE_OUT_SPDIF;
- } else {
- ALOGE("%s: Unknown device(s) %#x", __func__, devices);
- }
-exit:
- ALOGV("%s: exit: snd_device(%s)", __func__, device_table[snd_device]);
- return snd_device;
-}
-
-snd_device_t platform_get_input_snd_device(void *platform, audio_devices_t out_device)
-{
- struct platform_data *my_data = (struct platform_data *)platform;
- struct audio_device *adev = my_data->adev;
- audio_source_t source = (adev->active_input == NULL) ?
- AUDIO_SOURCE_DEFAULT : adev->active_input->source;
-
- audio_mode_t mode = adev->mode;
- audio_devices_t in_device = ((adev->active_input == NULL) ?
- AUDIO_DEVICE_NONE : adev->active_input->device)
- & ~AUDIO_DEVICE_BIT_IN;
- audio_channel_mask_t channel_mask = (adev->active_input == NULL) ?
- AUDIO_CHANNEL_IN_MONO : adev->active_input->channel_mask;
- snd_device_t snd_device = SND_DEVICE_NONE;
- int channel_count = popcount(channel_mask);
-
- ALOGV("%s: enter: out_device(%#x) in_device(%#x)",
- __func__, out_device, in_device);
- if (source == AUDIO_SOURCE_CAMCORDER) {
- if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC ||
- in_device & AUDIO_DEVICE_IN_BACK_MIC) {
- snd_device = SND_DEVICE_IN_CAMCORDER_MIC;
- }
- } else if (source == AUDIO_SOURCE_VOICE_RECOGNITION) {
- if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
- if (channel_count == 2) {
- snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_STEREO;
- adev->acdb_settings |= DMIC_FLAG;
- } else if (adev->active_input->enable_ns)
- snd_device = SND_DEVICE_IN_VOICE_REC_MIC_NS;
- else if (my_data->fluence_type != FLUENCE_NONE &&
- my_data->fluence_in_voice_rec) {
- snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE;
- adev->acdb_settings |= DMIC_FLAG;
- } else {
- snd_device = SND_DEVICE_IN_VOICE_REC_MIC;
- }
- }
- } else if (source == AUDIO_SOURCE_VOICE_COMMUNICATION) {
- if (out_device & AUDIO_DEVICE_OUT_SPEAKER)
- in_device = AUDIO_DEVICE_IN_BACK_MIC;
- if (adev->active_input) {
- if (adev->active_input->enable_aec &&
- adev->active_input->enable_ns) {
- if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
- if (my_data->fluence_type & FLUENCE_DUAL_MIC &&
- my_data->fluence_in_spkr_mode) {
- snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS;
- adev->acdb_settings |= DMIC_FLAG;
- } else
- snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC_NS;
- } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
- if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
- snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC_NS;
- adev->acdb_settings |= DMIC_FLAG;
- } else
- snd_device = SND_DEVICE_IN_HANDSET_MIC_AEC_NS;
- } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
- snd_device = SND_DEVICE_IN_HEADSET_MIC_FLUENCE;
- }
- set_echo_reference(adev->mixer, "SLIM_RX");
- } else if (adev->active_input->enable_aec) {
- if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
- if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
- snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC;
- adev->acdb_settings |= DMIC_FLAG;
- } else
- snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC;
- } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
- if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
- snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC;
- adev->acdb_settings |= DMIC_FLAG;
- } else
- snd_device = SND_DEVICE_IN_HANDSET_MIC_AEC;
- } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
- snd_device = SND_DEVICE_IN_HEADSET_MIC_FLUENCE;
- }
- set_echo_reference(adev->mixer, "SLIM_RX");
- } else if (adev->active_input->enable_ns) {
- if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
- if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
- snd_device = SND_DEVICE_IN_SPEAKER_DMIC_NS;
- adev->acdb_settings |= DMIC_FLAG;
- } else
- snd_device = SND_DEVICE_IN_SPEAKER_MIC_NS;
- } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
- if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
- snd_device = SND_DEVICE_IN_HANDSET_DMIC_NS;
- adev->acdb_settings |= DMIC_FLAG;
- } else
- snd_device = SND_DEVICE_IN_HANDSET_MIC_NS;
- } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
- snd_device = SND_DEVICE_IN_HEADSET_MIC_FLUENCE;
- }
- set_echo_reference(adev->mixer, "NONE");
- } else
- set_echo_reference(adev->mixer, "NONE");
- }
- } else if (source == AUDIO_SOURCE_MIC) {
- if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC &&
- channel_count == 1 ) {
- if(my_data->fluence_type & FLUENCE_DUAL_MIC &&
- my_data->fluence_in_audio_rec)
- snd_device = SND_DEVICE_IN_HANDSET_DMIC;
- }
- } else if (source == AUDIO_SOURCE_FM_RX ||
- source == AUDIO_SOURCE_FM_RX_A2DP) {
- snd_device = SND_DEVICE_IN_CAPTURE_FM;
- } else if (source == AUDIO_SOURCE_DEFAULT) {
- goto exit;
- }
-
-
- if (snd_device != SND_DEVICE_NONE) {
- goto exit;
- }
-
- if (in_device != AUDIO_DEVICE_NONE &&
- !(in_device & AUDIO_DEVICE_IN_VOICE_CALL) &&
- !(in_device & AUDIO_DEVICE_IN_COMMUNICATION)) {
- if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
- if (channel_count == 2)
- snd_device = SND_DEVICE_IN_HANDSET_STEREO_DMIC;
- else
- snd_device = SND_DEVICE_IN_HANDSET_MIC;
- } else if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
- snd_device = SND_DEVICE_IN_SPEAKER_MIC;
- } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
- snd_device = SND_DEVICE_IN_HEADSET_MIC;
- } else if (in_device & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
- if (my_data->btsco_sample_rate == SAMPLE_RATE_16KHZ)
- snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
- else
- snd_device = SND_DEVICE_IN_BT_SCO_MIC;
- } else if (in_device & AUDIO_DEVICE_IN_AUX_DIGITAL) {
- snd_device = SND_DEVICE_IN_HDMI_MIC;
- } else if (in_device & AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET ||
- in_device & AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET) {
- snd_device = SND_DEVICE_IN_USB_HEADSET_MIC;
- } else if (in_device & AUDIO_DEVICE_IN_FM_RX) {
- snd_device = SND_DEVICE_IN_CAPTURE_FM;
- } else {
- ALOGE("%s: Unknown input device(s) %#x", __func__, in_device);
- ALOGW("%s: Using default handset-mic", __func__);
- snd_device = SND_DEVICE_IN_HANDSET_MIC;
- }
- } else {
- if (out_device & AUDIO_DEVICE_OUT_EARPIECE) {
- snd_device = SND_DEVICE_IN_HANDSET_MIC;
- } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
- snd_device = SND_DEVICE_IN_HEADSET_MIC;
- } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER) {
- if (channel_count > 1)
- snd_device = SND_DEVICE_IN_SPEAKER_STEREO_DMIC;
- else
- snd_device = SND_DEVICE_IN_SPEAKER_MIC;
- } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE) {
- snd_device = SND_DEVICE_IN_HANDSET_MIC;
- } else if (out_device & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET) {
- if (my_data->btsco_sample_rate == SAMPLE_RATE_16KHZ)
- snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
- else
- snd_device = SND_DEVICE_IN_BT_SCO_MIC;
- } else if (out_device & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
- snd_device = SND_DEVICE_IN_HDMI_MIC;
- } else if (out_device & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET ||
- out_device & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET) {
- snd_device = SND_DEVICE_IN_USB_HEADSET_MIC;
- } else {
- ALOGE("%s: Unknown output device(s) %#x", __func__, out_device);
- ALOGW("%s: Using default handset-mic", __func__);
- snd_device = SND_DEVICE_IN_HANDSET_MIC;
- }
- }
-exit:
- ALOGV("%s: exit: in_snd_device(%s)", __func__, device_table[snd_device]);
- return snd_device;
-}
-
-int platform_set_hdmi_channels(void *platform, int channel_count)
-{
- struct platform_data *my_data = (struct platform_data *)platform;
- struct audio_device *adev = my_data->adev;
- struct mixer_ctl *ctl;
- const char *channel_cnt_str = NULL;
- const char *mixer_ctl_name = "HDMI_RX Channels";
- switch (channel_count) {
- case 8:
- channel_cnt_str = "Eight"; break;
- case 7:
- channel_cnt_str = "Seven"; break;
- case 6:
- channel_cnt_str = "Six"; break;
- case 5:
- channel_cnt_str = "Five"; break;
- case 4:
- channel_cnt_str = "Four"; break;
- case 3:
- channel_cnt_str = "Three"; break;
- default:
- channel_cnt_str = "Two"; break;
- }
- ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
- if (!ctl) {
- ALOGE("%s: Could not get ctl for mixer cmd - %s",
- __func__, mixer_ctl_name);
- return -EINVAL;
- }
- ALOGV("HDMI channel count: %s", channel_cnt_str);
- mixer_ctl_set_enum_by_string(ctl, channel_cnt_str);
- return 0;
-}
-
-int platform_edid_get_max_channels(void *platform)
-{
- struct platform_data *my_data = (struct platform_data *)platform;
- struct audio_device *adev = my_data->adev;
- char block[MAX_SAD_BLOCKS * SAD_BLOCK_SIZE];
- char *sad = block;
- int num_audio_blocks;
- int channel_count;
- int max_channels = 0;
- int i, ret, count;
-
- struct mixer_ctl *ctl;
-
- ctl = mixer_get_ctl_by_name(adev->mixer, AUDIO_DATA_BLOCK_MIXER_CTL);
- if (!ctl) {
- ALOGE("%s: Could not get ctl for mixer cmd - %s",
- __func__, AUDIO_DATA_BLOCK_MIXER_CTL);
- return 0;
- }
-
- mixer_ctl_update(ctl);
-
- count = mixer_ctl_get_num_values(ctl);
-
- /* Read SAD blocks, clamping the maximum size for safety */
- if (count > (int)sizeof(block))
- count = (int)sizeof(block);
-
- ret = mixer_ctl_get_array(ctl, block, count);
- if (ret != 0) {
- ALOGE("%s: mixer_ctl_get_array() failed to get EDID info", __func__);
- return 0;
- }
-
- /* Calculate the number of SAD blocks */
- num_audio_blocks = count / SAD_BLOCK_SIZE;
-
- for (i = 0; i < num_audio_blocks; i++) {
- /* Only consider LPCM blocks */
- if ((sad[0] >> 3) != EDID_FORMAT_LPCM) {
- sad += 3;
- continue;
- }
-
- channel_count = (sad[0] & 0x7) + 1;
- if (channel_count > max_channels)
- max_channels = channel_count;
-
- /* Advance to next block */
- sad += 3;
- }
-
- return max_channels;
-}
-
-static int platform_set_slowtalk(struct platform_data *my_data, bool state)
-{
- int ret = 0;
- struct audio_device *adev = my_data->adev;
- struct mixer_ctl *ctl;
- const char *mixer_ctl_name = "Slowtalk Enable";
- uint32_t set_values[ ] = {0,
- ALL_SESSION_VSID};
-
- set_values[0] = state;
- ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
- if (!ctl) {
- ALOGE("%s: Could not get ctl for mixer cmd - %s",
- __func__, mixer_ctl_name);
- ret = -EINVAL;
- } else {
- ALOGV("Setting slowtalk state: %d", state);
- ret = mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
- my_data->slowtalk = state;
- }
-
- if (my_data->csd != NULL) {
- ret = my_data->csd->slow_talk(ALL_SESSION_VSID, state);
- if (ret < 0) {
- ALOGE("%s: csd_client_disable_device, failed, error %d",
- __func__, ret);
- }
- }
- return ret;
-}
-
-int platform_set_parameters(void *platform, struct str_parms *parms)
-{
- struct platform_data *my_data = (struct platform_data *)platform;
- char *str;
- char value[32];
- int val;
- int ret = 0;
-
- ALOGV("%s: enter: %s", __func__, str_parms_to_str(parms));
-
- ret = str_parms_get_int(parms, AUDIO_PARAMETER_KEY_BTSCO, &val);
- if (ret >= 0) {
- str_parms_del(parms, AUDIO_PARAMETER_KEY_BTSCO);
- my_data->btsco_sample_rate = val;
- }
-
- ret = str_parms_get_int(parms, AUDIO_PARAMETER_KEY_SLOWTALK, &val);
- if (ret >= 0) {
- str_parms_del(parms, AUDIO_PARAMETER_KEY_SLOWTALK);
- ret = platform_set_slowtalk(my_data, val);
- if (ret)
- ALOGE("%s: Failed to set slow talk err: %d", __func__, ret);
- }
-
- ALOGV("%s: exit with code(%d)", __func__, ret);
- return ret;
-}
-
-int platform_set_incall_recoding_session_id(void *platform,
- uint32_t session_id)
-{
- int ret = 0;
- struct platform_data *my_data = (struct platform_data *)platform;
- struct audio_device *adev = my_data->adev;
- struct mixer_ctl *ctl;
- const char *mixer_ctl_name = "Voc VSID";
- int num_ctl_values;
- int i;
-
- ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
- if (!ctl) {
- ALOGE("%s: Could not get ctl for mixer cmd - %s",
- __func__, mixer_ctl_name);
- ret = -EINVAL;
- } else {
- num_ctl_values = mixer_ctl_get_num_values(ctl);
- for (i = 0; i < num_ctl_values; i++) {
- if (mixer_ctl_set_value(ctl, i, session_id)) {
- ALOGV("Error: invalid session_id: %x", session_id);
- ret = -EINVAL;
- break;
- }
- }
- }
-
- return ret;
-}
-
-void platform_get_parameters(void *platform,
- struct str_parms *query,
- struct str_parms *reply)
-{
- struct platform_data *my_data = (struct platform_data *)platform;
- char *str = NULL;
- char value[256] = {0};
- int ret;
- int fluence_type;
-
- ret = str_parms_get_str(query, AUDIO_PARAMETER_KEY_FLUENCE_TYPE,
- value, sizeof(value));
- if (ret >= 0) {
- if (my_data->fluence_type & FLUENCE_QUAD_MIC) {
- strlcpy(value, "fluencepro", sizeof(value));
- } else if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
- strlcpy(value, "fluence", sizeof(value));
- } else {
- strlcpy(value, "none", sizeof(value));
- }
-
- str_parms_add_str(reply, AUDIO_PARAMETER_KEY_FLUENCE_TYPE, value);
- }
-
- memset(value, 0, sizeof(value));
- ret = str_parms_get_str(query, AUDIO_PARAMETER_KEY_SLOWTALK,
- value, sizeof(value));
- if (ret >= 0) {
- str_parms_add_int(reply, AUDIO_PARAMETER_KEY_SLOWTALK,
- my_data->slowtalk);
- }
-
- ALOGV("%s: exit: returns - %s", __func__, str_parms_to_str(reply));
-}
-
-/* Delay in Us */
-int64_t platform_render_latency(audio_usecase_t usecase)
-{
- switch (usecase) {
- case USECASE_AUDIO_PLAYBACK_DEEP_BUFFER:
- return DEEP_BUFFER_PLATFORM_DELAY;
- case USECASE_AUDIO_PLAYBACK_LOW_LATENCY:
- return LOW_LATENCY_PLATFORM_DELAY;
- default:
- return 0;
- }
-}
-
-int platform_update_usecase_from_source(int source, int usecase)
-{
- ALOGV("%s: input source :%d", __func__, source);
- if(source == AUDIO_SOURCE_FM_RX_A2DP)
- usecase = USECASE_AUDIO_RECORD_FM_VIRTUAL;
- return usecase;
-}
diff --git a/hal_mpq/mpq8092/platform.h b/hal_mpq/mpq8092/platform.h
deleted file mode 100644
index 562f979..0000000
--- a/hal_mpq/mpq8092/platform.h
+++ /dev/null
@@ -1,671 +0,0 @@
-/*
- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
- * Not a Contribution.
- *
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef QCOM_AUDIO_PLATFORM_H
-#define QCOM_AUDIO_PLATFORM_H
-
-enum {
- FLUENCE_NONE,
- FLUENCE_DUAL_MIC = 0x1,
- FLUENCE_QUAD_MIC = 0x2,
-};
-
-#include <hardware/audio.h>
-/*
- * Below are the devices for which is back end is same, SLIMBUS_0_RX.
- * All these devices are handled by the internal HW codec. We can
- * enable any one of these devices at any time
- */
-#define AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND \
- (AUDIO_DEVICE_OUT_EARPIECE | AUDIO_DEVICE_OUT_SPEAKER | \
- AUDIO_DEVICE_OUT_WIRED_HEADSET | AUDIO_DEVICE_OUT_WIRED_HEADPHONE)
-/*TODO remove this once define in audio.h */
-#define AUDIO_DEVICE_OUT_SPDIF 0x4000
-
-/* Sound devices specific to the platform
- * The DEVICE_OUT_* and DEVICE_IN_* should be mapped to these sound
- * devices to enable corresponding mixer paths
- */
-enum {
- SND_DEVICE_NONE = 0,
-
- /* Playback devices */
- SND_DEVICE_MIN,
- SND_DEVICE_OUT_BEGIN = SND_DEVICE_MIN,
- SND_DEVICE_OUT_HANDSET = SND_DEVICE_OUT_BEGIN,
- SND_DEVICE_OUT_SPEAKER,
- SND_DEVICE_OUT_SPEAKER_REVERSE,
- SND_DEVICE_OUT_HEADPHONES,
- SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES,
- SND_DEVICE_OUT_VOICE_HANDSET,
- SND_DEVICE_OUT_VOICE_SPEAKER,
- SND_DEVICE_OUT_VOICE_HEADPHONES,
- SND_DEVICE_OUT_HDMI,
- SND_DEVICE_OUT_SPEAKER_AND_HDMI,
- SND_DEVICE_OUT_BT_SCO,
- SND_DEVICE_OUT_BT_SCO_WB,
- SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES,
- SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES,
- SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET,
- SND_DEVICE_OUT_AFE_PROXY,
- SND_DEVICE_OUT_USB_HEADSET,
- SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET,
- SND_DEVICE_OUT_TRANSMISSION_FM,
- SND_DEVICE_OUT_ANC_HEADSET,
- SND_DEVICE_OUT_ANC_FB_HEADSET,
- SND_DEVICE_OUT_VOICE_ANC_HEADSET,
- SND_DEVICE_OUT_VOICE_ANC_FB_HEADSET,
- SND_DEVICE_OUT_SPEAKER_AND_ANC_HEADSET,
- SND_DEVICE_OUT_ANC_HANDSET,
- SND_DEVICE_OUT_SPEAKER_PROTECTED,
- SND_DEVICE_OUT_SPDIF,
- SND_DEVICE_OUT_END,
-
- /*
- * Note: IN_BEGIN should be same as OUT_END because total number of devices
- * SND_DEVICES_MAX should not exceed MAX_RX + MAX_TX devices.
- */
- /* Capture devices */
- SND_DEVICE_IN_BEGIN = SND_DEVICE_OUT_END,
- SND_DEVICE_IN_HANDSET_MIC = SND_DEVICE_IN_BEGIN,
- SND_DEVICE_IN_HANDSET_MIC_AEC,
- SND_DEVICE_IN_HANDSET_MIC_NS,
- SND_DEVICE_IN_HANDSET_MIC_AEC_NS,
- SND_DEVICE_IN_HANDSET_DMIC,
- SND_DEVICE_IN_HANDSET_DMIC_AEC,
- SND_DEVICE_IN_HANDSET_DMIC_NS,
- SND_DEVICE_IN_HANDSET_DMIC_AEC_NS,
- SND_DEVICE_IN_SPEAKER_MIC,
- SND_DEVICE_IN_SPEAKER_MIC_AEC,
- SND_DEVICE_IN_SPEAKER_MIC_NS,
- SND_DEVICE_IN_SPEAKER_MIC_AEC_NS,
- SND_DEVICE_IN_SPEAKER_DMIC,
- SND_DEVICE_IN_SPEAKER_DMIC_AEC,
- SND_DEVICE_IN_SPEAKER_DMIC_NS,
- SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS,
- SND_DEVICE_IN_HEADSET_MIC,
- SND_DEVICE_IN_HEADSET_MIC_FLUENCE,
- SND_DEVICE_IN_VOICE_SPEAKER_MIC,
- SND_DEVICE_IN_VOICE_HEADSET_MIC,
- SND_DEVICE_IN_HDMI_MIC,
- SND_DEVICE_IN_BT_SCO_MIC,
- SND_DEVICE_IN_BT_SCO_MIC_WB,
- SND_DEVICE_IN_CAMCORDER_MIC,
- SND_DEVICE_IN_VOICE_DMIC,
- SND_DEVICE_IN_VOICE_SPEAKER_DMIC,
- SND_DEVICE_IN_VOICE_SPEAKER_QMIC,
- SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC,
- SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC,
- SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC,
- SND_DEVICE_IN_VOICE_REC_MIC,
- SND_DEVICE_IN_VOICE_REC_MIC_NS,
- SND_DEVICE_IN_VOICE_REC_DMIC_STEREO,
- SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE,
- SND_DEVICE_IN_USB_HEADSET_MIC,
- SND_DEVICE_IN_CAPTURE_FM,
- SND_DEVICE_IN_AANC_HANDSET_MIC,
- SND_DEVICE_IN_QUAD_MIC,
- SND_DEVICE_IN_HANDSET_STEREO_DMIC,
- SND_DEVICE_IN_SPEAKER_STEREO_DMIC,
- SND_DEVICE_IN_CAPTURE_VI_FEEDBACK,
- SND_DEVICE_IN_END,
-
- SND_DEVICE_MAX = SND_DEVICE_IN_END,
-
-};
-
-#define MIXER_CARD 0
-#define SOUND_CARD 0
-
-#define DEFAULT_OUTPUT_SAMPLING_RATE 48000
-
-#define ALL_SESSION_VSID 0xFFFFFFFF
-#define DEFAULT_MUTE_RAMP_DURATION 500
-#define DEFAULT_VOLUME_RAMP_DURATION_MS 20
-#define MIXER_PATH_MAX_LENGTH 100
-
-#define MAX_VOL_INDEX 5
-#define MIN_VOL_INDEX 0
-#define percent_to_index(val, min, max) \
- ((val) * ((max) - (min)) * 0.01 + (min) + .5)
-
-/*
- * tinyAlsa library interprets period size as number of frames
- * one frame = channel_count * sizeof (pcm sample)
- * so if format = 16-bit PCM and channels = Stereo, frame size = 2 ch * 2 = 4 bytes
- * DEEP_BUFFER_OUTPUT_PERIOD_SIZE = 1024 means 1024 * 4 = 4096 bytes
- * We should take care of returning proper size when AudioFlinger queries for
- * the buffer size of an input/output stream
- */
-#define DEEP_BUFFER_OUTPUT_PERIOD_SIZE 960
-#define DEEP_BUFFER_OUTPUT_PERIOD_COUNT 8
-#define LOW_LATENCY_OUTPUT_PERIOD_SIZE 240
-#define LOW_LATENCY_OUTPUT_PERIOD_COUNT 2
-
-/*******************************************************************************
-ADTS HEADER PARSING
-*******************************************************************************/
-//Required for ADTS Header Parsing
-#define ADTS_HEADER_SYNC_RESULT 0xfff0
-#define ADTS_HEADER_SYNC_MASK 0xfff6
-/*******************************************************************************
-HDMI and SPDIF Device Output format control
-*******************************************************************************/
-
-#define HDMI_MULTI_PERIOD_SIZE 336
-#define HDMI_MULTI_PERIOD_COUNT 8
-#define HDMI_MULTI_DEFAULT_CHANNEL_COUNT 6
-#define HDMI_MULTI_PERIOD_BYTES (HDMI_MULTI_PERIOD_SIZE * HDMI_MULTI_DEFAULT_CHANNEL_COUNT * 2)
-
-#define AUDIO_CAPTURE_PERIOD_DURATION_MSEC 20
-#define AUDIO_CAPTURE_PERIOD_COUNT 2
-
-#define DEVICE_NAME_MAX_SIZE 128
-#define HW_INFO_ARRAY_MAX_SIZE 32
-
-#define DEEP_BUFFER_PCM_DEVICE 0
-#define AUDIO_RECORD_PCM_DEVICE 0
-#define MULTIMEDIA2_PCM_DEVICE 1
-#define FM_PLAYBACK_PCM_DEVICE 5
-#define FM_CAPTURE_PCM_DEVICE 6
-#define INCALL_MUSIC_UPLINK_PCM_DEVICE 1
-#define INCALL_MUSIC_UPLINK2_PCM_DEVICE 16
-#define SPKR_PROT_CALIB_RX_PCM_DEVICE 5
-#define SPKR_PROT_CALIB_TX_PCM_DEVICE 22
-#define COMPRESS_VOIP_CALL_PCM_DEVICE 3
-#define MULTI_CHANNEL_PCM_DEVICE 1
-#define VOICE_CALL_PCM_DEVICE 2
-//TODO: update the device number as per the dai links
-#define PLAYBACK_OFFLOAD_DEVICE1 2
-#define PLAYBACK_OFFLOAD_DEVICE2 3
-#define PLAYBACK_OFFLOAD_DEVICE3 4
-#define PLAYBACK_OFFLOAD_DEVICE4 19
-
-#define LOWLATENCY_PCM_DEVICE 15
-#define COMPRESS_CAPTURE_DEVICE 19
-
-#ifdef PLATFORM_MSM8x26
-#define VOICE_CALL_PCM_DEVICE 2
-#define VOICE2_CALL_PCM_DEVICE 14
-#define VOLTE_CALL_PCM_DEVICE 17
-#define QCHAT_CALL_PCM_DEVICE 18
-#elif PLATFORM_APQ8084
-#define VOICE_CALL_PCM_DEVICE 20
-#define VOICE2_CALL_PCM_DEVICE 13
-#define VOLTE_CALL_PCM_DEVICE 21
-#define QCHAT_CALL_PCM_DEVICE 06
-#else
-#define VOICE_CALL_PCM_DEVICE 2
-#define VOICE2_CALL_PCM_DEVICE 13
-#define VOLTE_CALL_PCM_DEVICE 14
-#define QCHAT_CALL_PCM_DEVICE 20
-#endif
-
-#define LIB_CSD_CLIENT "libcsd-client.so"
-/* CSD-CLIENT related functions */
-typedef int (*init_t)();
-typedef int (*deinit_t)();
-typedef int (*disable_device_t)();
-typedef int (*enable_device_t)(int, int, uint32_t);
-typedef int (*volume_t)(uint32_t, int);
-typedef int (*mic_mute_t)(uint32_t, int);
-typedef int (*slow_talk_t)(uint32_t, uint8_t);
-typedef int (*start_voice_t)(uint32_t);
-typedef int (*stop_voice_t)(uint32_t);
-typedef int (*start_playback_t)(uint32_t);
-typedef int (*stop_playback_t)(uint32_t);
-typedef int (*start_record_t)(uint32_t, int);
-typedef int (*stop_record_t)(uint32_t, int);
-/* CSD Client structure */
-struct csd_data {
- void *csd_client;
- init_t init;
- deinit_t deinit;
- disable_device_t disable_device;
- enable_device_t enable_device;
- volume_t volume;
- mic_mute_t mic_mute;
- slow_talk_t slow_talk;
- start_voice_t start_voice;
- stop_voice_t stop_voice;
- start_playback_t start_playback;
- stop_playback_t stop_playback;
- start_record_t start_record;
- stop_record_t stop_record;
-};
-
-void *hw_info_init(const char *snd_card_name);
-void hw_info_deinit(void *hw_info);
-void hw_info_append_hw_type(void *hw_info, snd_device_t snd_device,
- char *device_name);
-
-/*******************************************************************************
-USECASES AND THE CORRESPONDING DEVICE FORMATS THAT WE SUPPORT IN HAL
-*******************************************************************************/
-/*
-In general max of 2 for pass through. Additional 1 for handling transcode
-as the existence of transcode is with a PCM handle followed by transcode handle
-So, a (AC3/EAC3) pass through + trancode require - 1 for pas through, 1 - pcm and
-1 - transcode
-*/
-#define NUM_DEVICES_SUPPORT_COMPR_DATA 2+1
-#define NUM_SUPPORTED_CODECS 16
-#define NUM_COLUMN_FOR_INDEXING 2
-#define NUM_STATES_FOR_EACH_DEVICE_FMT 3
-#define DECODER_TYPE_IDX 0
-#define ROUTE_FORMAT_IDX 1
-
-#define MIN_SIZE_FOR_METADATA 64
-#define NUM_OF_PERIODS 8
-/*Period size to be a multiple of chanels * bitwidth,
-So min period size = LCM (1,2...8) * 4*/
-#define PERIOD_SIZE_COMPR 3360
-#define MS11_INPUT_BUFFER_SIZE 1536
-/*Max Period size which is exposed by the compr driver
-The value needs to be modified when the period size is modified*/
-#define PLAYBACK_MAX_PERIOD_SIZE (160 * 1024)
-
-#define COMPR_INPUT_BUFFER_SIZE (PERIOD_SIZE_COMPR - MIN_SIZE_FOR_METADATA)
-#define PCM_16_BITS_PER_SAMPLE 2
-#define PCM_24_BITS_PER_SAMPLE 3
-#define AC3_PERIOD_SIZE 1536 * PCM_16_BITS_PER_SAMPLE
-#define TIME_PER_BUFFER 40 //Time duration in ms
-#define SAMPLES_PER_CHANNEL 32*1024 //1536*2 /*TODO:correct it
-#define MAX_INPUT_CHANNELS_SUPPORTED 8
-#define FACTOR_FOR_BUFFERING 2
-#define STEREO_CHANNELS 2
-#define MAX_OUTPUT_CHANNELS_SUPPORTED 8
-#define PCM_BLOCK_PER_CHANNEL_MS11 1536*2
-#define AAC_BLOCK_PER_CHANNEL_MS11 768
-#define NUMBER_BITS_IN_A_BYTE 8
-#define AC3_BUFFER_SIZE 1920*2
-
-#define MAX_OUTPUT_CHANNELS_SUPPORTED 8
-
-#define PCM_2CH_OUT 0
-#define PCM_MCH_OUT 1
-#define SPDIF_OUT 2
-#define COMPRESSED_OUT 2 // should be same as SPDIF_OUT
-#define TRANSCODE_OUT 3
-#define FACTOR_FOR_BUFFERING 2
-
-#define NUM_DEVICES_SUPPORT_COMPR_DATA 2+1
-#define NUM_SUPPORTED_CODECS 16
-#define NUM_COLUMN_FOR_INDEXING 2
-#define NUM_STATES_FOR_EACH_DEVICE_FMT 3
-#define DECODER_TYPE_IDX 0
-#define ROUTE_FORMAT_IDX 1
-#define NUM_OF_PERIODS 8
-
-enum {
- LPCM,
- MULTI_CH_PCM,
- COMPR,
- TRANSCODE
-};
-
-
-/*
-List of indexes of the supported formats
-Redundant formats such as (AAC-LC, HEAAC) are removed from the indexes as they
-are treated with the AAC format
-*/
-enum {
- PCM_IDX = 0,
- AAC_IDX,
- AC3_IDX,
- EAC3_IDX,
- DTS_IDX,
- DTS_LBR_IDX,
- MP3_IDX,
- WMA_IDX,
- WMA_PRO_IDX,
- MP2_IDX,
- ALL_FORMATS_IDX
-};
-/*
-List of pass through's supported in the current usecases
-*/
-enum {
- NO_PASSTHROUGH = 0,
- AC3_PASSTHR,
- EAC3_PASSTHR,
- DTS_PASSTHR
-};
-/*
-List of transcoder's supported in the current usecases
-*/
-enum {
- NO_TRANSCODER = 0,
- AC3_TRANSCODER,
- DTS_TRANSCODER
-};
-/*
-Requested end device format by user/app through set parameters
-*/
-enum {
- UNCOMPRESSED = 0,
- COMPRESSED,
- COMPRESSED_CONVERT_EAC3_AC3,
- COMPRESSED_CONVERT_ANY_AC3,
- COMPRESSED_CONVERT_ANY_DTS,
- AUTO_DEVICE_FORMAT,
- UNCOMPRESSED_MCH, /* not to be exposed, internal use only */
- COMPRESSED_CONVERT_AC3_ASSOC, /* not to be exposed, internal use only */
- ALL_DEVICE_FORMATS
-};
-/*
-List of type of data routed on end device
-*/
-typedef enum {
- ROUTE_NONE = 0x0,
- ROUTE_UNCOMPRESSED = 0x1,
- ROUTE_COMPRESSED = 0x2,
- ROUTE_SW_TRANSCODED = 0x10, //route sub-format, not to be used directly
- ROUTE_DSP_TRANSCODED = 0x20, //route sub-format, not to be used directly
- ROUTE_MCH = 0x40, //route sub-format, not to be used directly
- ROUTE_UNCOMPRESSED_MCH = (ROUTE_UNCOMPRESSED | ROUTE_MCH),
- ROUTE_SW_TRANSCODED_COMPRESSED = (ROUTE_COMPRESSED | ROUTE_SW_TRANSCODED),
- ROUTE_DSP_TRANSCODED_COMPRESSED = (ROUTE_COMPRESSED | ROUTE_DSP_TRANSCODED)
-}route_format_t;
-/*
-List of end device formats
-*/
-enum {
- FORMAT_INVALID = -1,
- FORMAT_PCM,
- FORMAT_COMPR
-};
-/*
-Below are the only different types of decode that we perform
-*/
-enum {
- DSP_DECODE = 1, // render uncompressed
- DSP_PASSTHROUGH = 2, // render compressed
- DSP_TRANSCODE = 4, // render as compressed
- SW_DECODE = 8, // render as uncompressed
- SW_DECODE_MCH = 16, // render as uncompressed
- SW_PASSTHROUGH = 32, // render compressed
- SW_TRANSCODE = 64, // render compressed
- NUM_DECODE_PATH = 7
-};
-/*
-Modes of buffering that we can support
-As of now, we only support input buffering to an extent specified by usecase
-*/
-enum {
- NO_BUFFERING_MODE = 0,
- INPUT_BUFFERING_MODE,
- OUTPUT_BUFFEING_MODE
-};
-/*
-playback controls
-*/
-enum {
- PLAY = 1,
- PAUSE = (1<<1),
- RESUME = (1<<2),
- SEEK = (1<<3),
- EOS = (1<<4),
- STOP = (1<<5),
- STANDBY = (1<<6),
- INIT = (1<<7),
-};
-/*
-Multiple instance of use case
-*/
-enum {
- STEREO_DRIVER = 0,
- MULTI_CHANNEL_DRIVER,
- COMRPESSED_DRIVER,
-};
-/*
-Instance bits
-*/
-enum {
- MULTI_CHANNEL_1_BIT = 1<<4,
- MULTI_CHANNEL_2_BIT = 1<<5,
- MULTI_CHANNEL_3_BIT = 1<<6,
- COMPRESSED_1_BIT = 1<<12,
- COMPRESSED_2_BIT = 1<<13,
- COMPRESSED_3_BIT = 1<<14,
- COMPRESSED_4_BIT = 1<<15,
- COMPRESSED_5_BIT = 1<<16,
- COMPRESSED_6_BIT = 1<<17
-};
-
-/*
-List of support formats configured from frameworks
-*/
-static const int supportedFormats[NUM_SUPPORTED_CODECS] = {
- AUDIO_FORMAT_PCM_16_BIT,
- AUDIO_FORMAT_PCM_24_BIT,
- AUDIO_FORMAT_AAC,
- AUDIO_FORMAT_HE_AAC_V1,
- AUDIO_FORMAT_HE_AAC_V2,
- AUDIO_FORMAT_AAC_ADIF,
- AUDIO_FORMAT_AC3,
- AUDIO_FORMAT_AC3_DM,
- AUDIO_FORMAT_EAC3,
- AUDIO_FORMAT_EAC3_DM,
- AUDIO_FORMAT_DTS,
- AUDIO_FORMAT_DTS_LBR,
- AUDIO_FORMAT_MP3,
- AUDIO_FORMAT_WMA,
- AUDIO_FORMAT_WMA_PRO,
- AUDIO_FORMAT_MP2
-};
-/*
-we can only have 6 types of decoder type stored with bit masks.
-*/
-static const int route_to_driver[NUM_DECODE_PATH][NUM_COLUMN_FOR_INDEXING] = {
- {DSP_DECODE, ROUTE_UNCOMPRESSED_MCH},
- {DSP_PASSTHROUGH, ROUTE_COMPRESSED},
- {DSP_TRANSCODE, ROUTE_DSP_TRANSCODED_COMPRESSED},
- {SW_DECODE, ROUTE_UNCOMPRESSED},
- {SW_DECODE_MCH, ROUTE_UNCOMPRESSED_MCH},
- {SW_PASSTHROUGH, ROUTE_COMPRESSED},
- {SW_TRANSCODE, ROUTE_SW_TRANSCODED_COMPRESSED}
-};
-/*
-table to query index based on the format
-*/
-static const int format_index[NUM_SUPPORTED_CODECS][NUM_COLUMN_FOR_INDEXING] = {
-/*---------------------------------------------
-| FORMAT | INDEX |
-----------------------------------------------*/
- {AUDIO_FORMAT_PCM_16_BIT, PCM_IDX},
- {AUDIO_FORMAT_PCM_24_BIT, PCM_IDX},
- {AUDIO_FORMAT_AAC, AAC_IDX},
- {AUDIO_FORMAT_HE_AAC_V1, AAC_IDX},
- {AUDIO_FORMAT_HE_AAC_V2, AAC_IDX},
- {AUDIO_FORMAT_AAC_ADIF, AAC_IDX},
- {AUDIO_FORMAT_AC3, AC3_IDX},
- {AUDIO_FORMAT_AC3_DM, AC3_IDX},
- {AUDIO_FORMAT_EAC3, EAC3_IDX},
- {AUDIO_FORMAT_EAC3_DM, EAC3_IDX},
- {AUDIO_FORMAT_DTS, DTS_IDX},
- {AUDIO_FORMAT_DTS_LBR, DTS_LBR_IDX},
- {AUDIO_FORMAT_MP3, MP3_IDX},
- {AUDIO_FORMAT_WMA, WMA_IDX},
- {AUDIO_FORMAT_WMA_PRO, WMA_PRO_IDX},
- {AUDIO_FORMAT_MP2, MP2_IDX}
-};
-
-/*
-Table to query non HDMI and SPDIF devices and their states such as type of
-decode, type of data routed to end device and type of transcoding needed
-*/
-static const int usecase_decode_format[ALL_FORMATS_IDX*NUM_STATES_FOR_EACH_DEVICE_FMT] = {
-/*-----------------
-| UNCOMPR |
------------------*/
-/* PCM */
- DSP_DECODE, //PCM_IDX
- FORMAT_PCM, //ROUTE_FORMAT
- NO_TRANSCODER,//TRANSCODE_FORMAT
-/* PCM */
- SW_DECODE, // AAC_IDX
- FORMAT_PCM, //ROUTE_FORMAT
- NO_TRANSCODER,//TRANSCODE_FORMAT
-/* PCM */
- SW_DECODE, //AC3_IDX
- FORMAT_PCM, //ROUTE_FORMAT
- NO_TRANSCODER,//TRANSCODE_FORMAT
-/* PCM */
- SW_DECODE, //EAC3_IDX
- FORMAT_PCM, //ROUTE_FORMAT
- NO_TRANSCODER,//TRANSCODE_FORMAT
-/* PCM */
- DSP_DECODE, //DTS_IDX
- FORMAT_PCM, //ROUTE_FORMAT
- NO_TRANSCODER,//TRANSCODE_FORMAT
-/* PCM */
- DSP_DECODE, //DTS_LBR_IDX
- FORMAT_PCM, //ROUTE_FORMAT
- NO_TRANSCODER,//TRANSCODE_FORMAT
-/* PCM */
- DSP_DECODE, //MP3_IDX
- FORMAT_PCM, //ROUTE_FORMAT
- NO_TRANSCODER,//TRANSCODE_FORMAT
-/* PCM */
- DSP_DECODE, //WMA_IDX
- FORMAT_PCM, //ROUTE_FORMAT
- NO_TRANSCODER,//TRANSCODE_FORMAT
-/* PCM */
- DSP_DECODE, //WMA_PRO_IDX
- FORMAT_PCM, //ROUTE_FORMAT
- NO_TRANSCODER,//TRANSCODE_FORMAT
-/* PCM */
- DSP_DECODE, //MP2_IDX
- FORMAT_PCM, //ROUTE_FORMAT
- NO_TRANSCODER//TRANSCODE_FORMAT
-};
-/*
-Table to query HDMI and SPDIF devices and their states such as type of
-decode, type of data routed to end device and type of transcoding needed
-*/
-static const int usecase_docode_hdmi_spdif[ALL_FORMATS_IDX*NUM_STATES_FOR_EACH_DEVICE_FMT]
- [ALL_DEVICE_FORMATS] = {
-/*-------------------------------------------------------------------------------------------------------------------------------------------------------
-| UNCOMPRESSED | COMPR | COMPR_CONV | COMPR_CONV | COMPR_CONV | AUTO | UNCOMPR_MCH | AC3_AC3 |
-| | | EAC3_AC3 | ANY_AC3 | ANY_DTS | | | |
---------------------------------------------------------------------------------------------------------------------------------------------------------*/
-/* PCM PCM PCM PCM PCM PCM PCM PCM */
- {DSP_DECODE, DSP_DECODE, DSP_DECODE, DSP_DECODE, DSP_DECODE|DSP_TRANSCODE, DSP_DECODE, DSP_DECODE, DSP_DECODE}, //PCM_IDX
- {FORMAT_PCM, FORMAT_PCM, FORMAT_PCM, FORMAT_PCM, FORMAT_COMPR, FORMAT_PCM, FORMAT_PCM, FORMAT_PCM}, //ROUTE_FORMAT
- {NO_TRANSCODER, NO_TRANSCODER, NO_TRANSCODER, NO_TRANSCODER, DTS_TRANSCODER, NO_TRANSCODER, NO_TRANSCODER, NO_TRANSCODER}, //TRANSCODE_FMT
-/* PCM PCM PCM AC3 PCM PCM PCM PCM */
- {SW_DECODE, SW_DECODE, SW_DECODE, SW_TRANSCODE, DSP_DECODE, SW_DECODE, SW_DECODE_MCH, SW_DECODE}, //AAC_IDX
- {FORMAT_PCM, FORMAT_PCM, FORMAT_PCM, FORMAT_COMPR, FORMAT_PCM, FORMAT_PCM, FORMAT_PCM, FORMAT_PCM}, //ROUTE_FORMAT
- {NO_TRANSCODER, NO_TRANSCODER, NO_TRANSCODER, AC3_TRANSCODER, NO_TRANSCODER, NO_TRANSCODER, NO_TRANSCODER, NO_TRANSCODER}, //TRANSCODE_FMT
-/* PCM AC3 AC3 AC3 PCM AC3 PCM AC3 */
- {SW_DECODE, SW_PASSTHROUGH, SW_PASSTHROUGH, SW_PASSTHROUGH, DSP_DECODE, SW_PASSTHROUGH, SW_DECODE_MCH, SW_TRANSCODE}, //AC3_IDX
- {FORMAT_PCM, FORMAT_COMPR, FORMAT_COMPR, FORMAT_COMPR, FORMAT_PCM, FORMAT_COMPR, FORMAT_PCM, FORMAT_COMPR}, //ROUTE_FORMAT
- {NO_TRANSCODER, AC3_PASSTHR, AC3_PASSTHR, AC3_PASSTHR, NO_TRANSCODER, AC3_PASSTHR, NO_TRANSCODER, AC3_TRANSCODER}, //TRANSCODE_FMT
-/* PCM EAC3 AC3 AC3 PCM EAC3 PCM PCM */
- {SW_DECODE, SW_PASSTHROUGH, SW_TRANSCODE, SW_TRANSCODE, DSP_DECODE, SW_PASSTHROUGH, SW_DECODE_MCH, SW_TRANSCODE}, //EAC3_IDX
- {FORMAT_PCM, FORMAT_COMPR, FORMAT_COMPR, FORMAT_COMPR, FORMAT_PCM, FORMAT_COMPR, FORMAT_PCM, FORMAT_COMPR}, //ROUTE_FORMAT
- {NO_TRANSCODER, EAC3_PASSTHR, AC3_TRANSCODER, AC3_TRANSCODER, NO_TRANSCODER, EAC3_PASSTHR, NO_TRANSCODER, AC3_TRANSCODER}, //TRANSCODE_FMT
-/* PCM DTS PCM PCM DTS DTS PCM PCM */
- {DSP_DECODE, DSP_PASSTHROUGH, DSP_DECODE, DSP_DECODE, DSP_PASSTHROUGH, DSP_PASSTHROUGH, DSP_DECODE, DSP_DECODE},//DTS_IDX
- {FORMAT_PCM, FORMAT_COMPR, FORMAT_PCM, FORMAT_PCM, FORMAT_COMPR, FORMAT_COMPR, FORMAT_PCM, FORMAT_PCM}, //ROUTE_FORMAT
- {NO_TRANSCODER, DTS_PASSTHR, NO_TRANSCODER, NO_TRANSCODER, DTS_PASSTHR, DTS_PASSTHR, NO_TRANSCODER, NO_TRANSCODER}, //TRANSCODE_FMT
-/* PCM DTS_LBR PCM PCM DTS DTS PCM PCM */
- {DSP_DECODE, DSP_PASSTHROUGH, DSP_DECODE, DSP_DECODE, DSP_PASSTHROUGH, DSP_PASSTHROUGH, DSP_DECODE, DSP_DECODE},//DTS_LBR_IDX
- {FORMAT_PCM, FORMAT_COMPR, FORMAT_PCM, FORMAT_PCM, FORMAT_COMPR, FORMAT_COMPR, FORMAT_PCM, FORMAT_PCM}, //ROUTE_FORMAT
- {NO_TRANSCODER, DTS_PASSTHR, NO_TRANSCODER, NO_TRANSCODER, DTS_PASSTHR, DTS_PASSTHR, NO_TRANSCODER, NO_TRANSCODER}, //TRANSCODE_FMT
-/* PCM PCM PCM PCM DTS PCM PCM PCM */
- {DSP_DECODE, DSP_DECODE, DSP_DECODE, DSP_DECODE, DSP_DECODE|DSP_TRANSCODE, DSP_DECODE, DSP_DECODE, DSP_DECODE}, //MP3_IDX
- {FORMAT_PCM, FORMAT_PCM, FORMAT_PCM, FORMAT_PCM, FORMAT_COMPR, FORMAT_PCM, FORMAT_PCM, FORMAT_PCM}, //ROUTE_FORMAT
- {NO_TRANSCODER, NO_TRANSCODER, NO_TRANSCODER, NO_TRANSCODER, DTS_TRANSCODER, NO_TRANSCODER, NO_TRANSCODER, NO_TRANSCODER}, //TRANSCODE_FMT
-/* PCM PCM PCM PCM DTS PCM PCM PCM */
- {DSP_DECODE, DSP_DECODE, DSP_DECODE, DSP_DECODE, DSP_DECODE|DSP_TRANSCODE, DSP_DECODE, DSP_DECODE, DSP_DECODE}, //WMA_IDX
- {FORMAT_PCM, FORMAT_PCM, FORMAT_PCM, FORMAT_PCM, FORMAT_COMPR, FORMAT_PCM, FORMAT_PCM, FORMAT_PCM}, //ROUTE_FORMAT
- {NO_TRANSCODER, NO_TRANSCODER, NO_TRANSCODER, NO_TRANSCODER, DTS_TRANSCODER, NO_TRANSCODER, NO_TRANSCODER, NO_TRANSCODER}, //TRANSCODE_FMT
-/* PCM PCM PCM PCM DTS PCM PCM PCM */
- {DSP_DECODE, DSP_DECODE, DSP_DECODE, DSP_DECODE, DSP_DECODE|DSP_TRANSCODE, DSP_DECODE, DSP_DECODE, DSP_DECODE}, //WMA_PRO_IDX
- {FORMAT_PCM, FORMAT_PCM, FORMAT_PCM, FORMAT_PCM, FORMAT_COMPR, FORMAT_PCM, FORMAT_PCM, FORMAT_PCM}, //ROUTE_FORMAT
- {NO_TRANSCODER, NO_TRANSCODER, NO_TRANSCODER, NO_TRANSCODER, DTS_TRANSCODER, NO_TRANSCODER, NO_TRANSCODER, NO_TRANSCODER}, //TRANSCODE_FMT
-/* PCM PCM PCM PCM DTS PCM PCM PCM */
- {DSP_DECODE, DSP_DECODE, DSP_DECODE, DSP_DECODE, DSP_DECODE|DSP_TRANSCODE, DSP_DECODE, DSP_DECODE, DSP_DECODE}, //MP2_IDX
- {FORMAT_PCM, FORMAT_PCM, FORMAT_PCM, FORMAT_PCM, FORMAT_COMPR, FORMAT_PCM, FORMAT_PCM, FORMAT_PCM}, //ROUTE_FORMAT
- {NO_TRANSCODER, NO_TRANSCODER, NO_TRANSCODER, NO_TRANSCODER, DTS_TRANSCODER, NO_TRANSCODER, NO_TRANSCODER, NO_TRANSCODER} //TRANSCODE_FMT
-};
-/*
-List of decoders which require config as part of first buffer
-*/
-static const int decodersRequireConfig[] = {
- AUDIO_FORMAT_AAC,
- AUDIO_FORMAT_HE_AAC_V1,
- AUDIO_FORMAT_HE_AAC_V2,
- AUDIO_FORMAT_AAC_ADIF,
- AUDIO_FORMAT_WMA,
- AUDIO_FORMAT_WMA_PRO
-};
-/*
-List of enum that are used in Broadcast.
-NOTE: Need to be removed once broadcast is moved with updated states as above
-*/
-enum {
- INVALID_FORMAT = -1,
- PCM_FORMAT = 0,
- COMPRESSED_FORMAT = 1,
- COMPRESSED_FORCED_PCM_FORMAT = 2,
- COMPRESSED_PASSTHROUGH_FORMAT = 3
-};
-
-
-struct audio_bitstream_sm {
- int buffering_factor;
- int buffering_factor_cnt;
- // Buffer pointers for input and output
- char *inp_buf;
- char *inp_buf_curr_ptr;
- char *inp_buf_write_ptr;
- uint32_t inp_buf_size;
-
- char *enc_out_buf;
- char *enc_out_buf_write_ptr;
- uint32_t enc_out_buf_size;
-
- char *pcm_2_out_buf;
- char *pcm_2_out_buf_write_ptr;
- uint32_t pcm_2_out_buf_size;
-
- char *pcm_mch_out_buf;
- char *pcm_mch_out_buf_write_ptr;
- uint32_t pcm_mch_out_buf_size;
-
- char *passt_out_buf;
- char *passt_out_buf_write_ptr;
- uint32_t passt_out_buf_size;
-};
-
-/*
-Meta data structure for handling compressed output
-*/
-struct output_metadata {
- uint32_t metadataLength;
- uint32_t bufferLength;
- uint64_t timestamp;
- uint32_t reserved[12];
-};
-
-#endif // QCOM_AUDIO_PLATFORM_H
diff --git a/hal_mpq/platform_api.h b/hal_mpq/platform_api.h
deleted file mode 100644
index 955aa3b..0000000
--- a/hal_mpq/platform_api.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
- * Not a contribution.
- *
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef QCOM_AUDIO_PLATFORM_API_H
-#define QCOM_AUDIO_PLATFORM_API_H
-
-void *platform_init(struct audio_device *adev);
-void platform_deinit(void *platform);
-const char *platform_get_snd_device_name(snd_device_t snd_device);
-int platform_get_snd_device_name_extn(void *platform, snd_device_t snd_device,
- char *device_name);
-void platform_add_backend_name(char *mixer_path, snd_device_t snd_device);
-int platform_get_pcm_device_id(audio_usecase_t usecase, int device_type);
-int platform_send_audio_calibration(void *platform, snd_device_t snd_device);
-int platform_switch_voice_call_device_pre(void *platform);
-int platform_switch_voice_call_device_post(void *platform,
- snd_device_t out_snd_device,
- snd_device_t in_snd_device);
-int platform_switch_voice_call_usecase_route_post(void *platform,
- snd_device_t out_snd_device,
- snd_device_t in_snd_device);
-int platform_start_voice_call(void *platform, uint32_t vsid);
-int platform_stop_voice_call(void *platform, uint32_t vsid);
-int platform_set_voice_volume(void *platform, int volume);
-int platform_set_mic_mute(void *platform, bool state);
-snd_device_t platform_get_output_snd_device(void *platform, audio_devices_t devices);
-snd_device_t platform_get_input_snd_device(void *platform, audio_devices_t out_device);
-int platform_set_hdmi_channels(void *platform, int channel_count);
-int platform_edid_get_max_channels(void *platform);
-void platform_get_parameters(void *platform, struct str_parms *query,
- struct str_parms *reply);
-int platform_set_parameters(void *platform, struct str_parms *parms);
-int platform_set_incall_recoding_session_id(void *platform, uint32_t session_id);
-
-/* returns the latency for a usecase in Us */
-int64_t platform_render_latency(audio_usecase_t usecase);
-int platform_update_usecase_from_source(int source, audio_usecase_t usecase);
-audio_usecase_t platform_get_usecase(audio_usecase_stream_type_t uc_type);
-int platform_free_usecase(audio_usecase_t uc_id);
-
-#endif // QCOM_AUDIO_PLATFORM_API_H
diff --git a/legacy/Android.mk b/legacy/Android.mk
deleted file mode 100644
index 95d9ada..0000000
--- a/legacy/Android.mk
+++ /dev/null
@@ -1,5 +0,0 @@
-ifneq ($(filter msm8960,$(TARGET_BOARD_PLATFORM)),)
-
-include $(call all-subdir-makefiles)
-
-endif
diff --git a/legacy/alsa_sound/ALSAControl.cpp b/legacy/alsa_sound/ALSAControl.cpp
deleted file mode 100644
index 5b2cf31..0000000
--- a/legacy/alsa_sound/ALSAControl.cpp
+++ /dev/null
@@ -1,131 +0,0 @@
-/* ALSAControl.cpp
- **
- ** Copyright 2008-2009 Wind River Systems
- ** Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
- **
- ** Licensed under the Apache License, Version 2.0 (the "License");
- ** you may not use this file except in compliance with the License.
- ** You may obtain a copy of the License at
- **
- ** http://www.apache.org/licenses/LICENSE-2.0
- **
- ** Unless required by applicable law or agreed to in writing, software
- ** distributed under the License is distributed on an "AS IS" BASIS,
- ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ** See the License for the specific language governing permissions and
- ** limitations under the License.
- */
-
-#include <errno.h>
-#include <stdarg.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <dlfcn.h>
-
-#define LOG_TAG "ALSAControl"
-//#define LOG_NDEBUG 0
-#define LOG_NDDEBUG 0
-#include <utils/Log.h>
-#include <utils/String8.h>
-
-#include <cutils/properties.h>
-#include <media/AudioRecord.h>
-#include <hardware_legacy/power.h>
-
-#include "AudioHardwareALSA.h"
-
-namespace android_audio_legacy
-{
-
-ALSAControl::ALSAControl(const char *device)
-{
- ALOGD("ALSAControl: ctor device %s", device);
- mHandle = mixer_open(device);
- ALOGV("ALSAControl: ctor mixer %p", mHandle);
-}
-
-ALSAControl::~ALSAControl()
-{
- if (mHandle) mixer_close(mHandle);
-}
-
-status_t ALSAControl::get(const char *name, unsigned int &value, int index)
-{
- struct mixer_ctl *ctl;
-
- if (!mHandle) {
- ALOGE("Control not initialized");
- return NO_INIT;
- }
-
- ctl = mixer_get_control(mHandle, name, index);
- if (!ctl)
- return BAD_VALUE;
-
- mixer_ctl_get(ctl, &value);
- return NO_ERROR;
-}
-
-status_t ALSAControl::set(const char *name, unsigned int value, int index)
-{
- struct mixer_ctl *ctl;
- int ret = 0;
- ALOGD("set:: name %s value %d index %d", name, value, index);
- if (!mHandle) {
- ALOGE("Control not initialized");
- return NO_INIT;
- }
-
- // ToDo: Do we need to send index here? Right now it works with 0
- ctl = mixer_get_control(mHandle, name, 0);
- if(ctl == NULL) {
- ALOGE("Could not get the mixer control");
- return BAD_VALUE;
- }
- ret = mixer_ctl_set(ctl, value);
- return (ret < 0) ? BAD_VALUE : NO_ERROR;
-}
-
-status_t ALSAControl::set(const char *name, const char *value)
-{
- struct mixer_ctl *ctl;
- int ret = 0;
- ALOGD("set:: name %s value %s", name, value);
-
- if (!mHandle) {
- ALOGE("Control not initialized");
- return NO_INIT;
- }
-
- ctl = mixer_get_control(mHandle, name, 0);
- if(ctl == NULL) {
- ALOGE("Could not get the mixer control");
- return BAD_VALUE;
- }
- ret = mixer_ctl_select(ctl, value);
- return (ret < 0) ? BAD_VALUE : NO_ERROR;
-}
-
-status_t ALSAControl::setext(const char *name, int count, char **setValues)
-{
- struct mixer_ctl *ctl;
- int ret = 0;
- ALOGD("setext:: name %s count %d", name, count);
- if (!mHandle) {
- ALOGE("Control not initialized");
- return NO_INIT;
- }
-
- // ToDo: Do we need to send index here? Right now it works with 0
- ctl = mixer_get_control(mHandle, name, 0);
- if(ctl == NULL) {
- ALOGE("Could not get the mixer control");
- return BAD_VALUE;
- }
- ret = mixer_ctl_set_value(ctl, count, setValues);
- return (ret < 0) ? BAD_VALUE : NO_ERROR;
-}
-
-}; // namespace android
diff --git a/legacy/alsa_sound/ALSAMixer.cpp b/legacy/alsa_sound/ALSAMixer.cpp
deleted file mode 100644
index d1383cf..0000000
--- a/legacy/alsa_sound/ALSAMixer.cpp
+++ /dev/null
@@ -1,433 +0,0 @@
-/* ALSAMixer.cpp
- **
- ** Copyright 2008-2010 Wind River Systems
- **
- ** Licensed under the Apache License, Version 2.0 (the "License");
- ** you may not use this file except in compliance with the License.
- ** You may obtain a copy of the License at
- **
- ** http://www.apache.org/licenses/LICENSE-2.0
- **
- ** Unless required by applicable law or agreed to in writing, software
- ** distributed under the License is distributed on an "AS IS" BASIS,
- ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ** See the License for the specific language governing permissions and
- ** limitations under the License.
- */
-
-#include <errno.h>
-#include <stdarg.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <dlfcn.h>
-
-#define LOG_TAG "AudioHardwareALSA"
-#include <utils/Log.h>
-#include <utils/String8.h>
-
-#include <cutils/properties.h>
-#include <media/AudioRecord.h>
-#include <hardware_legacy/power.h>
-
-#include "AudioHardwareALSA.h"
-
-#define SND_MIXER_VOL_RANGE_MIN (0)
-#define SND_MIXER_VOL_RANGE_MAX (100)
-
-#define ALSA_NAME_MAX 128
-
-#define ALSA_STRCAT(x,y) \
- if (strlen(x) + strlen(y) < ALSA_NAME_MAX) \
- strcat(x, y);
-
-namespace android
-{
-
-// ----------------------------------------------------------------------------
-
-struct mixer_info_t;
-
-struct alsa_properties_t
-{
- const AudioSystem::audio_devices device;
- const char *propName;
- const char *propDefault;
- mixer_info_t *mInfo;
-};
-
-#define ALSA_PROP(dev, name, out, in) \
- {\
- {dev, "alsa.mixer.playback." name, out, NULL},\
- {dev, "alsa.mixer.capture." name, in, NULL}\
- }
-
-static alsa_properties_t
-mixerMasterProp[SND_PCM_STREAM_LAST+1] =
- ALSA_PROP(AudioSystem::DEVICE_OUT_ALL, "master", "PCM", "Capture");
-
-static alsa_properties_t
-mixerProp[][SND_PCM_STREAM_LAST+1] = {
- ALSA_PROP(AudioSystem::DEVICE_OUT_EARPIECE, "earpiece", "Earpiece", "Capture"),
- ALSA_PROP(AudioSystem::DEVICE_OUT_SPEAKER, "speaker", "Speaker", ""),
- ALSA_PROP(AudioSystem::DEVICE_OUT_WIRED_HEADSET, "headset", "Headphone", "Capture"),
- ALSA_PROP(AudioSystem::DEVICE_OUT_BLUETOOTH_SCO, "bluetooth.sco", "Bluetooth", "Bluetooth Capture"),
- ALSA_PROP(AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP, "bluetooth.a2dp", "Bluetooth A2DP", "Bluetooth A2DP Capture"),
- ALSA_PROP(static_cast<AudioSystem::audio_devices>(0), "", NULL, NULL)
-};
-
-struct mixer_info_t
-{
- mixer_info_t() :
- elem(0),
- min(SND_MIXER_VOL_RANGE_MIN),
- max(SND_MIXER_VOL_RANGE_MAX),
- mute(false)
- {
- }
-
- snd_mixer_elem_t *elem;
- long min;
- long max;
- long volume;
- bool mute;
- char name[ALSA_NAME_MAX];
-};
-
-static int initMixer (snd_mixer_t **mixer, const char *name)
-{
- int err;
-
- if ((err = snd_mixer_open(mixer, 0)) < 0) {
- ALOGE("Unable to open mixer: %s", snd_strerror(err));
- return err;
- }
-
- if ((err = snd_mixer_attach(*mixer, name)) < 0) {
- ALOGW("Unable to attach mixer to device %s: %s",
- name, snd_strerror(err));
-
- if ((err = snd_mixer_attach(*mixer, "hw:00")) < 0) {
- ALOGE("Unable to attach mixer to device default: %s",
- snd_strerror(err));
-
- snd_mixer_close (*mixer);
- *mixer = NULL;
- return err;
- }
- }
-
- if ((err = snd_mixer_selem_register(*mixer, NULL, NULL)) < 0) {
- ALOGE("Unable to register mixer elements: %s", snd_strerror(err));
- snd_mixer_close (*mixer);
- *mixer = NULL;
- return err;
- }
-
- // Get the mixer controls from the kernel
- if ((err = snd_mixer_load(*mixer)) < 0) {
- ALOGE("Unable to load mixer elements: %s", snd_strerror(err));
- snd_mixer_close (*mixer);
- *mixer = NULL;
- return err;
- }
-
- return 0;
-}
-
-typedef int (*hasVolume_t)(snd_mixer_elem_t*);
-
-static const hasVolume_t hasVolume[] = {
- snd_mixer_selem_has_playback_volume,
- snd_mixer_selem_has_capture_volume
-};
-
-typedef int (*getVolumeRange_t)(snd_mixer_elem_t*, long int*, long int*);
-
-static const getVolumeRange_t getVolumeRange[] = {
- snd_mixer_selem_get_playback_volume_range,
- snd_mixer_selem_get_capture_volume_range
-};
-
-typedef int (*setVolume_t)(snd_mixer_elem_t*, long int);
-
-static const setVolume_t setVol[] = {
- snd_mixer_selem_set_playback_volume_all,
- snd_mixer_selem_set_capture_volume_all
-};
-
-ALSAMixer::ALSAMixer()
-{
- int err;
-
- initMixer (&mMixer[SND_PCM_STREAM_PLAYBACK], "AndroidOut");
- initMixer (&mMixer[SND_PCM_STREAM_CAPTURE], "AndroidIn");
-
- snd_mixer_selem_id_t *sid;
- snd_mixer_selem_id_alloca(&sid);
-
- for (int i = 0; i <= SND_PCM_STREAM_LAST; i++) {
-
- if (!mMixer[i]) continue;
-
- mixer_info_t *info = mixerMasterProp[i].mInfo = new mixer_info_t;
-
- property_get (mixerMasterProp[i].propName,
- info->name,
- mixerMasterProp[i].propDefault);
-
- for (snd_mixer_elem_t *elem = snd_mixer_first_elem(mMixer[i]);
- elem;
- elem = snd_mixer_elem_next(elem)) {
-
- if (!snd_mixer_selem_is_active(elem))
- continue;
-
- snd_mixer_selem_get_id(elem, sid);
-
- // Find PCM playback volume control element.
- const char *elementName = snd_mixer_selem_id_get_name(sid);
-
- if (info->elem == NULL &&
- strcmp(elementName, info->name) == 0 &&
- hasVolume[i] (elem)) {
-
- info->elem = elem;
- getVolumeRange[i] (elem, &info->min, &info->max);
- info->volume = info->max;
- setVol[i] (elem, info->volume);
- if (i == SND_PCM_STREAM_PLAYBACK &&
- snd_mixer_selem_has_playback_switch (elem))
- snd_mixer_selem_set_playback_switch_all (elem, 1);
- break;
- }
- }
-
- ALOGV("Mixer: master '%s' %s.", info->name, info->elem ? "found" : "not found");
-
- for (int j = 0; mixerProp[j][i].device; j++) {
-
- mixer_info_t *info = mixerProp[j][i].mInfo = new mixer_info_t;
-
- property_get (mixerProp[j][i].propName,
- info->name,
- mixerProp[j][i].propDefault);
-
- for (snd_mixer_elem_t *elem = snd_mixer_first_elem(mMixer[i]);
- elem;
- elem = snd_mixer_elem_next(elem)) {
-
- if (!snd_mixer_selem_is_active(elem))
- continue;
-
- snd_mixer_selem_get_id(elem, sid);
-
- // Find PCM playback volume control element.
- const char *elementName = snd_mixer_selem_id_get_name(sid);
-
- if (info->elem == NULL &&
- strcmp(elementName, info->name) == 0 &&
- hasVolume[i] (elem)) {
-
- info->elem = elem;
- getVolumeRange[i] (elem, &info->min, &info->max);
- info->volume = info->max;
- setVol[i] (elem, info->volume);
- if (i == SND_PCM_STREAM_PLAYBACK &&
- snd_mixer_selem_has_playback_switch (elem))
- snd_mixer_selem_set_playback_switch_all (elem, 1);
- break;
- }
- }
- ALOGV("Mixer: route '%s' %s.", info->name, info->elem ? "found" : "not found");
- }
- }
- ALOGV("mixer initialized.");
-}
-
-ALSAMixer::~ALSAMixer()
-{
- for (int i = 0; i <= SND_PCM_STREAM_LAST; i++) {
- if (mMixer[i]) snd_mixer_close (mMixer[i]);
- if (mixerMasterProp[i].mInfo) {
- delete mixerMasterProp[i].mInfo;
- mixerMasterProp[i].mInfo = NULL;
- }
- for (int j = 0; mixerProp[j][i].device; j++) {
- if (mixerProp[j][i].mInfo) {
- delete mixerProp[j][i].mInfo;
- mixerProp[j][i].mInfo = NULL;
- }
- }
- }
- ALOGV("mixer destroyed.");
-}
-
-status_t ALSAMixer::setMasterVolume(float volume)
-{
- mixer_info_t *info = mixerMasterProp[SND_PCM_STREAM_PLAYBACK].mInfo;
- if (!info || !info->elem) return INVALID_OPERATION;
-
- long minVol = info->min;
- long maxVol = info->max;
-
- // Make sure volume is between bounds.
- long vol = minVol + volume * (maxVol - minVol);
- if (vol > maxVol) vol = maxVol;
- if (vol < minVol) vol = minVol;
-
- info->volume = vol;
- snd_mixer_selem_set_playback_volume_all (info->elem, vol);
-
- return NO_ERROR;
-}
-
-status_t ALSAMixer::setMasterGain(float gain)
-{
- mixer_info_t *info = mixerMasterProp[SND_PCM_STREAM_CAPTURE].mInfo;
- if (!info || !info->elem) return INVALID_OPERATION;
-
- long minVol = info->min;
- long maxVol = info->max;
-
- // Make sure volume is between bounds.
- long vol = minVol + gain * (maxVol - minVol);
- if (vol > maxVol) vol = maxVol;
- if (vol < minVol) vol = minVol;
-
- info->volume = vol;
- snd_mixer_selem_set_capture_volume_all (info->elem, vol);
-
- return NO_ERROR;
-}
-
-status_t ALSAMixer::setVolume(uint32_t device, float left, float right)
-{
- for (int j = 0; mixerProp[j][SND_PCM_STREAM_PLAYBACK].device; j++)
- if (mixerProp[j][SND_PCM_STREAM_PLAYBACK].device & device) {
-
- mixer_info_t *info = mixerProp[j][SND_PCM_STREAM_PLAYBACK].mInfo;
- if (!info || !info->elem) return INVALID_OPERATION;
-
- long minVol = info->min;
- long maxVol = info->max;
-
- // Make sure volume is between bounds.
- long vol = minVol + left * (maxVol - minVol);
- if (vol > maxVol) vol = maxVol;
- if (vol < minVol) vol = minVol;
-
- info->volume = vol;
- snd_mixer_selem_set_playback_volume_all (info->elem, vol);
- }
-
- return NO_ERROR;
-}
-
-status_t ALSAMixer::setGain(uint32_t device, float gain)
-{
- for (int j = 0; mixerProp[j][SND_PCM_STREAM_CAPTURE].device; j++)
- if (mixerProp[j][SND_PCM_STREAM_CAPTURE].device & device) {
-
- mixer_info_t *info = mixerProp[j][SND_PCM_STREAM_CAPTURE].mInfo;
- if (!info || !info->elem) return INVALID_OPERATION;
-
- long minVol = info->min;
- long maxVol = info->max;
-
- // Make sure volume is between bounds.
- long vol = minVol + gain * (maxVol - minVol);
- if (vol > maxVol) vol = maxVol;
- if (vol < minVol) vol = minVol;
-
- info->volume = vol;
- snd_mixer_selem_set_capture_volume_all (info->elem, vol);
- }
-
- return NO_ERROR;
-}
-
-status_t ALSAMixer::setCaptureMuteState(uint32_t device, bool state)
-{
- for (int j = 0; mixerProp[j][SND_PCM_STREAM_CAPTURE].device; j++)
- if (mixerProp[j][SND_PCM_STREAM_CAPTURE].device & device) {
-
- mixer_info_t *info = mixerProp[j][SND_PCM_STREAM_CAPTURE].mInfo;
- if (!info || !info->elem) return INVALID_OPERATION;
-
- if (snd_mixer_selem_has_capture_switch (info->elem)) {
-
- int err = snd_mixer_selem_set_capture_switch_all (info->elem, static_cast<int>(!state));
- if (err < 0) {
- ALOGE("Unable to %s capture mixer switch %s",
- state ? "enable" : "disable", info->name);
- return INVALID_OPERATION;
- }
- }
-
- info->mute = state;
- }
-
- return NO_ERROR;
-}
-
-status_t ALSAMixer::getCaptureMuteState(uint32_t device, bool *state)
-{
- if (!state) return BAD_VALUE;
-
- for (int j = 0; mixerProp[j][SND_PCM_STREAM_CAPTURE].device; j++)
- if (mixerProp[j][SND_PCM_STREAM_CAPTURE].device & device) {
-
- mixer_info_t *info = mixerProp[j][SND_PCM_STREAM_CAPTURE].mInfo;
- if (!info || !info->elem) return INVALID_OPERATION;
-
- *state = info->mute;
- return NO_ERROR;
- }
-
- return BAD_VALUE;
-}
-
-status_t ALSAMixer::setPlaybackMuteState(uint32_t device, bool state)
-{
- for (int j = 0; mixerProp[j][SND_PCM_STREAM_PLAYBACK].device; j++)
- if (mixerProp[j][SND_PCM_STREAM_PLAYBACK].device & device) {
-
- mixer_info_t *info = mixerProp[j][SND_PCM_STREAM_PLAYBACK].mInfo;
- if (!info || !info->elem) return INVALID_OPERATION;
-
- if (snd_mixer_selem_has_playback_switch (info->elem)) {
-
- int err = snd_mixer_selem_set_playback_switch_all (info->elem, static_cast<int>(!state));
- if (err < 0) {
- ALOGE("Unable to %s playback mixer switch %s",
- state ? "enable" : "disable", info->name);
- return INVALID_OPERATION;
- }
- }
-
- info->mute = state;
- }
-
- return NO_ERROR;
-}
-
-status_t ALSAMixer::getPlaybackMuteState(uint32_t device, bool *state)
-{
- if (!state) return BAD_VALUE;
-
- for (int j = 0; mixerProp[j][SND_PCM_STREAM_PLAYBACK].device; j++)
- if (mixerProp[j][SND_PCM_STREAM_PLAYBACK].device & device) {
-
- mixer_info_t *info = mixerProp[j][SND_PCM_STREAM_PLAYBACK].mInfo;
- if (!info || !info->elem) return INVALID_OPERATION;
-
- *state = info->mute;
- return NO_ERROR;
- }
-
- return BAD_VALUE;
-}
-
-}; // namespace android
diff --git a/legacy/alsa_sound/ALSAStreamOps.cpp b/legacy/alsa_sound/ALSAStreamOps.cpp
deleted file mode 100644
index ad9a117..0000000
--- a/legacy/alsa_sound/ALSAStreamOps.cpp
+++ /dev/null
@@ -1,375 +0,0 @@
-/* ALSAStreamOps.cpp
- **
- ** Copyright 2008-2009 Wind River Systems
- ** Copyright (c) 2011, The Linux Foundation. All rights reserved.
- **
- ** Licensed under the Apache License, Version 2.0 (the "License");
- ** you may not use this file except in compliance with the License.
- ** You may obtain a copy of the License at
- **
- ** http://www.apache.org/licenses/LICENSE-2.0
- **
- ** Unless required by applicable law or agreed to in writing, software
- ** distributed under the License is distributed on an "AS IS" BASIS,
- ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ** See the License for the specific language governing permissions and
- ** limitations under the License.
- */
-
-#include <errno.h>
-#include <stdarg.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <dlfcn.h>
-
-#define LOG_TAG "ALSAStreamOps"
-//#define LOG_NDEBUG 0
-#define LOG_NDDEBUG 0
-#include <utils/Log.h>
-#include <utils/String8.h>
-
-#include <cutils/properties.h>
-#include <media/AudioRecord.h>
-#include <hardware_legacy/power.h>
-#include "AudioUtil.h"
-#include "AudioHardwareALSA.h"
-
-namespace android_audio_legacy
-{
-
-// unused 'enumVal;' is to catch error at compile time if enumVal ever changes
-// or applied on a non-existent enum
-#define ENUM_TO_STRING(var, enumVal) {var = #enumVal; enumVal;}
-
-// ----------------------------------------------------------------------------
-
-ALSAStreamOps::ALSAStreamOps(AudioHardwareALSA *parent, alsa_handle_t *handle) :
- mParent(parent),
- mHandle(handle)
-{
-}
-
-ALSAStreamOps::~ALSAStreamOps()
-{
- Mutex::Autolock autoLock(mParent->mLock);
-
- if((!strcmp(mHandle->useCase, SND_USE_CASE_VERB_IP_VOICECALL)) ||
- (!strcmp(mHandle->useCase, SND_USE_CASE_MOD_PLAY_VOIP))) {
- if((mParent->mVoipStreamCount)) {
- mParent->mVoipStreamCount--;
- if(mParent->mVoipStreamCount > 0) {
- ALOGD("ALSAStreamOps::close() Ignore");
- return ;
- }
- }
- mParent->mVoipStreamCount = 0;
- mParent->mVoipBitRate = 0;
- }
- close();
-
- for(ALSAHandleList::iterator it = mParent->mDeviceList.begin();
- it != mParent->mDeviceList.end(); ++it) {
- if (mHandle == &(*it)) {
- it->useCase[0] = 0;
- mParent->mDeviceList.erase(it);
- break;
- }
- }
-}
-
-// use emulated popcount optimization
-// http://www.df.lth.se/~john_e/gems/gem002d.html
-static inline uint32_t popCount(uint32_t u)
-{
- u = ((u&0x55555555) + ((u>>1)&0x55555555));
- u = ((u&0x33333333) + ((u>>2)&0x33333333));
- u = ((u&0x0f0f0f0f) + ((u>>4)&0x0f0f0f0f));
- u = ((u&0x00ff00ff) + ((u>>8)&0x00ff00ff));
- u = ( u&0x0000ffff) + (u>>16);
- return u;
-}
-
-status_t ALSAStreamOps::set(int *format,
- uint32_t *channels,
- uint32_t *rate,
- uint32_t device)
-{
- mDevices = device;
- if (channels && *channels != 0) {
- if (mHandle->channels != popCount(*channels))
- return BAD_VALUE;
- } else if (channels) {
- if (mHandle->devices & AudioSystem::DEVICE_OUT_ALL) {
- switch(*channels) {
- case AUDIO_CHANNEL_OUT_5POINT1: // 5.0
- case (AUDIO_CHANNEL_OUT_QUAD | AUDIO_CHANNEL_OUT_FRONT_CENTER): // 5.1
- case AUDIO_CHANNEL_OUT_QUAD:
- case AUDIO_CHANNEL_OUT_STEREO:
- case AUDIO_CHANNEL_OUT_MONO:
- break;
- default:
- *channels = AUDIO_CHANNEL_OUT_STEREO;
- return BAD_VALUE;
- }
- } else {
- switch(*channels) {
-#ifdef QCOM_SSR_ENABLED
- // For 5.1 recording
- case AudioSystem::CHANNEL_IN_5POINT1:
-#endif
- // Do not fall through...
- case AUDIO_CHANNEL_IN_MONO:
- case AUDIO_CHANNEL_IN_STEREO:
- case AUDIO_CHANNEL_IN_FRONT_BACK:
- break;
- default:
- *channels = AUDIO_CHANNEL_IN_MONO;
- return BAD_VALUE;
- }
- }
- }
-
- if (rate && *rate > 0) {
- if (mHandle->sampleRate != *rate)
- return BAD_VALUE;
- } else if (rate) {
- *rate = mHandle->sampleRate;
- }
-
- snd_pcm_format_t iformat = mHandle->format;
-
- if (format) {
- switch(*format) {
- case AudioSystem::FORMAT_DEFAULT:
- break;
-
- case AudioSystem::PCM_16_BIT:
- iformat = SNDRV_PCM_FORMAT_S16_LE;
- break;
- case AudioSystem::AMR_NB:
- case AudioSystem::AMR_WB:
-#ifdef QCOM_QCHAT_ENABLED
- case AudioSystem::EVRC:
- case AudioSystem::EVRCB:
- case AudioSystem::EVRCWB:
-#endif
- iformat = *format;
- break;
-
- case AudioSystem::PCM_8_BIT:
- iformat = SNDRV_PCM_FORMAT_S8;
- break;
-
- default:
- ALOGE("Unknown PCM format %i. Forcing default", *format);
- break;
- }
-
- if (mHandle->format != iformat)
- return BAD_VALUE;
-
- switch(iformat) {
- case SNDRV_PCM_FORMAT_S16_LE:
- *format = AudioSystem::PCM_16_BIT;
- break;
- case SNDRV_PCM_FORMAT_S8:
- *format = AudioSystem::PCM_8_BIT;
- break;
- default:
- break;
- }
- }
-
- return NO_ERROR;
-}
-
-status_t ALSAStreamOps::setParameters(const String8& keyValuePairs)
-{
- AudioParameter param = AudioParameter(keyValuePairs);
- String8 key = String8(AudioParameter::keyRouting);
- int device;
-
-#ifdef SEPERATED_AUDIO_INPUT
- String8 key_input = String8(AudioParameter::keyInputSource);
- int source;
-
- if (param.getInt(key_input, source) == NO_ERROR) {
- ALOGD("setParameters(), input_source = %d", source);
- mParent->mALSADevice->setInput(source);
- param.remove(key_input);
- }
-#endif
-
- if (param.getInt(key, device) == NO_ERROR) {
- // Ignore routing if device is 0.
- ALOGD("setParameters(): keyRouting with device 0x%x", device);
- // reset to speaker when disconnecting HDMI to avoid timeout due to write errors
- if ((device == 0) && (mDevices == AudioSystem::DEVICE_OUT_AUX_DIGITAL)) {
- device = AudioSystem::DEVICE_OUT_SPEAKER;
- }
- if (device)
- mDevices = device;
- else
- ALOGV("must not change mDevices to 0");
-
- if(device) {
- mParent->doRouting(device);
- }
- param.remove(key);
- }
-#ifdef QCOM_FM_ENABLED
- else {
- key = String8(AudioParameter::keyHandleFm);
- if (param.getInt(key, device) == NO_ERROR) {
- ALOGD("setParameters(): handleFm with device %d", device);
- mDevices = device;
- if(device) {
- mParent->handleFm(device);
- }
- param.remove(key);
- }
- }
-#endif
-
- return NO_ERROR;
-}
-
-String8 ALSAStreamOps::getParameters(const String8& keys)
-{
- AudioParameter param = AudioParameter(keys);
- String8 value;
- String8 key = String8(AudioParameter::keyRouting);
-
- if (param.get(key, value) == NO_ERROR) {
- param.addInt(key, (int)mDevices);
- }
- else {
-#ifdef QCOM_VOIP_ENABLED
- key = String8(AudioParameter::keyVoipCheck);
- if (param.get(key, value) == NO_ERROR) {
- if((!strncmp(mHandle->useCase, SND_USE_CASE_VERB_IP_VOICECALL, strlen(SND_USE_CASE_VERB_IP_VOICECALL))) ||
- (!strncmp(mHandle->useCase, SND_USE_CASE_MOD_PLAY_VOIP, strlen(SND_USE_CASE_MOD_PLAY_VOIP))))
- param.addInt(key, true);
- else
- param.addInt(key, false);
- }
-#endif
- }
- key = String8(AUDIO_PARAMETER_STREAM_SUP_CHANNELS);
- if (param.get(key, value) == NO_ERROR) {
- EDID_AUDIO_INFO info = { 0 };
- bool first = true;
- value = String8();
- if (AudioUtil::getHDMIAudioSinkCaps(&info)) {
- for (int i = 0; i < info.nAudioBlocks && i < MAX_EDID_BLOCKS; i++) {
- String8 append;
- switch (info.AudioBlocksArray[i].nChannels) {
- //Do not handle stereo output in Multi-channel cases
- //Stereo case is handled in normal playback path
- case 6:
- ENUM_TO_STRING(append, AUDIO_CHANNEL_OUT_5POINT1);
- break;
- case 8:
- ENUM_TO_STRING(append, AUDIO_CHANNEL_OUT_7POINT1);
- break;
- default:
- ALOGD("Unsupported number of channels %d", info.AudioBlocksArray[i].nChannels);
- break;
- }
- if (!append.isEmpty()) {
- value += (first ? append : String8("|") + append);
- first = false;
- }
- }
- } else {
- ALOGE("Failed to get HDMI sink capabilities");
- }
- param.add(key, value);
- }
- ALOGV("getParameters() %s", param.toString().string());
- return param.toString();
-}
-
-uint32_t ALSAStreamOps::sampleRate() const
-{
- return mHandle->sampleRate;
-}
-
-//
-// Return the number of bytes (not frames)
-//
-size_t ALSAStreamOps::bufferSize() const
-{
- ALOGV("bufferSize() returns %d", mHandle->bufferSize);
- return mHandle->bufferSize;
-}
-
-int ALSAStreamOps::format() const
-{
- int audioSystemFormat;
-
- snd_pcm_format_t ALSAFormat = mHandle->format;
-
- switch(ALSAFormat) {
- case SNDRV_PCM_FORMAT_S8:
- audioSystemFormat = AudioSystem::PCM_8_BIT;
- break;
-
- case AudioSystem::AMR_NB:
- case AudioSystem::AMR_WB:
-#ifdef QCOM_QCHAT_ENABLED
- case AudioSystem::EVRC:
- case AudioSystem::EVRCB:
- case AudioSystem::EVRCWB:
-#endif
- audioSystemFormat = mHandle->format;
- break;
- case SNDRV_PCM_FORMAT_S16_LE:
- audioSystemFormat = AudioSystem::PCM_16_BIT;
- break;
-
- default:
- LOG_FATAL("Unknown AudioSystem bit width %d!", audioSystemFormat);
- audioSystemFormat = AudioSystem::PCM_16_BIT;
- break;
- }
-
- ALOGV("ALSAFormat:0x%x,audioSystemFormat:0x%x",ALSAFormat,audioSystemFormat);
- return audioSystemFormat;
-}
-
-uint32_t ALSAStreamOps::channels() const
-{
- return mHandle->channelMask;
-}
-
-void ALSAStreamOps::close()
-{
- ALOGD("close");
- if((!strncmp(mHandle->useCase, SND_USE_CASE_VERB_IP_VOICECALL, strlen(SND_USE_CASE_VERB_IP_VOICECALL))) ||
- (!strncmp(mHandle->useCase, SND_USE_CASE_MOD_PLAY_VOIP, strlen(SND_USE_CASE_MOD_PLAY_VOIP)))) {
- mParent->mVoipBitRate = 0;
- mParent->mVoipStreamCount = 0;
- }
- mParent->mALSADevice->close(mHandle);
-}
-
-//
-// Set playback or capture PCM device. It's possible to support audio output
-// or input from multiple devices by using the ALSA plugins, but this is
-// not supported for simplicity.
-//
-// The AudioHardwareALSA API does not allow one to set the input routing.
-//
-// If the "routes" value does not map to a valid device, the default playback
-// device is used.
-//
-status_t ALSAStreamOps::open(int mode)
-{
- ALOGD("open");
- return mParent->mALSADevice->open(mHandle);
-}
-
-} // namespace androidi_audio_legacy
diff --git a/legacy/alsa_sound/Android.mk b/legacy/alsa_sound/Android.mk
deleted file mode 100644
index 534dd6a..0000000
--- a/legacy/alsa_sound/Android.mk
+++ /dev/null
@@ -1,141 +0,0 @@
-# hardware/libaudio-alsa/Android.mk
-#
-# Copyright 2008 Wind River Systems
-#
-
-ifeq ($(strip $(BOARD_USES_ALSA_AUDIO)),true)
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_ARM_MODE := arm
-LOCAL_CFLAGS := -D_POSIX_SOURCE
-LOCAL_CFLAGS += -DQCOM_CSDCLIENT_ENABLED
-LOCAL_CFLAGS += -DQCOM_ACDB_ENABLED
-
-ifeq ($(strip $(BOARD_USES_FLUENCE_INCALL)),true)
-LOCAL_CFLAGS += -DUSES_FLUENCE_INCALL
-endif
-
-ifeq ($(strip $(BOARD_USES_SEPERATED_AUDIO_INPUT)),true)
-LOCAL_CFLAGS += -DSEPERATED_AUDIO_INPUT
-endif
-
-LOCAL_SRC_FILES := \
- AudioHardwareALSA.cpp \
- AudioStreamOutALSA.cpp \
- AudioStreamInALSA.cpp \
- ALSAStreamOps.cpp \
- audio_hw_hal.cpp \
- AudioUsbALSA.cpp \
- AudioUtil.cpp
-
-LOCAL_STATIC_LIBRARIES := \
- libmedia_helper \
- libaudiohw_legacy \
- libaudiopolicy_legacy \
-
-LOCAL_SHARED_LIBRARIES := \
- libcutils \
- libutils \
- libmedia \
- libhardware \
- libc \
- libpower \
- libalsa-intf
-
-ifeq ($(TARGET_SIMULATOR),true)
- LOCAL_LDLIBS += -ldl
-else
- LOCAL_SHARED_LIBRARIES += libdl
-endif
-
-LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/mm-audio/audio-alsa
-LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/mm-audio/libalsa-intf
-LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/mm-audio/surround_sound/
-LOCAL_C_INCLUDES += hardware/libhardware/include
-LOCAL_C_INCLUDES += hardware/libhardware_legacy/include
-LOCAL_C_INCLUDES += frameworks/base/include
-LOCAL_C_INCLUDES += system/core/include
-
-
-LOCAL_MODULE := audio.primary.msm8960
-LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_SHARED_LIBRARY)
-
-# This is the ALSA audio policy manager
-
-include $(CLEAR_VARS)
-
-LOCAL_CFLAGS := -D_POSIX_SOURCE
-LOCAL_CFLAGS += -DQCOM_ACDB_ENABLED
-
-LOCAL_SRC_FILES := \
- audio_policy_hal.cpp \
- AudioPolicyManagerALSA.cpp
-
-LOCAL_MODULE := audio_policy.msm8960
-LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_STATIC_LIBRARIES := \
- libmedia_helper \
- libaudiopolicy_legacy
-
-LOCAL_SHARED_LIBRARIES := \
- libcutils \
- libutils
-
-LOCAL_C_INCLUDES += hardware/libhardware_legacy/audio
-
-include $(BUILD_SHARED_LIBRARY)
-
-# This is the ALSA module which behaves closely like the original
-
-include $(CLEAR_VARS)
-
-LOCAL_PRELINK_MODULE := false
-
-LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
-
-LOCAL_CFLAGS := -D_POSIX_SOURCE -Wno-multichar
-LOCAL_CFLAGS += -DQCOM_ACDB_ENABLED
-
-ifeq ($(strip $(BOARD_USES_FLUENCE_INCALL)),true)
-LOCAL_CFLAGS += -DUSES_FLUENCE_INCALL
-endif
-
-ifeq ($(strip $(BOARD_USES_SEPERATED_AUDIO_INPUT)),true)
-LOCAL_CFLAGS += -DSEPERATED_AUDIO_INPUT
-endif
-
-ifneq ($(ALSA_DEFAULT_SAMPLE_RATE),)
- LOCAL_CFLAGS += -DALSA_DEFAULT_SAMPLE_RATE=$(ALSA_DEFAULT_SAMPLE_RATE)
-endif
-
-LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/mm-audio/libalsa-intf
-
-LOCAL_SRC_FILES:= \
- alsa_default.cpp \
- ALSAControl.cpp \
- AudioUtil.cpp
-
-LOCAL_SHARED_LIBRARIES := \
- libcutils \
- liblog \
- libalsa-intf
-
-ifeq ($(TARGET_SIMULATOR),true)
- LOCAL_LDLIBS += -ldl
-else
- LOCAL_SHARED_LIBRARIES += libdl
-endif
-
-LOCAL_MODULE:= alsa.msm8960
-LOCAL_MODULE_TAGS := optional
-
- include $(BUILD_SHARED_LIBRARY)
-endif
diff --git a/legacy/alsa_sound/AudioHardwareALSA.cpp b/legacy/alsa_sound/AudioHardwareALSA.cpp
deleted file mode 100644
index c61a3e8..0000000
--- a/legacy/alsa_sound/AudioHardwareALSA.cpp
+++ /dev/null
@@ -1,1707 +0,0 @@
-/* AudioHardwareALSA.cpp
- **
- ** Copyright 2008-2010 Wind River Systems
- ** Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
- **
- ** Licensed under the Apache License, Version 2.0 (the "License");
- ** you may not use this file except in compliance with the License.
- ** You may obtain a copy of the License at
- **
- ** http://www.apache.org/licenses/LICENSE-2.0
- **
- ** Unless required by applicable law or agreed to in writing, software
- ** distributed under the License is distributed on an "AS IS" BASIS,
- ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ** See the License for the specific language governing permissions and
- ** limitations under the License.
- */
-
-#include <errno.h>
-#include <stdarg.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <dlfcn.h>
-#include <math.h>
-
-#define LOG_TAG "AudioHardwareALSA"
-//#define LOG_NDEBUG 0
-#define LOG_NDDEBUG 0
-#include <utils/Log.h>
-#include <utils/String8.h>
-#include <sys/prctl.h>
-#include <sys/resource.h>
-#include <sys/poll.h>
-#include <sys/ioctl.h>
-#include <cutils/properties.h>
-#include <media/AudioRecord.h>
-#include <hardware_legacy/power.h>
-
-#include "AudioHardwareALSA.h"
-#ifdef QCOM_USBAUDIO_ENABLED
-#include "AudioUsbALSA.h"
-#endif
-#include "AudioUtil.h"
-
-extern "C"
-{
- //
- // Function for dlsym() to look up for creating a new AudioHardwareInterface.
- //
- android_audio_legacy::AudioHardwareInterface *createAudioHardware(void) {
- return android_audio_legacy::AudioHardwareALSA::create();
- }
-#ifdef QCOM_ACDB_ENABLED
- static int (*acdb_init)();
- static void (*acdb_deallocate)();
-#endif
-#ifdef QCOM_CSDCLIENT_ENABLED
- static int (*csd_client_init)();
- static int (*csd_client_deinit)();
- static int (*csd_start_playback)();
- static int (*csd_stop_playback)();
-#endif
-} // extern "C"
-
-namespace android_audio_legacy
-{
-
-// ----------------------------------------------------------------------------
-
-AudioHardwareInterface *AudioHardwareALSA::create() {
- return new AudioHardwareALSA();
-}
-
-AudioHardwareALSA::AudioHardwareALSA() :
- mALSADevice(0),mVoipStreamCount(0),mVoipBitRate(0)
- ,mCallState(0),mAcdbHandle(NULL),mCsdHandle(NULL),mMicMute(0)
-{
- FILE *fp;
- char soundCardInfo[200];
- hw_module_t *module;
- char platform[128], baseband[128];
- int err = hw_get_module(ALSA_HARDWARE_MODULE_ID,
- (hw_module_t const**)&module);
- int codec_rev = 2;
- ALOGD("hw_get_module(ALSA_HARDWARE_MODULE_ID) returned err %d", err);
- if (err == 0) {
- hw_device_t* device;
- err = module->methods->open(module, ALSA_HARDWARE_NAME, &device);
- if (err == 0) {
- mALSADevice = (alsa_device_t *)device;
- mALSADevice->init(mALSADevice, mDeviceList);
- mCSCallActive = 0;
- mVolteCallActive = 0;
- mIsFmActive = 0;
- mDevSettingsFlag = 0;
-#ifdef QCOM_USBAUDIO_ENABLED
- mAudioUsbALSA = new AudioUsbALSA();
- musbPlaybackState = 0;
- musbRecordingState = 0;
-#endif
-#ifdef USES_FLUENCE_INCALL
- mDevSettingsFlag |= TTY_OFF | DMIC_FLAG;
-#else
- mDevSettingsFlag |= TTY_OFF;
-#endif
- mBluetoothVGS = false;
- mFusion3Platform = false;
-
-#ifdef QCOM_ACDB_ENABLED
- mAcdbHandle = ::dlopen("/system/lib/libacdbloader.so", RTLD_NOW);
- if (mAcdbHandle == NULL) {
- ALOGE("AudioHardware: DLOPEN not successful for ACDBLOADER");
- } else {
- ALOGD("AudioHardware: DLOPEN successful for ACDBLOADER");
- acdb_init = (int (*)())::dlsym(mAcdbHandle,"acdb_loader_init_ACDB");
- if (acdb_init == NULL) {
- ALOGE("dlsym:Error:%s Loading acdb_loader_init_ACDB", dlerror());
- }else {
- acdb_init();
- acdb_deallocate = (void (*)())::dlsym(mAcdbHandle,"acdb_loader_deallocate_ACDB");
- }
- }
-#endif
-
-#ifdef QCOM_CSDCLIENT_ENABLED
- mCsdHandle = ::dlopen("/system/lib/libcsd-client.so", RTLD_NOW);
- if (mCsdHandle == NULL) {
- ALOGE("AudioHardware: DLOPEN not successful for CSD CLIENT");
- } else {
- ALOGD("AudioHardware: DLOPEN successful for CSD CLIENT");
- csd_client_init = (int (*)())::dlsym(mCsdHandle,"csd_client_init");
- csd_client_deinit = (int (*)())::dlsym(mCsdHandle,"csd_client_deinit");
- csd_start_playback = (int (*)())::dlsym(mCsdHandle,"csd_client_start_playback");
- csd_stop_playback = (int (*)())::dlsym(mCsdHandle,"csd_client_stop_playback");
-
- if (csd_client_init == NULL) {
- ALOGE("dlsym: Error:%s Loading csd_client_init", dlerror());
- } else {
- csd_client_init();
- }
- }
- mALSADevice->setCsdHandle(mCsdHandle);
-#endif
- if((fp = fopen("/proc/asound/cards","r")) == NULL) {
- ALOGE("Cannot open /proc/asound/cards file to get sound card info");
- } else {
- while((fgets(soundCardInfo, sizeof(soundCardInfo), fp) != NULL)) {
- ALOGV("SoundCardInfo %s", soundCardInfo);
- if (strstr(soundCardInfo, "msm8960-tabla1x-snd-card")) {
- codec_rev = 1;
- break;
- } else if (strstr(soundCardInfo, "msm-snd-card")) {
- codec_rev = 2;
- break;
- } else if (strstr(soundCardInfo, "msm8930-sitar-snd-card")) {
- codec_rev = 3;
- break;
- }
- }
- fclose(fp);
- }
-
- if (codec_rev == 1) {
- ALOGV("Detected tabla 1.x sound card");
- snd_use_case_mgr_open(&mUcMgr, "snd_soc_msm");
- } else if (codec_rev == 3) {
- ALOGV("Detected sitar 1.x sound card");
- snd_use_case_mgr_open(&mUcMgr, "snd_soc_msm_Sitar");
- } else {
- property_get("ro.board.platform", platform, "");
- property_get("ro.baseband", baseband, "");
- if (!strcmp("msm8960", platform) && !strcmp("mdm", baseband)) {
- ALOGV("Detected Fusion tabla 2.x");
- mFusion3Platform = true;
- snd_use_case_mgr_open(&mUcMgr, "snd_soc_msm_2x_Fusion3");
- } else {
- ALOGV("Detected tabla 2.x sound card");
- snd_use_case_mgr_open(&mUcMgr, "snd_soc_msm_2x");
- }
- }
-
- if (mUcMgr < 0) {
- ALOGE("Failed to open ucm instance: %d", errno);
- } else {
- ALOGI("ucm instance opened: %u", (unsigned)mUcMgr);
- mUcMgr->acdb_handle = NULL;
-#ifdef QCOM_ACDB_ENABLED
- if (mAcdbHandle) {
- mUcMgr->acdb_handle = static_cast<void*> (mAcdbHandle);
- if (mFusion3Platform)
- mUcMgr->isFusion3Platform = true;
- else
- mUcMgr->isFusion3Platform = false;
- }
-#endif
- }
- } else {
- ALOGE("ALSA Module could not be opened!!!");
- }
- } else {
- ALOGE("ALSA Module not found!!!");
- }
-}
-
-AudioHardwareALSA::~AudioHardwareALSA()
-{
- if (mUcMgr != NULL) {
- ALOGV("closing ucm instance: %u", (unsigned)mUcMgr);
- snd_use_case_mgr_close(mUcMgr);
- }
- if (mALSADevice) {
- mALSADevice->common.close(&mALSADevice->common);
- }
- for(ALSAHandleList::iterator it = mDeviceList.begin();
- it != mDeviceList.end(); ++it) {
- it->useCase[0] = 0;
- mDeviceList.erase(it);
- }
-#ifdef QCOM_ACDB_ENABLED
- if (acdb_deallocate == NULL) {
- ALOGE("dlsym: Error:%s Loading acdb_deallocate_ACDB", dlerror());
- } else {
- acdb_deallocate();
- }
- if (mAcdbHandle) {
- ::dlclose(mAcdbHandle);
- mAcdbHandle = NULL;
- }
-#endif
-#ifdef QCOM_USBAUDIO_ENABLED
- delete mAudioUsbALSA;
-#endif
-
-#ifdef QCOM_CSDCLEINT_ENABLED
- if (mCsdHandle) {
- if (csd_client_deinit == NULL) {
- ALOGE("dlsym: Error:%s Loading csd_client_deinit", dlerror());
- } else {
- csd_client_deinit();
- }
- ::dlclose(mCsdHandle);
- mCsdHandle = NULL;
- }
-#endif
-}
-
-status_t AudioHardwareALSA::initCheck()
-{
- if (!mALSADevice)
- return NO_INIT;
-
- return NO_ERROR;
-}
-
-status_t AudioHardwareALSA::setVoiceVolume(float v)
-{
- ALOGV("setVoiceVolume(%f)\n", v);
- if (v < 0.0) {
- ALOGW("setVoiceVolume(%f) under 0.0, assuming 0.0\n", v);
- v = 0.0;
- } else if (v > 1.0) {
- ALOGW("setVoiceVolume(%f) over 1.0, assuming 1.0\n", v);
- v = 1.0;
- }
-
- int newMode = mode();
- ALOGV("setVoiceVolume newMode %d",newMode);
- int vol = lrint(v * 100.0);
-
- // Voice volume levels from android are mapped to driver volume levels as follows.
- // 0 -> 5, 20 -> 4, 40 ->3, 60 -> 2, 80 -> 1, 100 -> 0
- // So adjust the volume to get the correct volume index in driver
- vol = 100 - vol;
-
- if (mALSADevice) {
- if(newMode == AudioSystem::MODE_IN_COMMUNICATION) {
- mALSADevice->setVoipVolume(vol);
- } else if (newMode == AudioSystem::MODE_IN_CALL){
- if (mCSCallActive == CS_ACTIVE)
- mALSADevice->setVoiceVolume(vol);
- if (mVolteCallActive == IMS_ACTIVE)
- mALSADevice->setVoLTEVolume(vol);
- }
- }
-
- return NO_ERROR;
-}
-
-#ifdef QCOM_FM_ENABLED
-status_t AudioHardwareALSA::setFmVolume(float value)
-{
- status_t status = NO_ERROR;
-
- int vol;
-
- if (value < 0.0) {
- ALOGW("setFmVolume(%f) under 0.0, assuming 0.0\n", value);
- value = 0.0;
- } else if (value > 1.0) {
- ALOGW("setFmVolume(%f) over 1.0, assuming 1.0\n", value);
- value = 1.0;
- }
- vol = lrint((value * 0x2000) + 0.5);
-
- ALOGV("setFmVolume(%f)\n", value);
- ALOGV("Setting FM volume to %d (available range is 0 to 0x2000)\n", vol);
-
- mALSADevice->setFmVolume(vol);
-
- return status;
-}
-#endif
-
-status_t AudioHardwareALSA::setMasterVolume(float volume)
-{
- return NO_ERROR;
-}
-
-status_t AudioHardwareALSA::setMode(int mode)
-{
- status_t status = NO_ERROR;
-
- if (mode != mMode) {
- status = AudioHardwareBase::setMode(mode);
- }
-
- if (mode == AudioSystem::MODE_IN_CALL) {
- mCallState = CS_ACTIVE;
- }else if (mode == AudioSystem::MODE_NORMAL) {
- mCallState = 0;
- }
-
- return status;
-}
-
-status_t AudioHardwareALSA::setParameters(const String8& keyValuePairs)
-{
- AudioParameter param = AudioParameter(keyValuePairs);
- String8 key;
- String8 value;
- status_t status = NO_ERROR;
- int device;
- int btRate;
- int state;
- ALOGV("setParameters() %s", keyValuePairs.string());
-
- key = String8(TTY_MODE_KEY);
- if (param.get(key, value) == NO_ERROR) {
- mDevSettingsFlag &= TTY_CLEAR;
- if (value == "tty_full") {
- mDevSettingsFlag |= TTY_FULL;
- } else if (value == "tty_hco") {
- mDevSettingsFlag |= TTY_HCO;
- } else if (value == "tty_vco") {
- mDevSettingsFlag |= TTY_VCO;
- } else {
- mDevSettingsFlag |= TTY_OFF;
- }
- ALOGI("Changed TTY Mode=%s", value.string());
- mALSADevice->setFlags(mDevSettingsFlag);
- if(mMode != AudioSystem::MODE_IN_CALL){
- return NO_ERROR;
- }
- doRouting(0);
- }
-
- key = String8(FLUENCE_KEY);
- if (param.get(key, value) == NO_ERROR) {
- if (value == "quadmic") {
- mDevSettingsFlag |= QMIC_FLAG;
- mDevSettingsFlag &= (~DMIC_FLAG);
- ALOGV("Fluence quadMic feature Enabled");
- } else if (value == "dualmic") {
- mDevSettingsFlag |= DMIC_FLAG;
- mDevSettingsFlag &= (~QMIC_FLAG);
- ALOGV("Fluence dualmic feature Enabled");
- } else if (value == "none") {
- mDevSettingsFlag &= (~DMIC_FLAG);
- mDevSettingsFlag &= (~QMIC_FLAG);
- ALOGV("Fluence feature Disabled");
- }
- mALSADevice->setFlags(mDevSettingsFlag);
- doRouting(0);
- }
-
-#ifdef QCOM_CSDCLIENT_ENABLED
- if (mFusion3Platform) {
- key = String8(INCALLMUSIC_KEY);
- if (param.get(key, value) == NO_ERROR) {
- if (value == "true") {
- ALOGV("Enabling Incall Music setting in the setparameter\n");
- if (csd_start_playback == NULL) {
- ALOGE("dlsym: Error:%s Loading csd_client_start_playback", dlerror());
- } else {
- csd_start_playback();
- }
- } else {
- ALOGV("Disabling Incall Music setting in the setparameter\n");
- if (csd_stop_playback == NULL) {
- ALOGE("dlsym: Error:%s Loading csd_client_stop_playback", dlerror());
- } else {
- csd_stop_playback();
- }
- }
- }
- }
-#endif
-
- key = String8(ANC_KEY);
- if (param.get(key, value) == NO_ERROR) {
- if (value == "true") {
- ALOGV("Enabling ANC setting in the setparameter\n");
- mDevSettingsFlag |= ANC_FLAG;
- } else {
- ALOGV("Disabling ANC setting in the setparameter\n");
- mDevSettingsFlag &= (~ANC_FLAG);
- }
- mALSADevice->setFlags(mDevSettingsFlag);
- doRouting(0);
- }
-
- key = String8(AudioParameter::keyRouting);
- if (param.getInt(key, device) == NO_ERROR) {
- // Ignore routing if device is 0.
- if(device) {
- doRouting(device);
- }
- param.remove(key);
- }
-
- key = String8(BT_SAMPLERATE_KEY);
- if (param.getInt(key, btRate) == NO_ERROR) {
- mALSADevice->setBtscoRate(btRate);
- param.remove(key);
- }
-
- key = String8(BTHEADSET_VGS);
- if (param.get(key, value) == NO_ERROR) {
- if (value == "on") {
- mBluetoothVGS = true;
- } else {
- mBluetoothVGS = false;
- }
- }
-
- key = String8(WIDEVOICE_KEY);
- if (param.get(key, value) == NO_ERROR) {
- bool flag = false;
- if (value == "true") {
- flag = true;
- }
- if(mALSADevice) {
- mALSADevice->enableWideVoice(flag);
- }
- param.remove(key);
- }
-
- key = String8(VOIPRATE_KEY);
- if (param.get(key, value) == NO_ERROR) {
- mVoipBitRate = atoi(value);
- param.remove(key);
- }
-
- key = String8(FENS_KEY);
- if (param.get(key, value) == NO_ERROR) {
- bool flag = false;
- if (value == "true") {
- flag = true;
- }
- if(mALSADevice) {
- mALSADevice->enableFENS(flag);
- }
- param.remove(key);
- }
-
-#ifdef QCOM_FM_ENABLED
- key = String8(AudioParameter::keyHandleFm);
- if (param.getInt(key, device) == NO_ERROR) {
- // Ignore if device is 0
- if(device) {
- handleFm(device);
- }
- param.remove(key);
- }
-#endif
-
- key = String8(ST_KEY);
- if (param.get(key, value) == NO_ERROR) {
- bool flag = false;
- if (value == "true") {
- flag = true;
- }
- if(mALSADevice) {
- mALSADevice->enableSlowTalk(flag);
- }
- param.remove(key);
- }
- key = String8(MODE_CALL_KEY);
- if (param.getInt(key,state) == NO_ERROR) {
- if (mCallState != state) {
- mCallState = state;
- doRouting(0);
- }
- mCallState = state;
- }
- if (param.size()) {
- status = BAD_VALUE;
- }
- return status;
-}
-
-String8 AudioHardwareALSA::getParameters(const String8& keys)
-{
- AudioParameter param = AudioParameter(keys);
- String8 value;
-
- String8 key = String8(DUALMIC_KEY);
- if (param.get(key, value) == NO_ERROR) {
- value = String8("false");
- param.add(key, value);
- }
-
- key = String8(FLUENCE_KEY);
- if (param.get(key, value) == NO_ERROR) {
- if ((mDevSettingsFlag & QMIC_FLAG) &&
- (mDevSettingsFlag & ~DMIC_FLAG))
- value = String8("quadmic");
- else if ((mDevSettingsFlag & DMIC_FLAG) &&
- (mDevSettingsFlag & ~QMIC_FLAG))
- value = String8("dualmic");
- else if ((mDevSettingsFlag & ~DMIC_FLAG) &&
- (mDevSettingsFlag & ~QMIC_FLAG))
- value = String8("none");
- param.add(key, value);
- }
-
-#ifdef QCOM_FM_ENABLED
- key = String8("Fm-radio");
- if ( param.get(key,value) == NO_ERROR ) {
- if ( mIsFmActive ) {
- param.addInt(String8("isFMON"), true );
- }
- }
-#endif
-
- key = String8(BTHEADSET_VGS);
- if (param.get(key, value) == NO_ERROR) {
- if(mBluetoothVGS)
- param.addInt(String8("isVGS"), true);
- }
-
- ALOGV("AudioHardwareALSA::getParameters() %s", param.toString().string());
- return param.toString();
-}
-
-#ifdef QCOM_USBAUDIO_ENABLED
-void AudioHardwareALSA::closeUSBPlayback()
-{
- ALOGV("closeUSBPlayback, musbPlaybackState: %d", musbPlaybackState);
- musbPlaybackState = 0;
- mAudioUsbALSA->exitPlaybackThread(SIGNAL_EVENT_KILLTHREAD);
-}
-
-void AudioHardwareALSA::closeUSBRecording()
-{
- ALOGV("closeUSBRecording");
- musbRecordingState = 0;
- mAudioUsbALSA->exitRecordingThread(SIGNAL_EVENT_KILLTHREAD);
-}
-
-void AudioHardwareALSA::closeUsbPlaybackIfNothingActive(){
- ALOGV("closeUsbPlaybackIfNothingActive, musbPlaybackState: %d", musbPlaybackState);
- if(!musbPlaybackState && mAudioUsbALSA != NULL) {
- mAudioUsbALSA->exitPlaybackThread(SIGNAL_EVENT_TIMEOUT);
- }
-}
-
-void AudioHardwareALSA::closeUsbRecordingIfNothingActive(){
- ALOGV("closeUsbRecordingIfNothingActive, musbRecordingState: %d", musbRecordingState);
- if(!musbRecordingState && mAudioUsbALSA != NULL) {
- ALOGD("Closing USB Recording Session as no stream is active");
- mAudioUsbALSA->setkillUsbRecordingThread(true);
- }
-}
-
-void AudioHardwareALSA::startUsbPlaybackIfNotStarted(){
- ALOGV("Starting the USB playback %d kill %d", musbPlaybackState,
- mAudioUsbALSA->getkillUsbPlaybackThread());
- if((!musbPlaybackState) || (mAudioUsbALSA->getkillUsbPlaybackThread() == true)) {
- mAudioUsbALSA->startPlayback();
- }
-}
-
-void AudioHardwareALSA::startUsbRecordingIfNotStarted(){
- ALOGV("Starting the recording musbRecordingState: %d killUsbRecordingThread %d",
- musbRecordingState, mAudioUsbALSA->getkillUsbRecordingThread());
- if((!musbRecordingState) || (mAudioUsbALSA->getkillUsbRecordingThread() == true)) {
- mAudioUsbALSA->startRecording();
- }
-}
-#endif
-
-void AudioHardwareALSA::doRouting(int device)
-{
- Mutex::Autolock autoLock(mLock);
- int newMode = mode();
- bool isRouted = false;
-
- if ((device == AudioSystem::DEVICE_IN_VOICE_CALL)
-#ifdef QCOM_FM_ENABLED
- || (device == AudioSystem::DEVICE_IN_FM_RX)
- || (device == AudioSystem::DEVICE_OUT_DIRECTOUTPUT)
- || (device == AudioSystem::DEVICE_IN_FM_RX_A2DP)
-#endif
- || (device == AudioSystem::DEVICE_IN_COMMUNICATION)
- ) {
- ALOGV("Ignoring routing for FM/INCALL/VOIP recording");
- return;
- }
- if (device == 0)
- device = mCurDevice;
- ALOGV("doRouting: device %d newMode %d mCSCallActive %d mVolteCallActive %d"
- "mIsFmActive %d", device, newMode, mCSCallActive, mVolteCallActive,
- mIsFmActive);
-
- isRouted = routeVoLTECall(device, newMode);
- isRouted |= routeVoiceCall(device, newMode);
-
- if(!isRouted) {
-#ifdef QCOM_USBAUDIO_ENABLED
- if(!(device & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET) &&
- !(device & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET) &&
- !(device & AudioSystem::DEVICE_IN_ANLG_DOCK_HEADSET) &&
- (musbPlaybackState)){
- //USB unplugged
- device &= ~ AudioSystem::DEVICE_OUT_PROXY;
- device &= ~ AudioSystem::DEVICE_IN_PROXY;
- ALSAHandleList::iterator it = mDeviceList.end();
- it--;
- mALSADevice->route(&(*it), (uint32_t)device, newMode);
- ALOGD("USB UNPLUGGED, setting musbPlaybackState to 0");
- musbPlaybackState = 0;
- musbRecordingState = 0;
- closeUSBRecording();
- closeUSBPlayback();
- } else if((device & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)||
- (device & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)){
- ALOGD("Routing everything to prox now");
- ALSAHandleList::iterator it = mDeviceList.end();
- it--;
- mALSADevice->route(&(*it), AudioSystem::DEVICE_OUT_PROXY,
- newMode);
- for(it = mDeviceList.begin(); it != mDeviceList.end(); ++it) {
- if((!strcmp(it->useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER)) ||
- (!strcmp(it->useCase, SND_USE_CASE_MOD_PLAY_LPA))) {
- ALOGV("doRouting: LPA device switch to proxy");
- startUsbPlaybackIfNotStarted();
- musbPlaybackState |= USBPLAYBACKBIT_LPA;
- break;
- } else if((!strcmp(it->useCase, SND_USE_CASE_VERB_VOICECALL)) ||
- (!strcmp(it->useCase, SND_USE_CASE_MOD_PLAY_VOICE))) {
- ALOGV("doRouting: VOICE device switch to proxy");
- startUsbRecordingIfNotStarted();
- startUsbPlaybackIfNotStarted();
- musbPlaybackState |= USBPLAYBACKBIT_VOICECALL;
- musbRecordingState |= USBPLAYBACKBIT_VOICECALL;
- break;
- }else if((!strcmp(it->useCase, SND_USE_CASE_VERB_DIGITAL_RADIO)) ||
- (!strcmp(it->useCase, SND_USE_CASE_MOD_PLAY_FM))) {
- ALOGV("doRouting: FM device switch to proxy");
- startUsbPlaybackIfNotStarted();
- musbPlaybackState |= USBPLAYBACKBIT_FM;
- break;
- }
- }
- } else
-#endif
- {
- ALSAHandleList::iterator it = mDeviceList.end();
- it--;
- mALSADevice->route(&(*it), (uint32_t)device, newMode);
- }
- }
- mCurDevice = device;
-}
-
-uint32_t AudioHardwareALSA::getVoipMode(int format)
-{
- switch(format) {
- case AudioSystem::PCM_16_BIT:
- return MODE_PCM;
- break;
- case AudioSystem::AMR_NB:
- return MODE_AMR;
- break;
- case AudioSystem::AMR_WB:
- return MODE_AMR_WB;
- break;
-
-#ifdef QCOM_QCHAT_ENABLED
- case AudioSystem::EVRC:
- return MODE_IS127;
- break;
-
- case AudioSystem::EVRCB:
- return MODE_4GV_NB;
- break;
- case AudioSystem::EVRCWB:
- return MODE_4GV_WB;
- break;
-#endif
-
- default:
- return MODE_PCM;
- }
-}
-
-AudioStreamOut *
-AudioHardwareALSA::openOutputStream(uint32_t devices,
- int *format,
- uint32_t *channels,
- uint32_t *sampleRate,
- status_t *status)
-{
- Mutex::Autolock autoLock(mLock);
- ALOGV("openOutputStream: devices 0x%x channels %d sampleRate %d",
- devices, *channels, *sampleRate);
-
- audio_output_flags_t flag = static_cast<audio_output_flags_t> (*status);
-
- status_t err = BAD_VALUE;
- *status = NO_ERROR;
- AudioStreamOutALSA *out = 0;
- ALSAHandleList::iterator it;
-
- if (devices & (devices - 1)) {
- if (status) *status = err;
- ALOGE("openOutputStream called with bad devices");
- return out;
- }
-
-
-# if 0
- if((devices == AudioSystem::DEVICE_OUT_DIRECTOUTPUT) &&
- ((*sampleRate == VOIP_SAMPLING_RATE_8K) || (*sampleRate == VOIP_SAMPLING_RATE_16K))) {
- bool voipstream_active = false;
- for(it = mDeviceList.begin();
- it != mDeviceList.end(); ++it) {
- if((!strcmp(it->useCase, SND_USE_CASE_VERB_IP_VOICECALL)) ||
- (!strcmp(it->useCase, SND_USE_CASE_MOD_PLAY_VOIP))) {
- ALOGD("openOutput: it->rxHandle %d it->handle %d",it->rxHandle,it->handle);
- voipstream_active = true;
- break;
- }
- }
- if(voipstream_active == false) {
- mVoipStreamCount = 0;
- alsa_handle_t alsa_handle;
- unsigned long bufferSize;
- if(*sampleRate == VOIP_SAMPLING_RATE_8K) {
- bufferSize = VOIP_BUFFER_SIZE_8K;
- }
- else if(*sampleRate == VOIP_SAMPLING_RATE_16K) {
- bufferSize = VOIP_BUFFER_SIZE_16K;
- }
- else {
- ALOGE("unsupported samplerate %d for voip",*sampleRate);
- if (status) *status = err;
- return out;
- }
- alsa_handle.module = mALSADevice;
- alsa_handle.bufferSize = bufferSize;
- alsa_handle.devices = devices;
- alsa_handle.handle = 0;
- if(*format == AudioSystem::PCM_16_BIT)
- alsa_handle.format = SNDRV_PCM_FORMAT_S16_LE;
- else
- alsa_handle.format = *format;
- alsa_handle.channels = VOIP_DEFAULT_CHANNEL_MODE;
- alsa_handle.channelMask = AUDIO_CHANNEL_IN_MONO;
- alsa_handle.sampleRate = *sampleRate;
- alsa_handle.latency = VOIP_PLAYBACK_LATENCY;
- alsa_handle.rxHandle = 0;
- alsa_handle.ucMgr = mUcMgr;
- mALSADevice->setVoipConfig(getVoipMode(*format), mVoipBitRate);
- char *use_case;
- snd_use_case_get(mUcMgr, "_verb", (const char **)&use_case);
- if ((use_case == NULL) || (!strcmp(use_case, SND_USE_CASE_VERB_INACTIVE))) {
- strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_IP_VOICECALL, sizeof(alsa_handle.useCase));
- } else {
- strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_PLAY_VOIP, sizeof(alsa_handle.useCase));
- }
- free(use_case);
- mDeviceList.push_back(alsa_handle);
- it = mDeviceList.end();
- it--;
- ALOGV("openoutput: mALSADevice->route useCase %s mCurDevice %d mVoipStreamCount %d mode %d", it->useCase,mCurDevice,mVoipStreamCount, mode());
- if((mCurDevice & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)||
- (mCurDevice & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)||
- (mCurDevice & AudioSystem::DEVICE_OUT_PROXY)){
- ALOGD("Routing to proxy for normal voip call in openOutputStream");
- mCurDevice |= AudioSystem::DEVICE_OUT_PROXY;
- alsa_handle.devices = AudioSystem::DEVICE_OUT_PROXY;
- mALSADevice->route(&(*it), mCurDevice, AudioSystem::MODE_IN_COMMUNICATION);
- ALOGD("enabling VOIP in openoutputstream, musbPlaybackState: %d", musbPlaybackState);
- startUsbPlaybackIfNotStarted();
- musbPlaybackState |= USBPLAYBACKBIT_VOIPCALL;
- ALOGD("Starting recording in openoutputstream, musbRecordingState: %d", musbRecordingState);
- startUsbRecordingIfNotStarted();
- musbRecordingState |= USBRECBIT_VOIPCALL;
- } else{
- mALSADevice->route(&(*it), mCurDevice, AudioSystem::MODE_IN_COMMUNICATION);
- }
- if(!strcmp(it->useCase, SND_USE_CASE_VERB_IP_VOICECALL)) {
- snd_use_case_set(mUcMgr, "_verb", SND_USE_CASE_VERB_IP_VOICECALL);
- } else {
- snd_use_case_set(mUcMgr, "_enamod", SND_USE_CASE_MOD_PLAY_VOIP);
- }
- err = mALSADevice->startVoipCall(&(*it));
- if (err) {
- ALOGE("Device open failed");
- return NULL;
- }
- }
- out = new AudioStreamOutALSA(this, &(*it));
- err = out->set(format, channels, sampleRate, devices);
- if(err == NO_ERROR) {
- mVoipStreamCount++; //increment VoipstreamCount only if success
- ALOGD("openoutput mVoipStreamCount %d",mVoipStreamCount);
- }
- if (status) *status = err;
- return out;
- } else
-#endif
- if ((flag & AUDIO_OUTPUT_FLAG_DIRECT) &&
- (devices == AudioSystem::DEVICE_OUT_AUX_DIGITAL)) {
- ALOGD("Multi channel PCM");
- alsa_handle_t alsa_handle;
- EDID_AUDIO_INFO info = { 0 };
-
- alsa_handle.module = mALSADevice;
- alsa_handle.devices = devices;
- alsa_handle.handle = 0;
- alsa_handle.format = SNDRV_PCM_FORMAT_S16_LE;
-
- if (!AudioUtil::getHDMIAudioSinkCaps(&info)) {
- ALOGE("openOutputStream: Failed to get HDMI sink capabilities");
- return NULL;
- }
- if (0 == *channels) {
- alsa_handle.channels = info.AudioBlocksArray[info.nAudioBlocks-1].nChannels;
- if (alsa_handle.channels > 6) {
- alsa_handle.channels = 6;
- }
- *channels = audio_channel_out_mask_from_count(alsa_handle.channels);
- } else {
- alsa_handle.channels = AudioSystem::popCount(*channels);
- }
- alsa_handle.channelMask = *channels;
-
- if (6 == alsa_handle.channels) {
- alsa_handle.bufferSize = DEFAULT_MULTI_CHANNEL_BUF_SIZE;
- } else {
- alsa_handle.bufferSize = DEFAULT_BUFFER_SIZE;
- }
- if (0 == *sampleRate) {
- alsa_handle.sampleRate = info.AudioBlocksArray[info.nAudioBlocks-1].nSamplingFreq;
- *sampleRate = alsa_handle.sampleRate;
- } else {
- alsa_handle.sampleRate = *sampleRate;
- }
- alsa_handle.latency = PLAYBACK_LATENCY;
- alsa_handle.rxHandle = 0;
- alsa_handle.ucMgr = mUcMgr;
- ALOGD("alsa_handle.channels %d alsa_handle.sampleRate %d",alsa_handle.channels,alsa_handle.sampleRate);
-
- char *use_case;
- snd_use_case_get(mUcMgr, "_verb", (const char **)&use_case);
- if ((use_case == NULL) || (!strcmp(use_case, SND_USE_CASE_VERB_INACTIVE))) {
- strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_HIFI2 , sizeof(alsa_handle.useCase));
- } else {
- strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_PLAY_MUSIC2, sizeof(alsa_handle.useCase));
- }
- free(use_case);
- mDeviceList.push_back(alsa_handle);
- ALSAHandleList::iterator it = mDeviceList.end();
- it--;
- ALOGD("it->useCase %s", it->useCase);
- mALSADevice->route(&(*it), devices, mode());
- if(!strcmp(it->useCase, SND_USE_CASE_VERB_HIFI2)) {
- snd_use_case_set(mUcMgr, "_verb", SND_USE_CASE_VERB_HIFI2 );
- } else {
- snd_use_case_set(mUcMgr, "_enamod", SND_USE_CASE_MOD_PLAY_MUSIC2);
- }
- ALOGD("channels: %d", AudioSystem::popCount(*channels));
- err = mALSADevice->open(&(*it));
-
- if (err) {
- ALOGE("Device open failed err:%d",err);
- } else {
- out = new AudioStreamOutALSA(this, &(*it));
- err = out->set(format, channels, sampleRate, devices);
- }
- if (status) *status = err;
- return out;
- } else {
-
- alsa_handle_t alsa_handle;
- unsigned long bufferSize = DEFAULT_BUFFER_SIZE;
-
- for (size_t b = 1; (bufferSize & ~b) != 0; b <<= 1)
- bufferSize &= ~b;
-
- alsa_handle.module = mALSADevice;
- alsa_handle.bufferSize = bufferSize;
- alsa_handle.devices = devices;
- alsa_handle.handle = 0;
- alsa_handle.format = SNDRV_PCM_FORMAT_S16_LE;
- alsa_handle.channels = DEFAULT_CHANNEL_MODE;
- alsa_handle.channelMask = AUDIO_CHANNEL_OUT_STEREO;
- alsa_handle.sampleRate = DEFAULT_SAMPLING_RATE;
- alsa_handle.latency = PLAYBACK_LATENCY;
- alsa_handle.rxHandle = 0;
- alsa_handle.ucMgr = mUcMgr;
- alsa_handle.isDeepbufferOutput = false;
-
- char *use_case;
- snd_use_case_get(mUcMgr, "_verb", (const char **)&use_case);
-
- if (flag & AUDIO_OUTPUT_FLAG_DEEP_BUFFER) {
- ALOGD("openOutputStream: DeepBuffer Output");
- alsa_handle.isDeepbufferOutput = true;
- if ((use_case == NULL) || (!strcmp(use_case, SND_USE_CASE_VERB_INACTIVE))) {
- strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_HIFI, sizeof(alsa_handle.useCase));
- } else {
- strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_PLAY_MUSIC, sizeof(alsa_handle.useCase));
- }
- } else {
- ALOGD("openOutputStream: Lowlatency Output");
- alsa_handle.bufferSize = PLAYBACK_LOW_LATENCY_BUFFER_SIZE;
- alsa_handle.latency = PLAYBACK_LOW_LATENCY_MEASURED;
- if ((use_case == NULL) || (!strcmp(use_case, SND_USE_CASE_VERB_INACTIVE))) {
- strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_MUSIC, sizeof(alsa_handle.useCase));
- } else {
- strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_PLAY_LOWLATENCY_MUSIC, sizeof(alsa_handle.useCase));
- }
- }
- free(use_case);
- mDeviceList.push_back(alsa_handle);
- ALSAHandleList::iterator it = mDeviceList.end();
- it--;
- ALOGV("useCase %s", it->useCase);
-#ifdef QCOM_USBAUDIO_ENABLED
- if((devices & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)||
- (devices & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)){
- ALOGD("Routing to proxy for normal playback in openOutputStream");
- devices |= AudioSystem::DEVICE_OUT_PROXY;
- }
-#endif
- mALSADevice->route(&(*it), devices, mode());
- if (flag & AUDIO_OUTPUT_FLAG_DEEP_BUFFER) {
- if(!strcmp(it->useCase, SND_USE_CASE_VERB_HIFI)) {
- snd_use_case_set(mUcMgr, "_verb", SND_USE_CASE_VERB_HIFI);
- } else {
- snd_use_case_set(mUcMgr, "_enamod", SND_USE_CASE_MOD_PLAY_MUSIC);
- }
- } else {
- if(!strcmp(it->useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_MUSIC)) {
- snd_use_case_set(mUcMgr, "_verb", SND_USE_CASE_VERB_HIFI_LOWLATENCY_MUSIC);
- } else {
- snd_use_case_set(mUcMgr, "_enamod", SND_USE_CASE_MOD_PLAY_LOWLATENCY_MUSIC);
- }
- }
- err = mALSADevice->open(&(*it));
- if (err) {
- ALOGE("Device open failed");
- } else {
- out = new AudioStreamOutALSA(this, &(*it));
- err = out->set(format, channels, sampleRate, devices);
- }
-
- if (status) *status = err;
- return out;
- }
-}
-
-void
-AudioHardwareALSA::closeOutputStream(AudioStreamOut* out)
-{
- delete out;
-}
-
-#ifdef QCOM_TUNNEL_LPA_ENABLED
-AudioStreamOut *
-AudioHardwareALSA::openOutputSession(uint32_t devices,
- int *format,
- status_t *status,
- int sessionId,
- uint32_t samplingRate,
- uint32_t channels)
-{
- Mutex::Autolock autoLock(mLock);
- ALOGD("openOutputSession = %d" ,sessionId);
- AudioStreamOutALSA *out = 0;
- status_t err = BAD_VALUE;
-
- alsa_handle_t alsa_handle;
- unsigned long bufferSize = DEFAULT_BUFFER_SIZE;
-
- for (size_t b = 1; (bufferSize & ~b) != 0; b <<= 1)
- bufferSize &= ~b;
-
- alsa_handle.module = mALSADevice;
- alsa_handle.bufferSize = bufferSize;
- alsa_handle.devices = devices;
- alsa_handle.handle = 0;
- alsa_handle.format = SNDRV_PCM_FORMAT_S16_LE;
- alsa_handle.channels = DEFAULT_CHANNEL_MODE;
- alsa_handle.channelMask = AUDIO_CHANNEL_OUT_STEREO;
- alsa_handle.sampleRate = DEFAULT_SAMPLING_RATE;
- alsa_handle.latency = VOICE_LATENCY;
- alsa_handle.rxHandle = 0;
- alsa_handle.ucMgr = mUcMgr;
-
- char *use_case;
- if(sessionId == TUNNEL_SESSION_ID) {
- snd_use_case_get(mUcMgr, "_verb", (const char **)&use_case);
- if ((use_case == NULL) || (!strcmp(use_case, SND_USE_CASE_VERB_INACTIVE))) {
- strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_HIFI_TUNNEL, sizeof(alsa_handle.useCase));
- } else {
- strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_PLAY_TUNNEL, sizeof(alsa_handle.useCase));
- }
- } else {
- snd_use_case_get(mUcMgr, "_verb", (const char **)&use_case);
- if ((use_case == NULL) || (!strcmp(use_case, SND_USE_CASE_VERB_INACTIVE))) {
- strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER, sizeof(alsa_handle.useCase));
- } else {
- strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_PLAY_LPA, sizeof(alsa_handle.useCase));
- }
- }
- free(use_case);
- mDeviceList.push_back(alsa_handle);
- ALSAHandleList::iterator it = mDeviceList.end();
- it--;
- ALOGD("useCase %s", it->useCase);
-#ifdef QCOM_USBAUDIO_ENABLED
- if((devices & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)||
- (devices & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)){
- ALOGD("Routing to proxy for LPA in openOutputSession");
- devices |= AudioSystem::DEVICE_OUT_PROXY;
- mALSADevice->route(&(*it), devices, mode());
- devices = AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET;
- ALOGD("Starting USBPlayback for LPA");
- startUsbPlaybackIfNotStarted();
- musbPlaybackState |= USBPLAYBACKBIT_LPA;
- } else
-#endif
- {
- mALSADevice->route(&(*it), devices, mode());
- }
- if(sessionId == TUNNEL_SESSION_ID) {
- if(!strcmp(it->useCase, SND_USE_CASE_VERB_HIFI_TUNNEL)) {
- snd_use_case_set(mUcMgr, "_verb", SND_USE_CASE_VERB_HIFI_TUNNEL);
- } else {
- snd_use_case_set(mUcMgr, "_enamod", SND_USE_CASE_MOD_PLAY_TUNNEL);
- }
- }
- else {
- if(!strcmp(it->useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER)) {
- snd_use_case_set(mUcMgr, "_verb", SND_USE_CASE_VERB_HIFI_LOW_POWER);
- } else {
- snd_use_case_set(mUcMgr, "_enamod", SND_USE_CASE_MOD_PLAY_LPA);
- }
- }
- err = mALSADevice->open(&(*it));
- out = new AudioStreamOutALSA(this, &(*it));
-
- if (status) *status = err;
- return out;
-}
-
-void
-AudioHardwareALSA::closeOutputSession(AudioStreamOut* out)
-{
- delete out;
-}
-#endif
-
-AudioStreamIn *
-AudioHardwareALSA::openInputStream(uint32_t devices,
- int *format,
- uint32_t *channels,
- uint32_t *sampleRate,
- status_t *status,
- AudioSystem::audio_in_acoustics acoustics)
-{
- Mutex::Autolock autoLock(mLock);
- char *use_case;
- int newMode = mode();
- uint32_t route_devices;
-
- status_t err = BAD_VALUE;
- AudioStreamInALSA *in = 0;
- ALSAHandleList::iterator it;
-
- ALOGD("openInputStream: devices 0x%x channels %d sampleRate %d", devices, *channels, *sampleRate);
- if (devices & (devices - 1)) {
- if (status) *status = err;
- return in;
- }
-
- if((devices == AudioSystem::DEVICE_IN_COMMUNICATION) &&
- ((*sampleRate == VOIP_SAMPLING_RATE_8K) || (*sampleRate == VOIP_SAMPLING_RATE_16K))) {
- bool voipstream_active = false;
- for(it = mDeviceList.begin();
- it != mDeviceList.end(); ++it) {
- if((!strcmp(it->useCase, SND_USE_CASE_VERB_IP_VOICECALL)) ||
- (!strcmp(it->useCase, SND_USE_CASE_MOD_PLAY_VOIP))) {
- ALOGD("openInput: it->rxHandle %p it->handle %p",it->rxHandle,it->handle);
- voipstream_active = true;
- break;
- }
- }
- if(voipstream_active == false) {
- mVoipStreamCount = 0;
- alsa_handle_t alsa_handle;
- unsigned long bufferSize;
- if(*sampleRate == VOIP_SAMPLING_RATE_8K) {
- bufferSize = VOIP_BUFFER_SIZE_8K;
- }
- else if(*sampleRate == VOIP_SAMPLING_RATE_16K) {
- bufferSize = VOIP_BUFFER_SIZE_16K;
- }
- else {
- ALOGE("unsupported samplerate %d for voip",*sampleRate);
- if (status) *status = err;
- return in;
- }
- alsa_handle.module = mALSADevice;
- alsa_handle.bufferSize = bufferSize;
- alsa_handle.devices = devices;
- alsa_handle.handle = 0;
- if(*format == AudioSystem::PCM_16_BIT)
- alsa_handle.format = SNDRV_PCM_FORMAT_S16_LE;
- else
- alsa_handle.format = *format;
- alsa_handle.channels = VOIP_DEFAULT_CHANNEL_MODE;
- alsa_handle.channelMask = AUDIO_CHANNEL_IN_MONO;
- alsa_handle.sampleRate = *sampleRate;
- alsa_handle.latency = VOIP_RECORD_LATENCY;
- alsa_handle.rxHandle = 0;
- alsa_handle.ucMgr = mUcMgr;
- mALSADevice->setVoipConfig(getVoipMode(*format), mVoipBitRate);
- snd_use_case_get(mUcMgr, "_verb", (const char **)&use_case);
- if ((use_case != NULL) && (strcmp(use_case, SND_USE_CASE_VERB_INACTIVE))) {
- strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_PLAY_VOIP, sizeof(alsa_handle.useCase));
- } else {
- strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_IP_VOICECALL, sizeof(alsa_handle.useCase));
- }
- free(use_case);
- mDeviceList.push_back(alsa_handle);
- it = mDeviceList.end();
- it--;
- ALOGD("mCurrDevice: %d", mCurDevice);
-#ifdef QCOM_USBAUDIO_ENABLED
- if((mCurDevice == AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)||
- (mCurDevice == AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)){
- ALOGD("Routing everything from proxy for voipcall");
- mALSADevice->route(&(*it), AudioSystem::DEVICE_IN_PROXY, AudioSystem::MODE_IN_COMMUNICATION);
- ALOGD("enabling VOIP in openInputstream, musbPlaybackState: %d", musbPlaybackState);
- startUsbPlaybackIfNotStarted();
- musbPlaybackState |= USBPLAYBACKBIT_VOIPCALL;
- ALOGD("Starting recording in openoutputstream, musbRecordingState: %d", musbRecordingState);
- startUsbRecordingIfNotStarted();
- musbRecordingState |= USBRECBIT_VOIPCALL;
- } else
-#endif
- {
- mALSADevice->route(&(*it),mCurDevice, AudioSystem::MODE_IN_COMMUNICATION);
- }
- if(!strcmp(it->useCase, SND_USE_CASE_VERB_IP_VOICECALL)) {
- snd_use_case_set(mUcMgr, "_verb", SND_USE_CASE_VERB_IP_VOICECALL);
- } else {
- snd_use_case_set(mUcMgr, "_enamod", SND_USE_CASE_MOD_PLAY_VOIP);
- }
- if(sampleRate) {
- it->sampleRate = *sampleRate;
- }
- if(channels)
- it->channels = AudioSystem::popCount(*channels);
- err = mALSADevice->startVoipCall(&(*it));
- if (err) {
- ALOGE("Error opening pcm input device");
- return NULL;
- }
- }
- in = new AudioStreamInALSA(this, &(*it), acoustics);
- err = in->set(format, channels, sampleRate, devices);
- if(err == NO_ERROR) {
- mVoipStreamCount++; //increment VoipstreamCount only if success
- ALOGD("OpenInput mVoipStreamCount %d",mVoipStreamCount);
- }
- ALOGD("openInput: After Get alsahandle");
- if (status) *status = err;
- return in;
- } else {
- alsa_handle_t alsa_handle;
- unsigned long bufferSize = MIN_CAPTURE_BUFFER_SIZE_PER_CH;
-
- alsa_handle.module = mALSADevice;
- alsa_handle.bufferSize = bufferSize;
- alsa_handle.devices = devices;
- alsa_handle.handle = 0;
- alsa_handle.format = SNDRV_PCM_FORMAT_S16_LE;
- alsa_handle.channels = VOICE_CHANNEL_MODE;
- alsa_handle.channelMask = AUDIO_CHANNEL_IN_MONO;
- alsa_handle.sampleRate = android::AudioRecord::DEFAULT_SAMPLE_RATE;
- alsa_handle.latency = RECORD_LATENCY;
- alsa_handle.rxHandle = 0;
- alsa_handle.ucMgr = mUcMgr;
- snd_use_case_get(mUcMgr, "_verb", (const char **)&use_case);
- if ((use_case != NULL) && (strcmp(use_case, SND_USE_CASE_VERB_INACTIVE))) {
- if ((devices == AudioSystem::DEVICE_IN_VOICE_CALL) &&
- (newMode == AudioSystem::MODE_IN_CALL)) {
- ALOGD("openInputStream: into incall recording, channels %d", *channels);
- mIncallMode = *channels;
- if ((*channels & AudioSystem::CHANNEL_IN_VOICE_UPLINK) &&
- (*channels & AudioSystem::CHANNEL_IN_VOICE_DNLINK)) {
- if (mFusion3Platform) {
- mALSADevice->setVocRecMode(INCALL_REC_STEREO);
- strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_CAPTURE_VOICE,
- sizeof(alsa_handle.useCase));
- } else {
- strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_CAPTURE_VOICE_UL_DL,
- sizeof(alsa_handle.useCase));
- }
- } else if (*channels & AudioSystem::CHANNEL_IN_VOICE_DNLINK) {
- if (mFusion3Platform) {
- mALSADevice->setVocRecMode(INCALL_REC_MONO);
- strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_CAPTURE_VOICE,
- sizeof(alsa_handle.useCase));
- } else {
- strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_CAPTURE_VOICE_DL,
- sizeof(alsa_handle.useCase));
- }
- }
-#ifdef QCOM_FM_ENABLED
- } else if((devices == AudioSystem::DEVICE_IN_FM_RX)) {
- strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_CAPTURE_FM, sizeof(alsa_handle.useCase));
- } else if(devices == AudioSystem::DEVICE_IN_FM_RX_A2DP) {
- strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_CAPTURE_A2DP_FM, sizeof(alsa_handle.useCase));
-#endif
- } else {
- char value[128];
- property_get("persist.audio.lowlatency.rec",value,"0");
- if (!strcmp("true", value)) {
- strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_CAPTURE_LOWLATENCY_MUSIC, sizeof(alsa_handle.useCase));
- } else {
- strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC, sizeof(alsa_handle.useCase));
- }
- }
- } else {
- if ((devices == AudioSystem::DEVICE_IN_VOICE_CALL) &&
- (newMode == AudioSystem::MODE_IN_CALL)) {
- ALOGD("openInputStream: incall recording, channels %d", *channels);
- mIncallMode = *channels;
- if ((*channels & AudioSystem::CHANNEL_IN_VOICE_UPLINK) &&
- (*channels & AudioSystem::CHANNEL_IN_VOICE_DNLINK)) {
- if (mFusion3Platform) {
- mALSADevice->setVocRecMode(INCALL_REC_STEREO);
- strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_INCALL_REC,
- sizeof(alsa_handle.useCase));
- } else {
- strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_UL_DL_REC,
- sizeof(alsa_handle.useCase));
- }
- } else if (*channels & AudioSystem::CHANNEL_IN_VOICE_DNLINK) {
- if (mFusion3Platform) {
- mALSADevice->setVocRecMode(INCALL_REC_MONO);
- strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_INCALL_REC,
- sizeof(alsa_handle.useCase));
- } else {
- strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_DL_REC,
- sizeof(alsa_handle.useCase));
- }
- }
-#ifdef QCOM_FM_ENABLED
- } else if(devices == AudioSystem::DEVICE_IN_FM_RX) {
- strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_FM_REC, sizeof(alsa_handle.useCase));
- } else if (devices == AudioSystem::DEVICE_IN_FM_RX_A2DP) {
- strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_FM_A2DP_REC, sizeof(alsa_handle.useCase));
-#endif
- } else {
- char value[128];
- property_get("persist.audio.lowlatency.rec",value,"0");
- if (!strcmp("true", value)) {
- strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_REC, sizeof(alsa_handle.useCase));
- } else {
- strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_HIFI_REC, sizeof(alsa_handle.useCase));
- }
- }
- }
- free(use_case);
- mDeviceList.push_back(alsa_handle);
- ALSAHandleList::iterator it = mDeviceList.end();
- it--;
- //update channel info before do routing
- if(channels) {
- it->channels = AudioSystem::popCount((*channels) &
- (AudioSystem::CHANNEL_IN_STEREO
- | AudioSystem::CHANNEL_IN_MONO
-#ifdef QCOM_SSR_ENABLED
- | AudioSystem::CHANNEL_IN_5POINT1
-#endif
- | AUDIO_CHANNEL_IN_FRONT_BACK));
- it->channelMask = *channels;
- ALOGV("updated channel info: channels=%d channelMask %08x",
- it->channels, it->channelMask);
- }
- if (devices == AudioSystem::DEVICE_IN_VOICE_CALL){
- /* Add current devices info to devices to do route */
-#ifdef QCOM_USBAUDIO_ENABLED
- if(mCurDevice == AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET ||
- mCurDevice == AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET){
- ALOGD("Routing everything from proxy for VOIP call");
- route_devices = devices | AudioSystem::DEVICE_IN_PROXY;
- } else
-#endif
- {
- route_devices = devices | mCurDevice;
- }
- mALSADevice->route(&(*it), route_devices, mode());
- } else {
-#ifdef QCOM_USBAUDIO_ENABLED
- if(devices & AudioSystem::DEVICE_IN_ANLG_DOCK_HEADSET ||
- devices & AudioSystem::DEVICE_IN_PROXY) {
- devices |= AudioSystem::DEVICE_IN_PROXY;
- ALOGD("routing everything from proxy");
- mALSADevice->route(&(*it), devices, mode());
- } else
-#endif
- {
- mALSADevice->route(&(*it), devices, mode());
- }
- }
- if(!strcmp(it->useCase, SND_USE_CASE_VERB_HIFI_REC) ||
- !strcmp(it->useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_REC) ||
-#ifdef QCOM_FM_ENABLED
- !strcmp(it->useCase, SND_USE_CASE_VERB_FM_REC) ||
- !strcmp(it->useCase, SND_USE_CASE_VERB_FM_A2DP_REC) ||
-#endif
- !strcmp(it->useCase, SND_USE_CASE_VERB_DL_REC) ||
- !strcmp(it->useCase, SND_USE_CASE_VERB_UL_DL_REC) ||
- !strcmp(it->useCase, SND_USE_CASE_VERB_INCALL_REC)) {
- snd_use_case_set(mUcMgr, "_verb", it->useCase);
- } else {
- snd_use_case_set(mUcMgr, "_enamod", it->useCase);
- }
- if(sampleRate) {
- it->sampleRate = *sampleRate;
- }
- if (!strncmp(it->useCase, SND_USE_CASE_VERB_HIFI_REC, strlen(SND_USE_CASE_VERB_HIFI_REC))
- || !strncmp(it->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC, strlen(SND_USE_CASE_MOD_CAPTURE_MUSIC))) {
- ALOGV("OpenInoutStream: Use larger buffer size for 5.1(%s) recording ", it->useCase);
- it->bufferSize = getInputBufferSize(it->sampleRate,*format,it->channels);
- }
- err = mALSADevice->open(&(*it));
- if (err) {
- ALOGE("Error opening pcm input device");
- } else {
- in = new AudioStreamInALSA(this, &(*it), acoustics);
- err = in->set(format, channels, sampleRate, devices);
- }
- if (status) *status = err;
- return in;
- }
-}
-
-void
-AudioHardwareALSA::closeInputStream(AudioStreamIn* in)
-{
- delete in;
-}
-
-status_t AudioHardwareALSA::setMicMute(bool state)
-{
- if (mMicMute != state) {
- mMicMute = state;
- ALOGD("setMicMute: mMicMute %d", mMicMute);
- if(mALSADevice) {
- mALSADevice->setMicMute(state);
- }
- }
- return NO_ERROR;
-}
-
-status_t AudioHardwareALSA::getMicMute(bool *state)
-{
- *state = mMicMute;
- return NO_ERROR;
-}
-
-status_t AudioHardwareALSA::dump(int fd, const Vector<String16>& args)
-{
- return NO_ERROR;
-}
-
-size_t AudioHardwareALSA::getInputBufferSize(uint32_t sampleRate, int format, int channelCount)
-{
- size_t bufferSize = 0;
- if (format == AudioSystem::PCM_16_BIT) {
- if(sampleRate == 8000 || sampleRate == 16000 || sampleRate == 32000) {
- bufferSize = (sampleRate * channelCount * 20 * sizeof(int16_t)) / 1000;
- } else if (sampleRate == 11025 || sampleRate == 12000) {
- bufferSize = 256 * sizeof(int16_t) * channelCount;
- } else if (sampleRate == 22050 || sampleRate == 24000) {
- bufferSize = 512 * sizeof(int16_t) * channelCount;
- } else if (sampleRate == 44100 || sampleRate == 48000) {
- bufferSize = 1024 * sizeof(int16_t) * channelCount;
- }
- } else {
- ALOGE("getInputBufferSize bad format: %d", format);
- }
- return bufferSize;
-}
-
-#ifdef QCOM_FM_ENABLED
-void AudioHardwareALSA::handleFm(int device)
-{
-int newMode = mode();
- if(device & AudioSystem::DEVICE_OUT_FM && mIsFmActive == 0) {
- // Start FM Radio on current active device
- unsigned long bufferSize = FM_BUFFER_SIZE;
- alsa_handle_t alsa_handle;
- char *use_case;
- ALOGV("Start FM");
- snd_use_case_get(mUcMgr, "_verb", (const char **)&use_case);
- if ((use_case == NULL) || (!strcmp(use_case, SND_USE_CASE_VERB_INACTIVE))) {
- strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_DIGITAL_RADIO, sizeof(alsa_handle.useCase));
- } else {
- strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_PLAY_FM, sizeof(alsa_handle.useCase));
- }
- free(use_case);
-
- for (size_t b = 1; (bufferSize & ~b) != 0; b <<= 1)
- bufferSize &= ~b;
- alsa_handle.module = mALSADevice;
- alsa_handle.bufferSize = bufferSize;
- alsa_handle.devices = device;
- alsa_handle.handle = 0;
- alsa_handle.format = SNDRV_PCM_FORMAT_S16_LE;
- alsa_handle.channels = DEFAULT_CHANNEL_MODE;
- alsa_handle.channelMask = AUDIO_CHANNEL_OUT_STEREO;
- alsa_handle.sampleRate = DEFAULT_SAMPLING_RATE;
- alsa_handle.latency = VOICE_LATENCY;
- alsa_handle.rxHandle = 0;
- alsa_handle.ucMgr = mUcMgr;
- mIsFmActive = 1;
- mDeviceList.push_back(alsa_handle);
- ALSAHandleList::iterator it = mDeviceList.end();
- it--;
- if((device & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)||
- (device & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)){
- device |= AudioSystem::DEVICE_OUT_PROXY;
- alsa_handle.devices = AudioSystem::DEVICE_OUT_PROXY;
- ALOGD("Routing to proxy for FM case");
- }
- mALSADevice->route(&(*it), (uint32_t)device, newMode);
- if(!strcmp(it->useCase, SND_USE_CASE_VERB_DIGITAL_RADIO)) {
- snd_use_case_set(mUcMgr, "_verb", SND_USE_CASE_VERB_DIGITAL_RADIO);
- } else {
- snd_use_case_set(mUcMgr, "_enamod", SND_USE_CASE_MOD_PLAY_FM);
- }
- mALSADevice->startFm(&(*it));
- if((device & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)||
- (device & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)){
- ALOGD("Starting FM, musbPlaybackState %d", musbPlaybackState);
- startUsbPlaybackIfNotStarted();
- musbPlaybackState |= USBPLAYBACKBIT_FM;
- }
- } else if (!(device & AudioSystem::DEVICE_OUT_FM) && mIsFmActive == 1) {
- //i Stop FM Radio
- ALOGV("Stop FM");
- for(ALSAHandleList::iterator it = mDeviceList.begin();
- it != mDeviceList.end(); ++it) {
- if((!strcmp(it->useCase, SND_USE_CASE_VERB_DIGITAL_RADIO)) ||
- (!strcmp(it->useCase, SND_USE_CASE_MOD_PLAY_FM))) {
- mALSADevice->close(&(*it));
- //mALSADevice->route(&(*it), (uint32_t)device, newMode);
- mDeviceList.erase(it);
- break;
- }
- }
- mIsFmActive = 0;
- musbPlaybackState &= ~USBPLAYBACKBIT_FM;
- if((device & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)||
- (device & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)){
- closeUsbPlaybackIfNothingActive();
- }
- }
-}
-#endif
-
-void AudioHardwareALSA::disableVoiceCall(char* verb, char* modifier, int mode, int device)
-{
- for(ALSAHandleList::iterator it = mDeviceList.begin();
- it != mDeviceList.end(); ++it) {
- if((!strcmp(it->useCase, verb)) ||
- (!strcmp(it->useCase, modifier))) {
- ALOGV("Disabling voice call");
- mALSADevice->close(&(*it));
- mALSADevice->route(&(*it), (uint32_t)device, mode);
- mDeviceList.erase(it);
- break;
- }
- }
-#ifdef QCOM_USBAUDIO_ENABLED
- if(musbPlaybackState & USBPLAYBACKBIT_VOICECALL) {
- ALOGD("Voice call ended on USB");
- musbPlaybackState &= ~USBPLAYBACKBIT_VOICECALL;
- musbRecordingState &= ~USBRECBIT_VOICECALL;
- closeUsbRecordingIfNothingActive();
- closeUsbPlaybackIfNothingActive();
- }
-#endif
-}
-void AudioHardwareALSA::enableVoiceCall(char* verb, char* modifier, int mode, int device)
-{
-// Start voice call
-unsigned long bufferSize = DEFAULT_VOICE_BUFFER_SIZE;
-alsa_handle_t alsa_handle;
-char *use_case;
- snd_use_case_get(mUcMgr, "_verb", (const char **)&use_case);
- if ((use_case == NULL) || (!strcmp(use_case, SND_USE_CASE_VERB_INACTIVE))) {
- strlcpy(alsa_handle.useCase, verb, sizeof(alsa_handle.useCase));
- } else {
- strlcpy(alsa_handle.useCase, modifier, sizeof(alsa_handle.useCase));
- }
- free(use_case);
-
- for (size_t b = 1; (bufferSize & ~b) != 0; b <<= 1)
- bufferSize &= ~b;
- alsa_handle.module = mALSADevice;
- alsa_handle.bufferSize = bufferSize;
- alsa_handle.devices = device;
- alsa_handle.handle = 0;
- alsa_handle.format = SNDRV_PCM_FORMAT_S16_LE;
- alsa_handle.channels = VOICE_CHANNEL_MODE;
- alsa_handle.channelMask = AUDIO_CHANNEL_IN_MONO;
- alsa_handle.sampleRate = VOICE_SAMPLING_RATE;
- alsa_handle.latency = VOICE_LATENCY;
- alsa_handle.rxHandle = 0;
- alsa_handle.ucMgr = mUcMgr;
- mDeviceList.push_back(alsa_handle);
- ALSAHandleList::iterator it = mDeviceList.end();
- it--;
-#ifdef QCOM_USBAUDIO_ENABLED
- if((device & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)||
- (device & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)){
- device |= AudioSystem::DEVICE_OUT_PROXY;
- alsa_handle.devices = device;
- }
-#endif
- mALSADevice->route(&(*it), (uint32_t)device, mode);
- if (!strcmp(it->useCase, verb)) {
- snd_use_case_set(mUcMgr, "_verb", verb);
- } else {
- snd_use_case_set(mUcMgr, "_enamod", modifier);
- }
- mALSADevice->startVoiceCall(&(*it));
-#ifdef QCOM_USBAUDIO_ENABLED
- if((device & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)||
- (device & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)){
- startUsbRecordingIfNotStarted();
- startUsbPlaybackIfNotStarted();
- musbPlaybackState |= USBPLAYBACKBIT_VOICECALL;
- musbRecordingState |= USBRECBIT_VOICECALL;
- }
-#endif
-}
-
-bool AudioHardwareALSA::routeVoiceCall(int device, int newMode)
-{
-int csCallState = mCallState&0xF;
- bool isRouted = false;
- switch (csCallState) {
- case CS_INACTIVE:
- if (mCSCallActive != CS_INACTIVE) {
- ALOGD("doRouting: Disabling voice call");
- disableVoiceCall((char *)SND_USE_CASE_VERB_VOICECALL,
- (char *)SND_USE_CASE_MOD_PLAY_VOICE, newMode, device);
- isRouted = true;
- mCSCallActive = CS_INACTIVE;
- }
- break;
- case CS_ACTIVE:
- if (mCSCallActive == CS_INACTIVE) {
- ALOGD("doRouting: Enabling CS voice call ");
- enableVoiceCall((char *)SND_USE_CASE_VERB_VOICECALL,
- (char *)SND_USE_CASE_MOD_PLAY_VOICE, newMode, device);
- isRouted = true;
- mCSCallActive = CS_ACTIVE;
- } else if (mCSCallActive == CS_HOLD) {
- ALOGD("doRouting: Resume voice call from hold state");
- ALSAHandleList::iterator vt_it;
- for(vt_it = mDeviceList.begin();
- vt_it != mDeviceList.end(); ++vt_it) {
- if((!strncmp(vt_it->useCase, SND_USE_CASE_VERB_VOICECALL,
- strlen(SND_USE_CASE_VERB_VOICECALL))) ||
- (!strncmp(vt_it->useCase, SND_USE_CASE_MOD_PLAY_VOICE,
- strlen(SND_USE_CASE_MOD_PLAY_VOICE)))) {
- alsa_handle_t *handle = (alsa_handle_t *)(&(*vt_it));
- mCSCallActive = CS_ACTIVE;
- if(ioctl((int)handle->handle->fd,SNDRV_PCM_IOCTL_PAUSE,0)<0)
- ALOGE("VoLTE resume failed");
- break;
- }
- }
- }
- break;
- case CS_HOLD:
- if (mCSCallActive == CS_ACTIVE) {
- ALOGD("doRouting: Voice call going to Hold");
- ALSAHandleList::iterator vt_it;
- for(vt_it = mDeviceList.begin();
- vt_it != mDeviceList.end(); ++vt_it) {
- if((!strncmp(vt_it->useCase, SND_USE_CASE_VERB_VOICECALL,
- strlen(SND_USE_CASE_VERB_VOICECALL))) ||
- (!strncmp(vt_it->useCase, SND_USE_CASE_MOD_PLAY_VOICE,
- strlen(SND_USE_CASE_MOD_PLAY_VOICE)))) {
- mCSCallActive = CS_HOLD;
- alsa_handle_t *handle = (alsa_handle_t *)(&(*vt_it));
- if(ioctl((int)handle->handle->fd,SNDRV_PCM_IOCTL_PAUSE,1)<0)
- ALOGE("Voice pause failed");
- break;
- }
- }
- }
- break;
- }
- return isRouted;
-}
-bool AudioHardwareALSA::routeVoLTECall(int device, int newMode)
-{
-int volteCallState = mCallState&0xF0;
-bool isRouted = false;
-switch (volteCallState) {
- case IMS_INACTIVE:
- if (mVolteCallActive != IMS_INACTIVE) {
- ALOGD("doRouting: Disabling IMS call");
- disableVoiceCall((char *)SND_USE_CASE_VERB_VOLTE,
- (char *)SND_USE_CASE_MOD_PLAY_VOLTE, newMode, device);
- isRouted = true;
- mVolteCallActive = IMS_INACTIVE;
- }
- break;
- case IMS_ACTIVE:
- if (mVolteCallActive == IMS_INACTIVE) {
- ALOGD("doRouting: Enabling IMS voice call ");
- enableVoiceCall((char *)SND_USE_CASE_VERB_VOLTE,
- (char *)SND_USE_CASE_MOD_PLAY_VOLTE, newMode, device);
- isRouted = true;
- mVolteCallActive = IMS_ACTIVE;
- } else if (mVolteCallActive == IMS_HOLD) {
- ALOGD("doRouting: Resume IMS call from hold state");
- ALSAHandleList::iterator vt_it;
- for(vt_it = mDeviceList.begin();
- vt_it != mDeviceList.end(); ++vt_it) {
- if((!strncmp(vt_it->useCase, SND_USE_CASE_VERB_VOLTE,
- strlen(SND_USE_CASE_VERB_VOLTE))) ||
- (!strncmp(vt_it->useCase, SND_USE_CASE_MOD_PLAY_VOLTE,
- strlen(SND_USE_CASE_MOD_PLAY_VOLTE)))) {
- alsa_handle_t *handle = (alsa_handle_t *)(&(*vt_it));
- mVolteCallActive = IMS_ACTIVE;
- if(ioctl((int)handle->handle->fd,SNDRV_PCM_IOCTL_PAUSE,0)<0)
- ALOGE("VoLTE resume failed");
- break;
- }
- }
- }
- break;
- case IMS_HOLD:
- if (mVolteCallActive == IMS_ACTIVE) {
- ALOGD("doRouting: IMS ACTIVE going to HOLD");
- ALSAHandleList::iterator vt_it;
- for(vt_it = mDeviceList.begin();
- vt_it != mDeviceList.end(); ++vt_it) {
- if((!strncmp(vt_it->useCase, SND_USE_CASE_VERB_VOLTE,
- strlen(SND_USE_CASE_VERB_VOLTE))) ||
- (!strncmp(vt_it->useCase, SND_USE_CASE_MOD_PLAY_VOLTE,
- strlen(SND_USE_CASE_MOD_PLAY_VOLTE)))) {
- mVolteCallActive = IMS_HOLD;
- alsa_handle_t *handle = (alsa_handle_t *)(&(*vt_it));
- if(ioctl((int)handle->handle->fd,SNDRV_PCM_IOCTL_PAUSE,1)<0)
- ALOGE("VoLTE Pause failed");
- break;
- }
- }
- }
- break;
- }
- return isRouted;
-}
-
-} // namespace android_audio_legacy
diff --git a/legacy/alsa_sound/AudioHardwareALSA.h b/legacy/alsa_sound/AudioHardwareALSA.h
deleted file mode 100644
index b65773a..0000000
--- a/legacy/alsa_sound/AudioHardwareALSA.h
+++ /dev/null
@@ -1,593 +0,0 @@
-/* AudioHardwareALSA.h
- **
- ** Copyright 2008-2010, Wind River Systems
- ** Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
- **
- ** Licensed under the Apache License, Version 2.0 (the "License");
- ** you may not use this file except in compliance with the License.
- ** You may obtain a copy of the License at
- **
- ** http://www.apache.org/licenses/LICENSE-2.0
- **
- ** Unless required by applicable law or agreed to in writing, software
- ** distributed under the License is distributed on an "AS IS" BASIS,
- ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ** See the License for the specific language governing permissions and
- ** limitations under the License.
- */
-
-#ifndef ANDROID_AUDIO_HARDWARE_ALSA_H
-#define ANDROID_AUDIO_HARDWARE_ALSA_H
-
-#define QCOM_CSDCLIENT_ENABLED 1
-
-#include <utils/List.h>
-#include <hardware_legacy/AudioHardwareBase.h>
-
-#include <hardware_legacy/AudioHardwareInterface.h>
-#include <hardware_legacy/AudioSystemLegacy.h>
-#include <system/audio.h>
-#include <hardware/audio.h>
-#include <utils/threads.h>
-#include <dlfcn.h>
-
-#ifdef QCOM_USBAUDIO_ENABLED
-#include <AudioUsbALSA.h>
-#endif
-
-extern "C" {
- #include <sound/asound.h>
- #include "alsa_audio.h"
- #include "msm8960_use_cases.h"
-}
-
-#include <hardware/hardware.h>
-
-namespace android_audio_legacy
-{
-using android::List;
-using android::Mutex;
-class AudioHardwareALSA;
-
-/**
- * The id of ALSA module
- */
-#define ALSA_HARDWARE_MODULE_ID "alsa"
-#define ALSA_HARDWARE_NAME "alsa"
-
-#define DEFAULT_SAMPLING_RATE 48000
-#define DEFAULT_CHANNEL_MODE 2
-#define VOICE_SAMPLING_RATE 8000
-#define VOICE_CHANNEL_MODE 1
-#define PLAYBACK_LATENCY 170000
-#define RECORD_LATENCY 96000
-#define VOICE_LATENCY 85333
-#define DEFAULT_BUFFER_SIZE 4096
-//4032 = 336(kernel buffer size) * 2(bytes pcm_16) * 6(number of channels)
-#define DEFAULT_MULTI_CHANNEL_BUF_SIZE 4032
-#define DEFAULT_VOICE_BUFFER_SIZE 2048
-#define PLAYBACK_LOW_LATENCY_BUFFER_SIZE 1024
-#define PLAYBACK_LOW_LATENCY 22000
-#define PLAYBACK_LOW_LATENCY_MEASURED 42000
-#define DEFAULT_IN_BUFFER_SIZE 320
-#define MIN_CAPTURE_BUFFER_SIZE_PER_CH 320
-#define MAX_CAPTURE_BUFFER_SIZE_PER_CH 2048
-#define FM_BUFFER_SIZE 1024
-
-#define VOIP_SAMPLING_RATE_8K 8000
-#define VOIP_SAMPLING_RATE_16K 16000
-#define VOIP_DEFAULT_CHANNEL_MODE 1
-#define VOIP_BUFFER_SIZE_8K 320
-#define VOIP_BUFFER_SIZE_16K 640
-#define VOIP_BUFFER_MAX_SIZE VOIP_BUFFER_SIZE_16K
-#define VOIP_PLAYBACK_LATENCY 6400
-#define VOIP_RECORD_LATENCY 6400
-
-#define MODE_IS127 0x2
-#define MODE_4GV_NB 0x3
-#define MODE_4GV_WB 0x4
-#define MODE_AMR 0x5
-#define MODE_AMR_WB 0xD
-#define MODE_PCM 0xC
-
-#define DUALMIC_KEY "dualmic_enabled"
-#define FLUENCE_KEY "fluence"
-#define ANC_KEY "anc_enabled"
-#define TTY_MODE_KEY "tty_mode"
-#define BT_SAMPLERATE_KEY "bt_samplerate"
-#define BTHEADSET_VGS "bt_headset_vgs"
-#define WIDEVOICE_KEY "wide_voice_enable"
-#define VOIPRATE_KEY "voip_rate"
-#define FENS_KEY "fens_enable"
-#define ST_KEY "st_enable"
-#define INCALLMUSIC_KEY "incall_music_enabled"
-
-#define ANC_FLAG 0x00000001
-#define DMIC_FLAG 0x00000002
-#define QMIC_FLAG 0x00000004
-#ifdef QCOM_SSR_ENABLED
-#define SSRQMIC_FLAG 0x00000008
-#endif
-
-#define TTY_OFF 0x00000010
-#define TTY_FULL 0x00000020
-#define TTY_VCO 0x00000040
-#define TTY_HCO 0x00000080
-#define TTY_CLEAR 0xFFFFFF0F
-
-#define LPA_SESSION_ID 1
-#define TUNNEL_SESSION_ID 2
-#ifdef QCOM_USBAUDIO_ENABLED
-static int USBPLAYBACKBIT_MUSIC = (1 << 0);
-static int USBPLAYBACKBIT_VOICECALL = (1 << 1);
-static int USBPLAYBACKBIT_VOIPCALL = (1 << 2);
-static int USBPLAYBACKBIT_FM = (1 << 3);
-static int USBPLAYBACKBIT_LPA = (1 << 4);
-
-static int USBRECBIT_REC = (1 << 0);
-static int USBRECBIT_VOICECALL = (1 << 1);
-static int USBRECBIT_VOIPCALL = (1 << 2);
-static int USBRECBIT_FM = (1 << 3);
-#endif
-
-#define DEVICE_SPEAKER_HEADSET "Speaker Headset"
-#define DEVICE_HEADSET "Headset"
-#define DEVICE_HEADPHONES "Headphones"
-
-#ifdef QCOM_SSR_ENABLED
-#define COEFF_ARRAY_SIZE 4
-#define FILT_SIZE ((512+1)* 6) /* # ((FFT bins)/2+1)*numOutputs */
-#define SSR_FRAME_SIZE 512
-#define SSR_INPUT_FRAME_SIZE (SSR_FRAME_SIZE * 4)
-#define SSR_OUTPUT_FRAME_SIZE (SSR_FRAME_SIZE * 6)
-#endif
-
-#define MODE_CALL_KEY "CALL_KEY"
-
-struct alsa_device_t;
-static uint32_t FLUENCE_MODE_ENDFIRE = 0;
-static uint32_t FLUENCE_MODE_BROADSIDE = 1;
-
-enum {
- INCALL_REC_MONO,
- INCALL_REC_STEREO,
-};
-
-enum audio_call_mode {
- CS_INACTIVE = 0x0,
- CS_ACTIVE = 0x1,
- CS_HOLD = 0x2,
- IMS_INACTIVE = 0x0,
- IMS_ACTIVE = 0x10,
- IMS_HOLD = 0x20
-};
-
-
-struct alsa_handle_t {
- alsa_device_t * module;
- uint32_t devices;
- char useCase[MAX_STR_LEN];
- struct pcm * handle;
- snd_pcm_format_t format;
- uint32_t channels;
- audio_channel_mask_t channelMask;
- uint32_t sampleRate;
- unsigned int latency; // Delay in usec
- unsigned int bufferSize; // Size of sample buffer
- unsigned int periodSize;
- bool isDeepbufferOutput;
- struct pcm * rxHandle;
- snd_use_case_mgr_t *ucMgr;
-};
-
-typedef List < alsa_handle_t > ALSAHandleList;
-
-struct use_case_t {
- char useCase[MAX_STR_LEN];
-};
-
-typedef List < use_case_t > ALSAUseCaseList;
-
-struct alsa_device_t {
- hw_device_t common;
-
- status_t (*init)(alsa_device_t *, ALSAHandleList &);
- status_t (*open)(alsa_handle_t *);
- status_t (*close)(alsa_handle_t *);
- status_t (*standby)(alsa_handle_t *);
- status_t (*route)(alsa_handle_t *, uint32_t, int);
- status_t (*startVoiceCall)(alsa_handle_t *);
- status_t (*startVoipCall)(alsa_handle_t *);
- status_t (*startFm)(alsa_handle_t *);
- void (*setVoiceVolume)(int);
- void (*setVoipVolume)(int);
- void (*setMicMute)(int);
- void (*setVoipMicMute)(int);
- void (*setVoipConfig)(int, int);
- status_t (*setFmVolume)(int);
- void (*setBtscoRate)(int);
- status_t (*setLpaVolume)(int);
- void (*enableWideVoice)(bool);
- void (*enableFENS)(bool);
- void (*setFlags)(uint32_t);
- status_t (*setCompressedVolume)(int);
- void (*enableSlowTalk)(bool);
- void (*setVocRecMode)(uint8_t);
- void (*setVoLTEMicMute)(int);
- void (*setVoLTEVolume)(int);
-#ifdef SEPERATED_AUDIO_INPUT
- void (*setInput)(int);
-#endif
-#ifdef QCOM_CSDCLIENT_ENABLED
- void (*setCsdHandle)(void*);
-#endif
-};
-
-// ----------------------------------------------------------------------------
-
-class ALSAMixer
-{
-public:
- ALSAMixer();
- virtual ~ALSAMixer();
-
- bool isValid() { return 1;}
- status_t setMasterVolume(float volume);
- status_t setMasterGain(float gain);
-
- status_t setVolume(uint32_t device, float left, float right);
- status_t setGain(uint32_t device, float gain);
-
- status_t setCaptureMuteState(uint32_t device, bool state);
- status_t getCaptureMuteState(uint32_t device, bool *state);
- status_t setPlaybackMuteState(uint32_t device, bool state);
- status_t getPlaybackMuteState(uint32_t device, bool *state);
-
-};
-
-class ALSAControl
-{
-public:
- ALSAControl(const char *device = "/dev/snd/controlC0");
- virtual ~ALSAControl();
-
- status_t get(const char *name, unsigned int &value, int index = 0);
- status_t set(const char *name, unsigned int value, int index = -1);
- status_t set(const char *name, const char *);
- status_t setext(const char *name, int count, char **setValues);
-
-private:
- struct mixer* mHandle;
-};
-
-class ALSAStreamOps
-{
-public:
- ALSAStreamOps(AudioHardwareALSA *parent, alsa_handle_t *handle);
- virtual ~ALSAStreamOps();
-
- status_t set(int *format, uint32_t *channels, uint32_t *rate, uint32_t device);
-
- status_t setParameters(const String8& keyValuePairs);
- String8 getParameters(const String8& keys);
-
- uint32_t sampleRate() const;
- size_t bufferSize() const;
- int format() const;
- uint32_t channels() const;
-
- status_t open(int mode);
- void close();
-
-protected:
- friend class AudioHardwareALSA;
-
- AudioHardwareALSA * mParent;
- alsa_handle_t * mHandle;
- uint32_t mDevices;
-};
-
-// ----------------------------------------------------------------------------
-
-class AudioStreamOutALSA : public AudioStreamOut, public ALSAStreamOps
-{
-public:
- AudioStreamOutALSA(AudioHardwareALSA *parent, alsa_handle_t *handle);
- virtual ~AudioStreamOutALSA();
-
- virtual uint32_t sampleRate() const
- {
- return ALSAStreamOps::sampleRate();
- }
-
- virtual size_t bufferSize() const
- {
- return ALSAStreamOps::bufferSize();
- }
-
- virtual uint32_t channels() const;
-
- virtual int format() const
- {
- return ALSAStreamOps::format();
- }
-
- virtual uint32_t latency() const;
-
- virtual ssize_t write(const void *buffer, size_t bytes);
- virtual status_t dump(int fd, const Vector<String16>& args);
-
- status_t setVolume(float left, float right);
-
- virtual status_t standby();
-
- virtual status_t setParameters(const String8& keyValuePairs) {
- return ALSAStreamOps::setParameters(keyValuePairs);
- }
-
- virtual String8 getParameters(const String8& keys) {
- return ALSAStreamOps::getParameters(keys);
- }
-
- // return the number of audio frames written by the audio dsp to DAC since
- // the output has exited standby
- virtual status_t getRenderPosition(uint32_t *dspFrames);
-
- status_t open(int mode);
- status_t close();
-
-private:
- uint32_t mFrameCount;
-
-protected:
- AudioHardwareALSA * mParent;
-};
-
-class AudioStreamInALSA : public AudioStreamIn, public ALSAStreamOps
-{
-public:
- AudioStreamInALSA(AudioHardwareALSA *parent,
- alsa_handle_t *handle,
- AudioSystem::audio_in_acoustics audio_acoustics);
- virtual ~AudioStreamInALSA();
-
- virtual uint32_t sampleRate() const
- {
- return ALSAStreamOps::sampleRate();
- }
-
- virtual size_t bufferSize() const
- {
- return ALSAStreamOps::bufferSize();
- }
-
- virtual uint32_t channels() const
- {
- return ALSAStreamOps::channels();
- }
-
- virtual int format() const
- {
- return ALSAStreamOps::format();
- }
-
- virtual ssize_t read(void* buffer, ssize_t bytes);
- virtual status_t dump(int fd, const Vector<String16>& args);
-
- virtual status_t setGain(float gain);
-
- virtual status_t standby();
-
- virtual status_t setParameters(const String8& keyValuePairs)
- {
- return ALSAStreamOps::setParameters(keyValuePairs);
- }
-
- virtual String8 getParameters(const String8& keys)
- {
- return ALSAStreamOps::getParameters(keys);
- }
-
- // Return the amount of input frames lost in the audio driver since the last call of this function.
- // Audio driver is expected to reset the value to 0 and restart counting upon returning the current value by this function call.
- // Such loss typically occurs when the user space process is blocked longer than the capacity of audio driver buffers.
- // Unit: the number of input audio frames
- virtual unsigned int getInputFramesLost() const;
-
- virtual status_t addAudioEffect(effect_handle_t effect)
- {
- return BAD_VALUE;
- }
-
- virtual status_t removeAudioEffect(effect_handle_t effect)
- {
- return BAD_VALUE;
- }
- status_t setAcousticParams(void* params);
-
- status_t open(int mode);
- status_t close();
-#ifdef QCOM_SSR_ENABLED
- // Helper function to initialize the Surround Sound library.
- status_t initSurroundSoundLibrary(unsigned long buffersize);
-#endif
-
-private:
- void resetFramesLost();
-
-#ifdef QCOM_CSDCLIENT_ENABLED
- int start_csd_record(int);
- int stop_csd_record(void);
-#endif
-
- unsigned int mFramesLost;
- AudioSystem::audio_in_acoustics mAcoustics;
-
-#ifdef QCOM_SSR_ENABLED
- // Function to read coefficients from files.
- status_t readCoeffsFromFile();
-
- FILE *mFp_4ch;
- FILE *mFp_6ch;
- int16_t **mRealCoeffs;
- int16_t **mImagCoeffs;
- void *mSurroundObj;
-
- int16_t *mSurroundInputBuffer;
- int16_t *mSurroundOutputBuffer;
- int mSurroundInputBufferIdx;
- int mSurroundOutputBufferIdx;
-#endif
-
-protected:
- AudioHardwareALSA * mParent;
-};
-
-class AudioHardwareALSA : public AudioHardwareBase
-{
-public:
- AudioHardwareALSA();
- virtual ~AudioHardwareALSA();
-
- /**
- * check to see if the audio hardware interface has been initialized.
- * return status based on values defined in include/utils/Errors.h
- */
- virtual status_t initCheck();
-
- /** set the audio volume of a voice call. Range is between 0.0 and 1.0 */
- virtual status_t setVoiceVolume(float volume);
-
- /**
- * set the audio volume for all audio activities other than voice call.
- * Range between 0.0 and 1.0. If any value other than NO_ERROR is returned,
- * the software mixer will emulate this capability.
- */
- virtual status_t setMasterVolume(float volume);
-#ifdef QCOM_FM_ENABLED
- virtual status_t setFmVolume(float volume);
-#endif
- /**
- * setMode is called when the audio mode changes. NORMAL mode is for
- * standard audio playback, RINGTONE when a ringtone is playing, and IN_CALL
- * when a call is in progress.
- */
- virtual status_t setMode(int mode);
-
- // mic mute
- virtual status_t setMicMute(bool state);
- virtual status_t getMicMute(bool* state);
-
- // set/get global audio parameters
- virtual status_t setParameters(const String8& keyValuePairs);
- virtual String8 getParameters(const String8& keys);
-
- // Returns audio input buffer size according to parameters passed or 0 if one of the
- // parameters is not supported
- virtual size_t getInputBufferSize(uint32_t sampleRate, int format, int channels);
-
-#ifdef QCOM_TUNNEL_LPA_ENABLED
- /** This method creates and opens the audio hardware output
- * session for LPA */
- virtual AudioStreamOut* openOutputSession(
- uint32_t devices,
- int *format,
- status_t *status,
- int sessionId,
- uint32_t samplingRate=0,
- uint32_t channels=0);
- virtual void closeOutputSession(AudioStreamOut* out);
-#endif
-
- /** This method creates and opens the audio hardware output stream */
- virtual AudioStreamOut* openOutputStream(
- uint32_t devices,
- int *format=0,
- uint32_t *channels=0,
- uint32_t *sampleRate=0,
- status_t *status=0);
- virtual void closeOutputStream(AudioStreamOut* out);
-
- /** This method creates and opens the audio hardware input stream */
- virtual AudioStreamIn* openInputStream(
- uint32_t devices,
- int *format,
- uint32_t *channels,
- uint32_t *sampleRate,
- status_t *status,
- AudioSystem::audio_in_acoustics acoustics);
- virtual void closeInputStream(AudioStreamIn* in);
-
- /**This method dumps the state of the audio hardware */
- //virtual status_t dumpState(int fd, const Vector<String16>& args);
-
- static AudioHardwareInterface* create();
-
- int mode()
- {
- return mMode;
- }
-
-protected:
- virtual status_t dump(int fd, const Vector<String16>& args);
- virtual uint32_t getVoipMode(int format);
- void doRouting(int device);
-#ifdef QCOM_FM_ENABLED
- void handleFm(int device);
-#endif
-#ifdef QCOM_USBAUDIO_ENABLED
- void closeUSBPlayback();
- void closeUSBRecording();
- void closeUsbRecordingIfNothingActive();
- void closeUsbPlaybackIfNothingActive();
- void startUsbPlaybackIfNotStarted();
- void startUsbRecordingIfNotStarted();
-#endif
-
- void disableVoiceCall(char* verb, char* modifier, int mode, int device);
- void enableVoiceCall(char* verb, char* modifier, int mode, int device);
- bool routeVoiceCall(int device, int newMode);
- bool routeVoLTECall(int device, int newMode);
- friend class AudioStreamOutALSA;
- friend class AudioStreamInALSA;
- friend class ALSAStreamOps;
-
- alsa_device_t * mALSADevice;
-
- ALSAHandleList mDeviceList;
-
-#ifdef QCOM_USBAUDIO_ENABLED
- AudioUsbALSA *mAudioUsbALSA;
-#endif
-
- Mutex mLock;
-
- snd_use_case_mgr_t *mUcMgr;
-
- uint32_t mCurDevice;
- /* The flag holds all the audio related device settings from
- * Settings and Qualcomm Settings applications */
- uint32_t mDevSettingsFlag;
- uint32_t mVoipStreamCount;
- uint32_t mVoipBitRate;
- uint32_t mIncallMode;
-
- bool mMicMute;
- int mCSCallActive;
- int mVolteCallActive;
- int mCallState;
- int mIsFmActive;
- bool mBluetoothVGS;
- bool mFusion3Platform;
-#ifdef QCOM_USBAUDIO_ENABLED
- int musbPlaybackState;
- int musbRecordingState;
-#endif
- void *mAcdbHandle;
- void *mCsdHandle;
-};
-
-// ----------------------------------------------------------------------------
-
-}; // namespace android_audio_legacy
-#endif // ANDROID_AUDIO_HARDWARE_ALSA_H
diff --git a/legacy/alsa_sound/AudioPolicyManagerALSA.cpp b/legacy/alsa_sound/AudioPolicyManagerALSA.cpp
deleted file mode 100644
index 36ae4d3..0000000
--- a/legacy/alsa_sound/AudioPolicyManagerALSA.cpp
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "AudioPolicyManagerALSA"
-//#define LOG_NDEBUG 0
-#define LOG_NDDEBUG 0
-#include <utils/Log.h>
-
-#include "AudioPolicyManagerALSA.h"
-#include <media/mediarecorder.h>
-
-namespace android_audio_legacy {
-
-// ----------------------------------------------------------------------------
-// AudioPolicyManagerALSA
-// ----------------------------------------------------------------------------
-
-//Compiling error seen if AudioParamer doesn't exist in this file
-
-AudioParameter param;
-
-// --- class factory
-
-
-extern "C" AudioPolicyInterface* createAudioPolicyManager(AudioPolicyClientInterface *clientInterface)
-{
- return new AudioPolicyManager(clientInterface);
-}
-
-extern "C" void destroyAudioPolicyManager(AudioPolicyInterface *interface)
-{
- delete interface;
-}
-
-void AudioPolicyManager::setPhoneState(int state) {
- ALOGV("setPhoneState() state %d", state);
- audio_devices_t newDevice = AUDIO_DEVICE_NONE;
- if (state < 0 || state >= AudioSystem::NUM_MODES) {
- ALOGW("setPhoneState() invalid state %d", state);
- return;
- }
-
- if (state == mPhoneState) {
- ALOGW("setPhoneState() setting same state %d", state);
- return;
- }
-
- // if leaving call state, handle special case of active streams
- // pertaining to sonification strategy see handleIncallSonification()
- if (isInCall()) {
- ALOGV("setPhoneState() in call state management: new state is %d", state);
- for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) {
- handleIncallSonification(stream, false, true);
- }
- }
-
- // store previous phone state for management of sonification strategy below
- int oldState = mPhoneState;
- mPhoneState = state;
- bool force = false;
-
- // are we entering or starting a call
- if (!isStateInCall(oldState) && isStateInCall(state)) {
- ALOGV(" Entering call in setPhoneState()");
- // force routing command to audio hardware when starting a call
- // even if no device change is needed
- force = true;
- } else if (isStateInCall(oldState) && !isStateInCall(state)) {
- ALOGV(" Exiting call in setPhoneState()");
- // force routing command to audio hardware when exiting a call
- // even if no device change is needed
- force = true;
- } else if (isStateInCall(state) && (state != oldState)) {
- ALOGV(" Switching between telephony and VoIP in setPhoneState()");
- // force routing command to audio hardware when switching between telephony and VoIP
- // even if no device change is needed
- force = true;
- }
-
- // check for device and output changes triggered by new phone state
- newDevice = getNewDevice(mPrimaryOutput, false /*fromCache*/);
- checkA2dpSuspend();
- checkOutputForAllStrategies();
- updateDevicesAndOutputs();
-
- AudioOutputDescriptor *hwOutputDesc = mOutputs.valueFor(mPrimaryOutput);
-
- // force routing command to audio hardware when ending call
- // even if no device change is needed
- if (isStateInCall(oldState) && newDevice == AUDIO_DEVICE_NONE) {
- newDevice = hwOutputDesc->device();
- }
-
- // when changing from ring tone to in call mode, mute the ringing tone
- // immediately and delay the route change to avoid sending the ring tone
- // tail into the earpiece or headset.
- int delayMs = 0;
- if (isStateInCall(state) && oldState == AudioSystem::MODE_RINGTONE) {
- // delay the device change command by twice the output latency to have some margin
- // and be sure that audio buffers not yet affected by the mute are out when
- // we actually apply the route change
- delayMs = hwOutputDesc->mLatency*2;
- setStreamMute(AudioSystem::RING, true, mPrimaryOutput);
- }
-
- if (isStateInCall(state)) {
- for (size_t i = 0; i < mOutputs.size(); i++) {
- AudioOutputDescriptor *desc = mOutputs.valueAt(i);
- //take the biggest latency for all outputs
- if (delayMs < desc->mLatency*2) {
- delayMs = desc->mLatency*2;
- }
- //mute STRATEGY_MEDIA on all outputs
- if (desc->strategyRefCount(STRATEGY_MEDIA) != 0) {
- setStrategyMute(STRATEGY_MEDIA, true, mOutputs.keyAt(i));
- setStrategyMute(STRATEGY_MEDIA, false, mOutputs.keyAt(i), MUTE_TIME_MS,
- getDeviceForStrategy(STRATEGY_MEDIA, true /*fromCache*/));
- }
- }
- }
-
- // Ignore the delay to enable voice call on this target as the enabling the
- // voice call has enough delay to make sure the ringtone audio completely
- // played out
- if (state == AudioSystem::MODE_IN_CALL && oldState == AudioSystem::MODE_RINGTONE) {
- delayMs = 40;
- }
-
- // change routing is necessary
- setOutputDevice(mPrimaryOutput, newDevice, force, delayMs);
-
- // if entering in call state, handle special case of active streams
- // pertaining to sonification strategy see handleIncallSonification()
- if (isStateInCall(state)) {
- ALOGV("setPhoneState() in call state management: new state is %d", state);
- // unmute the ringing tone after a sufficient delay if it was muted before
- // setting output device above
- if (oldState == AudioSystem::MODE_RINGTONE) {
- setStreamMute(AudioSystem::RING, false, mPrimaryOutput, MUTE_TIME_MS);
- }
- for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) {
- handleIncallSonification(stream, true, true);
- }
- }
-
- // Flag that ringtone volume must be limited to music volume until we exit MODE_RINGTONE
- if (state == AudioSystem::MODE_RINGTONE &&
- isStreamActive(AudioSystem::MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY)) {
- mLimitRingtoneVolume = true;
- } else {
- mLimitRingtoneVolume = false;
- }
-}
-
-}; // namespace androidi_audio_legacy
diff --git a/legacy/alsa_sound/AudioPolicyManagerALSA.h b/legacy/alsa_sound/AudioPolicyManagerALSA.h
deleted file mode 100644
index a343cff..0000000
--- a/legacy/alsa_sound/AudioPolicyManagerALSA.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- * Copyright (C) 2011-2012, The Linux Foundation. All rights reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-#include <stdint.h>
-#include <sys/types.h>
-#include <utils/Timers.h>
-#include <utils/Errors.h>
-#include <utils/KeyedVector.h>
-#include <hardware_legacy/AudioPolicyManagerBase.h>
-
-
-namespace android_audio_legacy {
-
-// ----------------------------------------------------------------------------
-
-class AudioPolicyManager: public AudioPolicyManagerBase
-{
-
-public:
- AudioPolicyManager(AudioPolicyClientInterface *clientInterface)
- : AudioPolicyManagerBase(clientInterface) {}
-
- virtual void setPhoneState(int state);
-
- virtual ~AudioPolicyManager() {}
-
-};
-};
diff --git a/legacy/alsa_sound/AudioStreamInALSA.cpp b/legacy/alsa_sound/AudioStreamInALSA.cpp
deleted file mode 100644
index 7887f55..0000000
--- a/legacy/alsa_sound/AudioStreamInALSA.cpp
+++ /dev/null
@@ -1,896 +0,0 @@
-/* AudioStreamInALSA.cpp
- **
- ** Copyright 2008-2009 Wind River Systems
- ** Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
- **
- ** Licensed under the Apache License, Version 2.0 (the "License");
- ** you may not use this file except in compliance with the License.
- ** You may obtain a copy of the License at
- **
- ** http://www.apache.org/licenses/LICENSE-2.0
- **
- ** Unless required by applicable law or agreed to in writing, software
- ** distributed under the License is distributed on an "AS IS" BASIS,
- ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ** See the License for the specific language governing permissions and
- ** limitations under the License.
- */
-
-#include <errno.h>
-#include <stdarg.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <dlfcn.h>
-
-#define LOG_TAG "AudioStreamInALSA"
-//#define LOG_NDEBUG 0
-#define LOG_NDDEBUG 0
-#include <utils/Log.h>
-#include <utils/String8.h>
-
-#include <cutils/properties.h>
-#include <media/AudioRecord.h>
-#include <hardware_legacy/power.h>
-
-#include "AudioHardwareALSA.h"
-
-extern "C" {
-#ifdef QCOM_CSDCLIENT_ENABLED
-static int (*csd_start_record)(int);
-static int (*csd_stop_record)(void);
-#endif
-
-#ifdef QCOM_SSR_ENABLED
-#include "surround_filters_interface.h"
-#endif
-}
-
-namespace android_audio_legacy
-{
-#ifdef QCOM_SSR_ENABLED
-#define SURROUND_FILE_1R "/system/etc/surround_sound/filter1r.pcm"
-#define SURROUND_FILE_2R "/system/etc/surround_sound/filter2r.pcm"
-#define SURROUND_FILE_3R "/system/etc/surround_sound/filter3r.pcm"
-#define SURROUND_FILE_4R "/system/etc/surround_sound/filter4r.pcm"
-
-#define SURROUND_FILE_1I "/system/etc/surround_sound/filter1i.pcm"
-#define SURROUND_FILE_2I "/system/etc/surround_sound/filter2i.pcm"
-#define SURROUND_FILE_3I "/system/etc/surround_sound/filter3i.pcm"
-#define SURROUND_FILE_4I "/system/etc/surround_sound/filter4i.pcm"
-
-// Use AAC/DTS channel mapping as default channel mapping: C,FL,FR,Ls,Rs,LFE
-const int chanMap[] = { 1, 2, 4, 3, 0, 5 };
-#endif
-
-AudioStreamInALSA::AudioStreamInALSA(AudioHardwareALSA *parent,
- alsa_handle_t *handle,
- AudioSystem::audio_in_acoustics audio_acoustics) :
- ALSAStreamOps(parent, handle),
- mFramesLost(0),
- mAcoustics(audio_acoustics),
- mParent(parent)
-#ifdef QCOM_SSR_ENABLED
- , mFp_4ch(NULL),
- mFp_6ch(NULL),
- mRealCoeffs(NULL),
- mImagCoeffs(NULL),
- mSurroundObj(NULL),
- mSurroundOutputBuffer(NULL),
- mSurroundInputBuffer(NULL),
- mSurroundOutputBufferIdx(0),
- mSurroundInputBufferIdx(0)
-#endif
-{
-#ifdef QCOM_SSR_ENABLED
- char c_multi_ch_dump[128] = {0};
- status_t err = NO_ERROR;
-
- // Call surround sound library init if device is Surround Sound
- if ( handle->channels == 6) {
- if (!strncmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC, strlen(SND_USE_CASE_VERB_HIFI_REC))
- || !strncmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC, strlen(SND_USE_CASE_MOD_CAPTURE_MUSIC))) {
-
- err = initSurroundSoundLibrary(handle->bufferSize);
- if ( NO_ERROR != err) {
- ALOGE("initSurroundSoundLibrary failed: %d handle->bufferSize:%d", err,handle->bufferSize);
- }
-
- property_get("ssr.pcmdump",c_multi_ch_dump,"0");
- if (0 == strncmp("true",c_multi_ch_dump, sizeof("ssr.dump-pcm"))) {
- //Remember to change file system permission of data(e.g. chmod 777 data/),
- //otherwise, fopen may fail.
- if ( !mFp_4ch)
- mFp_4ch = fopen("/data/4ch_ssr.pcm", "wb");
- if ( !mFp_6ch)
- mFp_6ch = fopen("/data/6ch_ssr.pcm", "wb");
- if ((!mFp_4ch) || (!mFp_6ch))
- ALOGE("mfp_4ch or mfp_6ch open failed: mfp_4ch:%p mfp_6ch:%p",mFp_4ch,mFp_6ch);
- }
- }
- }
-#endif
-}
-
-AudioStreamInALSA::~AudioStreamInALSA()
-{
- close();
-}
-
-status_t AudioStreamInALSA::setGain(float gain)
-{
- return 0; //mixer() ? mixer()->setMasterGain(gain) : (status_t)NO_INIT;
-}
-
-ssize_t AudioStreamInALSA::read(void *buffer, ssize_t bytes)
-{
- int period_size;
-
- ALOGV("read:: buffer %p, bytes %d", buffer, bytes);
-
- int n;
- status_t err;
- ssize_t read = 0;
- char *use_case;
- int newMode = mParent->mode();
-
- if((mHandle->handle == NULL) && (mHandle->rxHandle == NULL) &&
- (strcmp(mHandle->useCase, SND_USE_CASE_VERB_IP_VOICECALL)) &&
- (strcmp(mHandle->useCase, SND_USE_CASE_MOD_PLAY_VOIP))) {
- mParent->mLock.lock();
- snd_use_case_get(mHandle->ucMgr, "_verb", (const char **)&use_case);
- if ((use_case != NULL) && (strcmp(use_case, SND_USE_CASE_VERB_INACTIVE))) {
- if ((mHandle->devices == AudioSystem::DEVICE_IN_VOICE_CALL) &&
- (newMode == AudioSystem::MODE_IN_CALL)) {
- ALOGD("read:: mParent->mIncallMode=%d", mParent->mIncallMode);
- if ((mParent->mIncallMode & AudioSystem::CHANNEL_IN_VOICE_UPLINK) &&
- (mParent->mIncallMode & AudioSystem::CHANNEL_IN_VOICE_DNLINK)) {
-#ifdef QCOM_CSDCLIENT_ENABLED
- if (mParent->mFusion3Platform) {
- mParent->mALSADevice->setVocRecMode(INCALL_REC_STEREO);
- strlcpy(mHandle->useCase, SND_USE_CASE_MOD_CAPTURE_VOICE,
- sizeof(mHandle->useCase));
- start_csd_record(INCALL_REC_STEREO);
- } else
-#endif
- {
- strlcpy(mHandle->useCase, SND_USE_CASE_MOD_CAPTURE_VOICE_UL_DL,
- sizeof(mHandle->useCase));
- }
- } else if (mParent->mIncallMode & AudioSystem::CHANNEL_IN_VOICE_DNLINK) {
-#ifdef QCOM_CSDCLIENT_ENABLED
- if (mParent->mFusion3Platform) {
- mParent->mALSADevice->setVocRecMode(INCALL_REC_MONO);
- strlcpy(mHandle->useCase, SND_USE_CASE_MOD_CAPTURE_VOICE,
- sizeof(mHandle->useCase));
- start_csd_record(INCALL_REC_MONO);
- } else
-#endif
- {
- strlcpy(mHandle->useCase, SND_USE_CASE_MOD_CAPTURE_VOICE_DL,
- sizeof(mHandle->useCase));
- }
- }
-#ifdef QCOM_FM_ENABLED
- } else if(mHandle->devices == AudioSystem::DEVICE_IN_FM_RX) {
- strlcpy(mHandle->useCase, SND_USE_CASE_MOD_CAPTURE_FM, sizeof(mHandle->useCase));
- } else if (mHandle->devices == AudioSystem::DEVICE_IN_FM_RX_A2DP) {
- strlcpy(mHandle->useCase, SND_USE_CASE_MOD_CAPTURE_A2DP_FM, sizeof(mHandle->useCase));
-#endif
- } else if(!strcmp(mHandle->useCase, SND_USE_CASE_MOD_PLAY_VOIP)) {
- strlcpy(mHandle->useCase, SND_USE_CASE_MOD_PLAY_VOIP, sizeof(mHandle->useCase));
- } else {
- char value[128];
- property_get("persist.audio.lowlatency.rec",value,"0");
- if (!strcmp("true", value)) {
- strlcpy(mHandle->useCase, SND_USE_CASE_MOD_CAPTURE_LOWLATENCY_MUSIC, sizeof(mHandle->useCase));
- } else {
- strlcpy(mHandle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC, sizeof(mHandle->useCase));
- }
- }
- } else {
- if ((mHandle->devices == AudioSystem::DEVICE_IN_VOICE_CALL) &&
- (newMode == AudioSystem::MODE_IN_CALL)) {
- ALOGD("read:: ---- mParent->mIncallMode=%d", mParent->mIncallMode);
- if ((mParent->mIncallMode & AudioSystem::CHANNEL_IN_VOICE_UPLINK) &&
- (mParent->mIncallMode & AudioSystem::CHANNEL_IN_VOICE_DNLINK)) {
-#ifdef QCOM_CSDCLIENT_ENABLED
- if (mParent->mFusion3Platform) {
- mParent->mALSADevice->setVocRecMode(INCALL_REC_STEREO);
- strlcpy(mHandle->useCase, SND_USE_CASE_VERB_INCALL_REC,
- sizeof(mHandle->useCase));
- start_csd_record(INCALL_REC_STEREO);
- } else
-#endif
- {
- strlcpy(mHandle->useCase, SND_USE_CASE_VERB_UL_DL_REC,
- sizeof(mHandle->useCase));
- }
- } else if (mParent->mIncallMode & AudioSystem::CHANNEL_IN_VOICE_DNLINK) {
-#ifdef QCOM_CSDCLIENT_ENABLED
- if (mParent->mFusion3Platform) {
- mParent->mALSADevice->setVocRecMode(INCALL_REC_MONO);
- strlcpy(mHandle->useCase, SND_USE_CASE_VERB_INCALL_REC,
- sizeof(mHandle->useCase));
- start_csd_record(INCALL_REC_MONO);
- } else
-#endif
- {
- strlcpy(mHandle->useCase, SND_USE_CASE_VERB_DL_REC,
- sizeof(mHandle->useCase));
- }
- }
-#ifdef QCOM_FM_ENABLED
- } else if(mHandle->devices == AudioSystem::DEVICE_IN_FM_RX) {
- strlcpy(mHandle->useCase, SND_USE_CASE_VERB_FM_REC, sizeof(mHandle->useCase));
- } else if (mHandle->devices == AudioSystem::DEVICE_IN_FM_RX_A2DP) {
- strlcpy(mHandle->useCase, SND_USE_CASE_VERB_FM_A2DP_REC, sizeof(mHandle->useCase));
-#endif
- } else if(!strcmp(mHandle->useCase, SND_USE_CASE_VERB_IP_VOICECALL)){
- strlcpy(mHandle->useCase, SND_USE_CASE_VERB_IP_VOICECALL, sizeof(mHandle->useCase));
- } else {
- char value[128];
- property_get("persist.audio.lowlatency.rec",value,"0");
- if (!strcmp("true", value)) {
- strlcpy(mHandle->useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_REC, sizeof(mHandle->useCase));
- } else {
- strlcpy(mHandle->useCase, SND_USE_CASE_VERB_HIFI_REC, sizeof(mHandle->useCase));
- }
- }
- }
- if (mHandle->channelMask == AUDIO_CHANNEL_IN_FRONT_BACK) {
- mHandle->module->setFlags(mParent->mDevSettingsFlag | DMIC_FLAG);
- }
- free(use_case);
- if((!strcmp(mHandle->useCase, SND_USE_CASE_VERB_IP_VOICECALL)) ||
- (!strcmp(mHandle->useCase, SND_USE_CASE_MOD_PLAY_VOIP))) {
-#ifdef QCOM_USBAUDIO_ENABLED
- if((mDevices & AudioSystem::DEVICE_IN_ANLG_DOCK_HEADSET) ||
- (mDevices & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)) {
- mHandle->module->route(mHandle, (mDevices | AudioSystem::DEVICE_IN_PROXY) , AudioSystem::MODE_IN_COMMUNICATION);
- }else
-#endif
- {
- mHandle->module->route(mHandle, mDevices , AudioSystem::MODE_IN_COMMUNICATION);
- }
- } else {
-#ifdef QCOM_USBAUDIO_ENABLED
- if((mHandle->devices == AudioSystem::DEVICE_IN_ANLG_DOCK_HEADSET)||
- (mHandle->devices == AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)){
- mHandle->module->route(mHandle, AudioSystem::DEVICE_IN_PROXY , mParent->mode());
- } else
-#endif
- {
-
- mHandle->module->route(mHandle, mDevices , mParent->mode());
- }
- }
- if (!strcmp(mHandle->useCase, SND_USE_CASE_VERB_HIFI_REC) ||
- !strcmp(mHandle->useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_REC) ||
- !strcmp(mHandle->useCase, SND_USE_CASE_VERB_FM_REC) ||
- !strcmp(mHandle->useCase, SND_USE_CASE_VERB_IP_VOICECALL) ||
- !strcmp(mHandle->useCase, SND_USE_CASE_VERB_FM_A2DP_REC) ||
- !strcmp(mHandle->useCase, SND_USE_CASE_VERB_UL_DL_REC) ||
- !strcmp(mHandle->useCase, SND_USE_CASE_VERB_DL_REC) ||
- !strcmp(mHandle->useCase, SND_USE_CASE_VERB_INCALL_REC)) {
- snd_use_case_set(mHandle->ucMgr, "_verb", mHandle->useCase);
- } else {
- snd_use_case_set(mHandle->ucMgr, "_enamod", mHandle->useCase);
- }
- if((!strcmp(mHandle->useCase, SND_USE_CASE_VERB_IP_VOICECALL)) ||
- (!strcmp(mHandle->useCase, SND_USE_CASE_MOD_PLAY_VOIP))) {
- err = mHandle->module->startVoipCall(mHandle);
- }
- else
- mHandle->module->open(mHandle);
- if(mHandle->handle == NULL) {
- ALOGE("read:: PCM device open failed");
- mParent->mLock.unlock();
-
- return 0;
- }
-#ifdef QCOM_USBAUDIO_ENABLED
- if((mHandle->devices == AudioSystem::DEVICE_IN_ANLG_DOCK_HEADSET)||
- (mHandle->devices == AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)){
- if((!strcmp(mHandle->useCase, SND_USE_CASE_VERB_IP_VOICECALL)) ||
- (!strcmp(mHandle->useCase, SND_USE_CASE_MOD_PLAY_VOIP))) {
- mParent->musbRecordingState |= USBRECBIT_VOIPCALL;
- } else {
- mParent->startUsbRecordingIfNotStarted();
- mParent->musbRecordingState |= USBRECBIT_REC;
- }
- }
-#endif
- mParent->mLock.unlock();
- }
-#ifdef QCOM_USBAUDIO_ENABLED
- if(((mDevices & AudioSystem::DEVICE_IN_ANLG_DOCK_HEADSET) ||
- (mDevices & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)) &&
- (!mParent->musbRecordingState)) {
- mParent->mLock.lock();
- ALOGD("Starting UsbRecording thread");
- mParent->startUsbRecordingIfNotStarted();
- if(!strcmp(mHandle->useCase, SND_USE_CASE_VERB_IP_VOICECALL) ||
- !strcmp(mHandle->useCase, SND_USE_CASE_MOD_PLAY_VOIP)) {
- ALOGD("Enabling voip recording bit");
- mParent->musbRecordingState |= USBRECBIT_VOIPCALL;
- }else{
- ALOGD("Enabling HiFi Recording bit");
- mParent->musbRecordingState |= USBRECBIT_REC;
- }
- mParent->mLock.unlock();
- }
-#endif
- period_size = mHandle->periodSize;
- int read_pending = bytes;
-
-#ifdef QCOM_SSR_ENABLED
- if (mSurroundObj) {
- int processed = 0;
- int processed_pending;
- int samples = bytes >> 1;
- void *buffer_start = buffer;
- int period_bytes = mHandle->handle->period_size;
- int period_samples = period_bytes >> 1;
-
- do {
- if (mSurroundOutputBufferIdx > 0) {
- ALOGV("AudioStreamInALSA::read() - copy processed output "
- "to buffer, mSurroundOutputBufferIdx = %d",
- mSurroundOutputBufferIdx);
- // Copy processed output to buffer
- processed_pending = mSurroundOutputBufferIdx;
- if (processed_pending > (samples - processed)) {
- processed_pending = (samples - processed);
- }
- memcpy(buffer, mSurroundOutputBuffer, processed_pending * sizeof(Word16));
- buffer += processed_pending * sizeof(Word16);
- processed += processed_pending;
- if (mSurroundOutputBufferIdx > processed_pending) {
- // Shift leftover samples to beginning of the buffer
- memcpy(&mSurroundOutputBuffer[0],
- &mSurroundOutputBuffer[processed_pending],
- (mSurroundOutputBufferIdx - processed_pending) * sizeof(Word16));
- }
- mSurroundOutputBufferIdx -= processed_pending;
- }
-
- if (processed >= samples) {
- ALOGV("AudioStreamInALSA::read() - done processing buffer, "
- "processed = %d", processed);
- // Done processing this buffer
- break;
- }
-
- // Fill input buffer until there is enough to process
- read_pending = SSR_INPUT_FRAME_SIZE - mSurroundInputBufferIdx;
- read = mSurroundInputBufferIdx;
- while (mHandle->handle && read_pending > 0) {
- n = pcm_read(mHandle->handle, &mSurroundInputBuffer[read],
- period_bytes);
- ALOGV("pcm_read() returned n = %d buffer:%p size:%d", n, &mSurroundInputBuffer[read], period_bytes);
- if (n && n != -EAGAIN) {
- //Recovery part of pcm_read. TODO:split recovery.
- return static_cast<ssize_t>(n);
- }
- else if (n < 0) {
- // Recovery is part of pcm_write. TODO split is later.
- return static_cast<ssize_t>(n);
- }
- else {
- read_pending -= period_samples;
- read += period_samples;
- }
- }
-
-
- if (mFp_4ch) {
- fwrite( mSurroundInputBuffer, 1,
- SSR_INPUT_FRAME_SIZE * sizeof(Word16), mFp_4ch);
- }
-
- //apply ssr libs to conver 4ch to 6ch
- surround_filters_intl_process(mSurroundObj,
- &mSurroundOutputBuffer[mSurroundOutputBufferIdx],
- (Word16 *)mSurroundInputBuffer);
-
- // Shift leftover samples to beginning of input buffer
- if (read_pending < 0) {
- memcpy(&mSurroundInputBuffer[0],
- &mSurroundInputBuffer[SSR_INPUT_FRAME_SIZE],
- (-read_pending) * sizeof(Word16));
- }
- mSurroundInputBufferIdx = -read_pending;
-
- if (mFp_6ch) {
- fwrite( &mSurroundOutputBuffer[mSurroundOutputBufferIdx],
- 1, SSR_OUTPUT_FRAME_SIZE * sizeof(Word16), mFp_6ch);
- }
-
- mSurroundOutputBufferIdx += SSR_OUTPUT_FRAME_SIZE;
- ALOGV("do_while loop: processed=%d, samples=%d\n", processed, samples);
- } while (mHandle->handle && processed < samples);
- read = processed * sizeof(Word16);
- buffer = buffer_start;
- } else
-#endif
- {
-
- do {
- if (read_pending < period_size) {
- read_pending = period_size;
- }
-
- n = pcm_read(mHandle->handle, buffer,
- period_size);
- ALOGV("pcm_read() returned n = %d", n);
- if (n && (n == -EIO || n == -EAGAIN || n == -EPIPE || n == -EBADFD)) {
- mParent->mLock.lock();
- ALOGW("pcm_read() returned error n %d, Recovering from error\n", n);
- pcm_close(mHandle->handle);
- mHandle->handle = NULL;
- if((!strncmp(mHandle->useCase, SND_USE_CASE_VERB_IP_VOICECALL, strlen(SND_USE_CASE_VERB_IP_VOICECALL))) ||
- (!strncmp(mHandle->useCase, SND_USE_CASE_MOD_PLAY_VOIP, strlen(SND_USE_CASE_MOD_PLAY_VOIP)))) {
- pcm_close(mHandle->rxHandle);
- mHandle->rxHandle = NULL;
- mHandle->module->startVoipCall(mHandle);
- }
- else
- mHandle->module->open(mHandle);
-
- if(mHandle->handle == NULL) {
- ALOGE("read:: PCM device re-open failed");
- mParent->mLock.unlock();
- return 0;
- }
-
- mParent->mLock.unlock();
- continue;
- }
- else if (n < 0) {
- ALOGD("pcm_read() returned n < 0");
- return static_cast<ssize_t>(n);
- }
- else {
- read += static_cast<ssize_t>((period_size));
- read_pending -= period_size;
- //Set mute by cleanning buffers read
- if (mParent->mMicMute) {
- memset(buffer, 0, period_size);
- }
- buffer = ((uint8_t *)buffer) + period_size;
- }
-
- } while (mHandle->handle && read < bytes);
- }
-
- return read;
-}
-
-status_t AudioStreamInALSA::dump(int fd, const Vector<String16>& args)
-{
- return NO_ERROR;
-}
-
-status_t AudioStreamInALSA::open(int mode)
-{
- Mutex::Autolock autoLock(mParent->mLock);
-
- status_t status = ALSAStreamOps::open(mode);
-
- return status;
-}
-
-status_t AudioStreamInALSA::close()
-{
- Mutex::Autolock autoLock(mParent->mLock);
-
- ALOGD("close");
- if((!strcmp(mHandle->useCase, SND_USE_CASE_VERB_IP_VOICECALL)) ||
- (!strcmp(mHandle->useCase, SND_USE_CASE_MOD_PLAY_VOIP))) {
- if((mParent->mVoipStreamCount)) {
-#ifdef QCOM_USBAUDIO_ENABLED
- ALOGD("musbRecordingState: %d, mVoipStreamCount:%d",mParent->musbRecordingState,
- mParent->mVoipStreamCount );
- if(mParent->mVoipStreamCount == 1) {
- ALOGD("Deregistering VOIP Call bit, musbPlaybackState:%d,"
- "musbRecordingState:%d", mParent->musbPlaybackState, mParent->musbRecordingState);
- mParent->musbPlaybackState &= ~USBPLAYBACKBIT_VOIPCALL;
- mParent->musbRecordingState &= ~USBRECBIT_VOIPCALL;
- mParent->closeUsbRecordingIfNothingActive();
- mParent->closeUsbPlaybackIfNothingActive();
- }
-#endif
- return NO_ERROR;
- }
- mParent->mVoipStreamCount = 0;
-#ifdef QCOM_USBAUDIO_ENABLED
- } else {
- ALOGD("Deregistering REC bit, musbRecordingState:%d", mParent->musbRecordingState);
- mParent->musbRecordingState &= ~USBRECBIT_REC;
-#endif
- }
-#ifdef QCOM_CSDCLIENT_ENABLED
- if (mParent->mFusion3Platform) {
- if((!strcmp(mHandle->useCase, SND_USE_CASE_VERB_INCALL_REC)) ||
- (!strcmp(mHandle->useCase, SND_USE_CASE_MOD_CAPTURE_VOICE))) {
- stop_csd_record();
- }
- }
-#endif
- ALOGD("close");
-#ifdef QCOM_USBAUDIO_ENABLED
- mParent->closeUsbRecordingIfNothingActive();
-#endif
-
- ALSAStreamOps::close();
-
-#ifdef QCOM_SSR_ENABLED
- if (mSurroundObj) {
- surround_filters_release(mSurroundObj);
- if (mSurroundObj)
- free(mSurroundObj);
- mSurroundObj = NULL;
- if (mRealCoeffs){
- for (int i =0; i<COEFF_ARRAY_SIZE; i++ ) {
- if (mRealCoeffs[i]) {
- free(mRealCoeffs[i]);
- mRealCoeffs[i] = NULL;
- }
- }
- free(mRealCoeffs);
- mRealCoeffs = NULL;
- }
- if (mImagCoeffs){
- for (int i =0; i<COEFF_ARRAY_SIZE; i++ ) {
- if (mImagCoeffs[i]) {
- free(mImagCoeffs[i]);
- mImagCoeffs[i] = NULL;
- }
- }
- free(mImagCoeffs);
- mImagCoeffs = NULL;
- }
- if (mSurroundOutputBuffer){
- free(mSurroundOutputBuffer);
- mSurroundOutputBuffer = NULL;
- }
- if (mSurroundInputBuffer) {
- free(mSurroundInputBuffer);
- mSurroundInputBuffer = NULL;
- }
-
- if ( mFp_4ch ) fclose(mFp_4ch);
- if ( mFp_6ch ) fclose(mFp_6ch);
-
- }
-#endif
-
- return NO_ERROR;
-}
-
-status_t AudioStreamInALSA::standby()
-{
- Mutex::Autolock autoLock(mParent->mLock);
-
- ALOGD("standby");
-
- if((!strcmp(mHandle->useCase, SND_USE_CASE_VERB_IP_VOICECALL)) ||
- (!strcmp(mHandle->useCase, SND_USE_CASE_MOD_PLAY_VOIP))) {
- return NO_ERROR;
- }
-
-#ifdef QCOM_CSDCLIENT_ENABLED
- ALOGD("standby");
- if (mParent->mFusion3Platform) {
- if((!strcmp(mHandle->useCase, SND_USE_CASE_VERB_INCALL_REC)) ||
- (!strcmp(mHandle->useCase, SND_USE_CASE_MOD_CAPTURE_VOICE))) {
- ALOGD(" into standby, stop record");
- stop_csd_record();
- }
- }
-#endif
- mHandle->module->standby(mHandle);
-
-#ifdef QCOM_USBAUDIO_ENABLED
- ALOGD("Checking for musbRecordingState %d", mParent->musbRecordingState);
- mParent->musbRecordingState &= ~USBRECBIT_REC;
- mParent->closeUsbRecordingIfNothingActive();
-#endif
-
- if (mHandle->channelMask == AUDIO_CHANNEL_IN_FRONT_BACK) {
- mHandle->module->setFlags(mParent->mDevSettingsFlag);
- }
-
- return NO_ERROR;
-}
-
-void AudioStreamInALSA::resetFramesLost()
-{
- mFramesLost = 0;
-}
-
-unsigned int AudioStreamInALSA::getInputFramesLost() const
-{
- unsigned int count = mFramesLost;
- // Stupid interface wants us to have a side effect of clearing the count
- // but is defined as a const to prevent such a thing.
- ((AudioStreamInALSA *)this)->resetFramesLost();
- return count;
-}
-
-status_t AudioStreamInALSA::setAcousticParams(void *params)
-{
- Mutex::Autolock autoLock(mParent->mLock);
-
- return (status_t)NO_ERROR;
-}
-
-#ifdef QCOM_SSR_ENABLED
-status_t AudioStreamInALSA::initSurroundSoundLibrary(unsigned long buffersize)
-{
- int subwoofer = 0; // subwoofer channel assignment: default as first microphone input channel
- int low_freq = 4; // frequency upper bound for subwoofer: frequency=(low_freq-1)/FFT_SIZE*samplingRate, default as 4
- int high_freq = 100; // frequency upper bound for spatial processing: frequency=(high_freq-1)/FFT_SIZE*samplingRate, default as 100
- int ret = 0;
-
- mSurroundInputBufferIdx = 0;
- mSurroundOutputBufferIdx = 0;
-
- if ( mSurroundObj ) {
- ALOGE("ola filter library is already initialized");
- return ALREADY_EXISTS;
- }
-
- // Allocate memory for input buffer
- mSurroundInputBuffer = (Word16 *) calloc(2 * SSR_INPUT_FRAME_SIZE,
- sizeof(Word16));
- if ( !mSurroundInputBuffer ) {
- ALOGE("Memory allocation failure. Not able to allocate memory for surroundInputBuffer");
- goto init_fail;
- }
-
- // Allocate memory for output buffer
- mSurroundOutputBuffer = (Word16 *) calloc(2 * SSR_OUTPUT_FRAME_SIZE,
- sizeof(Word16));
- if ( !mSurroundOutputBuffer ) {
- ALOGE("Memory allocation failure. Not able to allocate memory for surroundOutputBuffer");
- goto init_fail;
- }
-
- // Allocate memory for real and imag coeffs array
- mRealCoeffs = (Word16 **) calloc(COEFF_ARRAY_SIZE, sizeof(Word16 *));
- if ( !mRealCoeffs ) {
- ALOGE("Memory allocation failure during real Coefficient array");
- goto init_fail;
- }
-
- mImagCoeffs = (Word16 **) calloc(COEFF_ARRAY_SIZE, sizeof(Word16 *));
- if ( !mImagCoeffs ) {
- ALOGE("Memory allocation failure during imaginary Coefficient array");
- goto init_fail;
- }
-
- if( readCoeffsFromFile() != NO_ERROR) {
- ALOGE("Error while loading coeffs from file");
- goto init_fail;
- }
-
- //calculate the size of data to allocate for mSurroundObj
- ret = surround_filters_init(NULL,
- 6, // Num output channel
- 4, // Num input channel
- mRealCoeffs, // Coeffs hardcoded in header
- mImagCoeffs, // Coeffs hardcoded in header
- subwoofer,
- low_freq,
- high_freq,
- NULL);
-
- if ( ret > 0 ) {
- ALOGV("Allocating surroundObj size is %d", ret);
- mSurroundObj = (void *)malloc(ret);
- memset(mSurroundObj,0,ret);
- if (NULL != mSurroundObj) {
- //initialize after allocating the memory for mSurroundObj
- ret = surround_filters_init(mSurroundObj,
- 6,
- 4,
- mRealCoeffs,
- mImagCoeffs,
- subwoofer,
- low_freq,
- high_freq,
- NULL);
- if (0 != ret) {
- ALOGE("surround_filters_init failed with ret:%d",ret);
- surround_filters_release(mSurroundObj);
- goto init_fail;
- }
- } else {
- ALOGE("Allocationg mSurroundObj failed");
- goto init_fail;
- }
- } else {
- ALOGE("surround_filters_init(mSurroundObj=Null) failed with ret: %d",ret);
- goto init_fail;
- }
-
- (void) surround_filters_set_channel_map(mSurroundObj, chanMap);
-
- return NO_ERROR;
-
-init_fail:
- if (mSurroundObj) {
- free(mSurroundObj);
- mSurroundObj = NULL;
- }
- if (mSurroundOutputBuffer) {
- free(mSurroundOutputBuffer);
- mSurroundOutputBuffer = NULL;
- }
- if (mSurroundInputBuffer) {
- free(mSurroundInputBuffer);
- mSurroundInputBuffer = NULL;
- }
- if (mRealCoeffs){
- for (int i =0; i<COEFF_ARRAY_SIZE; i++ ) {
- if (mRealCoeffs[i]) {
- free(mRealCoeffs[i]);
- mRealCoeffs[i] = NULL;
- }
- }
- free(mRealCoeffs);
- mRealCoeffs = NULL;
- }
- if (mImagCoeffs){
- for (int i =0; i<COEFF_ARRAY_SIZE; i++ ) {
- if (mImagCoeffs[i]) {
- free(mImagCoeffs[i]);
- mImagCoeffs[i] = NULL;
- }
- }
- free(mImagCoeffs);
- mImagCoeffs = NULL;
- }
-
- return NO_MEMORY;
-
-}
-
-
-// Helper function to read coeffs from File and updates real and imaginary
-// coeff array member variable
-status_t AudioStreamInALSA::readCoeffsFromFile()
-{
- FILE *flt1r;
- FILE *flt2r;
- FILE *flt3r;
- FILE *flt4r;
- FILE *flt1i;
- FILE *flt2i;
- FILE *flt3i;
- FILE *flt4i;
-
- if ( (flt1r = fopen(SURROUND_FILE_1R, "rb")) == NULL ) {
- ALOGE("Cannot open filter co-efficient file %s", SURROUND_FILE_1R);
- return NAME_NOT_FOUND;
- }
-
- if ( (flt2r = fopen(SURROUND_FILE_2R, "rb")) == NULL ) {
- ALOGE("Cannot open filter co-efficient file %s", SURROUND_FILE_2R);
- return NAME_NOT_FOUND;
- }
-
- if ( (flt3r = fopen(SURROUND_FILE_3R, "rb")) == NULL ) {
- ALOGE("Cannot open filter co-efficient file %s", SURROUND_FILE_3R);
- return NAME_NOT_FOUND;
- }
-
- if ( (flt4r = fopen(SURROUND_FILE_4R, "rb")) == NULL ) {
- ALOGE("Cannot open filter co-efficient file %s", SURROUND_FILE_4R);
- return NAME_NOT_FOUND;
- }
-
- if ( (flt1i = fopen(SURROUND_FILE_1I, "rb")) == NULL ) {
- ALOGE("Cannot open filter co-efficient file %s", SURROUND_FILE_1I);
- return NAME_NOT_FOUND;
- }
-
- if ( (flt2i = fopen(SURROUND_FILE_2I, "rb")) == NULL ) {
- ALOGE("Cannot open filter co-efficient file %s", SURROUND_FILE_2I);
- return NAME_NOT_FOUND;
- }
-
- if ( (flt3i = fopen(SURROUND_FILE_3I, "rb")) == NULL ) {
- ALOGE("Cannot open filter co-efficient file %s", SURROUND_FILE_3I);
- return NAME_NOT_FOUND;
- }
-
- if ( (flt4i = fopen(SURROUND_FILE_4I, "rb")) == NULL ) {
- ALOGE("Cannot open filter co-efficient file %s", SURROUND_FILE_4I);
- return NAME_NOT_FOUND;
- }
- ALOGV("readCoeffsFromFile all filter files opened");
-
- for (int i=0; i<COEFF_ARRAY_SIZE; i++) {
- mRealCoeffs[i] = (Word16 *)calloc(FILT_SIZE, sizeof(Word16));
- }
- for (int i=0; i<COEFF_ARRAY_SIZE; i++) {
- mImagCoeffs[i] = (Word16 *)calloc(FILT_SIZE, sizeof(Word16));
- }
-
- // Read real co-efficients
- if (NULL != mRealCoeffs[0]) {
- fread(mRealCoeffs[0], sizeof(int16), FILT_SIZE, flt1r);
- }
- if (NULL != mRealCoeffs[0]) {
- fread(mRealCoeffs[1], sizeof(int16), FILT_SIZE, flt2r);
- }
- if (NULL != mRealCoeffs[0]) {
- fread(mRealCoeffs[2], sizeof(int16), FILT_SIZE, flt3r);
- }
- if (NULL != mRealCoeffs[0]) {
- fread(mRealCoeffs[3], sizeof(int16), FILT_SIZE, flt4r);
- }
-
- // read imaginary co-efficients
- if (NULL != mImagCoeffs[0]) {
- fread(mImagCoeffs[0], sizeof(int16), FILT_SIZE, flt1i);
- }
- if (NULL != mImagCoeffs[0]) {
- fread(mImagCoeffs[1], sizeof(int16), FILT_SIZE, flt2i);
- }
- if (NULL != mImagCoeffs[0]) {
- fread(mImagCoeffs[2], sizeof(int16), FILT_SIZE, flt3i);
- }
- if (NULL != mImagCoeffs[0]) {
- fread(mImagCoeffs[3], sizeof(int16), FILT_SIZE, flt4i);
- }
-
- fclose(flt1r);
- fclose(flt2r);
- fclose(flt3r);
- fclose(flt4r);
- fclose(flt1i);
- fclose(flt2i);
- fclose(flt3i);
- fclose(flt4i);
-
- return NO_ERROR;
-}
-#endif
-
-#ifdef QCOM_CSDCLIENT_ENABLED
-int AudioStreamInALSA::start_csd_record(int param)
-{
- int err = NO_ERROR;
-
- if (mParent->mCsdHandle != NULL) {
- csd_start_record = (int (*)(int))::dlsym(mParent->mCsdHandle,"csd_client_start_record");
- if (csd_start_record == NULL) {
- ALOGE("dlsym:Error:%s Loading csd_client_start_record", dlerror());
- } else {
- err = csd_start_record(param);
- }
- }
- return err;
-}
-
-int AudioStreamInALSA::stop_csd_record()
-{
- int err = NO_ERROR;
- if (mParent->mCsdHandle != NULL) {
- csd_stop_record = (int (*)())::dlsym(mParent->mCsdHandle,"csd_client_stop_record");
- if (csd_start_record == NULL) {
- ALOGE("dlsym:Error:%s Loading csd_client_start_record", dlerror());
- } else {
- csd_stop_record();
- }
- }
- return err;
-}
-#endif
-
-} // namespace android_audio_legacy
diff --git a/legacy/alsa_sound/AudioStreamOutALSA.cpp b/legacy/alsa_sound/AudioStreamOutALSA.cpp
deleted file mode 100644
index bbb8d3d..0000000
--- a/legacy/alsa_sound/AudioStreamOutALSA.cpp
+++ /dev/null
@@ -1,384 +0,0 @@
-/* AudioStreamOutALSA.cpp
- **
- ** Copyright 2008-2009 Wind River Systems
- ** Copyright (c) 2011, The Linux Foundation. All rights reserved.
- **
- ** Licensed under the Apache License, Version 2.0 (the "License");
- ** you may not use this file except in compliance with the License.
- ** You may obtain a copy of the License at
- **
- ** http://www.apache.org/licenses/LICENSE-2.0
- **
- ** Unless required by applicable law or agreed to in writing, software
- ** distributed under the License is distributed on an "AS IS" BASIS,
- ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ** See the License for the specific language governing permissions and
- ** limitations under the License.
- */
-
-#include <errno.h>
-#include <stdarg.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <dlfcn.h>
-#include <math.h>
-
-#define LOG_TAG "AudioStreamOutALSA"
-//#define LOG_NDEBUG 0
-#define LOG_NDDEBUG 0
-#include <utils/Log.h>
-#include <utils/String8.h>
-
-#include <cutils/properties.h>
-#include <media/AudioRecord.h>
-#include <hardware_legacy/power.h>
-
-#include "AudioHardwareALSA.h"
-
-#ifndef ALSA_DEFAULT_SAMPLE_RATE
-#define ALSA_DEFAULT_SAMPLE_RATE 44100 // in Hz
-#endif
-
-namespace android_audio_legacy
-{
-
-// ----------------------------------------------------------------------------
-
-static const int DEFAULT_SAMPLE_RATE = ALSA_DEFAULT_SAMPLE_RATE;
-
-// ----------------------------------------------------------------------------
-
-AudioStreamOutALSA::AudioStreamOutALSA(AudioHardwareALSA *parent, alsa_handle_t *handle) :
- ALSAStreamOps(parent, handle),
- mParent(parent),
- mFrameCount(0)
-{
-}
-
-AudioStreamOutALSA::~AudioStreamOutALSA()
-{
- close();
-}
-
-uint32_t AudioStreamOutALSA::channels() const
-{
- int c = ALSAStreamOps::channels();
- return c;
-}
-
-status_t AudioStreamOutALSA::setVolume(float left, float right)
-{
- int vol;
- float volume;
- status_t status = NO_ERROR;
-
- volume = (left + right) / 2;
- if (volume < 0.0) {
- ALOGW("AudioSessionOutALSA::setVolume(%f) under 0.0, assuming 0.0\n", volume);
- volume = 0.0;
- } else if (volume > 1.0) {
- ALOGW("AudioSessionOutALSA::setVolume(%f) over 1.0, assuming 1.0\n", volume);
- volume = 1.0;
- }
- vol = lrint((volume * 0x2000)+0.5);
-
- if(!strcmp(mHandle->useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER) ||
- !strcmp(mHandle->useCase, SND_USE_CASE_MOD_PLAY_LPA)) {
- ALOGV("setLpaVolume(%f)\n", volume);
- ALOGV("Setting LPA volume to %d (available range is 0 to 100)\n", vol);
- mHandle->module->setLpaVolume(vol);
- return status;
- }
- else if(!strcmp(mHandle->useCase, SND_USE_CASE_VERB_HIFI_TUNNEL) ||
- !strcmp(mHandle->useCase, SND_USE_CASE_MOD_PLAY_TUNNEL)) {
- ALOGV("setCompressedVolume(%f)\n", volume);
- ALOGV("Setting Compressed volume to %d (available range is 0 to 100)\n", vol);
- mHandle->module->setCompressedVolume(vol);
- return status;
- }
- else if(!strncmp(mHandle->useCase, SND_USE_CASE_VERB_IP_VOICECALL,
- sizeof(mHandle->useCase)) || !strncmp(mHandle->useCase,
- SND_USE_CASE_MOD_PLAY_VOIP, sizeof(mHandle->useCase))) {
- ALOGV("Avoid Software volume by returning success\n");
- return status;
- }
- return INVALID_OPERATION;
-}
-
-ssize_t AudioStreamOutALSA::write(const void *buffer, size_t bytes)
-{
- int period_size;
- char *use_case;
-
- ALOGV("write:: buffer %p, bytes %d", buffer, bytes);
-
- snd_pcm_sframes_t n = 0;
- size_t sent = 0;
- status_t err;
-
- int write_pending = bytes;
-
- if((mHandle->handle == NULL) && (mHandle->rxHandle == NULL) &&
- (strcmp(mHandle->useCase, SND_USE_CASE_VERB_IP_VOICECALL)) &&
- (strcmp(mHandle->useCase, SND_USE_CASE_MOD_PLAY_VOIP))) {
- mParent->mLock.lock();
-
- ALOGD("mHandle->useCase: %s", mHandle->useCase);
- snd_use_case_get(mHandle->ucMgr, "_verb", (const char **)&use_case);
- if ((use_case == NULL) || (!strcmp(use_case, SND_USE_CASE_VERB_INACTIVE))) {
- if(!strcmp(mHandle->useCase, SND_USE_CASE_MOD_PLAY_VOIP)){
- strlcpy(mHandle->useCase, SND_USE_CASE_VERB_IP_VOICECALL,
- sizeof(SND_USE_CASE_VERB_IP_VOICECALL));
- } else if(!strcmp(mHandle->useCase,SND_USE_CASE_MOD_PLAY_MUSIC2)) {
- strlcpy(mHandle->useCase, SND_USE_CASE_VERB_HIFI2,
- sizeof(SND_USE_CASE_MOD_PLAY_MUSIC2));
- } else if (!strcmp(mHandle->useCase,SND_USE_CASE_MOD_PLAY_MUSIC)){
- strlcpy(mHandle->useCase, SND_USE_CASE_VERB_HIFI,
- sizeof(SND_USE_CASE_MOD_PLAY_MUSIC));
- } else if(!strcmp(mHandle->useCase, SND_USE_CASE_MOD_PLAY_LOWLATENCY_MUSIC)) {
- strlcpy(mHandle->useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_MUSIC,
- sizeof(SND_USE_CASE_MOD_PLAY_LOWLATENCY_MUSIC));
- }
- } else {
- if(!strcmp(mHandle->useCase, SND_USE_CASE_VERB_IP_VOICECALL)){
- strlcpy(mHandle->useCase, SND_USE_CASE_MOD_PLAY_VOIP,
- sizeof(SND_USE_CASE_MOD_PLAY_VOIP));
- } else if(!strcmp(mHandle->useCase,SND_USE_CASE_VERB_HIFI2)) {
- strlcpy(mHandle->useCase, SND_USE_CASE_MOD_PLAY_MUSIC2,
- sizeof(SND_USE_CASE_MOD_PLAY_MUSIC2));
- } else if (!strcmp(mHandle->useCase,SND_USE_CASE_VERB_HIFI)){
- strlcpy(mHandle->useCase, SND_USE_CASE_MOD_PLAY_MUSIC,
- sizeof(SND_USE_CASE_MOD_PLAY_MUSIC));
- } else if(!strcmp(mHandle->useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_MUSIC)) {
- strlcpy(mHandle->useCase, SND_USE_CASE_MOD_PLAY_LOWLATENCY_MUSIC,
- sizeof(SND_USE_CASE_MOD_PLAY_LOWLATENCY_MUSIC));
- }
- }
- free(use_case);
- if((!strcmp(mHandle->useCase, SND_USE_CASE_VERB_IP_VOICECALL)) ||
- (!strcmp(mHandle->useCase, SND_USE_CASE_MOD_PLAY_VOIP))) {
-#ifdef QCOM_USBAUDIO_ENABLED
- if((mDevices & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)||
- (mDevices & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)||
- (mDevices & AudioSystem::DEVICE_OUT_PROXY)) {
- mDevices |= AudioSystem::DEVICE_OUT_PROXY;
- mHandle->module->route(mHandle, mDevices , mParent->mode());
- }else
-#endif
- {
- mHandle->module->route(mHandle, mDevices , AudioSystem::MODE_IN_COMMUNICATION);
- }
-#ifdef QCOM_USBAUDIO_ENABLED
- } else if((mDevices & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)||
- (mDevices & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)||
- (mDevices & AudioSystem::DEVICE_OUT_PROXY)) {
- mDevices |= AudioSystem::DEVICE_OUT_PROXY;
- mHandle->module->route(mHandle, mDevices , mParent->mode());
-#endif
- } else {
- mHandle->module->route(mHandle, mDevices , mParent->mode());
- }
- if (!strcmp(mHandle->useCase, SND_USE_CASE_VERB_HIFI) ||
- !strcmp(mHandle->useCase, SND_USE_CASE_VERB_HIFI2) ||
- !strcmp(mHandle->useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_MUSIC) ||
- !strcmp(mHandle->useCase, SND_USE_CASE_VERB_IP_VOICECALL)) {
- snd_use_case_set(mHandle->ucMgr, "_verb", mHandle->useCase);
- } else {
- snd_use_case_set(mHandle->ucMgr, "_enamod", mHandle->useCase);
- }
- if((!strcmp(mHandle->useCase, SND_USE_CASE_VERB_IP_VOICECALL)) ||
- (!strcmp(mHandle->useCase, SND_USE_CASE_MOD_PLAY_VOIP))) {
- err = mHandle->module->startVoipCall(mHandle);
- }
- else
- mHandle->module->open(mHandle);
- if(mHandle->handle == NULL) {
- ALOGE("write:: device open failed");
- mParent->mLock.unlock();
- return bytes;
- }
-#ifdef QCOM_USBAUDIO_ENABLED
- if((mHandle->devices == AudioSystem::DEVICE_IN_ANLG_DOCK_HEADSET)||
- (mHandle->devices == AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)){
- if((!strcmp(mHandle->useCase, SND_USE_CASE_VERB_IP_VOICECALL)) ||
- (!strcmp(mHandle->useCase, SND_USE_CASE_MOD_PLAY_VOIP))) {
- mParent->musbPlaybackState |= USBPLAYBACKBIT_VOIPCALL;
- } else {
- mParent->startUsbPlaybackIfNotStarted();
- mParent->musbPlaybackState |= USBPLAYBACKBIT_MUSIC;
- }
- }
-#endif
-
- mParent->mLock.unlock();
- }
-
-#ifdef QCOM_USBAUDIO_ENABLED
- if(((mDevices & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET) ||
- (mDevices & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)) &&
- (!mParent->musbPlaybackState)) {
- mParent->mLock.lock();
- mParent->startUsbPlaybackIfNotStarted();
- ALOGV("Starting playback on USB");
- if(!strcmp(mHandle->useCase, SND_USE_CASE_VERB_IP_VOICECALL) ||
- !strcmp(mHandle->useCase, SND_USE_CASE_MOD_PLAY_VOIP)) {
- ALOGD("Setting VOIPCALL bit here, musbPlaybackState %d", mParent->musbPlaybackState);
- mParent->musbPlaybackState |= USBPLAYBACKBIT_VOIPCALL;
- }else{
- ALOGV("enabling music, musbPlaybackState: %d ", mParent->musbPlaybackState);
- mParent->musbPlaybackState |= USBPLAYBACKBIT_MUSIC;
- }
- mParent->mLock.unlock();
- }
-#endif
-
- period_size = mHandle->periodSize;
- do {
- if (write_pending < period_size) {
- write_pending = period_size;
- }
- if((mParent->mVoipStreamCount) && (mHandle->rxHandle != 0)) {
- n = pcm_write(mHandle->rxHandle,
- (char *)buffer + sent,
- period_size);
- } else if (mHandle->handle != 0){
- n = pcm_write(mHandle->handle,
- (char *)buffer + sent,
- period_size);
- }
- if (n < 0) {
- mParent->mLock.lock();
- if (mHandle->handle != NULL) {
- ALOGE("pcm_write returned error %d, trying to recover\n", n);
- pcm_close(mHandle->handle);
- mHandle->handle = NULL;
- if((!strncmp(mHandle->useCase, SND_USE_CASE_VERB_IP_VOICECALL, strlen(SND_USE_CASE_VERB_IP_VOICECALL))) ||
- (!strncmp(mHandle->useCase, SND_USE_CASE_MOD_PLAY_VOIP, strlen(SND_USE_CASE_MOD_PLAY_VOIP)))) {
- pcm_close(mHandle->rxHandle);
- mHandle->rxHandle = NULL;
- mHandle->module->startVoipCall(mHandle);
- }
- else
- mHandle->module->open(mHandle);
- if(mHandle->handle == NULL) {
- ALOGE("write:: device re-open failed");
- mParent->mLock.unlock();
- return bytes;
- }
- }
- mParent->mLock.unlock();
- continue;
- }
- else {
- mFrameCount += n;
- sent += static_cast<ssize_t>((period_size));
- write_pending -= period_size;
- }
-
- } while ((mHandle->handle||(mHandle->rxHandle && mParent->mVoipStreamCount)) && sent < bytes);
-
- return sent;
-}
-
-status_t AudioStreamOutALSA::dump(int fd, const Vector<String16>& args)
-{
- return NO_ERROR;
-}
-
-status_t AudioStreamOutALSA::open(int mode)
-{
- Mutex::Autolock autoLock(mParent->mLock);
-
- return ALSAStreamOps::open(mode);
-}
-
-status_t AudioStreamOutALSA::close()
-{
- Mutex::Autolock autoLock(mParent->mLock);
-
- ALOGV("close");
- if((!strcmp(mHandle->useCase, SND_USE_CASE_VERB_IP_VOICECALL)) ||
- (!strcmp(mHandle->useCase, SND_USE_CASE_MOD_PLAY_VOIP))) {
- if((mParent->mVoipStreamCount)) {
-#ifdef QCOM_USBAUDIO_ENABLED
- if(mParent->mVoipStreamCount == 1) {
- ALOGV("Deregistering VOIP Call bit, musbPlaybackState:%d, musbRecordingState: %d",
- mParent->musbPlaybackState, mParent->musbRecordingState);
- mParent->musbPlaybackState &= ~USBPLAYBACKBIT_VOIPCALL;
- mParent->musbRecordingState &= ~USBRECBIT_VOIPCALL;
- mParent->closeUsbPlaybackIfNothingActive();
- mParent->closeUsbRecordingIfNothingActive();
- }
-#endif
- return NO_ERROR;
- }
- mParent->mVoipStreamCount = 0;
- }
-#ifdef QCOM_USBAUDIO_ENABLED
- else if((!strcmp(mHandle->useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER)) ||
- (!strcmp(mHandle->useCase, SND_USE_CASE_MOD_PLAY_LPA))) {
- mParent->musbPlaybackState &= ~USBPLAYBACKBIT_LPA;
- } else {
- mParent->musbPlaybackState &= ~USBPLAYBACKBIT_MUSIC;
- }
-
- mParent->closeUsbPlaybackIfNothingActive();
-#endif
-
- ALSAStreamOps::close();
-
- return NO_ERROR;
-}
-
-status_t AudioStreamOutALSA::standby()
-{
- Mutex::Autolock autoLock(mParent->mLock);
-
- ALOGV("standby");
-
- if((!strcmp(mHandle->useCase, SND_USE_CASE_VERB_IP_VOICECALL)) ||
- (!strcmp(mHandle->useCase, SND_USE_CASE_MOD_PLAY_VOIP))) {
- return NO_ERROR;
- }
-
-#ifdef QCOM_USBAUDIO_ENABLED
- if((!strcmp(mHandle->useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER)) ||
- (!strcmp(mHandle->useCase, SND_USE_CASE_MOD_PLAY_LPA))) {
- ALOGV("Deregistering LPA bit");
- mParent->musbPlaybackState &= ~USBPLAYBACKBIT_LPA;
- } else {
- ALOGV("Deregistering MUSIC bit, musbPlaybackState: %d", mParent->musbPlaybackState);
- mParent->musbPlaybackState &= ~USBPLAYBACKBIT_MUSIC;
- }
-#endif
-
- mHandle->module->standby(mHandle);
-
-#ifdef QCOM_USBAUDIO_ENABLED
- mParent->closeUsbPlaybackIfNothingActive();
-#endif
-
- mFrameCount = 0;
-
- return NO_ERROR;
-}
-
-#define USEC_TO_MSEC(x) ((x + 999) / 1000)
-
-uint32_t AudioStreamOutALSA::latency() const
-{
- // Android wants latency in milliseconds.
- return USEC_TO_MSEC (mHandle->latency);
-}
-
-// return the number of audio frames written by the audio dsp to DAC since
-// the output has exited standby
-status_t AudioStreamOutALSA::getRenderPosition(uint32_t *dspFrames)
-{
- *dspFrames = mFrameCount;
- return NO_ERROR;
-}
-
-} // namespace android_audio_legacy
diff --git a/legacy/alsa_sound/AudioUsbALSA.cpp b/legacy/alsa_sound/AudioUsbALSA.cpp
deleted file mode 100644
index 93e0754..0000000
--- a/legacy/alsa_sound/AudioUsbALSA.cpp
+++ /dev/null
@@ -1,1063 +0,0 @@
-/* AudioUsbALSA.cpp
-Copyright (c) 2012, The Linux Foundation. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following
- disclaimer in the documentation and/or other materials provided
- with the distribution.
- * Neither the name of The Linux Foundation nor the names of its
- contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.*/
-
-#define LOG_TAG "AudioUsbALSA"
-#define LOG_NDEBUG 0
-#define LOG_NDDEBUG 0
-#include <utils/Log.h>
-#include <utils/String8.h>
-
-#include <cutils/properties.h>
-#include <media/AudioRecord.h>
-#include <hardware_legacy/power.h>
-#include <sys/poll.h>
-#include <sys/ioctl.h>
-#include <fcntl.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <errno.h>
-#include <jni.h>
-#include <stdio.h>
-#include <sys/eventfd.h>
-
-
-#include "AudioUsbALSA.h"
-struct pollfd pfdProxyPlayback[2];
-struct pollfd pfdUsbPlayback[2];
-struct pollfd pfdProxyRecording[1];
-struct pollfd pfdUsbRecording[1];
-
-#define USB_PERIOD_SIZE 2048
-#define PROXY_PERIOD_SIZE 3072
-
-namespace android_audio_legacy
-{
-AudioUsbALSA::AudioUsbALSA()
-{
- mproxypfdPlayback = -1;
- musbpfdPlayback = -1;
- mkillPlayBackThread = false;
- mkillRecordingThread = false;
-}
-
-AudioUsbALSA::~AudioUsbALSA()
-{
- mkillPlayBackThread = true;
- mkillRecordingThread = true;
-}
-
-
-int AudioUsbALSA::getnumOfRates(char *ratesStr){
- int i, size = 0;
- char *nextSRString, *temp_ptr;
- nextSRString = strtok_r(ratesStr, " ,", &temp_ptr);
- if (nextSRString == NULL) {
- ALOGE("ERROR: getnumOfRates: could not find rates string");
- return NULL;
- }
- for (i = 1; nextSRString != NULL; i++) {
- size ++;
- nextSRString = strtok_r(NULL, " ,.-", &temp_ptr);
- }
- return size;
-}
-
-
-status_t AudioUsbALSA::getCap(char * type, int &channels, int &sampleRate)
-{
- ALOGD("getCap for %s",type);
- long unsigned fileSize;
- FILE *fp;
- char *buffer;
- int err = 1;
- int size = 0;
- int fd, i, lchannelsPlayback;
- char *read_buf, *str_start, *channel_start, *ratesStr, *ratesStrForVal,
- *ratesStrStart, *chString, *nextSRStr, *test, *nextSRString, *temp_ptr;
- struct stat st;
- memset(&st, 0x0, sizeof(struct stat));
- sampleRate = 0;
- fd = open(PATH, O_RDONLY);
- if (fd <0) {
- ALOGE("ERROR: failed to open config file %s error: %d\n", PATH, errno);
- close(fd);
- return UNKNOWN_ERROR;
- }
-
- if (fstat(fd, &st) < 0) {
- ALOGE("ERROR: failed to stat %s error %d\n", PATH, errno);
- close(fd);
- return UNKNOWN_ERROR;
- }
-
- fileSize = st.st_size;
-
- read_buf = (char *)malloc(BUFFSIZE);
- memset(read_buf, 0x0, BUFFSIZE);
- err = read(fd, read_buf, BUFFSIZE);
- str_start = strstr(read_buf, type);
- if (str_start == NULL) {
- ALOGE("ERROR:%s section not found in usb config file", type);
- close(fd);
- free(read_buf);
- return UNKNOWN_ERROR;
- }
-
- channel_start = strstr(str_start, "Channels:");
- if (channel_start == NULL) {
- ALOGE("ERROR: Could not find Channels information");
- close(fd);
- free(read_buf);
- return UNKNOWN_ERROR;
- }
- channel_start = strstr(channel_start, " ");
- if (channel_start == NULL) {
- ALOGE("ERROR: Channel section not found in usb config file");
- close(fd);
- free(read_buf);
- return UNKNOWN_ERROR;
- }
-
- lchannelsPlayback = atoi(channel_start);
- if (lchannelsPlayback == 1) {
- channels = 1;
- } else {
- channels = 2;
- }
- ALOGD("channels supported by device: %d", lchannelsPlayback);
- ratesStrStart = strstr(str_start, "Rates:");
- if (ratesStrStart == NULL) {
- ALOGE("ERROR: Cant find rates information");
- close(fd);
- free(read_buf);
- return UNKNOWN_ERROR;
- }
-
- ratesStrStart = strstr(ratesStrStart, " ");
- if (ratesStrStart == NULL) {
- ALOGE("ERROR: Channel section not found in usb config file");
- close(fd);
- free(read_buf);
- return UNKNOWN_ERROR;
- }
-
- //copy to ratesStr, current line.
- char *target = strchr(ratesStrStart, '\n');
- if (target == NULL) {
- ALOGE("ERROR: end of line not found");
- close(fd);
- free(read_buf);
- return UNKNOWN_ERROR;
- }
- size = target - ratesStrStart;
- ratesStr = (char *)malloc(size + 1) ;
- ratesStrForVal = (char *)malloc(size + 1) ;
- memcpy(ratesStr, ratesStrStart, size);
- memcpy(ratesStrForVal, ratesStrStart, size);
- ratesStr[size] = '\0';
- ratesStrForVal[size] = '\0';
-
- size = getnumOfRates(ratesStr);
- if (!size) {
- ALOGE("ERROR: Could not get rate size, returning");
- close(fd);
- free(ratesStrForVal);
- free(ratesStr);
- free(read_buf);
- return UNKNOWN_ERROR;
- }
-
- //populate playback rates array
- int ratesSupported[size];
- nextSRString = strtok_r(ratesStrForVal, " ,", &temp_ptr);
- if (nextSRString == NULL) {
- ALOGE("ERROR: Could not get first rate val");
- close(fd);
- free(ratesStrForVal);
- free(ratesStr);
- free(read_buf);
- return UNKNOWN_ERROR;
- }
-
- ratesSupported[0] = atoi(nextSRString);
- for (i = 1; i<size; i++) {
- nextSRString = strtok_r(NULL, " ,.-", &temp_ptr);
- ratesSupported[i] = atoi(nextSRString);
- ALOGV("ratesSupported[%d] for playback: %d",i, ratesSupported[i]);
- }
-
- for (i = 0; i<=size; i++) {
- if (ratesSupported[i] <= 48000) {
- sampleRate = ratesSupported[i];
- break;
- }
- }
- ALOGD("sampleRate: %d", sampleRate);
-
- close(fd);
- free(ratesStrForVal);
- free(ratesStr);
- free(read_buf);
- ratesStrForVal = NULL;
- ratesStr = NULL;
- read_buf = NULL;
- return NO_ERROR;
-}
-
-void AudioUsbALSA::exitPlaybackThread(uint64_t writeVal)
-{
- ALOGD("exitPlaybackThread, mproxypfdPlayback: %d", mproxypfdPlayback);
- if (writeVal == SIGNAL_EVENT_KILLTHREAD) {
- int err;
-
- err = closeDevice(mproxyPlaybackHandle);
- if (err) {
- ALOGE("Info: Could not close proxy %p", mproxyPlaybackHandle);
- }
- err = closeDevice(musbPlaybackHandle);
- if (err) {
- ALOGE("Info: Could not close USB device %p", musbPlaybackHandle);
- }
- }
- if ((mproxypfdPlayback != -1) && (musbpfdPlayback != -1)) {
- write(mproxypfdPlayback, &writeVal, sizeof(uint64_t));
- write(musbpfdPlayback, &writeVal, sizeof(uint64_t));
- mkillPlayBackThread = true;
- pthread_join(mPlaybackUsb,NULL);
- }
-}
-
-void AudioUsbALSA::exitRecordingThread(uint64_t writeVal)
-{
- ALOGD("exitRecordingThread");
- if (writeVal == SIGNAL_EVENT_KILLTHREAD) {
- int err;
-
- err = closeDevice(mproxyRecordingHandle);
- if (err) {
- ALOGE("Info: Could not close proxy for recording %p", mproxyRecordingHandle);
- }
- err = closeDevice(musbRecordingHandle);
- if (err) {
- ALOGE("Info: Could not close USB recording device %p", musbRecordingHandle);
- }
- }
- mkillRecordingThread = true;
-}
-
-void AudioUsbALSA::setkillUsbRecordingThread(bool val){
- ALOGD("setkillUsbRecordingThread");
- mkillRecordingThread = val;
-}
-
-status_t AudioUsbALSA::setHardwareParams(pcm *txHandle, uint32_t sampleRate, uint32_t channels, int periodBytes)
-{
- ALOGD("setHardwareParams");
- struct snd_pcm_hw_params *params;
- unsigned long bufferSize, reqBuffSize;
- unsigned int periodTime, bufferTime;
- unsigned int requestedRate = sampleRate;
- int status = 0;
-
- params = (snd_pcm_hw_params*) calloc(1, sizeof(struct snd_pcm_hw_params));
- if (!params) {
- return NO_INIT;
- }
-
- param_init(params);
- param_set_mask(params, SNDRV_PCM_HW_PARAM_ACCESS,
- SNDRV_PCM_ACCESS_MMAP_INTERLEAVED);
- param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
- SNDRV_PCM_FORMAT_S16_LE);
- param_set_mask(params, SNDRV_PCM_HW_PARAM_SUBFORMAT,
- SNDRV_PCM_SUBFORMAT_STD);
- ALOGV("Setting period size:%d samplerate:%d, channels: %d",periodBytes,sampleRate, channels);
- param_set_min(params, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, periodBytes);
- param_set_int(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS, 16);
- param_set_int(params, SNDRV_PCM_HW_PARAM_FRAME_BITS,
- channels - 1 ? 32 : 16);
- param_set_int(params, SNDRV_PCM_HW_PARAM_CHANNELS,
- channels);
- param_set_int(params, SNDRV_PCM_HW_PARAM_RATE, sampleRate);
- param_set_hw_refine(txHandle, params);
-
- if (param_set_hw_params(txHandle, params)) {
- ALOGE("ERROR: cannot set hw params");
- return NO_INIT;
- }
-
- param_dump(params);
-
- txHandle->period_size = pcm_period_size(params);
- txHandle->buffer_size = pcm_buffer_size(params);
- txHandle->period_cnt = txHandle->buffer_size/txHandle->period_size;
-
- ALOGD("setHardwareParams: buffer_size %d, period_size %d, period_cnt %d",
- txHandle->buffer_size, txHandle->period_size,
- txHandle->period_cnt);
-
- return NO_ERROR;
-}
-
-status_t AudioUsbALSA::setSoftwareParams(pcm *pcm, bool playback)
-{
- ALOGD("setSoftwareParams");
- struct snd_pcm_sw_params* params;
-
- params = (snd_pcm_sw_params*) calloc(1, sizeof(struct snd_pcm_sw_params));
- if (!params) {
- LOG_ALWAYS_FATAL("Failed to allocate ALSA software parameters!");
- return NO_INIT;
- }
-
- params->tstamp_mode = SNDRV_PCM_TSTAMP_NONE;
- params->period_step = 1;
-
- params->avail_min = (pcm->flags & PCM_MONO) ? pcm->period_size/2 : pcm->period_size/4;
-
- if (playback) {
- params->start_threshold = (pcm->flags & PCM_MONO) ? pcm->period_size*8 : pcm->period_size*4;
- params->xfer_align = (pcm->flags & PCM_MONO) ? pcm->period_size*8 : pcm->period_size*4;
- } else {
- params->start_threshold = (pcm->flags & PCM_MONO) ? pcm->period_size/2 : pcm->period_size/4;
- params->xfer_align = (pcm->flags & PCM_MONO) ? pcm->period_size/2 : pcm->period_size/4;
- }
- params->stop_threshold = pcm->buffer_size;
-
- params->xfer_align = (pcm->flags & PCM_MONO) ? pcm->period_size/2 : pcm->period_size/4;
- params->silence_size = 0;
- params->silence_threshold = 0;
-
- if (param_set_sw_params(pcm, params)) {
- ALOGE("ERROR: cannot set sw params");
- return NO_INIT;
- }
-
- return NO_ERROR;
-}
-
-status_t AudioUsbALSA::closeDevice(pcm *handle)
-{
- ALOGD("closeDevice handle %p", handle);
- status_t err = NO_ERROR;
- if (handle) {
- err = pcm_close(handle);
- if (err != NO_ERROR) {
- ALOGE("INFO: closeDevice: pcm_close failed with err %d", err);
- }
- }
- handle = NULL;
- return err;
-}
-
-void AudioUsbALSA::RecordingThreadEntry() {
- ALOGD("Inside RecordingThreadEntry");
- int nfds = 1;
- mtimeOutRecording = TIMEOUT_INFINITE;
- int fd;
- long frames;
- static int start = 0;
- struct snd_xferi x;
- int filed;
- unsigned avail, bufsize;
- int bytes_written;
- uint32_t sampleRate;
- uint32_t channels;
- u_int8_t *srcUsb_addr = NULL;
- u_int8_t *dstProxy_addr = NULL;
- int err;
- const char *fn = "/data/RecordPcm.pcm";
- filed = open(fn, O_WRONLY | O_CREAT | O_TRUNC | O_APPEND, 0664);
-
- err = getCap((char *)"Capture:", mchannelsCapture, msampleRateCapture);
- if (err) {
- ALOGE("ERROR: Could not get capture capabilities from usb device");
- return;
- }
- int channelFlag = PCM_MONO;
- if (mchannelsCapture >= 2) {
- channelFlag = PCM_STEREO;
- }
-
- musbRecordingHandle = configureDevice(PCM_IN|channelFlag|PCM_MMAP, (char *)"hw:1,0",
- msampleRateCapture, mchannelsCapture,768,false);
- if (!musbRecordingHandle) {
- ALOGE("ERROR: Could not configure USB device for recording");
- return;
- } else {
- ALOGD("USB device Configured for recording");
- }
-
- pfdUsbRecording[0].fd = musbRecordingHandle->fd; //DEBUG
- pfdUsbRecording[0].events = POLLIN;
-
- mproxyRecordingHandle = configureDevice(PCM_OUT|channelFlag|PCM_MMAP, (char *)"hw:0,7",
- msampleRateCapture, mchannelsCapture,768,false);
- if (!mproxyRecordingHandle) {
- ALOGE("ERROR: Could not configure Proxy for recording");
- closeDevice(musbRecordingHandle);
- return;
- } else {
- ALOGD("Proxy Configured for recording");
- }
-
- bufsize = musbRecordingHandle->period_size;
- pfdProxyRecording[0].fd = mproxyRecordingHandle->fd;
- pfdProxyRecording[0].events = POLLOUT;
- frames = (musbRecordingHandle->flags & PCM_MONO) ? (bufsize / 2) : (bufsize / 4);
- x.frames = (musbRecordingHandle->flags & PCM_MONO) ? (bufsize / 2) : (bufsize / 4);
-
- /***********************keep reading from usb and writing to proxy******************************************/
- while (mkillRecordingThread != true) {
- if (!musbRecordingHandle->running) {
- if (pcm_prepare(musbRecordingHandle)) {
- ALOGE("ERROR: pcm_prepare failed for usb device for recording");
- mkillRecordingThread = true;
- break;;
- }
- }
- if (!mproxyRecordingHandle->running) {
- if (pcm_prepare(mproxyRecordingHandle)) {
- ALOGE("ERROR: pcm_prepare failed for proxy device for recording");
- mkillRecordingThread = true;
- break;;
- }
- }
-
- /********** USB syncing before write **************/
- if (!musbRecordingHandle->start && !mkillRecordingThread) {
- err = startDevice(musbRecordingHandle, &mkillRecordingThread);
- if (err == EPIPE) {
- continue;
- } else if (err != NO_ERROR) {
- mkillRecordingThread = true;
- break;
- }
- }
- for (;;) {
- if (!musbRecordingHandle->running) {
- if (pcm_prepare(musbRecordingHandle)) {
- ALOGE("ERROR: pcm_prepare failed for proxy device for recording");
- mkillRecordingThread = true;
- break;
- }
- }
- /* Sync the current Application pointer from the kernel */
- musbRecordingHandle->sync_ptr->flags = SNDRV_PCM_SYNC_PTR_APPL |
- SNDRV_PCM_SYNC_PTR_AVAIL_MIN;
-
- err = syncPtr(musbRecordingHandle, &mkillRecordingThread);
- if (err == EPIPE) {
- continue;
- } else if (err != NO_ERROR) {
- break;
- }
-
- avail = pcm_avail(musbRecordingHandle);
- if (avail < musbRecordingHandle->sw_p->avail_min) {
- poll(pfdUsbRecording, nfds, TIMEOUT_INFINITE);
- continue;
- } else {
- break;
- }
- }
- if (mkillRecordingThread) {
- break;
- }
- if (x.frames > avail)
- frames = avail;
-
- srcUsb_addr = dst_address(musbRecordingHandle);
- /**********End USB syncing before write**************/
-
- /*************Proxy syncing before write ******************/
-
- for (;;) {
- if (!mproxyRecordingHandle->running) {
- if (pcm_prepare(mproxyRecordingHandle)) {
- ALOGE("ERROR: pcm_prepare failed for proxy device for recording");
- mkillRecordingThread = true;
- break;
- }
- }
- mproxyRecordingHandle->sync_ptr->flags = SNDRV_PCM_SYNC_PTR_APPL |
- SNDRV_PCM_SYNC_PTR_AVAIL_MIN;
-
- err = syncPtr(mproxyRecordingHandle, &mkillRecordingThread);
- if (err == EPIPE) {
- continue;
- } else if (err != NO_ERROR) {
- break;
- }
- avail = pcm_avail(mproxyRecordingHandle);
- if (avail < mproxyRecordingHandle->sw_p->avail_min) {
- poll(pfdProxyRecording, nfds, TIMEOUT_INFINITE);
- continue;
- } else {
- break;
- }
- }
- if (mkillRecordingThread) {
- break;
- }
-
- dstProxy_addr = dst_address(mproxyRecordingHandle);
- memset(dstProxy_addr, 0x0, bufsize);
-
- /**************End Proxy syncing before write *************/
-
- memcpy(dstProxy_addr, srcUsb_addr, bufsize );
-
- /************* sync up after write -- USB *********************/
- musbRecordingHandle->sync_ptr->c.control.appl_ptr += frames;
- musbRecordingHandle->sync_ptr->flags = 0;
- err = syncPtr(musbRecordingHandle, &mkillRecordingThread);
- if (err == EPIPE) {
- continue;
- } else if (err != NO_ERROR) {
- break;
- }
-
- /************* end sync up after write -- USB *********************/
-
- /**************** sync up after write -- Proxy ************************/
- mproxyRecordingHandle->sync_ptr->c.control.appl_ptr += frames;
- mproxyRecordingHandle->sync_ptr->flags = 0;
-
- err = syncPtr(mproxyRecordingHandle, &mkillRecordingThread);
- if (err == EPIPE) {
- continue;
- } else if (err != NO_ERROR) {
- break;
- }
-
- bytes_written = mproxyRecordingHandle->sync_ptr->c.control.appl_ptr - mproxyRecordingHandle->sync_ptr->s.status.hw_ptr;
- if ((bytes_written >= mproxyRecordingHandle->sw_p->start_threshold) && (!mproxyRecordingHandle->start)) {
- if (!mkillPlayBackThread) {
- err = startDevice(mproxyRecordingHandle, &mkillRecordingThread);
- if (err == EPIPE) {
- continue;
- } else if (err != NO_ERROR) {
- mkillRecordingThread = true;
- break;
- }
- }
- }
- }
- /*************** End sync up after write -- Proxy *********************/
- if (mkillRecordingThread) {
- closeDevice(mproxyRecordingHandle);
- closeDevice(musbRecordingHandle);
- }
- ALOGD("Exiting USB Recording thread");
-}
-
-void *AudioUsbALSA::PlaybackThreadWrapper(void *me) {
- static_cast<AudioUsbALSA *>(me)->PlaybackThreadEntry();
- return NULL;
-}
-
-void *AudioUsbALSA::RecordingThreadWrapper(void *me) {
- static_cast<AudioUsbALSA *>(me)->RecordingThreadEntry();
- return NULL;
-}
-
-struct pcm * AudioUsbALSA::configureDevice(unsigned flags, char* hw, int sampleRate, int channelCount, int periodSize, bool playback){
- int err = NO_ERROR;
- struct pcm * handle = NULL;
- handle = pcm_open(flags, hw);
- if (!handle || handle->fd < 0) {
- ALOGE("ERROR: pcm_open failed");
- return NULL;
- }
-
- if (!pcm_ready(handle)) {
- ALOGE("ERROR: pcm_ready failed");
- closeDevice(handle);
- return NULL;
- }
-
- ALOGD("Setting hardware params: sampleRate:%d, channels: %d",sampleRate, channelCount);
- err = setHardwareParams(handle, sampleRate, channelCount,periodSize);
- if (err != NO_ERROR) {
- ALOGE("ERROR: setHardwareParams failed");
- closeDevice(handle);
- return NULL;
- }
-
- err = setSoftwareParams(handle, playback);
- if (err != NO_ERROR) {
- ALOGE("ERROR: setSoftwareParams failed");
- closeDevice(handle);
- return NULL;
- }
-
- err = mmap_buffer(handle);
- if (err) {
- ALOGE("ERROR: mmap_buffer failed");
- closeDevice(handle);
- return NULL;
- }
-
- err = pcm_prepare(handle);
- if (err) {
- ALOGE("ERROR: pcm_prepare failed");
- closeDevice(handle);
- return NULL;
- }
-
- return handle;
-}
-
-status_t AudioUsbALSA::startDevice(pcm *handle, bool *killThread) {
- int err = NO_ERROR;;
- if (ioctl(handle->fd, SNDRV_PCM_IOCTL_START)) {
- err = -errno;
- if (errno == EPIPE) {
- ALOGE("ERROR: SNDRV_PCM_IOCTL_START returned EPIPE for usb recording case");
- handle->underruns++;
- handle->running = 0;
- handle->start = 0;
- return errno;
- } else {
- ALOGE("ERROR: SNDRV_PCM_IOCTL_START failed for usb recording case errno:%d", errno);
- *killThread = true;
- return errno;
- }
- }
- handle->start = 1;
- if (handle == musbRecordingHandle) {
- ALOGD("Usb Driver started for recording");
- } else if (handle == mproxyRecordingHandle) {
- ALOGD("Proxy Driver started for recording");
- } else if (handle == musbPlaybackHandle) {
- ALOGD("Usb Driver started for playback");
- } else if (handle == mproxyPlaybackHandle) {
- ALOGD("proxy Driver started for playback");
- }
- return NO_ERROR;
-}
-
-status_t AudioUsbALSA::syncPtr(struct pcm *handle, bool *killThread) {
- int err;
- err = sync_ptr(handle);
- if (err == EPIPE) {
- ALOGE("ERROR: Failed in sync_ptr \n");
- handle->running = 0;
- handle->underruns++;
- handle->start = 0;
- } else if (err == ENODEV) {
- ALOGE("Info: Device not available");
- } else if (err != NO_ERROR) {
- ALOGE("ERROR: Sync ptr returned %d", err);
- *killThread = true;
- }
- return err;
-}
-
-void AudioUsbALSA::pollForProxyData(){
- int err_poll = poll(pfdProxyPlayback, mnfdsPlayback, mtimeOut);
- if (err_poll == 0 ) {
- ALOGD("POLL timedout");
- mkillPlayBackThread = true;
- pfdProxyPlayback[0].revents = 0;
- pfdProxyPlayback[1].revents = 0;
- return;
- }
-
- if (pfdProxyPlayback[1].revents & POLLIN) {
- ALOGD("Signalled from HAL about timeout");
- uint64_t u;
- read(mproxypfdPlayback, &u, sizeof(uint64_t));
- pfdProxyPlayback[1].revents = 0;
- if (u == SIGNAL_EVENT_KILLTHREAD) {
- ALOGD("kill thread event");
- mkillPlayBackThread = true;
- pfdProxyPlayback[0].revents = 0;
- pfdProxyPlayback[1].revents = 0;
- return;
- } else if (u == SIGNAL_EVENT_TIMEOUT) {
- ALOGD("Setting timeout for 3 sec");
- mtimeOut = POLL_TIMEOUT;
- }
- } else if (pfdProxyPlayback[1].revents & POLLERR || pfdProxyPlayback[1].revents & POLLHUP ||
- pfdProxyPlayback[1].revents & POLLNVAL) {
- ALOGE("Info: proxy throwing error from location 1");
- mkillPlayBackThread = true;
- pfdProxyPlayback[0].revents = 0;
- pfdProxyPlayback[1].revents = 0;
- return;
- }
-
- if (pfdProxyPlayback[0].revents & POLLERR || pfdProxyPlayback[0].revents & POLLHUP ||
- pfdProxyPlayback[0].revents & POLLNVAL) {
- ALOGE("Info: proxy throwing error");
- mkillPlayBackThread = true;
- pfdProxyPlayback[0].revents = 0;
- pfdProxyPlayback[1].revents = 0;
- }
-}
-
-void AudioUsbALSA::pollForUsbData(){
- int err_poll = poll(pfdUsbPlayback, mnfdsPlayback, mtimeOut);
- if (err_poll == 0 ) {
- ALOGD("POLL timedout");
- mkillPlayBackThread = true;
- pfdUsbPlayback[0].revents = 0;
- pfdUsbPlayback[1].revents = 0;
- return;
- }
-
- if (pfdUsbPlayback[1].revents & POLLIN) {
- ALOGD("Info: Signalled from HAL about an event");
- uint64_t u;
- read(musbpfdPlayback, &u, sizeof(uint64_t));
- pfdUsbPlayback[0].revents = 0;
- pfdUsbPlayback[1].revents = 0;
- if (u == SIGNAL_EVENT_KILLTHREAD) {
- ALOGD("kill thread");
- mkillPlayBackThread = true;
- return;
- } else if (u == SIGNAL_EVENT_TIMEOUT) {
- ALOGD("Setting timeout for 3 sec");
- mtimeOut = POLL_TIMEOUT;
- }
- } else if (pfdUsbPlayback[1].revents & POLLERR || pfdUsbPlayback[1].revents & POLLHUP ||
- pfdUsbPlayback[1].revents & POLLNVAL) {
- ALOGE("Info: usb throwing error from location 1");
- mkillPlayBackThread = true;
- pfdUsbPlayback[0].revents = 0;
- pfdUsbPlayback[1].revents = 0;
- return;
- }
-
- if (pfdUsbPlayback[0].revents & POLLERR || pfdProxyPlayback[0].revents & POLLHUP ||
- pfdUsbPlayback[0].revents & POLLNVAL) {
- ALOGE("Info: usb throwing error");
- mkillPlayBackThread = true;
- pfdUsbPlayback[0].revents = 0;
- return;
- }
-}
-
-void AudioUsbALSA::PlaybackThreadEntry() {
- ALOGD("PlaybackThreadEntry");
- mnfdsPlayback = 2;
- mtimeOut = TIMEOUT_INFINITE;
- long frames;
- static int fd;
- struct snd_xferi x;
- int bytes_written;
- unsigned avail, xfer, bufsize;
- unsigned proxyPeriod, usbPeriod;
- uint32_t sampleRate;
- uint32_t channels;
- unsigned int tmp;
- int numOfBytesWritten;
- int err;
- int filed;
- const char *fn = "/data/test.pcm";
- mdstUsb_addr = NULL;
- msrcProxy_addr = NULL;
-
- int proxySizeRemaining = 0;
- int usbSizeFilled = 0;
-
- pid_t tid = gettid();
- androidSetThreadPriority(tid, ANDROID_PRIORITY_URGENT_AUDIO);
-
- err = getCap((char *)"Playback:", mchannelsPlayback, msampleRatePlayback);
- if (err) {
- ALOGE("ERROR: Could not get playback capabilities from usb device");
- return;
- }
-
- musbPlaybackHandle = configureDevice(PCM_OUT|PCM_STEREO|PCM_MMAP, (char *)"hw:1,0",
- msampleRatePlayback, mchannelsPlayback, USB_PERIOD_SIZE, true);
- if (!musbPlaybackHandle) {
- ALOGE("ERROR: configureUsbDevice failed, returning");
- closeDevice(musbPlaybackHandle);
- return;
- } else {
- ALOGD("USB Configured for playback");
- }
-
- if (!mkillPlayBackThread) {
- pfdUsbPlayback[0].fd = musbPlaybackHandle->timer_fd;
- pfdUsbPlayback[0].events = POLLIN;
- musbpfdPlayback = eventfd(0,0);
- pfdUsbPlayback[1].fd = musbpfdPlayback;
- pfdUsbPlayback[1].events = (POLLIN | POLLOUT | POLLERR | POLLNVAL | POLLHUP);
- }
-
- mproxyPlaybackHandle = configureDevice(PCM_IN|PCM_STEREO|PCM_MMAP, (char *)"hw:0,8",
- msampleRatePlayback, mchannelsPlayback, PROXY_PERIOD_SIZE, false);
- if (!mproxyPlaybackHandle) {
- ALOGE("ERROR: Could not configure Proxy, returning");
- closeDevice(musbPlaybackHandle);
- return;
- } else {
- ALOGD("Proxy Configured for playback");
- }
-
- proxyPeriod = mproxyPlaybackHandle->period_size;
- usbPeriod = musbPlaybackHandle->period_size;
-
- if (!mkillPlayBackThread) {
- pfdProxyPlayback[0].fd = mproxyPlaybackHandle->fd;
- pfdProxyPlayback[0].events = (POLLIN); // | POLLERR | POLLNVAL);
- mproxypfdPlayback = eventfd(0,0);
- pfdProxyPlayback[1].fd = mproxypfdPlayback;
- pfdProxyPlayback[1].events = (POLLIN | POLLOUT| POLLERR | POLLNVAL);
- }
-
- frames = (mproxyPlaybackHandle->flags & PCM_MONO) ? (proxyPeriod / 2) : (proxyPeriod / 4);
- x.frames = (mproxyPlaybackHandle->flags & PCM_MONO) ? (proxyPeriod / 2) : (proxyPeriod / 4);
- int usbframes = (musbPlaybackHandle->flags & PCM_MONO) ? (usbPeriod / 2) : (usbPeriod / 4);
-
- u_int8_t *proxybuf = ( u_int8_t *) malloc(PROXY_PERIOD_SIZE);
- u_int8_t *usbbuf = ( u_int8_t *) malloc(USB_PERIOD_SIZE);
- memset(proxybuf, 0x0, PROXY_PERIOD_SIZE);
- memset(usbbuf, 0x0, USB_PERIOD_SIZE);
-
-
- /***********************keep reading from proxy and writing to USB******************************************/
- while (mkillPlayBackThread != true) {
- if (!mproxyPlaybackHandle->running) {
- if (pcm_prepare(mproxyPlaybackHandle)) {
- ALOGE("ERROR: pcm_prepare failed for proxy");
- mkillPlayBackThread = true;
- break;
- }
- }
- if (!musbPlaybackHandle->running) {
- if (pcm_prepare(musbPlaybackHandle)) {
- ALOGE("ERROR: pcm_prepare failed for usb");
- mkillPlayBackThread = true;
- break;
- }
- }
-
- /********** Proxy syncing before write **************/
- if (!mkillPlayBackThread && (!mproxyPlaybackHandle->start)) {
- err = startDevice(mproxyPlaybackHandle, &mkillPlayBackThread);
- if (err == EPIPE) {
- continue;
- } else if (err != NO_ERROR) {
- mkillPlayBackThread = true;
- break;
- }
- }
- if (proxySizeRemaining == 0) {
- for (;;) {
- if (!mproxyPlaybackHandle->running) {
- if (pcm_prepare(mproxyPlaybackHandle)) {
- ALOGE("ERROR: pcm_prepare failed for proxy");
- mkillPlayBackThread = true;
- break;
- }
- }
- /* Sync the current Application pointer from the kernel */
- mproxyPlaybackHandle->sync_ptr->flags = SNDRV_PCM_SYNC_PTR_APPL |
- SNDRV_PCM_SYNC_PTR_AVAIL_MIN;
-
- if (mtimeOut == TIMEOUT_INFINITE && !mkillPlayBackThread) {
- err = syncPtr(mproxyPlaybackHandle, &mkillPlayBackThread);
- if (err == EPIPE) {
- continue;
- } else if (err != NO_ERROR) {
- break;
- }
- avail = pcm_avail(mproxyPlaybackHandle);
- }
- if (avail < mproxyPlaybackHandle->sw_p->avail_min && !mkillPlayBackThread) {
- pollForProxyData();
- //if polling returned some error
- if (!mkillPlayBackThread) {
- continue;
- } else {
- break;
- }
- } else { //Got some data or mkillPlayBackThread is true
- break;
- }
- }
- if (mkillPlayBackThread) {
- break;
- }
-
- if (x.frames > avail)
- frames = avail;
-
- if (!mkillPlayBackThread) {
- msrcProxy_addr = dst_address(mproxyPlaybackHandle);
- memcpy(proxybuf, msrcProxy_addr, proxyPeriod );
-
- x.frames -= frames;
- mproxyPlaybackHandle->sync_ptr->c.control.appl_ptr += frames;
- mproxyPlaybackHandle->sync_ptr->flags = 0;
- proxySizeRemaining = proxyPeriod;
- }
-
- if (!mkillPlayBackThread) {
- err = syncPtr(mproxyPlaybackHandle, &mkillPlayBackThread);
- if (err == EPIPE) {
- continue;
- } else if (err != NO_ERROR) {
- break;
- }
- }
- }
- //ALOGE("usbSizeFilled %d, proxySizeRemaining %d ",usbSizeFilled,proxySizeRemaining);
- if (usbPeriod - usbSizeFilled <= proxySizeRemaining) {
- memcpy(usbbuf + usbSizeFilled, proxybuf + proxyPeriod - proxySizeRemaining, usbPeriod - usbSizeFilled);
- proxySizeRemaining -= (usbPeriod - usbSizeFilled);
- usbSizeFilled = usbPeriod;
- }
- else {
- memcpy(usbbuf + usbSizeFilled, proxybuf + proxyPeriod - proxySizeRemaining,proxySizeRemaining);
- usbSizeFilled += proxySizeRemaining;
- proxySizeRemaining = 0;
- }
-
- if (usbSizeFilled == usbPeriod) {
- for (;;) {
- if (!musbPlaybackHandle->running) {
- if (pcm_prepare(musbPlaybackHandle)) {
- ALOGE("ERROR: pcm_prepare failed for usb");
- mkillPlayBackThread = true;
- break;
- }
- }
- /*************USB syncing before write ******************/
- musbPlaybackHandle->sync_ptr->flags = SNDRV_PCM_SYNC_PTR_APPL |
- SNDRV_PCM_SYNC_PTR_AVAIL_MIN;
- if (mtimeOut == TIMEOUT_INFINITE && !mkillPlayBackThread) {
- err = syncPtr(musbPlaybackHandle, &mkillPlayBackThread);
- if (err == EPIPE) {
- continue;
- } else if (err != NO_ERROR) {
- break;
- }
- avail = pcm_avail(musbPlaybackHandle);
- //ALOGV("Avail USB is: %d", avail);
- }
-
- if (avail < musbPlaybackHandle->sw_p->avail_min && !mkillPlayBackThread) {
- pollForUsbData();
- if (!mkillPlayBackThread) {
- continue;
- } else {
- break;
- }
- } else {
- break;
- }
- }
- if (mkillPlayBackThread) {
- break;
- }
-
- if (!mkillPlayBackThread) {
- mdstUsb_addr = dst_address(musbPlaybackHandle);
-
- /**************End USB syncing before write *************/
-
- memcpy(mdstUsb_addr, usbbuf, usbPeriod );
- usbSizeFilled = 0;
- memset(usbbuf, 0x0, usbPeriod);
- }
-
- /**************** sync up after write -- USB ************************/
- musbPlaybackHandle->sync_ptr->c.control.appl_ptr += usbframes;
- musbPlaybackHandle->sync_ptr->flags = 0;
- if (!mkillPlayBackThread) {
- err = syncPtr(musbPlaybackHandle, &mkillPlayBackThread);
- if (err == EPIPE) {
- continue;
- } else if (err != NO_ERROR) {
- break;
- }
- }
-
- bytes_written = musbPlaybackHandle->sync_ptr->c.control.appl_ptr - musbPlaybackHandle->sync_ptr->s.status.hw_ptr;
- ALOGE("Appl ptr %d , hw_ptr %d, difference %d",musbPlaybackHandle->sync_ptr->c.control.appl_ptr, musbPlaybackHandle->sync_ptr->s.status.hw_ptr, bytes_written);
-
- /*
- Following is the check to prevent USB from going to bad state.
- This happens in case of an underrun where there is not enough
- data from the proxy
- */
- if (bytes_written <= usbPeriod && musbPlaybackHandle->start) {
- ioctl(musbPlaybackHandle->fd, SNDRV_PCM_IOCTL_PAUSE,1);
- pcm_prepare(musbPlaybackHandle);
- musbPlaybackHandle->start = false;
- continue;
- }
- if ((bytes_written >= musbPlaybackHandle->sw_p->start_threshold) && (!musbPlaybackHandle->start)) {
- if (!mkillPlayBackThread) {
- err = startDevice(musbPlaybackHandle, &mkillPlayBackThread);
- if (err == EPIPE) {
- continue;
- } else if (err != NO_ERROR) {
- mkillPlayBackThread = true;
- break;
- }
- }
- }
- /*************** End sync up after write -- USB *********************/
- }
- }
- if (mkillPlayBackThread) {
- if (proxybuf)
- free(proxybuf);
- if (usbbuf)
- free(usbbuf);
- mproxypfdPlayback = -1;
- musbpfdPlayback = -1;
- closeDevice(mproxyPlaybackHandle);
- closeDevice(musbPlaybackHandle);
- }
- ALOGD("Exiting USB Playback Thread");
-}
-
-void AudioUsbALSA::startPlayback()
-{
- mkillPlayBackThread = false;
- ALOGD("Creating USB Playback Thread");
- pthread_create(&mPlaybackUsb, NULL, PlaybackThreadWrapper, this);
-}
-
-void AudioUsbALSA::startRecording()
-{
- //create Thread
- mkillRecordingThread = false;
- ALOGV("Creating USB recording Thread");
- pthread_create(&mRecordingUsb, NULL, RecordingThreadWrapper, this);
-}
-}
diff --git a/legacy/alsa_sound/AudioUsbALSA.h b/legacy/alsa_sound/AudioUsbALSA.h
deleted file mode 100644
index d06bbb7..0000000
--- a/legacy/alsa_sound/AudioUsbALSA.h
+++ /dev/null
@@ -1,143 +0,0 @@
-/* AudioUsbALSA.h
-
-Copyright (c) 2012, The Linux Foundation. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following
- disclaimer in the documentation and/or other materials provided
- with the distribution.
- * Neither the name of The Linux Foundation nor the names of its
- contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.*/
-
-#ifndef ANDROID_AUDIO_USB_ALSA_H
-#define ANDROID_AUDIO_USB_ALSA_H
-
-#include <utils/List.h>
-#include <hardware_legacy/AudioHardwareBase.h>
-
-#include <hardware_legacy/AudioHardwareInterface.h>
-#include <hardware_legacy/AudioSystemLegacy.h>
-#include <system/audio.h>
-#include <hardware/audio.h>
-#include <utils/threads.h>
-
-#define DEFAULT_BUFFER_SIZE 2048
-#define POLL_TIMEOUT 3000
-#define DEFAULT_CHANNEL_MODE 2
-#define CHANNEL_MODE_ONE 1
-#define PROXY_DEFAULT_SAMPLING_RATE 48000
-#define SIGNAL_EVENT_TIMEOUT 1
-#define SIGNAL_EVENT_KILLTHREAD 2
-
-#define BUFFSIZE 1000000
-
-#define PATH "/proc/asound/card1/stream0"
-
-extern "C" {
- #include <sound/asound.h>
- #include "alsa_audio.h"
- #include "msm8960_use_cases.h"
-}
-
-#include <hardware/hardware.h>
-
-namespace android_audio_legacy
-{
-using android::List;
-using android::Mutex;
-class AudioUsbALSA;
-
-class AudioUsbALSA
-{
-private:
- int mproxypfdPlayback;
- int musbpfdPlayback;
- int mnfdsPlayback;
- int mnfdsRecording;
- int mtimeOut;
- int mtimeOutRecording;
- struct pcm *mproxyRecordingHandle;
- struct pcm *musbRecordingHandle;
- struct pcm *mproxyPlaybackHandle;
- struct pcm *musbPlaybackHandle;
- u_int8_t *mdstUsb_addr;
- u_int8_t *msrcProxy_addr;
- bool mkillPlayBackThread;
- bool mkillRecordingThread;
- pthread_t mPlaybackUsb;
- pthread_t mRecordingUsb;
- snd_use_case_mgr_t *mUcMgr;
-
- //Helper functions
- struct pcm * configureDevice(unsigned flags, char* hw, int sampleRate, int channelCount, int periodSize, bool playback);
- status_t syncPtr(struct pcm *handle, bool *killThread);
-
- //playback
- void pollForProxyData();
- void pollForUsbData();
-
- //recording
- void pollForUsbDataForRecording();
- void pollForProxyDataForRecording();
-
- status_t startDevice(pcm *handle, bool *killThread);
-
- void PlaybackThreadEntry();
- static void *PlaybackThreadWrapper(void *me);
-
- void RecordingThreadEntry();
- static void *RecordingThreadWrapper(void *me);
-
- status_t setHardwareParams(pcm *local_handle, uint32_t sampleRate, uint32_t channels, int periodSize);
-
- status_t setSoftwareParams(pcm *pcm, bool playback);
-
- status_t closeDevice(pcm *handle);
-
- status_t getCap(char * type, int &channels, int &sampleRate);
- int getnumOfRates(char *rateStr);
- int mchannelsPlayback;
- int msampleRatePlayback;
- int mchannelsCapture;
- int msampleRateCapture;
-
-public:
- AudioUsbALSA();
- virtual ~AudioUsbALSA();
-
- void exitPlaybackThread(uint64_t writeVal);
- void exitRecordingThread(uint64_t writeVal);
- void setkillUsbRecordingThread(bool val);
- bool getkillUsbPlaybackThread() {
- return mkillPlayBackThread;
- }
- bool getkillUsbRecordingThread() {
- return mkillRecordingThread;
- }
- //Playback
- void startPlayback();
-
- //Capture
- void startRecording();
-};
-
-}; // namespace android_audio_legacy
-#endif // ANDROID_AUDIO_USB_ALSA_H
diff --git a/legacy/alsa_sound/AudioUtil.cpp b/legacy/alsa_sound/AudioUtil.cpp
deleted file mode 100644
index 3549f24..0000000
--- a/legacy/alsa_sound/AudioUtil.cpp
+++ /dev/null
@@ -1,279 +0,0 @@
-/* AudioUtil.cpp
- *
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "AudioUtil"
-//#define LOG_NDEBUG 0
-#include <utils/Log.h>
-
-#include "AudioUtil.h"
-
-int AudioUtil::printFormatFromEDID(unsigned char format) {
- switch (format) {
- case LPCM:
- ALOGV("Format:LPCM");
- break;
- case AC3:
- ALOGV("Format:AC-3");
- break;
- case MPEG1:
- ALOGV("Format:MPEG1 (Layers 1 & 2)");
- break;
- case MP3:
- ALOGV("Format:MP3 (MPEG1 Layer 3)");
- break;
- case MPEG2_MULTI_CHANNEL:
- ALOGV("Format:MPEG2 (multichannel)");
- break;
- case AAC:
- ALOGV("Format:AAC");
- break;
- case DTS:
- ALOGV("Format:DTS");
- break;
- case ATRAC:
- ALOGV("Format:ATRAC");
- break;
- case SACD:
- ALOGV("Format:One-bit audio aka SACD");
- break;
- case DOLBY_DIGITAL_PLUS:
- ALOGV("Format:Dolby Digital +");
- break;
- case DTS_HD:
- ALOGV("Format:DTS-HD");
- break;
- case MAT:
- ALOGV("Format:MAT (MLP)");
- break;
- case DST:
- ALOGV("Format:DST");
- break;
- case WMA_PRO:
- ALOGV("Format:WMA Pro");
- break;
- default:
- ALOGV("Invalid format ID....");
- break;
- }
- return format;
-}
-
-int AudioUtil::getSamplingFrequencyFromEDID(unsigned char byte) {
- int nFreq = 0;
-
- if (byte & BIT(6)) {
- ALOGV("192kHz");
- nFreq = 192000;
- } else if (byte & BIT(5)) {
- ALOGV("176kHz");
- nFreq = 176000;
- } else if (byte & BIT(4)) {
- ALOGV("96kHz");
- nFreq = 96000;
- } else if (byte & BIT(3)) {
- ALOGV("88.2kHz");
- nFreq = 88200;
- } else if (byte & BIT(2)) {
- ALOGV("48kHz");
- nFreq = 48000;
- } else if (byte & BIT(1)) {
- ALOGV("44.1kHz");
- nFreq = 44100;
- } else if (byte & BIT(0)) {
- ALOGV("32kHz");
- nFreq = 32000;
- }
- return nFreq;
-}
-
-int AudioUtil::getBitsPerSampleFromEDID(unsigned char byte,
- unsigned char format) {
- int nBitsPerSample = 0;
- if (format == 1) {
- if (byte & BIT(2)) {
- ALOGV("24bit");
- nBitsPerSample = 24;
- } else if (byte & BIT(1)) {
- ALOGV("20bit");
- nBitsPerSample = 20;
- } else if (byte & BIT(0)) {
- ALOGV("16bit");
- nBitsPerSample = 16;
- }
- } else {
- ALOGV("not lpcm format, return 0");
- return 0;
- }
- return nBitsPerSample;
-}
-
-bool AudioUtil::getHDMIAudioSinkCaps(EDID_AUDIO_INFO* pInfo) {
- unsigned char channels[16];
- unsigned char formats[16];
- unsigned char frequency[16];
- unsigned char bitrate[16];
- unsigned char* data = NULL;
- unsigned char* original_data_ptr = NULL;
- int count = 0;
- bool bRet = false;
- const char* file = "/sys/class/graphics/fb1/audio_data_block";
- FILE* fpaudiocaps = fopen(file, "rb");
- if (fpaudiocaps) {
- ALOGV("opened audio_caps successfully...");
- fseek(fpaudiocaps, 0, SEEK_END);
- long size = ftell(fpaudiocaps);
- ALOGV("audiocaps size is %ld\n",size);
- data = (unsigned char*) malloc(size);
- if (data) {
- fseek(fpaudiocaps, 0, SEEK_SET);
- original_data_ptr = data;
- fread(data, 1, size, fpaudiocaps);
- }
- fclose(fpaudiocaps);
- } else {
- ALOGE("failed to open audio_caps");
- }
-
- if (pInfo && data) {
- int length = 0;
- memcpy(&count, data, sizeof(int));
- data+= sizeof(int);
- ALOGV("#Audio Block Count is %d",count);
- memcpy(&length, data, sizeof(int));
- data += sizeof(int);
- ALOGV("Total length is %d",length);
- unsigned int sad[MAX_SHORT_AUDIO_DESC_CNT];
- int nblockindex = 0;
- int nCountDesc = 0;
- while (length >= MIN_AUDIO_DESC_LENGTH && count < MAX_SHORT_AUDIO_DESC_CNT) {
- sad[nblockindex] = (unsigned int)data[0] + ((unsigned int)data[1] << 8)
- + ((unsigned int)data[2] << 16);
- nblockindex+=1;
- nCountDesc++;
- length -= MIN_AUDIO_DESC_LENGTH;
- data += MIN_AUDIO_DESC_LENGTH;
- }
- memset(pInfo, 0, sizeof(EDID_AUDIO_INFO));
- pInfo->nAudioBlocks = nCountDesc;
- ALOGV("Total # of audio descriptors %d",nCountDesc);
- int nIndex = 0;
- while (nCountDesc--) {
- channels [nIndex] = (sad[nIndex] & 0x7) + 1;
- formats [nIndex] = (sad[nIndex] & 0xFF) >> 3;
- frequency[nIndex] = (sad[nIndex] >> 8) & 0xFF;
- bitrate [nIndex] = (sad[nIndex] >> 16) & 0xFF;
- nIndex++;
- }
- bRet = true;
- for (int i = 0; i < pInfo->nAudioBlocks; i++) {
- ALOGV("AUDIO DESC BLOCK # %d\n",i);
-
- pInfo->AudioBlocksArray[i].nChannels = channels[i];
- ALOGV("pInfo->AudioBlocksArray[i].nChannels %d\n", pInfo->AudioBlocksArray[i].nChannels);
-
- ALOGV("Format Byte %d\n", formats[i]);
- pInfo->AudioBlocksArray[i].nFormatId = (EDID_AUDIO_FORMAT_ID)printFormatFromEDID(formats[i]);
- ALOGV("pInfo->AudioBlocksArray[i].nFormatId %d",pInfo->AudioBlocksArray[i].nFormatId);
-
- ALOGV("Frequency Byte %d\n", frequency[i]);
- pInfo->AudioBlocksArray[i].nSamplingFreq = getSamplingFrequencyFromEDID(frequency[i]);
- ALOGV("pInfo->AudioBlocksArray[i].nSamplingFreq %d",pInfo->AudioBlocksArray[i].nSamplingFreq);
-
- ALOGV("BitsPerSample Byte %d\n", bitrate[i]);
- pInfo->AudioBlocksArray[i].nBitsPerSample = getBitsPerSampleFromEDID(bitrate[i],formats[i]);
- ALOGV("pInfo->AudioBlocksArray[i].nBitsPerSample %d",pInfo->AudioBlocksArray[i].nBitsPerSample);
- }
- getSpeakerAllocation(pInfo);
- }
- if (original_data_ptr)
- free(original_data_ptr);
-
- return bRet;
-}
-
-bool AudioUtil::getSpeakerAllocation(EDID_AUDIO_INFO* pInfo) {
- int count = 0;
- bool bRet = false;
- unsigned char* data = NULL;
- unsigned char* original_data_ptr = NULL;
- const char* spkrfile = "/sys/class/graphics/fb1/spkr_alloc_data_block";
- FILE* fpspkrfile = fopen(spkrfile, "rb");
- if(fpspkrfile) {
- ALOGV("opened spkr_alloc_data_block successfully...");
- fseek(fpspkrfile,0,SEEK_END);
- long size = ftell(fpspkrfile);
- ALOGV("fpspkrfile size is %ld\n",size);
- data = (unsigned char*)malloc(size);
- if(data) {
- original_data_ptr = data;
- fseek(fpspkrfile,0,SEEK_SET);
- fread(data,1,size,fpspkrfile);
- }
- fclose(fpspkrfile);
- } else {
- ALOGE("failed to open fpspkrfile");
- }
-
- if(pInfo && data) {
- int length = 0;
- memcpy(&count, data, sizeof(int));
- ALOGV("Count is %d",count);
- data += sizeof(int);
- memcpy(&length, data, sizeof(int));
- ALOGV("Total length is %d",length);
- data+= sizeof(int);
- ALOGV("Total speaker allocation Block count # %d\n",count);
- bRet = true;
- for (int i = 0; i < count; i++) {
- ALOGV("Speaker Allocation BLOCK # %d\n",i);
- pInfo->nSpeakerAllocation[0] = data[0];
- pInfo->nSpeakerAllocation[1] = data[1];
- pInfo->nSpeakerAllocation[2] = data[2];
- ALOGV("pInfo->nSpeakerAllocation %x %x %x\n", data[0],data[1],data[2]);
-
-
- if (pInfo->nSpeakerAllocation[0] & BIT(7)) {
- ALOGV("FLW/FRW");
- } else if (pInfo->nSpeakerAllocation[0] & BIT(6)) {
- ALOGV("RLC/RRC");
- } else if (pInfo->nSpeakerAllocation[0] & BIT(5)) {
- ALOGV("FLC/FRC");
- } else if (pInfo->nSpeakerAllocation[0] & BIT(4)) {
- ALOGV("RC");
- } else if (pInfo->nSpeakerAllocation[0] & BIT(3)) {
- ALOGV("RL/RR");
- } else if (pInfo->nSpeakerAllocation[0] & BIT(2)) {
- ALOGV("FC");
- } else if (pInfo->nSpeakerAllocation[0] & BIT(1)) {
- ALOGV("LFE");
- } else if (pInfo->nSpeakerAllocation[0] & BIT(0)) {
- ALOGV("FL/FR");
- }
-
- if (pInfo->nSpeakerAllocation[1] & BIT(2)) {
- ALOGV("FCH");
- } else if (pInfo->nSpeakerAllocation[1] & BIT(1)) {
- ALOGV("TC");
- } else if (pInfo->nSpeakerAllocation[1] & BIT(0)) {
- ALOGV("FLH/FRH");
- }
- }
- }
- if (original_data_ptr)
- free(original_data_ptr);
- return bRet;
-}
diff --git a/legacy/alsa_sound/AudioUtil.h b/legacy/alsa_sound/AudioUtil.h
deleted file mode 100644
index 6575315..0000000
--- a/legacy/alsa_sound/AudioUtil.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/* AudioUtil.h
- *
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ALSA_SOUND_AUDIO_UTIL_H
-#define ALSA_SOUND_AUDIO_UTIL_H
-
-#define BIT(nr) (1UL << (nr))
-#define MAX_EDID_BLOCKS 10
-#define MAX_SHORT_AUDIO_DESC_CNT 30
-#define MIN_AUDIO_DESC_LENGTH 3
-#define MIN_SPKR_ALLOCATION_DATA_LENGTH 3
-
-typedef enum EDID_AUDIO_FORMAT_ID {
- LPCM = 1,
- AC3,
- MPEG1,
- MP3,
- MPEG2_MULTI_CHANNEL,
- AAC,
- DTS,
- ATRAC,
- SACD,
- DOLBY_DIGITAL_PLUS,
- DTS_HD,
- MAT,
- DST,
- WMA_PRO
-} EDID_AUDIO_FORMAT_ID;
-
-typedef struct EDID_AUDIO_BLOCK_INFO {
- EDID_AUDIO_FORMAT_ID nFormatId;
- int nSamplingFreq;
- int nBitsPerSample;
- int nChannels;
-} EDID_AUDIO_BLOCK_INFO;
-
-typedef struct EDID_AUDIO_INFO {
- int nAudioBlocks;
- unsigned char nSpeakerAllocation[MIN_SPKR_ALLOCATION_DATA_LENGTH];
- EDID_AUDIO_BLOCK_INFO AudioBlocksArray[MAX_EDID_BLOCKS];
-} EDID_AUDIO_INFO;
-
-class AudioUtil {
-public:
-
- //Parses EDID audio block when if HDMI is connected to determine audio sink capabilities.
- static bool getHDMIAudioSinkCaps(EDID_AUDIO_INFO*);
-
-private:
- static int printFormatFromEDID(unsigned char format);
- static int getSamplingFrequencyFromEDID(unsigned char byte);
- static int getBitsPerSampleFromEDID(unsigned char byte,
- unsigned char format);
- static bool getSpeakerAllocation(EDID_AUDIO_INFO* pInfo);
-};
-
-#endif /* ALSA_SOUND_AUDIO_UTIL_H */
diff --git a/legacy/alsa_sound/CleanSpec.mk b/legacy/alsa_sound/CleanSpec.mk
deleted file mode 100755
index d2bc78b..0000000
--- a/legacy/alsa_sound/CleanSpec.mk
+++ /dev/null
@@ -1,51 +0,0 @@
-# Copyright (C) 2007 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-# If you don't need to do a full clean build but would like to touch
-# a file or delete some intermediate files, add a clean step to the end
-# of the list. These steps will only be run once, if they haven't been
-# run before.
-#
-# E.g.:
-# $(call add-clean-step, touch -c external/sqlite/sqlite3.h)
-# $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libz_intermediates)
-#
-# Always use "touch -c" and "rm -f" or "rm -rf" to gracefully deal with
-# files that are missing or have been moved.
-#
-# Use $(PRODUCT_OUT) to get to the "out/target/product/blah/" directory.
-# Use $(OUT_DIR) to refer to the "out" directory.
-#
-# If you need to re-do something that's already mentioned, just copy
-# the command and add it to the bottom of the list. E.g., if a change
-# that you made last week required touching a file and a change you
-# made today requires touching the same file, just copy the old
-# touch step and add it to the end of the list.
-#
-# ************************************************
-# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
-# ************************************************
-
-# For example:
-#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/AndroidTests_intermediates)
-#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/core_intermediates)
-#$(call add-clean-step, find $(OUT_DIR) -type f -name "IGTalkSession*" -print0 | xargs -0 rm -f)
-#$(call add-clean-step, rm -rf $(PRODUCT_OUT)/data/*)
-
-$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/etc/audio_policy.conf)
-
-# ************************************************
-# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
-# ************************************************
diff --git a/legacy/alsa_sound/MODULE_LICENSE_APACHE2 b/legacy/alsa_sound/MODULE_LICENSE_APACHE2
deleted file mode 100644
index e69de29..0000000
--- a/legacy/alsa_sound/MODULE_LICENSE_APACHE2
+++ /dev/null
diff --git a/legacy/alsa_sound/NOTICE b/legacy/alsa_sound/NOTICE
deleted file mode 100644
index ada44e1..0000000
--- a/legacy/alsa_sound/NOTICE
+++ /dev/null
@@ -1,191 +0,0 @@
-
- Copyright (c) 2005-2008, The Android Open Source Project
- Copyright 2008 Wind River Systems
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
diff --git a/legacy/alsa_sound/acoustics_default.cpp b/legacy/alsa_sound/acoustics_default.cpp
deleted file mode 100644
index aa21190..0000000
--- a/legacy/alsa_sound/acoustics_default.cpp
+++ /dev/null
@@ -1,99 +0,0 @@
-/* acoustics_default.cpp
- **
- ** Copyright 2009 Wind River Systems
- **
- ** Licensed under the Apache License, Version 2.0 (the "License");
- ** you may not use this file except in compliance with the License.
- ** You may obtain a copy of the License at
- **
- ** http://www.apache.org/licenses/LICENSE-2.0
- **
- ** Unless required by applicable law or agreed to in writing, software
- ** distributed under the License is distributed on an "AS IS" BASIS,
- ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ** See the License for the specific language governing permissions and
- ** limitations under the License.
- */
-
-#define LOG_TAG "AcousticsModule"
-#include <utils/Log.h>
-
-#include "AudioHardwareALSA.h"
-
-namespace android
-{
-
-static int s_device_open(const hw_module_t*, const char*, hw_device_t**);
-static int s_device_close(hw_device_t*);
-
-static status_t s_use_handle(acoustic_device_t *, alsa_handle_t *);
-static status_t s_cleanup(acoustic_device_t *);
-static status_t s_set_params(acoustic_device_t *,
- AudioSystem::audio_in_acoustics, void *params);
-
-static hw_module_methods_t s_module_methods = {
- open : s_device_open
-};
-
-extern "C" hw_module_t HAL_MODULE_INFO_SYM = {
- tag : HARDWARE_MODULE_TAG,
- version_major : 1,
- version_minor : 0,
- id : ACOUSTICS_HARDWARE_MODULE_ID,
- name : "ALSA acoustics module",
- author : "Wind River",
- methods : &s_module_methods,
- dso : 0,
- reserved : { 0, },
-};
-
-static int s_device_open(const hw_module_t* module, const char* name,
- hw_device_t** device)
-{
- acoustic_device_t *dev;
- dev = (acoustic_device_t *) malloc(sizeof(*dev));
- if (!dev) return -ENOMEM;
-
- memset(dev, 0, sizeof(*dev));
-
- /* initialize the procs */
- dev->common.tag = HARDWARE_DEVICE_TAG;
- dev->common.version = 0;
- dev->common.module = (hw_module_t *) module;
- dev->common.close = s_device_close;
-
- // Required methods...
- dev->use_handle = s_use_handle;
- dev->cleanup = s_cleanup;
- dev->set_params = s_set_params;
-
- // read, write, and recover are optional methods...
-
- *device = &dev->common;
- return 0;
-}
-
-static int s_device_close(hw_device_t* device)
-{
- free(device);
- return 0;
-}
-
-static status_t s_use_handle(acoustic_device_t *dev, alsa_handle_t *h)
-{
- return NO_ERROR;
-}
-
-static status_t s_cleanup(acoustic_device_t *dev)
-{
- ALOGD("Acoustics close stub called.");
- return NO_ERROR;
-}
-
-static status_t s_set_params(acoustic_device_t *dev,
- AudioSystem::audio_in_acoustics acoustics, void *params)
-{
- ALOGD("Acoustics set_params stub called with %d.", (int)acoustics);
- return NO_ERROR;
-}
-}
diff --git a/legacy/alsa_sound/alsa_default.cpp b/legacy/alsa_sound/alsa_default.cpp
deleted file mode 100644
index 5be2958..0000000
--- a/legacy/alsa_sound/alsa_default.cpp
+++ /dev/null
@@ -1,1833 +0,0 @@
-/* alsa_default.cpp
- **
- ** Copyright 2009 Wind River Systems
- ** Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
- **
- ** Licensed under the Apache License, Version 2.0 (the "License");
- ** you may not use this file except in compliance with the License.
- ** You may obtain a copy of the License at
- **
- ** http://www.apache.org/licenses/LICENSE-2.0
- **
- ** Unless required by applicable law or agreed to in writing, software
- ** distributed under the License is distributed on an "AS IS" BASIS,
- ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ** See the License for the specific language governing permissions and
- ** limitations under the License.
- */
-
-#define LOG_TAG "ALSAModule"
-//#define LOG_NDEBUG 0
-#define LOG_NDDEBUG 0
-#include <utils/Log.h>
-#include <cutils/properties.h>
-#include <linux/ioctl.h>
-#include "AudioUtil.h"
-#include "AudioHardwareALSA.h"
-#include <media/AudioRecord.h>
-#include <dlfcn.h>
-#ifdef QCOM_CSDCLIENT_ENABLED
-extern "C" {
-static int (*csd_disable_device)();
-static int (*csd_enable_device)(int, int, uint32_t);
-static int (*csd_volume)(int);
-static int (*csd_mic_mute)(int);
-static int (*csd_wide_voice)(uint8_t);
-static int (*csd_slow_talk)(uint8_t);
-static int (*csd_fens)(uint8_t);
-static int (*csd_start_voice)();
-static int (*csd_stop_voice)();
-}
-#endif
-
-#ifndef ALSA_DEFAULT_SAMPLE_RATE
-#define ALSA_DEFAULT_SAMPLE_RATE 44100 // in Hz
-#endif
-
-#define BTSCO_RATE_16KHZ 16000
-#define USECASE_TYPE_RX 1
-#define USECASE_TYPE_TX 2
-#define MAX_HDMI_CHANNEL_CNT 6
-
-namespace android_audio_legacy
-{
-
-static int s_device_open(const hw_module_t*, const char*, hw_device_t**);
-static int s_device_close(hw_device_t*);
-static status_t s_init(alsa_device_t *, ALSAHandleList &);
-static status_t s_open(alsa_handle_t *);
-static status_t s_close(alsa_handle_t *);
-static status_t s_standby(alsa_handle_t *);
-static status_t s_route(alsa_handle_t *, uint32_t, int);
-static status_t s_start_voice_call(alsa_handle_t *);
-static status_t s_start_voip_call(alsa_handle_t *);
-static status_t s_start_fm(alsa_handle_t *);
-static void s_set_voice_volume(int);
-static void s_set_voip_volume(int);
-static void s_set_mic_mute(int);
-static void s_set_voip_mic_mute(int);
-static void s_set_voip_config(int, int);
-static status_t s_set_fm_vol(int);
-static void s_set_btsco_rate(int);
-static status_t s_set_lpa_vol(int);
-static void s_enable_wide_voice(bool flag);
-static void s_enable_fens(bool flag);
-static void s_set_flags(uint32_t flags);
-static status_t s_set_compressed_vol(int);
-static void s_enable_slow_talk(bool flag);
-static void s_set_voc_rec_mode(uint8_t mode);
-static void s_set_volte_mic_mute(int state);
-static void s_set_volte_volume(int vol);
-static bool s_is_tmus();
-#ifdef SEPERATED_AUDIO_INPUT
-static void s_setInput(int);
-
-static int input_source;
-#endif
-static int mccmnc;
-#ifdef QCOM_CSDCLIENT_ENABLED
-static void s_set_csd_handle(void*);
-#endif
-
-static char mic_type[25];
-static char curRxUCMDevice[50];
-static char curTxUCMDevice[50];
-static int fluence_mode;
-static int fmVolume;
-#ifdef USES_FLUENCE_INCALL
-static uint32_t mDevSettingsFlag = TTY_OFF | DMIC_FLAG;
-#else
-static uint32_t mDevSettingsFlag = TTY_OFF;
-#endif
-static int btsco_samplerate = 8000;
-static ALSAUseCaseList mUseCaseList;
-static void *csd_handle;
-
-static hw_module_methods_t s_module_methods = {
- open : s_device_open
-};
-
-extern "C" {
-hw_module_t HAL_MODULE_INFO_SYM = {
- tag : HARDWARE_MODULE_TAG,
- version_major : 1,
- version_minor : 0,
- id : ALSA_HARDWARE_MODULE_ID,
- name : "QCOM ALSA module",
- author : "QuIC Inc",
- methods : &s_module_methods,
- dso : 0,
- reserved : {0,},
-};
-}
-
-static int s_device_open(const hw_module_t* module, const char* name,
- hw_device_t** device)
-{
- char value[128];
- alsa_device_t *dev;
- dev = (alsa_device_t *) malloc(sizeof(*dev));
- if (!dev) return -ENOMEM;
-
- memset(dev, 0, sizeof(*dev));
-
- /* initialize the procs */
- dev->common.tag = HARDWARE_DEVICE_TAG;
- dev->common.version = 0;
- dev->common.module = (hw_module_t *) module;
- dev->common.close = s_device_close;
- dev->init = s_init;
- dev->open = s_open;
- dev->close = s_close;
- dev->route = s_route;
- dev->standby = s_standby;
- dev->startVoiceCall = s_start_voice_call;
- dev->startVoipCall = s_start_voip_call;
- dev->startFm = s_start_fm;
- dev->setVoiceVolume = s_set_voice_volume;
- dev->setVoipVolume = s_set_voip_volume;
- dev->setMicMute = s_set_mic_mute;
- dev->setVoipMicMute = s_set_voip_mic_mute;
- dev->setVoipConfig = s_set_voip_config;
- dev->setFmVolume = s_set_fm_vol;
- dev->setBtscoRate = s_set_btsco_rate;
- dev->setLpaVolume = s_set_lpa_vol;
- dev->enableWideVoice = s_enable_wide_voice;
- dev->enableFENS = s_enable_fens;
- dev->setFlags = s_set_flags;
- dev->setCompressedVolume = s_set_compressed_vol;
- dev->enableSlowTalk = s_enable_slow_talk;
- dev->setVocRecMode = s_set_voc_rec_mode;
- dev->setVoLTEMicMute = s_set_volte_mic_mute;
- dev->setVoLTEVolume = s_set_volte_volume;
-#ifdef SEPERATED_AUDIO_INPUT
- dev->setInput = s_setInput;
-#endif
-#ifdef QCOM_CSDCLIENT_ENABLED
- dev->setCsdHandle = s_set_csd_handle;
-#endif
- *device = &dev->common;
-
- property_get("persist.audio.handset.mic",value,"0");
- strlcpy(mic_type, value, sizeof(mic_type));
- property_get("persist.audio.fluence.mode",value,"0");
- if (!strcmp("broadside", value)) {
- fluence_mode = FLUENCE_MODE_BROADSIDE;
- } else {
- fluence_mode = FLUENCE_MODE_ENDFIRE;
- }
- strlcpy(curRxUCMDevice, "None", sizeof(curRxUCMDevice));
- strlcpy(curTxUCMDevice, "None", sizeof(curTxUCMDevice));
- ALOGV("ALSA module opened");
-
- return 0;
-}
-
-static int s_device_close(hw_device_t* device)
-{
- free(device);
- device = NULL;
- return 0;
-}
-
-// ----------------------------------------------------------------------------
-
-static const int DEFAULT_SAMPLE_RATE = ALSA_DEFAULT_SAMPLE_RATE;
-
-static void switchDevice(alsa_handle_t *handle, uint32_t devices, uint32_t mode);
-static char *getUCMDevice(uint32_t devices, int input, char *rxDevice);
-static void disableDevice(alsa_handle_t *handle);
-int getUseCaseType(const char *useCase);
-
-static int callMode = AudioSystem::MODE_NORMAL;
-// ----------------------------------------------------------------------------
-
-bool platform_is_Fusion3()
-{
- char platform[128], baseband[128];
- property_get("ro.board.platform", platform, "");
- property_get("ro.baseband", baseband, "");
- if (!strcmp("msm8960", platform) && !strcmp("mdm", baseband))
- return true;
- else
- return false;
-}
-
-int deviceName(alsa_handle_t *handle, unsigned flags, char **value)
-{
- int ret = 0;
- char ident[70];
-
- if (flags & PCM_IN) {
- strlcpy(ident, "CapturePCM/", sizeof(ident));
- } else {
- strlcpy(ident, "PlaybackPCM/", sizeof(ident));
- }
- strlcat(ident, handle->useCase, sizeof(ident));
- ret = snd_use_case_get(handle->ucMgr, ident, (const char **)value);
- ALOGD("Device value returned is %s", (*value));
- return ret;
-}
-
-status_t setHDMIChannelCount()
-{
- status_t err = NO_ERROR;
- int channel_count = 0;
- const char *channel_cnt_str = NULL;
- EDID_AUDIO_INFO info = { 0 };
-
- ALSAControl control("/dev/snd/controlC0");
- if (AudioUtil::getHDMIAudioSinkCaps(&info)) {
- for (int i = 0; i < info.nAudioBlocks && i < MAX_EDID_BLOCKS; i++) {
- if (info.AudioBlocksArray[i].nChannels > channel_count &&
- info.AudioBlocksArray[i].nChannels <= MAX_HDMI_CHANNEL_CNT) {
- channel_count = info.AudioBlocksArray[i].nChannels;
- }
- }
- }
-
- switch (channel_count) {
- case 6: channel_cnt_str = "Six"; break;
- case 5: channel_cnt_str = "Five"; break;
- case 4: channel_cnt_str = "Four"; break;
- case 3: channel_cnt_str = "Three"; break;
- default: channel_cnt_str = "Two"; break;
- }
- ALOGD("HDMI channel count: %s", channel_cnt_str);
- control.set("HDMI_RX Channels", channel_cnt_str);
-
- return err;
-}
-
-status_t setHardwareParams(alsa_handle_t *handle)
-{
- struct snd_pcm_hw_params *params;
- unsigned long bufferSize, reqBuffSize;
- unsigned int periodTime, bufferTime;
- unsigned int requestedRate = handle->sampleRate;
- int status = 0;
- int channels = handle->channels;
- snd_pcm_format_t format = SNDRV_PCM_FORMAT_S16_LE;
-
- params = (snd_pcm_hw_params*) calloc(1, sizeof(struct snd_pcm_hw_params));
- if (!params) {
- ALOGE("Failed to allocate ALSA hardware parameters!");
- return NO_INIT;
- }
-
- reqBuffSize = handle->bufferSize;
- ALOGD("setHardwareParams: reqBuffSize %d channels %d sampleRate %d",
- (int) reqBuffSize, handle->channels, handle->sampleRate);
-
-#ifdef QCOM_SSR_ENABLED
- if (channels == 6) {
- if (!strncmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC, strlen(SND_USE_CASE_VERB_HIFI_REC))
- || !strncmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC, strlen(SND_USE_CASE_MOD_CAPTURE_MUSIC))) {
- ALOGV("HWParams: Use 4 channels in kernel for 5.1(%s) recording ", handle->useCase);
- channels = 4;
- }
- }
-#endif
-
- param_init(params);
- param_set_mask(params, SNDRV_PCM_HW_PARAM_ACCESS,
- SNDRV_PCM_ACCESS_RW_INTERLEAVED);
- if (handle->format != SNDRV_PCM_FORMAT_S16_LE) {
- if (handle->format == AudioSystem::AMR_NB
- || handle->format == AudioSystem::AMR_WB
-#ifdef QCOM_QCHAT_ENABLED
- || handle->format == AudioSystem::EVRC
- || handle->format == AudioSystem::EVRCB
- || handle->format == AudioSystem::EVRCWB
-#endif
- )
- format = SNDRV_PCM_FORMAT_SPECIAL;
- }
- param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
- format);
- param_set_mask(params, SNDRV_PCM_HW_PARAM_SUBFORMAT,
- SNDRV_PCM_SUBFORMAT_STD);
- param_set_int(params, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, reqBuffSize);
- param_set_int(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS, 16);
- param_set_int(params, SNDRV_PCM_HW_PARAM_FRAME_BITS,
- channels * 16);
- param_set_int(params, SNDRV_PCM_HW_PARAM_CHANNELS,
- channels);
- param_set_int(params, SNDRV_PCM_HW_PARAM_RATE, handle->sampleRate);
- param_set_hw_refine(handle->handle, params);
-
- if (param_set_hw_params(handle->handle, params)) {
- ALOGE("cannot set hw params");
- return NO_INIT;
- }
- param_dump(params);
-
- handle->handle->buffer_size = pcm_buffer_size(params);
- handle->handle->period_size = pcm_period_size(params);
- handle->handle->period_cnt = handle->handle->buffer_size/handle->handle->period_size;
- ALOGD("setHardwareParams: buffer_size %d, period_size %d, period_cnt %d",
- handle->handle->buffer_size, handle->handle->period_size,
- handle->handle->period_cnt);
- handle->handle->rate = handle->sampleRate;
- handle->handle->channels = handle->channels;
- handle->periodSize = handle->handle->period_size;
- if (strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC) &&
- strcmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC) &&
- (6 != handle->channels)) {
- //Do not update buffersize for 5.1 recording
- handle->bufferSize = handle->handle->period_size;
- }
-
- return NO_ERROR;
-}
-
-status_t setSoftwareParams(alsa_handle_t *handle)
-{
- struct snd_pcm_sw_params* params;
- struct pcm* pcm = handle->handle;
-
- unsigned long periodSize = pcm->period_size;
- int channels = handle->channels;
-
- params = (snd_pcm_sw_params*) calloc(1, sizeof(struct snd_pcm_sw_params));
- if (!params) {
- LOG_ALWAYS_FATAL("Failed to allocate ALSA software parameters!");
- return NO_INIT;
- }
-
-#ifdef QCOM_SSR_ENABLED
- if (channels == 6) {
- if (!strncmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC, strlen(SND_USE_CASE_VERB_HIFI_REC))
- || !strncmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC, strlen(SND_USE_CASE_MOD_CAPTURE_MUSIC))) {
- ALOGV("SWParams: Use 4 channels in kernel for 5.1(%s) recording ", handle->useCase);
- channels = 4;
- }
- }
-#endif
-
- // Get the current software parameters
- params->tstamp_mode = SNDRV_PCM_TSTAMP_NONE;
- params->period_step = 1;
- if(((!strcmp(handle->useCase,SND_USE_CASE_MOD_PLAY_VOIP)) ||
- (!strcmp(handle->useCase,SND_USE_CASE_VERB_IP_VOICECALL)))){
- ALOGV("setparam: start & stop threshold for Voip ");
- params->avail_min = handle->channels - 1 ? periodSize/4 : periodSize/2;
- params->start_threshold = periodSize/2;
- params->stop_threshold = INT_MAX;
- } else {
- params->avail_min = periodSize/(channels * 2);
- params->start_threshold = periodSize/(channels * 2);
- params->stop_threshold = INT_MAX;
- }
- params->silence_threshold = 0;
- params->silence_size = 0;
-
- if (param_set_sw_params(handle->handle, params)) {
- ALOGE("cannot set sw params");
- return NO_INIT;
- }
- return NO_ERROR;
-}
-
-void switchDevice(alsa_handle_t *handle, uint32_t devices, uint32_t mode)
-{
- const char **mods_list;
- use_case_t useCaseNode;
- unsigned usecase_type = 0;
- bool inCallDevSwitch = false;
- char *rxDevice, *txDevice, ident[70], *use_case = NULL;
- int err = 0, index, mods_size;
- int rx_dev_id, tx_dev_id;
- ALOGD("%s: device %d mode:%d", __FUNCTION__, devices, mode);
-
- if ((mode == AudioSystem::MODE_IN_CALL) || (mode == AudioSystem::MODE_IN_COMMUNICATION)) {
- if ((devices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) ||
- (devices & AudioSystem::DEVICE_IN_WIRED_HEADSET)) {
- devices = devices | (AudioSystem::DEVICE_OUT_WIRED_HEADSET |
- AudioSystem::DEVICE_IN_WIRED_HEADSET);
- } else if (devices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE) {
- devices = devices | (AudioSystem::DEVICE_OUT_WIRED_HEADPHONE |
- AudioSystem::DEVICE_IN_BUILTIN_MIC);
- } else if (devices & AudioSystem::DEVICE_IN_BUILTIN_MIC) {
- if (mode == AudioSystem::MODE_IN_CALL) {
- devices |= AudioSystem::DEVICE_OUT_EARPIECE;
- } else if (mode == AudioSystem::MODE_IN_COMMUNICATION) {
- if (!strncmp(curRxUCMDevice, SND_USE_CASE_DEV_SPEAKER, MAX_LEN(curRxUCMDevice, SND_USE_CASE_DEV_SPEAKER))) {
- devices &= ~AudioSystem::DEVICE_IN_BUILTIN_MIC;
- devices |= AudioSystem::DEVICE_IN_BACK_MIC;
- }
- }
- } else if (devices & AudioSystem::DEVICE_OUT_EARPIECE) {
- devices = devices | AudioSystem::DEVICE_IN_BUILTIN_MIC;
- } else if (devices & AudioSystem::DEVICE_OUT_SPEAKER) {
- devices = devices | (AudioSystem::DEVICE_IN_BACK_MIC |
- AudioSystem::DEVICE_OUT_SPEAKER);
- } else if ((devices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO) ||
- (devices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET) ||
- (devices & AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET)) {
- devices = devices | (AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET |
- AudioSystem::DEVICE_OUT_BLUETOOTH_SCO);
-#ifdef QCOM_ANC_HEADSET_ENABLED
- } else if ((devices & AudioSystem::DEVICE_OUT_ANC_HEADSET) ||
- (devices & AudioSystem::DEVICE_IN_ANC_HEADSET)) {
- devices = devices | (AudioSystem::DEVICE_OUT_ANC_HEADSET |
- AudioSystem::DEVICE_IN_ANC_HEADSET);
- } else if (devices & AudioSystem::DEVICE_OUT_ANC_HEADPHONE) {
- devices = devices | (AudioSystem::DEVICE_OUT_ANC_HEADPHONE |
- AudioSystem::DEVICE_IN_BUILTIN_MIC);
-#endif
- } else if (devices & AudioSystem::DEVICE_OUT_AUX_DIGITAL) {
- if (mode == AudioSystem::MODE_IN_CALL)
- devices = devices | (AudioSystem::DEVICE_IN_BACK_MIC |
- AudioSystem::DEVICE_OUT_SPEAKER);
- else
- devices = devices | (AudioSystem::DEVICE_OUT_AUX_DIGITAL |
- AudioSystem::DEVICE_IN_BACK_MIC);
-#ifdef QCOM_PROXY_DEVICE_ENABLED
- } else if ((devices & AudioSystem::DEVICE_OUT_PROXY) ||
- (devices & AudioSystem::DEVICE_IN_PROXY)) {
- devices = devices | (AudioSystem::DEVICE_OUT_PROXY |
- AudioSystem::DEVICE_IN_PROXY);
-#endif
- }
- }
-#ifdef QCOM_SSR_ENABLED
- if ((devices & AudioSystem::DEVICE_IN_BUILTIN_MIC) && ( 6 == handle->channels)) {
- if (!strncmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC, strlen(SND_USE_CASE_VERB_HIFI_REC))
- || !strncmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC, strlen(SND_USE_CASE_MOD_CAPTURE_MUSIC))) {
- ALOGV(" switchDevice , use ssr devices for channels:%d usecase:%s",handle->channels,handle->useCase);
- s_set_flags(SSRQMIC_FLAG);
- }
- }
-#endif
-
- rxDevice = getUCMDevice(devices & AudioSystem::DEVICE_OUT_ALL, 0, NULL);
- txDevice = getUCMDevice(devices & AudioSystem::DEVICE_IN_ALL, 1, rxDevice);
-
- if ((rxDevice != NULL) && (txDevice != NULL)) {
- if (((strncmp(rxDevice, curRxUCMDevice, MAX_STR_LEN)) ||
- (strncmp(txDevice, curTxUCMDevice, MAX_STR_LEN))) &&
- ((mode == AudioSystem::MODE_IN_CALL) ||
- (mode == AudioSystem::MODE_IN_COMMUNICATION)))
- inCallDevSwitch = true;
- }
-
-#ifdef QCOM_CSDCLIENT_ENABLED
- if (platform_is_Fusion3() && (inCallDevSwitch == true)) {
- if (csd_disable_device == NULL) {
- ALOGE("dlsym:Error:%s Loading csd_client_disable_device", dlerror());
- } else {
- err = csd_disable_device();
- if (err < 0)
- {
- ALOGE("csd_client_disable_device, failed, error %d", err);
- }
- }
- }
-#endif
-
- snd_use_case_get(handle->ucMgr, "_verb", (const char **)&use_case);
- mods_size = snd_use_case_get_list(handle->ucMgr, "_enamods", &mods_list);
- if (rxDevice != NULL) {
- if ((strncmp(curRxUCMDevice, "None", 4)) &&
- ((strncmp(rxDevice, curRxUCMDevice, MAX_STR_LEN)) || (inCallDevSwitch == true))) {
- if ((use_case != NULL) && (strncmp(use_case, SND_USE_CASE_VERB_INACTIVE,
- strlen(SND_USE_CASE_VERB_INACTIVE)))) {
- usecase_type = getUseCaseType(use_case);
- if (usecase_type & USECASE_TYPE_RX) {
- ALOGD("Deroute use case %s type is %d\n", use_case, usecase_type);
- strlcpy(useCaseNode.useCase, use_case, MAX_STR_LEN);
- snd_use_case_set(handle->ucMgr, "_verb", SND_USE_CASE_VERB_INACTIVE);
- mUseCaseList.push_front(useCaseNode);
- }
- }
- if (mods_size) {
- for(index = 0; index < mods_size; index++) {
- usecase_type = getUseCaseType(mods_list[index]);
- if (usecase_type & USECASE_TYPE_RX) {
- ALOGD("Deroute use case %s type is %d\n", mods_list[index], usecase_type);
- strlcpy(useCaseNode.useCase, mods_list[index], MAX_STR_LEN);
- snd_use_case_set(handle->ucMgr, "_dismod", mods_list[index]);
- mUseCaseList.push_back(useCaseNode);
- }
- }
- }
- snd_use_case_set(handle->ucMgr, "_disdev", curRxUCMDevice);
- }
- }
- if (txDevice != NULL) {
- if ((strncmp(curTxUCMDevice, "None", 4)) &&
- ((strncmp(txDevice, curTxUCMDevice, MAX_STR_LEN)) || (inCallDevSwitch == true))) {
- if ((use_case != NULL) && (strncmp(use_case, SND_USE_CASE_VERB_INACTIVE,
- strlen(SND_USE_CASE_VERB_INACTIVE)))) {
- usecase_type = getUseCaseType(use_case);
- if ((usecase_type & USECASE_TYPE_TX) && (!(usecase_type & USECASE_TYPE_RX))) {
- ALOGD("Deroute use case %s type is %d\n", use_case, usecase_type);
- strlcpy(useCaseNode.useCase, use_case, MAX_STR_LEN);
- snd_use_case_set(handle->ucMgr, "_verb", SND_USE_CASE_VERB_INACTIVE);
- mUseCaseList.push_front(useCaseNode);
- }
- }
- if (mods_size) {
- for(index = 0; index < mods_size; index++) {
- usecase_type = getUseCaseType(mods_list[index]);
- if ((usecase_type & USECASE_TYPE_TX) && (!(usecase_type & USECASE_TYPE_RX))) {
- ALOGD("Deroute use case %s type is %d\n", mods_list[index], usecase_type);
- strlcpy(useCaseNode.useCase, mods_list[index], MAX_STR_LEN);
- snd_use_case_set(handle->ucMgr, "_dismod", mods_list[index]);
- mUseCaseList.push_back(useCaseNode);
- }
- }
- }
- snd_use_case_set(handle->ucMgr, "_disdev", curTxUCMDevice);
- }
- }
- ALOGD("%s,rxDev:%s, txDev:%s, curRxDev:%s, curTxDev:%s\n", __FUNCTION__, rxDevice, txDevice, curRxUCMDevice, curTxUCMDevice);
-
- if (rxDevice != NULL) {
- snd_use_case_set(handle->ucMgr, "_enadev", rxDevice);
- strlcpy(curRxUCMDevice, rxDevice, sizeof(curRxUCMDevice));
-#ifdef QCOM_FM_ENABLED
- if (devices & AudioSystem::DEVICE_OUT_FM)
- s_set_fm_vol(fmVolume);
-#endif
- }
- if (txDevice != NULL) {
- snd_use_case_set(handle->ucMgr, "_enadev", txDevice);
- strlcpy(curTxUCMDevice, txDevice, sizeof(curTxUCMDevice));
- }
- for(ALSAUseCaseList::iterator it = mUseCaseList.begin(); it != mUseCaseList.end(); ++it) {
- ALOGD("Route use case %s\n", it->useCase);
- if ((use_case != NULL) && (strncmp(use_case, SND_USE_CASE_VERB_INACTIVE,
- strlen(SND_USE_CASE_VERB_INACTIVE))) && (!strncmp(use_case, it->useCase, MAX_UC_LEN))) {
- snd_use_case_set(handle->ucMgr, "_verb", it->useCase);
- } else {
- snd_use_case_set(handle->ucMgr, "_enamod", it->useCase);
- }
- }
- if (!mUseCaseList.empty())
- mUseCaseList.clear();
- if (use_case != NULL) {
- free(use_case);
- use_case = NULL;
- }
- ALOGD("switchDevice: curTxUCMDevivce %s curRxDevDevice %s", curTxUCMDevice, curRxUCMDevice);
-
- if (platform_is_Fusion3() && (inCallDevSwitch == true)) {
- /* get tx acdb id */
- memset(&ident,0,sizeof(ident));
- strlcpy(ident, "ACDBID/", sizeof(ident));
- strlcat(ident, curTxUCMDevice, sizeof(ident));
- tx_dev_id = snd_use_case_get(handle->ucMgr, ident, NULL);
-
- /* get rx acdb id */
- memset(&ident,0,sizeof(ident));
- strlcpy(ident, "ACDBID/", sizeof(ident));
- strlcat(ident, curRxUCMDevice, sizeof(ident));
- rx_dev_id = snd_use_case_get(handle->ucMgr, ident, NULL);
-
- if (((rx_dev_id == DEVICE_SPEAKER_MONO_RX_ACDB_ID ) || (rx_dev_id == DEVICE_SPEAKER_STEREO_RX_ACDB_ID ))
- && tx_dev_id == DEVICE_HANDSET_TX_ACDB_ID) {
- tx_dev_id = DEVICE_SPEAKER_TX_ACDB_ID;
- }
-
-#ifdef QCOM_CSDCLIENT_ENABLED
- ALOGV("rx_dev_id=%d, tx_dev_id=%d\n", rx_dev_id, tx_dev_id);
- if (csd_enable_device == NULL) {
- ALOGE("dlsym:Error:%s Loading csd_client_enable_device", dlerror());
- } else {
- err = csd_enable_device(rx_dev_id, tx_dev_id, mDevSettingsFlag);
- if (err < 0)
- {
- ALOGE("csd_client_disable_device failed, error %d", err);
- }
- }
-#endif
- }
-
- if (rxDevice != NULL) {
- free(rxDevice);
- rxDevice = NULL;
- }
- if (txDevice != NULL) {
- free(txDevice);
- txDevice = NULL;
- }
-}
-
-// ----------------------------------------------------------------------------
-
-static status_t s_init(alsa_device_t *module, ALSAHandleList &list)
-{
- ALOGV("s_init: Initializing devices for ALSA module");
-
- list.clear();
-
- return NO_ERROR;
-}
-
-static status_t s_open(alsa_handle_t *handle)
-{
- char *devName;
- unsigned flags = 0;
- int err = NO_ERROR;
-
- if(handle->devices & AudioSystem::DEVICE_OUT_AUX_DIGITAL) {
- err = setHDMIChannelCount();
- if(err != OK) {
- ALOGE("setHDMIChannelCount err = %d", err);
- return err;
- }
- }
- /* No need to call s_close for LPA as pcm device open and close is handled by LPAPlayer in stagefright */
- if((!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER)) || (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_LPA))
- ||(!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_TUNNEL)) || (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_TUNNEL))) {
- ALOGV("s_open: Opening LPA /Tunnel playback");
- return NO_ERROR;
- }
-
- s_close(handle);
-
- ALOGV("s_open: handle %p", handle);
-
- // ASoC multicomponent requires a valid path (frontend/backend) for
- // the device to be opened
-
- // The PCM stream is opened in blocking mode, per ALSA defaults. The
- // AudioFlinger seems to assume blocking mode too, so asynchronous mode
- // should not be used.
- if ((!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER)) ||
- (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_LPA)) ||
- (!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_TUNNEL)) ||
- (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_TUNNEL))) {
- ALOGV("LPA/tunnel use case");
- flags |= PCM_MMAP;
- flags |= DEBUG_ON;
- } else if ((!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI)) ||
- (!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI2)) ||
- (!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_MUSIC)) ||
- (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_LOWLATENCY_MUSIC)) ||
- (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_MUSIC2)) ||
- (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_MUSIC))) {
- ALOGV("Music case");
- flags = PCM_OUT;
- } else {
- flags = PCM_IN;
- }
- if (handle->channels == 1) {
- flags |= PCM_MONO;
- }
- else if (handle->channels == 4 ) {
- flags |= PCM_QUAD;
- } else if (handle->channels == 6 ) {
-#ifdef QCOM_SSR_ENABLED
- if (!strncmp(handle->useCase, SND_USE_CASE_VERB_HIFI_REC, strlen(SND_USE_CASE_VERB_HIFI_REC))
- || !strncmp(handle->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC, strlen(SND_USE_CASE_MOD_CAPTURE_MUSIC))) {
- flags |= PCM_QUAD;
- } else {
- flags |= PCM_5POINT1;
- }
-#else
- flags |= PCM_5POINT1;
-#endif
- }
- else {
- flags |= PCM_STEREO;
- }
- if (deviceName(handle, flags, &devName) < 0) {
- ALOGE("Failed to get pcm device node: %s", devName);
- return NO_INIT;
- }
- if (devName != NULL) {
- handle->handle = pcm_open(flags, (char*)devName);
- } else {
- ALOGE("Failed to get pcm device node");
- return NO_INIT;
- }
-
- if (!handle->handle) {
- ALOGE("s_open: Failed to initialize ALSA device '%s'", devName);
- free(devName);
- return NO_INIT;
- }
-
- handle->handle->flags = flags;
- err = setHardwareParams(handle);
-
- if (err == NO_ERROR) {
- err = setSoftwareParams(handle);
- }
-
- if(err != NO_ERROR) {
- ALOGE("Set HW/SW params failed: Closing the pcm stream");
- s_standby(handle);
- }
-
- free(devName);
- return NO_ERROR;
-}
-
-static status_t s_start_voip_call(alsa_handle_t *handle)
-{
-
- char* devName;
- char* devName1;
- unsigned flags = 0;
- int err = NO_ERROR;
- uint8_t voc_pkt[VOIP_BUFFER_MAX_SIZE];
-
- s_close(handle);
- flags = PCM_OUT;
- flags |= PCM_MONO;
- ALOGV("s_open:s_start_voip_call handle %p", handle);
-
- if (deviceName(handle, flags, &devName) < 0) {
- ALOGE("Failed to get pcm device node");
- return NO_INIT;
- }
-
- if (devName != NULL) {
- handle->handle = pcm_open(flags, (char*)devName);
- } else {
- ALOGE("Failed to get pcm device node");
- return NO_INIT;
- }
-
- if (!handle->handle) {
- free(devName);
- ALOGE("s_open: Failed to initialize ALSA device '%s'", devName);
- return NO_INIT;
- }
-
- if (!pcm_ready(handle->handle)) {
- ALOGE(" pcm ready failed");
- }
-
- handle->handle->flags = flags;
- err = setHardwareParams(handle);
-
- if (err == NO_ERROR) {
- err = setSoftwareParams(handle);
- }
-
- err = pcm_prepare(handle->handle);
- if(err != NO_ERROR) {
- ALOGE("DEVICE_OUT_DIRECTOUTPUT: pcm_prepare failed");
- }
-
- /* first write required start dsp */
- memset(&voc_pkt,0,sizeof(voc_pkt));
- pcm_write(handle->handle,&voc_pkt,handle->handle->period_size);
- handle->rxHandle = handle->handle;
- free(devName);
- ALOGV("s_open: DEVICE_IN_COMMUNICATION ");
- flags = PCM_IN;
- flags |= PCM_MONO;
- handle->handle = 0;
-
- if (deviceName(handle, flags, &devName1) < 0) {
- ALOGE("Failed to get pcm device node");
- return NO_INIT;
- }
- if (devName != NULL) {
- handle->handle = pcm_open(flags, (char*)devName1);
- } else {
- ALOGE("Failed to get pcm device node");
- return NO_INIT;
- }
-
- if (!handle->handle) {
- free(devName);
- ALOGE("s_open: Failed to initialize ALSA device '%s'", devName);
- return NO_INIT;
- }
-
- if (!pcm_ready(handle->handle)) {
- ALOGE(" pcm ready in failed");
- }
-
- handle->handle->flags = flags;
-
- err = setHardwareParams(handle);
-
- if (err == NO_ERROR) {
- err = setSoftwareParams(handle);
- }
-
-
- err = pcm_prepare(handle->handle);
- if(err != NO_ERROR) {
- ALOGE("DEVICE_IN_COMMUNICATION: pcm_prepare failed");
- }
-
- /* first read required start dsp */
- memset(&voc_pkt,0,sizeof(voc_pkt));
- pcm_read(handle->handle,&voc_pkt,handle->handle->period_size);
- return NO_ERROR;
-}
-
-static status_t s_start_voice_call(alsa_handle_t *handle)
-{
- char* devName;
- unsigned flags = 0;
- int err = NO_ERROR;
-
- ALOGV("s_start_voice_call: handle %p", handle);
-
- // ASoC multicomponent requires a valid path (frontend/backend) for
- // the device to be opened
-
- flags = PCM_OUT | PCM_MONO;
- if (deviceName(handle, flags, &devName) < 0) {
- ALOGE("Failed to get pcm device node");
- return NO_INIT;
- }
- if (devName != NULL) {
- handle->handle = pcm_open(flags, (char*)devName);
- } else {
- ALOGE("Failed to get pcm device node");
- return NO_INIT;
- }
- if (!handle->handle) {
- ALOGE("s_start_voicecall: could not open PCM device");
- goto Error;
- }
-
- handle->handle->flags = flags;
- err = setHardwareParams(handle);
- if(err != NO_ERROR) {
- ALOGE("s_start_voice_call: setHardwareParams failed");
- goto Error;
- }
-
- err = setSoftwareParams(handle);
- if(err != NO_ERROR) {
- ALOGE("s_start_voice_call: setSoftwareParams failed");
- goto Error;
- }
-
- err = pcm_prepare(handle->handle);
- if(err != NO_ERROR) {
- ALOGE("s_start_voice_call: pcm_prepare failed");
- goto Error;
- }
-
- if (ioctl(handle->handle->fd, SNDRV_PCM_IOCTL_START)) {
- ALOGE("s_start_voice_call:SNDRV_PCM_IOCTL_START failed\n");
- goto Error;
- }
-
- // Store the PCM playback device pointer in rxHandle
- handle->rxHandle = handle->handle;
- free(devName);
-
- // Open PCM capture device
- flags = PCM_IN | PCM_MONO;
- if (deviceName(handle, flags, &devName) < 0) {
- ALOGE("Failed to get pcm device node");
- goto Error;
- }
- if (devName != NULL) {
- handle->handle = pcm_open(flags, (char*)devName);
- } else {
- ALOGE("Failed to get pcm device node");
- return NO_INIT;
- }
- if (!handle->handle) {
- free(devName);
- goto Error;
- }
-
- handle->handle->flags = flags;
- err = setHardwareParams(handle);
- if(err != NO_ERROR) {
- ALOGE("s_start_voice_call: setHardwareParams failed");
- goto Error;
- }
-
- err = setSoftwareParams(handle);
- if(err != NO_ERROR) {
- ALOGE("s_start_voice_call: setSoftwareParams failed");
- goto Error;
- }
-
- err = pcm_prepare(handle->handle);
- if(err != NO_ERROR) {
- ALOGE("s_start_voice_call: pcm_prepare failed");
- goto Error;
- }
-
- if (ioctl(handle->handle->fd, SNDRV_PCM_IOCTL_START)) {
- ALOGE("s_start_voice_call:SNDRV_PCM_IOCTL_START failed\n");
- goto Error;
- }
-
- if (platform_is_Fusion3()) {
-#ifdef QCOM_CSDCLIENT_ENABLED
- if (csd_start_voice == NULL) {
- ALOGE("dlsym:Error:%s Loading csd_client_start_voice", dlerror());
- } else {
- err = csd_start_voice();
- if (err < 0){
- ALOGE("s_start_voice_call: csd_client error %d\n", err);
- goto Error;
- }
- }
-#endif
- }
-
- free(devName);
- return NO_ERROR;
-
-Error:
- ALOGE("s_start_voice_call: Failed to initialize ALSA device '%s'", devName);
- free(devName);
- s_close(handle);
- return NO_INIT;
-}
-
-static status_t s_start_fm(alsa_handle_t *handle)
-{
- char *devName;
- unsigned flags = 0;
- int err = NO_ERROR;
-
- ALOGV("s_start_fm: handle %p", handle);
-
- // ASoC multicomponent requires a valid path (frontend/backend) for
- // the device to be opened
-
- flags = PCM_OUT | PCM_STEREO;
- if (deviceName(handle, flags, &devName) < 0) {
- ALOGE("Failed to get pcm device node");
- goto Error;
- }
- if (devName != NULL) {
- handle->handle = pcm_open(flags, (char*)devName);
- } else {
- ALOGE("Failed to get pcm device node");
- return NO_INIT;
- }
- if (!handle->handle) {
- ALOGE("s_start_fm: could not open PCM device");
- goto Error;
- }
-
- handle->handle->flags = flags;
- err = setHardwareParams(handle);
- if(err != NO_ERROR) {
- ALOGE("s_start_fm: setHardwareParams failed");
- goto Error;
- }
-
- err = setSoftwareParams(handle);
- if(err != NO_ERROR) {
- ALOGE("s_start_fm: setSoftwareParams failed");
- goto Error;
- }
-
- err = pcm_prepare(handle->handle);
- if(err != NO_ERROR) {
- ALOGE("s_start_fm: setSoftwareParams failed");
- goto Error;
- }
-
- if (ioctl(handle->handle->fd, SNDRV_PCM_IOCTL_START)) {
- ALOGE("s_start_fm: SNDRV_PCM_IOCTL_START failed\n");
- goto Error;
- }
-
- // Store the PCM playback device pointer in rxHandle
- handle->rxHandle = handle->handle;
- free(devName);
-
- // Open PCM capture device
- flags = PCM_IN | PCM_STEREO;
- if (deviceName(handle, flags, &devName) < 0) {
- ALOGE("Failed to get pcm device node");
- goto Error;
- }
- if (devName != NULL) {
- handle->handle = pcm_open(flags, (char*)devName);
- } else {
- ALOGE("Failed to get pcm device node");
- return NO_INIT;
- }
- if (!handle->handle) {
- goto Error;
- }
-
- handle->handle->flags = flags;
- err = setHardwareParams(handle);
- if(err != NO_ERROR) {
- ALOGE("s_start_fm: setHardwareParams failed");
- goto Error;
- }
-
- err = setSoftwareParams(handle);
- if(err != NO_ERROR) {
- ALOGE("s_start_fm: setSoftwareParams failed");
- goto Error;
- }
-
- err = pcm_prepare(handle->handle);
- if(err != NO_ERROR) {
- ALOGE("s_start_fm: pcm_prepare failed");
- goto Error;
- }
-
- if (ioctl(handle->handle->fd, SNDRV_PCM_IOCTL_START)) {
- ALOGE("s_start_fm: SNDRV_PCM_IOCTL_START failed\n");
- goto Error;
- }
-
- s_set_fm_vol(fmVolume);
- free(devName);
- return NO_ERROR;
-
-Error:
- free(devName);
- s_close(handle);
- return NO_INIT;
-}
-
-static status_t s_set_fm_vol(int value)
-{
- status_t err = NO_ERROR;
-
- ALSAControl control("/dev/snd/controlC0");
- control.set("Internal FM RX Volume",value,0);
- fmVolume = value;
-
- return err;
-}
-
-static status_t s_set_lpa_vol(int value)
-{
- status_t err = NO_ERROR;
-
- ALSAControl control("/dev/snd/controlC0");
- control.set("LPA RX Volume",value,0);
-
- return err;
-}
-
-static status_t s_start(alsa_handle_t *handle)
-{
- status_t err = NO_ERROR;
-
- if(!handle->handle) {
- ALOGE("No active PCM driver to start");
- return err;
- }
-
- err = pcm_prepare(handle->handle);
-
- return err;
-}
-
-static status_t s_close(alsa_handle_t *handle)
-{
- int ret;
- status_t err = NO_ERROR;
- struct pcm *h = handle->rxHandle;
-
- handle->rxHandle = 0;
- ALOGV("s_close: handle %p h %p", handle, h);
- if (h) {
- if ((!strcmp(handle->useCase, SND_USE_CASE_VERB_VOICECALL) ||
- !strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_VOICE)) &&
- platform_is_Fusion3()) {
-#ifdef QCOM_CSDCLIENT_ENABLED
- if (csd_stop_voice == NULL) {
- ALOGE("dlsym:Error:%s Loading csd_client_disable_device", dlerror());
- } else {
- err = csd_stop_voice();
- if (err < 0) {
- ALOGE("s_close: csd_client error %d\n", err);
- }
- }
-#endif
- }
-
- ALOGV("s_close rxHandle\n");
- err = pcm_close(h);
- if(err != NO_ERROR) {
- ALOGE("s_close: pcm_close failed for rxHandle with err %d", err);
- }
- }
-
- h = handle->handle;
- handle->handle = 0;
-
- if (h) {
- ALOGV("s_close handle h %p\n", h);
- err = pcm_close(h);
- if(err != NO_ERROR) {
- ALOGE("s_close: pcm_close failed for handle with err %d", err);
- }
-
- disableDevice(handle);
- } else if((!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER)) ||
- (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_LPA)) ||
- (!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_TUNNEL)) ||
- (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_TUNNEL))){
- disableDevice(handle);
- }
-
- return err;
-}
-
-/*
- this is same as s_close, but don't discard
- the device/mode info. This way we can still
- close the device, hit idle and power-save, reopen the pcm
- for the same device/mode after resuming
-*/
-static status_t s_standby(alsa_handle_t *handle)
-{
- int ret;
- status_t err = NO_ERROR;
- struct pcm *h = handle->rxHandle;
- handle->rxHandle = 0;
- ALOGV("s_standby: handle %p h %p", handle, h);
- if (h) {
- ALOGD("s_standby rxHandle\n");
- err = pcm_close(h);
- if(err != NO_ERROR) {
- ALOGE("s_standby: pcm_close failed for rxHandle with err %d", err);
- }
- }
-
- h = handle->handle;
- handle->handle = 0;
-
- if (h) {
- ALOGV("s_standby handle h %p\n", h);
- err = pcm_close(h);
- if(err != NO_ERROR) {
- ALOGE("s_standby: pcm_close failed for handle with err %d", err);
- }
- disableDevice(handle);
- } else if((!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER)) ||
- (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_LPA)) ||
- (!strcmp(handle->useCase, SND_USE_CASE_VERB_HIFI_TUNNEL)) ||
- (!strcmp(handle->useCase, SND_USE_CASE_MOD_PLAY_TUNNEL))) {
- disableDevice(handle);
- }
-
- return err;
-}
-
-static status_t s_route(alsa_handle_t *handle, uint32_t devices, int mode)
-{
- status_t status = NO_ERROR;
-
- ALOGD("s_route: devices 0x%x in mode %d", devices, mode);
- callMode = mode;
- switchDevice(handle, devices, mode);
- return status;
-}
-
-int getUseCaseType(const char *useCase)
-{
- ALOGD("use case is %s\n", useCase);
- if (!strncmp(useCase, SND_USE_CASE_VERB_HIFI,
- MAX_LEN(useCase,SND_USE_CASE_VERB_HIFI)) ||
- !strncmp(useCase, SND_USE_CASE_VERB_HIFI2,
- MAX_LEN(useCase, SND_USE_CASE_VERB_HIFI2)) ||
- !strncmp(useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_MUSIC,
- MAX_LEN(useCase,SND_USE_CASE_VERB_HIFI_LOWLATENCY_MUSIC)) ||
- !strncmp(useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER,
- MAX_LEN(useCase,SND_USE_CASE_VERB_HIFI_LOW_POWER)) ||
- !strncmp(useCase, SND_USE_CASE_VERB_HIFI_TUNNEL,
- MAX_LEN(useCase,SND_USE_CASE_VERB_HIFI_TUNNEL)) ||
- !strncmp(useCase, SND_USE_CASE_VERB_HIFI2,
- MAX_LEN(useCase,SND_USE_CASE_VERB_HIFI2)) ||
- !strncmp(useCase, SND_USE_CASE_VERB_DIGITAL_RADIO,
- MAX_LEN(useCase,SND_USE_CASE_VERB_DIGITAL_RADIO)) ||
- !strncmp(useCase, SND_USE_CASE_MOD_PLAY_MUSIC,
- MAX_LEN(useCase,SND_USE_CASE_MOD_PLAY_MUSIC)) ||
- !strncmp(useCase, SND_USE_CASE_MOD_PLAY_MUSIC2,
- MAX_LEN(useCase, SND_USE_CASE_MOD_PLAY_MUSIC2)) ||
- !strncmp(useCase, SND_USE_CASE_MOD_PLAY_LOWLATENCY_MUSIC,
- MAX_LEN(useCase,SND_USE_CASE_MOD_PLAY_LOWLATENCY_MUSIC)) ||
- !strncmp(useCase, SND_USE_CASE_MOD_PLAY_MUSIC2,
- MAX_LEN(useCase,SND_USE_CASE_MOD_PLAY_MUSIC2)) ||
- !strncmp(useCase, SND_USE_CASE_MOD_PLAY_LPA,
- MAX_LEN(useCase,SND_USE_CASE_MOD_PLAY_LPA)) ||
- !strncmp(useCase, SND_USE_CASE_MOD_PLAY_TUNNEL,
- MAX_LEN(useCase,SND_USE_CASE_MOD_PLAY_TUNNEL)) ||
- !strncmp(useCase, SND_USE_CASE_MOD_PLAY_FM,
- MAX_LEN(useCase,SND_USE_CASE_MOD_PLAY_FM))) {
- return USECASE_TYPE_RX;
- } else if (!strncmp(useCase, SND_USE_CASE_VERB_HIFI_REC,
- MAX_LEN(useCase,SND_USE_CASE_VERB_HIFI_REC)) ||
- !strncmp(useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_REC,
- MAX_LEN(useCase,SND_USE_CASE_VERB_HIFI_LOWLATENCY_REC)) ||
- !strncmp(useCase, SND_USE_CASE_VERB_FM_REC,
- MAX_LEN(useCase,SND_USE_CASE_VERB_FM_REC)) ||
- !strncmp(useCase, SND_USE_CASE_VERB_FM_A2DP_REC,
- MAX_LEN(useCase,SND_USE_CASE_VERB_FM_A2DP_REC)) ||
- !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC,
- MAX_LEN(useCase,SND_USE_CASE_MOD_CAPTURE_MUSIC)) ||
- !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_LOWLATENCY_MUSIC,
- MAX_LEN(useCase,SND_USE_CASE_MOD_CAPTURE_LOWLATENCY_MUSIC)) ||
- !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_FM,
- MAX_LEN(useCase,SND_USE_CASE_MOD_CAPTURE_FM)) ||
- !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_A2DP_FM,
- MAX_LEN(useCase,SND_USE_CASE_MOD_CAPTURE_A2DP_FM))) {
- return USECASE_TYPE_TX;
- } else if (!strncmp(useCase, SND_USE_CASE_VERB_VOICECALL,
- MAX_LEN(useCase,SND_USE_CASE_VERB_VOICECALL)) ||
- !strncmp(useCase, SND_USE_CASE_VERB_IP_VOICECALL,
- MAX_LEN(useCase,SND_USE_CASE_VERB_IP_VOICECALL)) ||
- !strncmp(useCase, SND_USE_CASE_VERB_DL_REC,
- MAX_LEN(useCase,SND_USE_CASE_VERB_DL_REC)) ||
- !strncmp(useCase, SND_USE_CASE_VERB_UL_DL_REC,
- MAX_LEN(useCase,SND_USE_CASE_VERB_UL_DL_REC)) ||
- !strncmp(useCase, SND_USE_CASE_VERB_INCALL_REC,
- MAX_LEN(useCase,SND_USE_CASE_VERB_INCALL_REC)) ||
- !strncmp(useCase, SND_USE_CASE_MOD_PLAY_VOICE,
- MAX_LEN(useCase,SND_USE_CASE_MOD_PLAY_VOICE)) ||
- !strncmp(useCase, SND_USE_CASE_MOD_PLAY_VOIP,
- MAX_LEN(useCase,SND_USE_CASE_MOD_PLAY_VOIP)) ||
- !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_VOICE_DL,
- MAX_LEN(useCase,SND_USE_CASE_MOD_CAPTURE_VOICE_DL)) ||
- !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_VOICE_UL_DL,
- MAX_LEN(useCase,SND_USE_CASE_MOD_CAPTURE_VOICE_UL_DL)) ||
- !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_VOICE,
- MAX_LEN(useCase, SND_USE_CASE_MOD_CAPTURE_VOICE)) ||
- !strncmp(useCase, SND_USE_CASE_VERB_VOLTE,
- MAX_LEN(useCase,SND_USE_CASE_VERB_VOLTE)) ||
- !strncmp(useCase, SND_USE_CASE_MOD_PLAY_VOLTE,
- MAX_LEN(useCase, SND_USE_CASE_MOD_PLAY_VOLTE))) {
- return (USECASE_TYPE_RX | USECASE_TYPE_TX);
- } else {
- ALOGE("unknown use case %s\n", useCase);
- return 0;
- }
-}
-
-static void disableDevice(alsa_handle_t *handle)
-{
- unsigned usecase_type = 0;
- int i, mods_size;
- char *useCase;
- const char **mods_list;
-
- snd_use_case_get(handle->ucMgr, "_verb", (const char **)&useCase);
- if (useCase != NULL) {
- if (!strncmp(useCase, handle->useCase, MAX_UC_LEN)) {
- snd_use_case_set(handle->ucMgr, "_verb", SND_USE_CASE_VERB_INACTIVE);
- } else {
- snd_use_case_set(handle->ucMgr, "_dismod", handle->useCase);
- }
- free(useCase);
- snd_use_case_get(handle->ucMgr, "_verb", (const char **)&useCase);
- if (strncmp(useCase, SND_USE_CASE_VERB_INACTIVE,
- strlen(SND_USE_CASE_VERB_INACTIVE)))
- usecase_type |= getUseCaseType(useCase);
- mods_size = snd_use_case_get_list(handle->ucMgr, "_enamods", &mods_list);
- ALOGV("Number of modifiers %d\n", mods_size);
- if (mods_size) {
- for(i = 0; i < mods_size; i++) {
- ALOGV("index %d modifier %s\n", i, mods_list[i]);
- usecase_type |= getUseCaseType(mods_list[i]);
- }
- }
- ALOGV("usecase_type is %d\n", usecase_type);
- if (!(usecase_type & USECASE_TYPE_TX) && (strncmp(curTxUCMDevice, "None", 4)))
- snd_use_case_set(handle->ucMgr, "_disdev", curTxUCMDevice);
- if (!(usecase_type & USECASE_TYPE_RX) && (strncmp(curRxUCMDevice, "None", 4)))
- snd_use_case_set(handle->ucMgr, "_disdev", curRxUCMDevice);
- } else {
- ALOGE("Invalid state, no valid use case found to disable");
- }
- free(useCase);
-}
-
-char *getUCMDevice(uint32_t devices, int input, char *rxDevice)
-{
- bool is_tmus = s_is_tmus();
-
- if (!input) {
- if (!(mDevSettingsFlag & TTY_OFF) &&
- (callMode == AudioSystem::MODE_IN_CALL) &&
- ((devices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) ||
- (devices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE))) {
-#ifdef QCOM_ANC_HEADSET_ENABLED
- ||
- (devices & AudioSystem::DEVICE_OUT_ANC_HEADSET) ||
- (devices & AudioSystem::DEVICE_OUT_ANC_HEADPHONE))) {
-#endif
- if (mDevSettingsFlag & TTY_VCO) {
- return strdup(SND_USE_CASE_DEV_TTY_HEADSET_RX);
- } else if (mDevSettingsFlag & TTY_FULL) {
- return strdup(SND_USE_CASE_DEV_TTY_FULL_RX);
- } else if (mDevSettingsFlag & TTY_HCO) {
- return strdup(SND_USE_CASE_DEV_TTY_HANDSET_RX); /* HANDSET RX */
- }
- }else if ((devices & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET) ||
- (devices & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)) {
- return strdup(SND_USE_CASE_DEV_PROXY_RX); /* PROXY RX */
- } else if ((devices & AudioSystem::DEVICE_OUT_SPEAKER) &&
- ((devices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) ||
- (devices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE))) {
- if (mDevSettingsFlag & ANC_FLAG) {
- return strdup(SND_USE_CASE_DEV_SPEAKER_ANC_HEADSET); /* COMBO SPEAKER+ANC HEADSET RX */
- } else {
- return strdup(SND_USE_CASE_DEV_SPEAKER_HEADSET); /* COMBO SPEAKER+HEADSET RX */
- }
- } else if ((devices & AudioSystem::DEVICE_OUT_SPEAKER) &&
- ((devices & AudioSystem::DEVICE_OUT_AUX_DIGITAL))) {
- return strdup(SND_USE_CASE_DEV_HDMI_SPEAKER);
-#ifdef QCOM_ANC_HEADSET_ENABLED
- } else if ((devices & AudioSystem::DEVICE_OUT_SPEAKER) &&
- ((devices & AudioSystem::DEVICE_OUT_ANC_HEADSET) ||
- (devices & AudioSystem::DEVICE_OUT_ANC_HEADPHONE))) {
- return strdup(SND_USE_CASE_DEV_SPEAKER_ANC_HEADSET); /* COMBO SPEAKER+ANC HEADSET RX */
- } else if ((devices & AudioSystem::DEVICE_OUT_SPEAKER) &&
- (devices & AudioSystem::DEVICE_OUT_FM_TX)) {
- return strdup(SND_USE_CASE_DEV_SPEAKER_FM_TX); /* COMBO SPEAKER+FM_TX RX */
-#endif
- } else if (devices & AudioSystem::DEVICE_OUT_EARPIECE) {
- if (callMode == AudioSystem::MODE_IN_CALL) {
- if(is_tmus)
- return strdup(SND_USE_CASE_DEV_VOC_EARPIECE_TMUS); /* Voice HANDSET RX for TMUS */
- else
- return strdup(SND_USE_CASE_DEV_VOC_EARPIECE); /* Voice HANDSET RX */
- } else
- return strdup(SND_USE_CASE_DEV_EARPIECE); /* HANDSET RX */
- } else if (devices & AudioSystem::DEVICE_OUT_SPEAKER) {
- if (callMode == AudioSystem::MODE_IN_CALL) {
- return strdup(SND_USE_CASE_DEV_VOC_SPEAKER); /* Voice SPEAKER RX */
- } else
- return strdup(SND_USE_CASE_DEV_SPEAKER); /* SPEAKER RX */
- } else if ((devices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) ||
- (devices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE)) {
- if (mDevSettingsFlag & ANC_FLAG) {
- if (callMode == AudioSystem::MODE_IN_CALL) {
- return strdup(SND_USE_CASE_DEV_VOC_ANC_HEADSET); /* Voice ANC HEADSET RX */
- } else
- return strdup(SND_USE_CASE_DEV_ANC_HEADSET); /* ANC HEADSET RX */
- } else {
- if (callMode == AudioSystem::MODE_IN_CALL) {
- return strdup(SND_USE_CASE_DEV_VOC_HEADPHONE); /* Voice HEADSET RX */
- } else
- return strdup(SND_USE_CASE_DEV_HEADPHONES); /* HEADSET RX */
- }
-#ifdef QCOM_ANC_HEADSET_ENABLED
- } else if ((devices & AudioSystem::DEVICE_OUT_ANC_HEADSET) ||
- (devices & AudioSystem::DEVICE_OUT_ANC_HEADPHONE)) {
- if (callMode == AudioSystem::MODE_IN_CALL) {
- return strdup(SND_USE_CASE_DEV_VOC_ANC_HEADSET); /* Voice ANC HEADSET RX */
- } else
- return strdup(SND_USE_CASE_DEV_ANC_HEADSET); /* ANC HEADSET RX */
-#endif
- } else if ((devices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO) ||
- (devices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET) ||
- (devices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT)) {
- if (btsco_samplerate == BTSCO_RATE_16KHZ)
- return strdup(SND_USE_CASE_DEV_BTSCO_WB_RX); /* BTSCO RX*/
- else
- return strdup(SND_USE_CASE_DEV_BTSCO_NB_RX); /* BTSCO RX*/
- } else if ((devices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP) ||
- (devices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES) ||
-#ifdef QCOM_VOIP_ENABLED
- (devices & AudioSystem::DEVICE_OUT_DIRECTOUTPUT) ||
-#endif
- (devices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER)) {
- /* Nothing to be done, use current active device */
- if (strncmp(curRxUCMDevice, "None", 4)) {
- return strdup(curRxUCMDevice);
- }
- } else if (devices & AudioSystem::DEVICE_OUT_AUX_DIGITAL) {
- return strdup(SND_USE_CASE_DEV_HDMI); /* HDMI RX */
-#ifdef QCOM_PROXY_DEVICE_ENABLED
- } else if (devices & AudioSystem::DEVICE_OUT_PROXY) {
- return strdup(SND_USE_CASE_DEV_PROXY_RX); /* PROXY RX */
-#endif
-#ifdef QCOM_FM_TX_ENABLED
- } else if (devices & AudioSystem::DEVICE_OUT_FM_TX) {
- return strdup(SND_USE_CASE_DEV_FM_TX); /* FM Tx */
-#endif
- } else if (devices & AudioSystem::DEVICE_OUT_DEFAULT) {
- if (callMode == AudioSystem::MODE_IN_CALL) {
- return strdup(SND_USE_CASE_DEV_VOC_SPEAKER); /* Voice SPEAKER RX */
- } else
- return strdup(SND_USE_CASE_DEV_SPEAKER); /* SPEAKER RX */
- } else {
- ALOGD("No valid output device: %u", devices);
- }
- } else {
- if (!(mDevSettingsFlag & TTY_OFF) &&
- (callMode == AudioSystem::MODE_IN_CALL) &&
- ((devices & AudioSystem::DEVICE_IN_WIRED_HEADSET)
-#ifdef QCOM_ANC_HEADSET_ENABLED
- || (devices & AudioSystem::DEVICE_IN_ANC_HEADSET)
-#endif
- )) {
- if (mDevSettingsFlag & TTY_HCO) {
- return strdup(SND_USE_CASE_DEV_TTY_HEADSET_TX);
- } else if (mDevSettingsFlag & TTY_FULL) {
- return strdup(SND_USE_CASE_DEV_TTY_FULL_TX);
- } else if (mDevSettingsFlag & TTY_VCO) {
- if (!strncmp(mic_type, "analog", 6)) {
- return strdup(SND_USE_CASE_DEV_TTY_HANDSET_ANALOG_TX);
- } else {
- return strdup(SND_USE_CASE_DEV_TTY_HANDSET_TX);
- }
- }
- } else if (devices & AudioSystem::DEVICE_IN_BUILTIN_MIC) {
- if (!strncmp(mic_type, "analog", 6)) {
- return strdup(SND_USE_CASE_DEV_HANDSET); /* HANDSET TX */
- } else {
- if (mDevSettingsFlag & DMIC_FLAG) {
- if(callMode == AudioSystem::MODE_IN_CALL) {
-#ifdef USES_FLUENCE_INCALL
- if (fluence_mode == FLUENCE_MODE_ENDFIRE) {
- if(is_tmus)
- return strdup(SND_USE_CASE_DEV_DUAL_MIC_ENDFIRE_TMUS); /* DUALMIC EF TX */
- else
- return strdup(SND_USE_CASE_DEV_DUAL_MIC_ENDFIRE); /* DUALMIC EF TX */
- } else if (fluence_mode == FLUENCE_MODE_BROADSIDE) {
- return strdup(SND_USE_CASE_DEV_DUAL_MIC_BROADSIDE); /* DUALMIC BS TX */
- } else {
- return strdup(SND_USE_CASE_DEV_HANDSET); /* BUILTIN-MIC TX */
- }
-#endif
- }
- if (((rxDevice != NULL) &&
- !strncmp(rxDevice, SND_USE_CASE_DEV_SPEAKER,
- (strlen(SND_USE_CASE_DEV_SPEAKER)+1))) ||
- !strncmp(curRxUCMDevice, SND_USE_CASE_DEV_SPEAKER,
- (strlen(SND_USE_CASE_DEV_SPEAKER)+1))) {
- if (fluence_mode == FLUENCE_MODE_ENDFIRE) {
- if (input_source == AUDIO_SOURCE_VOICE_RECOGNITION) {
-// TODO: check if different ACDB settings are needed when speaker is enabled
- return strdup(SND_USE_CASE_DEV_DUAL_MIC_ENDFIRE_VREC);
- } else {
- return strdup(SND_USE_CASE_DEV_SPEAKER_DUAL_MIC_ENDFIRE);
- }
- } else if (fluence_mode == FLUENCE_MODE_BROADSIDE) {
- if (input_source == AUDIO_SOURCE_VOICE_RECOGNITION) {
- return strdup(SND_USE_CASE_DEV_DUAL_MIC_BROADSIDE_VREC);
- } else {
- return strdup(SND_USE_CASE_DEV_SPEAKER_DUAL_MIC_BROADSIDE);
- }
- }
- } else {
- if (fluence_mode == FLUENCE_MODE_ENDFIRE) {
- if (input_source == AUDIO_SOURCE_VOICE_RECOGNITION) {
- return strdup(SND_USE_CASE_DEV_DUAL_MIC_ENDFIRE_VREC);
- } else {
- return strdup(SND_USE_CASE_DEV_DUAL_MIC_ENDFIRE);
- }
- } else if (fluence_mode == FLUENCE_MODE_BROADSIDE) {
- if (input_source == AUDIO_SOURCE_VOICE_RECOGNITION) {
- return strdup(SND_USE_CASE_DEV_DUAL_MIC_BROADSIDE_VREC);
- } else {
- return strdup(SND_USE_CASE_DEV_DUAL_MIC_BROADSIDE);
- }
- }
- }
- } else if (mDevSettingsFlag & QMIC_FLAG){
- return strdup(SND_USE_CASE_DEV_QUAD_MIC);
- }
-#ifdef QCOM_SSR_ENABLED
- else if (mDevSettingsFlag & SSRQMIC_FLAG){
- ALOGV("return SSRQMIC_FLAG: 0x%x devices:0x%x",mDevSettingsFlag,devices);
- // Mapping for quad mic input device.
- return strdup(SND_USE_CASE_DEV_SSR_QUAD_MIC); /* SSR Quad MIC */
- }
-#endif
-#ifdef SEPERATED_AUDIO_INPUT
- if(input_source == AUDIO_SOURCE_VOICE_RECOGNITION) {
- return strdup(SND_USE_CASE_DEV_VOICE_RECOGNITION ); /* VOICE RECOGNITION TX */
- }
-#endif
- else {
- return strdup(SND_USE_CASE_DEV_HANDSET); /* BUILTIN-MIC TX */
- }
- }
- } else if (devices & AudioSystem::DEVICE_IN_AUX_DIGITAL) {
- return strdup(SND_USE_CASE_DEV_HDMI_TX); /* HDMI TX */
-#ifdef QCOM_ANC_HEADSET_ENABLED
- } else if (devices & AudioSystem::DEVICE_IN_ANC_HEADSET) {
- return strdup(SND_USE_CASE_DEV_HEADSET); /* HEADSET TX */
-#endif
- } else if (devices & AudioSystem::DEVICE_IN_WIRED_HEADSET) {
- if (callMode == AudioSystem::MODE_IN_CALL) {
- return strdup(SND_USE_CASE_DEV_VOC_HEADSET); /* Voice HEADSET TX */
- } else
- return strdup(SND_USE_CASE_DEV_HEADSET); /* HEADSET TX */
- } else if (devices & AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
- if (btsco_samplerate == BTSCO_RATE_16KHZ)
- return strdup(SND_USE_CASE_DEV_BTSCO_WB_TX); /* BTSCO TX*/
- else
- return strdup(SND_USE_CASE_DEV_BTSCO_NB_TX); /* BTSCO TX*/
-#ifdef QCOM_USBAUDIO_ENABLED
- } else if ((devices & AudioSystem::DEVICE_IN_ANLG_DOCK_HEADSET) ||
- (devices & AudioSystem::DEVICE_IN_PROXY)) {
- return strdup(SND_USE_CASE_DEV_PROXY_TX); /* PROXY TX */
-#endif
- } else if ((devices & AudioSystem::DEVICE_IN_COMMUNICATION) ||
- (devices & AudioSystem::DEVICE_IN_VOICE_CALL)) {
- /* Nothing to be done, use current active device */
- if (strncmp(curTxUCMDevice, "None", 4)) {
- return strdup(curTxUCMDevice);
- }
-#ifdef QCOM_FM_ENABLED
- } else if ((devices & AudioSystem::DEVICE_IN_FM_RX) ||
- (devices & AudioSystem::DEVICE_IN_FM_RX_A2DP)) {
- /* Nothing to be done, use current tx device or set dummy device */
- if (strncmp(curTxUCMDevice, "None", 4)) {
- return strdup(curTxUCMDevice);
- } else {
- return strdup(SND_USE_CASE_DEV_DUMMY_TX);
- }
-#endif
- } else if ((devices & AudioSystem::DEVICE_IN_AMBIENT) ||
- (devices & AudioSystem::DEVICE_IN_BACK_MIC)) {
- ALOGI("No proper mapping found with UCM device list, setting default");
- if (!strncmp(mic_type, "analog", 6)) {
- return strdup(SND_USE_CASE_DEV_HANDSET); /* HANDSET TX */
- } else {
- if (callMode == AudioSystem::MODE_IN_CALL) {
- return strdup(SND_USE_CASE_DEV_VOC_LINE); /* Voice BUILTIN-MIC TX */
-#ifdef SEPERATED_AUDIO_INPUT
- } else if(input_source == AUDIO_SOURCE_CAMCORDER) {
- return strdup(SND_USE_CASE_DEV_CAMCORDER_TX ); /* CAMCORDER TX */
-#endif
- } else
- return strdup(SND_USE_CASE_DEV_LINE); /* BUILTIN-MIC TX */
- }
- } else {
- ALOGD("No valid input device: %u", devices);
- }
- }
- return NULL;
-}
-
-void s_set_voice_volume(int vol)
-{
- int err = 0;
- ALOGV("s_set_voice_volume: volume %d", vol);
- ALSAControl control("/dev/snd/controlC0");
- control.set("Voice Rx Volume", vol, 0);
-
- if (platform_is_Fusion3()) {
-#ifdef QCOM_CSDCLIENT_ENABLED
- if (csd_volume == NULL) {
- ALOGE("dlsym:Error:%s Loading csd_client_volume", dlerror());
- } else {
- err = csd_volume(vol);
- if (err < 0) {
- ALOGE("s_set_voice_volume: csd_client error %d", err);
- }
- }
-#endif
- }
-}
-
-void s_set_volte_volume(int vol)
-{
- ALOGV("s_set_volte_volume: volume %d", vol);
- ALSAControl control("/dev/snd/controlC0");
- control.set("VoLTE Rx Volume", vol, 0);
-}
-
-
-void s_set_voip_volume(int vol)
-{
- ALOGV("s_set_voip_volume: volume %d", vol);
- ALSAControl control("/dev/snd/controlC0");
- control.set("Voip Rx Volume", vol, 0);
-}
-void s_set_mic_mute(int state)
-{
- int err = 0;
- ALOGV("s_set_mic_mute: state %d", state);
- ALSAControl control("/dev/snd/controlC0");
- control.set("Voice Tx Mute", state, 0);
-
- if (platform_is_Fusion3()) {
-#ifdef QCOM_CSDCLIENT_ENABLED
- if (csd_mic_mute == NULL) {
- ALOGE("dlsym:Error:%s Loading csd_mic_mute", dlerror());
- } else {
- err=csd_mic_mute(state);
- if (err < 0) {
- ALOGE("s_set_mic_mute: csd_client error %d", err);
- }
- }
-#endif
- }
-}
-void s_set_volte_mic_mute(int state)
-{
- ALOGV("s_set_volte_mic_mute: state %d", state);
- ALSAControl control("/dev/snd/controlC0");
- control.set("VoLTE Tx Mute", state, 0);
-}
-
-void s_set_voip_mic_mute(int state)
-{
- ALOGV("s_set_voip_mic_mute: state %d", state);
- ALSAControl control("/dev/snd/controlC0");
- control.set("Voip Tx Mute", state, 0);
-}
-
-void s_set_voip_config(int mode, int rate)
-{
- ALOGV("s_set_voip_config: mode %d,rate %d", mode, rate);
- ALSAControl control("/dev/snd/controlC0");
- char** setValues;
- setValues = (char**)malloc(2*sizeof(char*));
- if (setValues == NULL) {
- return;
- }
- setValues[0] = (char*)malloc(4*sizeof(char));
- if (setValues[0] == NULL) {
- free(setValues);
- return;
- }
-
- setValues[1] = (char*)malloc(8*sizeof(char));
- if (setValues[1] == NULL) {
- free(setValues);
- free(setValues[0]);
- return;
- }
-
- sprintf(setValues[0], "%d",mode);
- sprintf(setValues[1], "%d",rate);
-
- control.setext("Voip Mode Rate Config", 2, setValues);
- free(setValues[1]);
- free(setValues[0]);
- free(setValues);
- return;
-}
-
-void s_set_btsco_rate(int rate)
-{
- btsco_samplerate = rate;
-}
-
-void s_enable_wide_voice(bool flag)
-{
- int err = 0;
-
- ALOGV("s_enable_wide_voice: flag %d", flag);
- ALSAControl control("/dev/snd/controlC0");
- if(flag == true) {
- control.set("Widevoice Enable", 1, 0);
- } else {
- control.set("Widevoice Enable", 0, 0);
- }
-
- if (platform_is_Fusion3()) {
-#ifdef QCOM_CSDCLIENT_ENABLED
- if (csd_wide_voice == NULL) {
- ALOGE("dlsym:Error:%s Loading csd_wide_voice", dlerror());
- } else {
- err = csd_wide_voice(flag);
- if (err < 0) {
- ALOGE("enableWideVoice: csd_client_wide_voice error %d", err);
- }
- }
-#endif
- }
-}
-
-void s_set_voc_rec_mode(uint8_t mode)
-{
- ALOGV("s_set_voc_rec_mode: mode %d", mode);
- ALSAControl control("/dev/snd/controlC0");
- control.set("Incall Rec Mode", mode, 0);
-}
-
-void s_enable_fens(bool flag)
-{
- int err = 0;
-
- ALOGV("s_enable_fens: flag %d", flag);
- ALSAControl control("/dev/snd/controlC0");
- if(flag == true) {
- control.set("FENS Enable", 1, 0);
- } else {
- control.set("FENS Enable", 0, 0);
- }
-
- if (platform_is_Fusion3()) {
-#ifdef QCOM_CSDCLIENT_ENABLED
- if (csd_fens == NULL) {
- ALOGE("dlsym:Error:%s Loading csd_fens", dlerror());
- } else {
- err = csd_fens(flag);
- if (err < 0) {
- ALOGE("s_enable_fens: csd_client error %d", err);
- }
- }
-#endif
- }
-}
-
-void s_enable_slow_talk(bool flag)
-{
- int err = 0;
-
- ALOGV("s_enable_slow_talk: flag %d", flag);
- ALSAControl control("/dev/snd/controlC0");
- if(flag == true) {
- control.set("Slowtalk Enable", 1, 0);
- } else {
- control.set("Slowtalk Enable", 0, 0);
- }
-
- if (platform_is_Fusion3()) {
-#ifdef QCOM_CSDCLIENT_ENABLED
- if (csd_slow_talk == NULL) {
- ALOGE("dlsym:Error:%s Loading csd_slow_talk", dlerror());
- } else {
- err = csd_slow_talk(flag);
- if (err < 0) {
- ALOGE("s_enable_slow_talk: csd_client error %d", err);
- }
- }
-#endif
- }
-}
-
-void s_set_flags(uint32_t flags)
-{
- ALOGV("s_set_flags: flags %d", flags);
- mDevSettingsFlag = flags;
-}
-
-static status_t s_set_compressed_vol(int value)
-{
- status_t err = NO_ERROR;
-
- ALSAControl control("/dev/snd/controlC0");
- control.set("COMPRESSED RX Volume",value,0);
-
- return err;
-}
-
-#ifdef SEPERATED_AUDIO_INPUT
-void s_setInput(int input)
-{
- input_source = input;
- ALOGD("s_setInput() : input_source = %d",input_source);
-}
-#endif
-
-#ifdef QCOM_CSDCLIENT_ENABLED
-static void s_set_csd_handle(void* handle)
-{
- csd_handle = static_cast<void*>(handle);
- ALOGI("%s csd_handle: %p", __func__, csd_handle);
-
- csd_disable_device = (int (*)())::dlsym(csd_handle,"csd_client_disable_device");
- csd_enable_device = (int (*)(int,int,uint32_t))::dlsym(csd_handle,"csd_client_enable_device");
- csd_start_voice = (int (*)())::dlsym(csd_handle,"csd_client_start_voice");
- csd_stop_voice = (int (*)())::dlsym(csd_handle,"csd_client_stop_voice");
- csd_volume = (int (*)(int))::dlsym(csd_handle,"csd_client_volume");
- csd_mic_mute = (int (*)(int))::dlsym(csd_handle,"csd_client_mic_mute");
- csd_wide_voice = (int (*)(uint8_t))::dlsym(csd_handle,"csd_client_wide_voice");
- csd_fens = (int (*)(uint8_t))::dlsym(csd_handle,"csd_client_fens");
- csd_slow_talk = (int (*)(uint8_t))::dlsym(csd_handle,"csd_client_slow_talk");
-}
-#endif
-
-static bool s_is_tmus()
-{
- char value[128];
- bool ret = false;
-
- if (mccmnc == 0) {
- property_get("gsm.sim.operator.numeric",value,"0");
- mccmnc = atoi(value);
- }
-
- ALOGD("%s: mnc_mcc : %d", __FUNCTION__, mccmnc);
- switch(mccmnc)
- {
- //TMUS MCC(310), MNC(490, 260, 026)
- case 310490:
- case 310260:
- case 310026:
- ret = true;
- break;
- default:
- ret = false;
- break;
- }
-
- return ret;
-}
-
-}
diff --git a/legacy/alsa_sound/audio_hw_hal.cpp b/legacy/alsa_sound/audio_hw_hal.cpp
deleted file mode 100644
index 24e50d3..0000000
--- a/legacy/alsa_sound/audio_hw_hal.cpp
+++ /dev/null
@@ -1,783 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "qcom_audio_hw_hal"
-//#define LOG_NDEBUG 0
-
-#include <stdint.h>
-
-#include <hardware/hardware.h>
-#include <system/audio.h>
-#include <hardware/audio.h>
-
-#include <hardware_legacy/AudioHardwareInterface.h>
-#include <hardware_legacy/AudioSystemLegacy.h>
-
-namespace android_audio_legacy {
-
-extern "C" {
-
-struct qcom_audio_module {
- struct audio_module module;
-};
-
-struct qcom_audio_device {
- struct audio_hw_device device;
-
- struct AudioHardwareInterface *hwif;
-};
-
-struct qcom_stream_out {
- struct audio_stream_out stream;
-
- AudioStreamOut *qcom_out;
-};
-
-struct qcom_stream_in {
- struct audio_stream_in stream;
-
- AudioStreamIn *qcom_in;
-};
-
-
-enum {
- HAL_API_REV_1_0,
- HAL_API_REV_2_0,
- HAL_API_REV_NUM
-} hal_api_rev;
-
-static uint32_t audio_device_conv_table[][HAL_API_REV_NUM] =
-{
- /* output devices */
- { AudioSystem::DEVICE_OUT_EARPIECE, AUDIO_DEVICE_OUT_EARPIECE },
- { AudioSystem::DEVICE_OUT_SPEAKER, AUDIO_DEVICE_OUT_SPEAKER },
- { AudioSystem::DEVICE_OUT_WIRED_HEADSET, AUDIO_DEVICE_OUT_WIRED_HEADSET },
- { AudioSystem::DEVICE_OUT_WIRED_HEADPHONE, AUDIO_DEVICE_OUT_WIRED_HEADPHONE },
- { AudioSystem::DEVICE_OUT_BLUETOOTH_SCO, AUDIO_DEVICE_OUT_BLUETOOTH_SCO },
- { AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET, AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET },
- { AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT, AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT },
- { AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP, AUDIO_DEVICE_OUT_BLUETOOTH_A2DP },
- { AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES, AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES },
- { AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER, AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER },
- { AudioSystem::DEVICE_OUT_AUX_DIGITAL, AUDIO_DEVICE_OUT_AUX_DIGITAL },
- { AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET, AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET },
- { AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET, AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET },
- { AudioSystem::DEVICE_OUT_DEFAULT, AUDIO_DEVICE_OUT_DEFAULT },
-#ifdef QCOM_ANC_HEADSET_ENABLED
- { AudioSystem::DEVICE_OUT_ANC_HEADSET, AUDIO_DEVICE_OUT_ANC_HEADSET },
- { AudioSystem::DEVICE_OUT_ANC_HEADPHONE, AUDIO_DEVICE_OUT_ANC_HEADPHONE },
-#endif
-#ifdef QCOM_FM_ENABLED
- { AudioSystem::DEVICE_OUT_FM, AUDIO_DEVICE_OUT_FM },
-#endif
-#ifdef QCOM_FM_TX_ENABLED
- { AudioSystem::DEVICE_OUT_FM_TX, AUDIO_DEVICE_OUT_FM_TX },
-#endif
-#ifdef QCOM_VOIP_ENABLED
- { AudioSystem::DEVICE_OUT_DIRECTOUTPUT, AUDIO_DEVICE_OUT_DIRECTOUTPUT },
-#endif
-#ifdef QCOM_PROXY_DEVICE_ENABLED
- { AudioSystem::DEVICE_OUT_PROXY, AUDIO_DEVICE_OUT_PROXY },
-#endif
- /* input devices */
- { AudioSystem::DEVICE_IN_COMMUNICATION, AUDIO_DEVICE_IN_COMMUNICATION },
- { AudioSystem::DEVICE_IN_AMBIENT, AUDIO_DEVICE_IN_AMBIENT },
- { AudioSystem::DEVICE_IN_BUILTIN_MIC, AUDIO_DEVICE_IN_BUILTIN_MIC },
- { AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET, AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET },
- { AudioSystem::DEVICE_IN_WIRED_HEADSET, AUDIO_DEVICE_IN_WIRED_HEADSET },
- { AudioSystem::DEVICE_IN_AUX_DIGITAL, AUDIO_DEVICE_IN_AUX_DIGITAL },
- { AudioSystem::DEVICE_IN_VOICE_CALL, AUDIO_DEVICE_IN_VOICE_CALL },
- { AudioSystem::DEVICE_IN_BACK_MIC, AUDIO_DEVICE_IN_BACK_MIC },
- { AudioSystem::DEVICE_IN_DEFAULT, AUDIO_DEVICE_IN_DEFAULT },
-#ifdef QCOM_ANC_HEADSET_ENABLED
- { AudioSystem::DEVICE_IN_ANC_HEADSET, AUDIO_DEVICE_IN_ANC_HEADSET },
-#endif
-#ifdef QCOM_FM_ENABLED
- { AudioSystem::DEVICE_IN_FM_RX, AUDIO_DEVICE_IN_FM_RX },
- { AudioSystem::DEVICE_IN_FM_RX_A2DP, AUDIO_DEVICE_IN_FM_RX_A2DP },
-#endif
-};
-
-static uint32_t convert_audio_device(uint32_t from_device, int from_rev, int to_rev)
-{
- const uint32_t k_num_devices = sizeof(audio_device_conv_table)/sizeof(uint32_t)/HAL_API_REV_NUM;
- uint32_t to_device = AUDIO_DEVICE_NONE;
- uint32_t in_bit = 0;
-
- if (from_rev != HAL_API_REV_1_0) {
- in_bit = from_device & AUDIO_DEVICE_BIT_IN;
- from_device &= ~AUDIO_DEVICE_BIT_IN;
- }
-
- while (from_device) {
- uint32_t i = 31 - __builtin_clz(from_device);
- uint32_t cur_device = (1 << i) | in_bit;
-
- for (i = 0; i < k_num_devices; i++) {
- if (audio_device_conv_table[i][from_rev] == cur_device) {
- to_device |= audio_device_conv_table[i][to_rev];
- break;
- }
- }
- from_device &= ~cur_device;
- }
- return to_device;
-}
-
-/** audio_stream_out implementation **/
-static uint32_t out_get_sample_rate(const struct audio_stream *stream)
-{
- const struct qcom_stream_out *out =
- reinterpret_cast<const struct qcom_stream_out *>(stream);
- return out->qcom_out->sampleRate();
-}
-
-static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate)
-{
- struct qcom_stream_out *out =
- reinterpret_cast<struct qcom_stream_out *>(stream);
-
- ALOGE("(%s:%d) %s: Implement me!", __FILE__, __LINE__, __func__);
- /* TODO: implement this */
- return 0;
-}
-
-static size_t out_get_buffer_size(const struct audio_stream *stream)
-{
- const struct qcom_stream_out *out =
- reinterpret_cast<const struct qcom_stream_out *>(stream);
- return out->qcom_out->bufferSize();
-}
-
-static audio_channel_mask_t out_get_channels(const struct audio_stream *stream)
-{
- const struct qcom_stream_out *out =
- reinterpret_cast<const struct qcom_stream_out *>(stream);
- return out->qcom_out->channels();
-}
-
-static audio_format_t out_get_format(const struct audio_stream *stream)
-{
- const struct qcom_stream_out *out =
- reinterpret_cast<const struct qcom_stream_out *>(stream);
- return (audio_format_t)out->qcom_out->format();
-}
-
-static int out_set_format(struct audio_stream *stream, audio_format_t format)
-{
- struct qcom_stream_out *out =
- reinterpret_cast<struct qcom_stream_out *>(stream);
- ALOGE("(%s:%d) %s: Implement me!", __FILE__, __LINE__, __func__);
- /* TODO: implement me */
- return 0;
-}
-
-static int out_standby(struct audio_stream *stream)
-{
- struct qcom_stream_out *out =
- reinterpret_cast<struct qcom_stream_out *>(stream);
- return out->qcom_out->standby();
-}
-
-static int out_dump(const struct audio_stream *stream, int fd)
-{
- const struct qcom_stream_out *out =
- reinterpret_cast<const struct qcom_stream_out *>(stream);
- Vector<String16> args;
- return out->qcom_out->dump(fd, args);
-}
-
-static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
-{
- struct qcom_stream_out *out =
- reinterpret_cast<struct qcom_stream_out *>(stream);
- int val;
- String8 s8 = String8(kvpairs);
- AudioParameter parms = AudioParameter(String8(kvpairs));
-
- if (parms.getInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), val) == NO_ERROR) {
- val = convert_audio_device(val, HAL_API_REV_2_0, HAL_API_REV_1_0);
- parms.remove(String8(AUDIO_PARAMETER_STREAM_ROUTING));
- parms.addInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), val);
- s8 = parms.toString();
- }
-
- return out->qcom_out->setParameters(s8);
-}
-
-static char * out_get_parameters(const struct audio_stream *stream, const char *keys)
-{
- const struct qcom_stream_out *out =
- reinterpret_cast<const struct qcom_stream_out *>(stream);
- String8 s8;
- int val;
-
- s8 = out->qcom_out->getParameters(String8(keys));
-
- AudioParameter parms = AudioParameter(s8);
- if (parms.getInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), val) == NO_ERROR) {
- val = convert_audio_device(val, HAL_API_REV_1_0, HAL_API_REV_2_0);
- parms.remove(String8(AUDIO_PARAMETER_STREAM_ROUTING));
- parms.addInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), val);
- s8 = parms.toString();
- }
-
- return strdup(s8.string());
-}
-
-static uint32_t out_get_latency(const struct audio_stream_out *stream)
-{
- const struct qcom_stream_out *out =
- reinterpret_cast<const struct qcom_stream_out *>(stream);
- return out->qcom_out->latency();
-}
-
-static int out_set_volume(struct audio_stream_out *stream, float left,
- float right)
-{
- struct qcom_stream_out *out =
- reinterpret_cast<struct qcom_stream_out *>(stream);
- return out->qcom_out->setVolume(left, right);
-}
-
-static ssize_t out_write(struct audio_stream_out *stream, const void* buffer,
- size_t bytes)
-{
- struct qcom_stream_out *out =
- reinterpret_cast<struct qcom_stream_out *>(stream);
- return out->qcom_out->write(buffer, bytes);
-}
-
-static int out_get_render_position(const struct audio_stream_out *stream,
- uint32_t *dsp_frames)
-{
- const struct qcom_stream_out *out =
- reinterpret_cast<const struct qcom_stream_out *>(stream);
- return out->qcom_out->getRenderPosition(dsp_frames);
-}
-
-static int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
-{
- return 0;
-}
-
-static int out_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
-{
- return 0;
-}
-
-static int out_get_next_write_timestamp(const struct audio_stream_out *stream,
- int64_t *timestamp)
-{
- const struct qcom_stream_out *out =
- reinterpret_cast<const struct qcom_stream_out *>(stream);
- return out->qcom_out->getNextWriteTimestamp(timestamp);
-}
-
-/** audio_stream_in implementation **/
-static uint32_t in_get_sample_rate(const struct audio_stream *stream)
-{
- const struct qcom_stream_in *in =
- reinterpret_cast<const struct qcom_stream_in *>(stream);
- return in->qcom_in->sampleRate();
-}
-
-static int in_set_sample_rate(struct audio_stream *stream, uint32_t rate)
-{
- struct qcom_stream_in *in =
- reinterpret_cast<struct qcom_stream_in *>(stream);
-
- ALOGE("(%s:%d) %s: Implement me!", __FILE__, __LINE__, __func__);
- /* TODO: implement this */
- return 0;
-}
-
-static size_t in_get_buffer_size(const struct audio_stream *stream)
-{
- const struct qcom_stream_in *in =
- reinterpret_cast<const struct qcom_stream_in *>(stream);
- return in->qcom_in->bufferSize();
-}
-
-static audio_channel_mask_t in_get_channels(const struct audio_stream *stream)
-{
- const struct qcom_stream_in *in =
- reinterpret_cast<const struct qcom_stream_in *>(stream);
- return in->qcom_in->channels();
-}
-
-static audio_format_t in_get_format(const struct audio_stream *stream)
-{
- const struct qcom_stream_in *in =
- reinterpret_cast<const struct qcom_stream_in *>(stream);
- return (audio_format_t)in->qcom_in->format();
-}
-
-static int in_set_format(struct audio_stream *stream, audio_format_t format)
-{
- struct qcom_stream_in *in =
- reinterpret_cast<struct qcom_stream_in *>(stream);
- ALOGE("(%s:%d) %s: Implement me!", __FILE__, __LINE__, __func__);
- /* TODO: implement me */
- return 0;
-}
-
-static int in_standby(struct audio_stream *stream)
-{
- struct qcom_stream_in *in = reinterpret_cast<struct qcom_stream_in *>(stream);
- return in->qcom_in->standby();
-}
-
-static int in_dump(const struct audio_stream *stream, int fd)
-{
- const struct qcom_stream_in *in =
- reinterpret_cast<const struct qcom_stream_in *>(stream);
- Vector<String16> args;
- return in->qcom_in->dump(fd, args);
-}
-
-static int in_set_parameters(struct audio_stream *stream, const char *kvpairs)
-{
- struct qcom_stream_in *in =
- reinterpret_cast<struct qcom_stream_in *>(stream);
- int val;
- AudioParameter parms = AudioParameter(String8(kvpairs));
- String8 s8 = String8(kvpairs);
-
- if (parms.getInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), val) == NO_ERROR) {
- val = convert_audio_device(val, HAL_API_REV_2_0, HAL_API_REV_1_0);
- parms.remove(String8(AUDIO_PARAMETER_STREAM_ROUTING));
- parms.addInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), val);
- s8 = parms.toString();
- }
-
- return in->qcom_in->setParameters(s8);
-}
-
-static char * in_get_parameters(const struct audio_stream *stream,
- const char *keys)
-{
- const struct qcom_stream_in *in =
- reinterpret_cast<const struct qcom_stream_in *>(stream);
- String8 s8;
- int val;
-
- s8 = in->qcom_in->getParameters(String8(keys));
-
- AudioParameter parms = AudioParameter(s8);
- if (parms.getInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), val) == NO_ERROR) {
- val = convert_audio_device(val, HAL_API_REV_1_0, HAL_API_REV_2_0);
- parms.remove(String8(AUDIO_PARAMETER_STREAM_ROUTING));
- parms.addInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), val);
- s8 = parms.toString();
- }
-
- return strdup(s8.string());
-}
-
-static int in_set_gain(struct audio_stream_in *stream, float gain)
-{
- struct qcom_stream_in *in =
- reinterpret_cast<struct qcom_stream_in *>(stream);
- return in->qcom_in->setGain(gain);
-}
-
-static ssize_t in_read(struct audio_stream_in *stream, void* buffer,
- size_t bytes)
-{
- struct qcom_stream_in *in =
- reinterpret_cast<struct qcom_stream_in *>(stream);
- return in->qcom_in->read(buffer, bytes);
-}
-
-static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream)
-{
- struct qcom_stream_in *in =
- reinterpret_cast<struct qcom_stream_in *>(stream);
- return in->qcom_in->getInputFramesLost();
-}
-
-static int in_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
-{
- const struct qcom_stream_in *in =
- reinterpret_cast<const struct qcom_stream_in *>(stream);
- return in->qcom_in->addAudioEffect(effect);
-}
-
-static int in_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
-{
- const struct qcom_stream_in *in =
- reinterpret_cast<const struct qcom_stream_in *>(stream);
- return in->qcom_in->removeAudioEffect(effect);
-}
-
-/** audio_hw_device implementation **/
-static inline struct qcom_audio_device * to_ladev(struct audio_hw_device *dev)
-{
- return reinterpret_cast<struct qcom_audio_device *>(dev);
-}
-
-static inline const struct qcom_audio_device * to_cladev(const struct audio_hw_device *dev)
-{
- return reinterpret_cast<const struct qcom_audio_device *>(dev);
-}
-
-static int adev_init_check(const struct audio_hw_device *dev)
-{
- const struct qcom_audio_device *qadev = to_cladev(dev);
-
- return qadev->hwif->initCheck();
-}
-
-static int adev_set_voice_volume(struct audio_hw_device *dev, float volume)
-{
- struct qcom_audio_device *qadev = to_ladev(dev);
- return qadev->hwif->setVoiceVolume(volume);
-}
-
-static int adev_set_master_volume(struct audio_hw_device *dev, float volume)
-{
- struct qcom_audio_device *qadev = to_ladev(dev);
- return qadev->hwif->setMasterVolume(volume);
-}
-
-static int adev_get_master_volume(struct audio_hw_device *dev, float *volume) {
-
- struct qcom_audio_device *qadev = to_ladev(dev);
- return qadev->hwif->getMasterVolume(volume);
-}
-
-#ifdef QCOM_FM_ENABLED
-static int adev_set_fm_volume(struct audio_hw_device *dev, float volume)
-{
- struct qcom_audio_device *qadev = to_ladev(dev);
- return qadev->hwif->setFmVolume(volume);
-}
-#endif
-
-static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode)
-{
- struct qcom_audio_device *qadev = to_ladev(dev);
- return qadev->hwif->setMode(mode);
-}
-
-static int adev_set_mic_mute(struct audio_hw_device *dev, bool state)
-{
- struct qcom_audio_device *qadev = to_ladev(dev);
- return qadev->hwif->setMicMute(state);
-}
-
-static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state)
-{
- const struct qcom_audio_device *qadev = to_cladev(dev);
- return qadev->hwif->getMicMute(state);
-}
-
-static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
-{
- struct qcom_audio_device *qadev = to_ladev(dev);
- return qadev->hwif->setParameters(String8(kvpairs));
-}
-
-static char * adev_get_parameters(const struct audio_hw_device *dev,
- const char *keys)
-{
- const struct qcom_audio_device *qadev = to_cladev(dev);
- String8 s8;
-
- s8 = qadev->hwif->getParameters(String8(keys));
- return strdup(s8.string());
-}
-
-static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev,
- const struct audio_config *config)
-{
- const struct qcom_audio_device *qadev = to_cladev(dev);
- uint8_t channelCount = popcount(config->channel_mask);
- return qadev->hwif->getInputBufferSize(config->sample_rate, config->format, channelCount);
-}
-
-#ifdef QCOM_TUNNEL_LPA_ENABLED
-static int adev_open_output_session(struct audio_hw_device *dev,
- uint32_t devices,
- int *format,
- int sessionId,
- uint32_t samplingRate,
- uint32_t channels,
- struct audio_stream_out **stream_out)
-{
- struct qcom_audio_device *qadev = to_ladev(dev);
- status_t status;
- struct qcom_stream_out *out;
- int ret;
-
- out = (struct qcom_stream_out *)calloc(1, sizeof(*out));
- if (!out)
- return -ENOMEM;
-
- out->qcom_out = qadev->hwif->openOutputSession(devices, format,&status,sessionId,samplingRate,channels);
- if (!out->qcom_out) {
- ret = status;
- goto err_open;
- }
-
- out->stream.common.standby = out_standby;
- out->stream.common.set_parameters = out_set_parameters;
- out->stream.set_volume = out_set_volume;
-
- *stream_out = &out->stream;
- return 0;
-
-err_open:
- free(out);
- *stream_out = NULL;
- return ret;
-}
-#endif
-
-static int adev_open_output_stream(struct audio_hw_device *dev,
- audio_io_handle_t handle,
- audio_devices_t devices,
- audio_output_flags_t flags,
- struct audio_config *config,
- struct audio_stream_out **stream_out)
-{
- struct qcom_audio_device *qadev = to_ladev(dev);
- status_t status;
- struct qcom_stream_out *out;
- int ret;
-
- out = (struct qcom_stream_out *)calloc(1, sizeof(*out));
- if (!out)
- return -ENOMEM;
-
- devices = convert_audio_device(devices, HAL_API_REV_2_0, HAL_API_REV_1_0);
- status = static_cast<audio_output_flags_t> (flags);
-
- out->qcom_out = qadev->hwif->openOutputStream(devices,
- (int *)&config->format,
- &config->channel_mask,
- &config->sample_rate,
- &status);
- if (!out->qcom_out) {
- ret = status;
- goto err_open;
- }
-
- out->stream.common.get_sample_rate = out_get_sample_rate;
- out->stream.common.set_sample_rate = out_set_sample_rate;
- out->stream.common.get_buffer_size = out_get_buffer_size;
- out->stream.common.get_channels = out_get_channels;
- out->stream.common.get_format = out_get_format;
- out->stream.common.set_format = out_set_format;
- out->stream.common.standby = out_standby;
- out->stream.common.dump = out_dump;
- out->stream.common.set_parameters = out_set_parameters;
- out->stream.common.get_parameters = out_get_parameters;
- out->stream.common.add_audio_effect = out_add_audio_effect;
- out->stream.common.remove_audio_effect = out_remove_audio_effect;
- out->stream.get_latency = out_get_latency;
- out->stream.set_volume = out_set_volume;
- out->stream.write = out_write;
- out->stream.get_render_position = out_get_render_position;
- out->stream.get_next_write_timestamp = out_get_next_write_timestamp;
-
- *stream_out = &out->stream;
- return 0;
-
-err_open:
- free(out);
- *stream_out = NULL;
- return ret;
-}
-
-static void adev_close_output_stream(struct audio_hw_device *dev,
- struct audio_stream_out* stream)
-{
- struct qcom_audio_device *qadev = to_ladev(dev);
- struct qcom_stream_out *out = reinterpret_cast<struct qcom_stream_out *>(stream);
-
- qadev->hwif->closeOutputStream(out->qcom_out);
- free(out);
-}
-
-/** This method creates and opens the audio hardware input stream */
-static int adev_open_input_stream(struct audio_hw_device *dev,
- audio_io_handle_t handle,
- audio_devices_t devices,
- audio_config *config,
- audio_stream_in **stream_in)
-{
- struct qcom_audio_device *qadev = to_ladev(dev);
- status_t status;
- struct qcom_stream_in *in;
- int ret;
-
- in = (struct qcom_stream_in *)calloc(1, sizeof(*in));
- if (!in)
- return -ENOMEM;
-
- devices = convert_audio_device(devices, HAL_API_REV_2_0, HAL_API_REV_1_0);
-
- in->qcom_in = qadev->hwif->openInputStream(devices, (int *)&config->format,
- &config->channel_mask,
- &config->sample_rate,
- &status,
- (AudioSystem::audio_in_acoustics)0);
- if (!in->qcom_in) {
- ret = status;
- goto err_open;
- }
-
- in->stream.common.get_sample_rate = in_get_sample_rate;
- in->stream.common.set_sample_rate = in_set_sample_rate;
- in->stream.common.get_buffer_size = in_get_buffer_size;
- in->stream.common.get_channels = in_get_channels;
- in->stream.common.get_format = in_get_format;
- in->stream.common.set_format = in_set_format;
- in->stream.common.standby = in_standby;
- in->stream.common.dump = in_dump;
- in->stream.common.set_parameters = in_set_parameters;
- in->stream.common.get_parameters = in_get_parameters;
- in->stream.common.add_audio_effect = in_add_audio_effect;
- in->stream.common.remove_audio_effect = in_remove_audio_effect;
- in->stream.set_gain = in_set_gain;
- in->stream.read = in_read;
- in->stream.get_input_frames_lost = in_get_input_frames_lost;
-
- *stream_in = &in->stream;
- return 0;
-
-err_open:
- free(in);
- *stream_in = NULL;
- return ret;
-}
-
-static void adev_close_input_stream(struct audio_hw_device *dev,
- struct audio_stream_in *stream)
-{
- struct qcom_audio_device *qadev = to_ladev(dev);
- struct qcom_stream_in *in =
- reinterpret_cast<struct qcom_stream_in *>(stream);
-
- qadev->hwif->closeInputStream(in->qcom_in);
- free(in);
-}
-
-static int adev_dump(const struct audio_hw_device *dev, int fd)
-{
- const struct qcom_audio_device *qadev = to_cladev(dev);
- Vector<String16> args;
-
- return qadev->hwif->dumpState(fd, args);
-}
-
-static int qcom_adev_close(hw_device_t* device)
-{
- struct audio_hw_device *hwdev =
- reinterpret_cast<struct audio_hw_device *>(device);
- struct qcom_audio_device *qadev = to_ladev(hwdev);
-
- if (!qadev)
- return 0;
-
- if (qadev->hwif)
- delete qadev->hwif;
-
- free(qadev);
- return 0;
-}
-
-static int qcom_adev_open(const hw_module_t* module, const char* name,
- hw_device_t** device)
-{
- struct qcom_audio_device *qadev;
- int ret;
-
- if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0)
- return -EINVAL;
-
- qadev = (struct qcom_audio_device *)calloc(1, sizeof(*qadev));
- if (!qadev)
- return -ENOMEM;
-
- qadev->device.common.tag = HARDWARE_DEVICE_TAG;
- qadev->device.common.version = AUDIO_DEVICE_API_VERSION_2_0;
- qadev->device.common.module = const_cast<hw_module_t*>(module);
- qadev->device.common.close = qcom_adev_close;
-
- qadev->device.init_check = adev_init_check;
- qadev->device.set_voice_volume = adev_set_voice_volume;
- qadev->device.set_master_volume = adev_set_master_volume;
- qadev->device.get_master_volume = adev_get_master_volume;
-#ifdef QCOM_FM_ENABLED
- qadev->device.set_fm_volume = adev_set_fm_volume;
-#endif
- qadev->device.set_mode = adev_set_mode;
- qadev->device.set_mic_mute = adev_set_mic_mute;
- qadev->device.get_mic_mute = adev_get_mic_mute;
- qadev->device.set_parameters = adev_set_parameters;
- qadev->device.get_parameters = adev_get_parameters;
- qadev->device.get_input_buffer_size = adev_get_input_buffer_size;
- qadev->device.open_output_stream = adev_open_output_stream;
-#ifdef QCOM_TUNNEL_LPA_ENABLED
- qadev->device.open_output_session = adev_open_output_session;
-#endif
- qadev->device.close_output_stream = adev_close_output_stream;
- qadev->device.open_input_stream = adev_open_input_stream;
- qadev->device.close_input_stream = adev_close_input_stream;
- qadev->device.dump = adev_dump;
-
- qadev->hwif = createAudioHardware();
- if (!qadev->hwif) {
- ret = -EIO;
- goto err_create_audio_hw;
- }
-
- *device = &qadev->device.common;
-
- return 0;
-
-err_create_audio_hw:
- free(qadev);
- return ret;
-}
-
-static struct hw_module_methods_t qcom_audio_module_methods = {
- open: qcom_adev_open
-};
-
-struct qcom_audio_module HAL_MODULE_INFO_SYM = {
- module: {
- common: {
- tag: HARDWARE_MODULE_TAG,
- module_api_version: AUDIO_MODULE_API_VERSION_0_1,
- hal_api_version: HARDWARE_HAL_API_VERSION,
- id: AUDIO_HARDWARE_MODULE_ID,
- name: "QCOM Audio HW HAL",
- author: "The Linux Foundation",
- methods: &qcom_audio_module_methods,
- dso : NULL,
- reserved : {0},
- },
- },
-};
-
-}; // extern "C"
-
-}; // namespace android_audio_legacy
diff --git a/legacy/alsa_sound/audio_policy_hal.cpp b/legacy/alsa_sound/audio_policy_hal.cpp
deleted file mode 100644
index a1687f7..0000000
--- a/legacy/alsa_sound/audio_policy_hal.cpp
+++ /dev/null
@@ -1,468 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "qcom_audio_policy_hal"
-//#define LOG_NDEBUG 0
-
-#include <stdint.h>
-
-#include <hardware/hardware.h>
-#include <system/audio.h>
-#include <system/audio_policy.h>
-#include <hardware/audio_policy.h>
-
-#include <hardware_legacy/AudioPolicyInterface.h>
-#include <hardware_legacy/AudioSystemLegacy.h>
-
-#include "AudioPolicyCompatClient.h"
-
-namespace android_audio_legacy {
-
-extern "C" {
-
-struct qcom_ap_module {
- struct audio_policy_module module;
-};
-
-struct qcom_ap_device {
- struct audio_policy_device device;
-};
-
-struct qcom_audio_policy {
- struct audio_policy policy;
-
- void *service;
- struct audio_policy_service_ops *aps_ops;
- AudioPolicyCompatClient *service_client;
- AudioPolicyInterface *apm;
-};
-
-static inline struct qcom_audio_policy * to_qap(struct audio_policy *pol)
-{
- return reinterpret_cast<struct qcom_audio_policy *>(pol);
-}
-
-static inline const struct qcom_audio_policy * to_cqap(const struct audio_policy *pol)
-{
- return reinterpret_cast<const struct qcom_audio_policy *>(pol);
-}
-
-
-static int ap_set_device_connection_state(struct audio_policy *pol,
- audio_devices_t device,
- audio_policy_dev_state_t state,
- const char *device_address)
-{
- struct qcom_audio_policy *qap = to_qap(pol);
- return qap->apm->setDeviceConnectionState(
- (AudioSystem::audio_devices)device,
- (AudioSystem::device_connection_state)state,
- device_address);
-}
-
-static audio_policy_dev_state_t ap_get_device_connection_state(
- const struct audio_policy *pol,
- audio_devices_t device,
- const char *device_address)
-{
- const struct qcom_audio_policy *qap = to_cqap(pol);
- return (audio_policy_dev_state_t)qap->apm->getDeviceConnectionState(
- (AudioSystem::audio_devices)device,
- device_address);
-}
-
-static void ap_set_phone_state(struct audio_policy *pol, audio_mode_t state)
-{
- struct qcom_audio_policy *qap = to_qap(pol);
- // as this is the legacy API, don't change it to use audio_mode_t instead of int
- qap->apm->setPhoneState((int) state);
-}
-
- /* indicate a change in ringer mode */
-static void ap_set_ringer_mode(struct audio_policy *pol, uint32_t mode,
- uint32_t mask)
-{
- // deprecated, never called
-}
-
- /* force using a specific device category for the specified usage */
-static void ap_set_force_use(struct audio_policy *pol,
- audio_policy_force_use_t usage,
- audio_policy_forced_cfg_t config)
-{
- struct qcom_audio_policy *qap = to_qap(pol);
- qap->apm->setForceUse((AudioSystem::force_use)usage,
- (AudioSystem::forced_config)config);
-}
-
- /* retreive current device category forced for a given usage */
-static audio_policy_forced_cfg_t ap_get_force_use(
- const struct audio_policy *pol,
- audio_policy_force_use_t usage)
-{
- const struct qcom_audio_policy *qap = to_cqap(pol);
- return (audio_policy_forced_cfg_t)qap->apm->getForceUse(
- (AudioSystem::force_use)usage);
-}
-
-/* if can_mute is true, then audio streams that are marked ENFORCED_AUDIBLE
- * can still be muted. */
-static void ap_set_can_mute_enforced_audible(struct audio_policy *pol,
- bool can_mute)
-{
- struct qcom_audio_policy *qap = to_qap(pol);
- qap->apm->setSystemProperty("ro.camera.sound.forced", can_mute ? "0" : "1");
-}
-
-static int ap_init_check(const struct audio_policy *pol)
-{
- const struct qcom_audio_policy *qap = to_cqap(pol);
- return qap->apm->initCheck();
-}
-
-static audio_io_handle_t ap_get_output(struct audio_policy *pol,
- audio_stream_type_t stream,
- uint32_t sampling_rate,
- audio_format_t format,
- audio_channel_mask_t channelMask,
- audio_output_flags_t flags)
-{
- struct qcom_audio_policy *qap = to_qap(pol);
-
- ALOGV("%s: tid %d", __func__, gettid());
- return qap->apm->getOutput((AudioSystem::stream_type)stream,
- sampling_rate, (int) format, channelMask,
- (AudioSystem::output_flags)flags);
-}
-
-static int ap_start_output(struct audio_policy *pol, audio_io_handle_t output,
- audio_stream_type_t stream, int session)
-{
- struct qcom_audio_policy *qap = to_qap(pol);
- return qap->apm->startOutput(output, (AudioSystem::stream_type)stream,
- session);
-}
-
-static int ap_stop_output(struct audio_policy *pol, audio_io_handle_t output,
- audio_stream_type_t stream, int session)
-{
- struct qcom_audio_policy *qap = to_qap(pol);
- return qap->apm->stopOutput(output, (AudioSystem::stream_type)stream,
- session);
-}
-
-static void ap_release_output(struct audio_policy *pol,
- audio_io_handle_t output)
-{
- struct qcom_audio_policy *qap = to_qap(pol);
- qap->apm->releaseOutput(output);
-}
-
-static audio_io_handle_t ap_get_input(struct audio_policy *pol, audio_source_t inputSource,
- uint32_t sampling_rate,
- audio_format_t format,
- audio_channel_mask_t channelMask,
- audio_in_acoustics_t acoustics)
-{
- struct qcom_audio_policy *qap = to_qap(pol);
- return qap->apm->getInput((int) inputSource, sampling_rate, (int) format, channelMask,
- (AudioSystem::audio_in_acoustics)acoustics);
-}
-
-static int ap_start_input(struct audio_policy *pol, audio_io_handle_t input)
-{
- struct qcom_audio_policy *qap = to_qap(pol);
- return qap->apm->startInput(input);
-}
-
-static int ap_stop_input(struct audio_policy *pol, audio_io_handle_t input)
-{
- struct qcom_audio_policy *qap = to_qap(pol);
- return qap->apm->stopInput(input);
-}
-
-static void ap_release_input(struct audio_policy *pol, audio_io_handle_t input)
-{
- struct qcom_audio_policy *qap = to_qap(pol);
- qap->apm->releaseInput(input);
-}
-
-static void ap_init_stream_volume(struct audio_policy *pol,
- audio_stream_type_t stream, int index_min,
- int index_max)
-{
- struct qcom_audio_policy *qap = to_qap(pol);
- qap->apm->initStreamVolume((AudioSystem::stream_type)stream, index_min,
- index_max);
-}
-
-static int ap_set_stream_volume_index(struct audio_policy *pol,
- audio_stream_type_t stream,
- int index)
-{
- struct qcom_audio_policy *qap = to_qap(pol);
- return qap->apm->setStreamVolumeIndex((AudioSystem::stream_type)stream,
- index,
- AUDIO_DEVICE_OUT_DEFAULT);
-}
-
-static int ap_get_stream_volume_index(const struct audio_policy *pol,
- audio_stream_type_t stream,
- int *index)
-{
- const struct qcom_audio_policy *qap = to_cqap(pol);
- return qap->apm->getStreamVolumeIndex((AudioSystem::stream_type)stream,
- index,
- AUDIO_DEVICE_OUT_DEFAULT);
-}
-
-static int ap_set_stream_volume_index_for_device(struct audio_policy *pol,
- audio_stream_type_t stream,
- int index,
- audio_devices_t device)
-{
- const struct qcom_audio_policy *qap = to_cqap(pol);
- return qap->apm->setStreamVolumeIndex((AudioSystem::stream_type)stream,
- index,
- device);
-}
-
-static int ap_get_stream_volume_index_for_device(const struct audio_policy *pol,
- audio_stream_type_t stream,
- int *index,
- audio_devices_t device)
-{
- const struct qcom_audio_policy *qap = to_cqap(pol);
- return qap->apm->getStreamVolumeIndex((AudioSystem::stream_type)stream,
- index,
- device);
-}
-
-static uint32_t ap_get_strategy_for_stream(const struct audio_policy *pol,
- audio_stream_type_t stream)
-{
- const struct qcom_audio_policy *qap = to_cqap(pol);
- return qap->apm->getStrategyForStream((AudioSystem::stream_type)stream);
-}
-
-static audio_devices_t ap_get_devices_for_stream(const struct audio_policy *pol,
- audio_stream_type_t stream)
-{
- const struct qcom_audio_policy *qap = to_cqap(pol);
- return qap->apm->getDevicesForStream((AudioSystem::stream_type)stream);
-}
-
-static audio_io_handle_t ap_get_output_for_effect(struct audio_policy *pol,
- const struct effect_descriptor_s *desc)
-{
- struct qcom_audio_policy *qap = to_qap(pol);
- return qap->apm->getOutputForEffect(desc);
-}
-
-static int ap_register_effect(struct audio_policy *pol,
- const struct effect_descriptor_s *desc,
- audio_io_handle_t io,
- uint32_t strategy,
- int session,
- int id)
-{
- struct qcom_audio_policy *qap = to_qap(pol);
- return qap->apm->registerEffect(desc, io, strategy, session, id);
-}
-
-static int ap_unregister_effect(struct audio_policy *pol, int id)
-{
- struct qcom_audio_policy *qap = to_qap(pol);
- return qap->apm->unregisterEffect(id);
-}
-
-static int ap_set_effect_enabled(struct audio_policy *pol, int id, bool enabled)
-{
- struct qcom_audio_policy *qap = to_qap(pol);
- return qap->apm->setEffectEnabled(id, enabled);
-}
-
-static bool ap_is_stream_active(const struct audio_policy *pol,
- audio_stream_type_t stream,
- uint32_t in_past_ms)
-{
- const struct qcom_audio_policy *qap = to_cqap(pol);
- return qap->apm->isStreamActive((int) stream, in_past_ms);
-}
-
-static bool ap_is_stream_active_remotely(const struct audio_policy *pol,
- audio_stream_type_t stream, uint32_t in_past_ms)
-{
- const struct qcom_audio_policy *qap = to_cqap(pol);
- return qap->apm->isStreamActiveRemotely((int) stream, in_past_ms);
-}
-
-static bool ap_is_source_active(const struct audio_policy *pol, audio_source_t source)
-{
- const struct qcom_audio_policy *qap = to_cqap(pol);
- return qap->apm->isSourceActive(source);
-}
-
-static int ap_dump(const struct audio_policy *pol, int fd)
-{
- const struct qcom_audio_policy *qap = to_cqap(pol);
- return qap->apm->dump(fd);
-}
-
-static int create_qcom_ap(const struct audio_policy_device *device,
- struct audio_policy_service_ops *aps_ops,
- void *service,
- struct audio_policy **ap)
-{
- struct qcom_audio_policy *qap;
- int ret;
-
- if (!service || !aps_ops)
- return -EINVAL;
-
- qap = (struct qcom_audio_policy *)calloc(1, sizeof(*qap));
- if (!qap)
- return -ENOMEM;
-
- qap->policy.set_device_connection_state = ap_set_device_connection_state;
- qap->policy.get_device_connection_state = ap_get_device_connection_state;
- qap->policy.set_phone_state = ap_set_phone_state;
- qap->policy.set_ringer_mode = ap_set_ringer_mode;
- qap->policy.set_force_use = ap_set_force_use;
- qap->policy.get_force_use = ap_get_force_use;
- qap->policy.set_can_mute_enforced_audible =
- ap_set_can_mute_enforced_audible;
- qap->policy.init_check = ap_init_check;
- qap->policy.get_output = ap_get_output;
- qap->policy.start_output = ap_start_output;
- qap->policy.stop_output = ap_stop_output;
- qap->policy.release_output = ap_release_output;
- qap->policy.get_input = ap_get_input;
- qap->policy.start_input = ap_start_input;
- qap->policy.stop_input = ap_stop_input;
- qap->policy.release_input = ap_release_input;
- qap->policy.init_stream_volume = ap_init_stream_volume;
- qap->policy.set_stream_volume_index = ap_set_stream_volume_index;
- qap->policy.get_stream_volume_index = ap_get_stream_volume_index;
- qap->policy.set_stream_volume_index_for_device = ap_set_stream_volume_index_for_device;
- qap->policy.get_stream_volume_index_for_device = ap_get_stream_volume_index_for_device;
- qap->policy.get_strategy_for_stream = ap_get_strategy_for_stream;
- qap->policy.get_devices_for_stream = ap_get_devices_for_stream;
- qap->policy.get_output_for_effect = ap_get_output_for_effect;
- qap->policy.register_effect = ap_register_effect;
- qap->policy.unregister_effect = ap_unregister_effect;
- qap->policy.set_effect_enabled = ap_set_effect_enabled;
- qap->policy.is_stream_active = ap_is_stream_active;
- qap->policy.is_stream_active_remotely = ap_is_stream_active_remotely;
- qap->policy.is_source_active = ap_is_source_active;
- qap->policy.dump = ap_dump;
-
- qap->service = service;
- qap->aps_ops = aps_ops;
- qap->service_client =
- new AudioPolicyCompatClient(aps_ops, service);
- if (!qap->service_client) {
- ret = -ENOMEM;
- goto err_new_compat_client;
- }
-
- qap->apm = createAudioPolicyManager(qap->service_client);
- if (!qap->apm) {
- ret = -ENOMEM;
- goto err_create_apm;
- }
-
- *ap = &qap->policy;
- return 0;
-
-err_create_apm:
- delete qap->service_client;
-err_new_compat_client:
- free(qap);
- *ap = NULL;
- return ret;
-}
-
-static int destroy_qcom_ap(const struct audio_policy_device *ap_dev,
- struct audio_policy *ap)
-{
- struct qcom_audio_policy *qap = to_qap(ap);
-
- if (!qap)
- return 0;
-
- if (qap->apm)
- destroyAudioPolicyManager(qap->apm);
- if (qap->service_client)
- delete qap->service_client;
- free(qap);
- return 0;
-}
-
-static int qcom_ap_dev_close(hw_device_t* device)
-{
- if (device)
- free(device);
- return 0;
-}
-
-static int qcom_ap_dev_open(const hw_module_t* module, const char* name,
- hw_device_t** device)
-{
- struct qcom_ap_device *dev;
-
- if (strcmp(name, AUDIO_POLICY_INTERFACE) != 0)
- return -EINVAL;
-
- dev = (struct qcom_ap_device *)calloc(1, sizeof(*dev));
- if (!dev)
- return -ENOMEM;
-
- dev->device.common.tag = HARDWARE_DEVICE_TAG;
- dev->device.common.version = 0;
- dev->device.common.module = const_cast<hw_module_t*>(module);
- dev->device.common.close = qcom_ap_dev_close;
- dev->device.create_audio_policy = create_qcom_ap;
- dev->device.destroy_audio_policy = destroy_qcom_ap;
-
- *device = &dev->device.common;
-
- return 0;
-}
-
-static struct hw_module_methods_t qcom_ap_module_methods = {
- open: qcom_ap_dev_open
-};
-
-struct qcom_ap_module HAL_MODULE_INFO_SYM = {
- module: {
- common: {
- tag: HARDWARE_MODULE_TAG,
- version_major: 1,
- version_minor: 0,
- id: AUDIO_POLICY_HARDWARE_MODULE_ID,
- name: "QCOM Audio Policy HAL",
- author: "The Linux Foundation",
- methods: &qcom_ap_module_methods,
- dso : NULL,
- reserved : {0},
- },
- },
-};
-
-}; // extern "C"
-
-}; // namespace android_audio_legacy
diff --git a/legacy/libalsa-intf/Android.mk b/legacy/libalsa-intf/Android.mk
deleted file mode 100644
index 5d509b3..0000000
--- a/legacy/libalsa-intf/Android.mk
+++ /dev/null
@@ -1,54 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-
-ifeq ($(strip $(BOARD_USES_ALSA_AUDIO)),true)
-# Any prebuilt files with default TAGS can use the below:
-
-include $(CLEAR_VARS)
-#LOCAL_SRC_FILES:= aplay.c alsa_pcm.c alsa_mixer.c
-LOCAL_SRC_FILES:= aplay.c
-LOCAL_MODULE:= aplay
-LOCAL_SHARED_LIBRARIES:= libc libcutils libalsa-intf
-LOCAL_MODULE_TAGS:= debug
-include $(BUILD_EXECUTABLE)
-
-include $(CLEAR_VARS)
-#LOCAL_SRC_FILES:= arec.c alsa_pcm.c
-LOCAL_SRC_FILES:= arec.c
-LOCAL_MODULE:= arec
-LOCAL_SHARED_LIBRARIES:= libc libcutils libalsa-intf
-LOCAL_MODULE_TAGS:= debug
-include $(BUILD_EXECUTABLE)
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES:= amix.c
-LOCAL_MODULE:= amix
-LOCAL_SHARED_LIBRARIES := libc libcutils libalsa-intf
-LOCAL_MODULE_TAGS:= debug
-include $(BUILD_EXECUTABLE)
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES:= alsaucm_test.c
-LOCAL_MODULE:= alsaucm_test
-LOCAL_SHARED_LIBRARIES:= libc libcutils libalsa-intf
-LOCAL_MODULE_TAGS:= debug
-include $(BUILD_EXECUTABLE)
-
-include $(CLEAR_VARS)
-LOCAL_COPY_HEADERS_TO := mm-audio/libalsa-intf
-LOCAL_COPY_HEADERS := alsa_audio.h
-LOCAL_COPY_HEADERS += alsa_ucm.h
-LOCAL_COPY_HEADERS += msm8960_use_cases.h
-LOCAL_SRC_FILES:= alsa_mixer.c alsa_pcm.c alsa_ucm.c
-LOCAL_MODULE:= libalsa-intf
-LOCAL_MODULE_TAGS := optional
-LOCAL_SHARED_LIBRARIES:= libc libcutils #libutils #libmedia libhardware_legacy
-LOCAL_CFLAGS := -DQC_PROP -DCONFIG_DIR=\"/system/etc/snd_soc_msm/\"
-
-ifeq ($(TARGET_SIMULATOR),true)
- LOCAL_LDLIBS += -ldl
-else
- LOCAL_SHARED_LIBRARIES += libdl
-endif
-LOCAL_PRELINK_MODULE := false
-include $(BUILD_SHARED_LIBRARY)
-endif
diff --git a/legacy/libalsa-intf/Makefile.am b/legacy/libalsa-intf/Makefile.am
deleted file mode 100644
index a05d073..0000000
--- a/legacy/libalsa-intf/Makefile.am
+++ /dev/null
@@ -1,47 +0,0 @@
-AM_CFLAGS = -Wundef \
- -Wstrict-prototypes \
- -Wno-trigraphs \
- -g -O0 \
- -fno-inline \
- -fno-short-enums \
- -fpic \
- -DQC_PROP
-
-AM_CPPFLAGS = -I. \
- $(ACDBLOADER_CFLAGS)
-
-c_sources = alsa_mixer.c \
- alsa_pcm.c \
- alsa_ucm.c
-
-h_sources = alsa_ucm.h \
- msm8960_use_cases.h \
- alsa_audio.h
-
-library_includedir = $(pkgincludedir)
-library_include_HEADERS = $(h_sources)
-
-lib_LTLIBRARIES = libalsa_intf.la
-libalsa_intf_la_CC = @CC@
-libalsa_intf_la_SOURCES = $(c_sources) $(h_sources)
-libalsa_intfdir = $(prefix)/snd_soc_msm
-dist_libalsa_intf_DATA = snd_soc_msm/snd_soc_msm \
- snd_soc_msm/snd_soc_msm_2x \
- snd_soc_msm/snd_soc_msm_2x_Fusion3 \
- snd_soc_msm/snd_soc_msm_Sitar
-libalsa_intf_la_CFLAGS = $(AM_CFLAGS) -DUSE_GLIB @GLIB_CFLAGS@ -DCONFIG_DIR=\"/etc/snd_soc_msm/\"
-libalsa_intf_la_CPPFLAGS = $(AM_CPPFLAGS) -DUSE_GLIB @GLIB_CFLAGS@
-libalsa_intf_la_LDFLAGS = $(ACDBLOADER_LIBS) -lm -lpthread @GLIB_LIBS@ -shared -version-info 1:0:0
-
-requiredlibs = libalsa_intf.la
-
-bin_PROGRAMS = aplay amix arec
-
-aplay_SOURCES = aplay.c
-aplay_LDADD = -lpthread $(requiredlibs)
-
-amix_SOURCES = amix.c
-amix_LDADD = -lpthread $(requiredlibs)
-
-arec_SOURCES = arec.c
-arec_LDADD = -lpthread $(requiredlibs)
diff --git a/legacy/libalsa-intf/alsa_audio.h b/legacy/libalsa-intf/alsa_audio.h
deleted file mode 100644
index 90fbe56..0000000
--- a/legacy/libalsa-intf/alsa_audio.h
+++ /dev/null
@@ -1,291 +0,0 @@
-/*
-** Copyright 2010, The Android Open-Source Project
-** Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-#ifndef _AUDIO_H_
-#define _AUDIO_H_
-
-#include <sound/asound.h>
-#define PCM_ERROR_MAX 128
-
-struct pcm {
- int fd;
- int timer_fd;
- unsigned rate;
- unsigned channels;
- unsigned flags;
- unsigned format;
- unsigned running:1;
- int underruns;
- unsigned buffer_size;
- unsigned period_size;
- unsigned period_cnt;
- char error[PCM_ERROR_MAX];
- struct snd_pcm_hw_params *hw_p;
- struct snd_pcm_sw_params *sw_p;
- struct snd_pcm_sync_ptr *sync_ptr;
- struct snd_pcm_channel_info ch[2];
- void *addr;
- int card_no;
- int device_no;
- int start;
-};
-
-enum decoder_alias {
- FORMAT_MP3,
- FORMAT_AC3_PASS_THROUGH = 2,
-};
-
-#define FORMAT(v) SNDRV_PCM_FORMAT_##v
-
-#define PCM_OUT 0x00000000
-#define PCM_IN 0x10000000
-
-#define PCM_STEREO 0x00000000
-#define PCM_MONO 0x01000000
-#define PCM_QUAD 0x02000000
-#define PCM_5POINT1 0x04000000
-
-#define PCM_44100HZ 0x00000000
-#define PCM_48000HZ 0x00100000
-#define PCM_8000HZ 0x00200000
-#define PCM_RATE_MASK 0x00F00000
-
-#define PCM_MMAP 0x00010000
-#define PCM_NMMAP 0x00000000
-
-#define DEBUG_ON 0x00000001
-#define DEBUG_OFF 0x00000000
-
-#define PCM_PERIOD_CNT_MIN 2
-#define PCM_PERIOD_CNT_SHIFT 16
-#define PCM_PERIOD_CNT_MASK (0xF << PCM_PERIOD_CNT_SHIFT)
-#define PCM_PERIOD_SZ_MIN 128
-#define PCM_PERIOD_SZ_SHIFT 12
-#define PCM_PERIOD_SZ_MASK (0xF << PCM_PERIOD_SZ_SHIFT)
-
-#define TIMEOUT_INFINITE -1
-
-/* Acquire/release a pcm channel.
- * Returns non-zero on error
- */
-
-struct mixer_ctl {
- struct mixer *mixer;
- struct snd_ctl_elem_info *info;
- char **ename;
-};
-
-#define __snd_alloca(ptr,type) do { *ptr = (type *) alloca(sizeof(type)); memset(*ptr, 0, sizeof(type)); } while (0)
-#define snd_ctl_elem_id_alloca(ptr) __snd_alloca(ptr, snd_ctl_elem_id)
-#define snd_ctl_card_info_alloca(ptr) __snd_alloca(ptr, snd_ctl_card_info)
-#define snd_ctl_event_alloca(ptr) __snd_alloca(ptr, snd_ctl_event)
-#define snd_ctl_elem_list_alloca(ptr) __snd_alloca(ptr, snd_ctl_elem_list)
-#define snd_ctl_elem_info_alloca(ptr) __snd_alloca(ptr, snd_ctl_elem_info)
-#define snd_ctl_elem_value_alloca(ptr) __snd_alloca(ptr, snd_ctl_elem_value)
-
-
-enum snd_pcm_stream_t {
- /** Playback stream */
- SND_PCM_STREAM_PLAYBACK = 0,
- /** Capture stream */
- SND_PCM_STREAM_CAPTURE,
- SND_PCM_STREAM_LAST = SND_PCM_STREAM_CAPTURE
-};
-
-enum _snd_ctl_elem_iface {
- /** Card level */
- SND_CTL_ELEM_IFACE_CARD = 0,
- /** Hardware dependent device */
- SND_CTL_ELEM_IFACE_HWDEP,
- /** Mixer */
- SND_CTL_ELEM_IFACE_MIXER,
- /** PCM */
- SND_CTL_ELEM_IFACE_PCM,
- /** RawMidi */
- SND_CTL_ELEM_IFACE_RAWMIDI,
- /** Timer */
- SND_CTL_ELEM_IFACE_TIMER,
- /** Sequencer */
- SND_CTL_ELEM_IFACE_SEQUENCER,
- SND_CTL_ELEM_IFACE_LAST = SND_CTL_ELEM_IFACE_SEQUENCER
-};
-
-struct mixer {
- int fd;
- struct snd_ctl_elem_info *info;
- struct mixer_ctl *ctl;
- unsigned count;
-};
-
-int get_format(const char* name);
-const char *get_format_name(int format);
-const char *get_format_desc(int format);
-struct pcm *pcm_open(unsigned flags, char *device);
-int pcm_close(struct pcm *pcm);
-int pcm_ready(struct pcm *pcm);
-int mmap_buffer(struct pcm *pcm);
-u_int8_t *dst_address(struct pcm *pcm);
-int sync_ptr(struct pcm *pcm);
-
-void param_init(struct snd_pcm_hw_params *p);
-void param_set_mask(struct snd_pcm_hw_params *p, int n, unsigned bit);
-void param_set_min(struct snd_pcm_hw_params *p, int n, unsigned val);
-void param_set_int(struct snd_pcm_hw_params *p, int n, unsigned val);
-void param_set_max(struct snd_pcm_hw_params *p, int n, unsigned val);
-int param_set_hw_refine(struct pcm *pcm, struct snd_pcm_hw_params *params);
-int param_set_hw_params(struct pcm *pcm, struct snd_pcm_hw_params *params);
-int param_set_sw_params(struct pcm *pcm, struct snd_pcm_sw_params *sparams);
-void param_dump(struct snd_pcm_hw_params *p);
-int pcm_prepare(struct pcm *pcm);
-long pcm_avail(struct pcm *pcm);
-
-/* Returns a human readable reason for the last error. */
-const char *pcm_error(struct pcm *pcm);
-
-/* Returns the buffer size (int bytes) that should be used for pcm_write.
- * This will be 1/2 of the actual fifo size.
- */
-int pcm_buffer_size(struct snd_pcm_hw_params *params);
-int pcm_period_size(struct snd_pcm_hw_params *params);
-
-/* Write data to the fifo.
- * Will start playback on the first write or on a write that
- * occurs after a fifo underrun.
- */
-int pcm_write(struct pcm *pcm, void *data, unsigned count);
-int pcm_read(struct pcm *pcm, void *data, unsigned count);
-
-struct mixer;
-struct mixer_ctl;
-
-struct mixer *mixer_open(const char *device);
-void mixer_close(struct mixer *mixer);
-void mixer_dump(struct mixer *mixer);
-
-struct mixer_ctl *mixer_get_control(struct mixer *mixer,
- const char *name, unsigned index);
-struct mixer_ctl *mixer_get_nth_control(struct mixer *mixer, unsigned n);
-
-int mixer_ctl_set(struct mixer_ctl *ctl, unsigned percent);
-int mixer_ctl_select(struct mixer_ctl *ctl, const char *value);
-void mixer_ctl_get(struct mixer_ctl *ctl, unsigned *value);
-int mixer_ctl_set_value(struct mixer_ctl *ctl, int count, char ** argv);
-
-
-#define MAX_NUM_CODECS 32
-
-/* compressed audio support */
-#ifdef QCOM_COMPRESSED_AUDIO_ENABLED
-struct snd_compr_caps {
- __u32 num_codecs;
- __u32 min_fragment_size;
- __u32 max_fragment_size;
- __u32 min_fragments;
- __u32 max_fragments;
- __u32 codecs[MAX_NUM_CODECS];
- __u32 reserved[11];
-};
-
-struct snd_enc_wma {
- __u32 super_block_align; /* WMA Type-specific data */
- __u32 bits_per_sample;
- __u32 channelmask;
- __u32 encodeopt;
-};
-
-struct snd_enc_vorbis {
- int quality;
- __u32 managed;
- __u32 max_bit_rate;
- __u32 min_bit_rate;
- __u32 downmix;
-};
-
-struct snd_enc_real {
- __u32 quant_bits;
- __u32 start_region;
- __u32 num_regions;
-};
-
-struct snd_enc_flac {
- __u32 num;
- __u32 gain;
-};
-
-struct snd_enc_generic {
- __u32 bw; /* encoder bandwidth */
- int reserved[15];
-};
-
-union snd_codec_options {
- struct snd_enc_wma wma;
- struct snd_enc_vorbis vorbis;
- struct snd_enc_real real;
- struct snd_enc_flac flac;
- struct snd_enc_generic generic;
-};
-
-struct snd_codec {
- __u32 id;
- __u32 ch_in;
- __u32 ch_out;
- __u32 sample_rate;
- __u32 bit_rate;
- __u32 rate_control;
- __u32 profile;
- __u32 level;
- __u32 ch_mode;
- __u32 format;
- __u32 align;
- union snd_codec_options options;
- __u32 reserved[3];
-};
-
-struct snd_compressed_buffer {
- size_t fragment_size;
- int fragments;
-};
-
-/* */
-struct snd_compr_params {
- struct snd_compressed_buffer buffer;
- struct snd_codec codec;
-};
-
-struct snd_compr_tstamp {
- size_t copied_bytes;
- size_t copied_total;
- size_t decoded;
- size_t rendered;
- __u32 sampling_rate;
- uint64_t timestamp;
-};
-
-#define SNDRV_COMPRESS_GET_CAPS _IOWR('C', 0x00, struct snd_compr_caps *)
-#define SNDRV_COMPRESS_GET_CODEC_CAPS _IOWR('C', 0x01, struct snd_compr_codec_caps *)
-#define SNDRV_COMPRESS_SET_PARAMS _IOW('C', 0x02, struct snd_compr_params *)
-#define SNDRV_COMPRESS_GET_PARAMS _IOR('C', 0x03, struct snd_compr_params *)
-#define SNDRV_COMPRESS_TSTAMP _IOR('C', 0x10, struct snd_compr_tstamp *)
-#define SNDRV_COMPRESS_AVAIL _IOR('C', 0x11, struct snd_compr_avail *)
-#define SNDRV_COMPRESS_PAUSE _IO('C', 0x20)
-#define SNDRV_COMPRESS_RESUME _IO('C', 0x21)
-#define SNDRV_COMPRESS_START _IO('C', 0x22)
-#define SNDRV_COMPRESS_STOP _IO('C', 0x23)
-#define SNDRV_COMPRESS_DRAIN _IO('C', 0x24)
-#endif
-
-#endif
diff --git a/legacy/libalsa-intf/alsa_mixer.c b/legacy/libalsa-intf/alsa_mixer.c
deleted file mode 100644
index c3738f0..0000000
--- a/legacy/libalsa-intf/alsa_mixer.c
+++ /dev/null
@@ -1,752 +0,0 @@
-/*
-** Copyright 2010, The Android Open-Source Project
-** Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <stdint.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <ctype.h>
-#include <math.h>
-
-#include <linux/ioctl.h>
-#define __force
-#define __bitwise
-#define __user
-#include <sound/asound.h>
-#include <sound/tlv.h>
-
-#include "alsa_audio.h"
-
-#define LOG_TAG "alsa_mixer"
-#define LOG_NDEBUG 1
-
-#ifdef ANDROID
-/* definitions for Android logging */
-#include <utils/Log.h>
-#else /* ANDROID */
-#include <math.h>
-#define ALOGI(...) fprintf(stdout, __VA_ARGS__)
-#define ALOGE(...) fprintf(stderr, __VA_ARGS__)
-#define ALOGV(...) fprintf(stderr, __VA_ARGS__)
-#endif /* ANDROID */
-
-#define check_range(val, min, max) \
- (((val < min) ? (min) : (val > max) ? (max) : (val)))
-
-/* .5 for rounding before casting to non-decmal value */
-/* Should not be used if you need decmal values */
-/* or are expecting negitive indexes */
-#define percent_to_index(val, min, max) \
- ((val) * ((max) - (min)) * 0.01 + (min) + .5)
-
-#define DEFAULT_TLV_SIZE 4096
-#define SPDIF_CHANNEL_STATUS_SIZE 24
-
-enum ctl_type {
- CTL_GLOBAL_VOLUME,
- CTL_PLAYBACK_VOLUME,
- CTL_CAPTURE_VOLUME,
-};
-
-static const struct suf {
- const char *suffix;
- snd_ctl_elem_iface_t type;
-} suffixes[] = {
- {" Playback Volume", CTL_PLAYBACK_VOLUME},
- {" Capture Volume", CTL_CAPTURE_VOLUME},
- {" Volume", CTL_GLOBAL_VOLUME},
- {NULL, 0}
-};
-
-static int is_volume(const char *name, enum ctl_type *type)
-{
- const struct suf *p;
- size_t nlen = strlen(name);
- p = suffixes;
- while (p->suffix) {
- size_t slen = strnlen(p->suffix, 44);
- size_t l;
- if (nlen > slen) {
- l = nlen - slen;
- if (strncmp(name + l, p->suffix, slen) == 0 &&
- (l < 1 || name[l-1] != '-')) { /* 3D Control - Switch */
- *type = p->type;
- return l;
- }
- }
- p++;
- }
- return 0;
-}
-
-static const char *elem_iface_name(snd_ctl_elem_iface_t n)
-{
- switch (n) {
- case SNDRV_CTL_ELEM_IFACE_CARD: return "CARD";
- case SNDRV_CTL_ELEM_IFACE_HWDEP: return "HWDEP";
- case SNDRV_CTL_ELEM_IFACE_MIXER: return "MIXER";
- case SNDRV_CTL_ELEM_IFACE_PCM: return "PCM";
- case SNDRV_CTL_ELEM_IFACE_RAWMIDI: return "MIDI";
- case SNDRV_CTL_ELEM_IFACE_TIMER: return "TIMER";
- case SNDRV_CTL_ELEM_IFACE_SEQUENCER: return "SEQ";
- default: return "???";
- }
-}
-
-static const char *elem_type_name(snd_ctl_elem_type_t n)
-{
- switch (n) {
- case SNDRV_CTL_ELEM_TYPE_NONE: return "NONE";
- case SNDRV_CTL_ELEM_TYPE_BOOLEAN: return "BOOL";
- case SNDRV_CTL_ELEM_TYPE_INTEGER: return "INT32";
- case SNDRV_CTL_ELEM_TYPE_ENUMERATED: return "ENUM";
- case SNDRV_CTL_ELEM_TYPE_BYTES: return "BYTES";
- case SNDRV_CTL_ELEM_TYPE_IEC958: return "IEC958";
- case SNDRV_CTL_ELEM_TYPE_INTEGER64: return "INT64";
- default: return "???";
- }
-}
-
-void mixer_close(struct mixer *mixer)
-{
- unsigned n,m;
-
- if (mixer->fd >= 0)
- close(mixer->fd);
-
- if (mixer->ctl) {
- for (n = 0; n < mixer->count; n++) {
- if (mixer->ctl[n].ename) {
- unsigned max = mixer->ctl[n].info->value.enumerated.items;
- for (m = 0; m < max; m++)
- free(mixer->ctl[n].ename[m]);
- free(mixer->ctl[n].ename);
- }
- }
- free(mixer->ctl);
- }
-
- if (mixer->info)
- free(mixer->info);
-
- free(mixer);
-}
-
-struct mixer *mixer_open(const char *device)
-{
- struct snd_ctl_elem_list elist;
- struct snd_ctl_elem_info tmp;
- struct snd_ctl_elem_id *eid = NULL;
- struct mixer *mixer = NULL;
- unsigned n, m;
- int fd;
-
- fd = open(device, O_RDWR);
- if (fd < 0) {
- ALOGE("Control open failed\n");
- return 0;
- }
-
- memset(&elist, 0, sizeof(elist));
- if (ioctl(fd, SNDRV_CTL_IOCTL_ELEM_LIST, &elist) < 0) {
- ALOGE("SNDRV_CTL_IOCTL_ELEM_LIST failed\n");
- goto fail;
- }
-
- mixer = calloc(1, sizeof(*mixer));
- if (!mixer)
- goto fail;
-
- mixer->ctl = calloc(elist.count, sizeof(struct mixer_ctl));
- mixer->info = calloc(elist.count, sizeof(struct snd_ctl_elem_info));
- if (!mixer->ctl || !mixer->info)
- goto fail;
-
- eid = calloc(elist.count, sizeof(struct snd_ctl_elem_id));
- if (!eid)
- goto fail;
-
- mixer->count = elist.count;
- mixer->fd = fd;
- elist.space = mixer->count;
- elist.pids = eid;
- if (ioctl(fd, SNDRV_CTL_IOCTL_ELEM_LIST, &elist) < 0)
- goto fail;
-
- for (n = 0; n < mixer->count; n++) {
- struct snd_ctl_elem_info *ei = mixer->info + n;
- ei->id.numid = eid[n].numid;
- if (ioctl(fd, SNDRV_CTL_IOCTL_ELEM_INFO, ei) < 0)
- goto fail;
- mixer->ctl[n].info = ei;
- mixer->ctl[n].mixer = mixer;
- if (ei->type == SNDRV_CTL_ELEM_TYPE_ENUMERATED) {
- char **enames = calloc(ei->value.enumerated.items, sizeof(char*));
- if (!enames)
- goto fail;
- mixer->ctl[n].ename = enames;
- for (m = 0; m < ei->value.enumerated.items; m++) {
- memset(&tmp, 0, sizeof(tmp));
- tmp.id.numid = ei->id.numid;
- tmp.value.enumerated.item = m;
- if (ioctl(fd, SNDRV_CTL_IOCTL_ELEM_INFO, &tmp) < 0)
- goto fail;
- enames[m] = strdup(tmp.value.enumerated.name);
- if (!enames[m])
- goto fail;
- }
- }
- }
-
- free(eid);
- return mixer;
-
-fail:
- if (eid)
- free(eid);
- if (mixer)
- mixer_close(mixer);
- else if (fd >= 0)
- close(fd);
- return 0;
-}
-
-void mixer_dump(struct mixer *mixer)
-{
- unsigned n, m;
-
- ALOGV(" id iface dev sub idx num perms type isvolume name\n");
- for (n = 0; n < mixer->count; n++) {
- enum ctl_type type;
- struct snd_ctl_elem_info *ei = mixer->info + n;
-
- ALOGV("%4d %5s %3d %3d %3d %3d %c%c%c%c%c%c%c%c%c %-6s %8d %s",
- ei->id.numid, elem_iface_name(ei->id.iface),
- ei->id.device, ei->id.subdevice, ei->id.index,
- ei->count,
- (ei->access & SNDRV_CTL_ELEM_ACCESS_READ) ? 'r' : ' ',
- (ei->access & SNDRV_CTL_ELEM_ACCESS_WRITE) ? 'w' : ' ',
- (ei->access & SNDRV_CTL_ELEM_ACCESS_VOLATILE) ? 'V' : ' ',
- (ei->access & SNDRV_CTL_ELEM_ACCESS_TIMESTAMP) ? 'T' : ' ',
- (ei->access & SNDRV_CTL_ELEM_ACCESS_TLV_READ) ? 'R' : ' ',
- (ei->access & SNDRV_CTL_ELEM_ACCESS_TLV_WRITE) ? 'W' : ' ',
- (ei->access & SNDRV_CTL_ELEM_ACCESS_TLV_COMMAND) ? 'C' : ' ',
- (ei->access & SNDRV_CTL_ELEM_ACCESS_INACTIVE) ? 'I' : ' ',
- (ei->access & SNDRV_CTL_ELEM_ACCESS_LOCK) ? 'L' : ' ',
- elem_type_name(ei->type),
- (is_volume(ei->id.name, &type)) ? 1 : 0,
- ei->id.name);
- switch (ei->type) {
- case SNDRV_CTL_ELEM_TYPE_INTEGER:
- ALOGV(ei->value.integer.step ?
- " { %ld-%ld, %ld }\n" : " { %ld-%ld }",
- ei->value.integer.min,
- ei->value.integer.max,
- ei->value.integer.step);
- break;
- case SNDRV_CTL_ELEM_TYPE_INTEGER64:
- ALOGV(ei->value.integer64.step ?
- " { %lld-%lld, %lld }\n" : " { %lld-%lld }",
- ei->value.integer64.min,
- ei->value.integer64.max,
- ei->value.integer64.step);
- break;
- case SNDRV_CTL_ELEM_TYPE_ENUMERATED: {
- unsigned m;
- ALOGV(" { %s=0", mixer->ctl[n].ename[0]);
- for (m = 1; m < ei->value.enumerated.items; m++)
- ALOGV(", %s=%d", mixer->ctl[n].ename[m],m);
- ALOGV(" }");
- break;
- }
- }
- ALOGV("\n");
- }
-}
-
-struct mixer_ctl *mixer_get_control(struct mixer *mixer,
- const char *name, unsigned index)
-{
- unsigned n;
- for (n = 0; n < mixer->count; n++) {
- if (mixer->info[n].id.index == index) {
- if (!strncmp(name, (char*) mixer->info[n].id.name,
- sizeof(mixer->info[n].id.name))) {
- return mixer->ctl + n;
- }
- }
- }
- return 0;
-}
-
-struct mixer_ctl *mixer_get_nth_control(struct mixer *mixer, unsigned n)
-{
- if (n < mixer->count)
- return mixer->ctl + n;
- return 0;
-}
-
-static void print_dB(long dB)
-{
- ALOGV("%li.%02lidB", dB / 100, (dB < 0 ? -dB : dB) % 100);
-}
-
-int mixer_ctl_read_tlv(struct mixer_ctl *ctl,
- unsigned int *tlv,
- long *min, long *max, unsigned int *tlv_type)
-{
- unsigned int tlv_size = DEFAULT_TLV_SIZE;
- unsigned int type;
- unsigned int size;
-
- if(!!(ctl->info->access & SNDRV_CTL_ELEM_ACCESS_TLV_READ)) {
- struct snd_ctl_tlv *xtlv;
- tlv[0] = -1;
- tlv[1] = 0;
- xtlv = calloc(1, sizeof(struct snd_ctl_tlv) + tlv_size);
- if (xtlv == NULL)
- return -ENOMEM;
- xtlv->numid = ctl->info->id.numid;
- xtlv->length = tlv_size;
- memcpy(xtlv->tlv, tlv, tlv_size);
- if (ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_TLV_READ, xtlv) < 0) {
- fprintf( stderr, "SNDRV_CTL_IOCTL_TLV_READ failed\n");
- free(xtlv);
- return -errno;
- }
- if (xtlv->tlv[1] + 2 * sizeof(unsigned int) > tlv_size) {
- free(xtlv);
- return -EFAULT;
- }
- memcpy(tlv, xtlv->tlv, xtlv->tlv[1] + 2 * sizeof(unsigned int));
- free(xtlv);
-
- type = tlv[0];
- *tlv_type = type;
- size = tlv[1];
- switch (type) {
- case SNDRV_CTL_TLVT_DB_SCALE: {
- int idx = 2;
- int step;
- ALOGV("dBscale-");
- if (size != 2 * sizeof(unsigned int)) {
- while (size > 0) {
- ALOGV("0x%08x,", tlv[idx++]);
- size -= sizeof(unsigned int);
- }
- } else {
- ALOGV(" min=");
- print_dB((int)tlv[2]);
- *min = (long)tlv[2];
- ALOGV(" step=");
- step = (tlv[3] & 0xffff);
- print_dB(tlv[3] & 0xffff);
- ALOGV(" max=");
- *max = (ctl->info->value.integer.max);
- print_dB((long)ctl->info->value.integer.max);
- ALOGV(" mute=%i\n", (tlv[3] >> 16) & 1);
- }
- break;
- }
- case SNDRV_CTL_TLVT_DB_LINEAR: {
- int idx = 2;
- ALOGV("dBLiner-");
- if (size != 2 * sizeof(unsigned int)) {
- while (size > 0) {
- ALOGV("0x%08x,", tlv[idx++]);
- size -= sizeof(unsigned int);
- }
- } else {
- ALOGV(" min=");
- *min = tlv[2];
- print_dB(tlv[2]);
- ALOGV(" max=");
- *max = tlv[3];
- print_dB(tlv[3]);
- }
- break;
- }
- default:
- break;
- }
- return 0;
- }
- return -EINVAL;
-}
-
-void mixer_ctl_get(struct mixer_ctl *ctl, unsigned *value)
-{
- struct snd_ctl_elem_value ev;
- unsigned int n;
- unsigned int *tlv = NULL;
- enum ctl_type type;
- unsigned int *tlv_type;
- long min, max;
-
- if (is_volume(ctl->info->id.name, &type)) {
- ALOGV("capability: volume\n");
- tlv = calloc(1, DEFAULT_TLV_SIZE);
- if (tlv == NULL) {
- ALOGE("failed to allocate memory\n");
- } else {
- mixer_ctl_read_tlv(ctl, tlv, &min, &max, &tlv_type);
- free(tlv);
- }
- }
-
- memset(&ev, 0, sizeof(ev));
- ev.id.numid = ctl->info->id.numid;
- if (ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_ELEM_READ, &ev))
- return;
- ALOGV("%s:", ctl->info->id.name);
-
- switch (ctl->info->type) {
- case SNDRV_CTL_ELEM_TYPE_BOOLEAN:
- for (n = 0; n < ctl->info->count; n++)
- ALOGV(" %s", ev.value.integer.value[n] ? "on" : "off");
- *value = ev.value.integer.value[0];
- break;
- case SNDRV_CTL_ELEM_TYPE_INTEGER: {
- for (n = 0; n < ctl->info->count; n++)
- ALOGV(" %ld", ev.value.integer.value[n]);
- *value = ev.value.integer.value[0];
- break;
- }
- case SNDRV_CTL_ELEM_TYPE_INTEGER64:
- for (n = 0; n < ctl->info->count; n++)
- ALOGV(" %lld", ev.value.integer64.value[n]);
- *value = ev.value.integer64.value[0];
- break;
- case SNDRV_CTL_ELEM_TYPE_ENUMERATED:
- for (n = 0; n < ctl->info->count; n++) {
- unsigned v = ev.value.enumerated.item[n];
- ALOGV(" %d (%s)", v,
- (v < ctl->info->value.enumerated.items) ? ctl->ename[v] : "???");
- *value = ev.value.enumerated.item[0];
- }
- break;
- default:
- ALOGV(" ???");
- }
- ALOGV("\n");
-}
-
-static long scale_int(struct snd_ctl_elem_info *ei, unsigned _percent)
-{
- long percent;
-
- if (_percent > 100)
- percent = 100;
- else
- percent = (long) _percent;
-
- return (long)percent_to_index(percent, ei->value.integer.min, ei->value.integer.max);
-}
-
-static long long scale_int64(struct snd_ctl_elem_info *ei, unsigned _percent)
-{
- long long percent;
-
- if (_percent > 100)
- percent = 100;
- else
- percent = (long) _percent;
-
- return (long long)percent_to_index(percent, ei->value.integer.min, ei->value.integer.max);
-}
-
-/*
- * Add support for controls taking more than one parameter as input value
- * This is useful for volume controls which take two parameters as input value.
- */
-int mixer_ctl_mulvalues(struct mixer_ctl *ctl, int count, char ** argv)
-{
- struct snd_ctl_elem_value ev;
- unsigned n;
-
- if (!ctl) {
- ALOGV("can't find control\n");
- return -1;
- }
- if (count < ctl->info->count || count > ctl->info->count)
- return -EINVAL;
-
-
- memset(&ev, 0, sizeof(ev));
- ev.id.numid = ctl->info->id.numid;
- switch (ctl->info->type) {
- case SNDRV_CTL_ELEM_TYPE_BOOLEAN:
- for (n = 0; n < ctl->info->count; n++)
- ev.value.integer.value[n] = !!atoi(argv[n]);
- break;
- case SNDRV_CTL_ELEM_TYPE_INTEGER: {
- for (n = 0; n < ctl->info->count; n++) {
- fprintf( stderr, "Value: %d idx:%d\n", atoi(argv[n]), n);
- ev.value.integer.value[n] = atoi(argv[n]);
- }
- break;
- }
- case SNDRV_CTL_ELEM_TYPE_INTEGER64: {
- for (n = 0; n < ctl->info->count; n++) {
- long long value_ll = scale_int64(ctl->info, atoi(argv[n]));
- fprintf( stderr, "ll_value = %lld\n", value_ll);
- ev.value.integer64.value[n] = value_ll;
- }
- break;
- }
- default:
- errno = EINVAL;
- return errno;
- }
-
- return ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_ELEM_WRITE, &ev);
-}
-
-int mixer_ctl_set(struct mixer_ctl *ctl, unsigned percent)
-{
- struct snd_ctl_elem_value ev;
- unsigned n;
- long min, max;
- unsigned int *tlv = NULL;
- enum ctl_type type;
- int volume = 0;
- unsigned int tlv_type;
-
- if (!ctl) {
- ALOGV("can't find control\n");
- return -1;
- }
-
- if (is_volume(ctl->info->id.name, &type)) {
- ALOGV("capability: volume\n");
- tlv = calloc(1, DEFAULT_TLV_SIZE);
- if (tlv == NULL) {
- ALOGE("failed to allocate memory\n");
- } else if (!mixer_ctl_read_tlv(ctl, tlv, &min, &max, &tlv_type)) {
- switch(tlv_type) {
- case SNDRV_CTL_TLVT_DB_LINEAR:
- ALOGV("tlv db linear: b4 %d\n", percent);
-
- if (min < 0) {
- max = max - min;
- min = 0;
- }
- percent = check_range(percent, min, max);
- ALOGV("tlv db linear: %d %d %d\n", percent, min, max);
- volume = 1;
- break;
- default:
- percent = (long)percent_to_index(percent, min, max);
- percent = check_range(percent, min, max);
- volume = 1;
- break;
- }
- } else
- ALOGV("mixer_ctl_read_tlv failed\n");
- free(tlv);
- }
- memset(&ev, 0, sizeof(ev));
- ev.id.numid = ctl->info->id.numid;
- switch (ctl->info->type) {
- case SNDRV_CTL_ELEM_TYPE_BOOLEAN:
- for (n = 0; n < ctl->info->count; n++)
- ev.value.integer.value[n] = !!percent;
- break;
- case SNDRV_CTL_ELEM_TYPE_INTEGER: {
- int value;
- if (!volume)
- value = scale_int(ctl->info, percent);
- else
- value = (int) percent;
- for (n = 0; n < ctl->info->count; n++)
- ev.value.integer.value[n] = value;
- break;
- }
- case SNDRV_CTL_ELEM_TYPE_INTEGER64: {
- long long value;
- if (!volume)
- value = scale_int64(ctl->info, percent);
- else
- value = (long long)percent;
- for (n = 0; n < ctl->info->count; n++)
- ev.value.integer64.value[n] = value;
- break;
- }
- case SNDRV_CTL_ELEM_TYPE_IEC958: {
- struct snd_aes_iec958 *iec958;
- iec958 = (struct snd_aes_iec958 *)percent;
- memcpy(ev.value.iec958.status,iec958->status,SPDIF_CHANNEL_STATUS_SIZE);
- break;
- }
- default:
- errno = EINVAL;
- return errno;
- }
-
- return ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_ELEM_WRITE, &ev);
-}
-
-/* the api parses the mixer control input to extract
- * the value of volume in any one of the following format
- * <volume><%>
- * <volume><dB>
- * All remaining formats are currently ignored.
- */
-
-static int set_volume_simple(struct mixer_ctl *ctl,
- char **ptr, long pmin, long pmax, int count)
-{
- long val, orig;
- char *p = *ptr, *s;
- struct snd_ctl_elem_value ev;
- unsigned n;
-
- if (*p == ':')
- p++;
- if (*p == '\0' || (!isdigit(*p) && *p != '-'))
- goto skip;
-
- s = p;
- val = strtol(s, &p, 10);
- if (*p == '.') {
- p++;
- strtol(p, &p, 10);
- }
- if (*p == '%') {
- val = (long)percent_to_index(strtod(s, NULL), pmin, pmax);
- p++;
- } else if (p[0] == 'd' && p[1] == 'B') {
- val = (long)(strtod(s, NULL) * 100.0);
- p += 2;
- } else {
- if (pmin < 0) {
- pmax = pmax - pmin;
- pmin = 0;
- }
- }
- val = check_range(val, pmin, pmax);
- ALOGV("val = %x", val);
-
- if (!ctl) {
- ALOGV("can't find control\n");
- return -EPERM;
- }
- if (count < ctl->info->count || count > ctl->info->count)
- return -EINVAL;
-
- ALOGV("Value = ");
-
- memset(&ev, 0, sizeof(ev));
- ev.id.numid = ctl->info->id.numid;
- switch (ctl->info->type) {
- case SNDRV_CTL_ELEM_TYPE_BOOLEAN:
- for (n = 0; n < ctl->info->count; n++)
- ev.value.integer.value[n] = !!val;
- print_dB(val);
- break;
- case SNDRV_CTL_ELEM_TYPE_INTEGER: {
- for (n = 0; n < ctl->info->count; n++)
- ev.value.integer.value[n] = val;
- print_dB(val);
- break;
- }
- case SNDRV_CTL_ELEM_TYPE_INTEGER64: {
- for (n = 0; n < ctl->info->count; n++) {
- long long value_ll = scale_int64(ctl->info, val);
- print_dB(value_ll);
- ev.value.integer64.value[n] = value_ll;
- }
- break;
- }
- default:
- errno = EINVAL;
- return errno;
- }
-
- ALOGV("\n");
- return ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_ELEM_WRITE, &ev);
-
-skip:
- if (*p == ',')
- p++;
- *ptr = p;
- return 0;
-}
-
-int mixer_ctl_set_value(struct mixer_ctl *ctl, int count, char ** argv)
-{
- unsigned int size;
- unsigned int *tlv = NULL;
- long min, max;
- enum ctl_type type;
- unsigned int tlv_type;
-
- if (is_volume(ctl->info->id.name, &type)) {
- ALOGV("capability: volume\n");
- tlv = calloc(1, DEFAULT_TLV_SIZE);
- if (tlv == NULL) {
- ALOGE("failed to allocate memory\n");
- } else if (!mixer_ctl_read_tlv(ctl, tlv, &min, &max, &tlv_type)) {
- ALOGV("min = %x max = %x", min, max);
- if (set_volume_simple(ctl, argv, min, max, count))
- mixer_ctl_mulvalues(ctl, count, argv);
- } else
- ALOGV("mixer_ctl_read_tlv failed\n");
- free(tlv);
- } else {
- mixer_ctl_mulvalues(ctl, count, argv);
- }
- return 0;
-}
-
-
-int mixer_ctl_select(struct mixer_ctl *ctl, const char *value)
-{
- unsigned n, max;
- struct snd_ctl_elem_value ev;
- unsigned int input_str_len, str_len;
-
- if (ctl->info->type != SNDRV_CTL_ELEM_TYPE_ENUMERATED) {
- errno = EINVAL;
- return -1;
- }
-
- input_str_len = strnlen(value,64);
-
- max = ctl->info->value.enumerated.items;
- for (n = 0; n < max; n++) {
-
- str_len = strnlen(ctl->ename[n], 64);
- if (str_len < input_str_len)
- str_len = input_str_len;
-
- if (!strncmp(value, ctl->ename[n], str_len)) {
- memset(&ev, 0, sizeof(ev));
- ev.value.enumerated.item[0] = n;
- ev.id.numid = ctl->info->id.numid;
- if (ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_ELEM_WRITE, &ev) < 0)
- return -1;
- return 0;
- }
- }
-
- errno = EINVAL;
- return errno;
-}
diff --git a/legacy/libalsa-intf/alsa_pcm.c b/legacy/libalsa-intf/alsa_pcm.c
deleted file mode 100644
index 51c5691..0000000
--- a/legacy/libalsa-intf/alsa_pcm.c
+++ /dev/null
@@ -1,856 +0,0 @@
-/*
-** Copyright 2010, The Android Open-Source Project
-** Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-#define LOG_TAG "alsa_pcm"
-#define LOG_NDEBUG 1
-#ifdef ANDROID
-/* definitions for Android logging */
-#include <utils/Log.h>
-#include <cutils/properties.h>
-#else /* ANDROID */
-#define strlcat g_strlcat
-#define strlcpy g_strlcpy
-#define ALOGI(...) fprintf(stdout, __VA_ARGS__)
-#define ALOGE(...) fprintf(stderr, __VA_ARGS__)
-#define ALOGV(...) fprintf(stderr, __VA_ARGS__)
-#endif /* ANDROID */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <stdarg.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-#include <stdint.h>
-#include <sys/ioctl.h>
-#include <sys/mman.h>
-#include <sys/time.h>
-#include <sys/poll.h>
-#include <linux/ioctl.h>
-#include <linux/types.h>
-
-#include "alsa_audio.h"
-
-#define __force
-#define __bitwise
-#define __user
-
-#define DEBUG 1
-
-enum format_alias {
- S8 = 0,
- U8,
- S16_LE,
- S16_BE,
- U16_LE,
- U16_BE,
- S24_LE,
- S24_BE,
- U24_LE,
- U24_BE,
- S32_LE,
- S32_BE,
- U32_LE,
- U32_BE,
- FLOAT_LE,
- FLOAT_BE,
- FLOAT64_LE,
- FLOAT64_BE,
- IEC958_SUBFRAME_LE,
- IEC958_SUBFRAME_BE,
- MU_LAW,
- A_LAW,
- IMA_ADPCM,
- MPEG,
- GSM,
- SPECIAL = 31,
- S24_3LE,
- S24_3BE,
- U24_3LE,
- U24_3BE,
- S20_3LE,
- S20_3BE,
- U20_3LE,
- U20_3BE,
- S18_3LE,
- S18_3BE,
- U18_3LE,
- U18_3BE,
- FORMAT_LAST,
-};
-const char *formats_list[][2] = {
- {"S8", "Signed 8 bit"},
- {"U8", "Unsigned 8 bit"},
- {"S16_LE", "Signed 16 bit Little Endian"},
- {"S16_BE", "Signed 16 bit Big Endian"},
- {"U16_LE", "Unsigned 16 bit Little Endian"},
- {"U16_BE", "Unsigned 16 bit Big Endian"},
- {"S24_LE", "Signed 24 bit Little Endian"},
- {"S24_BE", "Signed 24 bit Big Endian"},
- {"U24_LE", "Unsigned 24 bit Little Endian"},
- {"U24_BE", "Unsigned 24 bit Big Endian"},
- {"S32_LE", "Signed 32 bit Little Endian"},
- {"S32_BE", "Signed 32 bit Big Endian"},
- {"U32_LE", "Unsigned 32 bit Little Endian"},
- {"U32_BE", "Unsigned 32 bit Big Endian"},
- {"FLOAT_LE", "Float 32 bit Little Endian"},
- {"FLOAT_BE", "Float 32 bit Big Endian"},
- {"FLOAT64_LE", "Float 64 bit Little Endian"},
- {"FLOAT64_BE", "Float 64 bit Big Endian"},
- {"IEC958_SUBFRAME_LE", "IEC-958 Little Endian"},
- {"IEC958_SUBFRAME_BE", "IEC-958 Big Endian"},
- {"MU_LAW", "Mu-Law"},
- {"A_LAW", "A-Law"},
- {"IMA_ADPCM", "Ima-ADPCM"},
- {"MPEG", "MPEG"},
- {"GSM", "GSM"},
- [31] = {"SPECIAL", "Special"},
- {"S24_3LE", "Signed 24 bit Little Endian in 3bytes"},
- {"S24_3BE", "Signed 24 bit Big Endian in 3bytes"},
- {"U24_3LE", "Unsigned 24 bit Little Endian in 3bytes"},
- {"U24_3BE", "Unsigned 24 bit Big Endian in 3bytes"},
- {"S20_3LE", "Signed 20 bit Little Endian in 3bytes"},
- {"S20_3BE", "Signed 20 bit Big Endian in 3bytes"},
- {"U20_3LE", "Unsigned 20 bit Little Endian in 3bytes"},
- {"U20_3BE", "Unsigned 20 bit Big Endian in 3bytes"},
- {"S18_3LE", "Signed 18 bit Little Endian in 3bytes"},
- {"S18_3BE", "Signed 18 bit Big Endian in 3bytes"},
- {"U18_3LE", "Unsigned 18 bit Little Endian in 3bytes"},
- {"U18_3BE", "Unsigned 18 bit Big Endian in 3bytes"},
-};
-
-int get_compressed_format(const char *format)
-{
- const char *ch = format;
- if (strcmp(ch, "MP3") == 0) {
- printf("MP3 is selected\n");
- return FORMAT_MP3;
- } else if (strcmp(ch, "AC3_PASS_THROUGH") == 0) {
- printf("AC3 PASS THROUGH is selected\n");
- return FORMAT_AC3_PASS_THROUGH;
- } else {
- printf("invalid format\n");
- return -1;
- }
- return 0;
-}
-
-int get_format(const char* name)
-{
- int format;
- for (format = 0; format < FORMAT_LAST; format++) {
- if (formats_list[format][0] &&
- strcasecmp(name, formats_list[format][0]) == 0) {
- ALOGV("format_names %s", name);
- return format;
- }
- }
- return -EINVAL;
-}
-
-const char *get_format_name(int format)
-{
- if ((format < FORMAT_LAST) &&
- formats_list[format][0])
- return formats_list[format][0];
- return NULL;
-}
-
-const char *get_format_desc(int format)
-{
- if ((format < FORMAT_LAST) &&
- formats_list[format][1])
- return formats_list[format][1];
- return NULL;
-}
-
-/* alsa parameter manipulation cruft */
-
-#define PARAM_MAX SNDRV_PCM_HW_PARAM_LAST_INTERVAL
-static int oops(struct pcm *pcm, int e, const char *fmt, ...);
-
-static inline int param_is_mask(int p)
-{
- return (p >= SNDRV_PCM_HW_PARAM_FIRST_MASK) &&
- (p <= SNDRV_PCM_HW_PARAM_LAST_MASK);
-}
-
-static inline int param_is_interval(int p)
-{
- return (p >= SNDRV_PCM_HW_PARAM_FIRST_INTERVAL) &&
- (p <= SNDRV_PCM_HW_PARAM_LAST_INTERVAL);
-}
-
-static inline struct snd_interval *param_to_interval(struct snd_pcm_hw_params *p, int n)
-{
- return &(p->intervals[n - SNDRV_PCM_HW_PARAM_FIRST_INTERVAL]);
-}
-
-static inline struct snd_mask *param_to_mask(struct snd_pcm_hw_params *p, int n)
-{
- return &(p->masks[n - SNDRV_PCM_HW_PARAM_FIRST_MASK]);
-}
-
-void param_set_mask(struct snd_pcm_hw_params *p, int n, unsigned bit)
-{
- if (bit >= SNDRV_MASK_MAX)
- return;
- if (param_is_mask(n)) {
- struct snd_mask *m = param_to_mask(p, n);
- m->bits[0] = 0;
- m->bits[1] = 0;
- m->bits[bit >> 5] |= (1 << (bit & 31));
- }
-}
-
-void param_set_min(struct snd_pcm_hw_params *p, int n, unsigned val)
-{
- if (param_is_interval(n)) {
- struct snd_interval *i = param_to_interval(p, n);
- i->min = val;
- }
-}
-
-void param_set_max(struct snd_pcm_hw_params *p, int n, unsigned val)
-{
- if (param_is_interval(n)) {
- struct snd_interval *i = param_to_interval(p, n);
- i->max = val;
- }
-}
-
-void param_set_int(struct snd_pcm_hw_params *p, int n, unsigned val)
-{
- if (param_is_interval(n)) {
- struct snd_interval *i = param_to_interval(p, n);
- i->min = val;
- i->max = val;
- i->integer = 1;
- }
-}
-
-void param_init(struct snd_pcm_hw_params *p)
-{
- int n;
- memset(p, 0, sizeof(*p));
- for (n = SNDRV_PCM_HW_PARAM_FIRST_MASK;
- n <= SNDRV_PCM_HW_PARAM_LAST_MASK; n++) {
- struct snd_mask *m = param_to_mask(p, n);
- m->bits[0] = ~0;
- m->bits[1] = ~0;
- }
- for (n = SNDRV_PCM_HW_PARAM_FIRST_INTERVAL;
- n <= SNDRV_PCM_HW_PARAM_LAST_INTERVAL; n++) {
- struct snd_interval *i = param_to_interval(p, n);
- i->min = 0;
- i->max = ~0;
- }
-}
-
-/* debugging gunk */
-
-#if DEBUG
-static const char *param_name[PARAM_MAX+1] = {
- [SNDRV_PCM_HW_PARAM_ACCESS] = "access",
- [SNDRV_PCM_HW_PARAM_FORMAT] = "format",
- [SNDRV_PCM_HW_PARAM_SUBFORMAT] = "subformat",
-
- [SNDRV_PCM_HW_PARAM_SAMPLE_BITS] = "sample_bits",
- [SNDRV_PCM_HW_PARAM_FRAME_BITS] = "frame_bits",
- [SNDRV_PCM_HW_PARAM_CHANNELS] = "channels",
- [SNDRV_PCM_HW_PARAM_RATE] = "rate",
- [SNDRV_PCM_HW_PARAM_PERIOD_TIME] = "period_time",
- [SNDRV_PCM_HW_PARAM_PERIOD_SIZE] = "period_size",
- [SNDRV_PCM_HW_PARAM_PERIOD_BYTES] = "period_bytes",
- [SNDRV_PCM_HW_PARAM_PERIODS] = "periods",
- [SNDRV_PCM_HW_PARAM_BUFFER_TIME] = "buffer_time",
- [SNDRV_PCM_HW_PARAM_BUFFER_SIZE] = "buffer_size",
- [SNDRV_PCM_HW_PARAM_BUFFER_BYTES] = "buffer_bytes",
- [SNDRV_PCM_HW_PARAM_TICK_TIME] = "tick_time",
-};
-
-void param_dump(struct snd_pcm_hw_params *p)
-{
- int n;
-
- for (n = SNDRV_PCM_HW_PARAM_FIRST_MASK;
- n <= SNDRV_PCM_HW_PARAM_LAST_MASK; n++) {
- struct snd_mask *m = param_to_mask(p, n);
- ALOGV("%s = %08x%08x\n", param_name[n],
- m->bits[1], m->bits[0]);
- }
- for (n = SNDRV_PCM_HW_PARAM_FIRST_INTERVAL;
- n <= SNDRV_PCM_HW_PARAM_LAST_INTERVAL; n++) {
- struct snd_interval *i = param_to_interval(p, n);
- ALOGV("%s = (%d,%d) omin=%d omax=%d int=%d empty=%d\n",
- param_name[n], i->min, i->max, i->openmin,
- i->openmax, i->integer, i->empty);
- }
- ALOGV("info = %08x\n", p->info);
- ALOGV("msbits = %d\n", p->msbits);
- ALOGV("rate = %d/%d\n", p->rate_num, p->rate_den);
- ALOGV("fifo = %d\n", (int) p->fifo_size);
-}
-
-static void info_dump(struct snd_pcm_info *info)
-{
- ALOGV("device = %d\n", info->device);
- ALOGV("subdevice = %d\n", info->subdevice);
- ALOGV("stream = %d\n", info->stream);
- ALOGV("card = %d\n", info->card);
- ALOGV("id = '%s'\n", info->id);
- ALOGV("name = '%s'\n", info->name);
- ALOGV("subname = '%s'\n", info->subname);
- ALOGV("dev_class = %d\n", info->dev_class);
- ALOGV("dev_subclass = %d\n", info->dev_subclass);
- ALOGV("subdevices_count = %d\n", info->subdevices_count);
- ALOGV("subdevices_avail = %d\n", info->subdevices_avail);
-}
-#else
-void param_dump(struct snd_pcm_hw_params *p) {}
-static void info_dump(struct snd_pcm_info *info) {}
-#endif
-
-int param_set_hw_refine(struct pcm *pcm, struct snd_pcm_hw_params *params)
-{
- if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_HW_REFINE, params)) {
- ALOGE("SNDRV_PCM_IOCTL_HW_REFINE failed");
- return -EPERM;
- }
- return 0;
-}
-
-int param_set_hw_params(struct pcm *pcm, struct snd_pcm_hw_params *params)
-{
- if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_HW_PARAMS, params)) {
- return -EPERM;
- }
- pcm->hw_p = params;
- return 0;
-}
-
-int param_set_sw_params(struct pcm *pcm, struct snd_pcm_sw_params *sparams)
-{
- if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_SW_PARAMS, sparams)) {
- return -EPERM;
- }
- pcm->sw_p = sparams;
- return 0;
-}
-
-int pcm_buffer_size(struct snd_pcm_hw_params *params)
-{
- struct snd_interval *i = param_to_interval(params, SNDRV_PCM_HW_PARAM_BUFFER_BYTES);
- ALOGV("%s = (%d,%d) omin=%d omax=%d int=%d empty=%d\n",
- param_name[SNDRV_PCM_HW_PARAM_BUFFER_BYTES],
- i->min, i->max, i->openmin,
- i->openmax, i->integer, i->empty);
- return i->min;
-}
-
-int pcm_period_size(struct snd_pcm_hw_params *params)
-{
- struct snd_interval *i = param_to_interval(params, SNDRV_PCM_HW_PARAM_PERIOD_BYTES);
- ALOGV("%s = (%d,%d) omin=%d omax=%d int=%d empty=%d\n",
- param_name[SNDRV_PCM_HW_PARAM_PERIOD_BYTES],
- i->min, i->max, i->openmin,
- i->openmax, i->integer, i->empty);
- return i->min;
-}
-
-const char* pcm_error(struct pcm *pcm)
-{
- return pcm->error;
-}
-
-static int oops(struct pcm *pcm, int e, const char *fmt, ...)
-{
- va_list ap;
- int sz;
-
- va_start(ap, fmt);
- vsnprintf(pcm->error, PCM_ERROR_MAX, fmt, ap);
- va_end(ap);
- sz = strnlen(pcm->error, PCM_ERROR_MAX);
-
- if (errno)
- snprintf(pcm->error + sz, PCM_ERROR_MAX - sz,
- ": %s", strerror(e));
- return -1;
-}
-
-long pcm_avail(struct pcm *pcm)
-{
- struct snd_pcm_sync_ptr *sync_ptr = pcm->sync_ptr;
- if (pcm->flags & DEBUG_ON) {
- ALOGV("hw_ptr = %d buf_size = %d appl_ptr = %d\n",
- sync_ptr->s.status.hw_ptr,
- pcm->buffer_size,
- sync_ptr->c.control.appl_ptr);
- }
- if (pcm->flags & PCM_IN) {
- long avail = sync_ptr->s.status.hw_ptr - sync_ptr->c.control.appl_ptr;
- if (avail < 0)
- avail += pcm->sw_p->boundary;
- return avail;
- } else {
- long avail = sync_ptr->s.status.hw_ptr - sync_ptr->c.control.appl_ptr + ((pcm->flags & PCM_MONO) ? pcm->buffer_size/2 : pcm->buffer_size/4);
- if (avail < 0)
- avail += pcm->sw_p->boundary;
- else if ((unsigned long) avail >= pcm->sw_p->boundary)
- avail -= pcm->sw_p->boundary;
- return avail;
- }
-}
-
-int sync_ptr(struct pcm *pcm)
-{
- int err;
- err = ioctl(pcm->fd, SNDRV_PCM_IOCTL_SYNC_PTR, pcm->sync_ptr);
- if (err < 0) {
- err = errno;
- ALOGE("SNDRV_PCM_IOCTL_SYNC_PTR failed %d \n", err);
- return err;
- }
-
- return 0;
-}
-
-int mmap_buffer(struct pcm *pcm)
-{
- int err, i;
- char *ptr;
- unsigned size;
- struct snd_pcm_channel_info ch;
- int channels = (pcm->flags & PCM_MONO) ? 1 : 2;
-
- size = pcm->buffer_size;
- if (pcm->flags & DEBUG_ON)
- ALOGV("size = %d\n", size);
- pcm->addr = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED,
- pcm->fd, 0);
- if (pcm->addr)
- return 0;
- else
- return -errno;
-}
-
-/*
- * Destination offset would be mod of total data written
- * (application pointer) and the buffer size of the driver.
- * Hence destination address would be base address(pcm->addr) +
- * destination offset.
- */
-u_int8_t *dst_address(struct pcm *pcm)
-{
- unsigned long pcm_offset = 0;
- struct snd_pcm_sync_ptr *sync_ptr = pcm->sync_ptr;
- unsigned int appl_ptr = 0;
-
- appl_ptr = (pcm->flags & PCM_MONO) ? sync_ptr->c.control.appl_ptr*2 : sync_ptr->c.control.appl_ptr*4;
- pcm_offset = (appl_ptr % (unsigned long)pcm->buffer_size);
- return pcm->addr + pcm_offset;
-
-}
-
-int mmap_transfer(struct pcm *pcm, void *data, unsigned offset,
- long frames)
-{
- struct snd_pcm_sync_ptr *sync_ptr = pcm->sync_ptr;
- unsigned size;
- u_int8_t *dst_addr, *mmaped_addr;
- u_int8_t *src_addr = data;
- int channels = (pcm->flags & PCM_MONO) ? 1 : 2;
-
- dst_addr = dst_address(pcm);
-
- frames = frames * channels *2 ;
-
- while (frames-- > 0) {
- *(u_int8_t*)dst_addr = *(const u_int8_t*)src_addr;
- src_addr++;
- dst_addr++;
- }
- return 0;
-}
-
-int mmap_transfer_capture(struct pcm *pcm, void *data, unsigned offset,
- long frames)
-{
- struct snd_pcm_sync_ptr *sync_ptr = pcm->sync_ptr;
- unsigned long pcm_offset = 0;
- unsigned size;
- u_int8_t *dst_addr, *mmaped_addr;
- u_int8_t *src_addr;
- int channels = (pcm->flags & PCM_MONO) ? 1 : 2;
- unsigned int tmp = (pcm->flags & PCM_MONO) ? sync_ptr->c.control.appl_ptr*2 : sync_ptr->c.control.appl_ptr*4;
-
- pcm_offset = (tmp % (unsigned long)pcm->buffer_size);
- dst_addr = data;
- src_addr = pcm->addr + pcm_offset;
- frames = frames * channels *2 ;
-
- while (frames-- > 0) {
- *(u_int8_t*)dst_addr = *(const u_int8_t*)src_addr;
- src_addr++;
- dst_addr++;
- }
- return 0;
-}
-
-int pcm_prepare(struct pcm *pcm)
-{
- if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_PREPARE)) {
- ALOGE("cannot prepare channel: errno =%d\n", -errno);
- return -errno;
- }
- pcm->running = 1;
- return 0;
-}
-
-static int pcm_write_mmap(struct pcm *pcm, void *data, unsigned count)
-{
- long frames;
- int err;
- int bytes_written;
-
- frames = (pcm->flags & PCM_MONO) ? (count / 2) : (count / 4);
-
- pcm->sync_ptr->flags = SNDRV_PCM_SYNC_PTR_APPL | SNDRV_PCM_SYNC_PTR_AVAIL_MIN;
- err = sync_ptr(pcm);
- if (err == EPIPE) {
- ALOGE("Failed in sync_ptr\n");
- /* we failed to make our window -- try to restart */
- pcm->underruns++;
- pcm->running = 0;
- pcm_prepare(pcm);
- }
- pcm->sync_ptr->c.control.appl_ptr += frames;
- pcm->sync_ptr->flags = 0;
-
- err = sync_ptr(pcm);
- if (err == EPIPE) {
- ALOGE("Failed in sync_ptr 2 \n");
- /* we failed to make our window -- try to restart */
- pcm->underruns++;
- pcm->running = 0;
- pcm_prepare(pcm);
- }
- bytes_written = pcm->sync_ptr->c.control.appl_ptr - pcm->sync_ptr->s.status.hw_ptr;
- if ((bytes_written >= pcm->sw_p->start_threshold) && (!pcm->start)) {
- if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_START)) {
- err = -errno;
- if (errno == EPIPE) {
- ALOGE("Failed in SNDRV_PCM_IOCTL_START\n");
- /* we failed to make our window -- try to restart */
- pcm->underruns++;
- pcm->running = 0;
- pcm_prepare(pcm);
- } else {
- ALOGE("Error no %d \n", errno);
- return -errno;
- }
- } else {
- ALOGD(" start\n");
- pcm->start = 1;
- }
- }
- return 0;
-}
-
-static int pcm_write_nmmap(struct pcm *pcm, void *data, unsigned count)
-{
- struct snd_xferi x;
- int channels = (pcm->flags & PCM_MONO) ? 1 : ((pcm->flags & PCM_5POINT1)? 6 : 2 );
-
- if (pcm->flags & PCM_IN)
- return -EINVAL;
- x.buf = data;
- x.frames = (count / (channels * 2)) ;
-
- for (;;) {
- if (!pcm->running) {
- if (pcm_prepare(pcm))
- return -errno;
- }
- if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_WRITEI_FRAMES, &x)) {
- if (errno == EPIPE) {
- /* we failed to make our window -- try to restart */
- ALOGE("Underrun Error\n");
- pcm->underruns++;
- pcm->running = 0;
- continue;
- }
- return -errno;
- }
- if (pcm->flags & DEBUG_ON)
- ALOGV("Sent frame\n");
- return 0;
- }
-}
-
-int pcm_write(struct pcm *pcm, void *data, unsigned count)
-{
- if (pcm->flags & PCM_MMAP)
- return pcm_write_mmap(pcm, data, count);
- else
- return pcm_write_nmmap(pcm, data, count);
-}
-
-int pcm_read(struct pcm *pcm, void *data, unsigned count)
-{
- struct snd_xferi x;
-
- if (!(pcm->flags & PCM_IN))
- return -EINVAL;
-
- x.buf = data;
- if (pcm->flags & PCM_MONO) {
- x.frames = (count / 2);
- } else if (pcm->flags & PCM_QUAD) {
- x.frames = (count / 8);
- } else if (pcm->flags & PCM_5POINT1) {
- x.frames = (count / 12);
- } else {
- x.frames = (count / 4);
- }
-
- for (;;) {
- if (!pcm->running) {
- if (pcm_prepare(pcm))
- return -errno;
- if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_START)) {
- ALOGE("Arec:SNDRV_PCM_IOCTL_START failed\n");
- return -errno;
- }
- pcm->running = 1;
- }
- if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_READI_FRAMES, &x)) {
- if (errno == EPIPE) {
- /* we failed to make our window -- try to restart */
- ALOGE("Arec:Overrun Error\n");
- pcm->underruns++;
- pcm->running = 0;
- continue;
- }
- ALOGE("Arec: error%d\n", errno);
- return -errno;
- }
- return 0;
- }
-}
-
-static struct pcm bad_pcm = {
- .fd = -1,
-};
-
-static int enable_timer(struct pcm *pcm) {
-
- pcm->timer_fd = open("/dev/snd/timer", O_RDWR | O_NONBLOCK);
- if (pcm->timer_fd < 0) {
- close(pcm->fd);
- ALOGE("cannot open timer device 'timer'");
- return &bad_pcm;
- }
- int arg = 1;
- struct snd_timer_params timer_param;
- struct snd_timer_select sel;
- if (ioctl(pcm->timer_fd, SNDRV_TIMER_IOCTL_TREAD, &arg) < 0) {
- ALOGE("extended read is not supported (SNDRV_TIMER_IOCTL_TREAD)\n");
- }
- memset(&sel, 0, sizeof(sel));
- sel.id.dev_class = SNDRV_TIMER_CLASS_PCM;
- sel.id.dev_sclass = SNDRV_TIMER_SCLASS_NONE;
- sel.id.card = pcm->card_no;
- sel.id.device = pcm->device_no;
- if (pcm->flags & PCM_IN)
- sel.id.subdevice = 1;
- else
- sel.id.subdevice = 0;
-
- if (pcm->flags & DEBUG_ON) {
- ALOGD("sel.id.dev_class= %d\n", sel.id.dev_class);
- ALOGD("sel.id.dev_sclass = %d\n", sel.id.dev_sclass);
- ALOGD("sel.id.card = %d\n", sel.id.card);
- ALOGD("sel.id.device = %d\n", sel.id.device);
- ALOGD("sel.id.subdevice = %d\n", sel.id.subdevice);
- }
- if (ioctl(pcm->timer_fd, SNDRV_TIMER_IOCTL_SELECT, &sel) < 0) {
- ALOGE("SNDRV_TIMER_IOCTL_SELECT failed.\n");
- close(pcm->timer_fd);
- close(pcm->fd);
- return &bad_pcm;
- }
- memset(&timer_param, 0, sizeof(struct snd_timer_params));
- timer_param.flags |= SNDRV_TIMER_PSFLG_AUTO;
- timer_param.ticks = 1;
- timer_param.filter = (1<<SNDRV_TIMER_EVENT_MSUSPEND) | (1<<SNDRV_TIMER_EVENT_MRESUME) | (1<<SNDRV_TIMER_EVENT_TICK);
-
- if (ioctl(pcm->timer_fd, SNDRV_TIMER_IOCTL_PARAMS, &timer_param)< 0) {
- ALOGE("SNDRV_TIMER_IOCTL_PARAMS failed\n");
- }
- if (ioctl(pcm->timer_fd, SNDRV_TIMER_IOCTL_START) < 0) {
- close(pcm->timer_fd);
- ALOGE("SNDRV_TIMER_IOCTL_START failed\n");
- }
- return 0;
-}
-
-static int disable_timer(struct pcm *pcm) {
- if (pcm == &bad_pcm)
- return 0;
- if (ioctl(pcm->timer_fd, SNDRV_TIMER_IOCTL_STOP) < 0)
- ALOGE("SNDRV_TIMER_IOCTL_STOP failed\n");
- return close(pcm->timer_fd);
-}
-
-int pcm_close(struct pcm *pcm)
-{
- if (pcm == &bad_pcm)
- return 0;
-
- if (pcm->flags & PCM_MMAP) {
- disable_timer(pcm);
- if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_DROP) < 0) {
- ALOGE("Reset failed");
- }
-
- if (munmap(pcm->addr, pcm->buffer_size))
- ALOGE("munmap failed");
-
- if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_HW_FREE) < 0) {
- ALOGE("HW_FREE failed");
- }
- }
-
- if (pcm->fd >= 0)
- close(pcm->fd);
- pcm->running = 0;
- pcm->buffer_size = 0;
- pcm->fd = -1;
- if (pcm->sw_p)
- free(pcm->sw_p);
- if (pcm->hw_p)
- free(pcm->hw_p);
- if (pcm->sync_ptr)
- free(pcm->sync_ptr);
- free(pcm);
- return 0;
-}
-
-struct pcm *pcm_open(unsigned flags, char *device)
-{
- char dname[19];
- struct pcm *pcm;
- struct snd_pcm_info info;
- struct snd_pcm_hw_params params;
- struct snd_pcm_sw_params sparams;
- unsigned period_sz;
- unsigned period_cnt;
- char *tmp;
-
- if (flags & DEBUG_ON) {
- ALOGV("pcm_open(0x%08x)",flags);
- ALOGV("device %s\n",device);
- }
-
- pcm = calloc(1, sizeof(struct pcm));
- if (!pcm)
- return &bad_pcm;
-
- tmp = device+4;
- if ((strncmp(device, "hw:",3) != 0) || (strncmp(tmp, ",",1) != 0)){
- ALOGE("Wrong device fromat\n");
- free(pcm);
- return -EINVAL;
- }
-
- if (flags & PCM_IN) {
- strlcpy(dname, "/dev/snd/pcmC", sizeof(dname));
- tmp = device+3;
- strlcat(dname, tmp, (2+strlen(dname))) ;
- pcm->card_no = atoi(tmp);
- strlcat(dname, "D", (sizeof("D")+strlen(dname)));
- tmp = device+5;
- pcm->device_no = atoi(tmp);
- /* should be safe to assume pcm dev ID never exceed 99 */
- if (pcm->device_no > 9)
- strlcat(dname, tmp, (3+strlen(dname)));
- else
- strlcat(dname, tmp, (2+strlen(dname)));
- strlcat(dname, "c", (sizeof("c")+strlen(dname)));
- } else {
- strlcpy(dname, "/dev/snd/pcmC", sizeof(dname));
- tmp = device+3;
- strlcat(dname, tmp, (2+strlen(dname))) ;
- pcm->card_no = atoi(tmp);
- strlcat(dname, "D", (sizeof("D")+strlen(dname)));
- tmp = device+5;
- pcm->device_no = atoi(tmp);
- /* should be safe to assume pcm dev ID never exceed 99 */
- if (pcm->device_no > 9)
- strlcat(dname, tmp, (3+strlen(dname)));
- else
- strlcat(dname, tmp, (2+strlen(dname)));
- strlcat(dname, "p", (sizeof("p")+strlen(dname)));
- }
- if (pcm->flags & DEBUG_ON)
- ALOGV("Device name %s\n", dname);
-
- pcm->sync_ptr = calloc(1, sizeof(struct snd_pcm_sync_ptr));
- if (!pcm->sync_ptr) {
- free(pcm);
- return &bad_pcm;
- }
- pcm->flags = flags;
-
- pcm->fd = open(dname, O_RDWR|O_NONBLOCK);
- if (pcm->fd < 0) {
- free(pcm->sync_ptr);
- free(pcm);
- ALOGE("cannot open device '%s', errno %d", dname, errno);
- return &bad_pcm;
- }
-
- if (fcntl(pcm->fd, F_SETFL, fcntl(pcm->fd, F_GETFL) &
- ~O_NONBLOCK) < 0) {
- close(pcm->fd);
- free(pcm->sync_ptr);
- free(pcm);
- ALOGE("failed to change the flag, errno %d", errno);
- return &bad_pcm;
- }
-
- if (pcm->flags & PCM_MMAP)
- enable_timer(pcm);
-
- if (pcm->flags & DEBUG_ON)
- ALOGV("pcm_open() %s\n", dname);
- if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_INFO, &info)) {
- ALOGE("cannot get info - %s", dname);
- }
- if (pcm->flags & DEBUG_ON)
- info_dump(&info);
-
- return pcm;
-}
-
-int pcm_ready(struct pcm *pcm)
-{
- return pcm->fd >= 0;
-}
diff --git a/legacy/libalsa-intf/alsa_ucm.c b/legacy/libalsa-intf/alsa_ucm.c
deleted file mode 100644
index fac8498..0000000
--- a/legacy/libalsa-intf/alsa_ucm.c
+++ /dev/null
@@ -1,3917 +0,0 @@
-/*
- * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- * * Neither the name of The Linux Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#define LOG_TAG "alsa_ucm"
-//#define LOG_NDDEBUG 0
-
-#ifdef ANDROID
-/* definitions for Android logging */
-#include <utils/Log.h>
-#include <cutils/properties.h>
-#else /* ANDROID */
-#include <math.h>
-#define strlcat g_strlcat
-#define strlcpy g_strlcpy
-#define ALOGI(...) fprintf(stdout, __VA_ARGS__)
-#define ALOGE(...) fprintf(stderr, __VA_ARGS__)
-#define ALOGV(...) fprintf(stderr, __VA_ARGS__)
-#define ALOGD(...) fprintf(stderr, __VA_ARGS__)
-#endif /* ANDROID */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <stdarg.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-#include <pthread.h>
-#include <ctype.h>
-#include <sys/stat.h>
-#include <sys/ioctl.h>
-#include <sys/mman.h>
-#include <sys/time.h>
-#include <sys/poll.h>
-#include <stdint.h>
-#include <dlfcn.h>
-
-#include <linux/ioctl.h>
-#include "msm8960_use_cases.h"
-#if defined(QC_PROP)
- static void (*acdb_send_audio_cal)(int,int);
- static void (*acdb_send_voice_cal)(int,int);
-#endif
-#define PARSE_DEBUG 0
-
-/**
- * Create an identifier
- * fmt - sprintf like format,
- * ... - Optional arguments
- * returns - string allocated or NULL on error
- */
-char *snd_use_case_identifier(const char *fmt, ...)
-{
- ALOGE("API not implemented for now, to be updated if required");
- return NULL;
-}
-
-/**
- * Free a list
- * list - list to free
- * items - Count of strings
- * Return Zero on success, otherwise a negative error code
- */
-int snd_use_case_free_list(const char *list[], int items)
-{
- /* list points to UCM internal static tables,
- * hence there is no need to do a free call
- * just set the list to NULL and return */
- list = NULL;
- return 0;
-}
-
-/**
- * Obtain a list of entries
- * uc_mgr - UCM structure pointer or NULL for card list
- * identifier - NULL for card list
- * list - Returns allocated list
- * returns Number of list entries on success, otherwise a negative error code
- */
-int snd_use_case_get_list(snd_use_case_mgr_t *uc_mgr,
- const char *identifier,
- const char **list[])
-{
- use_case_verb_t *verb_list;
- int verb_index, list_size, index = 0;
-
- if (identifier == NULL) {
- *list = card_list;
- return ((int)MAX_NUM_CARDS);
- }
-
- pthread_mutex_lock(&uc_mgr->card_ctxt_ptr->card_lock);
- if ((uc_mgr->snd_card_index >= (int)MAX_NUM_CARDS) ||
- (uc_mgr->snd_card_index < 0) || (uc_mgr->card_ctxt_ptr == NULL)) {
- ALOGE("snd_use_case_get_list(): failed, invalid arguments");
- pthread_mutex_unlock(&uc_mgr->card_ctxt_ptr->card_lock);
- return -EINVAL;
- }
-
- if (!strncmp(identifier, "_verbs", 6)) {
- while(strncmp(uc_mgr->card_ctxt_ptr->verb_list[index],
- SND_UCM_END_OF_LIST, strlen(SND_UCM_END_OF_LIST))) {
- ALOGV("Index:%d Verb:%s", index,
- uc_mgr->card_ctxt_ptr->verb_list[index]);
- index++;
- }
- *list = (char ***)uc_mgr->card_ctxt_ptr->verb_list;
- pthread_mutex_unlock(&uc_mgr->card_ctxt_ptr->card_lock);
- return index;
- } else if (!strncmp(identifier, "_devices", 8)) {
- if (!strncmp(uc_mgr->card_ctxt_ptr->current_verb,
- SND_USE_CASE_VERB_INACTIVE, strlen(SND_USE_CASE_VERB_INACTIVE))) {
- ALOGE("Use case verb name not set, invalid current verb");
- pthread_mutex_unlock(&uc_mgr->card_ctxt_ptr->card_lock);
- return -EINVAL;
- }
- verb_list = uc_mgr->card_ctxt_ptr->use_case_verb_list;
- while(strncmp(uc_mgr->card_ctxt_ptr->current_verb,
- verb_list[index].use_case_name,
- (strlen(verb_list[index].use_case_name)+1))) {
- index++;
- }
- verb_index = index;
- index = 0;
- while(strncmp(verb_list[verb_index].device_list[index],
- SND_UCM_END_OF_LIST, strlen(SND_UCM_END_OF_LIST))) {
- ALOGV("Index:%d Device:%s", index,
- verb_list[verb_index].device_list[index]);
- index++;
- }
- *list = verb_list[verb_index].device_list;
- pthread_mutex_unlock(&uc_mgr->card_ctxt_ptr->card_lock);
- return index;
- } else if (!strncmp(identifier, "_modifiers", 10)) {
- if (!strncmp(uc_mgr->card_ctxt_ptr->current_verb,
- SND_USE_CASE_VERB_INACTIVE, MAX_STR_LEN)) {
- ALOGE("Use case verb name not set, invalid current verb");
- pthread_mutex_unlock(&uc_mgr->card_ctxt_ptr->card_lock);
- return -EINVAL;
- }
- verb_list = uc_mgr->card_ctxt_ptr->use_case_verb_list;
- while(strncmp(uc_mgr->card_ctxt_ptr->current_verb,
- verb_list[index].use_case_name,
- (strlen(verb_list[index].use_case_name)+1))) {
- index++;
- }
- verb_index = index;
- index = 0;
- while(strncmp(verb_list[verb_index].modifier_list[index],
- SND_UCM_END_OF_LIST, strlen(SND_UCM_END_OF_LIST))) {
- ALOGV("Index:%d Modifier:%s", index,
- verb_list[verb_index].modifier_list[index]);
- index++;
- }
- *list = verb_list[verb_index].modifier_list;
- pthread_mutex_unlock(&uc_mgr->card_ctxt_ptr->card_lock);
- return index;
- } else if (!strncmp(identifier, "_enadevs", 8)) {
- if (uc_mgr->device_list_count) {
- for (index = 0; index < uc_mgr->device_list_count; index++) {
- free(uc_mgr->current_device_list[index]);
- uc_mgr->current_device_list[index] = NULL;
- }
- free(uc_mgr->current_device_list);
- uc_mgr->current_device_list = NULL;
- uc_mgr->device_list_count = 0;
- }
- list_size =
- snd_ucm_get_size_of_list(uc_mgr->card_ctxt_ptr->dev_list_head);
- uc_mgr->device_list_count = list_size;
- if (list_size > 0) {
- uc_mgr->current_device_list =
- (char **)malloc(sizeof(char *)*list_size);
- if (uc_mgr->current_device_list == NULL) {
- *list = NULL;
- pthread_mutex_unlock(&uc_mgr->card_ctxt_ptr->card_lock);
- return -ENOMEM;
- }
- for (index = 0; index < list_size; index++) {
- uc_mgr->current_device_list[index] =
- snd_ucm_get_value_at_index(uc_mgr->card_ctxt_ptr->dev_list_head,
- index);
- }
- }
- *list = (const char **)uc_mgr->current_device_list;
- pthread_mutex_unlock(&uc_mgr->card_ctxt_ptr->card_lock);
- return (list_size);
- } else if (!strncmp(identifier, "_enamods", 8)) {
- if (uc_mgr->modifier_list_count) {
- for (index = 0; index < uc_mgr->modifier_list_count; index++) {
- free(uc_mgr->current_modifier_list[index]);
- uc_mgr->current_modifier_list[index] = NULL;
- }
- free(uc_mgr->current_modifier_list);
- uc_mgr->current_modifier_list = NULL;
- uc_mgr->modifier_list_count = 0;
- }
- list_size =
- snd_ucm_get_size_of_list(uc_mgr->card_ctxt_ptr->mod_list_head);
- uc_mgr->modifier_list_count = list_size;
- if (list_size > 0) {
- uc_mgr->current_modifier_list =
- (char **)malloc(sizeof(char *) * list_size);
- if (uc_mgr->current_modifier_list == NULL) {
- *list = NULL;
- pthread_mutex_unlock(&uc_mgr->card_ctxt_ptr->card_lock);
- return -ENOMEM;
- }
- for (index = 0; index < list_size; index++) {
- uc_mgr->current_modifier_list[index] =
- snd_ucm_get_value_at_index(uc_mgr->card_ctxt_ptr->mod_list_head,
- index);
- }
- }
- *list = (const char **)uc_mgr->current_modifier_list;
- pthread_mutex_unlock(&uc_mgr->card_ctxt_ptr->card_lock);
- return (list_size);
- } else {
- ALOGE("Invalid identifier: %s", identifier);
- pthread_mutex_unlock(&uc_mgr->card_ctxt_ptr->card_lock);
- return -EINVAL;
- }
-}
-
-
-/**
- * Get current value of the identifier
- * identifier - NULL for current card
- * _verb
- * <Name>/<_device/_modifier>
- * Name - PlaybackPCM
- * CapturePCM
- * PlaybackCTL
- * CaptureCTL
- * value - Value pointer
- * returns Zero if success, otherwise a negative error code
- */
-int snd_use_case_get(snd_use_case_mgr_t *uc_mgr,
- const char *identifier,
- const char **value)
-{
- card_mctrl_t *ctrl_list;
- use_case_verb_t *verb_list;
- char ident[MAX_STR_LEN], *ident1, *ident2, *temp_ptr;
- int index, verb_index = 0, ret = 0;
-
- pthread_mutex_lock(&uc_mgr->card_ctxt_ptr->card_lock);
- if ((uc_mgr->snd_card_index >= (int)MAX_NUM_CARDS) ||
- (uc_mgr->snd_card_index < 0) || (uc_mgr->card_ctxt_ptr == NULL)) {
- ALOGE("snd_use_case_get(): failed, invalid arguments");
- pthread_mutex_unlock(&uc_mgr->card_ctxt_ptr->card_lock);
- return -EINVAL;
- }
-
- if (identifier == NULL) {
- if (uc_mgr->card_ctxt_ptr->card_name != NULL) {
- *value = strdup(uc_mgr->card_ctxt_ptr->card_name);
- } else {
- *value = NULL;
- }
- pthread_mutex_unlock(&uc_mgr->card_ctxt_ptr->card_lock);
- return 0;
- }
-
- if (!strncmp(identifier, "_verb", 5)) {
- if (uc_mgr->card_ctxt_ptr->current_verb != NULL) {
- *value = strdup(uc_mgr->card_ctxt_ptr->current_verb);
- } else {
- *value = NULL;
- }
- pthread_mutex_unlock(&uc_mgr->card_ctxt_ptr->card_lock);
- return 0;
- }
-
- strlcpy(ident, identifier, sizeof(ident));
- if(!(ident1 = strtok_r(ident, "/", &temp_ptr))) {
- ALOGE("No valid identifier found: %s", ident);
- ret = -EINVAL;
- } else {
- if ((!strncmp(ident1, "PlaybackPCM", 11)) ||
- (!strncmp(ident1, "CapturePCM", 10))) {
- ident2 = strtok_r(NULL, "/", &temp_ptr);
- index = 0;
- if (ident2 != NULL) {
- verb_index = uc_mgr->card_ctxt_ptr->current_verb_index;
- verb_list = uc_mgr->card_ctxt_ptr->use_case_verb_list;
- if((get_usecase_type(uc_mgr, ident2)) == CTRL_LIST_VERB) {
- ctrl_list = verb_list[verb_index].verb_ctrls;
- } else {
- ctrl_list = verb_list[verb_index].mod_ctrls;
- }
- if((verb_index < 0) ||
- (!strncmp(uc_mgr->card_ctxt_ptr->current_verb,
- SND_UCM_END_OF_LIST, 3)) || (ctrl_list == NULL)) {
- ALOGE("Invalid current verb value: %s - %d",
- uc_mgr->card_ctxt_ptr->current_verb, verb_index);
- pthread_mutex_unlock(&uc_mgr->card_ctxt_ptr->card_lock);
- return -EINVAL;
- }
- while(strncmp(ctrl_list[index].case_name, ident2,
- (strlen(ident2)+1))) {
- if (!strncmp(ctrl_list[index].case_name,
- SND_UCM_END_OF_LIST, strlen(SND_UCM_END_OF_LIST))){
- *value = NULL;
- ret = -EINVAL;
- break;
- } else {
- index++;
- }
- }
- } else {
- ret = -EINVAL;
- }
- if (ret < 0) {
- ALOGE("No valid device/modifier found with given identifier: %s",
- ident2);
- } else {
- if(!strncmp(ident1, "PlaybackPCM", 11)) {
- if (ctrl_list[index].playback_dev_name) {
- *value = strdup(ctrl_list[index].playback_dev_name);
- } else {
- *value = NULL;
- ret = -ENODEV;
- }
- } else if(!strncmp(ident1, "CapturePCM", 10)) {
- if (ctrl_list[index].capture_dev_name) {
- *value = strdup(ctrl_list[index].capture_dev_name);
- } else {
- *value = NULL;
- ret = -ENODEV;
- }
- } else {
- ALOGE("No valid device name exists for given identifier: %s",
- ident2);
- *value = NULL;
- ret = -ENODEV;
- }
- }
- } else if ((!strncmp(ident1, "PlaybackCTL", 11)) ||
- (!strncmp(ident1, "CaptureCTL", 10))) {
- if(uc_mgr->card_ctxt_ptr->control_device != NULL) {
- *value = strdup(uc_mgr->card_ctxt_ptr->control_device);
- } else {
- ALOGE("No valid control device found");
- *value = NULL;
- ret = -ENODEV;
- }
- } else if (!strncmp(ident1, "ACDBID", 11)) {
- ident2 = strtok_r(NULL, "/", &temp_ptr);
- index = 0; verb_index = 0;
- verb_list = uc_mgr->card_ctxt_ptr->use_case_verb_list;
- if((verb_index < 0) ||
- (!strncmp(uc_mgr->card_ctxt_ptr->current_verb,
- SND_UCM_END_OF_LIST, 3)) ||
- (verb_list[verb_index].verb_ctrls == NULL)) {
- ALOGE("Invalid current verb value: %s - %d",
- uc_mgr->card_ctxt_ptr->current_verb, verb_index);
- pthread_mutex_unlock(&uc_mgr->card_ctxt_ptr->card_lock);
- return -EINVAL;
- }
- ctrl_list = verb_list[verb_index].device_ctrls;
- if (ident2 != NULL) {
- while(strncmp(ctrl_list[index].case_name, ident2,
- MAX_LEN(ctrl_list[index].case_name,ident2))) {
- if (!strncmp(ctrl_list[index].case_name, SND_UCM_END_OF_LIST,
- strlen(SND_UCM_END_OF_LIST))){
- ret = -EINVAL;
- break;
- } else {
- index++;
- }
- }
- }
- if (ret < 0) {
- ALOGE("No valid device/modifier found with given identifier: %s",
- ident2);
- } else {
- if (verb_list[verb_index].device_ctrls[index].acdb_id) {
- ret = verb_list[verb_index].device_ctrls[index].acdb_id;
- } else {
- ret = -ENODEV;
- }
- }
- } else if (!strncmp(ident1, "EffectsMixerCTL", 11)) {
- ident2 = strtok_r(NULL, "/", &temp_ptr);
- index = 0; verb_index = 0;
- verb_list = uc_mgr->card_ctxt_ptr->use_case_verb_list;
- if((verb_index < 0) ||
- (!strncmp(uc_mgr->card_ctxt_ptr->current_verb,
- SND_UCM_END_OF_LIST, 3)) ||
- (verb_list[verb_index].verb_ctrls == NULL)) {
- ALOGE("Invalid current verb value: %s - %d",
- uc_mgr->card_ctxt_ptr->current_verb, verb_index);
- pthread_mutex_unlock(&uc_mgr->card_ctxt_ptr->card_lock);
- return -EINVAL;
- }
- ctrl_list = verb_list[verb_index].device_ctrls;
- if (ident2 != NULL) {
- while(strncmp(ctrl_list[index].case_name, ident2, strlen(ident2)+1)) {
- if (!strncmp(ctrl_list[index].case_name, SND_UCM_END_OF_LIST,
- strlen(SND_UCM_END_OF_LIST))){
- ret = -EINVAL;
- break;
- } else {
- index++;
- }
- }
- }
- if (ret < 0) {
- ALOGE("No valid device/modifier found with given identifier: %s",
- ident2);
- } else {
- if (verb_list[verb_index].device_ctrls[index].effects_mixer_ctl) {
- *value = strdup(verb_list[verb_index].device_ctrls[index].effects_mixer_ctl);
- } else {
- *value = NULL;
- ret = -ENODEV;
- }
- }
- } else {
- ALOGE("Unsupported identifier value: %s", ident1);
- *value = NULL;
- ret = -EINVAL;
- }
- }
- pthread_mutex_unlock(&uc_mgr->card_ctxt_ptr->card_lock);
- return ret;
-}
-
-/**
- * Get current status
- * uc_mgr - UCM structure
- * identifier - _devstatus/<device>,
- _modstatus/<modifier>
- * value - result
- * returns 0 on success, otherwise a negative error code
- */
-int snd_use_case_geti(snd_use_case_mgr_t *uc_mgr,
- const char *identifier,
- long *value)
-{
- char ident[MAX_STR_LEN], *ident1, *ident2, *ident_value, *temp_ptr;
- int index, list_size, ret = -EINVAL;
-
- pthread_mutex_lock(&uc_mgr->card_ctxt_ptr->card_lock);
- if ((uc_mgr->snd_card_index >= (int)MAX_NUM_CARDS) ||
- (uc_mgr->snd_card_index < 0) || (uc_mgr->card_ctxt_ptr == NULL)) {
- ALOGE("snd_use_case_geti(): failed, invalid arguments");
- pthread_mutex_unlock(&uc_mgr->card_ctxt_ptr->card_lock);
- return -EINVAL;
- }
-
- *value = 0;
- strlcpy(ident, identifier, sizeof(ident));
- if(!(ident1 = strtok_r(ident, "/", &temp_ptr))) {
- ALOGE("No valid identifier found: %s", ident);
- ret = -EINVAL;
- } else {
- if (!strncmp(ident1, "_devstatus", 10)) {
- ident2 = strtok_r(NULL, "/", &temp_ptr);
- if (ident2 != NULL) {
- list_size =
- snd_ucm_get_size_of_list(uc_mgr->card_ctxt_ptr->dev_list_head);
- for (index = 0; index < list_size; index++) {
- if ((ident_value =
- snd_ucm_get_value_at_index(uc_mgr->card_ctxt_ptr->dev_list_head,
- index))) {
- if (!strncmp(ident2, ident_value,
- (strlen(ident_value)+1))) {
- *value = 1;
- free(ident_value);
- ident_value = NULL;
- break;
- } else {
- free(ident_value);
- ident_value = NULL;
- }
- }
- }
- ret = 0;
- }
- } else if (!strncmp(ident1, "_modstatus", 10)) {
- ident2 = strtok_r(NULL, "/", &temp_ptr);
- if (ident2 != NULL) {
- list_size =
- snd_ucm_get_size_of_list(uc_mgr->card_ctxt_ptr->mod_list_head);
- for (index = 0; index < list_size; index++) {
- if((ident_value =
- snd_ucm_get_value_at_index(uc_mgr->card_ctxt_ptr->mod_list_head,
- index))) {
- if (!strncmp(ident2, ident_value,
- (strlen(ident_value)+1))) {
- *value = 1;
- free(ident_value);
- ident_value = NULL;
- break;
- } else {
- free(ident_value);
- ident_value = NULL;
- }
- }
- }
- ret = 0;
- }
- } else {
- ALOGE("Unknown identifier: %s", ident1);
- }
- }
- pthread_mutex_unlock(&uc_mgr->card_ctxt_ptr->card_lock);
- return ret;
-}
-
-static int check_devices_for_voice_call(snd_use_case_mgr_t *uc_mgr,
-const char *use_case)
-{
- struct snd_ucm_ident_node *dev_node = NULL;
- int index = 0, list_size = 0, rx_dev_status = 0, tx_dev_status = 0;
-
- if ((!strncmp(use_case, SND_USE_CASE_VERB_VOICECALL,
- strlen(SND_USE_CASE_VERB_VOICECALL))) ||
- (!strncmp(use_case, SND_USE_CASE_VERB_IP_VOICECALL,
- strlen(SND_USE_CASE_VERB_IP_VOICECALL))) ||
- (!strncmp(use_case, SND_USE_CASE_MOD_PLAY_VOICE,
- strlen(SND_USE_CASE_MOD_PLAY_VOICE))) ||
- (!strncmp(use_case, SND_USE_CASE_MOD_PLAY_VOIP,
- strlen(SND_USE_CASE_MOD_PLAY_VOIP)))) {
- ALOGV("check_devices_for_voice_call(): voice cap detected\n");
- list_size =
- snd_ucm_get_size_of_list(uc_mgr->card_ctxt_ptr->dev_list_head);
- for (index = 0; index < list_size; index++) {
- if ((dev_node =
- snd_ucm_get_device_node(uc_mgr->card_ctxt_ptr->dev_list_head,
- index))) {
- if (dev_node->capability == CAP_RX && dev_node->active == 1) {
- rx_dev_status = 1;
- } else if (dev_node->capability == CAP_TX && dev_node->active == 1) {
- tx_dev_status = 1;
- }
- }
- }
- if (rx_dev_status == 1 && tx_dev_status == 1) {
- ALOGV("check_devices_for_voice_call(): Rx and Tx devices enabled\n");
- return 0;
- } else {
- ALOGV("check_devices_for_voice_call(): Rx/Tx dev not enabled: \
- %d,%d\n", rx_dev_status, tx_dev_status);
- return 1;
- }
- }
- return 0;
-}
-
-static int snd_use_case_apply_voice_acdb(snd_use_case_mgr_t *uc_mgr,
-int use_case_index)
-{
- card_mctrl_t *ctrl_list;
- int list_size, index, verb_index, ret = 0, voice_acdb = 0, rx_id, tx_id;
- char *ident_value = NULL;
-
- /* Check if voice call use case/modifier exists */
- if ((!strncmp(uc_mgr->card_ctxt_ptr->current_verb,
- SND_USE_CASE_VERB_VOICECALL, strlen(SND_USE_CASE_VERB_VOICECALL))) ||
- (!strncmp(uc_mgr->card_ctxt_ptr->current_verb,
- SND_USE_CASE_VERB_IP_VOICECALL,
- strlen(SND_USE_CASE_VERB_IP_VOICECALL)))) {
- voice_acdb = 1;
- }
- if (voice_acdb != 1) {
- list_size =
- snd_ucm_get_size_of_list(uc_mgr->card_ctxt_ptr->mod_list_head);
- for (index = 0; index < list_size; index++) {
- if ((ident_value =
- snd_ucm_get_value_at_index(uc_mgr->card_ctxt_ptr->mod_list_head,
- index))) {
- if ((!strncmp(ident_value, SND_USE_CASE_MOD_PLAY_VOICE,
- strlen(SND_USE_CASE_MOD_PLAY_VOICE))) ||
- (!strncmp(ident_value, SND_USE_CASE_MOD_PLAY_VOIP,
- strlen(SND_USE_CASE_MOD_PLAY_VOIP)))) {
- voice_acdb = 1;
- free(ident_value);
- ident_value = NULL;
- break;
- }
- free(ident_value);
- ident_value = NULL;
- }
- }
- }
-
- verb_index = uc_mgr->card_ctxt_ptr->current_verb_index;
- if((verb_index < 0) ||
- (!strncmp(uc_mgr->card_ctxt_ptr->current_verb,
- SND_UCM_END_OF_LIST, 3))) {
- ALOGE("Invalid current verb value: %s - %d",
- uc_mgr->card_ctxt_ptr->current_verb, verb_index);
- return -EINVAL;
- }
- if (voice_acdb == 1) {
- ctrl_list =
- uc_mgr->card_ctxt_ptr->use_case_verb_list[verb_index].device_ctrls;
- list_size =
- snd_ucm_get_size_of_list(uc_mgr->card_ctxt_ptr->dev_list_head);
- for (index = 0; index < list_size; index++) {
- if ((ident_value =
- snd_ucm_get_value_at_index(uc_mgr->card_ctxt_ptr->dev_list_head,
- index))) {
- if (strncmp(ident_value, ctrl_list[use_case_index].case_name,
- (strlen(ctrl_list[use_case_index].case_name)+1))) {
- break;
- }
- free(ident_value);
- ident_value = NULL;
- }
- }
- index = 0;
- if (ident_value != NULL) {
- while(strncmp(ctrl_list[index].case_name, ident_value,
- (strlen(ident_value)+1))) {
- if (!strncmp(ctrl_list[index].case_name, SND_UCM_END_OF_LIST,
- strlen(SND_UCM_END_OF_LIST))) {
- ret = -EINVAL;
- break;
- }
- index++;
- }
- if (ret < 0) {
- ALOGE("No valid device found: %s",ident_value);
- } else {
- if (ctrl_list[use_case_index].capability == CAP_RX) {
- rx_id = ctrl_list[use_case_index].acdb_id;
- tx_id = ctrl_list[index].acdb_id;
- } else {
- rx_id = ctrl_list[index].acdb_id;
- tx_id = ctrl_list[use_case_index].acdb_id;
- }
- if(((rx_id == DEVICE_SPEAKER_MONO_RX_ACDB_ID)||(rx_id == DEVICE_SPEAKER_STEREO_RX_ACDB_ID))
- && tx_id == DEVICE_HANDSET_TX_ACDB_ID) {
- tx_id = DEVICE_SPEAKER_TX_ACDB_ID;
- } else if (((rx_id == DEVICE_SPEAKER_MONO_RX_ACDB_ID )||(rx_id == DEVICE_SPEAKER_STEREO_RX_ACDB_ID))
- && tx_id == DEVICE_HANDSET_TX_FV5_ACDB_ID) {
- tx_id = DEVICE_SPEAKER_TX_FV5_ACDB_ID;
- }
-
- if ((rx_id != uc_mgr->current_rx_device) ||
- (tx_id != uc_mgr->current_tx_device)) {
- uc_mgr->current_rx_device = rx_id;
- uc_mgr->current_tx_device = tx_id;
- ALOGD("Voice acdb: rx id %d tx id %d",
- uc_mgr->current_rx_device,
- uc_mgr->current_tx_device);
- if (uc_mgr->acdb_handle && !uc_mgr->isFusion3Platform) {
- acdb_send_voice_cal = dlsym(uc_mgr->acdb_handle,"acdb_loader_send_voice_cal");
- if (acdb_send_voice_cal == NULL) {
- ALOGE("ucm: dlsym: Error:%s Loading acdb_loader_send_voice_cal", dlerror());
- }else {
- acdb_send_voice_cal(uc_mgr->current_rx_device,
- uc_mgr->current_tx_device);
- }
- }
- } else {
- ALOGV("Voice acdb: Required acdb already pushed \
- rx id %d tx id %d", uc_mgr->current_rx_device,
- uc_mgr->current_tx_device);
- }
- }
- free(ident_value);
- ident_value = NULL;
- }
- } else {
- ALOGV("No voice use case found");
- uc_mgr->current_rx_device = -1; uc_mgr->current_tx_device = -1;
- ret = -ENODEV;
- }
- return ret;
-}
-
-int get_use_case_index(snd_use_case_mgr_t *uc_mgr, const char *use_case,
-int ctrl_list_type)
-{
- use_case_verb_t *verb_list;
- card_mctrl_t *ctrl_list;
- int ret = 0, index = 0, verb_index;
-
- verb_list = uc_mgr->card_ctxt_ptr->use_case_verb_list;
- verb_index = uc_mgr->card_ctxt_ptr->current_verb_index;
- if (ctrl_list_type == CTRL_LIST_VERB) {
- ctrl_list =
- uc_mgr->card_ctxt_ptr->use_case_verb_list[verb_index].verb_ctrls;
- } else if (ctrl_list_type == CTRL_LIST_DEVICE) {
- ctrl_list =
- uc_mgr->card_ctxt_ptr->use_case_verb_list[verb_index].device_ctrls;
- } else if (ctrl_list_type == CTRL_LIST_MODIFIER) {
- ctrl_list =
- uc_mgr->card_ctxt_ptr->use_case_verb_list[verb_index].mod_ctrls;
- } else {
- ctrl_list = NULL;
- }
- if((verb_index < 0) ||
- (!strncmp(uc_mgr->card_ctxt_ptr->current_verb, SND_UCM_END_OF_LIST, 3)) ||
- (ctrl_list == NULL) || (ctrl_list[index].case_name == NULL)) {
- ALOGE("Invalid current verb value: %s - %d",
- uc_mgr->card_ctxt_ptr->current_verb, verb_index);
- return -EINVAL;
- }
- while(strncmp(ctrl_list[index].case_name, use_case, (strlen(use_case)+1))) {
- if (!strncmp(ctrl_list[index].case_name, SND_UCM_END_OF_LIST,
- strlen(SND_UCM_END_OF_LIST))) {
- ret = -EINVAL;
- break;
- }
- index++;
- if (ctrl_list[index].case_name == NULL) {
- ALOGE("Invalid case_name at index %d", index);
- ret = -EINVAL;
- break;
- }
- }
- if (ret < 0) {
- return ret;
- } else {
- return index;
- }
-}
-
-/* Apply the required mixer controls for specific use case
- * uc_mgr - UCM structure pointer
- * use_case - use case name
- * return 0 on sucess, otherwise a negative error code
- */
-int snd_use_case_apply_mixer_controls(snd_use_case_mgr_t *uc_mgr,
-const char *use_case, int enable, int ctrl_list_type, int uc_index)
-{
- card_mctrl_t *ctrl_list;
- mixer_control_t *mixer_list;
- struct mixer_ctl *ctl;
- int i, ret = 0, index = 0, verb_index, mixer_count;
-
- verb_index = uc_mgr->card_ctxt_ptr->current_verb_index;
- if (ctrl_list_type == CTRL_LIST_VERB) {
- ctrl_list =
- uc_mgr->card_ctxt_ptr->use_case_verb_list[verb_index].verb_ctrls;
- } else if (ctrl_list_type == CTRL_LIST_DEVICE) {
- ctrl_list =
- uc_mgr->card_ctxt_ptr->use_case_verb_list[verb_index].device_ctrls;
- } else if (ctrl_list_type == CTRL_LIST_MODIFIER) {
- ctrl_list =
- uc_mgr->card_ctxt_ptr->use_case_verb_list[verb_index].mod_ctrls;
- } else {
- ctrl_list = NULL;
- }
- if((verb_index < 0) ||
- (!strncmp(uc_mgr->card_ctxt_ptr->current_verb, SND_UCM_END_OF_LIST, 3)) ||
- (ctrl_list == NULL)) {
- ALOGE("Invalid current verb value: %s - %d",
- uc_mgr->card_ctxt_ptr->current_verb, verb_index);
- return -EINVAL;
- }
- if (uc_index < 0) {
- ALOGE("No valid use case found with the use case: %s", use_case);
- ret = -ENODEV;
- } else {
- if (!uc_mgr->card_ctxt_ptr->mixer_handle) {
- ALOGE("Control device not initialized");
- ret = -ENODEV;
- } else {
- if (enable &&
- (check_devices_for_voice_call(uc_mgr, use_case) != NULL))
- return ret;
- ALOGD("Set mixer controls for %s enable %d", use_case, enable);
- if (ctrl_list[uc_index].acdb_id && ctrl_list[uc_index].capability) {
- if (enable) {
- if (snd_use_case_apply_voice_acdb(uc_mgr, uc_index)) {
- ALOGV("acdb_id %d cap %d enable %d",
- ctrl_list[uc_index].acdb_id,
- ctrl_list[uc_index].capability, enable);
- if (uc_mgr->acdb_handle) {
- acdb_send_audio_cal = dlsym(uc_mgr->acdb_handle,"acdb_loader_send_audio_cal");
- if (acdb_send_audio_cal == NULL) {
- ALOGE("ucm:dlsym:Error:%s Loading acdb_loader_send_audio_cal", dlerror());
- } else {
- acdb_send_audio_cal(ctrl_list[uc_index].acdb_id,
- ctrl_list[uc_index].capability);
- }
- }
- }
- }
- }
- if (enable) {
- mixer_list = ctrl_list[uc_index].ena_mixer_list;
- mixer_count = ctrl_list[uc_index].ena_mixer_count;
- } else {
- mixer_list = ctrl_list[uc_index].dis_mixer_list;
- mixer_count = ctrl_list[uc_index].dis_mixer_count;
- }
- for(index = 0; index < mixer_count; index++) {
- if (mixer_list == NULL) {
- ALOGE("No valid controls exist for this case: %s", use_case);
- break;
- }
- ctl = mixer_get_control(uc_mgr->card_ctxt_ptr->mixer_handle,
- mixer_list[index].control_name, 0);
- if (ctl) {
- if (mixer_list[index].type == TYPE_INT) {
- ALOGV("Setting mixer control: %s, value: %d",
- mixer_list[index].control_name,
- mixer_list[index].value);
- ret = mixer_ctl_set(ctl, mixer_list[index].value);
- } else if (mixer_list[index].type == TYPE_MULTI_VAL) {
- ALOGD("Setting multi value: %s",
- mixer_list[index].control_name);
- ret = mixer_ctl_set_value(ctl, mixer_list[index].value,
- mixer_list[index].mulval);
- if (ret < 0)
- ALOGE("Failed to set multi value control %s\n",
- mixer_list[index].control_name);
- } else {
- ALOGV("Setting mixer control: %s, value: %s",
- mixer_list[index].control_name,
- mixer_list[index].string);
- ret = mixer_ctl_select(ctl, mixer_list[index].string);
- }
- if ((ret != 0) && enable) {
- /* Disable all the mixer controls which are
- * already enabled before failure */
- mixer_list = ctrl_list[uc_index].dis_mixer_list;
- mixer_count = ctrl_list[uc_index].dis_mixer_count;
- for(i = 0; i < mixer_count; i++) {
- ctl = mixer_get_control(
- uc_mgr->card_ctxt_ptr->mixer_handle,
- mixer_list[i].control_name, 0);
- if (ctl) {
- if (mixer_list[i].type == TYPE_INT) {
- ret = mixer_ctl_set(ctl,
- mixer_list[i].value);
- } else {
- ret = mixer_ctl_select(ctl,
- mixer_list[i].string);
- }
- }
- }
- ALOGE("Failed to enable the mixer controls for %s",
- use_case);
- break;
- }
- }
- }
- }
- }
- return ret;
-}
-
-int getUseCaseType(const char *useCase)
-{
- ALOGV("getUseCaseType: use case is %s\n", useCase);
- if (!strncmp(useCase, SND_USE_CASE_VERB_HIFI,
- MAX_LEN(useCase,SND_USE_CASE_VERB_HIFI)) ||
- !strncmp(useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_MUSIC,
- MAX_LEN(useCase,SND_USE_CASE_VERB_HIFI_LOWLATENCY_MUSIC)) ||
- !strncmp(useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER,
- MAX_LEN(useCase,SND_USE_CASE_VERB_HIFI_LOW_POWER)) ||
- !strncmp(useCase, SND_USE_CASE_VERB_HIFI_TUNNEL,
- MAX_LEN(useCase,SND_USE_CASE_VERB_HIFI_TUNNEL)) ||
- !strncmp(useCase, SND_USE_CASE_VERB_HIFI2,
- MAX_LEN(useCase,SND_USE_CASE_VERB_HIFI2)) ||
- !strncmp(useCase, SND_USE_CASE_VERB_DIGITAL_RADIO,
- MAX_LEN(useCase,SND_USE_CASE_VERB_DIGITAL_RADIO)) ||
- !strncmp(useCase, SND_USE_CASE_MOD_PLAY_MUSIC,
- MAX_LEN(useCase,SND_USE_CASE_MOD_PLAY_MUSIC)) ||
- !strncmp(useCase, SND_USE_CASE_MOD_PLAY_LOWLATENCY_MUSIC,
- MAX_LEN(useCase,SND_USE_CASE_MOD_PLAY_LOWLATENCY_MUSIC)) ||
- !strncmp(useCase, SND_USE_CASE_MOD_PLAY_MUSIC2,
- MAX_LEN(useCase,SND_USE_CASE_MOD_PLAY_MUSIC2)) ||
- !strncmp(useCase, SND_USE_CASE_MOD_PLAY_LPA,
- MAX_LEN(useCase,SND_USE_CASE_MOD_PLAY_LPA)) ||
- !strncmp(useCase, SND_USE_CASE_MOD_PLAY_TUNNEL,
- MAX_LEN(useCase,SND_USE_CASE_MOD_PLAY_TUNNEL)) ||
- !strncmp(useCase, SND_USE_CASE_MOD_PLAY_FM,
- MAX_LEN(useCase,SND_USE_CASE_MOD_PLAY_FM))) {
- return CAP_RX;
- } else if (!strncmp(useCase, SND_USE_CASE_VERB_HIFI_REC,
- MAX_LEN(useCase,SND_USE_CASE_VERB_HIFI_REC)) ||
- !strncmp(useCase, SND_USE_CASE_VERB_FM_REC,
- MAX_LEN(useCase,SND_USE_CASE_VERB_FM_REC)) ||
- !strncmp(useCase, SND_USE_CASE_VERB_FM_A2DP_REC,
- MAX_LEN(useCase,SND_USE_CASE_VERB_FM_A2DP_REC)) ||
- !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC,
- MAX_LEN(useCase,SND_USE_CASE_MOD_CAPTURE_MUSIC)) ||
- !strncmp(useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_REC,
- MAX_LEN(useCase,SND_USE_CASE_VERB_HIFI_LOWLATENCY_REC)) ||
- !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_LOWLATENCY_MUSIC,
- MAX_LEN(useCase,SND_USE_CASE_MOD_CAPTURE_LOWLATENCY_MUSIC)) ||
- !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_FM,
- MAX_LEN(useCase,SND_USE_CASE_MOD_CAPTURE_FM)) ||
- !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_A2DP_FM,
- MAX_LEN(useCase,SND_USE_CASE_MOD_CAPTURE_A2DP_FM))) {
- return CAP_TX;
- } else if (!strncmp(useCase, SND_USE_CASE_VERB_VOICECALL,
- MAX_LEN(useCase,SND_USE_CASE_VERB_VOICECALL)) ||
- !strncmp(useCase, SND_USE_CASE_VERB_IP_VOICECALL,
- MAX_LEN(useCase,SND_USE_CASE_VERB_IP_VOICECALL)) ||
- !strncmp(useCase, SND_USE_CASE_VERB_DL_REC,
- MAX_LEN(useCase,SND_USE_CASE_VERB_DL_REC)) ||
- !strncmp(useCase, SND_USE_CASE_VERB_UL_DL_REC,
- MAX_LEN(useCase,SND_USE_CASE_VERB_UL_DL_REC)) ||
- !strncmp(useCase, SND_USE_CASE_VERB_INCALL_REC,
- MAX_LEN(useCase,SND_USE_CASE_VERB_INCALL_REC)) ||
- !strncmp(useCase, SND_USE_CASE_MOD_PLAY_VOICE,
- MAX_LEN(useCase,SND_USE_CASE_MOD_PLAY_VOICE)) ||
- !strncmp(useCase, SND_USE_CASE_MOD_PLAY_VOIP,
- MAX_LEN(useCase,SND_USE_CASE_MOD_PLAY_VOIP)) ||
- !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_VOICE_DL,
- MAX_LEN(useCase,SND_USE_CASE_MOD_CAPTURE_VOICE_DL)) ||
- !strncmp(useCase, SND_USE_CASE_MOD_CAPTURE_VOICE_UL_DL,
- MAX_LEN(useCase,SND_USE_CASE_MOD_CAPTURE_VOICE_UL_DL)) ||
- !strncmp(useCase, SND_USE_CASE_VERB_VOLTE,
- MAX_LEN(useCase,SND_USE_CASE_VERB_VOLTE)) ||
- !strncmp(useCase, SND_USE_CASE_MOD_PLAY_VOLTE,
- MAX_LEN(useCase, SND_USE_CASE_MOD_PLAY_VOLTE))) {
- return CAP_VOICE;
- } else {
- ALOGE("unknown use case %s, returning voice capablity", useCase);
- return CAP_VOICE;
- }
-}
-
-/* Set/Reset mixer controls of specific use case for all current devices
- * uc_mgr - UCM structure pointer
- * ident - use case name (verb or modifier)
- * enable - 1 for enable and 0 for disable
- * return 0 on sucess, otherwise a negative error code
- */
-static int set_controls_of_usecase_for_all_devices(snd_use_case_mgr_t *uc_mgr,
-const char *ident, int enable, int ctrl_list_type)
-{
- card_mctrl_t *dev_list, *uc_list;
- char *current_device, use_case[MAX_UC_LEN];
- int list_size, index, uc_index, ret = 0, intdev_flag = 0;
- int verb_index, capability = 0, ident_cap = 0, dev_cap =0;
-
- ALOGV("set_use_case_ident_for_all_devices(): %s", ident);
- if ((verb_index = uc_mgr->card_ctxt_ptr->current_verb_index) < 0)
- verb_index = 0;
- dev_list =
- uc_mgr->card_ctxt_ptr->use_case_verb_list[verb_index].device_ctrls;
- if (ctrl_list_type == CTRL_LIST_VERB) {
- uc_list =
- uc_mgr->card_ctxt_ptr->use_case_verb_list[verb_index].verb_ctrls;
- } else if (ctrl_list_type == CTRL_LIST_MODIFIER) {
- uc_list =
- uc_mgr->card_ctxt_ptr->use_case_verb_list[verb_index].mod_ctrls;
- } else {
- uc_list = NULL;
- }
- ident_cap = getUseCaseType(ident);
- list_size = snd_ucm_get_size_of_list(uc_mgr->card_ctxt_ptr->dev_list_head);
- for (index = 0; index < list_size; index++) {
- current_device =
- snd_ucm_get_value_at_index(uc_mgr->card_ctxt_ptr->dev_list_head, index);
- if (current_device != NULL) {
- uc_index = get_use_case_index(uc_mgr, current_device,
- CTRL_LIST_DEVICE);
- dev_cap = dev_list[uc_index].capability;
- if (!capability) {
- capability = dev_list[uc_index].capability;
- } else if (capability != dev_list[uc_index].capability) {
- capability = CAP_VOICE;
- }
- if (ident_cap == CAP_VOICE || ident_cap == dev_cap) {
- if (enable) {
- if (!snd_ucm_get_status_at_index(
- uc_mgr->card_ctxt_ptr->dev_list_head, current_device)) {
- if (uc_index >= 0) {
- ALOGV("Applying mixer controls for device: %s",
- current_device);
- ret = snd_use_case_apply_mixer_controls(uc_mgr,
- current_device, enable, CTRL_LIST_DEVICE, uc_index);
- if (!ret)
- snd_ucm_set_status_at_index(
- uc_mgr->card_ctxt_ptr->dev_list_head,
- current_device, enable, dev_cap);
- }
- } else if (ident_cap == CAP_VOICE) {
- snd_use_case_apply_voice_acdb(uc_mgr, uc_index);
- }
- }
- strlcpy(use_case, ident, sizeof(use_case));
- strlcat(use_case, current_device, sizeof(use_case));
- ALOGV("Applying mixer controls for use case: %s", use_case);
- if ((uc_index =
- get_use_case_index(uc_mgr, use_case, ctrl_list_type)) < 0) {
- ALOGV("No valid use case found: %s", use_case);
- intdev_flag++;
- } else {
- if (capability == CAP_VOICE || ident_cap == CAP_VOICE ||
- capability == ident_cap) {
- ret = snd_use_case_apply_mixer_controls(uc_mgr, use_case,
- enable, ctrl_list_type, uc_index);
- }
- }
- use_case[0] = 0;
- free(current_device);
- }
- }
- }
- if (intdev_flag) {
- if ((uc_index = get_use_case_index(uc_mgr, ident, ctrl_list_type)) < 0) {
- ALOGE("use case %s not valid without device combination", ident);
- } else {
- if (capability == CAP_VOICE || capability == ident_cap ||
- ident_cap == CAP_VOICE) {
- snd_use_case_apply_mixer_controls(uc_mgr, ident, enable,
- ctrl_list_type, uc_index);
- }
- }
- }
- return ret;
-}
-
-/* Set/Reset mixer controls of specific use case for a specific device
- * uc_mgr - UCM structure pointer
- * ident - use case name (verb or modifier)
- * device - device for which use case needs to be set/reset
- * enable - 1 for enable and 0 for disable
- * return 0 on sucess, otherwise a negative error code
- */
-static int set_controls_of_usecase_for_device(snd_use_case_mgr_t *uc_mgr,
-const char *ident, const char *device, int enable, int ctrl_list_type)
-{
- card_mctrl_t *dev_list;
- char use_case[MAX_UC_LEN];
- int list_size, index, dev_index, uc_index, ret = 0;
- int verb_index, capability = 0;
-
- ALOGV("set_use_case_ident_for_device(): use case %s device %s", ident,
- device);
- if ((verb_index = uc_mgr->card_ctxt_ptr->current_verb_index) < 0)
- verb_index = 0;
- dev_list =
- uc_mgr->card_ctxt_ptr->use_case_verb_list[verb_index].device_ctrls;
- if (device != NULL) {
- if (enable) {
- dev_index = get_use_case_index(uc_mgr, device, CTRL_LIST_DEVICE);
- capability = dev_list[dev_index].capability;
- if (!snd_ucm_get_status_at_index(
- uc_mgr->card_ctxt_ptr->dev_list_head, device)) {
- ret = snd_use_case_apply_mixer_controls(uc_mgr, device,
- enable, CTRL_LIST_DEVICE, dev_index);
- if (!ret)
- snd_ucm_set_status_at_index(
- uc_mgr->card_ctxt_ptr->dev_list_head, device, enable,
- capability);
- }
- }
- strlcpy(use_case, ident, sizeof(use_case));
- strlcat(use_case, device, sizeof(use_case));
- ALOGV("Applying mixer controls for use case: %s", use_case);
- if ((uc_index = get_use_case_index(uc_mgr, use_case, ctrl_list_type)) < 0) {
- ALOGV("No valid use case found: %s", use_case );
- uc_index = get_use_case_index(uc_mgr, ident, ctrl_list_type);
- if (snd_use_case_apply_mixer_controls(uc_mgr, ident, enable,
- ctrl_list_type, uc_index) < 0) {
- ALOGV("use case %s not valid without device combination also",
- ident);
- }
- } else {
- ret = snd_use_case_apply_mixer_controls(uc_mgr, use_case, enable,
- ctrl_list_type, uc_index);
- }
- } else {
- uc_index = get_use_case_index(uc_mgr, ident, ctrl_list_type);
- if (snd_use_case_apply_mixer_controls(uc_mgr, ident, enable,
- ctrl_list_type, uc_index) < 0) {
- ALOGV("use case %s not valid without device combination also",
- ident);
- }
- }
- return ret;
-}
-
-/* Set/Reset mixer controls of specific device for all use cases
- * uc_mgr - UCM structure pointer
- * device - device name
- * enable - 1 for enable and 0 for disable
- * return 0 on sucess, otherwise a negative error code
- */
-static int set_controls_of_device_for_all_usecases(snd_use_case_mgr_t *uc_mgr,
-const char *device, int enable)
-{
- card_mctrl_t *dev_list, *uc_list;
- char *ident_value, use_case[MAX_UC_LEN];
- int verb_index, uc_index, dev_index, capability = 0;
- int list_size, index = 0, ret = -ENODEV, flag = 0, intdev_flag = 0;
-
- ALOGV("set_controls_of_device_for_all_usecases: %s", device);
- if ((verb_index = uc_mgr->card_ctxt_ptr->current_verb_index) < 0)
- verb_index = 0;
- dev_list =
- uc_mgr->card_ctxt_ptr->use_case_verb_list[verb_index].device_ctrls;
- dev_index = get_use_case_index(uc_mgr, device, CTRL_LIST_DEVICE);
- if (dev_index >= 0)
- capability = dev_list[dev_index].capability;
- if (strncmp(uc_mgr->card_ctxt_ptr->current_verb, SND_USE_CASE_VERB_INACTIVE,
- strlen(SND_USE_CASE_VERB_INACTIVE))) {
- uc_list =
- uc_mgr->card_ctxt_ptr->use_case_verb_list[verb_index].verb_ctrls;
- if (capability == CAP_VOICE ||
- capability == getUseCaseType(uc_mgr->card_ctxt_ptr->current_verb) ||
- getUseCaseType(uc_mgr->card_ctxt_ptr->current_verb) == CAP_VOICE) {
- strlcpy(use_case, uc_mgr->card_ctxt_ptr->current_verb,
- sizeof(use_case));
- strlcat(use_case, device, sizeof(use_case));
- if ((uc_index =
- get_use_case_index(uc_mgr, use_case, CTRL_LIST_VERB)) < 0) {
- ALOGV("No valid use case found: %s", use_case);
- intdev_flag = 1;
- } else {
- if (enable) {
- if (!snd_ucm_get_status_at_index(
- uc_mgr->card_ctxt_ptr->dev_list_head, device)) {
- ret = snd_use_case_apply_mixer_controls(uc_mgr, device,
- enable, CTRL_LIST_DEVICE, dev_index);
- if (!ret)
- snd_ucm_set_status_at_index(
- uc_mgr->card_ctxt_ptr->dev_list_head, device,
- enable, capability);
- flag = 1;
- }
- }
- ALOGV("set %d for use case value: %s", enable, use_case);
- ret = snd_use_case_apply_mixer_controls(uc_mgr, use_case,
- enable, CTRL_LIST_VERB, uc_index);
- if (ret != 0)
- ALOGE("No valid controls exists for usecase %s and device \
- %s, enable: %d", use_case, device, enable);
- }
- }
- if (intdev_flag) {
- if (enable && !flag) {
- if (!snd_ucm_get_status_at_index(
- uc_mgr->card_ctxt_ptr->dev_list_head, device)) {
- ret = snd_use_case_apply_mixer_controls(uc_mgr,
- device, enable, CTRL_LIST_DEVICE, dev_index);
- if (!ret)
- snd_ucm_set_status_at_index(
- uc_mgr->card_ctxt_ptr->dev_list_head, device, enable,
- capability);
- flag = 1;
- }
- }
- use_case[0] = 0;
- strlcpy(use_case, uc_mgr->card_ctxt_ptr->current_verb,
- sizeof(use_case));
- uc_index = get_use_case_index(uc_mgr, use_case, CTRL_LIST_VERB);
- if (capability == CAP_VOICE ||
- capability ==
- getUseCaseType(uc_mgr->card_ctxt_ptr->current_verb) ||
- getUseCaseType(uc_mgr->card_ctxt_ptr->current_verb) ==
- CAP_VOICE) {
- ALOGV("set %d for use case value: %s", enable, use_case);
- ret = snd_use_case_apply_mixer_controls(uc_mgr, use_case,
- enable, CTRL_LIST_VERB, uc_index);
- if (ret != 0)
- ALOGE("No valid controls exists for usecase %s and \
- device %s, enable: %d", use_case, device, enable);
- }
- intdev_flag = 0;
- }
- use_case[0] = 0;
- }
- snd_ucm_print_list(uc_mgr->card_ctxt_ptr->mod_list_head);
- uc_list =
- uc_mgr->card_ctxt_ptr->use_case_verb_list[verb_index].mod_ctrls;
- list_size = snd_ucm_get_size_of_list(uc_mgr->card_ctxt_ptr->mod_list_head);
- for (index = 0; index < list_size; index++) {
- if ((ident_value =
- snd_ucm_get_value_at_index(uc_mgr->card_ctxt_ptr->mod_list_head,
- index))) {
- if (capability == CAP_VOICE ||
- getUseCaseType(ident_value) == CAP_VOICE ||
- capability == getUseCaseType(ident_value)) {
- strlcpy(use_case, ident_value, sizeof(use_case));
- strlcat(use_case, device, sizeof(use_case));
- if ((uc_index = get_use_case_index(uc_mgr, use_case,
- CTRL_LIST_MODIFIER)) < 0) {
- ALOGV("No valid use case found: %s", use_case);
- intdev_flag = 1;
- } else {
- if (enable && !flag) {
- if (!snd_ucm_get_status_at_index(
- uc_mgr->card_ctxt_ptr->dev_list_head, device)) {
- ret = snd_use_case_apply_mixer_controls(uc_mgr,
- device, enable, CTRL_LIST_DEVICE,
- dev_index);
- if (!ret)
- snd_ucm_set_status_at_index(
- uc_mgr->card_ctxt_ptr->dev_list_head,
- device, enable, capability);
- flag = 1;
- }
- }
- ALOGV("set %d for use case value: %s", enable, use_case);
- ret = snd_use_case_apply_mixer_controls(uc_mgr,
- use_case, enable, CTRL_LIST_MODIFIER, uc_index);
- if (ret != 0)
- ALOGE("No valid controls exists for usecase %s and \
- device %s, enable: %d", use_case, device, enable);
- }
- }
- if (intdev_flag) {
- if (enable && !flag) {
- if (!snd_ucm_get_status_at_index(
- uc_mgr->card_ctxt_ptr->dev_list_head, device)) {
- ret = snd_use_case_apply_mixer_controls(uc_mgr,
- device, enable, CTRL_LIST_DEVICE, dev_index);
- if (!ret)
- snd_ucm_set_status_at_index(
- uc_mgr->card_ctxt_ptr->dev_list_head, device,
- enable, capability);
- flag = 1;
- }
- }
- use_case[0] = 0;
- strlcpy(use_case, ident_value, sizeof(use_case));
- uc_index =
- get_use_case_index(uc_mgr, ident_value, CTRL_LIST_MODIFIER);
- if (capability == CAP_VOICE ||
- capability == getUseCaseType(ident_value) ||
- getUseCaseType(ident_value) == CAP_VOICE) {
- ALOGV("set %d for use case value: %s", enable, use_case);
- ret = snd_use_case_apply_mixer_controls(uc_mgr, use_case,
- enable, CTRL_LIST_MODIFIER, uc_index);
- if (ret != 0)
- ALOGE("No valid controls exists for usecase %s and \
- device %s, enable: %d", use_case, device, enable);
- }
- intdev_flag = 0;
- }
- use_case[0] = 0;
- free(ident_value);
- }
- }
- if (!enable) {
- ret = snd_use_case_apply_mixer_controls(uc_mgr, device, enable,
- CTRL_LIST_DEVICE, dev_index);
- if (!ret)
- snd_ucm_set_status_at_index(uc_mgr->card_ctxt_ptr->dev_list_head,
- device, enable, capability);
- }
- return ret;
-}
-
-/* Returns usecase type i.e. either verb or modifier
- * uc_mgr - UCM structure pointer
- * usecase - usecase name either verb or modifier
- * return CTRL_LIST_VERB or CTRL_LIST_MODIFIER for verb/modifier respectively
- */
-static int get_usecase_type(snd_use_case_mgr_t *uc_mgr, const char *usecase)
-{
- int ret = -EINVAL, index = 0;
-
- while (strncmp(uc_mgr->card_ctxt_ptr->verb_list[index],
- SND_UCM_END_OF_LIST, strlen(SND_UCM_END_OF_LIST))) {
- if (!strncmp(uc_mgr->card_ctxt_ptr->verb_list[index], usecase,
- (strlen(usecase)+1))) {
- ret = 0;
- break;
- }
- index++;
- }
- if (ret == 0)
- return CTRL_LIST_VERB;
- else
- return CTRL_LIST_MODIFIER;
-}
-
-/* Set/Reset mixer controls of specific device and specific use cases
- * uc_mgr - UCM structure pointer
- * device - device name
- * usecase - use case for which device needs to be enabled
- * enable - 1 for enable and 0 for disable
- * return 0 on sucess, otherwise a negative error code
- */
-static int set_controls_of_device_for_usecase(snd_use_case_mgr_t *uc_mgr,
- const char *device, const char *usecase, int enable)
-{
- card_mctrl_t *dev_list;
- char use_case[MAX_UC_LEN];
- int ret = -ENODEV, uc_index, dev_index;
- int verb_index, capability = 0;
-
- ALOGV("set_device_for_ident(): %s %s", device, usecase);
- if ((verb_index = uc_mgr->card_ctxt_ptr->current_verb_index) < 0)
- verb_index = 0;
- dev_list =
- uc_mgr->card_ctxt_ptr->use_case_verb_list[verb_index].device_ctrls;
- dev_index = get_use_case_index(uc_mgr, device, CTRL_LIST_DEVICE);
- capability = dev_list[dev_index].capability;
- if (usecase != NULL) {
- strlcpy(use_case, usecase, sizeof(use_case));
- strlcat(use_case, device, sizeof(use_case));
- if ((uc_index = get_use_case_index(uc_mgr, use_case,
- get_usecase_type(uc_mgr, usecase))) < 0) {
- ALOGV("No valid use case found: %s", use_case);
- } else {
- if (enable) {
- if (!snd_ucm_get_status_at_index(
- uc_mgr->card_ctxt_ptr->dev_list_head, device)) {
- ret = snd_use_case_apply_mixer_controls(uc_mgr, device,
- enable, CTRL_LIST_DEVICE, dev_index);
- if (!ret)
- snd_ucm_set_status_at_index
- (uc_mgr->card_ctxt_ptr->dev_list_head, device, enable,
- capability);
- }
- }
- ALOGV("set %d for use case value: %s", enable, use_case);
- ret = snd_use_case_apply_mixer_controls(uc_mgr, use_case, enable,
- get_usecase_type(uc_mgr, usecase), uc_index);
- if (ret != 0)
- ALOGE("No valid controls exists for usecase %s and device %s, \
- enable: %d", use_case, device, enable);
- }
- use_case[0] = 0;
- } else {
- if (enable) {
- if (!snd_ucm_get_status_at_index(
- uc_mgr->card_ctxt_ptr->dev_list_head, device)) {
- ret = snd_use_case_apply_mixer_controls(uc_mgr, device, enable,
- CTRL_LIST_DEVICE, dev_index);
- if (!ret)
- snd_ucm_set_status_at_index(
- uc_mgr->card_ctxt_ptr->dev_list_head, device, enable,
- capability);
- }
- }
- }
- if (!enable) {
- ret = snd_use_case_apply_mixer_controls(uc_mgr, device, enable,
- CTRL_LIST_DEVICE, dev_index);
- if (!ret)
- snd_ucm_set_status_at_index(uc_mgr->card_ctxt_ptr->dev_list_head,
- device, enable, capability);
- }
- return ret;
-}
-
-/**
- * Set new value for an identifier
- * uc_mgr - UCM structure
- * identifier - _verb, _enadev, _disdev, _enamod, _dismod
- * _swdev, _swmod
- * value - Value to be set
- * returns 0 on success, otherwise a negative error code
- */
-int snd_use_case_set(snd_use_case_mgr_t *uc_mgr,
- const char *identifier,
- const char *value)
-{
- use_case_verb_t *verb_list;
- char ident[MAX_STR_LEN], *ident1, *ident2, *temp_ptr;
- int verb_index, list_size, index = 0, ret = -EINVAL;
-
- pthread_mutex_lock(&uc_mgr->card_ctxt_ptr->card_lock);
- if ((uc_mgr->snd_card_index >= (int)MAX_NUM_CARDS) || (value == NULL) ||
- (uc_mgr->snd_card_index < 0) || (uc_mgr->card_ctxt_ptr == NULL) ||
- (identifier == NULL)) {
- ALOGE("snd_use_case_set(): failed, invalid arguments");
- pthread_mutex_unlock(&uc_mgr->card_ctxt_ptr->card_lock);
- return -EINVAL;
- }
-
- ALOGD("snd_use_case_set(): uc_mgr %p identifier %s value %s", uc_mgr,
- identifier, value);
- strlcpy(ident, identifier, sizeof(ident));
- if(!(ident1 = strtok_r(ident, "/", &temp_ptr))) {
- ALOGV("No multiple identifiers found in identifier value");
- ident[0] = 0;
- } else {
- if (!strncmp(ident1, "_swdev", 6)) {
- if(!(ident2 = strtok_r(NULL, "/", &temp_ptr))) {
- ALOGD("Invalid disable device value: %s, but enabling new \
- device", ident2);
- } else {
- ret = snd_ucm_del_ident_from_list(
- &uc_mgr->card_ctxt_ptr->dev_list_head, ident2);
- if (ret < 0) {
- ALOGV("Ignore device %s disable, device not part of \
- enabled list", ident2);
- } else {
- ALOGV("swdev: device value to be disabled: %s", ident2);
- /* Disable mixer controls for
- * corresponding use cases and device */
- ret = set_controls_of_device_for_all_usecases(uc_mgr,
- ident2, 0);
- if (ret < 0) {
- ALOGV("Device %s not disabled, no valid use case \
- found: %d", ident2, errno);
- }
- }
- }
- pthread_mutex_unlock(&uc_mgr->card_ctxt_ptr->card_lock);
- ret = snd_use_case_set(uc_mgr, "_enadev", value);
- if (ret < 0) {
- ALOGV("Device %s not enabled, no valid use case found: %d",
- value, errno);
- }
- return ret;
- } else if (!strncmp(ident1, "_swmod", 6)) {
- pthread_mutex_unlock(&uc_mgr->card_ctxt_ptr->card_lock);
- if(!(ident2 = strtok_r(NULL, "/", &temp_ptr))) {
- ALOGD("Invalid modifier value: %s, but enabling new modifier",
- ident2);
- } else {
- ret = snd_use_case_set(uc_mgr, "_dismod", ident2);
- if (ret < 0) {
- ALOGV("Modifier %s not disabled, no valid use case \
- found: %d", ident2, errno);
- }
- }
- ret = snd_use_case_set(uc_mgr, "_enamod", value);
- if (ret < 0) {
- ALOGV("Modifier %s not enabled, no valid use case found: %d",
- value, errno);
- }
- return ret;
- } else {
- ALOGV("No switch device/modifier option found: %s", ident1);
- }
- ident[0] = 0;
- }
-
- if (!strncmp(identifier, "_verb", 5)) {
- /* Check if value is valid verb */
- while (strncmp(uc_mgr->card_ctxt_ptr->verb_list[index],
- SND_UCM_END_OF_LIST, strlen(SND_UCM_END_OF_LIST))) {
- if (!strncmp(uc_mgr->card_ctxt_ptr->verb_list[index], value,
- (strlen(value)+1))) {
- ret = 0;
- break;
- }
- index++;
- }
- if ((ret < 0) && (strncmp(value, SND_USE_CASE_VERB_INACTIVE,
- strlen(SND_USE_CASE_VERB_INACTIVE)))) {
- ALOGE("Invalid verb identifier value");
- } else {
- ALOGV("Index:%d Verb:%s", index,
- uc_mgr->card_ctxt_ptr->verb_list[index]);
- /* Disable the mixer controls for current use case
- * for all the enabled devices */
- if (strncmp(uc_mgr->card_ctxt_ptr->current_verb,
- SND_USE_CASE_VERB_INACTIVE,
- strlen(SND_USE_CASE_VERB_INACTIVE))) {
- ret = set_controls_of_usecase_for_all_devices(uc_mgr,
- uc_mgr->card_ctxt_ptr->current_verb, 0, CTRL_LIST_VERB);
- if (ret != 0)
- ALOGE("Failed to disable controls for use case: %s",
- uc_mgr->card_ctxt_ptr->current_verb);
- }
- strlcpy(uc_mgr->card_ctxt_ptr->current_verb, value, MAX_STR_LEN);
- /* Enable the mixer controls for the new use case
- * for all the enabled devices */
- if (strncmp(uc_mgr->card_ctxt_ptr->current_verb,
- SND_USE_CASE_VERB_INACTIVE,
- strlen(SND_USE_CASE_VERB_INACTIVE))) {
- uc_mgr->card_ctxt_ptr->current_verb_index = index;
- ret = set_controls_of_usecase_for_all_devices(uc_mgr,
- uc_mgr->card_ctxt_ptr->current_verb, 1, CTRL_LIST_VERB);
- }
- }
- } else if (!strncmp(identifier, "_enadev", 7)) {
- index = 0; ret = 0;
- list_size =
- snd_ucm_get_size_of_list(uc_mgr->card_ctxt_ptr->dev_list_head);
- for (index = 0; index < list_size; index++) {
- if ((ident1 =
- snd_ucm_get_value_at_index(uc_mgr->card_ctxt_ptr->dev_list_head,
- index))) {
- if (!strncmp(ident1, value, (strlen(value)+1))) {
- ALOGV("Ignore enable as %s device is already part of \
- enabled list", value);
- free(ident1);
- break;
- }
- free(ident1);
- }
- }
- if (index == list_size) {
- ALOGV("enadev: device value to be enabled: %s", value);
- snd_ucm_add_ident_to_list(&uc_mgr->card_ctxt_ptr->dev_list_head,
- value);
- }
- snd_ucm_print_list(uc_mgr->card_ctxt_ptr->dev_list_head);
- /* Apply Mixer controls of all verb and modifiers for this device*/
- ret = set_controls_of_device_for_all_usecases(uc_mgr, value, 1);
- } else if (!strncmp(identifier, "_disdev", 7)) {
- ret = snd_ucm_get_status_at_index(uc_mgr->card_ctxt_ptr->dev_list_head,
- value);
- if (ret < 0) {
- ALOGD("disdev: device %s not enabled, no need to disable", value);
- } else if (ret == 0) {
- ALOGV("disdev: device %s not active, remove from the list", value);
- ret =
- snd_ucm_del_ident_from_list(&uc_mgr->card_ctxt_ptr->dev_list_head,
- value);
- if (ret < 0) {
- ALOGE("Invalid device: Device not part of enabled device list");
- }
- } else {
- ret =
- snd_ucm_del_ident_from_list(&uc_mgr->card_ctxt_ptr->dev_list_head,
- value);
- if (ret < 0) {
- ALOGE("Invalid device: Device not part of enabled device list");
- } else {
- ALOGV("disdev: device value to be disabled: %s", value);
- index = get_use_case_index(uc_mgr, value, CTRL_LIST_DEVICE);
- /* Apply Mixer controls for corresponding device and modifier */
- ret = snd_use_case_apply_mixer_controls(uc_mgr, value, 0,
- CTRL_LIST_DEVICE, index);
- }
- }
- } else if (!strncmp(identifier, "_enamod", 7)) {
- index = 0; ret = 0;
- verb_index = uc_mgr->card_ctxt_ptr->current_verb_index;
- if (verb_index < 0) {
- ALOGE("Invalid verb identifier value");
- } else {
- ALOGV("Index:%d Verb:%s", verb_index,
- uc_mgr->card_ctxt_ptr->verb_list[verb_index]);
- verb_list = uc_mgr->card_ctxt_ptr->use_case_verb_list;
- while(strncmp(verb_list[verb_index].modifier_list[index], value,
- (strlen(value)+1))) {
- if (!strncmp(verb_list[verb_index].modifier_list[index],
- SND_UCM_END_OF_LIST, strlen(SND_UCM_END_OF_LIST))){
- ret = -EINVAL;
- break;
- }
- index++;
- }
- if (ret < 0) {
- ALOGE("Invalid modifier identifier value");
- } else {
- snd_ucm_add_ident_to_list(&uc_mgr->card_ctxt_ptr->mod_list_head,
- value);
- /* Enable the mixer controls for the new use case
- * for all the enabled devices */
- ret = set_controls_of_usecase_for_all_devices(uc_mgr, value, 1,
- CTRL_LIST_MODIFIER);
- }
- }
- } else if (!strncmp(identifier, "_dismod", 7)) {
- ret = snd_ucm_del_ident_from_list(&uc_mgr->card_ctxt_ptr->mod_list_head,
- value);
- if (ret < 0) {
- ALOGE("Modifier not enabled currently, invalid modifier");
- } else {
- ALOGV("dismod: modifier value to be disabled: %s", value);
- /* Enable the mixer controls for the new use case
- * for all the enabled devices */
- ret = set_controls_of_usecase_for_all_devices(uc_mgr, value, 0,
- CTRL_LIST_MODIFIER);
- }
- } else {
- ALOGE("Unknown identifier value: %s", identifier);
- }
- pthread_mutex_unlock(&uc_mgr->card_ctxt_ptr->card_lock);
- return ret;
-}
-
-/**
- * Set new value for an identifier based on use case
- * uc_mgr - UCM structure
- * identifier - _verb, _enadev, _disdev, _enamod, _dismod
- * _swdev, _swmod
- * value - Value to be set
- * usecase - usecase/device for which this command needs to be executed
- * returns 0 on success, otherwise a negative error code
- */
-int snd_use_case_set_case(snd_use_case_mgr_t *uc_mgr,
- const char *identifier,
- const char *value, const char *usecase)
-{
- use_case_verb_t *verb_list;
- char ident[MAX_STR_LEN], *ident1, *ident2, *temp_ptr;
- int verb_index, list_size, index = 0, ret = -EINVAL;
-
- pthread_mutex_lock(&uc_mgr->card_ctxt_ptr->card_lock);
- if ((uc_mgr->snd_card_index >= (int)MAX_NUM_CARDS) || (value == NULL) ||
- (uc_mgr->snd_card_index < 0) || (uc_mgr->card_ctxt_ptr == NULL) ||
- (identifier == NULL)) {
- ALOGE("snd_use_case_set_case(): failed, invalid arguments");
- pthread_mutex_unlock(&uc_mgr->card_ctxt_ptr->card_lock);
- return -EINVAL;
- }
-
- ALOGD("snd_use_case_set_case(): uc_mgr %p identifier %s value %s",
- uc_mgr, identifier, value);
- strlcpy(ident, identifier, sizeof(ident));
- if(!(ident1 = strtok_r(ident, "/", &temp_ptr))) {
- ALOGV("No multiple identifiers found in identifier value");
- ident[0] = 0;
- } else {
- if (!strncmp(ident1, "_swdev", 6)) {
- if(!(ident2 = strtok_r(NULL, "/", &temp_ptr))) {
- ALOGD("Invalid disable device value: %s, but enabling new \
- device", ident2);
- } else {
- ret = snd_ucm_del_ident_from_list(
- &uc_mgr->card_ctxt_ptr->dev_list_head, ident2);
- if (ret < 0) {
- ALOGV("Ignore device %s disable, device not part of \
- enabled list", ident2);
- } else {
- ALOGV("swdev: device value to be disabled: %s", ident2);
- /* Disable mixer controls for
- * corresponding use cases and device */
- ret = set_controls_of_device_for_usecase(uc_mgr, ident2,
- usecase, 0);
- if (ret < 0) {
- ALOGV("Device %s not disabled, no valid use case \
- found: %d", ident2, errno);
- }
- }
- }
- pthread_mutex_unlock(&uc_mgr->card_ctxt_ptr->card_lock);
- ret = snd_use_case_set_case(uc_mgr, "_enadev", value, usecase);
- if (ret < 0) {
- ALOGV("Device %s not enabled, no valid use case found: %d",
- value, errno);
- }
- return ret;
- } else if (!strncmp(ident1, "_swmod", 6)) {
- pthread_mutex_unlock(&uc_mgr->card_ctxt_ptr->card_lock);
- if(!(ident2 = strtok_r(NULL, "/", &temp_ptr))) {
- ALOGD("Invalid modifier value: %s, but enabling new modifier",
- ident2);
- } else {
- ret = snd_use_case_set_case(uc_mgr, "_dismod", ident2, usecase);
- if (ret < 0) {
- ALOGV("Modifier %s not disabled, no valid use case \
- found: %d", ident2, errno);
- }
- }
- ret = snd_use_case_set_case(uc_mgr, "_enamod", value, usecase);
- if (ret < 0) {
- ALOGV("Modifier %s not enabled, no valid use case found: %d",
- value, errno);
- }
- return ret;
- } else {
- ALOGV("No switch device/modifier option found: %s", ident1);
- }
- ident[0] = 0;
- }
-
- if (!strncmp(identifier, "_verb", 5)) {
- /* Check if value is valid verb */
- while (strncmp(uc_mgr->card_ctxt_ptr->verb_list[index],
- SND_UCM_END_OF_LIST, MAX_STR_LEN)) {
- if (!strncmp(uc_mgr->card_ctxt_ptr->verb_list[index],
- value, MAX_STR_LEN)) {
- ret = 0;
- break;
- }
- index++;
- }
- if ((ret < 0) && (strncmp(value, SND_USE_CASE_VERB_INACTIVE,
- MAX_STR_LEN))) {
- ALOGE("Invalid verb identifier value");
- } else {
- ALOGV("Index:%d Verb:%s", index,
- uc_mgr->card_ctxt_ptr->verb_list[index]);
- /* Disable the mixer controls for current use case
- * for specified device */
- if (strncmp(uc_mgr->card_ctxt_ptr->current_verb,
- SND_USE_CASE_VERB_INACTIVE, MAX_STR_LEN)) {
- ret = set_controls_of_usecase_for_device(uc_mgr,
- uc_mgr->card_ctxt_ptr->current_verb, usecase,
- 0, CTRL_LIST_VERB);
- if (ret != 0)
- ALOGE("Failed to disable controls for use case: %s",
- uc_mgr->card_ctxt_ptr->current_verb);
- }
- strlcpy(uc_mgr->card_ctxt_ptr->current_verb, value, MAX_STR_LEN);
- /* Enable the mixer controls for the new use case
- * for specified device */
- if (strncmp(uc_mgr->card_ctxt_ptr->current_verb,
- SND_USE_CASE_VERB_INACTIVE, MAX_STR_LEN)) {
- uc_mgr->card_ctxt_ptr->current_verb_index = index;
- index = 0;
- list_size =
- snd_ucm_get_size_of_list(uc_mgr->card_ctxt_ptr->dev_list_head);
- for (index = 0; index < list_size; index++) {
- if ((ident1 = snd_ucm_get_value_at_index(
- uc_mgr->card_ctxt_ptr->dev_list_head, index))) {
- if (!strncmp(ident1, usecase, MAX_STR_LEN)) {
- ALOGV("Device already part of enabled list: %s",
- usecase);
- free(ident1);
- break;
- }
- free(ident1);
- }
- }
- if (index == list_size) {
- ALOGV("enadev: device value to be enabled: %s", usecase);
- snd_ucm_add_ident_to_list(&uc_mgr->card_ctxt_ptr->dev_list_head,
- usecase);
- }
- ret = set_controls_of_usecase_for_device(uc_mgr,
- uc_mgr->card_ctxt_ptr->current_verb, usecase,
- 1, CTRL_LIST_VERB);
- }
- }
- } else if (!strncmp(identifier, "_enadev", 7)) {
- index = 0; ret = 0;
- list_size =
- snd_ucm_get_size_of_list(uc_mgr->card_ctxt_ptr->dev_list_head);
- for (index = 0; index < list_size; index++) {
- if ((ident1 =
- snd_ucm_get_value_at_index(uc_mgr->card_ctxt_ptr->dev_list_head,
- index))) {
- if (!strncmp(ident1, value, MAX_STR_LEN)) {
- ALOGV("Device already part of enabled list: %s", value);
- free(ident1);
- break;
- }
- free(ident1);
- }
- }
- if (index == list_size) {
- ALOGV("enadev: device value to be enabled: %s", value);
- snd_ucm_add_ident_to_list(&uc_mgr->card_ctxt_ptr->dev_list_head,
- value);
- }
- snd_ucm_print_list(uc_mgr->card_ctxt_ptr->dev_list_head);
- /* Apply Mixer controls of usecase for this device*/
- ret = set_controls_of_device_for_usecase(uc_mgr, value, usecase, 1);
- } else if (!strncmp(identifier, "_disdev", 7)) {
- ret = snd_ucm_get_status_at_index(uc_mgr->card_ctxt_ptr->dev_list_head,
- value);
- if (ret < 0) {
- ALOGD("disdev: device %s not enabled, no need to disable", value);
- } else if (ret == 0) {
- ALOGV("disdev: device %s not active, remove from the list", value);
- ret =
- snd_ucm_del_ident_from_list(&uc_mgr->card_ctxt_ptr->dev_list_head,
- value);
- if (ret < 0) {
- ALOGE("Invalid device: Device not part of enabled device list");
- }
- } else {
- ret =
- snd_ucm_del_ident_from_list(&uc_mgr->card_ctxt_ptr->dev_list_head,
- value);
- if (ret < 0) {
- ALOGE("Invalid device: Device not part of enabled device list");
- } else {
- ALOGV("disdev: device value to be disabled: %s", value);
- /* Apply Mixer controls of usecase for this device*/
- ret = set_controls_of_device_for_usecase(uc_mgr, value,
- usecase, 0);
- }
- }
- } else if (!strncmp(identifier, "_enamod", 7)) {
- if (!strncmp(uc_mgr->card_ctxt_ptr->current_verb,
- SND_USE_CASE_VERB_INACTIVE, MAX_STR_LEN)) {
- ALOGE("Invalid use case verb value");
- ret = -EINVAL;
- } else {
- ret = 0;
- while(strncmp(uc_mgr->card_ctxt_ptr->verb_list[index],
- uc_mgr->card_ctxt_ptr->current_verb, MAX_STR_LEN)) {
- if (!strncmp(uc_mgr->card_ctxt_ptr->verb_list[index],
- SND_UCM_END_OF_LIST, MAX_STR_LEN)){
- ret = -EINVAL;
- break;
- }
- index++;
- }
- }
- if (ret < 0) {
- ALOGE("Invalid verb identifier value");
- } else {
- verb_index = index; index = 0; ret = 0;
- verb_list = uc_mgr->card_ctxt_ptr->use_case_verb_list;
- ALOGV("Index:%d Verb:%s", verb_index,
- uc_mgr->card_ctxt_ptr->verb_list[verb_index]);
- while(strncmp(verb_list[verb_index].modifier_list[index],
- value, MAX_STR_LEN)) {
- if (!strncmp(verb_list[verb_index].modifier_list[index],
- SND_UCM_END_OF_LIST, MAX_STR_LEN)){
- ret = -EINVAL;
- break;
- }
- index++;
- }
- if (ret < 0) {
- ALOGE("Invalid modifier identifier value");
- } else {
- index = 0;
- list_size =
- snd_ucm_get_size_of_list(uc_mgr->card_ctxt_ptr->dev_list_head);
- for (index = 0; index < list_size; index++) {
- if ((ident1 = snd_ucm_get_value_at_index(
- uc_mgr->card_ctxt_ptr->dev_list_head, index))) {
- if (!strncmp(ident1, usecase, MAX_STR_LEN)) {
- ALOGV("Device already part of enabled list: %s",
- usecase);
- free(ident1);
- break;
- }
- free(ident1);
- }
- }
- if (index == list_size) {
- ALOGV("enadev: device value to be enabled: %s", usecase);
- snd_ucm_add_ident_to_list(&uc_mgr->card_ctxt_ptr->dev_list_head,
- usecase);
- }
- snd_ucm_add_ident_to_list(&uc_mgr->card_ctxt_ptr->mod_list_head,
- value);
- /* Enable the mixer controls for the new use case
- * for all the enabled devices */
- ret = set_controls_of_usecase_for_device(uc_mgr, value,
- usecase, 1, CTRL_LIST_MODIFIER);
- }
- }
- } else if (!strncmp(identifier, "_dismod", 7)) {
- ret = snd_ucm_del_ident_from_list(&uc_mgr->card_ctxt_ptr->mod_list_head,
- value);
- if (ret < 0) {
- ALOGE("Modifier not enabled currently, invalid modifier");
- } else {
- ALOGV("dismod: modifier value to be disabled: %s", value);
- /* Enable the mixer controls for the new use case
- * for all the enabled devices */
- ret = set_controls_of_usecase_for_device(uc_mgr, value, usecase,
- 0, CTRL_LIST_MODIFIER);
- }
- } else {
- ALOGE("Unknown identifier value: %s", identifier);
- }
- pthread_mutex_unlock(&uc_mgr->card_ctxt_ptr->card_lock);
- return ret;
-}
-
-/**
- * Open and initialise use case core for sound card
- * uc_mgr - Returned use case manager pointer
- * card_name - Sound card name.
- * returns 0 on success, otherwise a negative error code
- */
-int snd_use_case_mgr_open(snd_use_case_mgr_t **uc_mgr, const char *card_name)
-{
- snd_use_case_mgr_t *uc_mgr_ptr = NULL;
- int index, ret = -EINVAL;
- char tmp[2];
-
- ALOGV("snd_use_case_open(): card_name %s", card_name);
-
- if (card_name == NULL) {
- ALOGE("snd_use_case_mgr_open: failed, invalid arguments");
- return ret;
- }
-
- for (index = 0; index < (int)MAX_NUM_CARDS; index++) {
- if(!strncmp(card_name, card_mapping_list[index].card_name,
- (strlen(card_mapping_list[index].card_name)+1))) {
- ret = 0;
- break;
- }
- }
-
- if (ret < 0) {
- ALOGE("Card %s not found", card_name);
- } else {
- uc_mgr_ptr = (snd_use_case_mgr_t *)calloc(1,
- sizeof(snd_use_case_mgr_t));
- if (uc_mgr_ptr == NULL) {
- ALOGE("Failed to allocate memory for instance");
- return -ENOMEM;
- }
- uc_mgr_ptr->snd_card_index = index;
- uc_mgr_ptr->card_ctxt_ptr = (card_ctxt_t *)calloc(1,
- sizeof(card_ctxt_t));
- if (uc_mgr_ptr->card_ctxt_ptr == NULL) {
- ALOGE("Failed to allocate memory for card context");
- free(uc_mgr_ptr);
- uc_mgr_ptr = NULL;
- return -ENOMEM;
- }
- uc_mgr_ptr->card_ctxt_ptr->card_number =
- card_mapping_list[index].card_number;
- uc_mgr_ptr->card_ctxt_ptr->card_name =
- (char *)malloc((strlen(card_name)+1)*sizeof(char));
- if (uc_mgr_ptr->card_ctxt_ptr->card_name == NULL) {
- ALOGE("Failed to allocate memory for card name");
- free(uc_mgr_ptr->card_ctxt_ptr);
- free(uc_mgr_ptr);
- uc_mgr_ptr = NULL;
- return -ENOMEM;
- }
- strlcpy(uc_mgr_ptr->card_ctxt_ptr->card_name, card_name,
- ((strlen(card_name)+1)*sizeof(char)));
- uc_mgr_ptr->card_ctxt_ptr->control_device =
- (char *)malloc((strlen("/dev/snd/controlC")+2)*sizeof(char));
- if (uc_mgr_ptr->card_ctxt_ptr->control_device == NULL) {
- ALOGE("Failed to allocate memory for control device string");
- free(uc_mgr_ptr->card_ctxt_ptr->card_name);
- free(uc_mgr_ptr->card_ctxt_ptr);
- free(uc_mgr_ptr);
- uc_mgr_ptr = NULL;
- return -ENOMEM;
- }
- strlcpy(uc_mgr_ptr->card_ctxt_ptr->control_device,
- "/dev/snd/controlC", 18);
- snprintf(tmp, sizeof(tmp), "%d",
- uc_mgr_ptr->card_ctxt_ptr->card_number);
- strlcat(uc_mgr_ptr->card_ctxt_ptr->control_device, tmp,
- (strlen("/dev/snd/controlC")+2)*sizeof(char));
- uc_mgr_ptr->device_list_count = 0;
- uc_mgr_ptr->modifier_list_count = 0;
- uc_mgr_ptr->current_device_list = NULL;
- uc_mgr_ptr->current_modifier_list = NULL;
- uc_mgr_ptr->current_tx_device = -1;
- uc_mgr_ptr->current_rx_device = -1;
- pthread_mutexattr_init(&uc_mgr_ptr->card_ctxt_ptr->card_lock_attr);
- pthread_mutex_init(&uc_mgr_ptr->card_ctxt_ptr->card_lock,
- &uc_mgr_ptr->card_ctxt_ptr->card_lock_attr);
- strlcpy(uc_mgr_ptr->card_ctxt_ptr->current_verb,
- SND_USE_CASE_VERB_INACTIVE, MAX_STR_LEN);
- /* Reset all mixer controls if any applied
- * previously for the same card */
- snd_use_case_mgr_reset(uc_mgr_ptr);
- uc_mgr_ptr->card_ctxt_ptr->current_verb_index = -1;
- /* Parse config files and update mixer controls */
- ret = snd_ucm_parse(&uc_mgr_ptr);
- if(ret < 0) {
- ALOGE("Failed to parse config files: %d", ret);
- snd_ucm_free_mixer_list(&uc_mgr_ptr);
- }
- ALOGV("Open mixer device: %s",
- uc_mgr_ptr->card_ctxt_ptr->control_device);
- uc_mgr_ptr->card_ctxt_ptr->mixer_handle =
- mixer_open(uc_mgr_ptr->card_ctxt_ptr->control_device);
- ALOGV("Mixer handle %p", uc_mgr_ptr->card_ctxt_ptr->mixer_handle);
- *uc_mgr = uc_mgr_ptr;
- }
- ALOGV("snd_use_case_open(): returning instance %p", uc_mgr_ptr);
- return ret;
-}
-
-
-/**
- * \brief Reload and re-parse use case configuration files for sound card.
- * \param uc_mgr Use case manager
- * \return zero if success, otherwise a negative error code
- */
-int snd_use_case_mgr_reload(snd_use_case_mgr_t *uc_mgr) {
- ALOGE("Reload is not implemented for now as there is no use case currently");
- return 0;
-}
-
-/**
- * \brief Close use case manager
- * \param uc_mgr Use case manager
- * \return zero if success, otherwise a negative error code
- */
-int snd_use_case_mgr_close(snd_use_case_mgr_t *uc_mgr)
-{
- int ret = 0;
-
- if ((uc_mgr->snd_card_index >= (int)MAX_NUM_CARDS) ||
- (uc_mgr->snd_card_index < 0) || (uc_mgr->card_ctxt_ptr == NULL)) {
- ALOGE("snd_use_case_mgr_close(): failed, invalid arguments");
- return -EINVAL;
- }
-
- ALOGV("snd_use_case_close(): instance %p", uc_mgr);
- ret = snd_use_case_mgr_reset(uc_mgr);
- if (ret < 0)
- ALOGE("Failed to reset ucm session");
- snd_ucm_free_mixer_list(&uc_mgr);
- pthread_mutexattr_destroy(&uc_mgr->card_ctxt_ptr->card_lock_attr);
- pthread_mutex_destroy(&uc_mgr->card_ctxt_ptr->card_lock);
- if (uc_mgr->card_ctxt_ptr->mixer_handle) {
- mixer_close(uc_mgr->card_ctxt_ptr->mixer_handle);
- uc_mgr->card_ctxt_ptr->mixer_handle = NULL;
- }
- uc_mgr->snd_card_index = -1;
- uc_mgr->current_tx_device = -1;
- uc_mgr->current_rx_device = -1;
- free(uc_mgr->card_ctxt_ptr->control_device);
- free(uc_mgr->card_ctxt_ptr->card_name);
- free(uc_mgr->card_ctxt_ptr);
- uc_mgr->card_ctxt_ptr = NULL;
- free(uc_mgr);
- uc_mgr = NULL;
- ALOGV("snd_use_case_mgr_close(): card instace closed successfully");
- return ret;
-}
-
-/**
- * \brief Reset use case manager verb, device, modifier to deafult settings.
- * \param uc_mgr Use case manager
- * \return zero if success, otherwise a negative error code
- */
-int snd_use_case_mgr_reset(snd_use_case_mgr_t *uc_mgr)
-{
- char *ident_value;
- int index, list_size, ret = 0;
-
- ALOGV("snd_use_case_reset(): instance %p", uc_mgr);
- pthread_mutex_lock(&uc_mgr->card_ctxt_ptr->card_lock);
- if ((uc_mgr->snd_card_index >= (int)MAX_NUM_CARDS) ||
- (uc_mgr->snd_card_index < 0) || (uc_mgr->card_ctxt_ptr == NULL)) {
- ALOGE("snd_use_case_mgr_reset(): failed, invalid arguments");
- pthread_mutex_unlock(&uc_mgr->card_ctxt_ptr->card_lock);
- return -EINVAL;
- }
-
- /* Disable mixer controls of all the enabled modifiers */
- list_size = snd_ucm_get_size_of_list(uc_mgr->card_ctxt_ptr->mod_list_head);
- for (index = (list_size-1); index >= 0; index--) {
- if ((ident_value =
- snd_ucm_get_value_at_index(uc_mgr->card_ctxt_ptr->mod_list_head,
- index))) {
- snd_ucm_del_ident_from_list(&uc_mgr->card_ctxt_ptr->mod_list_head,
- ident_value);
- ret = set_controls_of_usecase_for_all_devices(uc_mgr,
- ident_value, 0, CTRL_LIST_MODIFIER);
- if (ret != 0)
- ALOGE("Failed to disable mixer controls for %s", ident_value);
- free(ident_value);
- }
- }
- /* Clear the enabled modifiers list */
- if (uc_mgr->modifier_list_count) {
- for (index = 0; index < uc_mgr->modifier_list_count; index++) {
- free(uc_mgr->current_modifier_list[index]);
- uc_mgr->current_modifier_list[index] = NULL;
- }
- free(uc_mgr->current_modifier_list);
- uc_mgr->current_modifier_list = NULL;
- uc_mgr->modifier_list_count = 0;
- }
- /* Disable mixer controls of current use case verb */
- if(strncmp(uc_mgr->card_ctxt_ptr->current_verb, SND_USE_CASE_VERB_INACTIVE,
- strlen(SND_USE_CASE_VERB_INACTIVE))) {
- ret = set_controls_of_usecase_for_all_devices(uc_mgr,
- uc_mgr->card_ctxt_ptr->current_verb, 0, CTRL_LIST_VERB);
- if (ret != 0)
- ALOGE("Failed to disable mixer controls for %s",
- uc_mgr->card_ctxt_ptr->current_verb);
- strlcpy(uc_mgr->card_ctxt_ptr->current_verb, SND_USE_CASE_VERB_INACTIVE,
- MAX_STR_LEN);
- }
- /* Disable mixer controls of all the enabled devices */
- list_size = snd_ucm_get_size_of_list(uc_mgr->card_ctxt_ptr->dev_list_head);
- for (index = (list_size-1); index >= 0; index--) {
- if ((ident_value =
- snd_ucm_get_value_at_index(uc_mgr->card_ctxt_ptr->dev_list_head,
- index))) {
- snd_ucm_del_ident_from_list(&uc_mgr->card_ctxt_ptr->dev_list_head,
- ident_value);
- ret = set_controls_of_device_for_all_usecases(uc_mgr,
- ident_value, 0);
- if (ret != 0)
- ALOGE("Failed to disable or no mixer controls set for %s",
- ident_value);
- free(ident_value);
- }
- }
- /* Clear the enabled devices list */
- if (uc_mgr->device_list_count) {
- for (index = 0; index < uc_mgr->device_list_count; index++) {
- free(uc_mgr->current_device_list[index]);
- uc_mgr->current_device_list[index] = NULL;
- }
- free(uc_mgr->current_device_list);
- uc_mgr->current_device_list = NULL;
- uc_mgr->device_list_count = 0;
- }
- uc_mgr->current_tx_device = -1;
- uc_mgr->current_rx_device = -1;
- pthread_mutex_unlock(&uc_mgr->card_ctxt_ptr->card_lock);
- return ret;
-}
-
-/* 2nd stage parsing done in seperate thread */
-void *second_stage_parsing_thread(void *uc_mgr_ptr)
-{
- use_case_verb_t *verb_list;
- char path[200];
- struct stat st;
- int fd, index = 0, ret = 0, rc = 0;
- char *read_buf = NULL, *next_str = NULL, *current_str = NULL, *buf = NULL;
- char *p = NULL, *verb_name = NULL, *file_name = NULL, *temp_ptr = NULL;
- snd_use_case_mgr_t **uc_mgr = (snd_use_case_mgr_t **)&uc_mgr_ptr;
-
- strlcpy(path, CONFIG_DIR, (strlen(CONFIG_DIR)+1));
- strlcat(path, (*uc_mgr)->card_ctxt_ptr->card_name, sizeof(path));
- ALOGV("master config file path:%s", path);
- fd = open(path, O_RDONLY);
- if (fd < 0) {
- ALOGE("failed to open config file %s error %d\n", path, errno);
- return NULL;
- }
- if (fstat(fd, &st) < 0) {
- ALOGE("failed to stat %s error %d\n", path, errno);
- close(fd);
- return NULL;
- }
- read_buf = (char *) mmap(0, st.st_size, PROT_READ | PROT_WRITE,
- MAP_PRIVATE, fd, 0);
- if (read_buf == MAP_FAILED) {
- ALOGE("failed to mmap file error %d\n", errno);
- close(fd);
- return NULL;
- }
- current_str = read_buf;
- verb_name = NULL;
- while (*current_str != (char)EOF) {
- next_str = strchr(current_str, '\n');
- if (!next_str)
- break;
- *next_str++ = '\0';
- if (verb_name == NULL) {
- buf = strstr(current_str, "SectionUseCase");
- if (buf == NULL) {
- if((current_str = next_str) == NULL)
- break;
- else
- continue;
- }
- /* Ignore parsing first use case (HiFi) as it is already parsed
- * in 1st stage of parsing */
- if (index == 0) {
- index++;
- if((current_str = next_str) == NULL)
- break;
- else
- continue;
- }
- p = strtok_r(buf, ".", &temp_ptr);
- while (p != NULL) {
- p = strtok_r(NULL, "\"", &temp_ptr);
- if (p == NULL)
- break;
- verb_name = (char *)malloc((strlen(p)+1)*sizeof(char));
- if(verb_name == NULL) {
- ret = -ENOMEM;
- break;
- }
- strlcpy(verb_name, p, (strlen(p)+1)*sizeof(char));
- break;
- }
- } else {
- buf = strstr(current_str, "File");
- if (buf == NULL) {
- if((current_str = next_str) == NULL)
- break;
- else
- continue;
- }
- p = strtok_r(buf, "\"", &temp_ptr);
- while (p != NULL) {
- p = strtok_r(NULL, "\"", &temp_ptr);
- if (p == NULL)
- break;
- file_name = (char *)malloc((strlen(p)+1)*sizeof(char));
- if(file_name == NULL) {
- ret = -ENOMEM;
- break;
- }
- strlcpy(file_name, p, (strlen(p)+1)*sizeof(char));
- break;
- }
- verb_list = (*uc_mgr)->card_ctxt_ptr->use_case_verb_list;
- if (file_name != NULL) {
- ret = snd_ucm_parse_verb(uc_mgr, file_name, index);
- verb_list[index].use_case_name =
- (char *)malloc((strlen(verb_name)+1)*sizeof(char));
- strlcpy(verb_list[index].use_case_name, verb_name,
- ((strlen(verb_name)+1)*sizeof(char)));
- /* Verb list might have been appended with END OF LIST in
- * 1st stage parsing. Delete this entry so that new verbs
- * are appended from here and END OF LIST will be added
- * again at the end of 2nd stage parsing
- */
- if((*uc_mgr)->card_ctxt_ptr->verb_list[index]) {
- free((*uc_mgr)->card_ctxt_ptr->verb_list[index]);
- (*uc_mgr)->card_ctxt_ptr->verb_list[index] = NULL;
- }
- (*uc_mgr)->card_ctxt_ptr->verb_list[index] =
- (char *)malloc((strlen(verb_name)+1)*sizeof(char));
- strlcpy((*uc_mgr)->card_ctxt_ptr->verb_list[index], verb_name,
- ((strlen(verb_name)+1)*sizeof(char)));
- free(verb_name);
- verb_name = NULL;
- free(file_name);
- file_name = NULL;
- }
- index++;
- (*uc_mgr)->card_ctxt_ptr->verb_list[index] =
- (char *)malloc((strlen(SND_UCM_END_OF_LIST)+1)*sizeof(char));
- strlcpy((*uc_mgr)->card_ctxt_ptr->verb_list[index],
- SND_UCM_END_OF_LIST,
- ((strlen(SND_UCM_END_OF_LIST)+1)*sizeof(char)));
- }
- if((current_str = next_str) == NULL)
- break;
- }
- if (verb_name != NULL) {
- free(verb_name);
- verb_name = NULL;
- }
- if (file_name != NULL) {
- free(file_name);
- file_name = NULL;
- }
- munmap(read_buf, st.st_size);
- close(fd);
-#if PARSE_DEBUG
- /* Prints use cases and mixer controls parsed from config files */
- snd_ucm_print((*uc_mgr));
-#endif
- if(ret < 0)
- ALOGE("Failed to parse config files: %d", ret);
- ALOGE("Exiting parsing thread uc_mgr %p\n", uc_mgr);
- return NULL;
-}
-
-/* Function can be used by UCM clients to wait until parsing completes
- * uc_mgr - use case manager structure
- * Returns 0 on success, error number otherwise
-*/
-int snd_use_case_mgr_wait_for_parsing(snd_use_case_mgr_t *uc_mgr)
-{
- int ret;
-
- ret = pthread_join(uc_mgr->thr, NULL);
- return ret;
-}
-
-/* Parse config files and update mixer controls for the use cases
- * 1st stage parsing done to parse HiFi config file
- * uc_mgr - use case manager structure
- * Returns 0 on sucess, negative error code otherwise
- */
-static int snd_ucm_parse(snd_use_case_mgr_t **uc_mgr)
-{
- use_case_verb_t *verb_list;
- struct stat st;
- int fd, verb_count, index = 0, ret = 0, rc;
- char *read_buf, *next_str, *current_str, *buf, *p, *verb_name;
- char *file_name = NULL, *temp_ptr;
- char path[200];
-
- strlcpy(path, CONFIG_DIR, (strlen(CONFIG_DIR)+1));
- strlcat(path, (*uc_mgr)->card_ctxt_ptr->card_name, sizeof(path));
- ALOGV("master config file path:%s", path);
- fd = open(path, O_RDONLY);
- if (fd < 0) {
- ALOGE("failed to open config file %s error %d\n", path, errno);
- return -EINVAL;
- }
- if (fstat(fd, &st) < 0) {
- ALOGE("failed to stat %s error %d\n", path, errno);
- close(fd);
- return -EINVAL;
- }
- read_buf = (char *) mmap(0, st.st_size, PROT_READ | PROT_WRITE,
- MAP_PRIVATE, fd, 0);
- if (read_buf == MAP_FAILED) {
- ALOGE("failed to mmap file error %d\n", errno);
- close(fd);
- return -EINVAL;
- }
- current_str = read_buf;
- verb_count = get_verb_count(current_str);
- (*uc_mgr)->card_ctxt_ptr->use_case_verb_list =
- (use_case_verb_t *)malloc((verb_count+1)*(sizeof(use_case_verb_t)));
- if ((*uc_mgr)->card_ctxt_ptr->use_case_verb_list == NULL) {
- ALOGE("failed to allocate memory for use case verb list\n");
- munmap(read_buf, st.st_size);
- close(fd);
- return -ENOMEM;
- }
- if (((*uc_mgr)->card_ctxt_ptr->verb_list =
- (char **)malloc((verb_count+2)*(sizeof(char *)))) == NULL) {
- ALOGE("failed to allocate memory for verb list\n");
- munmap(read_buf, st.st_size);
- close(fd);
- return -ENOMEM;
- }
- verb_name = NULL;
- if ((ret = is_single_config_format(current_str))) {
- ALOGD("Single config file format detected\n");
- ret = parse_single_config_format(uc_mgr, current_str, verb_count);
- munmap(read_buf, st.st_size);
- close(fd);
- return ret;
- }
- while (*current_str != (char)EOF) {
- next_str = strchr(current_str, '\n');
- if (!next_str)
- break;
- *next_str++ = '\0';
- if (verb_name == NULL) {
- buf = strstr(current_str, "SectionUseCase");
- if (buf == NULL) {
- if((current_str = next_str) == NULL)
- break;
- else
- continue;
- }
- verb_list = (*uc_mgr)->card_ctxt_ptr->use_case_verb_list;
- p = strtok_r(buf, ".", &temp_ptr);
- while (p != NULL) {
- p = strtok_r(NULL, "\"", &temp_ptr);
- if (p == NULL)
- break;
- verb_name = (char *)malloc((strlen(p)+1)*sizeof(char));
- if(verb_name == NULL) {
- ret = -ENOMEM;
- break;
- }
- strlcpy(verb_name, p, (strlen(p)+1)*sizeof(char));
- if ((verb_list[index].use_case_name =
- (char *)malloc((strlen(verb_name)+1)*sizeof(char)))) {
- strlcpy(verb_list[index].use_case_name,
- verb_name, ((strlen(verb_name)+1)*sizeof(char)));
- } else {
- ret = -ENOMEM;
- break;
- }
- if (((*uc_mgr)->card_ctxt_ptr->verb_list[index] =
- (char *)malloc((strlen(verb_name)+1)*sizeof(char)))) {
- strlcpy((*uc_mgr)->card_ctxt_ptr->verb_list[index],
- verb_name, ((strlen(verb_name)+1)*sizeof(char)));
- } else {
- ret = -ENOMEM;
- break;
- }
- break;
- }
- } else {
- buf = strstr(current_str, "File");
- if (buf == NULL) {
- if((current_str = next_str) == NULL)
- break;
- else
- continue;
- }
- p = strtok_r(buf, "\"", &temp_ptr);
- while (p != NULL) {
- p = strtok_r(NULL, "\"", &temp_ptr);
- if (p == NULL)
- break;
- file_name = (char *)malloc((strlen(p)+1)*sizeof(char));
- if(file_name == NULL) {
- ret = -ENOMEM;
- break;
- }
- strlcpy(file_name, p, (strlen(p)+1)*sizeof(char));
- break;
- }
- if (file_name != NULL) {
- ret = snd_ucm_parse_verb(uc_mgr, file_name, index);
- if (ret < 0)
- ALOGE("Failed to parse config file %s\n", file_name);
- free(verb_name);
- verb_name = NULL;
- free(file_name);
- file_name = NULL;
- }
- index++;
- /* Break here so that only one first use case config file (HiFi)
- * from master config file is parsed initially and all other
- * config files are parsed in seperate thread created below so
- * that audio HAL can initialize faster during boot-up
- */
- break;
- }
- if((current_str = next_str) == NULL)
- break;
- }
- munmap(read_buf, st.st_size);
- close(fd);
- if (((*uc_mgr)->card_ctxt_ptr->verb_list[index] =
- (char *)malloc((strlen(SND_UCM_END_OF_LIST)+1)*sizeof(char)))) {
- strlcpy((*uc_mgr)->card_ctxt_ptr->verb_list[index], SND_UCM_END_OF_LIST,
- ((strlen(SND_UCM_END_OF_LIST)+1)*sizeof(char)));
- } else {
- ALOGE("Failed to allocate memory\n");
- ret = -ENOMEM;
- }
- if (!ret) {
- ALOGD("Creating Parsing thread uc_mgr %p\n", uc_mgr);
- rc = pthread_create(&(*uc_mgr)->thr, 0, second_stage_parsing_thread,
- (void*)(*uc_mgr));
- if(rc < 0) {
- ALOGE("Failed to create parsing thread rc %d errno %d\n", rc, errno);
- } else {
- ALOGV("Prasing thread created successfully\n");
- }
- }
- if (verb_name)
- free(verb_name);
- if (file_name)
- free(file_name);
- return ret;
-}
-
-/* Parse a single config file format
- * uc_mgr - use case manager structure
- * buf - config file buffer to be parsed
- * Returns 0 on sucess, negative error code otherwise
- */
-static int parse_single_config_format(snd_use_case_mgr_t **uc_mgr,
-char *current_str, int num_verbs)
-{
- struct stat st;
- card_mctrl_t *list;
- use_case_verb_t *verb_list;
- int verb_count = 0, device_count = 0, mod_count = 0, index = -1, ret = 0;
- char *next_str, *buf, *p, *verb_ptr, *temp_ptr;
-
- verb_list = (*uc_mgr)->card_ctxt_ptr->use_case_verb_list;
- while (*current_str != (char)EOF) {
- next_str = strchr(current_str, '\n');
- if (!next_str)
- break;
- *next_str++ = '\0';
- if ((buf = strcasestr(current_str, "SectionUseCase")) != NULL) {
- if (index != -1) {
- list = (verb_list[index].verb_ctrls +
- verb_list[index].verb_count);
- list->case_name = (char *)
- malloc((strlen(SND_UCM_END_OF_LIST)+1)*sizeof(char));
- if(list->case_name == NULL) {
- free(verb_list[index].verb_ctrls);
- return -ENOMEM;
- }
- strlcpy(list->case_name, SND_UCM_END_OF_LIST,
- (strlen(SND_UCM_END_OF_LIST)+1)*sizeof(char));
- list->ena_mixer_list = NULL;
- list->dis_mixer_list = NULL;
- list->ena_mixer_count = 0;
- list->dis_mixer_count = 0;
- list->playback_dev_name = NULL;
- list->capture_dev_name = NULL;
- list->acdb_id = 0;
- list->capability = 0;
- }
- index++;
- p = strtok_r(buf, ".", &temp_ptr);
- while (p != NULL) {
- p = strtok_r(NULL, "\"", &temp_ptr);
- if (p == NULL)
- break;
- if ((verb_list[index].use_case_name =
- (char *)malloc((strlen(p)+1)*sizeof(char)))) {
- strlcpy(verb_list[index].use_case_name,
- p, ((strlen(p)+1)*sizeof(char)));
- } else {
- ret = -ENOMEM;
- break;
- }
- if (((*uc_mgr)->card_ctxt_ptr->verb_list[index] =
- (char *)malloc((strlen(p)+1)*sizeof(char)))) {
- strlcpy((*uc_mgr)->card_ctxt_ptr->verb_list[index],
- p, ((strlen(p)+1)*sizeof(char)));
- } else {
- ret = -ENOMEM;
- break;
- }
- break;
- }
- verb_list[index].verb_count = 0;
- verb_list[index].device_count = 0;
- verb_list[index].mod_count = 0;
- verb_list[index].device_list = NULL;
- verb_list[index].modifier_list = NULL;
- verb_list[index].verb_ctrls = NULL;
- verb_list[index].device_ctrls = NULL;
- verb_list[index].mod_ctrls = NULL;
- verb_count = get_num_verbs_config_format(next_str);
- verb_list[index].verb_ctrls = (card_mctrl_t *)
- malloc((verb_count+1)*sizeof(card_mctrl_t));
- if (verb_list[index].verb_ctrls == NULL) {
- ret = -ENOMEM;
- break;
- }
- verb_list[index].verb_count = 0;
- } else if (!strncasecmp(current_str, "SectionVerb", 11)) {
- ret = snd_ucm_parse_section(uc_mgr, ¤t_str,
- &next_str, index, CTRL_LIST_VERB);
- if (ret < 0)
- break;
- } else if (!strncasecmp(current_str, "SectionDevice", 13)) {
- if (device_count == 0) {
- device_count = get_num_device_config_format(next_str);
- verb_list[0].device_ctrls = (card_mctrl_t *)
- malloc((device_count+1)*sizeof(card_mctrl_t));
- if (verb_list[0].device_ctrls == NULL) {
- ret = -ENOMEM;
- break;
- }
- verb_list[0].device_list =
- (char **)malloc((device_count+1)*sizeof(char *));
- if (verb_list[0].device_list == NULL)
- return -ENOMEM;
- verb_list[0].device_count = 0;
- }
- ret = snd_ucm_parse_section(uc_mgr, ¤t_str,
- &next_str, 0, CTRL_LIST_DEVICE);
- if (ret < 0) {
- break;
- } else {
- list = (verb_list[0].device_ctrls +
- (verb_list[0].device_count - 1));
- verb_ptr = (char *)
- malloc((strlen(list->case_name)+1)*sizeof(char));
- if (verb_ptr == NULL) {
- ret = -ENOMEM;
- break;
- }
- strlcpy(verb_ptr, list->case_name,
- ((strlen(list->case_name)+1)*sizeof(char)));
- verb_list[0].device_list[(verb_list[0].device_count-1)]
- = verb_ptr;
- }
- } else if (!strncasecmp(current_str, "SectionModifier", 15)) {
- if (mod_count == 0) {
- mod_count = get_num_mod_config_format(next_str);
- verb_list[0].mod_ctrls = (card_mctrl_t *)
- malloc((mod_count+1)*sizeof(card_mctrl_t));
- if (verb_list[0].mod_ctrls == NULL) {
- ret = -ENOMEM;
- break;
- }
- verb_list[0].modifier_list =
- (char **)malloc((mod_count+1)*sizeof(char *));
- if (verb_list[0].modifier_list == NULL)
- return -ENOMEM;
- verb_list[0].mod_count = 0;
- }
- ret = snd_ucm_parse_section(uc_mgr, ¤t_str,
- &next_str, 0, CTRL_LIST_MODIFIER);
- if (ret < 0) {
- break;
- } else {
- list = (verb_list[0].mod_ctrls +
- (verb_list[0].mod_count - 1));
- verb_ptr = (char *)
- malloc((strlen(list->case_name)+1)*sizeof(char));
- if (verb_ptr == NULL) {
- ret = -ENOMEM;
- break;
- }
- strlcpy(verb_ptr, list->case_name,
- ((strlen(list->case_name)+1)*sizeof(char)));
- verb_list[0].modifier_list[(verb_list[0].mod_count - 1)]
- = verb_ptr;
- }
- }
- if((current_str = next_str) == NULL)
- break;
- }
- list = (verb_list[index].verb_ctrls +
- verb_list[index].verb_count);
- list->case_name =
- (char *)malloc((strlen(SND_UCM_END_OF_LIST)+1)*sizeof(char));
- if(list->case_name == NULL) {
- free(verb_list[index].verb_ctrls);
- return -ENOMEM;
- }
- strlcpy(list->case_name, SND_UCM_END_OF_LIST,
- (strlen(SND_UCM_END_OF_LIST)+1)*sizeof(char));
- list->ena_mixer_list = NULL;
- list->dis_mixer_list = NULL;
- list->ena_mixer_count = 0;
- list->dis_mixer_count = 0;
- list->playback_dev_name = NULL;
- list->capture_dev_name = NULL;
- list->acdb_id = 0;
- list->capability = 0;
- index++;
- if (index != -1) {
- if (((*uc_mgr)->card_ctxt_ptr->verb_list[index] =
- (char *)malloc((strlen(SND_UCM_END_OF_LIST)+1)*sizeof(char)))) {
- strlcpy((*uc_mgr)->card_ctxt_ptr->verb_list[index],
- SND_UCM_END_OF_LIST,
- ((strlen(SND_UCM_END_OF_LIST)+1)*sizeof(char)));
- } else {
- ALOGE("Failed to allocate memory\n");
- ret = -ENOMEM;
- }
- }
- /* Add end of list to device list */
- verb_ptr =
- (char *)malloc((strlen(SND_UCM_END_OF_LIST)+1)*sizeof(char));
- if (verb_ptr == NULL)
- return -ENOMEM;
- strlcpy(verb_ptr, SND_UCM_END_OF_LIST,
- ((strlen(SND_UCM_END_OF_LIST)+1)*sizeof(char)));
- verb_list[0].device_list[verb_list[0].device_count] = verb_ptr;
- /* Add end of list to modifier list */
- verb_ptr =
- (char *)malloc((strlen(SND_UCM_END_OF_LIST)+1)*sizeof(char));
- if (verb_ptr == NULL)
- return -ENOMEM;
- strlcpy(verb_ptr, SND_UCM_END_OF_LIST,
- ((strlen(SND_UCM_END_OF_LIST)+1)*sizeof(char)));
- verb_list[0].modifier_list[verb_list[0].mod_count] = verb_ptr;
- /* Add end of list to device controls list */
- list = (verb_list[0].device_ctrls +
- verb_list[0].device_count);
- list->case_name =
- (char *)malloc((strlen(SND_UCM_END_OF_LIST)+1)*sizeof(char));
- if(list->case_name == NULL) {
- free(verb_list[0].device_ctrls);
- return -ENOMEM;
- }
- strlcpy(list->case_name, SND_UCM_END_OF_LIST,
- (strlen(SND_UCM_END_OF_LIST)+1)*sizeof(char));
- list->ena_mixer_list = NULL;
- list->dis_mixer_list = NULL;
- list->ena_mixer_count = 0;
- list->dis_mixer_count = 0;
- list->playback_dev_name = NULL;
- list->capture_dev_name = NULL;
- list->acdb_id = 0;
- list->capability = 0;
- /* Add end of list to modifier controls list */
- list = (verb_list[0].mod_ctrls +
- verb_list[0].mod_count);
- list->case_name =
- (char *)malloc((strlen(SND_UCM_END_OF_LIST)+1)*sizeof(char));
- if(list->case_name == NULL) {
- free(verb_list[0].mod_ctrls);
- return -ENOMEM;
- }
- strlcpy(list->case_name, SND_UCM_END_OF_LIST,
- (strlen(SND_UCM_END_OF_LIST)+1)*sizeof(char));
- list->ena_mixer_list = NULL;
- list->dis_mixer_list = NULL;
- list->ena_mixer_count = 0;
- list->dis_mixer_count = 0;
- list->playback_dev_name = NULL;
- list->capture_dev_name = NULL;
- list->acdb_id = 0;
- list->capability = 0;
- for (index = 1; index < num_verbs; index++) {
- verb_list[index].device_ctrls = verb_list[0].device_ctrls;
- verb_list[index].device_list = verb_list[0].device_list;
- verb_list[index].device_count = verb_list[0].device_count;
- verb_list[index].mod_ctrls = verb_list[0].mod_ctrls;
- verb_list[index].modifier_list = verb_list[0].modifier_list;
- verb_list[index].mod_count = verb_list[0].mod_count;
- }
- if (ret < 0) {
- ALOGE("Failed to parse config file ret %d errno %d\n", ret, errno);
- } else {
- ALOGV("Prasing done successfully\n");
-#if PARSE_DEBUG
- /* Prints use cases and mixer controls parsed from config files */
- snd_ucm_print((*uc_mgr));
-#endif
- }
- return ret;
-}
-
-/* Returns number of verb sections for specific use case verb*/
-static int get_num_verbs_config_format(const char *nxt_str)
-{
- char *current_str, *next_str, *str_addr, *buf;
- int count = 0;
-
- next_str = (char *)malloc((strlen(nxt_str)+1)*sizeof(char));
- if (next_str == NULL) {
- ALOGE("Failed to allocate memory");
- return -ENOMEM;
- }
- strlcpy(next_str, nxt_str, ((strlen(nxt_str)+1)*sizeof(char)));
- str_addr = next_str;
- current_str = next_str;
- while(1) {
- next_str = strchr(current_str, '\n');
- if (!next_str)
- break;
- *next_str++ = '\0';
- buf = strcasestr(current_str, "SectionUseCase");
- if (buf != NULL)
- break;
- buf = strcasestr(current_str, "SectionVerb");
- if (buf != NULL)
- count++;
- if (*next_str == (char)EOF)
- break;
- if((current_str = next_str) == NULL)
- break;
- }
- free(str_addr);
- return count;
-}
-
-/* Returns number of common device sections for all use case verbs*/
-static int get_num_device_config_format(const char *nxt_str)
-{
- char *current_str, *next_str, *str_addr, *buf;
- int count = 1;
-
- next_str = (char *)malloc((strlen(nxt_str)+1)*sizeof(char));
- if (next_str == NULL) {
- ALOGE("Failed to allocate memory");
- return -ENOMEM;
- }
- strlcpy(next_str, nxt_str, ((strlen(nxt_str)+1)*sizeof(char)));
- str_addr = next_str;
- current_str = next_str;
- while(1) {
- next_str = strchr(current_str, '\n');
- if (!next_str)
- break;
- *next_str++ = '\0';
- buf = strcasestr(current_str, "SectionDevice");
- if (buf != NULL)
- count++;
- if (*next_str == (char)EOF)
- break;
- if((current_str = next_str) == NULL)
- break;
- }
- free(str_addr);
- return count;
-}
-
-/* Returns number of common modifier sections for all use case verbs*/
-static int get_num_mod_config_format(const char *nxt_str)
-{
- char *current_str, *next_str, *str_addr, *buf;
- int count = 1;
-
- next_str = (char *)malloc((strlen(nxt_str)+1)*sizeof(char));
- if (next_str == NULL) {
- ALOGE("Failed to allocate memory");
- return -ENOMEM;
- }
- strlcpy(next_str, nxt_str, ((strlen(nxt_str)+1)*sizeof(char)));
- str_addr = next_str;
- current_str = next_str;
- while(1) {
- next_str = strchr(current_str, '\n');
- if (!next_str)
- break;
- *next_str++ = '\0';
- buf = strcasestr(current_str, "SectionModifier");
- if (buf != NULL)
- count++;
- if (*next_str == (char)EOF)
- break;
- if((current_str = next_str) == NULL)
- break;
- }
- free(str_addr);
- return count;
-}
-
-/* Gets the number of use case verbs defined by master config file */
-static int get_verb_count(const char *nxt_str)
-{
- char *current_str, *next_str, *str_addr, *buf, *p;
- int count = 0;
-
- next_str = (char *)malloc((strlen(nxt_str)+1)*sizeof(char));
- if (next_str == NULL) {
- ALOGE("Failed to allocate memory");
- return -ENOMEM;
- }
- strlcpy(next_str, nxt_str, ((strlen(nxt_str)+1)*sizeof(char)));
- str_addr = next_str;
- current_str = next_str;
- while(1) {
- next_str = strchr(current_str, '\n');
- if (!next_str)
- break;
- *next_str++ = '\0';
- buf = strstr(current_str, "SectionUseCase");
- if (buf != NULL)
- count++;
- if (*next_str == (char)EOF)
- break;
- if((current_str = next_str) == NULL)
- break;
- }
- free(str_addr);
- return count;
-}
-
-/* Returns one if single config file per sound card format is being used */
-static int is_single_config_format(const char *nxt_str)
-{
- char *current_str, *next_str, *str_addr, *buf;
- int ret = 1, count = 0;
-
- next_str = (char *)malloc((strlen(nxt_str)+1)*sizeof(char));
- if (next_str == NULL) {
- ALOGE("Failed to allocate memory");
- return -ENOMEM;
- }
- strlcpy(next_str, nxt_str, ((strlen(nxt_str)+1)*sizeof(char)));
- str_addr = next_str;
- current_str = next_str;
- while(1) {
- next_str = strchr(current_str, '\n');
- if (!next_str)
- break;
- *next_str++ = '\0';
- buf = strstr(current_str, "SectionUseCase");
- if (buf != NULL)
- count++;
- buf = strstr(current_str, "File");
- if (buf != NULL)
- ret = 0;
- if ((*next_str == (char)EOF) || (count == 2))
- break;
- if((current_str = next_str) == NULL)
- break;
- }
- free(str_addr);
- return ret;
-}
-
-/* Parse a use case verb config files and update mixer controls for the verb
- * uc_mgr - use case manager structure
- * file_name - use case verb config file name
- * index - index of the verb in the list
- * Returns 0 on sucess, negative error code otherwise
- */
-static int snd_ucm_parse_verb(snd_use_case_mgr_t **uc_mgr,
-const char *file_name, int index)
-{
- struct stat st;
- card_mctrl_t *list;
- int device_count, modifier_count;
- int fd, ret = 0, parse_count = 0;
- char *read_buf, *next_str, *current_str, *verb_ptr;
- char path[200];
- use_case_verb_t *verb_list;
-
- strlcpy(path, CONFIG_DIR, (strlen(CONFIG_DIR)+1));
- strlcat(path, file_name, sizeof(path));
- ALOGV("path:%s", path);
- verb_list = (*uc_mgr)->card_ctxt_ptr->use_case_verb_list;
- while(1) {
- device_count = 0; modifier_count = 0;
- if (parse_count == 0) {
- verb_list[index].verb_count = 0;
- verb_list[index].device_count = 0;
- verb_list[index].mod_count = 0;
- verb_list[index].device_list = NULL;
- verb_list[index].modifier_list = NULL;
- verb_list[index].verb_ctrls = NULL;
- verb_list[index].device_ctrls = NULL;
- verb_list[index].mod_ctrls = NULL;
- }
- fd = open(path, O_RDONLY);
- if (fd < 0) {
- ALOGE("failed to open config file %s error %d\n", path, errno);
- return -EINVAL;
- }
- if (fstat(fd, &st) < 0) {
- ALOGE("failed to stat %s error %d\n", path, errno);
- close(fd);
- return -EINVAL;
- }
- read_buf = (char *) mmap(0, st.st_size, PROT_READ | PROT_WRITE,
- MAP_PRIVATE, fd, 0);
- if (read_buf == MAP_FAILED) {
- ALOGE("failed to mmap file error %d\n", errno);
- close(fd);
- return -EINVAL;
- }
- current_str = read_buf;
- while (*current_str != (char)EOF) {
- next_str = strchr(current_str, '\n');
- if (!next_str)
- break;
- *next_str++ = '\0';
- if (!strncasecmp(current_str, "SectionVerb", 11)) {
- if (parse_count == 0) {
- verb_list[index].verb_count++;
- } else {
- ret = snd_ucm_parse_section(uc_mgr, ¤t_str,
- &next_str, index, CTRL_LIST_VERB);
- if (ret < 0)
- break;
- }
- } else if (!strncasecmp(current_str, "SectionDevice", 13)) {
- if (parse_count == 0) {
- verb_list[index].device_count++;
- device_count++;
- } else {
- ret = snd_ucm_parse_section(uc_mgr, ¤t_str,
- &next_str, index, CTRL_LIST_DEVICE);
- if (ret < 0) {
- break;
- } else {
- list = (verb_list[index].device_ctrls +
- (verb_list[index].device_count - 1));
- verb_ptr = (char *)
- malloc((strlen(list->case_name)+1)*sizeof(char));
- if (verb_ptr == NULL) {
- ret = -ENOMEM;
- break;
- }
- strlcpy(verb_ptr, list->case_name,
- ((strlen(list->case_name)+1)*sizeof(char)));
- verb_list[index].device_list[device_count] = verb_ptr;
- device_count++;
- }
- }
- } else if (!strncasecmp(current_str, "SectionModifier", 15)) {
- if (parse_count == 0) {
- verb_list[index].mod_count++;
- modifier_count++;
- } else {
- ret = snd_ucm_parse_section(uc_mgr, ¤t_str,
- &next_str, index, CTRL_LIST_MODIFIER);
- if (ret < 0) {
- break;
- } else {
- list = (verb_list[index].mod_ctrls +
- (verb_list[index].mod_count - 1));
- verb_ptr = (char *)
- malloc((strlen(list->case_name)+1)*sizeof(char));
- if (verb_ptr == NULL) {
- ret = -ENOMEM;
- break;
- }
- strlcpy(verb_ptr, list->case_name,
- ((strlen(list->case_name)+1)*sizeof(char)));
- verb_list[index].modifier_list[modifier_count]
- = verb_ptr;
- modifier_count++;
- }
- }
- }
- if((current_str = next_str) == NULL)
- break;
- }
- munmap(read_buf, st.st_size);
- close(fd);
- if(ret < 0)
- return ret;
- if (parse_count == 0) {
- verb_list[index].device_list =
- (char **)malloc((device_count+1)*sizeof(char *));
- if (verb_list[index].device_list == NULL)
- return -ENOMEM;
- verb_list[index].modifier_list =
- (char **)malloc((modifier_count+1)*sizeof(char *));
- if (verb_list[index].modifier_list == NULL)
- return -ENOMEM;
- parse_count += verb_list[index].verb_count;
- verb_list[index].verb_ctrls = (card_mctrl_t *)
- malloc((verb_list[index].verb_count+1)*sizeof(card_mctrl_t));
- if (verb_list[index].verb_ctrls == NULL) {
- ret = -ENOMEM;
- break;
- }
- verb_list[index].verb_count = 0;
- parse_count += verb_list[index].device_count;
- verb_list[index].device_ctrls = (card_mctrl_t *)
- malloc((verb_list[index].device_count+1)*sizeof(card_mctrl_t));
- if (verb_list[index].device_ctrls == NULL) {
- ret = -ENOMEM;
- break;
- }
- verb_list[index].device_count = 0;
- parse_count += verb_list[index].mod_count;
- verb_list[index].mod_ctrls = (card_mctrl_t *)
- malloc((verb_list[index].mod_count+1)*sizeof(card_mctrl_t));
- if (verb_list[index].mod_ctrls == NULL) {
- ret = -ENOMEM;
- break;
- }
- verb_list[index].mod_count = 0;
- continue;
- } else {
- verb_ptr =
- (char *)malloc((strlen(SND_UCM_END_OF_LIST)+1)*sizeof(char));
- if (verb_ptr == NULL)
- return -ENOMEM;
- strlcpy(verb_ptr, SND_UCM_END_OF_LIST,
- ((strlen(SND_UCM_END_OF_LIST)+1)*sizeof(char)));
- verb_list[index].device_list[device_count] = verb_ptr;
- verb_ptr =
- (char *)malloc((strlen(SND_UCM_END_OF_LIST)+1)*sizeof(char));
- if (verb_ptr == NULL)
- return -ENOMEM;
- strlcpy(verb_ptr, SND_UCM_END_OF_LIST,
- ((strlen(SND_UCM_END_OF_LIST)+1)*sizeof(char)));
- verb_list[index].modifier_list[modifier_count] = verb_ptr;
- list = (verb_list[index].verb_ctrls +
- verb_list[index].verb_count);
- list->case_name =
- (char *)malloc((strlen(SND_UCM_END_OF_LIST)+1)*sizeof(char));
- if(list->case_name == NULL) {
- free(verb_list[index].verb_ctrls);
- return -ENOMEM;
- }
- strlcpy(list->case_name, SND_UCM_END_OF_LIST,
- (strlen(SND_UCM_END_OF_LIST)+1)*sizeof(char));
- list->ena_mixer_list = NULL;
- list->dis_mixer_list = NULL;
- list->ena_mixer_count = 0;
- list->dis_mixer_count = 0;
- list->playback_dev_name = NULL;
- list->capture_dev_name = NULL;
- list->acdb_id = 0;
- list->capability = 0;
- list = (verb_list[index].device_ctrls +
- verb_list[index].device_count);
- list->case_name =
- (char *)malloc((strlen(SND_UCM_END_OF_LIST)+1)*sizeof(char));
- if(list->case_name == NULL) {
- free(verb_list[index].device_ctrls);
- return -ENOMEM;
- }
- strlcpy(list->case_name, SND_UCM_END_OF_LIST,
- (strlen(SND_UCM_END_OF_LIST)+1)*sizeof(char));
- list->ena_mixer_list = NULL;
- list->dis_mixer_list = NULL;
- list->ena_mixer_count = 0;
- list->dis_mixer_count = 0;
- list->playback_dev_name = NULL;
- list->capture_dev_name = NULL;
- list->acdb_id = 0;
- list->capability = 0;
- list = (verb_list[index].mod_ctrls +
- verb_list[index].mod_count);
- list->case_name =
- (char *)malloc((strlen(SND_UCM_END_OF_LIST)+1)*sizeof(char));
- if(list->case_name == NULL) {
- free(verb_list[index].mod_ctrls);
- return -ENOMEM;
- }
- strlcpy(list->case_name, SND_UCM_END_OF_LIST,
- (strlen(SND_UCM_END_OF_LIST)+1)*sizeof(char));
- list->ena_mixer_list = NULL;
- list->dis_mixer_list = NULL;
- list->ena_mixer_count = 0;
- list->dis_mixer_count = 0;
- list->playback_dev_name = NULL;
- list->capture_dev_name = NULL;
- list->acdb_id = 0;
- list->capability = 0;
- parse_count = 0;
- break;
- }
- }
- return ret;
-}
-
-/* Print mixer controls in a specific list
- * list - list to be printed
- * verb_index - verb index
- * count - number of elements in the list
- * Returns 0 on sucess, negative error code otherwise
- */
-static int print_list(card_mctrl_t *list, int verb_index, int count)
-{
- int i, j;
-
- for(i=0; i < count; i++) {
- ALOGD("\tcase name: %s\n", list[i].case_name);
- ALOGD("\tEnable sequence: %d\n", list[i].ena_mixer_count);
- for(j=0; j<list[i].ena_mixer_count; j++) {
- ALOGD("\t\t%s : %d : %d: %s\n",
- list[i].ena_mixer_list[j].control_name,
- list[i].ena_mixer_list[j].type,
- list[i].ena_mixer_list[j].value,
- list[i].ena_mixer_list[j].string);
- }
- ALOGD("\tDisable sequence: %d\n", list[i].dis_mixer_count);
- for(j=0; j<list[i].dis_mixer_count; j++) {
- ALOGD("\t\t%s : %d : %d : %s\n",
- list[i].dis_mixer_list[j].control_name,
- list[i].dis_mixer_list[j].type,
- list[i].dis_mixer_list[j].value,
- list[i].dis_mixer_list[j].string);
- }
- }
- return 0;
-}
-
-/* Print mixer controls extracted from config files
- * uc_mgr - use case manager structure
- * Returns 0 on sucess, negative error code otherwise
- */
-static int snd_ucm_print(snd_use_case_mgr_t *uc_mgr)
-{
- card_mctrl_t *list;
- int i, j, verb_index = 0;
- use_case_verb_t *verb_list;
-
- pthread_mutex_lock(&uc_mgr->card_ctxt_ptr->card_lock);
- verb_list = uc_mgr->card_ctxt_ptr->use_case_verb_list;
- while(strncmp(uc_mgr->card_ctxt_ptr->verb_list[verb_index],
- SND_UCM_END_OF_LIST, 3)) {
- ALOGD("\nuse case verb: %s\n",
- uc_mgr->card_ctxt_ptr->verb_list[verb_index]);
- if(verb_list[verb_index].device_list) {
- ALOGD("\tValid device list:");
- i = 0;
- while(strncmp(verb_list[verb_index].device_list[i],
- SND_UCM_END_OF_LIST, 3)) {
- ALOGD("\t\t%s", verb_list[verb_index].device_list[i]);
- i++;
- }
- }
- if(verb_list[verb_index].modifier_list) {
- ALOGD("\tValid modifier list:");
- i = 0;
- while(strncmp(verb_list[verb_index].modifier_list[i],
- SND_UCM_END_OF_LIST, 3)) {
- ALOGD("\t\t%s", verb_list[verb_index].modifier_list[i]);
- i++;
- }
- }
- ALOGD("Verbs:\n");
- list = verb_list[verb_index].verb_ctrls;
- print_list(list, verb_index, verb_list[verb_index].verb_count);
- ALOGD("Devices:\n");
- list = verb_list[verb_index].device_ctrls;
- print_list(list, verb_index, verb_list[verb_index].device_count);
- ALOGD("Modifier:\n");
- list = verb_list[verb_index].mod_ctrls;
- print_list(list, verb_index, verb_list[verb_index].mod_count);
- verb_index++;
- }
- pthread_mutex_unlock(&uc_mgr->card_ctxt_ptr->card_lock);
- return 0;
-}
-
-/* Gets the number of controls for specific sequence of a use cae */
-static int get_controls_count(const char *nxt_str)
-{
- char *current_str, *next_str, *str_addr;
- int count = 0;
-
- next_str = (char *)malloc((strlen(nxt_str)+1)*sizeof(char));
- if (next_str == NULL) {
- ALOGE("Failed to allocate memory");
- return -ENOMEM;
- }
- strlcpy(next_str, nxt_str, ((strlen(nxt_str)+1)*sizeof(char)));
- str_addr = next_str;
- while(1) {
- current_str = next_str;
- next_str = strchr(current_str, '\n');
- if ((!next_str) || (!strncasecmp(current_str, "EndSection", 10)))
- break;
- *next_str++ = '\0';
- if (strcasestr(current_str, "EndSequence") != NULL) {
- break;
- } else {
- count++;
- }
- if (*next_str == (char)EOF)
- break;
- if(!strncasecmp(current_str, "EndSection", 10))
- break;
- }
- free(str_addr);
- return count;
-}
-
-/* Parse a section of config files
- * uc_mgr - use case manager structure
- * Returns 0 on sucess, negative error code otherwise
- */
-static int snd_ucm_parse_section(snd_use_case_mgr_t **uc_mgr, char **cur_str,
-char **nxt_str, int verb_index, int ctrl_list_type)
-{
- use_case_verb_t *verb_list;
- card_mctrl_t *list;
- int enable_seq = 0, disable_seq = 0, controls_count = 0, ret = 0;
- char *p, *current_str, *next_str, *name;
-
- verb_list = (*uc_mgr)->card_ctxt_ptr->use_case_verb_list;
- if (ctrl_list_type == CTRL_LIST_VERB) {
- list = (verb_list[verb_index].verb_ctrls +
- verb_list[verb_index].verb_count);
- } else if (ctrl_list_type == CTRL_LIST_DEVICE) {
- list = (verb_list[verb_index].device_ctrls +
- verb_list[verb_index].device_count);
- } else if (ctrl_list_type == CTRL_LIST_MODIFIER) {
- list = (verb_list[verb_index].mod_ctrls +
- verb_list[verb_index].mod_count);
- } else {
- ALOGE("Invalid list type: %d\n", ctrl_list_type);
- return -EINVAL;
- }
- list->case_name = NULL;
- list->ena_mixer_list = NULL;
- list->dis_mixer_list = NULL;
- list->ena_mixer_count = 0;
- list->dis_mixer_count = 0;
- list->playback_dev_name = NULL;
- list->capture_dev_name = NULL;
- list->acdb_id = 0;
- list->capability = 0;
- list->effects_mixer_ctl = NULL;
- current_str = *cur_str; next_str = *nxt_str;
- while(strncasecmp(current_str, "EndSection", 10)) {
- current_str = next_str;
- next_str = strchr(current_str, '\n');
- if ((!next_str) || (!strncasecmp(current_str, "EndSection", 10)))
- break;
- *next_str++ = '\0';
- if (strcasestr(current_str, "EndSequence") != NULL) {
- if (enable_seq == 1)
- enable_seq = 0;
- else if (disable_seq == 1)
- disable_seq = 0;
- else
- ALOGE("Error: improper config file\n");
- }
- if (enable_seq == 1) {
- ret = snd_ucm_extract_controls(current_str, &list->ena_mixer_list,
- list->ena_mixer_count);
- if (ret < 0)
- break;
- list->ena_mixer_count++;
- } else if (disable_seq == 1) {
- ret = snd_ucm_extract_controls(current_str, &list->dis_mixer_list,
- list->dis_mixer_count);
- if (ret < 0)
- break;
- list->dis_mixer_count++;
- } else if (strcasestr(current_str, "Name") != NULL) {
- ret = snd_ucm_extract_name(current_str, &list->case_name);
- if (ret < 0)
- break;
- ALOGV("Name of section is %s\n", list->case_name);
- } else if (strcasestr(current_str, "PlaybackPCM") != NULL) {
- ret = snd_ucm_extract_dev_name(current_str,
- &list->playback_dev_name);
- if (ret < 0)
- break;
- ALOGV("Device name of playback is %s\n",
- list->playback_dev_name);
- } else if (strcasestr(current_str, "CapturePCM") != NULL) {
- ret = snd_ucm_extract_dev_name(current_str,
- &list->capture_dev_name);
- if (ret < 0)
- break;
- ALOGV("Device name of capture is %s\n", list->capture_dev_name);
- } else if (strcasestr(current_str, "ACDBID") != NULL) {
- ret = snd_ucm_extract_acdb(current_str, &list->acdb_id,
- &list->capability);
- if (ret < 0)
- break;
- ALOGV("ACDB ID: %d CAPABILITY: %d\n", list->acdb_id,
- list->capability);
- } else if (strcasestr(current_str, "EffectsMixerCTL") != NULL) {
- ret = snd_ucm_extract_effects_mixer_ctl(current_str,
- &list->effects_mixer_ctl);
- if (ret < 0)
- break;
- ALOGV("Effects mixer ctl: %s: %d\n", list->effects_mixer_ctl);
- }
- if (strcasestr(current_str, "EnableSequence") != NULL) {
- controls_count = get_controls_count(next_str);
- if (controls_count < 0) {
- ret = -ENOMEM;
- break;
- }
- list->ena_mixer_list =
- (mixer_control_t *)malloc((controls_count*sizeof(mixer_control_t)));
- if (list->ena_mixer_list == NULL) {
- ret = -ENOMEM;
- break;
- }
- enable_seq = 1;
- } else if (strcasestr(current_str, "DisableSequence") != NULL) {
- controls_count = get_controls_count(next_str);
- if (controls_count < 0) {
- ret = -ENOMEM;
- break;
- }
- list->dis_mixer_list =
- (mixer_control_t *)malloc((controls_count*sizeof(mixer_control_t)));
- if (list->dis_mixer_list == NULL) {
- ret = -ENOMEM;
- break;
- }
- disable_seq = 1;
- }
- if (*next_str == (char)EOF)
- break;
- }
- if(ret == 0) {
- *cur_str = current_str; *nxt_str = next_str;
- if (ctrl_list_type == CTRL_LIST_VERB) {
- verb_list[verb_index].verb_count++;
- } else if (ctrl_list_type == CTRL_LIST_DEVICE) {
- verb_list[verb_index].device_count++;
- } else if (ctrl_list_type == CTRL_LIST_MODIFIER) {
- verb_list[verb_index].mod_count++;
- }
- }
- return ret;
-}
-
-/* Extract a mixer control name from config file
- * Returns 0 on sucess, negative error code otherwise
- */
-static int snd_ucm_extract_name(char *buf, char **case_name)
-{
- int ret = 0;
- char *p, *name = *case_name, *temp_ptr;
-
- p = strtok_r(buf, "\"", &temp_ptr);
- while (p != NULL) {
- p = strtok_r(NULL, "\"", &temp_ptr);
- if (p == NULL)
- break;
- name = (char *)malloc((strlen(p)+1)*sizeof(char));
- if(name == NULL) {
- ret = -ENOMEM;
- break;
- }
- strlcpy(name, p, (strlen(p)+1)*sizeof(char));
- *case_name = name;
- break;
- }
- return ret;
-}
-
-/* Extract a ACDB ID and capability of use case from config file
- * Returns 0 on sucess, negative error code otherwise
- */
-static int snd_ucm_extract_acdb(char *buf, int *id, int *cap)
-{
- char *p, key[] = "0123456789", *temp_ptr;
-
- p = strpbrk(buf, key);
- if (p == NULL) {
- *id = 0;
- *cap = 0;
- } else {
- p = strtok_r(p, ":", &temp_ptr);
- while (p != NULL) {
- *id = atoi(p);
- p = strtok_r(NULL, "\0", &temp_ptr);
- if (p == NULL)
- break;
- *cap = atoi(p);
- break;
- }
- }
- return 0;
-}
-
-/* Extract Effects Mixer ID of device from config file
- * Returns 0 on sucess, negative error code otherwise
- */
-static int snd_ucm_extract_effects_mixer_ctl(char *buf, char **mixer_name)
-{
- int ret = 0;
- char *p, *name = *mixer_name, *temp_ptr;
-
- p = strtok_r(buf, "\"", &temp_ptr);
- while (p != NULL) {
- p = strtok_r(NULL, "\"", &temp_ptr);
- if (p == NULL)
- break;
- name = (char *)malloc((strlen(p)+1)*sizeof(char));
- if(name == NULL) {
- ret = -ENOMEM;
- break;
- }
- strlcpy(name, p, (strlen(p)+1)*sizeof(char));
- *mixer_name = name;
- break;
- }
- return ret;
-}
-
-/* Extract a playback and capture device name of use case from config file
- * Returns 0 on sucess, negative error code otherwise
- */
-static int snd_ucm_extract_dev_name(char *buf, char **dev_name)
-{
- char key[] = "0123456789";
- char *p, *name = *dev_name;
- char dev_pre[] = "hw:0,";
- char *temp_ptr;
-
- p = strpbrk(buf, key);
- if (p == NULL) {
- *dev_name = NULL;
- } else {
- p = strtok_r(p, "\r\n", &temp_ptr);
- if (p == NULL) {
- *dev_name = NULL;
- } else {
- name = (char *)malloc((strlen(p)+strlen(dev_pre)+1)*sizeof(char));
- if(name == NULL)
- return -ENOMEM;
- strlcpy(name, dev_pre, (strlen(p)+strlen(dev_pre)+1)*sizeof(char));
- strlcat(name, p, (strlen(p)+strlen(dev_pre)+1)*sizeof(char));
- *dev_name = name;
- }
- }
- return 0;
-}
-
-static int get_num_values(const char *buf)
-{
- char *buf_addr, *p;
- int count = 0;
- char *temp_ptr;
-
- buf_addr = (char *)malloc((strlen(buf)+1)*sizeof(char));
- if (buf_addr == NULL) {
- ALOGE("Failed to allocate memory");
- return -ENOMEM;
- }
- strlcpy(buf_addr, buf, ((strlen(buf)+1)*sizeof(char)));
- p = strtok_r(buf_addr, " ", &temp_ptr);
- while (p != NULL) {
- count++;
- p = strtok_r(NULL, " ", &temp_ptr);
- if (p == NULL)
- break;
- }
- free(buf_addr);
- return count;
-}
-
-/* Extract a mixer control from config file
- * Returns 0 on sucess, negative error code otherwise
- */
-static int snd_ucm_extract_controls(char *buf, mixer_control_t **mixer_list,
-int size)
-{
- unsigned long temp;
- int ret = -EINVAL, i, index = 0, count = 0;
- char *p, *ps, *pmv, temp_coeff[20];
- mixer_control_t *list;
- static const char *const seps = "\r\n";
- char *temp_ptr, *temp_vol_ptr;
-
- p = strtok_r(buf, "'", &temp_ptr);
- while (p != NULL) {
- p = strtok_r(NULL, "'", &temp_ptr);
- if (p == NULL)
- break;
- list = ((*mixer_list)+size);
- list->control_name = (char *)malloc((strlen(p)+1)*sizeof(char));
- if(list->control_name == NULL) {
- ret = -ENOMEM;
- free((*mixer_list));
- break;
- }
- strlcpy(list->control_name, p, (strlen(p)+1)*sizeof(char));
- p = strtok_r(NULL, ":", &temp_ptr);
- if (p == NULL)
- break;
- if(!strncmp(p, "0", 1)) {
- list->type = TYPE_STR;
- } else if(!strncmp(p, "1", 1)) {
- list->type = TYPE_INT;
- } else if(!strncmp(p, "2", 1)) {
- list->type = TYPE_MULTI_VAL;
- } else {
- ALOGE("Unknown type: p %s\n", p);
- }
- p = strtok_r(NULL, seps, &temp_ptr);
- if (p == NULL)
- break;
- if(list->type == TYPE_INT) {
- list->value = atoi(p);
- list->string = NULL;
- list->mulval = NULL;
- } else if(list->type == TYPE_STR) {
- list->value = -1;
- list->string = (char *)malloc((strlen(p)+1)*sizeof(char));
- list->mulval = NULL;
- if(list->string == NULL) {
- ret = -ENOMEM;
- free((*mixer_list));
- free(list->control_name);
- break;
- }
- strlcpy(list->string, p, (strlen(p)+1)*sizeof(char));
- } else if(list->type == TYPE_MULTI_VAL) {
- if (p != NULL) {
- count = get_num_values(p);
- list->mulval = (char **)malloc(count*sizeof(char *));
- if (list->mulval == NULL) {
- ret = -ENOMEM;
- free((*mixer_list));
- free(list->control_name);
- break;
- }
- index = 0;
- /* To support volume values in percentage */
- if ((count == 1) && (strstr(p, "%") != NULL)) {
- pmv = strtok_r(p, " ", &temp_vol_ptr);
- while (pmv != NULL) {
- list->mulval[index] =
- (char *)malloc((strlen(pmv)+1)*sizeof(char));
- strlcpy(list->mulval[index], pmv, (strlen(pmv)+1));
- index++;
- pmv = strtok_r(NULL, " ", &temp_vol_ptr);
- if (pmv == NULL)
- break;
- }
- } else {
- pmv = strtok_r(p, " ", &temp_vol_ptr);
- while (pmv != NULL) {
- temp = strtoul(pmv, &ps, 16);
- snprintf(temp_coeff, sizeof(temp_coeff),"%lu", temp);
- list->mulval[index] =
- (char *)malloc((strlen(temp_coeff)+1)*sizeof(char));
- strlcpy(list->mulval[index], temp_coeff,
- (strlen(temp_coeff)+1));
- index++;
- pmv = strtok_r(NULL, " ", &temp_vol_ptr);
- if (pmv == NULL)
- break;
- }
- }
- list->value = count;
- list->string = NULL;
- }
- } else {
- ALOGE("Unknown type: p %s\n", p);
- list->value = -1;
- list->string = NULL;
- }
- ret = 0;
- break;
- }
- return ret;
-}
-
-void free_list(card_mctrl_t *list, int verb_index, int count)
-{
- int case_index = 0, index = 0, mindex = 0;
-
- for(case_index = 0; case_index < count; case_index++) {
- for(index = 0; index < list[case_index].ena_mixer_count; index++) {
- if(list[case_index].ena_mixer_list[index].control_name) {
- free(list[case_index].ena_mixer_list[index].control_name);
- }
- if(list[case_index].ena_mixer_list[index].string) {
- free(list[case_index].ena_mixer_list[index].string);
- }
- if(list[case_index].ena_mixer_list[index].mulval) {
- for(mindex = 0;
- mindex < list[case_index].ena_mixer_list[index].value;
- mindex++) {
- free(list[case_index].ena_mixer_list[index].mulval[mindex]);
- }
- if(list[case_index].ena_mixer_list[index].mulval) {
- free(list[case_index].ena_mixer_list[index].mulval);
- }
- }
- }
- for(index = 0; index < list[case_index].dis_mixer_count; index++) {
- if(list[case_index].dis_mixer_list[index].control_name) {
- free(list[case_index].dis_mixer_list[index].control_name);
- }
- if(list[case_index].dis_mixer_list[index].string) {
- free(list[case_index].dis_mixer_list[index].string);
- }
- if(list[case_index].dis_mixer_list[index].mulval) {
- for(mindex = 0;
- mindex < list[case_index].dis_mixer_list[index].value;
- mindex++) {
- free(list[case_index].dis_mixer_list[index].mulval[mindex]);
- }
- if(list[case_index].dis_mixer_list[index].mulval) {
- free(list[case_index].dis_mixer_list[index].mulval);
- }
- }
- }
- if(list[case_index].case_name) {
- free(list[case_index].case_name);
- }
- if(list[case_index].ena_mixer_list) {
- free(list[case_index].ena_mixer_list);
- }
- if(list[case_index].dis_mixer_list) {
- free(list[case_index].dis_mixer_list);
- }
- if(list[case_index].playback_dev_name) {
- free(list[case_index].playback_dev_name);
- }
- if(list[case_index].capture_dev_name) {
- free(list[case_index].capture_dev_name);
- }
- if(list[case_index].effects_mixer_ctl) {
- list[case_index].effects_mixer_ctl = NULL;
- }
- }
-}
-
-void snd_ucm_free_mixer_list(snd_use_case_mgr_t **uc_mgr)
-{
- card_mctrl_t *ctrl_list;
- use_case_verb_t *verb_list;
- int index = 0, verb_index = 0;
-
- pthread_mutex_lock(&(*uc_mgr)->card_ctxt_ptr->card_lock);
- verb_list = (*uc_mgr)->card_ctxt_ptr->use_case_verb_list;
- while(strncmp((*uc_mgr)->card_ctxt_ptr->verb_list[verb_index],
- SND_UCM_END_OF_LIST, 3)) {
- ctrl_list = verb_list[verb_index].verb_ctrls;
- free_list(ctrl_list, verb_index, verb_list[verb_index].verb_count);
- if(verb_list[verb_index].use_case_name)
- free(verb_list[verb_index].use_case_name);
- if((*uc_mgr)->card_ctxt_ptr->verb_list[verb_index]) {
- free((*uc_mgr)->card_ctxt_ptr->verb_list[verb_index]);
- }
- verb_index++;
- }
- verb_index -= 1;
- ctrl_list = verb_list[verb_index].device_ctrls;
- free_list(ctrl_list, verb_index, verb_list[verb_index].device_count);
- ctrl_list = verb_list[verb_index].mod_ctrls;
- free_list(ctrl_list, verb_index, verb_list[verb_index].mod_count);
- index = 0;
- while(1) {
- if (verb_list[verb_index].device_list[index]) {
- if (!strncmp(verb_list[verb_index].device_list[index],
- SND_UCM_END_OF_LIST, 3)) {
- free(verb_list[verb_index].device_list[index]);
- break;
- } else {
- free(verb_list[verb_index].device_list[index]);
- index++;
- }
- }
- }
- if (verb_list[verb_index].device_list)
- free(verb_list[verb_index].device_list);
- index = 0;
- while(1) {
- if (verb_list[verb_index].modifier_list[index]) {
- if (!strncmp(verb_list[verb_index].modifier_list[index],
- SND_UCM_END_OF_LIST, 3)) {
- free(verb_list[verb_index].modifier_list[index]);
- break;
- } else {
- free(verb_list[verb_index].modifier_list[index]);
- index++;
- }
- }
- }
- if (verb_list[verb_index].modifier_list)
- free(verb_list[verb_index].modifier_list);
- if((*uc_mgr)->card_ctxt_ptr->use_case_verb_list)
- free((*uc_mgr)->card_ctxt_ptr->use_case_verb_list);
- if((*uc_mgr)->card_ctxt_ptr->verb_list)
- free((*uc_mgr)->card_ctxt_ptr->verb_list);
- pthread_mutex_unlock(&(*uc_mgr)->card_ctxt_ptr->card_lock);
-}
-
-/* Add an identifier to the respective list
- * head - list head
- * value - node value that needs to be added
- * Returns 0 on sucess, negative error code otherwise
- */
-static int snd_ucm_add_ident_to_list(struct snd_ucm_ident_node **head,
-const char *value)
-{
- struct snd_ucm_ident_node *temp, *node;
-
- node =
- (struct snd_ucm_ident_node *)malloc(sizeof(struct snd_ucm_ident_node));
- if (node == NULL) {
- ALOGE("Failed to allocate memory for new node");
- return -ENOMEM;
- } else {
- node->next = NULL;
- strlcpy(node->ident, value, MAX_STR_LEN);
- node->active = 0;
- node->capability = 0;
- }
- if (*head == NULL) {
- *head = node;
- } else {
- temp = *head;
- while (temp->next != NULL) {
- temp = temp->next;
- }
- temp->next = node;
- }
- ALOGV("add_to_list: head %p, value %s", *head, node->ident);
- return 0;
-}
-
-/* Get the status of identifier at particulare index of the list
- * head - list head
- * ident - identifier value for which status needs to be get
- * status - status to be set (1 - active, 0 - inactive)
- */
-static int snd_ucm_get_status_at_index(struct snd_ucm_ident_node *head,
-const char *ident)
-{
- while (head != NULL) {
- if(!strncmp(ident, head->ident, (strlen(head->ident)+1))) {
- break;
- }
- head = head->next;
- }
- if (head == NULL) {
- ALOGV("Element not found in the list");
- } else {
- return(head->active);
- }
- return -EINVAL;
-}
-
-/* Get the node at particular index
- * head - list head
- * index - index value
- */
-struct snd_ucm_ident_node *snd_ucm_get_device_node(struct snd_ucm_ident_node *head,
-int index)
-{
- if (head == NULL) {
- ALOGV("Empty list");
- return NULL;
- }
-
- if ((index < 0) || (index >= (snd_ucm_get_size_of_list(head)))) {
- ALOGE("Element with given index %d doesn't exist in the list", index);
- return NULL;
- }
-
- while (index) {
- head = head->next;
- index--;
- }
-
- return head;
-}
-
-/* Set the status of identifier at particulare index of the list
- * head - list head
- * ident - identifier value for which status needs to be set
- * status - status to be set (1 - active, 0 - inactive)
- */
-static void snd_ucm_set_status_at_index(struct snd_ucm_ident_node *head,
-const char *ident, int status, int capability)
-{
- while (head != NULL) {
- if(!strncmp(ident, head->ident, (strlen(head->ident)+1))) {
- break;
- }
- head = head->next;
- }
- if (head == NULL) {
- ALOGE("Element not found to set the status");
- } else {
- head->active = status;
- head->capability = capability;
- }
-}
-
-/* Get the identifier value at particulare index of the list
- * head - list head
- * index - node index value
- * Returns node idetifier value at index on sucess, NULL otherwise
- */
-static char *snd_ucm_get_value_at_index(struct snd_ucm_ident_node *head,
-int index)
-{
- if (head == NULL) {
- ALOGV("Empty list");
- return NULL;
- }
-
- if ((index < 0) || (index >= (snd_ucm_get_size_of_list(head)))) {
- ALOGE("Element with given index %d doesn't exist in the list", index);
- return NULL;
- }
-
- while (index) {
- head = head->next;
- index--;
- }
-
- return (strdup(head->ident));
-}
-
-/* Get the size of the list
- * head - list head
- * Returns size of list on sucess, negative error code otherwise
- */
-static int snd_ucm_get_size_of_list(struct snd_ucm_ident_node *head)
-{
- int index = 0;
-
- if (head == NULL) {
- ALOGV("Empty list");
- return 0;
- }
-
- while (head->next != NULL) {
- index++;
- head = head->next;
- }
-
- return (index+1);
-}
-
-static void snd_ucm_print_list(struct snd_ucm_ident_node *head)
-{
- int index = 0;
-
- ALOGV("print_list: head %p", head);
- if (head == NULL) {
- ALOGV("Empty list");
- return;
- }
-
- while (head->next != NULL) {
- ALOGV("index: %d, value: %s", index, head->ident);
- index++;
- head = head->next;
- }
- ALOGV("index: %d, value: %s", index, head->ident);
-}
-
-/* Delete an identifier from respective list
- * head - list head
- * value - node value that needs to be deleted
- * Returns 0 on sucess, negative error code otherwise
- *
- */
-static int snd_ucm_del_ident_from_list(struct snd_ucm_ident_node **head,
-const char *value)
-{
- struct snd_ucm_ident_node *temp1, *temp2;
- int ret = -EINVAL;
-
- if (*head == NULL) {
- ALOGE("del_from_list: Empty list");
- return -EINVAL;
- } else if (!strncmp((*head)->ident, value, (strlen(value)+1))) {
- temp2 = *head;
- *head = temp2->next;
- ret = 0;
- } else {
- temp1 = *head;
- temp2 = temp1->next;
- while (temp2 != NULL) {
- if (!strncmp(temp2->ident, value, (strlen(value)+1))) {
- temp1->next = temp2->next;
- ret = 0;
- break;
- }
- temp1 = temp1->next;
- temp2 = temp1->next;
- }
- }
- if (ret < 0) {
- ALOGE("Element not found in enabled list");
- } else {
- temp2->next = NULL;
- temp2->ident[0] = 0;
- temp2->active = 0;
- temp2->capability = 0;
- free(temp2);
- temp2 = NULL;
- }
- return ret;
-}
diff --git a/legacy/libalsa-intf/alsa_ucm.h b/legacy/libalsa-intf/alsa_ucm.h
deleted file mode 100644
index a72ca27..0000000
--- a/legacy/libalsa-intf/alsa_ucm.h
+++ /dev/null
@@ -1,381 +0,0 @@
-/**
- * \file include/use-case.h
- * \brief use case interface for the ALSA driver
- * \author Liam Girdwood <lrg@slimlogic.co.uk>
- * \author Stefan Schmidt <stefan@slimlogic.co.uk>
- * \author Jaroslav Kysela <perex@perex.cz>
- * \author Justin Xu <justinx@slimlogic.co.uk>
- * \date 2008-2010
- */
-/*
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Copyright (C) 2008-2010 SlimLogic Ltd
- * Copyright (C) 2010 Wolfson Microelectronics PLC
- * Copyright (C) 2010 Texas Instruments Inc.
- *
- * Support for the verb/device/modifier core logic and API,
- * command line tool and file parser was kindly sponsored by
- * Texas Instruments Inc.
- * Support for multiple active modifiers and devices,
- * transition sequences, multiple client access and user defined use
- * cases was kindly sponsored by Wolfson Microelectronics PLC.
- */
-
-#ifndef __ALSA_USE_CASE_H
-#define __ALSA_USE_CASE_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * \defgroup Use Case Interface
- * The ALSA Use Case manager interface.
- * See \ref Usecase page for more details.
- * \{
- */
-
-/**
- * ALSA Use Case Interface
- *
- * The use case manager works by configuring the sound card ALSA kcontrols to
- * change the hardware digital and analog audio routing to match the requested
- * device use case. The use case manager kcontrol configurations are stored in
- * easy to modify text files.
- *
- * An audio use case can be defined by a verb and device parameter. The verb
- * describes the use case action i.e. a phone call, listening to music, recording
- * a conversation etc. The device describes the physical audio capture and playback
- * hardware i.e. headphones, phone handset, bluetooth headset, etc.
- *
- * It's intended clients will mostly only need to set the use case verb and
- * device for each system use case change (as the verb and device parameters
- * cover most audio use cases).
- *
- * However there are times when a use case has to be modified at runtime. e.g.
- *
- * o Incoming phone call when the device is playing music
- * o Recording sections of a phone call
- * o Playing tones during a call.
- *
- * In order to allow asynchronous runtime use case adaptations, we have a third
- * optional modifier parameter that can be used to further configure
- * the use case during live audio runtime.
- *
- * This interface allows clients to :-
- *
- * o Query the supported use case verbs, devices and modifiers for the machine.
- * o Set and Get use case verbs, devices and modifiers for the machine.
- * o Get the ALSA PCM playback and capture device PCMs for use case verb,
- * use case device and modifier.
- * o Get the TQ parameter for each use case verb, use case device and
- * modifier.
- * o Get the ALSA master playback and capture volume/switch kcontrols
- * for each use case.
- */
-
-
-/*
- * Use Case Verb.
- *
- * The use case verb is the main device audio action. e.g. the "HiFi" use
- * case verb will configure the audio hardware for HiFi Music playback
- * and capture.
- */
-#define SND_USE_CASE_VERB_INACTIVE "Inactive"
-#define SND_USE_CASE_VERB_HIFI "HiFi"
-#define SND_USE_CASE_VERB_HIFI_LOW_POWER "HiFi Low Power"
-#define SND_USE_CASE_VERB_VOICE "Voice"
-#define SND_USE_CASE_VERB_VOICE_LOW_POWER "Voice Low Power"
-#define SND_USE_CASE_VERB_VOICECALL "Voice Call"
-#define SND_USE_CASE_VERB_IP_VOICECALL "Voice Call IP"
-#define SND_USE_CASE_VERB_ANALOG_RADIO "FM Analog Radio"
-#define SND_USE_CASE_VERB_DIGITAL_RADIO "FM Digital Radio"
-/* add new verbs to end of list */
-
-
-/*
- * Use Case Device.
- *
- * Physical system devices the render and capture audio. Devices can be OR'ed
- * together to support audio on simultaneous devices.
- */
-#define SND_USE_CASE_DEV_NONE "None"
-#define SND_USE_CASE_DEV_SPEAKER "Speaker"
-#define SND_USE_CASE_DEV_LINE "Line"
-#define SND_USE_CASE_DEV_HEADPHONES "Headphones"
-#define SND_USE_CASE_DEV_HEADSET "Headset"
-#define SND_USE_CASE_DEV_HANDSET "Handset"
-#define SND_USE_CASE_DEV_BLUETOOTH "Bluetooth"
-#define SND_USE_CASE_DEV_EARPIECE "Earpiece"
-#define SND_USE_CASE_DEV_SPDIF "SPDIF"
-#define SND_USE_CASE_DEV_HDMI "HDMI"
-/* add new devices to end of list */
-
-
-/*
- * Use Case Modifiers.
- *
- * The use case modifier allows runtime configuration changes to deal with
- * asynchronous events.
- *
- * e.g. to record a voice call :-
- * 1. Set verb to SND_USE_CASE_VERB_VOICECALL (for voice call)
- * 2. Set modifier SND_USE_CASE_MOD_CAPTURE_VOICE when capture required.
- * 3. Call snd_use_case_get("CapturePCM") to get ALSA source PCM name
- * with captured voice pcm data.
- *
- * e.g. to play a ring tone when listenin to MP3 Music :-
- * 1. Set verb to SND_USE_CASE_VERB_HIFI (for MP3 playback)
- * 2. Set modifier to SND_USE_CASE_MOD_PLAY_TONE when incoming call happens.
- * 3. Call snd_use_case_get("PlaybackPCM") to get ALSA PCM sink name for
- * ringtone pcm data.
- */
-#define SND_USE_CASE_MOD_CAPTURE_VOICE "Capture Voice"
-#define SND_USE_CASE_MOD_CAPTURE_MUSIC "Capture Music"
-#define SND_USE_CASE_MOD_PLAY_MUSIC "Play Music"
-#define SND_USE_CASE_MOD_PLAY_VOICE "Play Voice"
-#define SND_USE_CASE_MOD_PLAY_TONE "Play Tone"
-#define SND_USE_CASE_MOD_ECHO_REF "Echo Reference"
-/* add new modifiers to end of list */
-
-
-/**
- * TQ - Tone Quality
- *
- * The interface allows clients to determine the audio TQ required for each
- * use case verb and modifier. It's intended as an optional hint to the
- * audio driver in order to lower power consumption.
- *
- */
-#define SND_USE_CASE_TQ_MUSIC "Music"
-#define SND_USE_CASE_TQ_VOICE "Voice"
-#define SND_USE_CASE_TQ_TONES "Tones"
-
-/** use case container */
-typedef struct snd_use_case_mgr snd_use_case_mgr_t;
-
-/**
- * \brief Create an identifier
- * \param fmt Format (sprintf like)
- * \param ... Optional arguments for sprintf like format
- * \return Allocated string identifier or NULL on error
- */
-char *snd_use_case_identifier(const char *fmt, ...);
-
-/**
- * \brief Free a string list
- * \param list The string list to free
- * \param items Count of strings
- * \return Zero if success, otherwise a negative error code
- */
-int snd_use_case_free_list(const char *list[], int items);
-
-/**
- * \brief Obtain a list of entries
- * \param uc_mgr Use case manager (may be NULL - card list)
- * \param identifier (may be NULL - card list)
- * \param list Returned allocated list
- * \return Number of list entries if success, otherwise a negative error code
- *
- * Defined identifiers:
- * NULL - get card list
- * (in pair cardname+comment)
- * _verbs - get verb list
- * (in pair verb+comment)
- * _devices[/<verb>] - get list of supported devices
- * (in pair device+comment)
- * _modifiers[/<verb>]- get list of supported modifiers
- * (in pair modifier+comment)
- * TQ[/<verb>] - get list of TQ identifiers
- * _enadevs - get list of enabled devices
- * _enamods - get list of enabled modifiers
- *
- * _supporteddevs/<modifier>|<device>[/<verb>] - list of supported devices
- * _conflictingdevs/<modifier>|<device>[/<verb>] - list of conflicting devices
- * Note that at most one of the supported/conflicting devs lists has
- * any entries, and when neither is present, all devices are supported.
- *
- */
-int snd_use_case_get_list(snd_use_case_mgr_t *uc_mgr,
- const char *identifier,
- const char **list[]);
-
-
-/**
- * \brief Get current - string
- * \param uc_mgr Use case manager
- * \param identifier
- * \param value Value pointer
- * \return Zero if success, otherwise a negative error code
- *
- * Note: String is dynamically allocated, use free() to
- * deallocate this string.
- *
- * Known identifiers:
- * NULL - return current card
- * _verb - return current verb
- *
- * [=]<NAME>[/[<modifier>|</device>][/<verb>]]
- * - value identifier <NAME>
- * - Search starts at given modifier or device if any,
- * else at a verb
- * - Search starts at given verb if any,
- * else current verb
- * - Searches modifier/device, then verb, then defaults
- * - Specify a leading "=" to search only the exact
- * device/modifier/verb specified, and not search
- * through each object in turn.
- * - Examples:
- * "PlaybackPCM/Play Music"
- * "CapturePCM/SPDIF"
- * From ValueDefaults only:
- * "=Variable"
- * From current active verb:
- * "=Variable//"
- * From verb "Verb":
- * "=Variable//Verb"
- * From "Modifier" in current active verb:
- * "=Variable/Modifier/"
- * From "Modifier" in "Verb":
- * "=Variable/Modifier/Verb"
- *
- * Recommended names for values:
- * TQ - Tone Quality
- * PlaybackPCM - full PCM playback device name
- * CapturePCM - full PCM capture device name
- * PlaybackCTL - playback control device name
- * PlaybackVolume - playback control volume ID string
- * PlaybackSwitch - playback control switch ID string
- * CaptureCTL - capture control device name
- * CaptureVolume - capture control volume ID string
- * CaptureSwitch - capture control switch ID string
- * PlaybackMixer - name of playback mixer
- * PlaybackMixerID - mixer playback ID
- * CaptureMixer - name of capture mixer
- * CaptureMixerID - mixer capture ID
- */
-int snd_use_case_get(snd_use_case_mgr_t *uc_mgr,
- const char *identifier,
- const char **value);
-
-/**
- * \brief Get current - integer
- * \param uc_mgr Use case manager
- * \param identifier
- * \param value result
- * \return Zero if success, otherwise a negative error code
- *
- * Known identifiers:
- * _devstatus/<device> - return status for given device
- * _modstatus/<modifier> - return status for given modifier
- */
-int snd_use_case_geti(snd_use_case_mgr_t *uc_mgr,
- const char *identifier,
- long *value);
-
-/**
- * \brief Set new
- * \param uc_mgr Use case manager
- * \param identifier
- * \param value Value
- * \return Zero if success, otherwise a negative error code
- *
- * Known identifiers:
- * _verb - set current verb = value
- * _enadev - enable given device = value
- * _disdev - disable given device = value
- * _swdev/<old_device> - new_device = value
- * - disable old_device and then enable new_device
- * - if old_device is not enabled just return
- * - check transmit sequence firstly
- * _enamod - enable given modifier = value
- * _dismod - disable given modifier = value
- * _swmod/<old_modifier> - new_modifier = value
- * - disable old_modifier and then enable new_modifier
- * - if old_modifier is not enabled just return
- * - check transmit sequence firstly
- */
-int snd_use_case_set(snd_use_case_mgr_t *uc_mgr,
- const char *identifier,
- const char *value);
-
-/**
- * \brief Open and initialise use case core for sound card
- * \param uc_mgr Returned use case manager pointer
- * \param card_name Sound card name.
- * \return zero if success, otherwise a negative error code
- */
-int snd_use_case_mgr_open(snd_use_case_mgr_t **uc_mgr, const char *card_name);
-
-
-/**
- * \brief Reload and re-parse use case configuration files for sound card.
- * \param uc_mgr Use case manager
- * \return zero if success, otherwise a negative error code
- */
-int snd_use_case_mgr_reload(snd_use_case_mgr_t *uc_mgr);
-
-/**
- * \brief Close use case manager
- * \param uc_mgr Use case manager
- * \return zero if success, otherwise a negative error code
- */
-int snd_use_case_mgr_close(snd_use_case_mgr_t *uc_mgr);
-
-/**
- * \brief Reset use case manager verb, device, modifier to deafult settings.
- * \param uc_mgr Use case manager
- * \return zero if success, otherwise a negative error code
- */
-int snd_use_case_mgr_reset(snd_use_case_mgr_t *uc_mgr);
-
-/*
- * helper functions
- */
-
-/**
- * \brief Obtain a list of cards
- * \param list Returned allocated list
- * \return Number of list entries if success, otherwise a negative error code
- */
-static inline int snd_use_case_card_list(const char **list[])
-{
- return snd_use_case_get_list(NULL, NULL, list);
-}
-
-/**
- * \brief Obtain a list of verbs
- * \param uc_mgr Use case manager
- * \param list Returned list of verbs
- * \return Number of list entries if success, otherwise a negative error code
- */
-static inline int snd_use_case_verb_list(snd_use_case_mgr_t *uc_mgr,
- const char **list[])
-{
- return snd_use_case_get_list(uc_mgr, "_verbs", list);
-}
-
-/**
- * \}
- */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __ALSA_USE_CASE_H */
diff --git a/legacy/libalsa-intf/alsaucm_test.c b/legacy/libalsa-intf/alsaucm_test.c
deleted file mode 100644
index aaed38e..0000000
--- a/legacy/libalsa-intf/alsaucm_test.c
+++ /dev/null
@@ -1,324 +0,0 @@
-/*
- * Copyright (c) 2012, The Linux Foundation. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- * * Neither the name of The Linux Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/ioctl.h>
-#include <sys/stat.h>
-#include <linux/ioctl.h>
-#include <fcntl.h>
-#include <string.h>
-#include <stdio.h>
-#include <errno.h>
-#include <stdlib.h>
-
-#include "alsa_ucm.h"
-#include "msm8960_use_cases.h"
-
-/* Function prototypes */
-static void print_help_menu(void);
-static void alsaucm_test_cmd_svr(void);
-static int process_cmd(char *cmdStr);
-
-/* Global data */
-snd_use_case_mgr_t *uc_mgr;
-
-/* Defines */
-enum ucm_cmd_id {
- UCM_OPEN = 0,
- UCM_SET,
- UCM_LISTCARDS,
- UCM_LIST,
- UCM_GET,
- UCM_GETI,
- UCM_RESET,
- UCM_RELOAD,
- UCM_HELP,
- UCM_QUIT,
- UCM_UNKNOWN
-};
-
-struct cmd {
- enum ucm_cmd_id code;
- const char *cmd_str;
-};
-
-static struct cmd cmds[] = {
- { UCM_OPEN, "open" },
- { UCM_SET, "set" },
- { UCM_LISTCARDS, "listcards" },
- { UCM_LIST, "list" },
- { UCM_GET, "get" },
- { UCM_GETI, "geti" },
- { UCM_RESET, "reset" },
- { UCM_RELOAD, "reload" },
- { UCM_HELP, "help" },
- { UCM_QUIT, "quit" },
- { UCM_UNKNOWN, NULL }
-};
-
-static void alsaucm_test_cmd_svr(void)
-{
- int fd;
- ssize_t read_count;
- char cmdstr[256] = {'\0'};
- char ch;
- char *exit_str = "quit";
-
- if (mknod("/data/alsaucm_test", S_IFIFO | 0666, 0) == 0) {
- fd = open("/data/alsaucm_test", O_RDONLY);
- while (1) {
- read_count = read(fd, &ch, 1);
- if (read_count == 0) {
- sleep(2);
- continue;
- } else if (read_count < 0) {
- fprintf(stderr, "alsaucm_test: error reading cmd\n");
- break;
- }
-
- if (ch != '\n') {
- strlcat(cmdstr, &ch , (2+strlen(cmdstr)));
- continue;
- } else {
- if (!strncmp(cmdstr, exit_str, strlen(cmdstr))) {
- /* free UCM instace */
- if (uc_mgr) {
- snd_use_case_mgr_close(uc_mgr);
- uc_mgr = NULL;
- }
- break;
- } else {
- process_cmd(cmdstr);
- memset(cmdstr, 0, sizeof(cmdstr));
- }
- }
- }
- printf("alsaucm_test: exit server mode\n");
- close(fd);
- remove("/data/alsaucm_test");
- } else {
- fprintf(stderr, "alsaucm_test: Failed to create server\n");
- }
-}
-
-
-static void print_help_menu(void)
-{
- printf("\nAvailable commands:\n"
- " open NAME open card NAME\n"
- " reset reset sound card to default state\n"
- " reload reload configuration\n"
- " listcards list available cards\n"
- " list IDENTIFIER list command\n"
- " get IDENTIFIER get string value\n"
- " geti IDENTIFIER get integer value\n"
- " set IDENTIFIER VALUE set string value\n"
- " help help\n"
- " quit quit\n");
-}
-
-int main(int argc, char **argv)
-{
- char *help_str = "help";
- argc--;
- argv++;
-
- if (argc > 0) {
- if (!strncmp(argv[0], help_str, strlen(argv[0])))
- print_help_menu();
- } else
- alsaucm_test_cmd_svr();
- return 0;
-}
-
-static int process_cmd(char *cmdStr)
-{
- const char **list = NULL , *str = NULL;
- long lval;
- int err, i;
- char *command = NULL;
- int count = 0;
- char *identifier = NULL, *value = NULL;
- struct cmd *cmd = NULL;
-
- command = strtok_r(cmdStr, " ", &value);
- identifier = strtok_r(NULL, " ", &value);
-
- if (command == NULL) {
- fprintf(stderr, "NULL pointer encountered. Invalid value for command");
- return -1;
- }
-
- for (cmd = cmds; cmd->cmd_str != NULL; cmd++) {
- if (strncmp(cmd->cmd_str, command, strlen(cmd->cmd_str)) == 0)
- break;
- }
-
- if (cmd->cmd_str == NULL) {
- fprintf(stderr, "Unknown command '%s'\n", command);
- return -EINVAL;
- }
-
- if ((identifier == NULL) && ((cmd->code != UCM_HELP) &&
- (cmd->code != UCM_LISTCARDS) && (cmd->code != UCM_RESET) &&
- (cmd->code != UCM_RELOAD)))
- {
- fprintf(stderr, "NULL pointer encountered. Invalid value for identifier");
- return -1;
- }
-
- switch (cmd->code) {
- case UCM_HELP:
- print_help_menu();
- break;
-
- case UCM_OPEN:
- if (uc_mgr) {
- snd_use_case_mgr_close(uc_mgr);
- uc_mgr = NULL;
- }
-
- err = snd_use_case_mgr_open(&uc_mgr, identifier);
- if (err < 0) {
- fprintf(stderr, "%s: error failed to open sound card %s: %d\n", cmd->cmd_str, identifier, err);
- return err;
- }
- snd_use_case_mgr_wait_for_parsing(uc_mgr);
- break;
-
- case UCM_LISTCARDS:
- err = snd_use_case_card_list(&list);
- if (err < 0) {
- fprintf(stderr, "%s: error failed to get card list: %d\n", cmd->cmd_str, err);
- return err;
- }
- if (err == 0) {
- printf("list is empty\n");
- return 0;
- }
-
- for (i = 0; i < err; i++)
- printf(" %i: %s\n", i+1, list[i]);
- snd_use_case_free_list(list, err);
- break;
-
- case UCM_RESET:
- if (!uc_mgr) {
- fprintf(stderr, "No card is opened before. %s command can't be executed\n", cmd->cmd_str);
- return -EINVAL;
- }
-
- err = snd_use_case_mgr_reset(uc_mgr);
- if (err < 0) {
- fprintf(stderr, "%s: error failed to reset sound card %d\n", cmd->cmd_str, err);
- return err;
- }
- break;
-
- case UCM_RELOAD:
- if (!uc_mgr) {
- fprintf(stderr, "No card is opened before. %s command can't be executed\n", cmd->cmd_str);
- return -EINVAL;
- }
-
- err = snd_use_case_mgr_reload(uc_mgr);
- if (err < 0) {
- fprintf(stderr, "%s: error failed to reload manager %d\n", cmd->cmd_str, err);
- return err;
- }
- break;
-
- case UCM_LIST:
- if (!uc_mgr) {
- fprintf(stderr, "No card is opened before. %s command can't be executed\n", cmd->cmd_str);
- return -EINVAL;
- }
-
- err = snd_use_case_get_list(uc_mgr, identifier, &list);
- if (err < 0) {
- fprintf(stderr, "%s: error failed to get list %s: %d\n", cmd->cmd_str, identifier, err);
- return err;
- }
- if (err == 0) {
- printf("list is empty\n");
- return 0;
- }
- for (i = 0; i < err; i++) {
- printf(" %i: %s\n", i+1, list[i]);
- }
- snd_use_case_free_list(list, err);
- break;
-
- case UCM_SET:
- if (!uc_mgr) {
- fprintf(stderr, "No card is opened before. %s command can't be executed\n", cmd->cmd_str);
- return -EINVAL;
- }
-
- err = snd_use_case_set(uc_mgr, identifier, value);
- if (err < 0) {
- fprintf(stderr, "%s: error failed to set %s=%s: %d\n", cmd->cmd_str, identifier, value, err);
- return err;
- }
- break;
-
- case UCM_GET:
- if (!uc_mgr) {
- fprintf(stderr, "No card is opened before. %s command can't be executed\n", cmd->cmd_str);
- return -EINVAL;
- }
-
- err = snd_use_case_get(uc_mgr, identifier, &str);
- if (err < 0) {
- fprintf(stderr, "%s: error failed to get %s: %d\n", cmd->cmd_str, identifier, err);
- return err;
- }
- printf(" %s=%s\n", identifier, str);
- free((void *)str);
- break;
-
- case UCM_GETI:
- if (!uc_mgr) {
- fprintf(stderr, "No card is opened before. %s command can't be executed\n", cmd->cmd_str);
- return -EINVAL;
- }
-
- err = snd_use_case_geti(uc_mgr, identifier, &lval);
- if (err < 0) {
- fprintf(stderr, "%s: error failed to get integer %s: %d\n", cmd->cmd_str, identifier, err);
- return lval;
- }
- printf(" %s=%li\n", identifier, lval);
- break;
-
- default:
- break;
- }
- return 0;
-}
-
diff --git a/legacy/libalsa-intf/amix.c b/legacy/libalsa-intf/amix.c
deleted file mode 100644
index b425ed5..0000000
--- a/legacy/libalsa-intf/amix.c
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
-** Copyright 2010, The Android Open-Source Project
-** Copyright (c) 2011, The Linux Foundation. All rights reserved.
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <ctype.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <stdint.h>
-#include <string.h>
-
-#include "alsa_audio.h"
-
-
-struct mixer_ctl *get_ctl(struct mixer *mixer, char *name)
-{
- char *p;
- unsigned idx = 0;
-
- if (isdigit(name[0]))
- return mixer_get_nth_control(mixer, atoi(name) - 1);
-
- p = strrchr(name, '#');
- if (p) {
- *p++ = 0;
- idx = atoi(p);
- }
-
- return mixer_get_control(mixer, name, idx);
-}
-
-int main(int argc, char **argv)
-{
- struct mixer *mixer;
- struct mixer_ctl *ctl;
- unsigned value;
- int r;
- const char* device = "/dev/snd/controlC0";
-
- mixer = mixer_open(device);
- if (!mixer){
- fprintf(stderr,"oops: %s: %d\n", strerror(errno), __LINE__);
- return -1;
- }
-
- if (argc == 1) {
- mixer_dump(mixer);
- mixer_close(mixer);
- return 0;
- }
-
- ctl = get_ctl(mixer, argv[1]);
- argc -= 2;
- argv += 2;
-
- if (!ctl) {
- fprintf(stderr,"can't find control\n");
- mixer_close(mixer);
- return -1;
- }
- if (argc) {
- if (isdigit(argv[0][0]))
- r = mixer_ctl_set_value(ctl, argc, argv);
- else
- r = mixer_ctl_select(ctl, argv[0]);
- if (r)
- fprintf(stderr,"oops: %s: %d\n", strerror(errno), __LINE__);
- } else {
- mixer_ctl_get(ctl, &value);
- }
- mixer_close(mixer);
- return 0;
-}
diff --git a/legacy/libalsa-intf/aplay.c b/legacy/libalsa-intf/aplay.c
deleted file mode 100644
index 120febd..0000000
--- a/legacy/libalsa-intf/aplay.c
+++ /dev/null
@@ -1,669 +0,0 @@
-/*
-** Copyright 2010, The Android Open-Source Project
-** Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <stdint.h>
-#include <string.h>
-#include <errno.h>
-#include <sys/poll.h>
-#include <sys/ioctl.h>
-#include <getopt.h>
-
-#include <sound/asound.h>
-#include "alsa_audio.h"
-
-#ifndef ANDROID
-#define strlcat g_strlcat
-#define strlcpy g_strlcpy
-#endif
-
-#define ID_RIFF 0x46464952
-#define ID_WAVE 0x45564157
-#define ID_FMT 0x20746d66
-#define ID_DATA 0x61746164
-
-#define FORMAT_PCM 1
-#define LOG_NDEBUG 1
-static pcm_flag = 1;
-static debug = 0;
-static uint32_t play_max_sz = 2147483648LL;
-static int format = SNDRV_PCM_FORMAT_S16_LE;
-static int period = 0;
-static int compressed = 0;
-static char *compr_codec;
-static int piped = 0;
-
-static struct option long_options[] =
-{
- {"pcm", 0, 0, 'P'},
- {"debug", 0, 0, 'V'},
- {"Mmap", 0, 0, 'M'},
- {"HW", 1, 0, 'D'},
- {"Rate", 1, 0, 'R'},
- {"channel", 1, 0, 'C'},
- {"format", 1, 0, 'F'},
- {"period", 1, 0, 'B'},
- {"compressed", 0, 0, 'T'},
- {0, 0, 0, 0}
-};
-
-struct wav_header {
- uint32_t riff_id;
- uint32_t riff_sz;
- uint32_t riff_fmt;
- uint32_t fmt_id;
- uint32_t fmt_sz;
- uint16_t audio_format;
- uint16_t num_channels;
- uint32_t sample_rate;
- uint32_t byte_rate; /* sample_rate * num_channels * bps / 8 */
- uint16_t block_align; /* num_channels * bps / 8 */
- uint16_t bits_per_sample;
- uint32_t data_id;
- uint32_t data_sz;
-};
-
-static int set_params(struct pcm *pcm)
-{
- struct snd_pcm_hw_params *params;
- struct snd_pcm_sw_params *sparams;
-
- unsigned long periodSize, bufferSize, reqBuffSize;
- unsigned int periodTime, bufferTime;
- unsigned int requestedRate = pcm->rate;
- int channels = (pcm->flags & PCM_MONO) ? 1 : ((pcm->flags & PCM_5POINT1)? 6 : 2 );
-
- params = (struct snd_pcm_hw_params*) calloc(1, sizeof(struct snd_pcm_hw_params));
- if (!params) {
- fprintf(stderr, "Aplay:Failed to allocate ALSA hardware parameters!");
- return -ENOMEM;
- }
-
- param_init(params);
-
- param_set_mask(params, SNDRV_PCM_HW_PARAM_ACCESS,
- (pcm->flags & PCM_MMAP)? SNDRV_PCM_ACCESS_MMAP_INTERLEAVED : SNDRV_PCM_ACCESS_RW_INTERLEAVED);
- param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, pcm->format);
- param_set_mask(params, SNDRV_PCM_HW_PARAM_SUBFORMAT,
- SNDRV_PCM_SUBFORMAT_STD);
- if (period)
- param_set_min(params, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, period);
- else
- param_set_min(params, SNDRV_PCM_HW_PARAM_PERIOD_TIME, 10);
- param_set_int(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS, 16);
- param_set_int(params, SNDRV_PCM_HW_PARAM_FRAME_BITS,
- pcm->channels * 16);
- param_set_int(params, SNDRV_PCM_HW_PARAM_CHANNELS,
- pcm->channels);
- param_set_int(params, SNDRV_PCM_HW_PARAM_RATE, pcm->rate);
- param_set_hw_refine(pcm, params);
-
- if (param_set_hw_params(pcm, params)) {
- fprintf(stderr, "Aplay:cannot set hw params\n");
- return -errno;
- }
- if (debug)
- param_dump(params);
-
- pcm->buffer_size = pcm_buffer_size(params);
- pcm->period_size = pcm_period_size(params);
- pcm->period_cnt = pcm->buffer_size/pcm->period_size;
- if (debug) {
- fprintf (stderr,"period_cnt = %d\n", pcm->period_cnt);
- fprintf (stderr,"period_size = %d\n", pcm->period_size);
- fprintf (stderr,"buffer_size = %d\n", pcm->buffer_size);
- }
- sparams = (struct snd_pcm_sw_params*) calloc(1, sizeof(struct snd_pcm_sw_params));
- if (!sparams) {
- fprintf(stderr, "Aplay:Failed to allocate ALSA software parameters!\n");
- return -ENOMEM;
- }
- // Get the current software parameters
- sparams->tstamp_mode = SNDRV_PCM_TSTAMP_NONE;
- sparams->period_step = 1;
-
- sparams->avail_min = pcm->period_size/(channels * 2) ;
- sparams->start_threshold = pcm->period_size/(channels * 2) ;
- sparams->stop_threshold = pcm->buffer_size ;
- sparams->xfer_align = pcm->period_size/(channels * 2) ; /* needed for old kernels */
-
- sparams->silence_size = 0;
- sparams->silence_threshold = 0;
-
- if (param_set_sw_params(pcm, sparams)) {
- fprintf(stderr, "Aplay:cannot set sw params");
- return -errno;
- }
- if (debug) {
- fprintf (stderr,"sparams->avail_min= %lu\n", sparams->avail_min);
- fprintf (stderr," sparams->start_threshold= %lu\n", sparams->start_threshold);
- fprintf (stderr," sparams->stop_threshold= %lu\n", sparams->stop_threshold);
- fprintf (stderr," sparams->xfer_align= %lu\n", sparams->xfer_align);
- fprintf (stderr," sparams->boundary= %lu\n", sparams->boundary);
- }
- return 0;
-}
-
-static int play_file(unsigned rate, unsigned channels, int fd,
- unsigned flags, const char *device, unsigned data_sz)
-{
- struct pcm *pcm;
- struct mixer *mixer;
- struct pcm_ctl *ctl = NULL;
- unsigned bufsize;
- char *data;
- long avail;
- long frames;
- int nfds = 1;
- struct snd_xferi x;
- unsigned offset = 0;
- int err;
- static int start = 0;
- struct pollfd pfd[1];
- int remainingData = 0;
-
- flags |= PCM_OUT;
-
- if (channels == 1)
- flags |= PCM_MONO;
- else if (channels == 6)
- flags |= PCM_5POINT1;
- else
- flags |= PCM_STEREO;
-
- if (debug)
- flags |= DEBUG_ON;
- else
- flags |= DEBUG_OFF;
-
- pcm = pcm_open(flags, device);
- if (pcm < 0)
- return pcm;
-
- if (!pcm_ready(pcm)) {
- pcm_close(pcm);
- return -EBADFD;
- }
-
-#ifdef QCOM_COMPRESSED_AUDIO_ENABLED
- if (compressed) {
- struct snd_compr_caps compr_cap;
- struct snd_compr_params compr_params;
- if (ioctl(pcm->fd, SNDRV_COMPRESS_GET_CAPS, &compr_cap)) {
- fprintf(stderr, "Aplay: SNDRV_COMPRESS_GET_CAPS, failed Error no %d \n", errno);
- pcm_close(pcm);
- return -errno;
- }
- if (!period)
- period = compr_cap.min_fragment_size;
- switch (get_compressed_format(compr_codec)) {
- case FORMAT_MP3:
- compr_params.codec.id = compr_cap.codecs[FORMAT_MP3];
- break;
- case FORMAT_AC3_PASS_THROUGH:
- compr_params.codec.id = compr_cap.codecs[FORMAT_AC3_PASS_THROUGH];
- printf("codec -d = %x\n", compr_params.codec.id);
- break;
- default:
- break;
- }
- if (ioctl(pcm->fd, SNDRV_COMPRESS_SET_PARAMS, &compr_params)) {
- fprintf(stderr, "Aplay: SNDRV_COMPRESS_SET_PARAMS,failed Error no %d \n", errno);
- pcm_close(pcm);
- return -errno;
- }
- }
-#endif
- pcm->channels = channels;
- pcm->rate = rate;
- pcm->flags = flags;
- pcm->format = format;
- if (set_params(pcm)) {
- fprintf(stderr, "Aplay:params setting failed\n");
- pcm_close(pcm);
- return -errno;
- }
-
- if (!pcm_flag) {
- if (pcm_prepare(pcm)) {
- fprintf(stderr, "Aplay:Failed in pcm_prepare\n");
- pcm_close(pcm);
- return -errno;
- }
- if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_START)) {
- fprintf(stderr, "Aplay: Hostless IOCTL_START Error no %d \n", errno);
- pcm_close(pcm);
- return -errno;
- }
- while(1);
- }
-
- remainingData = data_sz;
-
- if (flags & PCM_MMAP) {
- u_int8_t *dst_addr = NULL;
- struct snd_pcm_sync_ptr *sync_ptr1 = pcm->sync_ptr;
- if (mmap_buffer(pcm)) {
- fprintf(stderr, "Aplay:params setting failed\n");
- pcm_close(pcm);
- return -errno;
- }
- if (pcm_prepare(pcm)) {
- fprintf(stderr, "Aplay:Failed in pcm_prepare\n");
- pcm_close(pcm);
- return -errno;
- }
-
- bufsize = pcm->period_size;
- if (debug)
- fprintf(stderr, "Aplay:bufsize = %d\n", bufsize);
-
- pfd[0].fd = pcm->timer_fd;
- pfd[0].events = POLLIN;
-
- frames = (pcm->flags & PCM_MONO) ? (bufsize / 2) : (bufsize / 4);
- for (;;) {
- if (!pcm->running) {
- if (pcm_prepare(pcm)) {
- fprintf(stderr, "Aplay:Failed in pcm_prepare\n");
- pcm_close(pcm);
- return -errno;
- }
- pcm->running = 1;
- start = 0;
- }
- /* Sync the current Application pointer from the kernel */
- pcm->sync_ptr->flags = SNDRV_PCM_SYNC_PTR_APPL | SNDRV_PCM_SYNC_PTR_AVAIL_MIN;//SNDRV_PCM_SYNC_PTR_HWSYNC;
- err = sync_ptr(pcm);
- if (err == EPIPE) {
- fprintf(stderr, "Aplay:Failed in sync_ptr \n");
- /* we failed to make our window -- try to restart */
- pcm->underruns++;
- pcm->running = 0;
- continue;
- }
- /*
- * Check for the available buffer in driver. If available buffer is
- * less than avail_min we need to wait
- */
- avail = pcm_avail(pcm);
- if (avail < 0) {
- fprintf(stderr, "Aplay:Failed in pcm_avail\n");
- pcm_close(pcm);
- return avail;
- }
- if (avail < pcm->sw_p->avail_min) {
- poll(pfd, nfds, TIMEOUT_INFINITE);
- continue;
- }
- /*
- * Now that we have buffer size greater than avail_min available to
- * to be written we need to calcutate the buffer offset where we can
- * start writting.
- */
- dst_addr = dst_address(pcm);
-
- if (debug) {
- fprintf(stderr, "dst_addr = 0x%08x\n", dst_addr);
- fprintf(stderr, "Aplay:avail = %d frames = %d\n",avail, frames);
- fprintf(stderr, "Aplay:sync_ptr->s.status.hw_ptr %ld pcm->buffer_size %d sync_ptr->c.control.appl_ptr %ld\n",
- pcm->sync_ptr->s.status.hw_ptr,
- pcm->buffer_size,
- pcm->sync_ptr->c.control.appl_ptr);
- }
-
- /*
- * Read from the file to the destination buffer in kernel mmaped buffer
- * This reduces a extra copy of intermediate buffer.
- */
- memset(dst_addr, 0x0, bufsize);
-
- if (data_sz && !piped) {
- if (remainingData < bufsize) {
- bufsize = remainingData;
- frames = (pcm->flags & PCM_MONO) ? (remainingData / 2) : (remainingData / 4);
- }
- }
-
- err = read(fd, dst_addr , bufsize);
- if (debug)
- fprintf(stderr, "read %d bytes from file\n", err);
- if (err <= 0)
- break;
-
- if (data_sz && !piped) {
- remainingData -= bufsize;
- if (remainingData <= 0)
- break;
- }
-
- /*
- * Increment the application pointer with data written to kernel.
- * Update kernel with the new sync pointer.
- */
- pcm->sync_ptr->c.control.appl_ptr += frames;
- pcm->sync_ptr->flags = 0;
-
- err = sync_ptr(pcm);
- if (err == EPIPE) {
- fprintf(stderr, "Aplay:Failed in sync_ptr 2 \n");
- /* we failed to make our window -- try to restart */
- pcm->underruns++;
- pcm->running = 0;
- continue;
- }
-
- if (debug) {
- fprintf(stderr, "Aplay:sync_ptr->s.status.hw_ptr %ld sync_ptr->c.control.appl_ptr %ld\n",
- pcm->sync_ptr->s.status.hw_ptr,
- pcm->sync_ptr->c.control.appl_ptr);
-#ifdef QCOM_COMPRESSED_AUDIO_ENABLED
- if (compressed && start) {
- struct snd_compr_tstamp tstamp;
- if (ioctl(pcm->fd, SNDRV_COMPRESS_TSTAMP, &tstamp))
- fprintf(stderr, "Aplay: failed SNDRV_COMPRESS_TSTAMP\n");
- else
- fprintf(stderr, "timestamp = %lld\n", tstamp.timestamp);
- }
-#endif
- }
- /*
- * If we have reached start threshold of buffer prefill,
- * its time to start the driver.
- */
- if(start)
- goto start_done;
- if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_START)) {
- err = -errno;
- if (errno == EPIPE) {
- fprintf(stderr, "Aplay:Failed in SNDRV_PCM_IOCTL_START\n");
- /* we failed to make our window -- try to restart */
- pcm->underruns++;
- pcm->running = 0;
- continue;
- } else {
- fprintf(stderr, "Aplay:Error no %d \n", errno);
- pcm_close(pcm);
- return -errno;
- }
- } else
- start = 1;
-
-start_done:
- offset += frames;
- }
- while(1) {
- pcm->sync_ptr->flags = SNDRV_PCM_SYNC_PTR_APPL | SNDRV_PCM_SYNC_PTR_AVAIL_MIN;//SNDRV_PCM_SYNC_PTR_HWSYNC;
- sync_ptr(pcm);
- /*
- * Check for the available buffer in driver. If available buffer is
- * less than avail_min we need to wait
- */
- if (pcm->sync_ptr->s.status.hw_ptr >= pcm->sync_ptr->c.control.appl_ptr) {
- fprintf(stderr, "Aplay:sync_ptr->s.status.hw_ptr %ld sync_ptr->c.control.appl_ptr %ld\n",
- pcm->sync_ptr->s.status.hw_ptr,
- pcm->sync_ptr->c.control.appl_ptr);
- break;
- } else
- poll(pfd, nfds, TIMEOUT_INFINITE);
- }
- } else {
- if (pcm_prepare(pcm)) {
- fprintf(stderr, "Aplay:Failed in pcm_prepare\n");
- pcm_close(pcm);
- return -errno;
- }
-
- bufsize = pcm->period_size;
-
- data = calloc(1, bufsize);
- if (!data) {
- fprintf(stderr, "Aplay:could not allocate %d bytes\n", bufsize);
- pcm_close(pcm);
- return -ENOMEM;
- }
-
- if (data_sz && !piped) {
- if (remainingData < bufsize)
- bufsize = remainingData;
- }
-
- while (read(fd, data, bufsize) > 0) {
- if (pcm_write(pcm, data, bufsize)){
- fprintf(stderr, "Aplay: pcm_write failed\n");
- free(data);
- pcm_close(pcm);
- return -errno;
- }
- memset(data, 0, bufsize);
-
- if (data_sz && !piped) {
- remainingData -= bufsize;
- if (remainingData <= 0)
- break;
- if (remainingData < bufsize)
- bufsize = remainingData;
- }
- }
- free(data);
- }
- fprintf(stderr, "Aplay: Done playing\n");
- pcm_close(pcm);
- return 0;
-}
-
-int play_raw(const char *fg, int rate, int ch, const char *device, const char *fn)
-{
- int fd;
- unsigned flag = 0;
-
- if(!fn) {
- fd = fileno(stdin);
- piped = 1;
- } else {
- fd = open(fn, O_RDONLY);
- if (fd < 0) {
- fprintf(stderr, "Aplay:aplay: cannot open '%s'\n", fn);
- return fd;
- }
- }
-
- if (!strncmp(fg, "M", sizeof("M")))
- flag = PCM_MMAP;
- else if (!strncmp(fg, "N", sizeof("N")))
- flag = PCM_NMMAP;
-
- fprintf(stderr, "aplay: Playing '%s': format %s ch = %d\n",
- fn, get_format_desc(format), ch );
- return play_file(rate, ch, fd, flag, device, 0);
-}
-
-int play_wav(const char *fg, int rate, int ch, const char *device, const char *fn)
-{
- struct wav_header hdr;
- int fd;
- unsigned flag = 0;
-
- if (pcm_flag) {
- if(!fn) {
- fd = fileno(stdin);
- piped = 1;
- } else {
- fd = open(fn, O_RDONLY);
- if (fd < 0) {
- fprintf(stderr, "Aplay:aplay: cannot open '%s'\n", fn);
- return fd;
- }
- }
- if (compressed) {
- hdr.sample_rate = rate;
- hdr.num_channels = ch;
- hdr.data_sz = 0;
- goto ignore_header;
- }
-
- if (read(fd, &hdr, sizeof(hdr)) != sizeof(hdr)) {
- fprintf(stderr, "Aplay:aplay: cannot read header\n");
- return -errno;
- }
-
- if ((hdr.riff_id != ID_RIFF) ||
- (hdr.riff_fmt != ID_WAVE) ||
- (hdr.fmt_id != ID_FMT)) {
- fprintf(stderr, "Aplay:aplay: '%s' is not a riff/wave file\n", fn);
- return -EINVAL;
- }
- if ((hdr.audio_format != FORMAT_PCM) ||
- (hdr.fmt_sz != 16)) {
- fprintf(stderr, "Aplay:aplay: '%s' is not pcm format\n", fn);
- return -EINVAL;
- }
- if (hdr.bits_per_sample != 16) {
- fprintf(stderr, "Aplay:aplay: '%s' is not 16bit per sample\n", fn);
- return -EINVAL;
- }
- } else {
- fd = -EBADFD;
- hdr.sample_rate = rate;
- hdr.num_channels = ch;
- hdr.data_sz = 0;
- }
-
-ignore_header:
- if (!strncmp(fg, "M", sizeof("M")))
- flag = PCM_MMAP;
- else if (!strncmp(fg, "N", sizeof("N")))
- flag = PCM_NMMAP;
- fprintf(stderr, "aplay: Playing '%s':%s\n", fn, get_format_desc(format) );
-
- return play_file(hdr.sample_rate, hdr.num_channels, fd, flag, device, hdr.data_sz);
-}
-
-int main(int argc, char **argv)
-{
- int option_index = 0;
- int c,i;
- int ch = 2;
- int rate = 44100;
- char *mmap = "N";
- char *device = "hw:0,0";
- char *filename;
- int rc = 0;
-
- if (argc <2) {
- printf("\nUsage: aplay [options] <file>\n"
- "options:\n"
- "-D <hw:C,D> -- Alsa PCM by name\n"
- "-M -- Mmap stream\n"
- "-P -- Hostless steam[No PCM]\n"
- "-C -- Channels\n"
- "-R -- Rate\n"
- "-V -- verbose\n"
- "-F -- Format\n"
- "-B -- Period\n"
- "-T <MP3, AAC, AC3_PASS_THROUGH> -- Compressed\n"
- "<file> \n");
- fprintf(stderr, "Formats Supported:\n");
- for (i = 0; i <= SNDRV_PCM_FORMAT_LAST; ++i)
- if (get_format_name(i))
- fprintf(stderr, "%s ", get_format_name(i));
- fprintf(stderr, "\nSome of these may not be available on selected hardware\n");
- return 0;
- }
- while ((c = getopt_long(argc, argv, "PVMD:R:C:F:B:T:", long_options, &option_index)) != -1) {
- switch (c) {
- case 'P':
- pcm_flag = 0;
- break;
- case 'V':
- debug = 1;
- break;
- case 'M':
- mmap = "M";
- break;
- case 'D':
- device = optarg;
- break;
- case 'R':
- rate = (int)strtol(optarg, NULL, 0);
- break;
- case 'C':
- ch = (int)strtol(optarg, NULL, 0);
- break;
- case 'F':
- printf("optarg = %s\n", optarg);
- format = get_format(optarg);
- break;
- case 'B':
- period = (int)strtol(optarg, NULL, 0);
- break;
- case 'T':
- compressed = 1;
- printf("compressed codec type requested = %s\n", optarg);
- compr_codec = optarg;
- break;
- default:
- printf("\nUsage: aplay [options] <file>\n"
- "options:\n"
- "-D <hw:C,D> -- Alsa PCM by name\n"
- "-M -- Mmap stream\n"
- "-P -- Hostless steam[No PCM]\n"
- "-V -- verbose\n"
- "-C -- Channels\n"
- "-R -- Rate\n"
- "-F -- Format\n"
- "-B -- Period\n"
- "-T -- Compressed\n"
- "<file> \n");
- fprintf(stderr, "Formats Supported:\n");
- for (i = 0; i < SNDRV_PCM_FORMAT_LAST; ++i)
- if (get_format_name(i))
- fprintf(stderr, "%s ", get_format_name(i));
- fprintf(stderr, "\nSome of these may not be available on selected hardware\n");
- return -EINVAL;
- }
-
- }
- filename = (char*) calloc(1, 30);
- if (!filename) {
- fprintf(stderr, "Aplay:Failed to allocate filename!");
- return -ENOMEM;
- }
- if (optind > argc - 1) {
- free(filename);
- filename = NULL;
- } else {
- strlcpy(filename, argv[optind++], 30);
- }
-
- if (pcm_flag) {
- if (format == SNDRV_PCM_FORMAT_S16_LE)
- rc = play_wav(mmap, rate, ch, device, filename);
- else
- rc = play_raw(mmap, rate, ch, device, filename);
- } else {
- rc = play_wav(mmap, rate, ch, device, "dummy");
- }
- if (filename)
- free(filename);
-
- return rc;
-}
-
diff --git a/legacy/libalsa-intf/arec.c b/legacy/libalsa-intf/arec.c
deleted file mode 100644
index 30e710c..0000000
--- a/legacy/libalsa-intf/arec.c
+++ /dev/null
@@ -1,620 +0,0 @@
-/*
-** Copyright 2010, The Android Open-Source Project
-** Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <stdint.h>
-#include <string.h>
-#include <signal.h>
-#include <errno.h>
-#include <sys/poll.h>
-#include <sys/ioctl.h>
-#include <getopt.h>
-#include <limits.h>
-
-#include "alsa_audio.h"
-
-#define ID_RIFF 0x46464952
-#define ID_WAVE 0x45564157
-#define ID_FMT 0x20746d66
-#define ID_DATA 0x61746164
-
-#define FORMAT_PCM 1
-
-#ifndef ANDROID
-#define strlcat g_strlcat
-#define strlcpy g_strlcpy
-#endif
-
-static struct wav_header hdr;
-static int fd;
-static struct pcm *pcm;
-static int debug = 0;
-static int pcm_flag = 1;
-static int duration = 0;
-static char *filename;
-static char *data;
-static int format = SNDRV_PCM_FORMAT_S16_LE;
-static int period = 0;
-static int piped = 0;
-
-static struct option long_options[] =
-{
- {"pcm", 0, 0, 'P'},
- {"debug", 0, 0, 'V'},
- {"Mmap", 0, 0, 'M'},
- {"HW", 1, 0, 'D'},
- {"Rate", 1, 0, 'R'},
- {"channel", 1, 0, 'C'},
- {"duration", 1, 0, 'T'},
- {"format", 1, 0, 'F'},
- {"period", 1, 0, 'B'},
- {0, 0, 0, 0}
-};
-
-struct wav_header {
- uint32_t riff_id;
- uint32_t riff_sz;
- uint32_t riff_fmt;
- uint32_t fmt_id;
- uint32_t fmt_sz;
- uint16_t audio_format;
- uint16_t num_channels;
- uint32_t sample_rate;
- uint32_t byte_rate; /* sample_rate * num_channels * bps / 8 */
- uint16_t block_align; /* num_channels * bps / 8 */
- uint16_t bits_per_sample;
- uint32_t data_id;
- uint32_t data_sz;
-};
-
-static int set_params(struct pcm *pcm)
-{
- struct snd_pcm_hw_params *params;
- struct snd_pcm_sw_params *sparams;
-
- unsigned long periodSize, bufferSize, reqBuffSize;
- unsigned int periodTime, bufferTime;
- unsigned int requestedRate = pcm->rate;
-
- params = (struct snd_pcm_hw_params*) calloc(1, sizeof(struct snd_pcm_hw_params));
- if (!params) {
- fprintf(stderr, "Arec:Failed to allocate ALSA hardware parameters!");
- return -ENOMEM;
- }
-
- param_init(params);
-
- param_set_mask(params, SNDRV_PCM_HW_PARAM_ACCESS,
- (pcm->flags & PCM_MMAP)? SNDRV_PCM_ACCESS_MMAP_INTERLEAVED : SNDRV_PCM_ACCESS_RW_INTERLEAVED);
- param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, pcm->format);
- param_set_mask(params, SNDRV_PCM_HW_PARAM_SUBFORMAT,
- SNDRV_PCM_SUBFORMAT_STD);
- if (period)
- param_set_min(params, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, period);
- else
- param_set_min(params, SNDRV_PCM_HW_PARAM_PERIOD_TIME, 10);
- param_set_int(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS, 16);
- param_set_int(params, SNDRV_PCM_HW_PARAM_FRAME_BITS,
- pcm->channels * 16);
- param_set_int(params, SNDRV_PCM_HW_PARAM_CHANNELS,
- pcm->channels);
- param_set_int(params, SNDRV_PCM_HW_PARAM_RATE, pcm->rate);
-
- param_set_hw_refine(pcm, params);
-
- if (param_set_hw_params(pcm, params)) {
- fprintf(stderr, "Arec:cannot set hw params");
- return -errno;
- }
- if (debug)
- param_dump(params);
-
- pcm->buffer_size = pcm_buffer_size(params);
- pcm->period_size = pcm_period_size(params);
- pcm->period_cnt = pcm->buffer_size/pcm->period_size;
- if (debug) {
- fprintf (stderr,"period_size (%d)", pcm->period_size);
- fprintf (stderr," buffer_size (%d)", pcm->buffer_size);
- fprintf (stderr," period_cnt (%d)\n", pcm->period_cnt);
- }
- sparams = (struct snd_pcm_sw_params*) calloc(1, sizeof(struct snd_pcm_sw_params));
- if (!sparams) {
- fprintf(stderr, "Arec:Failed to allocate ALSA software parameters!\n");
- return -ENOMEM;
- }
- sparams->tstamp_mode = SNDRV_PCM_TSTAMP_NONE;
- sparams->period_step = 1;
-
- if (pcm->flags & PCM_MONO) {
- sparams->avail_min = pcm->period_size/2;
- sparams->xfer_align = pcm->period_size/2;
- } else if (pcm->flags & PCM_QUAD) {
- sparams->avail_min = pcm->period_size/8;
- sparams->xfer_align = pcm->period_size/8;
- } else if (pcm->flags & PCM_5POINT1) {
- sparams->avail_min = pcm->period_size/12;
- sparams->xfer_align = pcm->period_size/12;
- } else {
- sparams->avail_min = pcm->period_size/4;
- sparams->xfer_align = pcm->period_size/4;
- }
-
- sparams->start_threshold = 1;
- sparams->stop_threshold = INT_MAX;
- sparams->silence_size = 0;
- sparams->silence_threshold = 0;
-
- if (param_set_sw_params(pcm, sparams)) {
- fprintf(stderr, "Arec:cannot set sw params");
- return -errno;
- }
- if (debug) {
- fprintf (stderr,"avail_min (%lu)\n", sparams->avail_min);
- fprintf (stderr,"start_threshold (%lu)\n", sparams->start_threshold);
- fprintf (stderr,"stop_threshold (%lu)\n", sparams->stop_threshold);
- fprintf (stderr,"xfer_align (%lu)\n", sparams->xfer_align);
- }
- return 0;
-
-}
-
-int record_file(unsigned rate, unsigned channels, int fd, unsigned count, unsigned flags, const char *device)
-{
- unsigned xfer, bufsize;
- int r, avail;
- int nfds = 1;
- static int start = 0;
- struct snd_xferi x;
- long frames;
- unsigned offset = 0;
- int err;
- struct pollfd pfd[1];
- int rec_size = 0;
-
- flags |= PCM_IN;
-
- if (channels == 1)
- flags |= PCM_MONO;
- else if (channels == 4)
- flags |= PCM_QUAD;
- else if (channels == 6)
- flags |= PCM_5POINT1;
- else
- flags |= PCM_STEREO;
-
- pcm = pcm_open(flags, device);
- if (!pcm_ready(pcm)) {
- pcm_close(pcm);
- goto fail;
- }
- pcm->channels = channels;
- pcm->rate = rate;
- pcm->flags = flags;
- pcm->format = format;
- if (set_params(pcm)) {
- fprintf(stderr, "Arec:params setting failed\n");
- pcm_close(pcm);
- return -EINVAL;
- }
-
- if (!pcm_flag) {
- if (pcm_prepare(pcm)) {
- fprintf(stderr, "Arec:Failed in pcm_prepare\n");
- pcm_close(pcm);
- return -errno;
- }
- if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_START)) {
- fprintf(stderr, "Arec: Hostless IOCTL_START Error no %d \n", errno);
- pcm_close(pcm);
- return -errno;
- }
- while(1);
- }
-
- if (flags & PCM_MMAP) {
- u_int8_t *dst_addr = NULL;
- struct snd_pcm_sync_ptr *sync_ptr1 = pcm->sync_ptr;
- unsigned int tmp;
-
- if (mmap_buffer(pcm)) {
- fprintf(stderr, "Arec:params setting failed\n");
- pcm_close(pcm);
- return -EINVAL;
- }
- if (debug)
- fprintf(stderr, "Arec:mmap_buffer done\n");
-
- if (pcm_prepare(pcm)) {
- fprintf(stderr, "Arec:Failed in pcm_prepare\n");
- pcm_close(pcm);
- return -errno;
- }
-
- bufsize = pcm->period_size;
- if (debug)
- fprintf(stderr, "Arec:bufsize = %d\n", bufsize);
- if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_START)) {
- if (errno == EPIPE) {
- fprintf(stderr, "Arec:Failed in SNDRV_PCM_IOCTL_START\n");
- /* we failed to make our window -- try to restart */
- pcm->running = 0;
- } else {
- fprintf(stderr, "Arec:Error no %d \n", errno);
- return -errno;
- }
- }
-
- pfd[0].fd = pcm->fd;
- pfd[0].events = POLLIN;
-
- hdr.data_sz = 0;
- if (pcm->flags & PCM_MONO) {
- frames = bufsize / 2;
- } else if (pcm->flags & PCM_QUAD) {
- frames = bufsize / 8;
- } else if (pcm->flags & PCM_5POINT1) {
- frames = bufsize / 12;
- } else{
- frames = bufsize / 4;
- }
- x.frames = frames;
- for(;;) {
- if (!pcm->running) {
- if (pcm_prepare(pcm))
- return --errno;
- start = 0;
- }
- /* Sync the current Application pointer from the kernel */
- pcm->sync_ptr->flags = SNDRV_PCM_SYNC_PTR_APPL | SNDRV_PCM_SYNC_PTR_AVAIL_MIN;//SNDRV_PCM_SYNC_PTR_HWSYNC;
- err = sync_ptr(pcm);
- if (err == EPIPE) {
- fprintf(stderr, "Arec:Failed in sync_ptr \n");
- /* we failed to make our window -- try to restart */
- //pcm->overruns++;
- pcm->running = 0;
- continue;
- }
- /*
- * Check for the available data in driver. If available data is
- * less than avail_min we need to wait
- */
- avail = pcm_avail(pcm);
- if (debug)
- fprintf(stderr, "Arec:avail 1 = %d frames = %ld\n",avail, frames);
- if (avail < 0)
- return avail;
- if (avail < pcm->sw_p->avail_min) {
- poll(pfd, nfds, TIMEOUT_INFINITE);
- continue;
- }
- if (x.frames > avail)
- frames = avail;
- /*
- * Now that we have data size greater than avail_min available to
- * to be read we need to calcutate the buffer offset where we can
- * start reading from.
- */
- dst_addr = dst_address(pcm);
-
- /*
- * Write to the file at the destination address from kernel mmaped buffer
- * This reduces a extra copy of intermediate buffer.
- */
- if (write(fd, dst_addr, bufsize) != bufsize) {
- fprintf(stderr, "Arec:could not write %d bytes\n", bufsize);
- return -errno;
- }
- x.frames -= frames;
- pcm->sync_ptr->c.control.appl_ptr += frames;
- pcm->sync_ptr->flags = 0;
- err = sync_ptr(pcm);
- if (err == EPIPE) {
- fprintf(stderr, "Arec:Failed in sync_ptr \n");
- /* we failed to make our window -- try to restart */
- pcm->running = 0;
- continue;
- }
- rec_size += bufsize;
- hdr.data_sz += bufsize;
- hdr.riff_sz = hdr.data_sz + 44 - 8;
- if (!piped) {
- lseek(fd, 0, SEEK_SET);
- write(fd, &hdr, sizeof(hdr));
- lseek(fd, 0, SEEK_END);
- }
- if (rec_size >= count)
- break;
- }
- } else {
- bufsize = pcm->period_size;
- if (pcm_prepare(pcm)) {
- fprintf(stderr, "Arec:Failed in pcm_prepare\n");
- pcm_close(pcm);
- return -errno;
- }
-
- data = calloc(1, bufsize);
- if (!data) {
- fprintf(stderr, "Arec:could not allocate %d bytes\n", bufsize);
- return -ENOMEM;
- }
-
- while (!pcm_read(pcm, data, bufsize)) {
- if (write(fd, data, bufsize) != bufsize) {
- fprintf(stderr, "Arec:could not write %d bytes\n", bufsize);
- break;
- }
- rec_size += bufsize;
- hdr.data_sz += bufsize;
- hdr.riff_sz = hdr.data_sz + 44 - 8;
- if (!piped) {
- lseek(fd, 0, SEEK_SET);
- write(fd, &hdr, sizeof(hdr));
- lseek(fd, 0, SEEK_END);
- }
- if (rec_size >= count)
- break;
- }
- }
- fprintf(stderr, " rec_size =%d count =%d\n", rec_size, count);
- close(fd);
- free(data);
- pcm_close(pcm);
- return hdr.data_sz;
-
-fail:
- fprintf(stderr, "Arec:pcm error: %s\n", pcm_error(pcm));
- return -errno;
-}
-
-int rec_raw(const char *fg, const char *device, int rate, int ch,
- const char *fn)
-{
- unsigned flag = 0;
- uint32_t rec_max_sz = 2147483648LL;
- uint32_t count;
- int i = 0;
-
- if (!fn) {
- fd = fileno(stdout);
- piped = 1;
- } else {
- fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0664);
- if (fd < 0) {
- fprintf(stderr, "Arec:arec: cannot open '%s'\n", fn);
- return -EBADFD;
- }
- }
- if (duration == 0) {
- count = rec_max_sz;
- } else {
- count = rate * ch * 2;
- count *= (uint32_t)duration;
- }
- count = count < rec_max_sz ? count : rec_max_sz;
- if (debug)
- fprintf(stderr, "arec: %d ch, %d hz, %d bit, format %x\n",
- ch, rate, 16, format);
-
- if (!strncmp(fg, "M", sizeof("M"))) {
- flag = PCM_MMAP;
- } else if (!strncmp(fg, "N", sizeof("N"))) {
- flag = PCM_NMMAP;
- }
- return record_file(rate, ch, fd, count, flag, device);
-}
-
-int rec_wav(const char *fg, const char *device, int rate, int ch, const char *fn)
-{
- unsigned flag = 0;
- uint32_t rec_max_sz = 2147483648LL;
- uint32_t count = 0;
- int i = 0;
-
- if (pcm_flag) {
- if (!fn) {
- fd = fileno(stdout);
- piped = 1;
- } else {
- fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0664);
- if (fd < 0) {
- fprintf(stderr, "Arec:arec: cannot open '%s'\n", fn);
- return -EBADFD;
- }
- }
- memset(&hdr, 0, sizeof(struct wav_header));
- hdr.riff_id = ID_RIFF;
- hdr.riff_fmt = ID_WAVE;
- hdr.fmt_id = ID_FMT;
- hdr.fmt_sz = 16;
- hdr.audio_format = FORMAT_PCM;
- hdr.num_channels = ch;
- hdr.sample_rate = rate;
- hdr.bits_per_sample = 16;
- hdr.byte_rate = (rate * ch * hdr.bits_per_sample) / 8;
- hdr.block_align = ( hdr.bits_per_sample * ch ) / 8;
- hdr.data_id = ID_DATA;
- hdr.data_sz = 0;
-
- if (duration == 0) {
- count = rec_max_sz;
- } else {
- count = rate * ch * 2;
- count *= (uint32_t)duration;
- }
- hdr.riff_sz = hdr.data_sz + 44 - 8;
- if (write(fd, &hdr, sizeof(hdr)) != sizeof(hdr)) {
- if (debug)
- fprintf(stderr, "arec: cannot write header\n");
- return -errno;
- }
- if (debug)
- fprintf(stderr, "arec: %d ch, %d hz, %d bit, %s\n",
- hdr.num_channels, hdr.sample_rate, hdr.bits_per_sample,
- hdr.audio_format == FORMAT_PCM ? "PCM" : "unknown");
- } else {
- hdr.sample_rate = rate;
- hdr.num_channels = ch;
- }
-
- if (!strncmp(fg, "M", sizeof("M"))) {
- flag = PCM_MMAP;
- } else if (!strncmp(fg, "N", sizeof("N"))) {
- flag = PCM_NMMAP;
- }
- return record_file(hdr.sample_rate, hdr.num_channels, fd, count, flag, device);
-}
-
-static void signal_handler(int sig)
-{
- long file_size;
- FILE *fp;
-
- fprintf(stderr, "Arec:Aborted by signal %s...\n", strsignal(sig));
- fprintf(stderr, "Arec:lseeked to %d", (int) lseek(fd, 0, SEEK_SET));
- hdr.riff_sz = hdr.data_sz + 44 - 8;
- fprintf(stderr, "Arec: hdr.data_sz =%d\n", hdr.data_sz);
- fprintf(stderr, "Arec: hdr.riff_sz =%d\n", hdr.riff_sz);
- if (write(fd, &hdr, sizeof(hdr)) != sizeof(hdr)) {
- if (debug)
- fprintf(stderr, "Arec:arec: cannot write header\n");
- } else
- fd = -1;
-
- if (fd > 1) {
- close(fd);
- fd = -1;
- }
- free(filename);
- free(data);
- pcm = NULL;
- raise(sig);
-}
-
-int main(int argc, char **argv)
-{
- int rate = 48000;
- int ch = 1;
- int i = 0;
- int option_index = 0;
- int c;
- char *mmap = "N";
- char *device = "hw:0,0";
- struct sigaction sa;
- int rc = 0;
-
- if (argc < 2) {
- printf("\nUsage: arec [options] <file>\n"
- "options:\n"
- "-D <hw:C,D> -- Alsa PCM by name\n"
- "-M -- Mmap stream\n"
- "-P -- Hostless steam[No PCM]\n"
- "-V -- verbose\n"
- "-C -- Channels\n"
- "-R -- Rate\n"
- "-T -- Time in seconds for recording\n"
- "-F -- Format\n"
- "-B -- Period\n"
- "<file> \n");
- for (i = 0; i < SNDRV_PCM_FORMAT_LAST; ++i)
- if (get_format_name(i))
- fprintf(stderr, "%s ", get_format_name(i));
- fprintf(stderr, "\nSome of these may not be available on selected hardware\n");
- return 0;
- }
- while ((c = getopt_long(argc, argv, "PVMD:R:C:T:F:B:", long_options, &option_index)) != -1) {
- switch (c) {
- case 'P':
- pcm_flag = 0;
- break;
- case 'V':
- debug = 1;
- break;
- case 'M':
- mmap = "M";
- break;
- case 'D':
- device = optarg;
- break;
- case 'R':
- rate = (int)strtol(optarg, NULL, 0);
- break;
- case 'C':
- ch = (int)strtol(optarg, NULL, 0);
- break;
- case 'T':
- duration = (int)strtol(optarg, NULL, 0);
- break;
- case 'F':
- format = (int)get_format(optarg);
- break;
- case 'B':
- period = (int)strtol(optarg, NULL, 0);
- break;
- default:
- printf("\nUsage: arec [options] <file>\n"
- "options:\n"
- "-D <hw:C,D> -- Alsa PCM by name\n"
- "-M -- Mmap stream\n"
- "-P -- Hostless steam[No PCM]\n"
- "-V -- verbose\n"
- "-C -- Channels\n"
- "-R -- Rate\n"
- "-T -- Time in seconds for recording\n"
- "-F -- Format\n"
- "-B -- Period\n"
- "<file> \n");
- for (i = 0; i < SNDRV_PCM_FORMAT_LAST; ++i)
- if (get_format_name(i))
- fprintf(stderr, "%s ", get_format_name(i));
- fprintf(stderr, "\nSome of these may not be available on selected hardware\n");
- return -EINVAL;
- }
- }
- filename = (char*) calloc(1, 30);
- if (!filename) {
- fprintf(stderr, "Arec:Failed to allocate filename!");
- return -ENOMEM;
- }
- if (optind > argc - 1) {
- free(filename);
- filename = NULL;
- } else {
- strlcpy(filename, argv[optind++], 30);
- }
-
- memset(&sa, 0, sizeof(sa));
- sa.sa_handler = &signal_handler;
- sigaction(SIGABRT, &sa, NULL);
-
- if (pcm_flag) {
- if (format == SNDRV_PCM_FORMAT_S16_LE)
- rc = rec_wav(mmap, device, rate, ch, filename);
- else
- rc = rec_raw(mmap, device, rate, ch, filename);
- } else {
- rc = rec_wav(mmap, device, rate, ch, "dummy");
- }
- if (filename)
- free(filename);
-
- return rc;
-}
-
diff --git a/legacy/libalsa-intf/msm8960_use_cases.h b/legacy/libalsa-intf/msm8960_use_cases.h
deleted file mode 100644
index 7f98df1..0000000
--- a/legacy/libalsa-intf/msm8960_use_cases.h
+++ /dev/null
@@ -1,321 +0,0 @@
-/*
- * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- * * Neither the name of The Linux Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#ifndef _MSM8960_USE_CASES_H_
-#define _MSM8960_USE_CASES_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "alsa_ucm.h"
-#include "alsa_audio.h"
-#include <stdbool.h>
-#include <pthread.h>
-#define SND_UCM_END_OF_LIST "end"
-
-/* ACDB Device ID macros */
-#define CAP_RX 0x1
-#define CAP_TX 0x2
-#define CAP_VOICE 0x4
-#define DEVICE_HANDSET_RX_ACDB_ID 7 // HANDSET_SPKR
-#define DEVICE_HANDSET_RX_TMUS_ACDB_ID 81// HANDSET_SPKR
-#define DEVICE_HANDSET_TX_ACDB_ID 4 // HANDSET_MIC
-#define DEVICE_SPEAKER_MONO_RX_ACDB_ID 14// SPKR_PHONE_SPKR_MONO
-#define DEVICE_SPEAKER_STEREO_RX_ACDB_ID 15// SPKR_PHONE_SPKR_STEREO
-#define DEVICE_SPEAKER_TX_ACDB_ID 11// SPKR_PHONE_MIC
-#define DEVICE_HEADSET_RX_ACDB_ID 10// HEADSET_SPKR_STEREO
-#define DEVICE_HEADSET_TX_ACDB_ID 8 // HEADSET_MIC
-#define DEVICE_DUALMIC_HANDSET_TX_BROADSIDE_ACDB_ID 5 // HANDSET_MIC_BROADSIDE
-#define DEVICE_DUALMIC_HANDSET_TX_ENDFIRE_ACDB_ID 6 // HANDSET_MIC_ENDFIRE
-#define DEVICE_DUALMIC_HANDSET_TX_ENDFIRE_TMUS_ACDB_ID 91// HANDSET_MIC_ENDFIRE
-#define DEVICE_DUALMIC_SPEAKER_TX_BROADSIDE_ACDB_ID 12// SPKR_PHONE_MIC_BROADSIDE
-#define DEVICE_DUALMIC_SPEAKER_TX_ENDFIRE_ACDB_ID 13// SPKR_PHONE_MIC_ENDFIRE
-#define DEVICE_TTY_HEADSET_MONO_RX_ACDB_ID 17// TTY_HEADSET_SPKR
-#define DEVICE_TTY_HEADSET_MONO_TX_ACDB_ID 16// TTY_HEADSET_MIC
-#define DEVICE_BT_SCO_RX_ACDB_ID 22// BT_SCO_SPKR
-#define DEVICE_BT_SCO_TX_ACDB_ID 21// BT_SCO_SPKR
-#define DEVICE_BT_SCO_RX_WB_ACDB_ID 39// BT_SCO_WB_SPKR
-#define DEVICE_BT_SCO_TX_WB_ACDB_ID 38// BT_SCO_WB_MIC
-#define DEVICE_SPEAKER_HEADSET_RX_ACDB_ID DEVICE_HEADSET_RX_ACDB_ID // Use headset calibration
-#define DEVICE_HDMI_STEREO_RX_ACDB_ID 18// HDMI_SPKR
-#define DEVICE_ANC_HEADSET_STEREO_RX_ACDB_ID 26// ANC RX, same as regular headset
-#define DEVICE_QUADMIC_ACDB_ID 19// QUADMIC_SKPR
-#define DEVICE_PROXY_RX_ACDB_ID DEVICE_HDMI_STEREO_RX_ACDB_ID
-#define DEVICE_TTY_VCO_HANDSET_TX_ACDB_ID 36// TTY_VCO_HANDSET_MIC
-#define DEVICE_TTY_HCO_HANDSET_RX_ACDB_ID 37// TTY_HCO_HANDSET_SPRK
-#define DEVICE_HANDSET_TX_FV5_ACDB_ID 50
-#define DEVICE_DUALMIC_HANDSET_TX_ENDFIRE_FV5_ACDB_ID 51
-#define DEVICE_SPEAKER_TX_FV5_ACDB_ID 52
-#define DEVICE_DUALMIC_SPEAKER_TX_ENDFIRE_FV5_ACDB_ID 53
-#define DEVICE_INCALL_VOICE_RECORD_STEREO_ACDB_ID 45
-#define DEVICE_INCALL_MUSIC_DELIVERY_MONO_ACDB_ID 46
-#define DEVICE_INCALL_VOICE_RECORD_MONO_ACDB_ID 47
-#define DEVICE_CAMCORDER_TX_ACDB_ID 61// CAMCORDER_TX
-#define DEVICE_VOICE_RECOGNITION_ACDB_ID 62// VOICE_RECOGNITION
-
-/* mixer control type */
-#define TYPE_INT 0
-#define TYPE_STR 1
-#define TYPE_MULTI_VAL 2
-
-/* Maximum string length of use case and device combination */
-#define MAX_UC_LEN 100
-/* Maximum string length of use case or device */
-#define MAX_STR_LEN 50
-
-/* Returns maximum length of strings x and y */
-#define MAX_LEN(x,y) ((strlen(x)>strlen(y))?strlen(x):strlen(y))
-
-/* Mixer control list type enum*/
-enum {
- CTRL_LIST_VERB,
- CTRL_LIST_DEVICE,
- CTRL_LIST_MODIFIER,
-};
-
-/* mixer control structure */
-typedef struct mixer_control {
- char *control_name;
- unsigned type;
- unsigned value;
- char *string;
- char **mulval;
-}mixer_control_t;
-
-/* Use case mixer controls structure */
-typedef struct card_mctrl {
- char *case_name;
- int ena_mixer_count;
- mixer_control_t *ena_mixer_list;
- int dis_mixer_count;
- mixer_control_t *dis_mixer_list;
- char *playback_dev_name;
- char *capture_dev_name;
- int acdb_id;
- int capability;
- char *effects_mixer_ctl;
-}card_mctrl_t;
-
-/* identifier node structure for identifier list*/
-struct snd_ucm_ident_node {
- int active;
- int capability;
- char ident[MAX_STR_LEN];
- struct snd_ucm_ident_node *next;
-};
-
-/* Structure to maintain the valid devices and
- * modifiers list per each use case */
-typedef struct use_case_verb {
- char *use_case_name;
- char **device_list;
- char **modifier_list;
- int verb_count;
- int device_count;
- int mod_count;
- card_mctrl_t *verb_ctrls;
- card_mctrl_t *device_ctrls;
- card_mctrl_t *mod_ctrls;
-}use_case_verb_t;
-
-/* SND card context structure */
-typedef struct card_ctxt {
- char *card_name;
- int card_number;
- char *control_device;
- struct mixer *mixer_handle;
- char current_verb[MAX_STR_LEN];
- struct snd_ucm_ident_node *dev_list_head;
- struct snd_ucm_ident_node *mod_list_head;
- pthread_mutex_t card_lock;
- pthread_mutexattr_t card_lock_attr;
- int current_verb_index;
- use_case_verb_t *use_case_verb_list;
- char **verb_list;
-}card_ctxt_t;
-
-/** use case manager structure */
-struct snd_use_case_mgr {
- int snd_card_index;
- int device_list_count;
- int modifier_list_count;
- char **current_device_list;
- char **current_modifier_list;
- int current_tx_device;
- int current_rx_device;
- card_ctxt_t *card_ctxt_ptr;
- pthread_t thr;
- void *acdb_handle;
- bool isFusion3Platform;
-};
-
-#define MAX_NUM_CARDS (sizeof(card_list)/sizeof(char *))
-
-/* Valid sound cards list */
-static const char *card_list[] = {
- "snd_soc_msm",
- "snd_soc_msm_2x",
- "snd_soc_msm_2x_Fusion3",
- "snd_soc_msm_Sitar",
-};
-
-typedef struct card_mapping {
- char card_name[50];
- int card_number;
-}card_mapping_t;
-
-/* sound card name and number mapping */
-static card_mapping_t card_mapping_list[] = {
- {"snd_soc_msm", 0},
- {"snd_soc_msm_2x", 0},
- {"snd_soc_msm_2x_Fusion3", 0},
- {"snd_soc_msm_Sitar", 0},
-};
-
-/* New use cases, devices and modifiers added
- * which are not part of existing macros
- */
-#define SND_USE_CASE_VERB_FM_REC "FM REC"
-#define SND_USE_CASE_VERB_FM_A2DP_REC "FM A2DP REC"
-#define SND_USE_CASE_VERB_HIFI_REC "HiFi Rec"
-#define SND_USE_CASE_VERB_HIFI_LOWLATENCY_REC "HiFi Lowlatency Rec"
-#define SND_USE_CASE_VERB_DL_REC "DL REC"
-#define SND_USE_CASE_VERB_UL_DL_REC "UL DL REC"
-#define SND_USE_CASE_VERB_HIFI_TUNNEL "HiFi Tunnel"
-#define SND_USE_CASE_VERB_HIFI_LOWLATENCY_MUSIC "HiFi Lowlatency"
-#define SND_USE_CASE_VERB_HIFI2 "HiFi2"
-#define SND_USE_CASE_VERB_INCALL_REC "Incall REC"
-#define SND_USE_CASE_VERB_MI2S "MI2S"
-#define SND_USE_CASE_VERB_VOLTE "VoLTE"
-#define SND_USE_CASE_VERB_ADSP_TESTFWK "ADSP testfwk"
-
-#define SND_USE_CASE_DEV_FM_TX "FM Tx"
-#define SND_USE_CASE_DEV_ANC_HEADSET "ANC Headset"
-#define SND_USE_CASE_DEV_BTSCO_NB_RX "BT SCO Rx"
-#define SND_USE_CASE_DEV_BTSCO_NB_TX "BT SCO Tx"
-#define SND_USE_CASE_DEV_BTSCO_WB_RX "BT SCO WB Rx"
-#define SND_USE_CASE_DEV_BTSCO_WB_TX "BT SCO WB Tx"
-#define SND_USE_CASE_DEV_SPEAKER_HEADSET "Speaker Headset"
-#define SND_USE_CASE_DEV_SPEAKER_ANC_HEADSET "Speaker ANC Headset"
-#define SND_USE_CASE_DEV_SPEAKER_FM_TX "Speaker FM Tx"
-#define SND_USE_CASE_DEV_TTY_HEADSET_RX "TTY Headset Rx"
-#define SND_USE_CASE_DEV_TTY_HEADSET_TX "TTY Headset Tx"
-#define SND_USE_CASE_DEV_TTY_FULL_RX "TTY Full Rx"
-#define SND_USE_CASE_DEV_TTY_FULL_TX "TTY Full Tx"
-#define SND_USE_CASE_DEV_TTY_HANDSET_RX "TTY Handset Rx"
-#define SND_USE_CASE_DEV_TTY_HANDSET_TX "TTY Handset Tx"
-#define SND_USE_CASE_DEV_TTY_HANDSET_ANALOG_TX "TTY Handset Analog Tx"
-#define SND_USE_CASE_DEV_DUAL_MIC_BROADSIDE "DMIC Broadside"
-#define SND_USE_CASE_DEV_DUAL_MIC_BROADSIDE_VREC "DMIC Broadside Voice Rec"
-#define SND_USE_CASE_DEV_DUAL_MIC_ENDFIRE "DMIC Endfire"
-#define SND_USE_CASE_DEV_DUAL_MIC_ENDFIRE_TMUS "DMIC Endfire TMUS"
-#define SND_USE_CASE_DEV_DUAL_MIC_ENDFIRE_VREC "DMIC Endfire Voice Rec"
-#define SND_USE_CASE_DEV_SPEAKER_DUAL_MIC_BROADSIDE "Speaker DMIC Broadside"
-#define SND_USE_CASE_DEV_SPEAKER_DUAL_MIC_ENDFIRE "Speaker DMIC Endfire"
-#define SND_USE_CASE_DEV_HDMI_TX "HDMI Tx"
-#define SND_USE_CASE_DEV_HDMI_SPDIF "HDMI SPDIF"
-#define SND_USE_CASE_DEV_QUAD_MIC "QMIC"
-#define SND_USE_CASE_DEV_SSR_QUAD_MIC "SSR QMIC"
-#define SND_USE_CASE_DEV_PROXY_RX "PROXY Rx"
-#define SND_USE_CASE_DEV_PROXY_TX "PROXY Tx"
-#define SND_USE_CASE_DEV_HDMI_SPEAKER "HDMI Speaker"
-#define SND_USE_CASE_DEV_SPDIF_SPEAKER "SPDIF Speaker"
-#define SND_USE_CASE_DEV_SPDIF_HANDSET "SPDIF Earpiece"
-#define SND_USE_CASE_DEV_SPDIF_HEADSET "SPDIF Headphones"
-#define SND_USE_CASE_DEV_SPDIF_ANC_HEADSET "SPDIF ANC Headset"
-#define SND_USE_CASE_DEV_SPDIF_SPEAKER_HEADSET "SPDIF Speaker Headset"
-#define SND_USE_CASE_DEV_SPDIF_SPEAKER_ANC_HEADSET "SPDIF Speaker ANC Headset"
-#define SND_USE_CASE_DEV_DUMMY_TX "Dummy Tx"
-#define SND_USE_CASE_DEV_PROXY_RX_SPEAKER "PROXY Rx Speaker"
-#define SND_USE_CASE_DEV_PROXY_RX_HANDSET "PROXY Rx Earpiece"
-#define SND_USE_CASE_DEV_PROXY_RX_HEADSET "PROXY Rx Headphones"
-#define SND_USE_CASE_DEV_PROXY_RX_ANC_HEADSET "PROXY Rx ANC Headset"
-#define SND_USE_CASE_DEV_PROXY_RX_SPEAKER_HEADSET "PROXY Rx Speaker Headset"
-#define SND_USE_CASE_DEV_PROXY_RX_SPEAKER_ANC_HEADSET "PROXY Rx Speaker ANC Headset"
-#define SND_USE_CASE_DEV_CAMCORDER_TX "Camcorder Tx"
-#define SND_USE_CASE_DEV_VOICE_RECOGNITION "Voice Recognition"
-#define SND_USE_CASE_DEV_VOC_EARPIECE "Voice Earpiece"
-#define SND_USE_CASE_DEV_VOC_EARPIECE_TMUS "Voice Earpiece TMUS"
-#define SND_USE_CASE_DEV_VOC_HEADPHONE "Voice Headphones"
-#define SND_USE_CASE_DEV_VOC_HEADSET "Voice Headset"
-#define SND_USE_CASE_DEV_VOC_ANC_HEADSET "Voice ANC Headset"
-#define SND_USE_CASE_DEV_VOC_SPEAKER "Voice Speaker"
-#define SND_USE_CASE_DEV_VOC_LINE "Voice Line"
-
-#define SND_USE_CASE_MOD_PLAY_FM "Play FM"
-#define SND_USE_CASE_MOD_CAPTURE_FM "Capture FM"
-#define SND_USE_CASE_MOD_CAPTURE_LOWLATENCY_MUSIC "Capture Lowlatency Music"
-#define SND_USE_CASE_MOD_CAPTURE_A2DP_FM "Capture A2DP FM"
-#define SND_USE_CASE_MOD_PLAY_LPA "Play LPA"
-#define SND_USE_CASE_MOD_PLAY_VOIP "Play VOIP"
-#define SND_USE_CASE_MOD_CAPTURE_VOIP "Capture VOIP"
-#define SND_USE_CASE_MOD_CAPTURE_VOICE_DL "Capture Voice Downlink"
-#define SND_USE_CASE_MOD_CAPTURE_VOICE_UL_DL "Capture Voice Uplink Downlink"
-#define SND_USE_CASE_MOD_PLAY_TUNNEL "Play Tunnel"
-#define SND_USE_CASE_MOD_PLAY_LOWLATENCY_MUSIC "Play Lowlatency Music"
-#define SND_USE_CASE_MOD_PLAY_MUSIC2 "Play Music2"
-#define SND_USE_CASE_MOD_PLAY_MI2S "Play MI2S"
-#define SND_USE_CASE_MOD_PLAY_VOLTE "Play VoLTE"
-
-/* List utility functions for maintaining enabled devices and modifiers */
-static int snd_ucm_add_ident_to_list(struct snd_ucm_ident_node **head, const char *value);
-static char *snd_ucm_get_value_at_index(struct snd_ucm_ident_node *head, int index);
-static int snd_ucm_get_size_of_list(struct snd_ucm_ident_node *head);
-static int snd_ucm_del_ident_from_list(struct snd_ucm_ident_node **head, const char *value);
-static int snd_ucm_free_list(struct snd_ucm_ident_node **head);
-static void snd_ucm_print_list(struct snd_ucm_ident_node *head);
-static void snd_ucm_set_status_at_index(struct snd_ucm_ident_node *head, const char *ident, int status, int capability);
-static int snd_ucm_get_status_at_index(struct snd_ucm_ident_node *head, const char *ident);
-struct snd_ucm_ident_node *snd_ucm_get_device_node(struct snd_ucm_ident_node *head, int index);
-static int snd_ucm_parse_verb(snd_use_case_mgr_t **uc_mgr, const char *file_name, int index);
-static int get_verb_count(const char *nxt_str);
-int snd_use_case_mgr_wait_for_parsing(snd_use_case_mgr_t *uc_mgr);
-int snd_use_case_set_case(snd_use_case_mgr_t *uc_mgr, const char *identifier,
- const char *value, const char *usecase);
-static int get_usecase_type(snd_use_case_mgr_t *uc_mgr, const char *usecase);
-static int parse_single_config_format(snd_use_case_mgr_t **uc_mgr, char *current_str, int num_verbs);
-static int get_num_verbs_config_format(const char *nxt_str);
-static int get_num_device_config_format(const char *nxt_str);
-static int get_num_mod_config_format(const char *nxt_str);
-static int is_single_config_format(const char *nxt_str);
-/* Parse functions */
-static int snd_ucm_parse(snd_use_case_mgr_t **uc_mgr);
-static int snd_ucm_parse_section(snd_use_case_mgr_t **uc_mgr, char **cur_str, char **nxt_str, int verb_index, int ctrl_list_type);
-static int snd_ucm_extract_name(char *buf, char **case_name);
-static int snd_ucm_extract_acdb(char *buf, int *id, int *cap);
-static int snd_ucm_extract_effects_mixer_ctl(char *buf, char **mixer_name);
-static int snd_ucm_extract_dev_name(char *buf, char **dev_name);
-static int snd_ucm_extract_controls(char *buf, mixer_control_t **mixer_list, int count);
-static int snd_ucm_print(snd_use_case_mgr_t *uc_mgr);
-static void snd_ucm_free_mixer_list(snd_use_case_mgr_t **uc_mgr);
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/policy_hal/Android.mk b/policy_hal/Android.mk
index 517f207..480df92 100644
--- a/policy_hal/Android.mk
+++ b/policy_hal/Android.mk
@@ -39,6 +39,9 @@
LOCAL_CFLAGS += -DWFD_CONCURRENCY
endif
+ifeq ($(strip $(AUDIO_FEATURE_ENABLED_MULTIPLE_TUNNEL)), true)
+LOCAL_CFLAGS += -DMULTIPLE_OFFLOAD_ENABLED
+endif
include $(BUILD_SHARED_LIBRARY)
diff --git a/policy_hal/AudioPolicyManager.cpp b/policy_hal/AudioPolicyManager.cpp
index 5605fbc..8bb002f 100644
--- a/policy_hal/AudioPolicyManager.cpp
+++ b/policy_hal/AudioPolicyManager.cpp
@@ -391,193 +391,6 @@
}
-status_t AudioPolicyManager::startOutput(audio_io_handle_t output,
- AudioSystem::stream_type stream,
- int session)
-{
- ALOGV("startOutput() output %d, stream %d, session %d", output, stream, session);
- ssize_t index = mOutputs.indexOfKey(output);
- if (index < 0) {
- ALOGW("startOutput() unknow output %d", output);
- return BAD_VALUE;
- }
-
- AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index);
-
- // increment usage count for this stream on the requested output:
- // NOTE that the usage count is the same for duplicated output and hardware output which is
- // necessary for a correct control of hardware output routing by startOutput() and stopOutput()
- outputDesc->changeRefCount(stream, 1);
-
- if (outputDesc->mRefCount[stream] == 1) {
- audio_devices_t newDevice = getNewDevice(output, false /*fromCache*/);
- routing_strategy strategy = getStrategy(stream);
- bool shouldWait = (strategy == STRATEGY_SONIFICATION) ||
- (strategy == STRATEGY_SONIFICATION_RESPECTFUL);
- uint32_t waitMs = 0;
- bool force = false;
- for (size_t i = 0; i < mOutputs.size(); i++) {
- AudioOutputDescriptor *desc = mOutputs.valueAt(i);
- if (desc != outputDesc) {
- // force a device change if any other output is managed by the same hw
- // module and has a current device selection that differs from selected device.
- // In this case, the audio HAL must receive the new device selection so that it can
- // change the device currently selected by the other active output.
- if (outputDesc->sharesHwModuleWith(desc) &&
- desc->device() != newDevice) {
- force = true;
- }
- // wait for audio on other active outputs to be presented when starting
- // a notification so that audio focus effect can propagate.
- uint32_t latency = desc->latency();
- if (shouldWait && desc->isActive(latency * 2) && (waitMs < latency)) {
- waitMs = latency;
- }
- }
- }
- uint32_t muteWaitMs = setOutputDevice(output, newDevice, force);
-
- // handle special case for sonification while in call
- if (isInCall()) {
- handleIncallSonification(stream, true, false);
- }
-
- // apply volume rules for current stream and device if necessary
- checkAndSetVolume(stream,
- mStreams[stream].getVolumeIndex(newDevice),
- output,
- newDevice);
-
- // update the outputs if starting an output with a stream that can affect notification
- // routing
- handleNotificationRoutingForStream(stream);
- if (waitMs > muteWaitMs) {
- usleep((waitMs - muteWaitMs) * 2 * 1000);
- }
- }
-#ifdef DOLBY_UDC
- // It is observed that in some use-cases where both outputs are present eg. bluetooth and headphone,
- // the output for particular stream type is decided in this routine. Hence we must call
- // getDeviceForStrategy in order to get the current active output for this stream type and update
- // the dolby system property.
- if (stream == AudioSystem::MUSIC)
- {
- audio_devices_t audioOutputDevice = getDeviceForStrategy(getStrategy(AudioSystem::MUSIC), true);
- DolbySystemProperty::set(audioOutputDevice);
- }
-#endif // DOLBY_END
- return NO_ERROR;
-}
-
-
-status_t AudioPolicyManager::stopOutput(audio_io_handle_t output,
- AudioSystem::stream_type stream,
- int session)
-{
- ALOGV("stopOutput() output %d, stream %d, session %d", output, stream, session);
- ssize_t index = mOutputs.indexOfKey(output);
- if (index < 0) {
- ALOGW("stopOutput() unknow output %d", output);
- return BAD_VALUE;
- }
-
- AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index);
-
- // handle special case for sonification while in call
- if (isInCall()) {
- handleIncallSonification(stream, false, false);
- }
-
- if (outputDesc->mRefCount[stream] > 0) {
- // decrement usage count of this stream on the output
- outputDesc->changeRefCount(stream, -1);
- // store time at which the stream was stopped - see isStreamActive()
- if (outputDesc->mRefCount[stream] == 0) {
- outputDesc->mStopTime[stream] = systemTime();
- audio_devices_t newDevice = getNewDevice(output, false /*fromCache*/);
- // delay the device switch by twice the latency because stopOutput() is executed when
- // the track stop() command is received and at that time the audio track buffer can
- // still contain data that needs to be drained. The latency only covers the audio HAL
- // and kernel buffers. Also the latency does not always include additional delay in the
- // audio path (audio DSP, CODEC ...)
- setOutputDevice(output, newDevice, false, outputDesc->mLatency*2);
-
- // force restoring the device selection on other active outputs if it differs from the
- // one being selected for this output
- for (size_t i = 0; i < mOutputs.size(); i++) {
- audio_io_handle_t curOutput = mOutputs.keyAt(i);
- AudioOutputDescriptor *desc = mOutputs.valueAt(i);
- if (curOutput != output &&
- desc->isActive() &&
- outputDesc->sharesHwModuleWith(desc) &&
- (newDevice != desc->device())) {
- setOutputDevice(curOutput,
- getNewDevice(curOutput, false /*fromCache*/),
- true,
- outputDesc->mLatency*2);
- }
- }
- // update the outputs if stopping one with a stream that can affect notification routing
- handleNotificationRoutingForStream(stream);
- }
- return NO_ERROR;
- } else {
- ALOGW("stopOutput() refcount is already 0 for output %d", output);
- return INVALID_OPERATION;
- }
-}
-
-audio_devices_t AudioPolicyManager::getNewDevice(audio_io_handle_t output, bool fromCache)
-{
- audio_devices_t device = AUDIO_DEVICE_NONE;
-
- AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output);
- AudioOutputDescriptor *primaryOutputDesc = mOutputs.valueFor(mPrimaryOutput);
- // check the following by order of priority to request a routing change if necessary:
- // 1: the strategy enforced audible is active on the output:
- // use device for strategy enforced audible
- // 2: we are in call or the strategy phone is active on the output:
- // use device for strategy phone
- // 3: the strategy sonification is active on the output:
- // use device for strategy sonification
- // 4: the strategy "respectful" sonification is active on the output:
- // use device for strategy "respectful" sonification
- // 5: the strategy media is active on the output:
- // use device for strategy media
- // 6: the strategy DTMF is active on the output:
- // use device for strategy DTMF
- if (outputDesc->isStrategyActive(STRATEGY_ENFORCED_AUDIBLE)) {
- device = getDeviceForStrategy(STRATEGY_ENFORCED_AUDIBLE, fromCache);
- } else if (isInCall() ||
- outputDesc->isStrategyActive(STRATEGY_PHONE)) {
- device = getDeviceForStrategy(STRATEGY_PHONE, fromCache);
- } else if (outputDesc->isStrategyActive(STRATEGY_SONIFICATION)||
- (primaryOutputDesc->isStrategyActive(STRATEGY_SONIFICATION)&& !primaryOutputDesc->isStrategyActive(STRATEGY_MEDIA))){
- device = getDeviceForStrategy(STRATEGY_SONIFICATION, fromCache);
- } else if (outputDesc->isStrategyActive(STRATEGY_SONIFICATION_RESPECTFUL)) {
- device = getDeviceForStrategy(STRATEGY_SONIFICATION_RESPECTFUL, fromCache);
- } else if (outputDesc->isStrategyActive(STRATEGY_MEDIA)) {
- device = getDeviceForStrategy(STRATEGY_MEDIA, fromCache);
- } else if (outputDesc->isStrategyActive(STRATEGY_DTMF)) {
- device = getDeviceForStrategy(STRATEGY_DTMF, fromCache);
- }
-
- ALOGV("getNewDevice() selected device %x", device);
- return device;
-}
-
-//private function, no changes from AudioPolicyManagerBase
-void AudioPolicyManager::handleNotificationRoutingForStream(AudioSystem::stream_type stream) {
- switch(stream) {
- case AudioSystem::MUSIC:
- checkOutputForStrategy(STRATEGY_SONIFICATION_RESPECTFUL);
- updateDevicesAndOutputs();
- break;
- default:
- break;
- }
-}
-
audio_io_handle_t AudioPolicyManager::getInput(int inputSource,
uint32_t samplingRate,
uint32_t format,
@@ -1324,6 +1137,18 @@
if (profile != NULL) {
AudioOutputDescriptor *outputDesc = NULL;
+#ifdef MULTIPLE_OFFLOAD_ENABLED
+ bool multiOffloadEnabled = false;
+ char value[PROPERTY_VALUE_MAX] = {0};
+ property_get("audio.offload.multiple.enabled", value, NULL);
+ if (atoi(value) || !strncmp("true", value, 4))
+ multiOffloadEnabled = true;
+ // if multiple concurrent offload decode is supported
+ // do no check for reuse and also don't close previous output if its offload
+ // previous output will be closed during track destruction
+ if (multiOffloadEnabled)
+ goto get_output__new_output_desc;
+#endif
for (size_t i = 0; i < mOutputs.size(); i++) {
AudioOutputDescriptor *desc = mOutputs.valueAt(i);
if (!desc->isDuplicated() && (profile == desc->mProfile)) {
@@ -1342,6 +1167,7 @@
if (outputDesc != NULL) {
closeOutput(outputDesc->mId);
}
+get_output__new_output_desc:
outputDesc = new AudioOutputDescriptor(profile);
outputDesc->mDevice = device;
outputDesc->mSamplingRate = samplingRate;
diff --git a/policy_hal/AudioPolicyManager.h b/policy_hal/AudioPolicyManager.h
index f2488b2..dce5bad 100644
--- a/policy_hal/AudioPolicyManager.h
+++ b/policy_hal/AudioPolicyManager.h
@@ -61,12 +61,6 @@
virtual bool isOffloadSupported(const audio_offload_info_t& offloadInfo);
virtual void setPhoneState(int state);
- virtual status_t startOutput(audio_io_handle_t output,
- AudioSystem::stream_type stream,
- int session = 0);
- virtual status_t stopOutput(audio_io_handle_t output,
- AudioSystem::stream_type stream,
- int session = 0);
protected:
// return the strategy corresponding to a given stream type
static routing_strategy getStrategy(AudioSystem::stream_type stream);
@@ -94,7 +88,6 @@
// check that volume change is permitted, compute and send new volume to audio hardware
status_t checkAndSetVolume(int stream, int index, audio_io_handle_t output, audio_devices_t device, int delayMs = 0, bool force = false);
- audio_devices_t getNewDevice(audio_io_handle_t output, bool fromCache);
// returns the category the device belongs to with regard to volume curve management
static device_category getDeviceCategory(audio_devices_t device);
@@ -106,10 +99,7 @@
//parameter indicates if HDMI plug in/out detected
bool mHdmiAudioEvent;
-
private:
- void handleNotificationRoutingForStream(AudioSystem::stream_type stream);
-
// Used for voip + voice concurrency usecase
int mPrevPhoneState;