archive:computers:realaq
_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); }
/home/gen.uk/domains/wiki.gen.uk/public_html/data/pages/archive/computers/realaq.txt · Last modified: 2001/11/08 10:19 by 127.0.0.1