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

Rob nomail at example.com
Sun Nov 18 15:33:21 UTC 2012


Here is the sourcecode:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <tgmath.h>

#include <sys/soundcard.h>

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

#define FSAMP   8000                            /* sample rate */
#define AMPLI   30000                           /* output amplitude */
#define TONE1   440                             /* tone 1 freq */
#define DURA1   ((int)(0.1*FSAMP))              /* duration = 100 ms */
#define TONE2   440                             /* tone 2 freq */
#define DURA2   ((int)(0.1*FSAMP))              /* duration = 100 ms */
#define STAR2   ((int)(0.25*FSAMP))             /* start tone2 = 250 ms */
#define RAMP    ((int)(0.01*FSAMP))             /* ramp-up/down = 10 ms */
#define PAUSE   ((int)(1.75*FSAMP))             /* pause = 1750 ms */
#define CYCLE   (STAR2+DURA2+PAUSE)             /* total cycle time */

short int sample[CYCLE];

int
main (argc,argv)
int argc;
char *argv;

{
    int soundfd;
    int blksize;
    int n;
    int ampli;
    double rate;

    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);
    }

    if (argc > 1) {
        printf("%s: blocksize %d bytes\n",SoundDev,n);
        printf("sample rate: %d length: %d\n",FSAMP,sizeof(sample));
        printf("tone1: %dms %dHz %dms ramp\n",1000*DURA1/FSAMP,TONE1,1000*RAMP/FSAMP);
        printf("tone2: %dms %dHz %dms ramp\n",1000*DURA2/FSAMP,TONE2,1000*RAMP/FSAMP);
        printf("pause: %dms\n",1000*PAUSE/FSAMP);
    }

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

    memset(sample,0,sizeof(sample));

    /* tone1 */

    rate = ((double)TONE1 * 2 * M_PI) / (double)FSAMP;

    for (n = 0; n < DURA1; n++) {
        if (n < RAMP)
            ampli = n * AMPLI / RAMP;
        else
            if (n > (DURA1 - RAMP))
                ampli = (DURA1 - n) * AMPLI / RAMP;
            else
                ampli = AMPLI;

        sample[n] = ampli * sin((double)n * rate);

        if (argc > 2) {
            printf("n=%d ampli=%d sample=%d\n",n,ampli,sample[n]);
        }
    }

    /* tone2 */

    rate = ((double)TONE2 * 2 * M_PI) / (double)FSAMP;

    for (n = 0; n < DURA2; n++) {
        if (n < RAMP)
            ampli = n * AMPLI / RAMP;
        else
            if (n > (DURA2 - RAMP))
                ampli = (DURA2 - n) * AMPLI / RAMP;
            else
                ampli = AMPLI;

        sample[STAR2+n] = ampli * sin((double)n * rate);

        if (argc > 2) {
            printf("n=%d ampli=%d sample=%d\n",STAR2+n,ampli,sample[STAR2+n]);
        }
    }

    /* send the prepared buffer in an endless loop */

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

    exit(0);
}



More information about the questions mailing list