Date: Thu, 18 Jan 1996 14:07:16 -0600 From: Jim Lowe <james@miller.cs.uwm.edu> To: luigi@labinfo.iet.unipi.it Cc: multimedia@freebsd.org, multimedia@rah.star-gate.com, tlehman@becky.acet.org, toml@mitre.org Subject: Re: FreeBSD and VAT Message-ID: <199601182007.OAA10985@miller.cs.uwm.edu>
next in thread | raw e-mail | index | archive | help
> > The soundblaster will probably always sound a little choppy just because it > > really doesn't run at 8khz. The way to fix that is to purchase a full duplex > ^^^^^^^^^^^^^^^^^^^ > > What do you mean by that ? You cannot expect any two cards to have > exactly the same rate, so the software (and I mean the user-level > software, not the device driver) must compensate speed mismatches > by removing/adding samples. If it doesn't in a soft way (by means > of small corrections at every segment), sooner or later you will > be way out of sync and you will hear clicks. > > I cannot tell what is the maximum % difference in sample rates > which can give acceptable results (it depends a lot on the block > size you are using), but my feeling is that 1% or less should not > give too bad results. > Usually the sound cards are not even close to 8khz. They are sometimes off by > 1khz depending on the sound card. Vat doesn't take this into consideration. In fact, Vat uses the sound card for a timer. It assumes that the packets are arriving at 8khz and uses this value, no matter what the record rate actually is, as Vat's internal clock. The block/packet size in vat is 160 bytes (or 20ms @ 8khz). I don't think that 1% would be a problem for short bursty conversations. If one was playing a CD for a long period of time (say 40 minutes), or listening to a conference, then 1% compounded could be a problem -- since then it is 1% per second for 40 minutes. I don't know that I agree with the way they implemented the internal clock in vat, but I am not sure they had much to choose from. They wanted the program to run on a variety of systems. The only thing that I can think of that will give you 20ms resolution would be the system interval timer (which I am not sure if it available on all systems such at NT, Macs, Windows, etc...) or reading 8000hz samples (160 byte blocks) from a sound card. Now on Sun, Dec, and workstation type systems, the variance in the sound cards is about .001%. This is also true about the CS4231 codec on the GUS PnP cards if my test program was working correctly when Amancio ran it. My GUS Max card has a variance of about 2% at 8000hz if I tell it to run at 8230hz. I can make a PAS-16 have a variance of about .1% if I run it at 8116hz. The problem is that not every PC sound card works the same. Some of this depends on the bus and chipset timing. The CS4231 actually goes through a calibration cycle to set the correct frequency. The VOXware sound drivers that are in FreeBSD/Linux do not attempt to do frequency correction in the drivers. But if someone would like to do this, the code is certainly available :-). Vmix attempts to correct for this utilizing interval timers -- but doesn't do a real good job. Attached is the program I used for timing of various sound cards. -Jim ----------------------------------------------- #include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/time.h> #include <sys/file.h> #include <errno.h> #include <machine/soundcard.h> /* #define BROKEN_SELECT /* soundcard needs read before select */ char *dev="/dev/dsp1"; /* or on command line */ int blocksize = 160; main(int ac, char **av) { struct timeval tv, start; int fd; fd_set rfd; int cc; int i; double u; if(ac>1) dev = av[1]; if((fd=open(dev, O_RDONLY)) < 0) { perror(dev); exit(-1); } if(ioctl(fd, SNDCTL_DSP_SETBLKSIZE, &blocksize) < 0) { printf("Setting blocksize failed: %s\n", strerror(errno)); } #ifdef BROKEN_SELECT read(fd, dev, 1); #endif gettimeofday(&start, 0); cc = 0; i = 0; FD_ZERO(&rfd); while (1) { int n; char buf[blocksize]; FD_SET(fd, &rfd); select(fd+1, &rfd, 0, 0, 0); n = read(fd, buf, blocksize); if (n < 0) { perror("read"); exit(1); } if(n!=blocksize) printf("read %d, wanted blocksize\n", n); cc += n; if (++i >= 50) { i = 0; gettimeofday(&tv, 0); u = tv.tv_sec - start.tv_sec; u += 1e-6 * (tv.tv_usec - start.tv_usec); printf("%d %lg %lg\n", cc, u, (double)cc / u); fflush(stdout); } } }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199601182007.OAA10985>