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

Diff for /src/usr.bin/aucat/Attic/wav.c between version 1.14 and 1.15

version 1.14, 2010/04/03 17:59:17 version 1.15, 2010/04/06 20:07:01
Line 23 
Line 23 
 #include "aproc.h"  #include "aproc.h"
 #include "conf.h"  #include "conf.h"
 #include "dev.h"  #include "dev.h"
   #include "midi.h"
 #include "wav.h"  #include "wav.h"
   #include "opt.h"
 #ifdef DEBUG  #ifdef DEBUG
 #include "dbg.h"  #include "dbg.h"
 #endif  #endif
Line 123 
Line 125 
 void rwav_eof(struct aproc *, struct abuf *);  void rwav_eof(struct aproc *, struct abuf *);
 void rwav_hup(struct aproc *, struct abuf *);  void rwav_hup(struct aproc *, struct abuf *);
 void rwav_done(struct aproc *);  void rwav_done(struct aproc *);
   struct aproc *rwav_new(struct file *);
   
 int wwav_in(struct aproc *, struct abuf *);  int wwav_in(struct aproc *, struct abuf *);
 int wwav_out(struct aproc *, struct abuf *);  int wwav_out(struct aproc *, struct abuf *);
 void wwav_eof(struct aproc *, struct abuf *);  void wwav_eof(struct aproc *, struct abuf *);
 void wwav_hup(struct aproc *, struct abuf *);  void wwav_hup(struct aproc *, struct abuf *);
 void wwav_done(struct aproc *);  void wwav_done(struct aproc *);
   struct aproc *wwav_new(struct file *);
   
   void wav_setvol(void *, unsigned);
   void wav_startreq(void *);
   void wav_stopreq(void *);
   void wav_locreq(void *, unsigned);
   
   struct ctl_ops ctl_wavops = {
           wav_setvol,
           wav_startreq,
           wav_stopreq,
           wav_locreq
   };
   
 struct aproc_ops rwav_ops = {  struct aproc_ops rwav_ops = {
         "rwav",          "rwav",
         rwav_in,          rwav_in,
         rwav_out,          rwav_out,
         rwav_eof,          rfile_eof,
         rwav_hup,          rfile_hup,
         NULL, /* newin */          NULL, /* newin */
         NULL, /* newout */          NULL, /* newout */
         NULL, /* ipos */          NULL, /* ipos */
Line 147 
Line 163 
         "wwav",          "wwav",
         wwav_in,          wwav_in,
         wwav_out,          wwav_out,
         wwav_eof,          wfile_eof,
         wwav_hup,          wfile_hup,
         NULL, /* newin */          NULL, /* newin */
         NULL, /* newout */          NULL, /* newout */
         NULL, /* ipos */          NULL, /* ipos */
Line 156 
Line 172 
         wwav_done          wwav_done
 };  };
   
 struct aproc *  #ifdef DEBUG
 rwav_new(struct file *f)  /*
    * print the given wav structure
    */
   void
   wav_dbg(struct wav *f)
 {  {
         struct aproc *p;          static char *pstates[] = { "ini", "sta", "rdy", "run", "fai" };
   
         p = aproc_new(&rwav_ops, f->name);          dbg_puts("wav(");
         p->u.io.file = f;          if (f->slot >= 0 && APROC_OK(dev_midi)) {
         f->rproc = p;                  dbg_puts(dev_midi->u.ctl.slot[f->slot].name);
         return p;                  dbg_putu(dev_midi->u.ctl.slot[f->slot].unit);
           } else
                   dbg_puts(f->pipe.file.name);
           dbg_puts(")/");
           dbg_puts(pstates[f->pstate]);
 }  }
   #endif
   
 int  /*
 rwav_in(struct aproc *p, struct abuf *ibuf_dummy)   * convert ``count'' samples using the given char->short map
    */
   void
   wav_conv(unsigned char *data, unsigned count, short *map)
 {  {
         struct abuf *obuf = LIST_FIRST(&p->obuflist);          unsigned i;
         struct file *f = p->u.io.file;          unsigned char *iptr;
         unsigned char *data;          short *optr;
         unsigned count;  
   
         if (ABUF_FULL(obuf) || !(f->state & FILE_ROK))          iptr = data + count;
                 return 0;          optr = (short *)data + count;
         data = abuf_wgetblk(obuf, &count, 0);          for (i = count; i > 0; i--) {
         count = file_read(f, data, count);                  --optr;
         if (count == 0)                  --iptr;
                 return 0;                  *optr = map[*iptr];
         abuf_wcommit(obuf, count);          }
         if (!abuf_flush(obuf))  
                 return 0;  
         return 1;  
 }  }
   
 int  /*
 rwav_out(struct aproc *p, struct abuf *obuf)   * read method of the file structure
    */
   unsigned
   wav_read(struct file *file, unsigned char *data, unsigned count)
 {  {
         struct file *f = p->u.io.file;          struct wav *f = (struct wav *)file;
         unsigned char *data;          unsigned n;
         unsigned count;  
   
         if (f->state & FILE_RINUSE)          if (f->map)
                   count /= sizeof(short);
           if (f->rbytes >= 0 && count > f->rbytes) {
                   count = f->rbytes; /* file->rbytes fits in count */
                   if (count == 0) {
   #ifdef DEBUG
                           if (debug_level >= 3) {
                                   wav_dbg(f);
                                   dbg_puts(": read complete\n");
                           }
   #endif
                           if (!f->tr)
                                   file_eof(&f->pipe.file);
                           return 0;
                   }
           }
           n = pipe_read(file, data, count);
           if (n == 0)
                 return 0;                  return 0;
         if (ABUF_FULL(obuf) || !(f->state & FILE_ROK))          if (f->rbytes >= 0)
                 return 0;                  f->rbytes -= n;
         data = abuf_wgetblk(obuf, &count, 0);          if (f->map) {
         count = file_read(f, data, count);                  wav_conv(data, n, f->map);
         if (count == 0)                  n *= sizeof(short);
                 return 0;          }
         abuf_wcommit(obuf, count);          return n;
         return 1;  
 }  }
   
 void  /*
 rwav_done(struct aproc *p)   * write method of the file structure
    */
   unsigned
   wav_write(struct file *file, unsigned char *data, unsigned count)
 {  {
         struct file *f = p->u.io.file;          struct wav *f = (struct wav *)file;
         struct abuf *obuf;          unsigned n;
   
         if (f == NULL)          if (f->wbytes >= 0 && count > f->wbytes) {
                 return;                  count = f->wbytes; /* wbytes fits in count */
         /*                  if (count == 0) {
          * all buffers must be detached before deleting f->wproc,  #ifdef DEBUG
          * because otherwise it could trigger this code again                          if (debug_level >= 3) {
          */                                  wav_dbg(f);
         obuf = LIST_FIRST(&p->obuflist);                                  dbg_puts(": write complete\n");
         if (obuf)                          }
                 abuf_eof(obuf);  #endif
         if (f->wproc) {                          file_hup(&f->pipe.file);
                 f->rproc = NULL;                          return 0;
                 aproc_del(f->wproc);                  }
         } else          }
                 file_del(f);          n = pipe_write(file, data, count);
         p->u.io.file = NULL;          if (f->wbytes >= 0)
                   f->wbytes -= n;
           f->endpos += n;
           return n;
 }  }
   
   /*
    * close method of the file structure
    */
 void  void
 rwav_eof(struct aproc *p, struct abuf *ibuf_dummy)  wav_close(struct file *file)
 {  {
         aproc_del(p);          struct wav *f = (struct wav *)file;
   
           if (f->mode & MODE_RECMASK) {
                   pipe_trunc(&f->pipe.file, f->endpos);
                   if (f->hdr == HDR_WAV) {
                           wav_writehdr(f->pipe.fd,
                               &f->hpar,
                               &f->startpos,
                               f->endpos - f->startpos);
                   }
           }
           pipe_close(file);
 }  }
   
   /*
    * attach play (rec) abuf structure to the device and
    * switch to the ``RUN'' state; the play abug must not be empty
    */
   int
   wav_attach(struct wav *f, int force)
   {
           struct abuf *rbuf = NULL, *wbuf = NULL;
   
           if (f->mode & MODE_PLAY)
                   rbuf = LIST_FIRST(&f->pipe.file.rproc->obuflist);
           if (f->mode & MODE_RECMASK)
                   wbuf = LIST_FIRST(&f->pipe.file.wproc->ibuflist);
           f->pstate = WAV_RUN;
   #ifdef DEBUG
           if (debug_level >= 3) {
                   wav_dbg(f);
                   dbg_puts(": attaching\n");
           }
   #endif
           dev_attach(f->pipe.file.name, f->mode,
               rbuf, &f->hpar, wbuf, &f->hpar, f->xrun, f->maxweight);
           if (f->mode & MODE_PLAY)
                   dev_setvol(rbuf, MIDI_TO_ADATA(f->vol));
           return 1;
   }
   
   /*
    * allocate the play (rec) abuf structure; if this is a
    * file to record, then attach it to the device
    *
    * XXX: buffer size should be larger than dev_bufsz, because
    *      in non-server mode we don't prime play buffers with
    *      silence
    */
 void  void
 rwav_hup(struct aproc *p, struct abuf *obuf)  wav_allocbuf(struct wav *f)
 {  {
         aproc_del(p);          struct abuf *buf;
           unsigned nfr;
   
           f->pstate = WAV_START;
           if (f->mode & MODE_PLAY) {
                   nfr = 2 * dev_bufsz * f->hpar.rate / dev_rate;
                   buf = abuf_new(nfr, &f->hpar);
                   aproc_setout(f->pipe.file.rproc, buf);
                   abuf_fill(buf);
                   if (!ABUF_WOK(buf) || (f->pipe.file.state & FILE_EOF))
                           f->pstate = WAV_READY;
           }
           if (f->mode & MODE_RECMASK) {
                   nfr = 2 * dev_bufsz * f->hpar.rate / dev_rate;
                   buf = abuf_new(nfr, &f->hpar);
                   aproc_setin(f->pipe.file.wproc, buf);
                   f->pstate = WAV_READY;
           }
   #ifdef DEBUG
           if (debug_level >= 3) {
                   wav_dbg(f);
                   dbg_puts(": allocating buffers\n");
           }
   #endif
           if (f->pstate == WAV_READY && ctl_slotstart(dev_midi, f->slot))
                   (void)wav_attach(f, 0);
 }  }
   
 struct aproc *  /*
 wwav_new(struct file *f)   * free abuf structure and switch to the ``INIT'' state
    */
   void
   wav_freebuf(struct wav *f)
 {  {
         struct aproc *p;          struct abuf *rbuf = NULL, *wbuf = NULL;
   
         p = aproc_new(&wwav_ops, f->name);          if (f->mode & MODE_PLAY)
         p->u.io.file = f;                  rbuf = LIST_FIRST(&f->pipe.file.rproc->obuflist);
         f->wproc = p;          if (f->mode & MODE_RECMASK)
         return p;                  wbuf = LIST_FIRST(&f->pipe.file.wproc->ibuflist);
           f->pstate = WAV_INIT;
   #ifdef DEBUG
           if (debug_level >= 3) {
                   wav_dbg(f);
                   dbg_puts(": freeing buffers\n");
           }
   #endif
           if (rbuf || wbuf)
                   ctl_slotstop(dev_midi, f->slot);
           if (rbuf)
                   abuf_eof(rbuf);
           if (wbuf)
                   abuf_hup(wbuf);
 }  }
   
   /*
    * switch to the ``INIT'' state performing
    * necessary actions to reach it
    */
 void  void
 wwav_done(struct aproc *p)  wav_reset(struct wav *f)
 {  {
         struct file *f = p->u.io.file;          switch (f->pstate) {
         struct abuf *ibuf;          case WAV_START:
           case WAV_READY:
                   if (ctl_slotstart(dev_midi, f->slot))
                           (void)wav_attach(f, 1);
                   /* PASSTHROUGH */
           case WAV_RUN:
                   wav_freebuf(f);
                   f->pstate = WAV_INIT;
                   /* PASSTHROUGH */
           case WAV_INIT:
           case WAV_FAILED:
                   /* nothing yet */
                   break;
           }
   }
   
         if (f == NULL)  /*
                 return;   * terminate the wav reader/writer
    */
   void
   wav_exit(struct wav *f)
   {
           if (f->mode & MODE_PLAY) {
                   aproc_del(f->pipe.file.rproc);
           } else if (f->mode & MODE_RECMASK) {
                   aproc_del(f->pipe.file.wproc);
           }
   }
   
   /*
    * seek to f->mmcpos and prepare to start, close
    * the file on error.
    */
   int
   wav_seekmmc(struct wav *f)
   {
         /*          /*
          * all buffers must be detached before deleting f->rproc,           * don't go beyond the end-of-file, if so
          * because otherwise it could trigger this code again           * put it in INIT state so it dosn't start
          */           */
         ibuf = LIST_FIRST(&p->ibuflist);          if (f->mmcpos > f->endpos) {
         if (ibuf)                  wav_reset(f);
                 abuf_hup(ibuf);                  f->pstate = WAV_FAILED;
         if (f->rproc) {                  /*
                 f->wproc = NULL;                   * don't make other stream wait for us
                 aproc_del(f->rproc);                   */
         } else                  if (f->slot >= 0)
                 file_del(f);                          ctl_slotstart(dev_midi, f->slot);
         p->u.io.file = NULL;                  return 0;
           }
           if (!pipe_seek(&f->pipe.file, f->mmcpos)) {
                   wav_exit(f);
                   return 0;
           }
           if (f->hdr == HDR_WAV)
                   f->wbytes = WAV_DATAMAX - f->mmcpos;
           f->rbytes = f->endpos - f->mmcpos;
           wav_reset(f);
           wav_allocbuf(f);
           return 1;
 }  }
   
   /*
    * read samples from the file and possibly start it
    */
 int  int
 wwav_in(struct aproc *p, struct abuf *ibuf)  wav_rdata(struct wav *f)
 {  {
         struct file *f = p->u.io.file;          struct aproc *p;
         unsigned char *data;          struct abuf *obuf;
         unsigned count;  
   
         if (f->state & FILE_WINUSE)          p = f->pipe.file.rproc;
           obuf = LIST_FIRST(&p->obuflist);
           if (obuf == NULL)
                 return 0;                  return 0;
         if (ABUF_EMPTY(ibuf) || !(f->state & FILE_WOK))          if (!ABUF_WOK(obuf) || !(f->pipe.file.state & FILE_ROK))
                 return 0;                  return 0;
         data = abuf_rgetblk(ibuf, &count, 0);          if (!rfile_do(p, obuf->len, NULL))
         count = file_write(f, data, count);  
         if (count == 0)  
                 return 0;                  return 0;
         abuf_rdiscard(ibuf, count);          switch (f->pstate) {
           case WAV_START:
                   if (!ABUF_WOK(obuf) || (f->pipe.file.state & FILE_EOF))
                           f->pstate = WAV_READY;
                   /* PASSTHROUGH */
           case WAV_READY:
                   if (ctl_slotstart(dev_midi, f->slot))
                           (void)wav_attach(f, 0);
                   break;
   #ifdef DEBUG
           case WAV_RUN:
                   break;
           default:
                   wav_dbg(f);
                   dbg_puts(": bad state\n");
                   dbg_panic();
   #endif
           }
           if (f->rbytes == 0 && f->tr) {
   #ifdef DEBUG
                   if (debug_level >= 3) {
                           wav_dbg(f);
                           dbg_puts(": trying to restart\n");
                   }
   #endif
                   if (!wav_seekmmc(f))
                           return 0;
           }
         return 1;          return 1;
 }  }
   
 int  int
 wwav_out(struct aproc *p, struct abuf *obuf_dummy)  wav_wdata(struct wav *f)
 {  {
         struct abuf *ibuf = LIST_FIRST(&p->ibuflist);          struct aproc *p;
         struct file *f = p->u.io.file;          struct abuf *ibuf;
         unsigned char *data;  
         unsigned count;  
   
         if (!abuf_fill(ibuf))          if (!(f->pipe.file.state & FILE_WOK))
                 return 0;                  return 0;
         if (ABUF_EMPTY(ibuf) || !(f->state & FILE_WOK))          p = f->pipe.file.wproc;
           ibuf = LIST_FIRST(&p->ibuflist);
           if (ibuf == NULL)
                 return 0;                  return 0;
         data = abuf_rgetblk(ibuf, &count, 0);          if (!ABUF_ROK(ibuf))
         if (count == 0) {  
                 /* XXX: this can't happen, right ? */  
                 return 0;                  return 0;
         }          if (!wfile_do(p, ibuf->len, NULL))
         count = file_write(f, data, count);  
         if (count == 0)  
                 return 0;                  return 0;
         abuf_rdiscard(ibuf, count);  
         return 1;          return 1;
 }  }
   
   /*
    * callback to set the volume, invoked by the MIDI control code
    */
 void  void
 wwav_eof(struct aproc *p, struct abuf *ibuf)  wav_setvol(void *arg, unsigned vol)
 {  {
         aproc_del(p);          struct wav *f = (struct wav *)arg;
           struct abuf *rbuf;
   
           f->vol = vol;
           if ((f->mode & MODE_PLAY) && f->pstate == WAV_RUN) {
                   rbuf = LIST_FIRST(&f->pipe.file.rproc->obuflist);
                   dev_setvol(rbuf, MIDI_TO_ADATA(vol));
           }
 }  }
   
   /*
    * callback to start the stream, invoked by the MIDI control code
    */
 void  void
 wwav_hup(struct aproc *p, struct abuf *obuf_dummy)  wav_startreq(void *arg)
 {  {
         aproc_del(p);          struct wav *f = (struct wav *)arg;
   
           switch (f->pstate) {
           case WAV_FAILED:
   #ifdef DEBUG
                   if (debug_level >= 2) {
                           wav_dbg(f);
                           dbg_puts(": skipped (failed to seek)\n");
                   }
   #endif
                   return;
           case WAV_READY:
                   if (f->mode & MODE_RECMASK)
                           f->endpos = f->startpos;
                   (void)wav_attach(f, 0);
                   break;
   #ifdef DEBUG
           default:
                   wav_dbg(f);
                   dbg_puts(": not in READY state\n");
                   dbg_panic();
                   break;
   #endif
           }
 }  }
   
   /*
    * callback to stop the stream, invoked by the MIDI control code
    */
   void
   wav_stopreq(void *arg)
   {
           struct wav *f = (struct wav *)arg;
   
   #ifdef DEBUG
           if (debug_level >= 2) {
                   wav_dbg(f);
                   dbg_puts(": stopping");
                   if (f->pstate != WAV_FAILED && (f->mode & MODE_RECMASK)) {
                           dbg_puts(", ");
                           dbg_putu(f->endpos);
                           dbg_puts(" bytes recorded");
                   }
                   dbg_puts("\n");
           }
   #endif
           if (!f->tr) {
                   wav_exit(f);
                   return;
           }
           (void)wav_seekmmc(f);
   }
   
   /*
    * callback to relocate the stream, invoked by the MIDI control code
    * on a stopped stream
    */
   void
   wav_locreq(void *arg, unsigned mmc)
   {
           struct wav *f = (struct wav *)arg;
   
   #ifdef DEBUG
           if (f->pstate == WAV_RUN) {
                   wav_dbg(f);
                   dbg_puts(": in RUN state\n");
                   dbg_panic();
           }
   #endif
           f->mmcpos = f->startpos +
               ((off_t)mmc * f->hpar.rate / MTC_SEC) * aparams_bpf(&f->hpar);
           (void)wav_seekmmc(f);
   }
   
   /*
    * create a file reader in the ``INIT'' state
    */
 struct wav *  struct wav *
 wav_new_in(struct fileops *ops, char *name, unsigned hdr,  wav_new_in(struct fileops *ops, unsigned mode, char *name, unsigned hdr,
     struct aparams *par, unsigned xrun, unsigned volctl)      struct aparams *par, unsigned xrun, unsigned volctl, int tr)
 {  {
         int fd;          int fd;
         struct wav *f;          struct wav *f;
         struct aproc *p;  
         struct abuf *buf;  
         unsigned nfr;  
   
         if (name != NULL) {          if (name != NULL) {
                 fd = open(name, O_RDONLY | O_NONBLOCK, 0666);                  fd = open(name, O_RDONLY | O_NONBLOCK, 0666);
Line 356 
Line 649 
         if (f == NULL)          if (f == NULL)
                 return NULL;                  return NULL;
         if (hdr == HDR_WAV) {          if (hdr == HDR_WAV) {
                 if (!wav_readhdr(f->pipe.fd, par, &f->rbytes, &f->map)) {                  if (!wav_readhdr(f->pipe.fd, par, &f->startpos, &f->rbytes, &f->map)) {
                         file_del((struct file *)f);                          file_del((struct file *)f);
                         return NULL;                          return NULL;
                 }                  }
                 f->hpar = *par;                  f->endpos = f->startpos + f->rbytes;
         } else {          } else {
                 f->rbytes = -1;                  f->startpos = 0;
                   f->endpos = pipe_endpos(&f->pipe.file);
                   if (f->endpos > 0) {
                           if (!pipe_seek(&f->pipe.file, 0)) {
                                   file_del((struct file *)f);
                                   return NULL;
                           }
                           f->rbytes = f->endpos;
                   } else
                           f->rbytes = -1;
                 f->map = NULL;                  f->map = NULL;
         }          }
           f->tr = tr;
           f->mode = mode;
           f->hpar = *par;
         f->hdr = 0;          f->hdr = 0;
         nfr = dev_bufsz * par->rate / dev_rate;          f->xrun = xrun;
         buf = abuf_new(nfr, par);          f->maxweight = MIDI_TO_ADATA(volctl);
         p = rwav_new((struct file *)f);          f->slot = ctl_slotnew(dev_midi, "play", &ctl_wavops, f, 1);
         aproc_setout(p, buf);          rwav_new((struct file *)f);
         abuf_fill(buf); /* XXX: move this in dev_attach() ? */          wav_allocbuf(f);
         dev_attach(name, buf, par, xrun, NULL, NULL, 0, ADATA_UNIT);  
         dev_setvol(buf, MIDI_TO_ADATA(volctl));  
 #ifdef DEBUG  #ifdef DEBUG
         if (debug_level >= 2) {          if (debug_level >= 2) {
                 dbg_puts(name);                  dbg_puts(name);
                 dbg_puts(": playing ");                  dbg_puts(": playing ");
                   dbg_putu(f->startpos);
                   dbg_puts("..");
                   dbg_putu(f->endpos);
                   dbg_puts(": playing ");
                 aparams_dbg(par);                  aparams_dbg(par);
                   if (f->tr)
                           dbg_puts(", mmc");
                 dbg_puts("\n");                  dbg_puts("\n");
         }          }
 #endif  #endif
         return f;          return f;
 }  }
   
   /*
    * create a file writer in the ``INIT'' state
    */
 struct wav *  struct wav *
 wav_new_out(struct fileops *ops, char *name, unsigned hdr,  wav_new_out(struct fileops *ops, unsigned mode, char *name, unsigned hdr,
     struct aparams *par, unsigned xrun)      struct aparams *par, unsigned xrun, int tr)
 {  {
         int fd;          int fd;
         struct wav *f;          struct wav *f;
         struct aproc *p;  
         struct abuf *buf;  
         unsigned nfr;  
   
         if (name == NULL) {          if (name == NULL) {
                 name = "stdout";                  name = "stdout";
Line 414 
Line 723 
                 par->le = 1;                  par->le = 1;
                 par->sig = (par->bits <= 8) ? 0 : 1;                  par->sig = (par->bits <= 8) ? 0 : 1;
                 par->bps = (par->bits + 7) / 8;                  par->bps = (par->bits + 7) / 8;
                 if (!wav_writehdr(f->pipe.fd, par)) {                  if (!wav_writehdr(f->pipe.fd, par, &f->startpos, 0)) {
                         file_del((struct file *)f);                          file_del((struct file *)f);
                         return NULL;                          return NULL;
                 }                  }
                 f->hpar = *par;  
                 f->wbytes = WAV_DATAMAX;                  f->wbytes = WAV_DATAMAX;
         } else                  f->endpos = f->startpos;
           } else {
                 f->wbytes = -1;                  f->wbytes = -1;
                   f->startpos = f->endpos = 0;
           }
           f->tr = tr;
           f->mode = mode;
           f->hpar = *par;
         f->hdr = hdr;          f->hdr = hdr;
         nfr = dev_bufsz * par->rate / dev_rate;          f->xrun = xrun;
         p = wwav_new((struct file *)f);          f->slot = ctl_slotnew(dev_midi, "rec", &ctl_wavops, f, 1);
         buf = abuf_new(nfr, par);          wwav_new((struct file *)f);
         aproc_setin(p, buf);          wav_allocbuf(f);
         dev_attach(name, NULL, NULL, 0, buf, par, xrun, 0);  
 #ifdef DEBUG  #ifdef DEBUG
         if (debug_level >= 2) {          if (debug_level >= 2) {
                 dbg_puts(name);                  dbg_puts(name);
Line 440 
Line 753 
 }  }
   
 void  void
 wav_conv(unsigned char *data, unsigned count, short *map)  rwav_done(struct aproc *p)
 {  {
         unsigned i;          struct wav *f = (struct wav *)p->u.io.file;
         unsigned char *iptr;  
         short *optr;  
   
         iptr = data + count;          if (f->slot >= 0)
         optr = (short *)data + count;                  ctl_slotdel(dev_midi, f->slot);
         for (i = count; i > 0; i--) {          f->slot = -1;
                 --optr;          rfile_done(p);
                 --iptr;  }
                 *optr = map[*iptr];  
   int
   rwav_in(struct aproc *p, struct abuf *ibuf_dummy)
   {
           struct wav *f = (struct wav *)p->u.io.file;
           struct abuf *obuf;
   
           if (!wav_rdata(f))
                   return 0;
           obuf = LIST_FIRST(&p->obuflist);
           if (obuf && f->pstate >= WAV_RUN) {
                   if (!abuf_flush(obuf))
                           return 0;
         }          }
           return 1;
 }  }
   
 unsigned  int
 wav_read(struct file *file, unsigned char *data, unsigned count)  rwav_out(struct aproc *p, struct abuf *obuf)
 {  {
         struct wav *f = (struct wav *)file;          struct wav *f = (struct wav *)p->u.io.file;
         unsigned n;  
   
         if (f->map)          if (f->pipe.file.state & FILE_RINUSE)
                 count /= sizeof(short);                  return 0;
         if (f->rbytes >= 0 && count > f->rbytes) {          for (;;) {
                 count = f->rbytes; /* file->rbytes fits in count */                  if (!wav_rdata(f))
                 if (count == 0) {  
 #ifdef DEBUG  
                         if (debug_level >= 3) {  
                                 file_dbg(&f->pipe.file);  
                                 dbg_puts(": read complete\n");  
                         }  
 #endif  
                         file_eof(&f->pipe.file);  
                         return 0;                          return 0;
                 }  
         }          }
         n = pipe_read(file, data, count);          return 1;
         if (n == 0)  }
   
   struct aproc *
   rwav_new(struct file *f)
   {
           struct aproc *p;
   
           p = aproc_new(&rwav_ops, f->name);
           p->u.io.file = f;
           p->u.io.partial = 0;;
           f->rproc = p;
           return p;
   }
   
   void
   wwav_done(struct aproc *p)
   {
           struct wav *f = (struct wav *)p->u.io.file;
   
           if (f->slot >= 0)
                   ctl_slotdel(dev_midi, f->slot);
           f->slot = -1;
           wfile_done(p);
   }
   
   int
   wwav_in(struct aproc *p, struct abuf *ibuf)
   {
           struct wav *f = (struct wav *)p->u.io.file;
   
           if (f->pipe.file.state & FILE_WINUSE)
                 return 0;                  return 0;
         if (f->rbytes >= 0)          for (;;) {
                 f->rbytes -= n;                  if (!wav_wdata(f))
         if (f->map) {                          return 0;
                 wav_conv(data, n, f->map);  
                 n *= sizeof(short);  
         }          }
         return n;          return 1;
 }  }
   
 unsigned  int
 wav_write(struct file *file, unsigned char *data, unsigned count)  wwav_out(struct aproc *p, struct abuf *obuf_dummy)
 {  {
         struct wav *f = (struct wav *)file;          struct abuf *ibuf = LIST_FIRST(&p->ibuflist);
         unsigned n;          struct wav *f = (struct wav *)p->u.io.file;
   
         if (f->wbytes >= 0 && count > f->wbytes) {          if (ibuf && f->pstate == WAV_RUN) {
                 count = f->wbytes; /* wbytes fits in count */                  if (!abuf_fill(ibuf))
                 if (count == 0) {  
 #ifdef DEBUG  
                         if (debug_level >= 3) {  
                                 file_dbg(&f->pipe.file);  
                                 dbg_puts(": write complete\n");  
                         }  
 #endif  
                         file_hup(&f->pipe.file);  
                         return 0;                          return 0;
                 }  
         }          }
         n = pipe_write(file, data, count);          if (!wav_wdata(f))
         if (f->wbytes >= 0)                  return 0;
                 f->wbytes -= n;          return 1;
         return n;  
 }  }
   
 void  struct aproc *
 wav_close(struct file *file)  wwav_new(struct file *f)
 {  {
         struct wav *f = (struct wav *)file;          struct aproc *p;
   
         if (f->hdr == HDR_WAV)          p = aproc_new(&wwav_ops, f->name);
                 wav_writehdr(f->pipe.fd, &f->hpar);          p->u.io.file = f;
         pipe_close(file);          p->u.io.partial = 0;;
           f->wproc = p;
           return p;
 }  }
   

Legend:
Removed from v.1.14  
changed lines
  Added in v.1.15