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

Diff for /src/usr.bin/aucat/Attic/sock.c between version 1.41 and 1.42

version 1.41, 2010/04/03 17:59:17 version 1.42, 2010/04/06 20:07:01
Line 14 
Line 14 
  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF   * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.   * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */   */
 /*  
  * TODO:  
  *  
  *      change f->bufsz to contain only socket-side buffer,  
  *      because it's less error prone  
  */  
   
 #include <stdio.h>  #include <stdio.h>
 #include <stdlib.h>  #include <stdlib.h>
Line 36 
Line 30 
 #include "dbg.h"  #include "dbg.h"
 #endif  #endif
   
 int sock_attach(struct sock *, int);  void sock_attach(struct sock *, int);
 int sock_read(struct sock *);  int sock_read(struct sock *);
 int sock_write(struct sock *);  int sock_write(struct sock *);
 int sock_execmsg(struct sock *);  int sock_execmsg(struct sock *);
Line 59 
Line 53 
 void  void
 sock_dbg(struct sock *f)  sock_dbg(struct sock *f)
 {  {
         static char *pstates[] = { "hel", "ini", "sta", "run", "mid" };          static char *pstates[] = { "hel", "ini", "sta", "rdy", "run", "mid" };
         static char *rstates[] = { "rdat", "rmsg", "rret" };          static char *rstates[] = { "rdat", "rmsg", "rret" };
         static char *wstates[] = { "widl", "wmsg", "wdat" };          static char *wstates[] = { "widl", "wmsg", "wdat" };
   
         if (f->slot >= 0 && dev_midi) {          if (f->slot >= 0 && APROC_OK(dev_midi)) {
                 dbg_puts(dev_midi->u.ctl.slot[f->slot].name);                  dbg_puts(dev_midi->u.ctl.slot[f->slot].name);
                 dbg_putu(dev_midi->u.ctl.slot[f->slot].unit);                  dbg_putu(dev_midi->u.ctl.slot[f->slot].unit);
         } else          } else
Line 79 
Line 73 
   
 void sock_setvol(void *, unsigned);  void sock_setvol(void *, unsigned);
 void sock_startreq(void *);  void sock_startreq(void *);
   void sock_stopreq(void *);
   void sock_locreq(void *, unsigned);
   
 struct ctl_ops ctl_sockops = {  struct ctl_ops ctl_sockops = {
         sock_setvol,          sock_setvol,
         sock_startreq          sock_startreq,
           sock_stopreq,
           sock_locreq
 };  };
   
 void  void
Line 158 
Line 156 
 {  {
         struct sock *f = (struct sock *)p->u.io.file;          struct sock *f = (struct sock *)p->u.io.file;
   
         if (f->mode & AMSG_REC)          if (f->mode & AMSG_RECMASK)
                 return;                  return;
   
         f->delta += delta;          f->delta += delta;
Line 257 
Line 255 
 {  {
         struct sock *f = (struct sock *)p->u.io.file;          struct sock *f = (struct sock *)p->u.io.file;
   
         if (!(f->mode & AMSG_REC))          if (!(f->mode & AMSG_RECMASK))
                 return;                  return;
   
         f->delta += delta;          f->delta += delta;
Line 306 
Line 304 
         f->mode = 0;          f->mode = 0;
         f->opt = opt_byname("default");          f->opt = opt_byname("default");
         if (f->opt) {          if (f->opt) {
                 if (dev_sub)                  if (f->opt->mode & MODE_RECMASK)
                         f->wpar = f->opt->wpar;                          f->wpar = f->opt->wpar;
                 if (dev_mix)                  if (f->opt->mode & MODE_PLAY)
                         f->rpar = f->opt->rpar;                          f->rpar = f->opt->rpar;
         }          }
         f->xrun = AMSG_IGNORE;          f->xrun = AMSG_IGNORE;
Line 316 
Line 314 
         f->round = dev_round;          f->round = dev_round;
         f->delta = 0;          f->delta = 0;
         f->tickpending = 0;          f->tickpending = 0;
           f->startpending = 0;
         f->vol = f->lastvol = MIDI_MAXCTL;          f->vol = f->lastvol = MIDI_MAXCTL;
         f->slot = -1;          f->slot = -1;
   
         wproc = aproc_new(&wsock_ops, f->pipe.file.name);          wproc = aproc_new(&wsock_ops, f->pipe.file.name);
         wproc->u.io.file = &f->pipe.file;          wproc->u.io.file = &f->pipe.file;
           wproc->u.io.partial = 0;
         f->pipe.file.wproc = wproc;          f->pipe.file.wproc = wproc;
         f->wstate = SOCK_WIDLE;          f->wstate = SOCK_WIDLE;
         f->wtodo = 0xdeadbeef;          f->wtodo = 0xdeadbeef;
   
         rproc = aproc_new(&rsock_ops, f->pipe.file.name);          rproc = aproc_new(&rsock_ops, f->pipe.file.name);
         rproc->u.io.file = &f->pipe.file;          rproc->u.io.file = &f->pipe.file;
           rproc->u.io.partial = 0;
         f->pipe.file.rproc = rproc;          f->pipe.file.rproc = rproc;
         f->rstate = SOCK_RMSG;          f->rstate = SOCK_RMSG;
         f->rtodo = sizeof(struct amsg);          f->rtodo = sizeof(struct amsg);
Line 357 
Line 358 
         if (wbuf)          if (wbuf)
                 abuf_hup(wbuf);                  abuf_hup(wbuf);
         f->tickpending = 0;          f->tickpending = 0;
           f->startpending = 0;
 }  }
   
 /*  /*
Line 367 
Line 369 
 {  {
         struct abuf *rbuf = NULL, *wbuf = NULL;          struct abuf *rbuf = NULL, *wbuf = NULL;
   
           f->pstate = SOCK_START;
         if (f->mode & AMSG_PLAY) {          if (f->mode & AMSG_PLAY) {
                 rbuf = abuf_new(f->bufsz, &f->rpar);                  rbuf = abuf_new(f->bufsz, &f->rpar);
                 aproc_setout(f->pipe.file.rproc, rbuf);                  aproc_setout(f->pipe.file.rproc, rbuf);
                   if (!ABUF_WOK(rbuf) || (f->pipe.file.state & FILE_EOF))
                           f->pstate = SOCK_READY;
         }          }
         if (f->mode & AMSG_REC) {          if (f->mode & AMSG_RECMASK) {
                 wbuf = abuf_new(f->bufsz, &f->wpar);                  wbuf = abuf_new(f->bufsz, &f->wpar);
                 aproc_setin(f->pipe.file.wproc, wbuf);                  aproc_setin(f->pipe.file.wproc, wbuf);
                 f->walign = dev_round * wbuf->bpf;                  f->walign = f->round;
         }          }
         f->delta = 0;          f->delta = 0;
           f->wmax = 0;
           f->rmax = f->bufsz;
         f->tickpending = 0;          f->tickpending = 0;
           f->startpending = 0;
 #ifdef DEBUG  #ifdef DEBUG
         if (debug_level >= 3) {          if (debug_level >= 3) {
                 sock_dbg(f);                  sock_dbg(f);
                 dbg_puts(": allocating ");                  dbg_puts(": allocating ");
                 dbg_putu(f->bufsz);                  dbg_putu(f->bufsz);
                 dbg_puts(" fr buffers\n");                  dbg_puts(" fr buffers, rmax = ");
                   dbg_putu(f->rmax);
                   dbg_puts("\n");
         }          }
 #endif  #endif
         f->pstate = SOCK_START;          if (f->mode & AMSG_PLAY) {
         if (!(f->mode & AMSG_PLAY) && ctl_slotstart(dev_midi, f->slot))                  f->pstate = SOCK_START;
                 (void)sock_attach(f, 0);          } else {
                   f->pstate = SOCK_READY;
                   if (ctl_slotstart(dev_midi, f->slot))
                           (void)sock_attach(f, 0);
           }
 }  }
   
 /*  /*
Line 423 
Line 437 
         struct sock *f = (struct sock *)arg;          struct sock *f = (struct sock *)arg;
   
 #ifdef DEBUG  #ifdef DEBUG
         if (f->pstate != SOCK_START) {          if (f->pstate != SOCK_READY) {
                 sock_dbg(f);                  sock_dbg(f);
                 dbg_puts(": not in START state\n");                  dbg_puts(": not in READY state\n");
                 dbg_panic();                  dbg_panic();
         }          }
 #endif  #endif
Line 433 
Line 447 
 }  }
   
 /*  /*
    * Callback invoked by MMC stop
    */
   void
   sock_stopreq(void *arg)
   {
   #ifdef DEBUG
           struct sock *f = (struct sock *)arg;
   
           if (debug_level >= 3) {
                   sock_dbg(f);
                   dbg_puts(": ignored STOP signal\n");
           }
   #endif
   }
   
   /*
    * Callback invoked by MMC relocate, ignored
    */
   void
   sock_locreq(void *arg, unsigned mmcpos)
   {
   #ifdef DEBUG
           struct sock *f = (struct sock *)arg;
   
           if (debug_level >= 3) {
                   sock_dbg(f);
                   dbg_puts(": ignored RELOCATE signal\n");
           }
   #endif
   }
   
   /*
  * Attach play and/or record buffers to dev_mix and/or dev_sub.   * Attach play and/or record buffers to dev_mix and/or dev_sub.
  */   */
 int  void
 sock_attach(struct sock *f, int force)  sock_attach(struct sock *f, int force)
 {  {
         struct abuf *rbuf, *wbuf;          struct abuf *rbuf, *wbuf;
Line 448 
Line 494 
          * the buffer isn't completely filled.           * the buffer isn't completely filled.
          */           */
         if (!force && rbuf && ABUF_WOK(rbuf))          if (!force && rbuf && ABUF_WOK(rbuf))
                 return 0;                  return;
   
           /*
            * get the current position, the origin is when
            * the first sample is played/recorded
            */
           f->delta = dev_getpos() * (int)f->round / (int)dev_round;
           f->startpending = 1;
           f->pstate = SOCK_RUN;
 #ifdef DEBUG  #ifdef DEBUG
         if (debug_level >= 3) {          if (debug_level >= 3) {
                 sock_dbg(f);                  sock_dbg(f);
                 dbg_puts(": attaching to device\n");                  dbg_puts(": attaching at ");
                   dbg_puti(f->delta);
                   dbg_puts("\n");
         }          }
 #endif  #endif
         f->pstate = SOCK_RUN;  
   
         /*          /*
          * Attach them to the device.           * We dont check whether the device is dying,
            * because dev_xxx() functions are supposed to
            * work (i.e., not to crash)
          */           */
         dev_attach(f->pipe.file.name,          dev_attach(f->pipe.file.name, f->mode,
             (f->mode & AMSG_PLAY) ? rbuf : NULL, &f->rpar, f->xrun,              rbuf, &f->rpar, wbuf, &f->wpar, f->xrun, f->opt->maxweight);
             (f->mode & AMSG_REC)  ? wbuf : NULL, &f->wpar, f->xrun,  
             f->opt->maxweight);  
         if (f->mode & AMSG_PLAY)          if (f->mode & AMSG_PLAY)
                 dev_setvol(rbuf, MIDI_TO_ADATA(f->vol));                  dev_setvol(rbuf, MIDI_TO_ADATA(f->vol));
   
Line 475 
Line 528 
                 if (!sock_write(f))                  if (!sock_write(f))
                         break;                          break;
         }          }
         return 1;  
 }  }
   
 void  void
Line 483 
Line 535 
 {  {
         switch (f->pstate) {          switch (f->pstate) {
         case SOCK_START:          case SOCK_START:
           case SOCK_READY:
                 if (ctl_slotstart(dev_midi, f->slot)) {                  if (ctl_slotstart(dev_midi, f->slot)) {
                         (void)sock_attach(f, 1);                          (void)sock_attach(f, 1);
                         f->pstate = SOCK_RUN;                          f->pstate = SOCK_RUN;
Line 584 
Line 637 
 {  {
         struct aproc *p;          struct aproc *p;
         struct abuf *obuf;          struct abuf *obuf;
         unsigned char *data;          unsigned n;
         unsigned count, n;  
   
 #ifdef DEBUG  #ifdef DEBUG
         if (f->pstate != SOCK_MIDI && f->rtodo == 0) {          if (f->pstate != SOCK_MIDI && f->rtodo == 0) {
Line 598 
Line 650 
         obuf = LIST_FIRST(&p->obuflist);          obuf = LIST_FIRST(&p->obuflist);
         if (obuf == NULL)          if (obuf == NULL)
                 return 0;                  return 0;
         if (ABUF_FULL(obuf) || !(f->pipe.file.state & FILE_ROK))          if (!ABUF_WOK(obuf) || !(f->pipe.file.state & FILE_ROK))
                 return 0;                  return 0;
         data = abuf_wgetblk(obuf, &count, 0);          if (f->pstate == SOCK_MIDI) {
         if (f->pstate != SOCK_MIDI && count > f->rtodo)                  if (!rfile_do(p, obuf->len, NULL))
                 count = f->rtodo;                          return 0;
         n = file_read(&f->pipe.file, data, count);          } else {
         if (n == 0)                  if (!rfile_do(p, f->rtodo, &n))
                 return 0;                          return 0;
         abuf_wcommit(obuf, n);  
         if (f->pstate != SOCK_MIDI)  
                 f->rtodo -= n;                  f->rtodo -= n;
                   if (f->pstate == SOCK_START) {
                           if (!ABUF_WOK(obuf) || (f->pipe.file.state & FILE_EOF))
                                   f->pstate = SOCK_READY;
                   }
           }
         return 1;          return 1;
 }  }
   
Line 621 
Line 676 
 {  {
         struct aproc *p;          struct aproc *p;
         struct abuf *ibuf;          struct abuf *ibuf;
         unsigned char *data;          unsigned n;
         unsigned count, n;  
 #define ZERO_MAX 0x1000  
         static unsigned char zero[ZERO_MAX];  
   
 #ifdef DEBUG  #ifdef DEBUG
         if (f->pstate != SOCK_MIDI && f->wtodo == 0) {          if (f->pstate != SOCK_MIDI && f->wtodo == 0) {
Line 637 
Line 689 
                 return 0;                  return 0;
         p = f->pipe.file.wproc;          p = f->pipe.file.wproc;
         ibuf = LIST_FIRST(&p->ibuflist);          ibuf = LIST_FIRST(&p->ibuflist);
         if (ibuf) {  #ifdef DEBUG
                 if (ABUF_EMPTY(ibuf))          if (f->pstate != SOCK_MIDI && ibuf == NULL) {
                   sock_dbg(f);
                   dbg_puts(": attempted to write on detached buffer\n");
                   dbg_panic();
           }
   #endif
           if (ibuf == NULL)
                   return 0;
           if (!ABUF_ROK(ibuf))
                   return 0;
           if (f->pstate == SOCK_MIDI) {
                   if (!wfile_do(p, ibuf->len, NULL))
                         return 0;                          return 0;
                 data = abuf_rgetblk(ibuf, &count, 0);  
                 if (f->pstate != SOCK_MIDI && count > f->wtodo)  
                         count = f->wtodo;  
                 n = file_write(&f->pipe.file, data, count);  
                 if (n == 0)  
                         return 0;  
                 abuf_rdiscard(ibuf, n);  
                 if (f->pstate != SOCK_MIDI)  
                         f->wtodo -= n;  
         } else {          } else {
                 if (f->pstate == SOCK_MIDI)                  if (!wfile_do(p, f->wtodo, &n))
                         return 0;  
                 /*  
                  * There's no dev_detach() routine yet,  
                  * so now we abruptly destroy the buffer.  
                  * Until we implement dev_detach, complete  
                  * the packet with zeros...  
                  */  
                 count = ZERO_MAX;  
                 if (count > f->wtodo)  
                         count = f->wtodo;  
                 n = file_write(&f->pipe.file, zero, count);  
                 if (n == 0)  
                         return 0;                          return 0;
                 f->wtodo -= n;                  f->wtodo -= n;
         }          }
Line 720 
Line 762 
                 f->rpar.le = f->wpar.le = p->le ? 1 : 0;                  f->rpar.le = f->wpar.le = p->le ? 1 : 0;
         if (AMSG_ISSET(p->msb))          if (AMSG_ISSET(p->msb))
                 f->rpar.msb = f->wpar.msb = p->msb ? 1 : 0;                  f->rpar.msb = f->wpar.msb = p->msb ? 1 : 0;
         if (AMSG_ISSET(p->rchan) && (f->mode & AMSG_REC)) {          if (AMSG_ISSET(p->rchan) && (f->mode & AMSG_RECMASK)) {
                 if (p->rchan < 1)                  if (p->rchan < 1)
                         p->rchan = 1;                          p->rchan = 1;
                 if (p->rchan > NCHAN_MAX)                  if (p->rchan > NCHAN_MAX)
Line 835 
Line 877 
         }          }
         if (AMSG_ISSET(p->appbufsz)) {          if (AMSG_ISSET(p->appbufsz)) {
                 rate = (f->mode & AMSG_PLAY) ? f->rpar.rate : f->wpar.rate;                  rate = (f->mode & AMSG_PLAY) ? f->rpar.rate : f->wpar.rate;
                 min = 2;                  min = 1;
                 max = 2 + rate / dev_round;                  max = 1 + rate / dev_round;
                 min *= f->round;                  min *= f->round;
                 max *= f->round;                  max *= f->round;
                 p->appbufsz += f->round - 1;                  p->appbufsz += f->round - 1;
Line 857 
Line 899 
         }          }
 #ifdef DEBUG  #ifdef DEBUG
         if (debug_level >= 2) {          if (debug_level >= 2) {
                 if (f->slot >= -1 && dev_midi) {                  if (f->slot >= 0 && dev_midi) {
                         dbg_puts(dev_midi->u.ctl.slot[f->slot].name);                          dbg_puts(dev_midi->u.ctl.slot[f->slot].name);
                         dbg_putu(dev_midi->u.ctl.slot[f->slot].unit);                          dbg_putu(dev_midi->u.ctl.slot[f->slot].unit);
                 } else                  } else
Line 868 
Line 910 
                         dbg_puts(", play = ");                          dbg_puts(", play = ");
                         aparams_dbg(&f->rpar);                          aparams_dbg(&f->rpar);
                 }                  }
                 if (f->mode & AMSG_REC) {                  if (f->mode & AMSG_RECMASK) {
                         dbg_puts(", rec:");                          dbg_puts(", rec:");
                         aparams_dbg(&f->wpar);                          aparams_dbg(&f->wpar);
                 }                  }
Line 928 
Line 970 
         /*          /*
          * XXX : dev_midi can no longer be NULL, right ?           * XXX : dev_midi can no longer be NULL, right ?
          */           */
         if (dev_midi && (p->proto & (AMSG_MIDIIN | AMSG_MIDIOUT))) {          if (APROC_OK(dev_midi) && (p->proto & (AMSG_MIDIIN | AMSG_MIDIOUT))) {
                 if (p->proto & ~(AMSG_MIDIIN | AMSG_MIDIOUT)) {                  if (p->proto & ~(AMSG_MIDIIN | AMSG_MIDIOUT)) {
 #ifdef DEBUG  #ifdef DEBUG
                         if (debug_level >= 1) {                          if (debug_level >= 1) {
Line 948 
Line 990 
         f->opt = opt_byname(p->opt);          f->opt = opt_byname(p->opt);
         if (f->opt == NULL)          if (f->opt == NULL)
                 return 0;                  return 0;
         if (dev_sub)          if (f->opt->mode & MODE_RECMASK)
                 f->wpar = f->opt->wpar;                  f->wpar = f->opt->wpar;
         if (dev_mix)          if (f->opt->mode & MODE_PLAY)
                 f->rpar = f->opt->rpar;                  f->rpar = f->opt->rpar;
         if (f->opt->mmc)          if (f->opt->mmc)
                 f->xrun = AMSG_SYNC;                  f->xrun = AMSG_SYNC;
Line 968 
Line 1010 
         }          }
         f->mode = 0;          f->mode = 0;
         if (p->proto & AMSG_PLAY) {          if (p->proto & AMSG_PLAY) {
                 if (!dev_mix) {                  if (!APROC_OK(dev_mix) || !(f->opt->mode & MODE_PLAY)) {
 #ifdef DEBUG  #ifdef DEBUG
                         if (debug_level >= 1) {                          if (debug_level >= 1) {
                                 sock_dbg(f);                                  sock_dbg(f);
Line 980 
Line 1022 
                 f->mode |= AMSG_PLAY;                  f->mode |= AMSG_PLAY;
         }          }
         if (p->proto & AMSG_REC) {          if (p->proto & AMSG_REC) {
                 if (!dev_sub) {                  if (!(APROC_OK(dev_sub)    && (f->opt->mode & MODE_REC)) &&
                       !(APROC_OK(dev_submon) && (f->opt->mode & MODE_MON))) {
 #ifdef DEBUG  #ifdef DEBUG
                         if (debug_level >= 1) {                          if (debug_level >= 1) {
                                 sock_dbg(f);                                  sock_dbg(f);
Line 989 
Line 1032 
 #endif  #endif
                         return 0;                          return 0;
                 }                  }
                 f->mode |= AMSG_REC;                  f->mode |= (f->opt->mode & MODE_MON) ? AMSG_MON : AMSG_REC;
         }          }
         if (dev_midi) {          if (APROC_OK(dev_midi)) {
                 f->slot = ctl_slotnew(dev_midi,                  f->slot = ctl_slotnew(dev_midi,
                      p->who, &ctl_sockops, f,                       p->who, &ctl_sockops, f,
                      f->opt->mmc);                       f->opt->mmc);
Line 1017 
Line 1060 
 sock_execmsg(struct sock *f)  sock_execmsg(struct sock *f)
 {  {
         struct amsg *m = &f->rmsg;          struct amsg *m = &f->rmsg;
           struct abuf *obuf;
   
         switch (m->cmd) {          switch (m->cmd) {
         case AMSG_DATA:          case AMSG_DATA:
Line 1026 
Line 1070 
                         dbg_puts(": DATA message\n");                          dbg_puts(": DATA message\n");
                 }                  }
 #endif  #endif
                 if (f->pstate != SOCK_RUN && f->pstate != SOCK_START) {                  if (f->pstate != SOCK_RUN && f->pstate != SOCK_START &&
                       f->pstate != SOCK_READY) {
 #ifdef DEBUG  #ifdef DEBUG
                         if (debug_level >= 1) {                          if (debug_level >= 1) {
                                 sock_dbg(f);                                  sock_dbg(f);
Line 1046 
Line 1091 
                         aproc_del(f->pipe.file.rproc);                          aproc_del(f->pipe.file.rproc);
                         return 0;                          return 0;
                 }                  }
                 if (f->pstate == SOCK_START &&                  obuf = LIST_FIRST(&f->pipe.file.rproc->obuflist);
                     ABUF_FULL(LIST_FIRST(&f->pipe.file.rproc->obuflist))) {                  if (f->pstate == SOCK_START && !ABUF_WOK(obuf)) {
 #ifdef DEBUG  #ifdef DEBUG
                         if (debug_level >= 1) {                          if (debug_level >= 1) {
                                 sock_dbg(f);                                  sock_dbg(f);
Line 1057 
Line 1102 
                         aproc_del(f->pipe.file.rproc);                          aproc_del(f->pipe.file.rproc);
                         return 0;                          return 0;
                 }                  }
                   if (m->u.data.size % obuf->bpf != 0) {
   #ifdef DEBUG
                           if (debug_level >= 1) {
                                   sock_dbg(f);
                                   dbg_puts(": unaligned data chunk\n");
                           }
   #endif
                           aproc_del(f->pipe.file.rproc);
                           return 0;
                   }
                 f->rstate = SOCK_RDATA;                  f->rstate = SOCK_RDATA;
                 f->rtodo = m->u.data.size;                  f->rtodo = m->u.data.size / obuf->bpf;
   #ifdef DEBUG
                   if (f->rtodo > f->rmax && debug_level >= 2) {
                           sock_dbg(f);
                           dbg_puts(": received past current position, rtodo = ");
                           dbg_putu(f->rtodo);
                           dbg_puts(", rmax = ");
                           dbg_putu(f->rmax);
                           dbg_puts("\n");
                           aproc_del(f->pipe.file.rproc);
                           return 0;
                   }
   #endif
                   f->rmax -= f->rtodo;
                 if (f->rtodo == 0) {                  if (f->rtodo == 0) {
 #ifdef DEBUG  #ifdef DEBUG
                         if (debug_level >= 1) {                          if (debug_level >= 1) {
Line 1098 
Line 1166 
                         dbg_puts(": STOP message\n");                          dbg_puts(": STOP message\n");
                 }                  }
 #endif  #endif
                 if (f->pstate != SOCK_RUN && f->pstate != SOCK_START) {                  if (f->pstate != SOCK_RUN &&
                       f->pstate != SOCK_START && f->pstate != SOCK_READY) {
 #ifdef DEBUG  #ifdef DEBUG
                         if (debug_level >= 1) {                          if (debug_level >= 1) {
                                 sock_dbg(f);                                  sock_dbg(f);
Line 1107 
Line 1176 
 #endif  #endif
                         aproc_del(f->pipe.file.rproc);                          aproc_del(f->pipe.file.rproc);
                         return 0;                          return 0;
                   /*
                    * XXX: device could have desappeared at this point,
                    * see how this is fixed in wav.c
                    */
                 }                  }
                 if (f->pstate == SOCK_START &&                  if ((f->pstate == SOCK_START || f->pstate == SOCK_READY) &&
                     ctl_slotstart(dev_midi, f->slot))                      ctl_slotstart(dev_midi, f->slot))
                         (void)sock_attach(f, 1);                          (void)sock_attach(f, 1);
                 sock_freebuf(f);                  if (f->wstate != SOCK_WDATA || f->wtodo == 0)
                           sock_freebuf(f);
                   else
                           f->pstate = SOCK_STOP;
                 AMSG_INIT(m);                  AMSG_INIT(m);
                 m->cmd = AMSG_ACK;                  m->cmd = AMSG_ACK;
                 f->rstate = SOCK_RRET;                  f->rstate = SOCK_RRET;
Line 1161 
Line 1237 
                 AMSG_INIT(m);                  AMSG_INIT(m);
                 m->cmd = AMSG_GETPAR;                  m->cmd = AMSG_GETPAR;
                 m->u.par.legacy_mode = f->mode;                  m->u.par.legacy_mode = f->mode;
                 m->u.par.bits = f->rpar.bits;                  if (f->mode & AMSG_PLAY) {
                 m->u.par.bps = f->rpar.bps;                          m->u.par.bits = f->rpar.bits;
                 m->u.par.sig = f->rpar.sig;                          m->u.par.bps = f->rpar.bps;
                 m->u.par.le = f->rpar.le;                          m->u.par.sig = f->rpar.sig;
                 m->u.par.msb = f->rpar.msb;                          m->u.par.le = f->rpar.le;
                 m->u.par.rate = f->rpar.rate;                          m->u.par.msb = f->rpar.msb;
                 m->u.par.rchan = f->wpar.cmax - f->wpar.cmin + 1;                          m->u.par.rate = f->rpar.rate;
                 m->u.par.pchan = f->rpar.cmax - f->rpar.cmin + 1;                          m->u.par.pchan = f->rpar.cmax - f->rpar.cmin + 1;
                   }
                   if (f->mode & AMSG_RECMASK) {
                           m->u.par.bits = f->wpar.bits;
                           m->u.par.bps = f->wpar.bps;
                           m->u.par.sig = f->wpar.sig;
                           m->u.par.le = f->wpar.le;
                           m->u.par.msb = f->wpar.msb;
                           m->u.par.rate = f->wpar.rate;
                           m->u.par.rchan = f->wpar.cmax - f->wpar.cmin + 1;
                   }
                 m->u.par.appbufsz = f->bufsz;                  m->u.par.appbufsz = f->bufsz;
                 m->u.par.bufsz =                  m->u.par.bufsz =
                     f->bufsz + (dev_bufsz / dev_round) * f->round;                      f->bufsz + (dev_bufsz / dev_round) * f->round;
Line 1196 
Line 1282 
                 AMSG_INIT(m);                  AMSG_INIT(m);
                 m->cmd = AMSG_GETCAP;                  m->cmd = AMSG_GETCAP;
                 m->u.cap.rate = dev_rate;                  m->u.cap.rate = dev_rate;
                 m->u.cap.pchan = dev_mix ?                  m->u.cap.pchan = (f->opt->mode & MODE_PLAY) ?
                     (f->opt->rpar.cmax - f->opt->rpar.cmin + 1) : 0;                      (f->opt->rpar.cmax - f->opt->rpar.cmin + 1) : 0;
                 m->u.cap.rchan = dev_sub ?                  m->u.cap.rchan = (f->opt->mode & (MODE_PLAY | MODE_REC)) ?
                     (f->opt->wpar.cmax - f->opt->wpar.cmin + 1) : 0;                      (f->opt->wpar.cmax - f->opt->wpar.cmin + 1) : 0;
                 m->u.cap.bits = sizeof(short) * 8;                  m->u.cap.bits = sizeof(short) * 8;
                 m->u.cap.bps = sizeof(short);                  m->u.cap.bps = sizeof(short);
Line 1212 
Line 1298 
                         dbg_puts(": SETVOL message\n");                          dbg_puts(": SETVOL message\n");
                 }                  }
 #endif  #endif
                 if (f->pstate != SOCK_RUN &&                  if (f->pstate != SOCK_RUN && f->pstate != SOCK_START &&
                     f->pstate != SOCK_START && f->pstate != SOCK_INIT) {                      f->pstate != SOCK_INIT && f->pstate != SOCK_READY) {
 #ifdef DEBUG  #ifdef DEBUG
                         if (debug_level >= 1) {                          if (debug_level >= 1) {
                                 sock_dbg(f);                                  sock_dbg(f);
Line 1321 
Line 1407 
 {  {
         struct aproc *p;          struct aproc *p;
         struct abuf *ibuf;          struct abuf *ibuf;
         unsigned size;          unsigned size, max;
   
         if (f->pstate == SOCK_MIDI) {          if (f->pstate == SOCK_MIDI) {
 #ifdef DEBUG  #ifdef DEBUG
Line 1338 
Line 1424 
         /*          /*
          * If pos changed, build a MOVE message.           * If pos changed, build a MOVE message.
          */           */
         if (f->tickpending) {          if ((f->tickpending && f->delta > 0) || f->startpending) {
 #ifdef DEBUG  #ifdef DEBUG
                 if (debug_level >= 4) {                  if (debug_level >= 4) {
                         sock_dbg(f);                          sock_dbg(f);
Line 1347 
Line 1433 
                         dbg_puts("\n");                          dbg_puts("\n");
                 }                  }
 #endif  #endif
                   f->wmax += f->delta;
                   if (f->delta > 0)
                           f->rmax += f->delta;
                 AMSG_INIT(&f->wmsg);                  AMSG_INIT(&f->wmsg);
                 f->wmsg.cmd = AMSG_MOVE;                  f->wmsg.cmd = AMSG_MOVE;
                 f->wmsg.u.ts.delta = f->delta;                  f->wmsg.u.ts.delta = f->delta;
Line 1354 
Line 1443 
                 f->wstate = SOCK_WMSG;                  f->wstate = SOCK_WMSG;
                 f->delta = 0;                  f->delta = 0;
                 f->tickpending = 0;                  f->tickpending = 0;
                   f->startpending = 0;
                 return 1;                  return 1;
         }          }
   
Line 1384 
Line 1474 
         p = f->pipe.file.wproc;          p = f->pipe.file.wproc;
         ibuf = LIST_FIRST(&p->ibuflist);          ibuf = LIST_FIRST(&p->ibuflist);
         if (ibuf && ABUF_ROK(ibuf)) {          if (ibuf && ABUF_ROK(ibuf)) {
                 size = ibuf->used - (ibuf->used % ibuf->bpf);  #ifdef DEBUG
                 if (size > AMSG_DATAMAX)                  if (ibuf->used > f->wmax && debug_level >= 3) {
                         size = AMSG_DATAMAX - (AMSG_DATAMAX % ibuf->bpf);                          sock_dbg(f);
                           dbg_puts(": attempt to send past current position\n");
                   }
   #endif
                   max = AMSG_DATAMAX / ibuf->bpf;
                   size = ibuf->used;
                 if (size > f->walign)                  if (size > f->walign)
                         size = f->walign;                          size = f->walign;
                   if (size > f->wmax)
                           size = f->wmax;
                   if (size > max)
                           size = max;
                   if (size == 0)
                           return 0;
                 f->walign -= size;                  f->walign -= size;
                   f->wmax -= size;
                 if (f->walign == 0)                  if (f->walign == 0)
                         f->walign = dev_round * ibuf->bpf;                          f->walign = f->round;
                 AMSG_INIT(&f->wmsg);                  AMSG_INIT(&f->wmsg);
                 f->wmsg.cmd = AMSG_DATA;                  f->wmsg.cmd = AMSG_DATA;
                 f->wmsg.u.data.size = size;                  f->wmsg.u.data.size = size * ibuf->bpf;
                 f->wtodo = sizeof(struct amsg);                  f->wtodo = sizeof(struct amsg);
                 f->wstate = SOCK_WMSG;                  f->wstate = SOCK_WMSG;
                 return 1;                  return 1;
Line 1440 
Line 1542 
                         f->rtodo = sizeof(struct amsg);                          f->rtodo = sizeof(struct amsg);
                 }                  }
                 /*                  /*
                  * XXX: have to way that the buffer is full before starting                   * XXX: sock_attach() may not start if there's not enough
                    *      samples queues, if so ctl_slotstart() will trigger
                    *      other streams, but this one won't start.
                  */                   */
                 if (f->pstate == SOCK_START && ctl_slotstart(dev_midi, f->slot))                  if (f->pstate == SOCK_READY && ctl_slotstart(dev_midi, f->slot))
                         (void)sock_attach(f, 0);                          (void)sock_attach(f, 0);
                 break;                  break;
         case SOCK_RRET:          case SOCK_RRET:
Line 1525 
Line 1629 
                         f->wtodo = 0xdeadbeef;                          f->wtodo = 0xdeadbeef;
                         break;                          break;
                 }                  }
                   /*
                    * XXX: why not set f->wtodo in sock_wmsg() ?
                    */
                 f->wstate = SOCK_WDATA;                  f->wstate = SOCK_WDATA;
                 f->wtodo = f->wmsg.u.data.size;                  f->wtodo = f->wmsg.u.data.size /
                       LIST_FIRST(&f->pipe.file.wproc->ibuflist)->bpf;
                 /* PASSTHROUGH */                  /* PASSTHROUGH */
         case SOCK_WDATA:          case SOCK_WDATA:
                 if (!sock_wdata(f))                  if (!sock_wdata(f))
Line 1535 
Line 1643 
                         break;                          break;
                 f->wstate = SOCK_WIDLE;                  f->wstate = SOCK_WIDLE;
                 f->wtodo = 0xdeadbeef;                  f->wtodo = 0xdeadbeef;
                   if (f->pstate == SOCK_STOP)
                           sock_freebuf(f);
                 /* PASSTHROUGH */                  /* PASSTHROUGH */
         case SOCK_WIDLE:          case SOCK_WIDLE:
                 if (!sock_return(f))                  if (!sock_return(f))

Legend:
Removed from v.1.41  
changed lines
  Added in v.1.42