💾 Archived View for spam.works › mirrors › textfiles › computers › realaq.asc captured on 2023-06-14 at 16:04:54.

View Raw

More Information

-=-=-=-=-=-=-

_REAL-TIME DATA AQUISITION_
by Mike Bunnell and Mitch Bunnell


[LISTING ONE]

     /*  dbuff.c     Double buffering program for continuous
     reading from input and continuous writing to output

     */
     
     #include <stdio.h> 
     #include <smem.h> 
     #include <sem.h>

     extern char *malloc(); 
     extern int errno;

     #define BSIZE 65536      /* size of each buffer */

     struct xbuff {  
          char buffer[BSIZE];
          int count;
          int psem;
          int csem;
          int done;
          struct xbuff *other;
     }; 

     /*    
          Write function that is used by the output task
     */ 

     outputr(p, prio) 
     register struct xbuff *p;     
     int prio;
     {
          int count;

          setpriority(0, getpid(), prio);
          while () {
               sem_wait(p->csem);           /* wait for buffer to fill */
               if (p->count <= 0) {
                   sem_signal(p->psem);    /* leave if finished or error */
                   break;
?               }
               count = write(1, p->buffer, p->count);  /* write output */
               if (count <= 0) {
                    /* exit if error on write */
                    p->done = 1;      
                    sem_signal(p->psem);
                    break;
               }    

               /* tell producer buffer has been emptied */
               sem_signal(p->psem);  
               p = p->other;
          }
     }

     /*

               Read function that is used by the input task
     */ 
     inputr(p, prio) 
     register struct xbuff *p; 
     int prio;
     {
         int count;

         setpriority(0, getpid(), prio);
         do {
              /* wait for consumer to empty buffer */
              sem_wait(p->psem);  
              if (p->done) {
                   break;
              }
             /* read from input and fill buffer */
             count = read(0, p->buffer, BSIZE); 
             p->count = count;

             /* tell consumer task buffer is filled  */
             sem_signal(p->csem);    
             p = p->other;
        }  while (count > 0); /* exit when no more data */
     }

     main(argc, argv) 
     int argc; 
     char **argv;
     {
         register struct xbuff *buffa, *buffb;
         int inprio, outprio;

         /* default to current priority  */
         inprio = outprio = getpriority(0, 0);  
         if (argc == 2) {            
             /* Get input priority from command line if present */
             inprio = atoi(argv[1]);      
?         }
         if (argc == 3) {            
              /* Get output priority from command line if present */
              inprio = atoi(argv[1]);
              outprio = atoi(argv[2]);
         }

         /* Allocate shared memory  */
         buffa = (struct xbuff *) smem_get(
                 "buffa", 
                 (long)sizeof(struct xbuff), 
                 SM_READ | SM_WRITE);
         buffb = (struct xbuff *) smem_get(
                 "buffb", 
                 (long)sizeof(struct xbuff), 
                 SM_READ | SM_WRITE);

         /* delete old semaphores if they exist */
         sem_delete("buffac");         
         sem_delete("buffap");         
         sem_delete("buffbc");
         sem_delete("buffbp");

         buffa->csem = sem_get("buffac", 0);  /* Create new semaphores to */
         buffa->psem = sem_get("buffap", 1);  /* control access to shared */
         buffb->csem = sem_get("buffbc", 0);  /* memory                   */
         buffb->psem = sem_get("buffbp", 1);
         buffa->done = buffb->done = 0;

         buffa->other = buffb;
         buffb->other = buffa;

     /*    
              Create another task to write.
              This task will read.
     */   

          if (fork() != 0)             /* Create another task to  */
               inputr(buffa, inprio);  /* write.  This task will  */
          else                         /* read                    */
               outputr(buffa, outprio);
     }


[LISTING TWO]

     /* Reverb.c    IIR filter program to add reverberation */

     #include  <file.h>
?
     extern char *malloc(); 
     
     ewrite(s)
     char *s;
     {
          write(2, s, strlen(s));
     }

     /*   
          Read the whole size read() under UNIX returns the amount it
          read.  Last buffer is (biased) zero-filled.
     */ 
     fullread(fd, buff, size) 
     int fd; 
     char *buff; 
     int size;
     {
          int i, j;

          i = 0;
          do { 
              j = read(fd, &buff[i], size - i);
              if (j <= 0) {
                  /* This must be the last buffer of the file */
                  while (i < size)
                      buff[i++] = 0x800;
                  return -1;
              }
              i += j;
         }  while (i < size);

         return size;
     }

     main(ac, av) 
     int ac; 
     char **av;
     {
          short *ibuff, *obuff;
          int delay;
          int i;
          int fd;
          int rundown;
          int rv;
          char *fn;
          register short *p, *q;

          if (ac > 2) {
              ewrite("usage: reverb [delay]\n    (delay expressed in samples)\n");
              exit(1);
          }
          if (ac == 2)
              delay = atoi(av[1]);
          else
?              delay = 10240;

          /* make sure delay is multiple of 512 bytes */
          delay -= delay & 511;    

          /* make delay >= 512 andd <= 128K           */
          if (delay < 512)      
              delay = 512;
          if (delay > 128*1024)
              delay = 128*1024;

          fd = 0;

          ibuff = (short *) malloc(delay * sizeof(*ibuff));
          obuff = (short *) calloc(delay * sizeof(*obuff)); 

          do {
              /* Read a buffer, but don't check error status yet */
              rv = fullread(fd, ibuff, delay * sizeof(short));

              /* 
                Add the fresh input samples to the old samples, after 
                dividing the old samples by 2
              */
              for (p = ibuff, q = obuff, i = 0; i < delay; ++i, ++p, ++q)
                 *q = ((*q - 0x800) >> 1) + *p;

              /*
                 Write the output reverbed buffer
              */
              write(1, obuff, delay * sizeof(short));
          } while (rv != -1);

          /*
              Allow sound in output buffer to "die down"
          */
          for (rundown = 11; --rundown >= 0; ) { 
              for (q = obuff, i = 0; i < delay; ++i)
                   *q = (*q - 0x800) >> 1;

              write(1, obuff, delay * sizeof(short));
          }
     }  

[LISTING THREE]

     /*  reverse.c   Write a file in reverse to standard output */

     #include  <file.h> 
     #include  <types.h> 
?     #include  <time.h> 
     #include  <stat.h> 

     main(ac, av)

     int ac; 
     char **av;
     {
          int fd;
          short buff[4096];
          int rc;
          int i, j, t;
          long pos;
          struct stat s;

          ++av;
          if ((fd = open(*av, O_RDONLY, 0)) == -1) {
              perror(*av);            /* exit if can't open file */
              exit(1);
          }       

           fstat(fd, &s);             /* find the size of the file */
          pos = s.st_size &  1;

          while (pos > 0) {
              /* See how many bytes can be read now */
              if (pos < sizeof(buff))
                  rc = pos;
              else
                  rc = sizeof(buff);

              pos -= rc;
             /* Seek back a block and read */
             lseek(fd, pos, 0);
             read(fd, buff, rc);

             /* Reverse the samples in the block */
             for (i = 0, j = (rc / 2) - 1; i < j; ++i, --j) { 
                 t = buff[i];
                 buff[i] = buff[j];
                 buff[j] = t;
             }

             /* Write the reversed block */
             write(1, buff, rc);
           }

          close(fd);
     }