Home | History | Annotate | Download | only in server
      1 /* Copyright 2016 The Chromium OS Authors. All rights reserved.
      2  * Use of this source code is governed by a BSD-style license that can be
      3  * found in the LICENSE file.
      4  */
      5 
      6 #include <stdlib.h>
      7 #include <string.h>
      8 #include <syslog.h>
      9 
     10 #include "cras_alsa_mixer_name.h"
     11 #include "utlist.h"
     12 
     13 struct mixer_name *mixer_name_add(struct mixer_name *names,
     14 				  const char *name,
     15 				  enum CRAS_STREAM_DIRECTION dir,
     16 				  mixer_name_type type)
     17 {
     18 	struct mixer_name *m_name;
     19 
     20 	if (!name)
     21 		return names;
     22 
     23 	m_name = (struct mixer_name *)calloc(1, sizeof(struct mixer_name));
     24 	if (!m_name)
     25 		return names;
     26 
     27 	m_name->name = strdup(name);
     28 	if (!m_name->name) {
     29 		free(m_name);
     30 		return names;
     31 	}
     32 	m_name->dir = dir;
     33 	m_name->type = type;
     34 
     35 	DL_APPEND(names, m_name);
     36 	return names;
     37 }
     38 
     39 struct mixer_name *mixer_name_add_array(struct mixer_name *names,
     40 					const char * const *name_array,
     41 					size_t name_array_size,
     42 					enum CRAS_STREAM_DIRECTION dir,
     43 					mixer_name_type type)
     44 {
     45 	size_t i;
     46 	for (i = 0; i < name_array_size; i++)
     47 		names = mixer_name_add(names, name_array[i], dir, type);
     48 	return names;
     49 }
     50 
     51 void mixer_name_free(struct mixer_name *names)
     52 {
     53 	struct mixer_name *m_name;
     54 	DL_FOREACH(names, m_name) {
     55 		DL_DELETE(names, m_name);
     56 		free((void*)m_name->name);
     57 		free(m_name);
     58 	}
     59 }
     60 
     61 struct mixer_name *mixer_name_find(struct mixer_name *names,
     62 				   const char *name,
     63 				   enum CRAS_STREAM_DIRECTION dir,
     64 				   mixer_name_type type)
     65 {
     66 	if (!name && type == MIXER_NAME_UNDEFINED)
     67 		return NULL;
     68 
     69 	struct mixer_name *m_name;
     70 	DL_FOREACH(names, m_name) {
     71 		/* Match the direction. */
     72 		if (dir != m_name->dir)
     73 			continue;
     74 		/* Match the type unless the type is UNDEFINED. */
     75 		if (type != MIXER_NAME_UNDEFINED &&
     76 		    type != m_name->type)
     77 			continue;
     78 		/* Match the name if it is non-NULL, or return the first
     79 		 * item with the correct type when the name is not defined. */
     80 		if ((type != MIXER_NAME_UNDEFINED && !name) ||
     81 		    (name && !strcmp(m_name->name, name)))
     82 			return m_name;
     83 	}
     84 	return NULL;
     85 }
     86 
     87 static const char *mixer_name_type_str(enum CRAS_STREAM_DIRECTION dir,
     88 				       mixer_name_type type)
     89 {
     90 	switch (dir) {
     91 	case CRAS_STREAM_OUTPUT:
     92 		switch (type) {
     93 		case MIXER_NAME_VOLUME:
     94 			return "output volume";
     95 		case MIXER_NAME_MAIN_VOLUME:
     96 			return "main volume";
     97 		case MIXER_NAME_UNDEFINED:
     98 			break;
     99 		}
    100 		break;
    101 	case CRAS_STREAM_INPUT:
    102 		switch (type) {
    103 		case MIXER_NAME_VOLUME:
    104 			return "input volume";
    105 		case MIXER_NAME_MAIN_VOLUME:
    106 			return "main capture";
    107 		case MIXER_NAME_UNDEFINED:
    108 			break;
    109 		}
    110 		break;
    111 	case CRAS_STREAM_UNDEFINED:
    112 	case CRAS_STREAM_POST_MIX_PRE_DSP:
    113 	case CRAS_NUM_DIRECTIONS:
    114 		break;
    115 	}
    116 	return "undefined";
    117 }
    118 
    119 void mixer_name_dump(struct mixer_name *names, const char *message)
    120 {
    121 	struct mixer_name *m_name;
    122 
    123 	if (!names) {
    124 		syslog(LOG_DEBUG, "%s: empty", message);
    125 		return;
    126 	}
    127 
    128 	syslog(LOG_DEBUG, "%s:", message);
    129 	DL_FOREACH(names, m_name) {
    130 		const char *type_str =
    131 			mixer_name_type_str(m_name->dir, m_name->type);
    132 		syslog(LOG_DEBUG, "    %s %s", m_name->name, type_str);
    133 	}
    134 }
    135