[ntp:questions] Audible signal generator ("BBC pips")?

David Godfrey dave at deltass.co.uk.nospam
Mon Dec 10 11:21:43 UTC 2012


Rob <nomail at example.com> wrote:

> Here is the sourcecode:

Thanks for that. I've tweaked it a little to actually generate the six
pips at the top of the minute. My ear can't detect a difference
between the BBC pips and these.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <math.h>
#include <sys/time.h>

#include <sys/soundcard.h>

char    *SoundDev = "/dev/dsp";                 /* device name for soundcard */

#define FSAMP   8000                            /* sample rate */
#define AMPLI   30000                           /* output amplitude */
#define TONE    1000                            /* tone freq */
#define DURA1   ((int)(0.1*FSAMP))              /* duration = 100 ms */
#define DURA2   ((int)(0.5*FSAMP))              /* duration = 500 ms */
#define RAMP    ((int)(0.01*FSAMP))             /* ramp-down = 10 ms */

int
main (int argc, char **argv)
{
    int soundfd,blksize,ampli;
    int n,i;
    double rate;
    int nshort=5,sleep;
    struct timeval time;
    struct timezone tz;
    short int sample[FSAMP*7];

    /* Sleep until near the top of minute */
    gettimeofday(&time,&tz);
    sleep = 52-time.tv_sec %60;
    if (sleep<0) sleep += 60;
    usleep(sleep*1000000);

    if ((soundfd = open(SoundDev,O_WRONLY)) < 0) {
        perror(SoundDev);
        exit(1);
    }

    n = APF_NETWORK;                            /* underruns occur */
    ioctl(soundfd,SNDCTL_DSP_PROFILE,&n);

    if (ioctl(soundfd,SNDCTL_DSP_GETBLKSIZE,&blksize) < 0 ||
        blksize < 1 || blksize > 65536) {
        perror(SoundDev);
        exit(1);
    }

    /* Parameter +/-1 to add/subtract leap second e.g. pips 1 */
    if (argc > 1) nshort += atoi(argv[1]);

    n = 0;                                      /* select MONO */
    if (ioctl(soundfd,SNDCTL_DSP_STEREO,&n) < 0) {
        perror(SoundDev);
        exit(1);
    }

    n = AFMT_S16_LE;                            /* Little-endian signed 16bit */
    if (ioctl(soundfd,SNDCTL_DSP_SETFMT,&n) < 0) {
        perror(SoundDev);
        exit(1);
    }

    n = FSAMP;                                  /* sample rate */
    if (ioctl(soundfd,SNDCTL_DSP_SPEED,&n) < 0) {
        perror(SoundDev);
        exit(1);
    }

    /* silence! */
    memset(sample,0,sizeof(sample));

    /* tone */
    rate = ((double)TONE * 2 * M_PI) / (double)FSAMP;

    /* Short pips */
    for (i=0;i<nshort;i++) {
        for (n = 0; n < DURA1; n++) {
	    if (n < RAMP)
	  /*            ampli = n * AMPLI / RAMP;*/
	        ampli = AMPLI;
	    else
	        if (n > (DURA1 - RAMP))
		    ampli = (DURA1 - n) * AMPLI / RAMP;
		else
		    ampli = AMPLI;
        sample[i*FSAMP+n] = ampli * sin((double)n * rate);
        }
    }

    /* Long pip on the minute */
    for (n = 0; n < DURA2; n++) {
        if (n < RAMP)
	  /*            ampli = n * AMPLI / RAMP;*/
            ampli = AMPLI;
        else
            if (n > (DURA2 - RAMP))
                ampli = (DURA2 - n) * AMPLI / RAMP;
            else
                ampli = AMPLI;
        sample[nshort*FSAMP+n] = ampli * sin((double)n * rate);
    }

    /* Busy wait for 55 second mark */
    do 
        gettimeofday(&time,&tz);
    while (time.tv_sec %60 != 55);

    if (write(soundfd,sample,sizeof(sample)) != sizeof(sample)) {
      perror(SoundDev);
      exit(1);
    }

    if (close(soundfd) < 0) {
        perror(SoundDev);
        exit(1);
    }

    exit(0);
}

-- 
Dave Godfrey



More information about the questions mailing list