]> git.alsa-project.org Git - alsa-utils.git/commitdiff
amixer - added basic TLV support (read only) for 'amixer controls'
authorJaroslav Kysela <perex@perex.cz>
Wed, 5 Jul 2006 15:46:10 +0000 (17:46 +0200)
committerJaroslav Kysela <perex@perex.cz>
Wed, 5 Jul 2006 15:46:10 +0000 (17:46 +0200)
amixer/amixer.c
configure.in

index 39f95825f252ed7ac5318d4aad4916d75ca99f5f..41fea08284c18786b6103f6879121b680c38ebf6 100644 (file)
@@ -154,6 +154,9 @@ static const char *control_access(snd_ctl_elem_info_t *info)
        *res++ = snd_ctl_elem_info_is_inactive(info) ? 'i' : '-';
        *res++ = snd_ctl_elem_info_is_volatile(info) ? 'v' : '-';
        *res++ = snd_ctl_elem_info_is_locked(info) ? 'l' : '-';
+       *res++ = snd_ctl_elem_info_is_tlv_readable(info) ? 'R' : '-';
+       *res++ = snd_ctl_elem_info_is_tlv_writable(info) ? 'W' : '-';
+       *res++ = snd_ctl_elem_info_is_tlv_commandable(info) ? 'C' : '-';
        *res++ = '\0';
        return result;
 }
@@ -378,12 +381,80 @@ static void show_control_id(snd_ctl_elem_id_t *id)
                printf(",subdevice=%i", subdevice);
 }
 
+static void print_spaces(unsigned int spaces)
+{
+       while (spaces-- > 0)
+               putc(' ', stdout);
+}
+
+static void print_dB(int dB)
+{
+       printf("%i.%02idB", dB / 100, dB % 100);
+}
+
+static void decode_tlv(unsigned int spaces, unsigned int *tlv, unsigned int tlv_size)
+{
+       unsigned int type = tlv[0];
+       unsigned int size;
+       unsigned int idx = 0;
+       
+       if (tlv_size < 2 * sizeof(unsigned int)) {
+               printf("TLV size error!\n");
+               return;
+       }
+       print_spaces(spaces);
+       printf("| ");
+       type = tlv[idx++];
+       size = tlv[idx++];
+       tlv_size -= 2 * sizeof(unsigned int);
+       if (size > tlv_size) {
+               printf("TLV size error (%i, %i, %i)!\n", type, size, tlv_size);
+               return;
+       }
+       switch (type) {
+       case SND_CTL_TLVT_CONTAINER:
+               size += sizeof(unsigned int) -1;
+               size /= sizeof(unsigned int);
+               while (idx < size) {
+                       if (tlv[idx+1] > (size - idx) * sizeof(unsigned int)) {
+                               printf("TLV size error in compound!\n");
+                               return;
+                       }
+                       decode_tlv(spaces + 2, tlv + idx, tlv[idx+1]);
+                       idx += 2 + (tlv[1] + sizeof(unsigned int) - 1) / sizeof(unsigned int);
+               }
+               break;
+       case SND_CTL_TLVT_DB_SCALE:
+               printf("dBscale-");
+               if (size != 2 * sizeof(unsigned int)) {
+                       while (size > 0) {
+                               printf("0x%x", tlv[idx++]);
+                               size -= sizeof(unsigned int);
+                       }
+               } else {
+                       printf("min=");
+                       print_dB(tlv[2]);
+                       printf(",step=");
+                       print_dB(tlv[3] & 0xffff);
+                       printf(",mute=%i", (tlv[3] >> 16) & 1);
+               }
+               break;
+       default:
+               printf("unk-%i-", type);
+               while (size > 0) {
+                       printf("0x%x", tlv[idx++]);
+                       size -= sizeof(unsigned int);
+               }
+               break;
+       }
+       putc('\n', stdout);
+}
+
 static int show_control(const char *space, snd_hctl_elem_t *elem,
                        int level)
 {
        int err;
-       unsigned int item, idx;
-       unsigned int count;
+       unsigned int item, idx, count, *tlv;
        snd_ctl_elem_type_t type;
        snd_ctl_elem_id_t *id;
        snd_ctl_elem_info_t *info;
@@ -465,7 +536,18 @@ static int show_control(const char *space, snd_hctl_elem_t *elem,
                        }
                }
                printf("\n");
+               if (!snd_ctl_elem_info_is_tlv_readable(info))
+                       goto __skip_tlv;
+               tlv = malloc(4096);
+               if ((err = snd_hctl_elem_tlv_read(elem, tlv, 4096)) < 0) {
+                       error("Control %s element TLV read error: %s\n", card, snd_strerror(err));
+                       free(tlv);
+                       return err;
+               }
+               decode_tlv(strlen(space), tlv, 4096);
+               free(tlv);
        }
+      __skip_tlv:
        return 0;
 }
 
index a475075f4e750f3ee93adfa41f6069e65c2573d8..fdecfa1bfdfc63502bc8e33f0fdefc3bca37e0d6 100644 (file)
@@ -27,7 +27,7 @@ AC_PROG_CC
 dnl AC_PROG_CXX
 AC_PROG_INSTALL
 AC_PROG_LN_S
-AM_PATH_ALSA(1.0.9)
+AM_PATH_ALSA(1.0.12)
 
 AC_ARG_ENABLE(alsamixer,
      [  --disable-alsamixer     Disable alsamixer compilation],