hal: visualizer: dynamically read pcm device

Dynamically read the sound card number and device id
of the pcm  device used for visualizer from procfs.

CRs-Fixed: 2430458
Change-Id: Ie757b7810eeeb8cebdbee557be1d930b6cab3f03
diff --git a/visualizer/offload_visualizer.c b/visualizer/offload_visualizer.c
index 678b73a..ccbd8bc 100644
--- a/visualizer/offload_visualizer.c
+++ b/visualizer/offload_visualizer.c
@@ -60,6 +60,11 @@
     EFFECT_STATE_ACTIVE,
 };
 
+enum pcm_device_param {
+    SND_CARD_NUM,
+    DEVICE_ID
+};
+
 typedef struct effect_context_s effect_context_t;
 typedef struct output_context_s output_context_t;
 
@@ -195,7 +200,7 @@
 #define SOUND_CARD 0
 
 #ifndef CAPTURE_DEVICE
-#define CAPTURE_DEVICE 8
+#define CAPTURE_DEVICE 7
 #endif
 
 /* Proxy port supports only MMAP read and those fixed parameters*/
@@ -356,6 +361,95 @@
     return 0;
 }
 
+// Get sound card number from pcm device
+int get_snd_card_num(char *device_info)
+{
+    char *token = NULL;
+    int num = -1;
+
+    token = strtok(device_info, ": ");
+    token = strtok(token, "-");
+    if (token)
+        num = atoi(token);
+
+    return num;
+}
+
+// Get device id from pcm device
+int get_device_id(char *device_info)
+{
+    char *token = NULL, *saveptr = NULL;
+    int id = -1;
+
+    token = strtok(device_info, ": ");
+    token = strtok_r(token, "-", &saveptr);
+    while (token != NULL) {
+        token = strtok_r(NULL, "-", &saveptr);
+        if (token) {
+            id = atoi(token);
+            break;
+        }
+    }
+
+    return id;
+}
+
+int parse_device_info(int param, char *device_info)
+{
+    switch (param) {
+        case SND_CARD_NUM:
+            return get_snd_card_num(device_info);
+        case DEVICE_ID:
+            return get_device_id(device_info);
+        default:
+            ALOGE("%s: invalid pcm device param", __func__);
+            return -1;
+    }
+}
+
+/*
+* Parse a pcm device from procfs
+* Entries in pcm file will have one of two formats:
+* <snd_card_num>-<device_id>: <descriptor> : : <playback> : <capture>
+* <snd_card_num>-<device_id>: <descriptor> : : <playback or capture>
+*/
+int parse_pcm_device(char *descriptor, int param)
+{
+    const char *pcm_devices_path = "/proc/asound/pcm";
+    char *device_info = NULL;
+    size_t len = 0;
+    ssize_t bytes_read = -1;
+    FILE *fp = NULL;
+    int ret = -1;
+
+    if (descriptor == NULL) {
+        ALOGE("%s: pcm device descriptor is NULL", __func__);
+        return ret;
+    }
+
+    if ((fp = fopen(pcm_devices_path, "r")) == NULL) {
+        ALOGE("Cannot open %s file to get list of pcm devices",
+              pcm_devices_path);
+        return ret;
+    }
+
+    while ((bytes_read = getline(&device_info, &len, fp) != -1)) {
+        if (strstr(device_info, descriptor)) {
+            ret = parse_device_info(param, device_info);
+            break;
+        }
+    }
+
+    if (device_info) {
+        free(device_info);
+        device_info = NULL;
+    }
+
+    fclose(fp);
+    fp = NULL;
+
+    return ret;
+}
 
 void *capture_thread_loop(void *arg)
 {
@@ -368,6 +462,8 @@
     struct pcm *pcm = NULL;
     int ret;
     int retry_num = 0;
+    int sound_card = SOUND_CARD;
+    int capture_device = CAPTURE_DEVICE;
 
     ALOGD("thread enter");
 
@@ -394,7 +490,15 @@
             if (!capture_enabled) {
                 ret = configure_proxy_capture(mixer, 1);
                 if (ret == 0) {
-                    pcm = pcm_open(SOUND_CARD, CAPTURE_DEVICE,
+                    sound_card =
+                       parse_pcm_device("AFE-PROXY TX", SND_CARD_NUM);
+                    sound_card =
+                       (sound_card == -1)? SOUND_CARD : sound_card;
+                    capture_device =
+                       parse_pcm_device("AFE-PROXY TX", DEVICE_ID);
+                    capture_device =
+                       (capture_device == -1)? CAPTURE_DEVICE : capture_device;
+                    pcm = pcm_open(sound_card, capture_device,
                                    PCM_IN|PCM_MMAP|PCM_NOIRQ, &pcm_config_capture);
                     if (pcm && !pcm_is_ready(pcm)) {
                         ALOGW("%s: %s", __func__, pcm_get_error(pcm));