[BACK]Return to mixerctl.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / mixerctl

Diff for /src/usr.bin/mixerctl/mixerctl.c between version 1.18 and 1.19

version 1.18, 2005/01/04 18:22:09 version 1.19, 2005/02/02 08:08:33
Line 40 
Line 40 
  * mixerctl(1) - a program to control audio mixing.   * mixerctl(1) - a program to control audio mixing.
  */   */
   
 #include <stdio.h>  
 #include <stdlib.h>  
 #include <fcntl.h>  
 #include <err.h>  
 #include <unistd.h>  
 #include <string.h>  
 #include <sys/types.h>  #include <sys/types.h>
 #include <sys/ioctl.h>  #include <sys/ioctl.h>
 #include <sys/audioio.h>  #include <sys/audioio.h>
   
 char *catstr(char *p, char *q);  #include <err.h>
 struct field *findfield(char *name);  #include <fcntl.h>
 void prfield(struct field *p, char *sep, int prvalset);  #include <stdio.h>
 int rdfield(struct field *p, char *q);  #include <stdlib.h>
 int main(int argc, char **argv);  #include <string.h>
 void usage(void);  #include <unistd.h>
   
 FILE *out = stdout;  void catstr(char *, char *, char *);
   struct field *findfield(char *);
   void prfield(struct field *, char *, int);
   void rdfield(int, struct field *, char *);
   __dead void usage(void);
   
   #define FIELD_NAME_MAX  64
   
 struct field {  struct field {
         char *name;          char name[FIELD_NAME_MAX];
         mixer_ctrl_t *valp;          mixer_ctrl_t *valp;
         mixer_devinfo_t *infp;          mixer_devinfo_t *infp;
 } *fields, *rfields;  } *fields, *rfields;
Line 68 
Line 68 
 mixer_ctrl_t *values;  mixer_ctrl_t *values;
 mixer_devinfo_t *infos;  mixer_devinfo_t *infos;
   
 char *  void
 catstr(char *p, char *q)  catstr(char *p, char *q, char *out)
 {  {
         int len;          char tmp[FIELD_NAME_MAX];
         char *r;  
   
         len = strlen(p) + 1 + strlen(q) + 1;          snprintf(tmp, FIELD_NAME_MAX, "%s.%s", p, q);
         if ((r = malloc(len)) == NULL)          strlcpy(out, tmp, FIELD_NAME_MAX);
                 err(1, "malloc()");  
         strlcpy(r, p, len);  
         strlcat(r, ".", len);  
         strlcat(r, q, len);  
         return (r);  
 }  }
   
 struct field *  struct field *
 findfield(char *name)  findfield(char *name)
 {  {
         int i;          int i;
         for (i = 0; fields[i].name; i++)          for (i = 0; fields[i].name[0] != '\0'; i++)
                 if (strcmp(fields[i].name, name) == 0)                  if (strcmp(fields[i].name, name) == 0)
                         return &fields[i];                          return &fields[i];
         return (0);          return (0);
 }  }
   
   #define e_member_name   un.e.member[i].label.name
   #define s_member_name   un.s.member[i].label.name
   
 void  void
 prfield(struct field *p, char *sep, int prvalset)  prfield(struct field *p, char *sep, int prvalset)
 {  {
Line 100 
Line 97 
         int i, n;          int i, n;
   
         if (sep)          if (sep)
                 fprintf(out, "%s%s", p->name, sep);                  printf("%s%s", p->name, sep);
         m = p->valp;          m = p->valp;
         switch(m->type) {          switch (m->type) {
         case AUDIO_MIXER_ENUM:          case AUDIO_MIXER_ENUM:
                 for (i = 0; i < p->infp->un.e.num_mem; i++)                  for (i = 0; i < p->infp->un.e.num_mem; i++)
                         if (p->infp->un.e.member[i].ord == m->un.ord)                          if (p->infp->un.e.member[i].ord == m->un.ord)
                                 fprintf(out, "%s",                                  printf("%s",
                                         p->infp->un.e.member[i].label.name);                                          p->infp->e_member_name);
                 if (prvalset) {                  if (prvalset) {
                         fprintf(out, "  [ ");                          printf("  [ ");
                         for (i = 0; i < p->infp->un.e.num_mem; i++)                          for (i = 0; i < p->infp->un.e.num_mem; i++)
                                 fprintf(out, "%s ", p->infp->un.e.member[i].label.name);                                  printf("%s ", p->infp->e_member_name);
                         fprintf(out, "]");                          printf("]");
                 }                  }
                 break;                  break;
         case AUDIO_MIXER_SET:          case AUDIO_MIXER_SET:
                 for (n = i = 0; i < p->infp->un.s.num_mem; i++)                  for (n = i = 0; i < p->infp->un.s.num_mem; i++)
                         if (m->un.mask & p->infp->un.s.member[i].mask)                          if (m->un.mask & p->infp->un.s.member[i].mask)
                                 fprintf(out, "%s%s", n++ ? "," : "",                                  printf("%s%s", n++ ? "," : "",
                                         p->infp->un.s.member[i].label.name);                                                  p->infp->s_member_name);
                 if (prvalset) {                  if (prvalset) {
                         fprintf(out, "  { ");                          printf("  { ");
                         for (i = 0; i < p->infp->un.s.num_mem; i++)                          for (i = 0; i < p->infp->un.s.num_mem; i++)
                                 fprintf(out, "%s ", p->infp->un.s.member[i].label.name);                                  printf("%s ", p->infp->s_member_name);
                         fprintf(out, "}");                          printf("}");
                 }                  }
                 break;                  break;
         case AUDIO_MIXER_VALUE:          case AUDIO_MIXER_VALUE:
                 if (m->un.value.num_channels == 1)                  if (m->un.value.num_channels == 1)
                         fprintf(out, "%d", m->un.value.level[0]);                          printf("%d", m->un.value.level[0]);
                 else                  else
                         fprintf(out, "%d,%d", m->un.value.level[0],                          printf("%d,%d", m->un.value.level[0],
                                m->un.value.level[1]);                                 m->un.value.level[1]);
                 if (prvalset)                  if (prvalset)
                         fprintf(out, " %s", p->infp->un.v.units.name);                          printf(" %s", p->infp->un.v.units.name);
                 break;                  break;
         default:          default:
                 errx(1, "Invalid format.");                  errx(1, "Invalid format.");
         }          }
 }  }
   
 int  void
 rdfield(struct field *p, char *q)  rdfield(int fd, struct field *p, char *q)
 {  {
         mixer_ctrl_t *m;          mixer_ctrl_t *m, oldval;
         int v, v0, v1, mask;          int v, v0, v1, mask;
         int i;          int i;
         char *s;          char *s;
   
           oldval = *p->valp;
         m = p->valp;          m = p->valp;
         switch(m->type) {  
           switch (m->type) {
         case AUDIO_MIXER_ENUM:          case AUDIO_MIXER_ENUM:
                 for (i = 0; i < p->infp->un.e.num_mem; i++)                  for (i = 0; i < p->infp->un.e.num_mem; i++)
                         if (strcmp(p->infp->un.e.member[i].label.name, q) == 0)                          if (strcmp(p->infp->e_member_name, q) == 0)
                                 break;                                  break;
                 if (i < p->infp->un.e.num_mem)                  if (i < p->infp->un.e.num_mem)
                         m->un.ord = p->infp->un.e.member[i].ord;                          m->un.ord = p->infp->un.e.member[i].ord;
Line 163 
Line 162 
         case AUDIO_MIXER_SET:          case AUDIO_MIXER_SET:
                 mask = 0;                  mask = 0;
                 for (v = 0; q && *q; q = s) {                  for (v = 0; q && *q; q = s) {
                         if (s = strchr(q, ','))                          if ((s = strchr(q, ',')) != NULL)
                                 *s++ = 0;                                  *s++ = 0;
                         for (i = 0; i < p->infp->un.s.num_mem; i++)                          for (i = 0; i < p->infp->un.s.num_mem; i++)
                                 if (strcmp(p->infp->un.s.member[i].label.name, q) == 0)                                  if (strcmp(p->infp->s_member_name, q) == 0)
                                         break;                                          break;
                         if (i < p->infp->un.s.num_mem)                          if (i < p->infp->un.s.num_mem)
                                 mask |= p->infp->un.s.member[i].mask;                                  mask |= p->infp->un.s.member[i].mask;
Line 229 
Line 228 
         default:          default:
                 errx(1, "Invalid format.");                  errx(1, "Invalid format.");
         }          }
         return (1);  
           if (ioctl(fd, AUDIO_MIXER_WRITE, p->valp) < 0) {
                   warn("AUDIO_MIXER_WRITE");
           } else {
                   *p->valp = oldval;
                   prfield(p, ": ", 0);
                   if (ioctl(fd, AUDIO_MIXER_READ, p->valp) < 0) {
                           warn("AUDIO_MIXER_READ");
                   } else {
                           printf(" -> ");
                           prfield(p, NULL, 0);
                           printf("\n");
                   }
           }
 }  }
   
 int  int
Line 240 
Line 252 
         char *file;          char *file;
         char *sep = "=";          char *sep = "=";
         mixer_devinfo_t dinfo;          mixer_devinfo_t dinfo;
         mixer_ctrl_t val;  
         int ndev;          int ndev;
   
         if ((file = getenv("MIXERDEVICE")) == 0 || *file == '\0')          if ((file = getenv("MIXERDEVICE")) == 0 || *file == '\0')
Line 296 
Line 307 
         for (i = 0; i < ndev; i++) {          for (i = 0; i < ndev; i++) {
                 infos[i].index = i;                  infos[i].index = i;
                 if (ioctl(fd, AUDIO_MIXER_DEVINFO, &infos[i]) < 0) {                  if (ioctl(fd, AUDIO_MIXER_DEVINFO, &infos[i]) < 0) {
                         ndev--, i--;                          ndev--;
                           i--;
                         continue;                          continue;
                 }                  }
         }          }
   
         for (i = 0; i < ndev; i++) {          for (i = 0; i < ndev; i++) {
                 rfields[i].name = infos[i].label.name;                  strlcpy(rfields[i].name, infos[i].label.name, FIELD_NAME_MAX);
                 rfields[i].valp = &values[i];                  rfields[i].valp = &values[i];
                 rfields[i].infp = &infos[i];                  rfields[i].infp = &infos[i];
         }          }
Line 327 
Line 339 
                         for (pos = infos[i].next; pos != AUDIO_MIXER_LAST;                          for (pos = infos[i].next; pos != AUDIO_MIXER_LAST;
                             pos = infos[pos].next) {                              pos = infos[pos].next) {
                                 fields[j] = rfields[pos];                                  fields[j] = rfields[pos];
                                 fields[j].name = catstr(rfields[i].name,                                  catstr(rfields[i].name, infos[pos].label.name,
                                                         infos[pos].label.name);                                      fields[j].name);
                                 infos[pos].type = -1;                                  infos[pos].type = -1;
                                 j++;                                  j++;
                         }                          }
Line 338 
Line 350 
         for (i = 0; i < j; i++) {          for (i = 0; i < j; i++) {
                 int cls = fields[i].infp->mixer_class;                  int cls = fields[i].infp->mixer_class;
                 if (cls >= 0 && cls < ndev)                  if (cls >= 0 && cls < ndev)
                         fields[i].name = catstr(infos[cls].label.name,                          catstr(infos[cls].label.name, fields[i].name,
                                                 fields[i].name);                              fields[i].name);
         }          }
   
         if (!argc && aflag) {          if (!argc && aflag) {
                 for (i = 0; fields[i].name; i++) {                  for (i = 0; fields[i].name[0] != '\0'; i++) {
                         prfield(&fields[i], sep, vflag);                          prfield(&fields[i], sep, vflag);
                         fprintf(out, "\n");                          printf("\n");
                 }                  }
         } else if (argc > 0 && !aflag) {          } else if (argc > 0 && !aflag) {
                 struct field *p;                  struct field *p;
   
                 while(argc--) {                  while (argc--) {
                         char *q;                          char *q;
   
                         if (q = strchr(*argv, '=')) {                          ch = 0;
                                 *q++ = 0;                          if ((q = strchr(*argv, '=')) != NULL) {
                                 p = findfield(*argv);                                  *q++ = '\0';
                                 if (p == NULL)                                  ch = 1;
                                         warnx("field %s does not exist", *argv);                          }
                                 else {  
                                         val = *p->valp;                          if ((p = findfield(*argv)) == NULL) {
                                         if (rdfield(p, q)) {                                  warnx("field %s does not exist", *argv);
                                                 if (ioctl(fd, AUDIO_MIXER_WRITE, p->valp) < 0)                          } else if (ch) {
                                                         warn("AUDIO_MIXER_WRITE");                                  rdfield(fd, p, q);
                                                 else if (sep && !qflag) {  
                                                         *p->valp = val;  
                                                         prfield(p, ": ", 0);  
                                                         ioctl(fd, AUDIO_MIXER_READ, p->valp);  
                                                         printf(" -> ");  
                                                         prfield(p, 0, 0);  
                                                         printf("\n");  
                                                 }  
                                         }  
                                 }  
                         } else {                          } else {
                                 p = findfield(*argv);                                  prfield(p, sep, vflag);
                                 if (p == NULL)                                  printf("\n");
                                         warnx("field %s does not exist", *argv);  
                                 else {  
                                         prfield(p, sep, vflag);  
                                         fprintf(out, "\n");  
                                 }  
                         }                          }
   
                         argv++;                          argv++;
                 }                  }
         } else          } else
Line 389 
Line 387 
         exit(0);          exit(0);
 }  }
   
 void  __dead void
 usage(void)  usage(void)
 {  {
         extern char *__progname;        /* from crt0.o */          extern char *__progname;        /* from crt0.o */

Legend:
Removed from v.1.18  
changed lines
  Added in v.1.19