Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 22 Dec 1997 14:05:42 -0600 (CST)
From:      Jim Lowe <james@miller.cs.uwm.edu>
To:        hasty@rah.star-gate.com, luigi@labinfo.iet.unipi.it
Cc:        multimedia@FreeBSD.ORG, steve@visint.co.uk
Subject:   Re: precise soundcard tuning ?
Message-ID:  <199712222005.OAA23623@miller.cs.uwm.edu>

next in thread | raw e-mail | index | archive | help
> From: Luigi Rizzo <luigi@labinfo.iet.unipi.it>
> Subject: Re: precise soundcard tuning ?
> To: hasty@rah.star-gate.com (Amancio Hasty)
> 
> While i was developing a delay compensation mechanism for my
> telephone app, I was printing the difference between the expected
> arrival time of data packets (based on the RTP timestamp which in
> turn is based on the card sample clock) and the actual arrival time
> (computed using the cpu clock).
> 
> It took some minutes to realize that the drift of about 8 samples/s
> was not a bug in my code but rather the clock drift!
> 

Try running this little program.  Depending on the buffer size and
card type you can get some interesting results.

	-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 /* */

char	*dev="/dev/dsp0";
int	blocksize = 160;

main(int ac, char **av)
{
        struct timeval  tv, start;
        int             fd;
        fd_set          rfd;
        int 		cc;
        int 		i;
	int		freq;
        double		 u;

	if(ac>1) {
		freq = atoi(av[1]);
	} else
		freq = 8000;

        if((fd=open(dev, O_RDONLY)) < 0) {
                perror("open failed\n");
                exit(-1);
        }
	if(ioctl(fd, SNDCTL_DSP_SETBLKSIZE, &blocksize) < 0) {
		printf("Setting blocksize failed: %s\n", strerror(errno));
	}
	if(ioctl(fd, SNDCTL_DSP_SPEED, &freq) < 0) {
		printf("Setting speed 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?199712222005.OAA23623>