[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.13 and 1.14

version 1.13, 2010/04/03 17:40:33 version 1.14, 2010/04/03 17:59:17
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 125 
Line 123 
 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,
         rfile_eof,          rwav_eof,
         rfile_hup,          rwav_hup,
         NULL, /* newin */          NULL, /* newin */
         NULL, /* newout */          NULL, /* newout */
         NULL, /* ipos */          NULL, /* ipos */
Line 163 
Line 147 
         "wwav",          "wwav",
         wwav_in,          wwav_in,
         wwav_out,          wwav_out,
         wfile_eof,          wwav_eof,
         wfile_hup,          wwav_hup,
         NULL, /* newin */          NULL, /* newin */
         NULL, /* newout */          NULL, /* newout */
         NULL, /* ipos */          NULL, /* ipos */
Line 172 
Line 156 
         wwav_done          wwav_done
 };  };
   
 #ifdef DEBUG  struct aproc *
 /*  rwav_new(struct file *f)
  * print the given wav structure  
  */  
 void  
 wav_dbg(struct wav *f)  
 {  {
         static char *pstates[] = { "ini", "sta", "rdy", "run", "fai" };          struct aproc *p;
   
         dbg_puts("wav(");          p = aproc_new(&rwav_ops, f->name);
         if (f->slot >= 0 && APROC_OK(dev_midi)) {          p->u.io.file = f;
                 dbg_puts(dev_midi->u.ctl.slot[f->slot].name);          f->rproc = p;
                 dbg_putu(dev_midi->u.ctl.slot[f->slot].unit);          return p;
         } else  
                 dbg_puts(f->pipe.file.name);  
         dbg_puts(")/");  
         dbg_puts(pstates[f->pstate]);  
 }  }
 #endif  
   
 /*  int
  * convert ``count'' samples using the given char->short map  rwav_in(struct aproc *p, struct abuf *ibuf_dummy)
  */  
 void  
 wav_conv(unsigned char *data, unsigned count, short *map)  
 {  {
         unsigned i;          struct abuf *obuf = LIST_FIRST(&p->obuflist);
         unsigned char *iptr;          struct file *f = p->u.io.file;
         short *optr;          unsigned char *data;
           unsigned count;
   
         iptr = data + count;          if (ABUF_FULL(obuf) || !(f->state & FILE_ROK))
         optr = (short *)data + count;  
         for (i = count; i > 0; i--) {  
                 --optr;  
                 --iptr;  
                 *optr = map[*iptr];  
         }  
 }  
   
 /*  
  * read method of the file structure  
  */  
 unsigned  
 wav_read(struct file *file, unsigned char *data, unsigned count)  
 {  
         struct wav *f = (struct wav *)file;  
         unsigned n;  
   
         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 (f->rbytes >= 0)          data = abuf_wgetblk(obuf, &count, 0);
                 f->rbytes -= n;          count = file_read(f, data, count);
         if (f->map) {          if (count == 0)
                 wav_conv(data, n, f->map);                  return 0;
                 n *= sizeof(short);          abuf_wcommit(obuf, count);
         }          if (!abuf_flush(obuf))
         return n;                  return 0;
           return 1;
 }  }
   
 /*  
  * write method of the file structure  
  */  
 unsigned  
 wav_write(struct file *file, unsigned char *data, unsigned count)  
 {  
         struct wav *f = (struct wav *)file;  
         unsigned n;  
   
         if (f->wbytes >= 0 && count > f->wbytes) {  
                 count = f->wbytes; /* wbytes fits in count */  
                 if (count == 0) {  
 #ifdef DEBUG  
                         if (debug_level >= 3) {  
                                 wav_dbg(f);  
                                 dbg_puts(": write complete\n");  
                         }  
 #endif  
                         file_hup(&f->pipe.file);  
                         return 0;  
                 }  
         }  
         n = pipe_write(file, data, count);  
         if (f->wbytes >= 0)  
                 f->wbytes -= n;  
         f->endpos += n;  
         return n;  
 }  
   
 /*  
  * close method of the file structure  
  */  
 void  
 wav_close(struct file *file)  
 {  
         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  int
 wav_attach(struct wav *f, int force)  rwav_out(struct aproc *p, struct abuf *obuf)
 {  {
         struct abuf *rbuf = NULL, *wbuf = NULL;          struct file *f = p->u.io.file;
           unsigned char *data;
           unsigned count;
   
         if (f->mode & MODE_PLAY)          if (f->state & FILE_RINUSE)
                 rbuf = LIST_FIRST(&f->pipe.file.rproc->obuflist);                  return 0;
         if (f->mode & MODE_RECMASK)          if (ABUF_FULL(obuf) || !(f->state & FILE_ROK))
                 wbuf = LIST_FIRST(&f->pipe.file.wproc->ibuflist);                  return 0;
         f->pstate = WAV_RUN;          data = abuf_wgetblk(obuf, &count, 0);
 #ifdef DEBUG          count = file_read(f, data, count);
         if (debug_level >= 3) {          if (count == 0)
                 wav_dbg(f);                  return 0;
                 dbg_puts(": attaching\n");          abuf_wcommit(obuf, count);
         }  
 #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;          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
 wav_allocbuf(struct wav *f)  rwav_done(struct aproc *p)
 {  {
         struct abuf *buf;          struct file *f = p->u.io.file;
         unsigned nfr;          struct abuf *obuf;
   
         f->pstate = WAV_START;          if (f == NULL)
         if (f->mode & MODE_PLAY) {                  return;
                 nfr = 2 * dev_bufsz * f->hpar.rate / dev_rate;          /*
                 buf = abuf_new(nfr, &f->hpar);           * all buffers must be detached before deleting f->wproc,
                 aproc_setout(f->pipe.file.rproc, buf);           * because otherwise it could trigger this code again
                 abuf_fill(buf);           */
                 if (!ABUF_WOK(buf) || (f->pipe.file.state & FILE_EOF))          obuf = LIST_FIRST(&p->obuflist);
                         f->pstate = WAV_READY;          if (obuf)
         }                  abuf_eof(obuf);
         if (f->mode & MODE_RECMASK) {          if (f->wproc) {
                 nfr = 2 * dev_bufsz * f->hpar.rate / dev_rate;                  f->rproc = NULL;
                 buf = abuf_new(nfr, &f->hpar);                  aproc_del(f->wproc);
                 aproc_setin(f->pipe.file.wproc, buf);          } else
                 f->pstate = WAV_READY;                  file_del(f);
         }          p->u.io.file = NULL;
 #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);  
 }  }
   
 /*  
  * free abuf structure and switch to the ``INIT'' state  
  */  
 void  void
 wav_freebuf(struct wav *f)  rwav_eof(struct aproc *p, struct abuf *ibuf_dummy)
 {  {
         struct abuf *rbuf = NULL, *wbuf = NULL;          aproc_del(p);
   
         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_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
 wav_reset(struct wav *f)  rwav_hup(struct aproc *p, struct abuf *obuf)
 {  {
         switch (f->pstate) {          aproc_del(p);
         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;  
         }  
 }  }
   
 /*  struct aproc *
  * terminate the wav reader/writer  wwav_new(struct file *f)
  */  
 void  
 wav_exit(struct wav *f)  
 {  {
         if (f->mode & MODE_PLAY) {          struct aproc *p;
                 aproc_del(f->pipe.file.rproc);  
         } else if (f->mode & MODE_RECMASK) {          p = aproc_new(&wwav_ops, f->name);
                 aproc_del(f->pipe.file.wproc);          p->u.io.file = f;
         }          f->wproc = p;
           return p;
 }  }
   
 /*  void
  * seek to f->mmcpos and prepare to start, close  wwav_done(struct aproc *p)
  * the file on error.  
  */  
 int  
 wav_seekmmc(struct wav *f)  
 {  {
           struct file *f = p->u.io.file;
           struct abuf *ibuf;
   
           if (f == NULL)
                   return;
         /*          /*
          * don't go beyond the end-of-file, if so           * all buffers must be detached before deleting f->rproc,
          * put it in INIT state so it dosn't start           * because otherwise it could trigger this code again
          */           */
         if (f->mmcpos > f->endpos) {          ibuf = LIST_FIRST(&p->ibuflist);
                 wav_reset(f);          if (ibuf)
                 f->pstate = WAV_FAILED;                  abuf_hup(ibuf);
                 /*          if (f->rproc) {
                  * don't make other stream wait for us                  f->wproc = NULL;
                  */                  aproc_del(f->rproc);
                 if (f->slot >= 0)          } else
                         ctl_slotstart(dev_midi, f->slot);                  file_del(f);
                 return 0;          p->u.io.file = NULL;
         }  
         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
 wav_rdata(struct wav *f)  wwav_in(struct aproc *p, struct abuf *ibuf)
 {  {
         struct aproc *p;          struct file *f = p->u.io.file;
         struct abuf *obuf;          unsigned char *data;
           unsigned count;
   
         p = f->pipe.file.rproc;          if (f->state & FILE_WINUSE)
         obuf = LIST_FIRST(&p->obuflist);  
         if (obuf == NULL)  
                 return 0;                  return 0;
         if (!ABUF_WOK(obuf) || !(f->pipe.file.state & FILE_ROK))          if (ABUF_EMPTY(ibuf) || !(f->state & FILE_WOK))
                 return 0;                  return 0;
         if (!rfile_do(p, obuf->len, NULL))          data = abuf_rgetblk(ibuf, &count, 0);
           count = file_write(f, data, count);
           if (count == 0)
                 return 0;                  return 0;
         switch (f->pstate) {          abuf_rdiscard(ibuf, count);
         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
 wav_wdata(struct wav *f)  wwav_out(struct aproc *p, struct abuf *obuf_dummy)
 {  {
         struct aproc *p;          struct abuf *ibuf = LIST_FIRST(&p->ibuflist);
         struct abuf *ibuf;          struct file *f = p->u.io.file;
           unsigned char *data;
           unsigned count;
   
         if (!(f->pipe.file.state & FILE_WOK))          if (!abuf_fill(ibuf))
                 return 0;                  return 0;
         p = f->pipe.file.wproc;          if (ABUF_EMPTY(ibuf) || !(f->state & FILE_WOK))
         ibuf = LIST_FIRST(&p->ibuflist);  
         if (ibuf == NULL)  
                 return 0;                  return 0;
         if (!ABUF_ROK(ibuf))          data = abuf_rgetblk(ibuf, &count, 0);
           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
 wav_setvol(void *arg, unsigned vol)  wwav_eof(struct aproc *p, struct abuf *ibuf)
 {  {
         struct wav *f = (struct wav *)arg;          aproc_del(p);
         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
 wav_startreq(void *arg)  wwav_hup(struct aproc *p, struct abuf *obuf_dummy)
 {  {
         struct wav *f = (struct wav *)arg;          aproc_del(p);
   
         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, unsigned mode, char *name, unsigned hdr,  wav_new_in(struct fileops *ops, char *name, unsigned hdr,
     struct aparams *par, unsigned xrun, unsigned volctl, int tr)      struct aparams *par, unsigned xrun, unsigned volctl)
 {  {
         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 649 
Line 356 
         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->startpos, &f->rbytes, &f->map)) {                  if (!wav_readhdr(f->pipe.fd, par, &f->rbytes, &f->map)) {
                         file_del((struct file *)f);                          file_del((struct file *)f);
                         return NULL;                          return NULL;
                 }                  }
                 f->endpos = f->startpos + f->rbytes;                  f->hpar = *par;
         } else {          } else {
                 f->startpos = 0;                  f->rbytes = -1;
                 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;
         f->xrun = xrun;          nfr = dev_bufsz * par->rate / dev_rate;
         f->maxweight = MIDI_TO_ADATA(volctl);          buf = abuf_new(nfr, par);
         f->slot = ctl_slotnew(dev_midi, "play", &ctl_wavops, f, 1);          p = rwav_new((struct file *)f);
         rwav_new((struct file *)f);          aproc_setout(p, buf);
         wav_allocbuf(f);          abuf_fill(buf); /* XXX: move this in dev_attach() ? */
           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, unsigned mode, char *name, unsigned hdr,  wav_new_out(struct fileops *ops, char *name, unsigned hdr,
     struct aparams *par, unsigned xrun, int tr)      struct aparams *par, unsigned xrun)
 {  {
         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 723 
Line 414 
                 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, &f->startpos, 0)) {                  if (!wav_writehdr(f->pipe.fd, par)) {
                         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;
                 f->endpos = f->startpos;          } else
         } 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;
         f->xrun = xrun;          nfr = dev_bufsz * par->rate / dev_rate;
         f->slot = ctl_slotnew(dev_midi, "rec", &ctl_wavops, f, 1);          p = wwav_new((struct file *)f);
         wwav_new((struct file *)f);          buf = abuf_new(nfr, par);
         wav_allocbuf(f);          aproc_setin(p, buf);
           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 753 
Line 440 
 }  }
   
 void  void
 rwav_done(struct aproc *p)  wav_conv(unsigned char *data, unsigned count, short *map)
 {  {
         struct wav *f = (struct wav *)p->u.io.file;          unsigned i;
           unsigned char *iptr;
           short *optr;
   
         if (f->slot >= 0)          iptr = data + count;
                 ctl_slotdel(dev_midi, f->slot);          optr = (short *)data + count;
         f->slot = -1;          for (i = count; i > 0; i--) {
         rfile_done(p);                  --optr;
 }                  --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;  
 }  }
   
 int  unsigned
 rwav_out(struct aproc *p, struct abuf *obuf)  wav_read(struct file *file, unsigned char *data, unsigned count)
 {  {
         struct wav *f = (struct wav *)p->u.io.file;          struct wav *f = (struct wav *)file;
           unsigned n;
   
         if (f->pipe.file.state & FILE_RINUSE)          if (f->map)
                 return 0;                  count /= sizeof(short);
         for (;;) {          if (f->rbytes >= 0 && count > f->rbytes) {
                 if (!wav_rdata(f))                  count = f->rbytes; /* file->rbytes fits in count */
                   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;
                   }
         }          }
         return 1;          n = pipe_read(file, data, count);
 }          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;
         for (;;) {          if (f->rbytes >= 0)
                 if (!wav_wdata(f))                  f->rbytes -= n;
                         return 0;          if (f->map) {
                   wav_conv(data, n, f->map);
                   n *= sizeof(short);
         }          }
         return 1;          return n;
 }  }
   
 int  unsigned
 wwav_out(struct aproc *p, struct abuf *obuf_dummy)  wav_write(struct file *file, unsigned char *data, unsigned count)
 {  {
         struct abuf *ibuf = LIST_FIRST(&p->ibuflist);          struct wav *f = (struct wav *)file;
         struct wav *f = (struct wav *)p->u.io.file;          unsigned n;
   
         if (ibuf && f->pstate == WAV_RUN) {          if (f->wbytes >= 0 && count > f->wbytes) {
                 if (!abuf_fill(ibuf))                  count = f->wbytes; /* wbytes fits in count */
                   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;
                   }
         }          }
         if (!wav_wdata(f))          n = pipe_write(file, data, count);
                 return 0;          if (f->wbytes >= 0)
         return 1;                  f->wbytes -= n;
           return n;
 }  }
   
 struct aproc *  void
 wwav_new(struct file *f)  wav_close(struct file *file)
 {  {
         struct aproc *p;          struct wav *f = (struct wav *)file;
   
         p = aproc_new(&wwav_ops, f->name);          if (f->hdr == HDR_WAV)
         p->u.io.file = f;                  wav_writehdr(f->pipe.fd, &f->hpar);
         p->u.io.partial = 0;;          pipe_close(file);
         f->wproc = p;  
         return p;  
 }  }
   

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