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

Diff for /src/usr.bin/sndiod/dev.c between version 1.91 and 1.92

version 1.91, 2021/03/02 12:15:46 version 1.92, 2021/03/03 10:00:27
Line 106 
Line 106 
         zomb_exit          zomb_exit
 };  };
   
   struct ctl *ctl_list = NULL;
 struct dev *dev_list = NULL;  struct dev *dev_list = NULL;
 unsigned int dev_sndnum = 0;  unsigned int dev_sndnum = 0;
   
Line 370 
Line 371 
                 master = d->master;                  master = d->master;
         else {          else {
                 master = 0;                  master = 0;
                 for (c = d->ctl_list; c != NULL; c = c->next) {                  for (c = ctl_list; c != NULL; c = c->next) {
                         if (c->type != CTL_NUM ||                          if (c->type != CTL_NUM ||
                             strcmp(c->group, "") != 0 ||                              strcmp(c->group, d->name) != 0 ||
                             strcmp(c->node0.name, "output") != 0 ||                              strcmp(c->node0.name, "output") != 0 ||
                             strcmp(c->func, "level") != 0)                              strcmp(c->func, "level") != 0)
                                 continue;                                  continue;
                           if (c->u.any.arg0 != d)
                                   continue;
                         v = (c->curval * 127 + c->maxval / 2) / c->maxval;                          v = (c->curval * 127 + c->maxval / 2) / c->maxval;
                         if (master < v)                          if (master < v)
                                 master = v;                                  master = v;
Line 465 
Line 468 
                     slot_array[chan].opt->dev != d)                      slot_array[chan].opt->dev != d)
                         return;                          return;
                 slot_setvol(slot_array + chan, msg[2]);                  slot_setvol(slot_array + chan, msg[2]);
                 dev_onval(d, CTLADDR_SLOT_LEVEL(chan), msg[2]);                  ctl_onval(CTL_SLOT_LEVEL, slot_array + chan, NULL, msg[2]);
                 return;                  return;
         }          }
         x = (struct sysex *)msg;          x = (struct sysex *)msg;
Line 479 
Line 482 
                         if (len == SYSEX_SIZE(master)) {                          if (len == SYSEX_SIZE(master)) {
                                 dev_master(d, x->u.master.coarse);                                  dev_master(d, x->u.master.coarse);
                                 if (d->master_enabled) {                                  if (d->master_enabled) {
                                         dev_onval(d, CTLADDR_MASTER,                                          ctl_onval(CTL_DEV_MASTER, d, NULL,
                                            x->u.master.coarse);                                             x->u.master.coarse);
                                 }                                  }
                         }                          }
Line 1005 
Line 1008 
                 if (d->mode & MODE_PLAY)                  if (d->mode & MODE_PLAY)
                         dev_mix_adjvol(d);                          dev_mix_adjvol(d);
         } else {          } else {
                 for (c = d->ctl_list; c != NULL; c = c->next) {                  for (c = ctl_list; c != NULL; c = c->next) {
                           if (c->scope != CTL_HW || c->u.hw.dev != d)
                                   continue;
                         if (c->type != CTL_NUM ||                          if (c->type != CTL_NUM ||
                             strcmp(c->group, "") != 0 ||                              strcmp(c->group, d->name) != 0 ||
                             strcmp(c->node0.name, "output") != 0 ||                              strcmp(c->node0.name, "output") != 0 ||
                             strcmp(c->func, "level") != 0)                              strcmp(c->func, "level") != 0)
                                 continue;                                  continue;
                         v = (master * c->maxval + 64) / 127;                          v = (master * c->maxval + 64) / 127;
                         dev_setctl(d, c->addr, v);                          ctl_setval(c, v);
                 }                  }
         }          }
 }  }
Line 1070 
Line 1075 
         d->master = MIDI_MAXCTL;          d->master = MIDI_MAXCTL;
         d->mtc.origin = 0;          d->mtc.origin = 0;
         d->tstate = MMC_STOP;          d->tstate = MMC_STOP;
         d->ctl_list = NULL;          snprintf(d->name, CTL_NAMEMAX, "%u", d->num);
         d->next = dev_list;          d->next = dev_list;
         dev_list = d;          dev_list = d;
         return d;          return d;
Line 1216 
Line 1221 
 int  int
 dev_open(struct dev *d)  dev_open(struct dev *d)
 {  {
         int i;  
         char name[CTL_NAMEMAX];          char name[CTL_NAMEMAX];
         struct dev_alt *a;          struct dev_alt *a;
         struct slot *s;  
   
         d->master_enabled = 0;          d->master_enabled = 0;
         d->mode = d->reqmode;          d->mode = d->reqmode;
Line 1243 
Line 1246 
         if (!dev_allocbufs(d))          if (!dev_allocbufs(d))
                 return 0;                  return 0;
   
         for (i = 0, s = slot_array; i < DEV_NSLOT; i++, s++) {  
                 if (s->opt == NULL || s->opt->dev != d || s->name[0] == 0)  
                         continue;  
                 slot_ctlname(s, name, CTL_NAMEMAX);  
                 dev_addctl(d, "app", CTL_NUM,  
                     CTLADDR_SLOT_LEVEL(i),  
                     name, -1, "level",  
                     NULL, -1, 127, s->vol);  
         }  
   
         /* if there are multiple alt devs, add server.device knob */          /* if there are multiple alt devs, add server.device knob */
         if (d->alt_list->next != NULL) {          if (d->alt_list->next != NULL) {
                 for (a = d->alt_list; a != NULL; a = a->next) {                  for (a = d->alt_list; a != NULL; a = a->next) {
                         snprintf(name, sizeof(name), "%d", a->idx);                          snprintf(name, sizeof(name), "%d", a->idx);
                         dev_addctl(d, "", CTL_SEL,                          ctl_new(CTL_DEV_ALT, d, &a->idx,
                             CTLADDR_ALT_SEL + a->idx,                              CTL_SEL, d->name, "server", -1, "device",
                             "server", -1, "device",  
                             name, -1, 1, a->idx == d->alt_num);                              name, -1, 1, a->idx == d->alt_num);
                 }                  }
         }          }
Line 1334 
Line 1326 
 void  void
 dev_close(struct dev *d)  dev_close(struct dev *d)
 {  {
         struct ctl *c;          struct dev_alt *a;
           unsigned int idx;
   
         d->pstate = DEV_CFG;          d->pstate = DEV_CFG;
         dev_sio_close(d);          dev_sio_close(d);
         dev_freebufs(d);          dev_freebufs(d);
   
         /* there are no clients, just free remaining local controls */          if (d->master_enabled) {
         while ((c = d->ctl_list) != NULL) {                  d->master_enabled = 0;
                 d->ctl_list = c->next;                  ctl_del(CTL_DEV_MASTER, d, NULL);
                 xfree(c);  
         }          }
           for (idx = 0, a = d->alt_list; a != NULL; idx++, a = a->next)
                   ctl_del(CTL_DEV_ALT, d, &idx);
 }  }
   
 /*  /*
Line 2325 
Line 2319 
                 return NULL;                  return NULL;
         s->ops = ops;          s->ops = ops;
         s->arg = arg;          s->arg = arg;
         for (c = o->dev->ctl_list; c != NULL; c = c->next)          for (c = ctl_list; c != NULL; c = c->next) {
                   if (!ctlslot_visible(s, c))
                           continue;
                 c->refs_mask |= s->self;                  c->refs_mask |= s->self;
           }
         return s;          return s;
 }  }
   
Line 2338 
Line 2335 
 {  {
         struct ctl *c, **pc;          struct ctl *c, **pc;
   
         pc = &s->opt->dev->ctl_list;          pc = &ctl_list;
         while ((c = *pc) != NULL) {          while ((c = *pc) != NULL) {
                 c->refs_mask &= ~s->self;                  c->refs_mask &= ~s->self;
                 if (c->refs_mask == 0) {                  if (c->refs_mask == 0) {
Line 2351 
Line 2348 
         dev_unref(s->opt->dev);          dev_unref(s->opt->dev);
 }  }
   
   int
   ctlslot_visible(struct ctlslot *s, struct ctl *c)
   {
           if (s->opt == NULL)
                   return 1;
           switch (c->scope) {
           case CTL_HW:
           case CTL_DEV_MASTER:
           case CTL_DEV_ALT:
                   return (s->opt->dev == c->u.any.arg0);
           case CTL_SLOT_LEVEL:
                   return (s->opt->dev == c->u.slot_level.slot->opt->dev);
           default:
                   return 0;
           }
   }
   
   struct ctl *
   ctlslot_lookup(struct ctlslot *s, int addr)
   {
           struct ctl *c;
   
           c = ctl_list;
           while (1) {
                   if (c == NULL)
                           return NULL;
                   if (c->type != CTL_NONE && c->addr == addr)
                           break;
                   c = c->next;
           }
           if (!ctlslot_visible(s, c))
                   return NULL;
           return c;
   }
   
 void  void
 ctl_node_log(struct ctl_node *c)  ctl_node_log(struct ctl_node *c)
 {  {
Line 2387 
Line 2419 
         }          }
         log_puts(" at ");          log_puts(" at ");
         log_putu(c->addr);          log_putu(c->addr);
           log_puts(" -> ");
           switch (c->scope) {
           case CTL_HW:
                   log_puts("hw:");
                   log_puts(c->u.hw.dev->name);
                   log_puts("/");
                   log_putu(c->u.hw.addr);
                   break;
           case CTL_DEV_MASTER:
                   log_puts("dev_master:");
                   log_puts(c->u.dev_master.dev->name);
                   break;
           case CTL_DEV_ALT:
                   log_puts("dev_alt:");
                   log_puts(c->u.dev_alt.dev->name);
                   log_putu(c->u.dev_alt.idx);
                   break;
           case CTL_SLOT_LEVEL:
                   log_puts("slot_level:");
                   log_puts(c->u.slot_level.slot->name);
                   log_putu(c->u.slot_level.slot->unit);
                   break;
           default:
                   log_puts("unknown");
           }
 }  }
   
   int
   ctl_setval(struct ctl *c, int val)
   {
           if (c->curval == val) {
                   if (log_level >= 3) {
                           ctl_log(c);
                           log_puts(": already set\n");
                   }
                   return 1;
           }
           if (val < 0 || val > c->maxval) {
                   if (log_level >= 3) {
                           log_putu(val);
                           log_puts(": ctl val out of bounds\n");
                   }
                   return 0;
           }
   
           switch (c->scope) {
           case CTL_HW:
                   if (log_level >= 3) {
                           ctl_log(c);
                           log_puts(": marked as dirty\n");
                   }
                   c->curval = val;
                   c->dirty = 1;
                   return dev_ref(c->u.hw.dev);
           case CTL_DEV_MASTER:
                   if (!c->u.dev_master.dev->master_enabled)
                           return 1;
                   dev_master(c->u.dev_master.dev, val);
                   dev_midi_master(c->u.dev_master.dev);
                   c->val_mask = ~0U;
                   c->curval = val;
                   return 1;
           case CTL_DEV_ALT:
                   dev_setalt (c->u.dev_alt.dev, c->u.dev_alt.idx);
                   return 1;
           case CTL_SLOT_LEVEL:
                   slot_setvol(c->u.slot_level.slot, val);
                   // XXX change dev_midi_vol() into slot_midi_vol()
                   dev_midi_vol(c->u.slot_level.slot->opt->dev, c->u.slot_level.slot);
                   c->val_mask = ~0U;
                   c->curval = val;
                   return 1;
           default:
                   if (log_level >= 2) {
                           ctl_log(c);
                           log_puts(": not writable\n");
                   }
                   return 1;
           }
   }
   
 /*  /*
  * add a ctl   * add a ctl
  */   */
 struct ctl *  struct ctl *
 dev_addctl(struct dev *d, char *gstr, int type, int addr,  ctl_new(int scope, void *arg0, void *arg1,
     char *str0, int unit0, char *func, char *str1, int unit1, int maxval, int val)      int type, char *gstr,
       char *str0, int unit0, char *func,
       char *str1, int unit1, int maxval, int val)
 {  {
         struct ctl *c, **pc;          struct ctl *c, **pc;
           struct ctlslot *s;
           int addr;
         int i;          int i;
   
           /*
            * find the smallest unused addr number and
            * the last position in the list
            */
           addr = 0;
           for (pc = &ctl_list; (c = *pc) != NULL; pc = &c->next) {
                   if (c->addr > addr)
                           addr = c->addr;
           }
           addr++;
   
         c = xmalloc(sizeof(struct ctl));          c = xmalloc(sizeof(struct ctl));
         c->type = type;          c->type = type;
         strlcpy(c->func, func, CTL_NAMEMAX);          strlcpy(c->func, func, CTL_NAMEMAX);
Line 2410 
Line 2536 
                 c->node1.unit = unit1;                  c->node1.unit = unit1;
         } else          } else
                 memset(&c->node1, 0, sizeof(struct ctl_node));                  memset(&c->node1, 0, sizeof(struct ctl_node));
           c->scope = scope;
           c->u.any.arg0 = arg0;
           switch (scope) {
           case CTL_HW:
                   c->u.hw.addr = *(unsigned int *)arg1;
                   break;
           case CTL_DEV_ALT:
                   c->u.dev_alt.idx = *(unsigned int *)arg1;
                   break;
           default:
                   c->u.any.arg1 = NULL;
           }
         c->addr = addr;          c->addr = addr;
         c->maxval = maxval;          c->maxval = maxval;
         c->val_mask = ~0;          c->val_mask = ~0;
         c->desc_mask = ~0;          c->desc_mask = ~0;
         c->curval = val;          c->curval = val;
         c->dirty = 0;          c->dirty = 0;
         c->refs_mask = 0;          c->refs_mask = CTL_DEVMASK;
         for (i = 0; i < DEV_NCTLSLOT; i++) {          for (s = ctlslot_array, i = 0; i < DEV_NCTLSLOT; i++, s++) {
                 c->refs_mask |= CTL_DEVMASK;                  if (s->ops == NULL)
                 if (ctlslot_array[i].ops != NULL)                          continue;
                   if (ctlslot_visible(s, c))
                         c->refs_mask |= 1 << i;                          c->refs_mask |= 1 << i;
         }          }
         for (pc = &d->ctl_list; *pc != NULL; pc = &(*pc)->next)          c->next = *pc;
                 ; /* nothing */  
         c->next = NULL;  
         *pc = c;          *pc = c;
 #ifdef DEBUG  #ifdef DEBUG
         if (log_level >= 3) {          if (log_level >= 2) {
                 dev_log(d);  
                 log_puts(": adding ");  
                 ctl_log(c);                  ctl_log(c);
                 log_puts("\n");                  log_puts(": added\n");
         }          }
 #endif  #endif
         return c;          return c;
 }  }
   
 void  void
 dev_rmctl(struct dev *d, int addr)  ctl_update(struct ctl *c)
 {  {
           struct ctlslot *s;
           unsigned int refs_mask;
           int i;
   
           for (s = ctlslot_array, i = 0; i < DEV_NCTLSLOT; i++, s++) {
                   if (s->ops == NULL)
                           continue;
                   refs_mask = ctlslot_visible(s, c) ? s->self : 0;
   
                   /* nothing to do if no visibility change */
                   if (((c->refs_mask & s->self) ^ refs_mask) == 0)
                           continue;
                   /* if control becomes visble */
                   if (refs_mask)
                           c->refs_mask |= s->self;
                   /* if control is hidden */
                   c->desc_mask |= s->self;
           }
   }
   
   int
   ctl_match(struct ctl *c, int scope, void *arg0, void *arg1)
   {
           if (c->type == CTL_NONE || c->scope != scope || c->u.any.arg0 != arg0)
                   return 0;
           if (arg0 != NULL && c->u.any.arg0 != arg0)
                   return 0;
           switch (scope) {
           case CTL_HW:
                   if (arg1 != NULL && c->u.hw.addr != *(unsigned int *)arg1)
                           return 0;
                   break;
           case CTL_DEV_ALT:
                   if (arg1 != NULL && c->u.dev_alt.idx != *(unsigned int *)arg1)
                           return 0;
                   break;
           }
           return 1;
   }
   
   struct ctl *
   ctl_find(int scope, void *arg0, void *arg1)
   {
           struct ctl *c;
   
           for (c = ctl_list; c != NULL; c = c->next) {
                   if (ctl_match(c, scope, arg0, arg1))
                           return c;
           }
           return NULL;
   }
   
   int
   ctl_onval(int scope, void *arg0, void *arg1, int val)
   {
           struct ctl *c;
   
           c = ctl_find(scope, arg0, arg1);
           if (c == NULL)
                   return 0;
           c->curval = val;
           c->val_mask = ~0U;
           return 1;
   }
   
   void
   ctl_del(int scope, void *arg0, void *arg1)
   {
         struct ctl *c, **pc;          struct ctl *c, **pc;
   
         pc = &d->ctl_list;          pc = &ctl_list;
         for (;;) {          for (;;) {
                 c = *pc;                  c = *pc;
                 if (c == NULL)                  if (c == NULL)
                         return;                          return;
                 if (c->type != CTL_NONE && c->addr == addr)                  if (ctl_match(c, scope, arg0, arg1)) {
                         break;  
                 pc = &c->next;  
         }  
         c->type = CTL_NONE;  
 #ifdef DEBUG  #ifdef DEBUG
         if (log_level >= 3) {                          if (log_level >= 2) {
                 dev_log(d);                                  ctl_log(c);
                 log_puts(": removing ");                                  log_puts(": removed\n");
                 ctl_log(c);                          }
                 log_puts(", refs_mask = 0x");  
                 log_putx(c->refs_mask);  
                 log_puts("\n");  
         }  
 #endif  #endif
         c->refs_mask &= ~CTL_DEVMASK;                          c->refs_mask &= ~CTL_DEVMASK;
         if (c->refs_mask == 0) {                          if (c->refs_mask == 0) {
                 *pc = c->next;                                  *pc = c->next;
                 xfree(c);                                  xfree(c);
                 return;                                  continue;
                           }
                           c->type = CTL_NONE;
                           c->desc_mask = ~0;
                   }
                   pc = &c->next;
         }          }
         c->desc_mask = ~0;  
 }  }
   
 void  void
Line 2479 
Line 2678 
         int found, i;          int found, i;
   
         found = 0;          found = 0;
         for (c = d->ctl_list; c != NULL; c = c->next) {          for (c = ctl_list; c != NULL; c = c->next) {
                 if (c->addr != CTLADDR_MASTER &&                  if (c->scope == CTL_HW &&
                       c->u.hw.dev == d &&
                     c->type == CTL_NUM &&                      c->type == CTL_NUM &&
                     strcmp(c->group, "") == 0 &&                      strcmp(c->group, d->name) == 0 &&
                     strcmp(c->node0.name, "output") == 0 &&                      strcmp(c->node0.name, "output") == 0 &&
                     strcmp(c->func, "level") == 0)                      strcmp(c->func, "level") == 0)
                         found = 1;                          found = 1;
Line 2494 
Line 2694 
                         log_puts(": software master level control disabled\n");                          log_puts(": software master level control disabled\n");
                 }                  }
                 d->master_enabled = 0;                  d->master_enabled = 0;
                 dev_rmctl(d, CTLADDR_MASTER);                  ctl_del(CTL_DEV_MASTER, d, NULL);
         } else if (!d->master_enabled && !found) {          } else if (!d->master_enabled && !found) {
                 if (log_level >= 2) {                  if (log_level >= 2) {
                         dev_log(d);                          dev_log(d);
                         log_puts(": software master level control enabled\n");                          log_puts(": software master level control enabled\n");
                 }                  }
                 d->master_enabled = 1;                  d->master_enabled = 1;
                 dev_addctl(d, "", CTL_NUM, CTLADDR_MASTER,                  ctl_new(CTL_DEV_MASTER, d, NULL,
                     "output", -1, "level", NULL, -1, 127, d->master);                      CTL_NUM, d->name, "output", -1, "level",
                       NULL, -1, 127, d->master);
         }          }
   
         for (s = ctlslot_array, i = DEV_NCTLSLOT; i > 0; i--, s++) {          for (s = ctlslot_array, i = DEV_NCTLSLOT; i > 0; i--, s++) {
Line 2511 
Line 2712 
         }          }
 }  }
   
 int  
 dev_setctl(struct dev *d, int addr, int val)  
 {  
         struct ctl *c;  
         struct slot *s;  
         int num;  
   
         c = d->ctl_list;  
         for (;;) {  
                 if (c == NULL) {  
                         if (log_level >= 3) {  
                                 dev_log(d);  
                                 log_puts(": ");  
                                 log_putu(addr);  
                                 log_puts(": no such ctl address\n");  
                         }  
                         return 0;  
                 }  
                 if (c->type != CTL_NONE && c->addr == addr)  
                         break;  
                 c = c->next;  
         }  
         if (c->curval == val) {  
                 if (log_level >= 3) {  
                         ctl_log(c);  
                         log_puts(": already set\n");  
                 }  
                 return 1;  
         }  
         if (val < 0 || val > c->maxval) {  
                 if (log_level >= 3) {  
                         dev_log(d);  
                         log_puts(": ");  
                         log_putu(val);  
                         log_puts(": ctl val out of bounds\n");  
                 }  
                 return 0;  
         }  
         if (addr >= CTLADDR_END) {  
                 if (log_level >= 3) {  
                         ctl_log(c);  
                         log_puts(": marked as dirty\n");  
                 }  
                 c->dirty = 1;  
                 dev_ref(d);  
         } else {  
                 if (addr >= CTLADDR_ALT_SEL) {  
                         if (val) {  
                                 num = addr - CTLADDR_ALT_SEL;  
                                 dev_setalt(d, num);  
                         }  
                         return 1;  
                 } else if (addr == CTLADDR_MASTER) {  
                         if (d->master_enabled) {  
                                 dev_master(d, val);  
                                 dev_midi_master(d);  
                         }  
                 } else {  
                         num = addr - CTLADDR_SLOT_LEVEL(0);  
                         s = slot_array + num;  
                         if (s->opt->dev != d)  
                                 return 1;  
                         slot_setvol(s, val);  
                         dev_midi_vol(d, s);  
                 }  
                 c->val_mask = ~0U;  
         }  
         c->curval = val;  
         return 1;  
 }  
   
 int  
 dev_onval(struct dev *d, int addr, int val)  
 {  
         struct ctl *c;  
   
         c = d->ctl_list;  
         for (;;) {  
                 if (c == NULL)  
                         return 0;  
                 if (c->type != CTL_NONE && c->addr == addr)  
                         break;  
                 c = c->next;  
         }  
         c->curval = val;  
         c->val_mask = ~0U;  
         return 1;  
 }  
   
 void  void
 dev_label(struct dev *d, int i)  dev_label(struct dev *d, int i)
 {  {
Line 2608 
Line 2720 
   
         slot_ctlname(&slot_array[i], name, CTL_NAMEMAX);          slot_ctlname(&slot_array[i], name, CTL_NAMEMAX);
   
         c = d->ctl_list;          c = ctl_list;
         for (;;) {          for (;;) {
                 if (c == NULL) {                  if (c == NULL) {
                         dev_addctl(d, "app", CTL_NUM,                          ctl_new(CTL_SLOT_LEVEL, slot_array + i, NULL,
                             CTLADDR_SLOT_LEVEL(i),                              CTL_NUM, "app", name, -1, "level",
                             name, -1, "level",  
                             NULL, -1, 127, slot_array[i].vol);                              NULL, -1, 127, slot_array[i].vol);
                         return;                          return;
                 }                  }
                 if (c->addr == CTLADDR_SLOT_LEVEL(i))                  if (ctl_match(c, CTL_SLOT_LEVEL, slot_array + i, NULL))
                         break;                          break;
                 c = c->next;                  c = c->next;
         }          }

Legend:
Removed from v.1.91  
changed lines
  Added in v.1.92