textfiles/computers/realaq.asc

299 lines
8.2 KiB
Plaintext
Raw Permalink Normal View History

2021-04-15 11:31:59 -07:00
_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; <0A> }
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]); <0A> }
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> <0A>
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 <0A> 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> <0A> #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);
}