home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / magazine / drdobbs / 1989 / 06 / realaq.asc < prev    next >
Text File  |  1989-05-27  |  8KB  |  299 lines

  1. _REAL-TIME DATA AQUISITION_
  2. by Mike Bunnell and Mitch Bunnell
  3.  
  4.  
  5. [LISTING ONE]
  6.  
  7.      /*  dbuff.c     Double buffering program for continuous
  8.      reading from input and continuous writing to output
  9.  
  10.      */
  11.      
  12.      #include <stdio.h> 
  13.      #include <smem.h> 
  14.      #include <sem.h>
  15.  
  16.      extern char *malloc(); 
  17.      extern int errno;
  18.  
  19.      #define BSIZE 65536      /* size of each buffer */
  20.  
  21.      struct xbuff {  
  22.           char buffer[BSIZE];
  23.           int count;
  24.           int psem;
  25.           int csem;
  26.           int done;
  27.           struct xbuff *other;
  28.      }; 
  29.  
  30.      /*    
  31.           Write function that is used by the output task
  32.      */ 
  33.  
  34.      outputr(p, prio) 
  35.      register struct xbuff *p;     
  36.      int prio;
  37.      {
  38.           int count;
  39.  
  40.           setpriority(0, getpid(), prio);
  41.           while () {
  42.                sem_wait(p->csem);           /* wait for buffer to fill */
  43.                if (p->count <= 0) {
  44.                    sem_signal(p->psem);    /* leave if finished or error */
  45.                    break;è               }
  46.                count = write(1, p->buffer, p->count);  /* write output */
  47.                if (count <= 0) {
  48.                     /* exit if error on write */
  49.                     p->done = 1;      
  50.                     sem_signal(p->psem);
  51.                     break;
  52.                }    
  53.  
  54.                /* tell producer buffer has been emptied */
  55.                sem_signal(p->psem);  
  56.                p = p->other;
  57.           }
  58.      }
  59.  
  60.      /*
  61.  
  62.                Read function that is used by the input task
  63.      */ 
  64.      inputr(p, prio) 
  65.      register struct xbuff *p; 
  66.      int prio;
  67.      {
  68.          int count;
  69.  
  70.          setpriority(0, getpid(), prio);
  71.          do {
  72.               /* wait for consumer to empty buffer */
  73.               sem_wait(p->psem);  
  74.               if (p->done) {
  75.                    break;
  76.               }
  77.              /* read from input and fill buffer */
  78.              count = read(0, p->buffer, BSIZE); 
  79.              p->count = count;
  80.  
  81.              /* tell consumer task buffer is filled  */
  82.              sem_signal(p->csem);    
  83.              p = p->other;
  84.         }  while (count > 0); /* exit when no more data */
  85.      }
  86.  
  87.      main(argc, argv) 
  88.      int argc; 
  89.      char **argv;
  90.      {
  91.          register struct xbuff *buffa, *buffb;
  92.          int inprio, outprio;
  93.  
  94.          /* default to current priority  */
  95.          inprio = outprio = getpriority(0, 0);  
  96.          if (argc == 2) {            
  97.              /* Get input priority from command line if present */
  98.              inprio = atoi(argv[1]);      è         }
  99.          if (argc == 3) {            
  100.               /* Get output priority from command line if present */
  101.               inprio = atoi(argv[1]);
  102.               outprio = atoi(argv[2]);
  103.          }
  104.  
  105.          /* Allocate shared memory  */
  106.          buffa = (struct xbuff *) smem_get(
  107.                  "buffa", 
  108.                  (long)sizeof(struct xbuff), 
  109.                  SM_READ | SM_WRITE);
  110.          buffb = (struct xbuff *) smem_get(
  111.                  "buffb", 
  112.                  (long)sizeof(struct xbuff), 
  113.                  SM_READ | SM_WRITE);
  114.  
  115.          /* delete old semaphores if they exist */
  116.          sem_delete("buffac");         
  117.          sem_delete("buffap");         
  118.          sem_delete("buffbc");
  119.          sem_delete("buffbp");
  120.  
  121.          buffa->csem = sem_get("buffac", 0);  /* Create new semaphores to */
  122.          buffa->psem = sem_get("buffap", 1);  /* control access to shared */
  123.          buffb->csem = sem_get("buffbc", 0);  /* memory                   */
  124.          buffb->psem = sem_get("buffbp", 1);
  125.          buffa->done = buffb->done = 0;
  126.  
  127.          buffa->other = buffb;
  128.          buffb->other = buffa;
  129.  
  130.      /*    
  131.               Create another task to write.
  132.               This task will read.
  133.      */   
  134.  
  135.           if (fork() != 0)             /* Create another task to  */
  136.                inputr(buffa, inprio);  /* write.  This task will  */
  137.           else                         /* read                    */
  138.                outputr(buffa, outprio);
  139.      }
  140.  
  141.  
  142. [LISTING TWO]
  143.  
  144.      /* Reverb.c    IIR filter program to add reverberation */
  145.  
  146.      #include  <file.h>è
  147.      extern char *malloc(); 
  148.      
  149.      ewrite(s)
  150.      char *s;
  151.      {
  152.           write(2, s, strlen(s));
  153.      }
  154.  
  155.      /*   
  156.           Read the whole size read() under UNIX returns the amount it
  157.           read.  Last buffer is (biased) zero-filled.
  158.      */ 
  159.      fullread(fd, buff, size) 
  160.      int fd; 
  161.      char *buff; 
  162.      int size;
  163.      {
  164.           int i, j;
  165.  
  166.           i = 0;
  167.           do { 
  168.               j = read(fd, &buff[i], size - i);
  169.               if (j <= 0) {
  170.                   /* This must be the last buffer of the file */
  171.                   while (i < size)
  172.                       buff[i++] = 0x800;
  173.                   return -1;
  174.               }
  175.               i += j;
  176.          }  while (i < size);
  177.  
  178.          return size;
  179.      }
  180.  
  181.      main(ac, av) 
  182.      int ac; 
  183.      char **av;
  184.      {
  185.           short *ibuff, *obuff;
  186.           int delay;
  187.           int i;
  188.           int fd;
  189.           int rundown;
  190.           int rv;
  191.           char *fn;
  192.           register short *p, *q;
  193.  
  194.           if (ac > 2) {
  195.               ewrite("usage: reverb [delay]\n    (delay expressed in samples)\n");
  196.               exit(1);
  197.           }
  198.           if (ac == 2)
  199.               delay = atoi(av[1]);
  200.           elseè              delay = 10240;
  201.  
  202.           /* make sure delay is multiple of 512 bytes */
  203.           delay -= delay & 511;    
  204.  
  205.           /* make delay >= 512 andd <= 128K           */
  206.           if (delay < 512)      
  207.               delay = 512;
  208.           if (delay > 128*1024)
  209.               delay = 128*1024;
  210.  
  211.           fd = 0;
  212.  
  213.           ibuff = (short *) malloc(delay * sizeof(*ibuff));
  214.           obuff = (short *) calloc(delay * sizeof(*obuff)); 
  215.  
  216.           do {
  217.               /* Read a buffer, but don't check error status yet */
  218.               rv = fullread(fd, ibuff, delay * sizeof(short));
  219.  
  220.               /* 
  221.                 Add the fresh input samples to the old samples, after 
  222.                 dividing the old samples by 2
  223.               */
  224.               for (p = ibuff, q = obuff, i = 0; i < delay; ++i, ++p, ++q)
  225.                  *q = ((*q - 0x800) >> 1) + *p;
  226.  
  227.               /*
  228.                  Write the output reverbed buffer
  229.               */
  230.               write(1, obuff, delay * sizeof(short));
  231.           } while (rv != -1);
  232.  
  233.           /*
  234.               Allow sound in output buffer to "die down"
  235.           */
  236.           for (rundown = 11; --rundown >= 0; ) { 
  237.               for (q = obuff, i = 0; i < delay; ++i)
  238.                    *q = (*q - 0x800) >> 1;
  239.  
  240.               write(1, obuff, delay * sizeof(short));
  241.           }
  242.      }  
  243.  
  244. [LISTING THREE]
  245.  
  246.      /*  reverse.c   Write a file in reverse to standard output */
  247.  
  248.      #include  <file.h> 
  249.      #include  <types.h> è     #include  <time.h> 
  250.      #include  <stat.h> 
  251.  
  252.      main(ac, av)
  253.  
  254.      int ac; 
  255.      char **av;
  256.      {
  257.           int fd;
  258.           short buff[4096];
  259.           int rc;
  260.           int i, j, t;
  261.           long pos;
  262.           struct stat s;
  263.  
  264.           ++av;
  265.           if ((fd = open(*av, O_RDONLY, 0)) == -1) {
  266.               perror(*av);            /* exit if can't open file */
  267.               exit(1);
  268.           }       
  269.  
  270.            fstat(fd, &s);             /* find the size of the file */
  271.           pos = s.st_size &  1;
  272.  
  273.           while (pos > 0) {
  274.               /* See how many bytes can be read now */
  275.               if (pos < sizeof(buff))
  276.                   rc = pos;
  277.               else
  278.                   rc = sizeof(buff);
  279.  
  280.               pos -= rc;
  281.              /* Seek back a block and read */
  282.              lseek(fd, pos, 0);
  283.              read(fd, buff, rc);
  284.  
  285.              /* Reverse the samples in the block */
  286.              for (i = 0, j = (rc / 2) - 1; i < j; ++i, --j) { 
  287.                  t = buff[i];
  288.                  buff[i] = buff[j];
  289.                  buff[j] = t;
  290.              }
  291.  
  292.              /* Write the reversed block */
  293.              write(1, buff, rc);
  294.            }
  295.  
  296.           close(fd);
  297.      }
  298.  
  299.