⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gen.c

📁 DTMF编解码程序,linux环境下
💻 C
字号:
/* *      gen.c -- generate different test signals * *      Copyright (C) 1997 *          Thomas Sailer (sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu) * *      This program is free software; you can redistribute it and/or modify *      it under the terms of the GNU General Public License as published by *      the Free Software Foundation; either version 2 of the License, or *      (at your option) any later version. * *      This program is distributed in the hope that it will be useful, *      but WITHOUT ANY WARRANTY; without even the implied warranty of *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *      GNU General Public License for more details. * *      You should have received a copy of the GNU General Public License *      along with this program; if not, write to the Free Software *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *//* ---------------------------------------------------------------------- */#include "gen.h"#include <sys/types.h>#include <sys/stat.h>#include <sys/wait.h>#include <string.h>#include <stdio.h>#include <fcntl.h>#include <unistd.h>#include <errno.h>#include <math.h>#include <stdlib.h>#ifdef SUN_AUDIO#include <sys/audioio.h>#include <stropts.h>#include <sys/conf.h>#else /* SUN_AUDIO */#include <sys/soundcard.h>#include <sys/ioctl.h>#endif /* SUN_AUDIO *//* ---------------------------------------------------------------------- */#ifdef __sun__#include <stdarg.h>int snprintf(char *buf, size_t sz, const char *fmt, ...){	int i;	va_list arg;	va_start(arg, fmt);	i = vsprintf(buf, fmt, arg);	va_end(arg);	return i;}#endif /* __sun__ *//* ---------------------------------------------------------------------- */static const char *allowed_types[] = {	"raw", "aiff", "au", "hcom", "sf", "voc", "cdr", "dat", 	"smp", "wav", "maud", "vwe", NULL};/* ---------------------------------------------------------------------- */typedef void (*t_init_procs)(struct gen_params *, struct gen_state *);typedef int (*t_gen_procs)(signed short *, int, struct gen_params *, struct gen_state *);static const t_init_procs init_procs[] = {	gen_init_dtmf, gen_init_sine, gen_init_zvei, gen_init_hdlc};static const t_gen_procs gen_procs[] = {	gen_dtmf, gen_sine, gen_zvei, gen_hdlc};/* ---------------------------------------------------------------------- */#define MAX_GEN 16static struct gen_params params[MAX_GEN];static struct gen_state state[MAX_GEN];static int num_gen = 0;/* ---------------------------------------------------------------------- */static int process_buffer(short *buf, int len){	int i;	int totnum = 0, num;	memset(buf, 0, len*sizeof(buf[0]));	for (i = 0; i < num_gen; i++) {		if (params[i].type >= sizeof(gen_procs)/sizeof(gen_procs[0]))			break;		if (!gen_procs[params[i].type])			break;		num = gen_procs[params[i].type](buf, len, params+i, state+i);		if (num > totnum)			totnum = num;	}	return totnum;}/* ---------------------------------------------------------------------- */#ifdef SUN_AUDIOstatic void output_sound(unsigned int sample_rate, const char *ifname){        audio_info_t audioinfo;        audio_info_t audioinfo2;	audio_device_t audiodev;	int fd;	short buffer[8192];	short *sp;	int i, num, num2;	if ((fd = open(ifname ? ifname : "/dev/audio", O_WRONLY)) < 0) {		perror("open");		exit (10);	}        if (ioctl(fd, AUDIO_GETDEV, &audiodev) == -1) {		perror("ioctl: AUDIO_GETDEV");		exit (10);        }        AUDIO_INITINFO(&audioinfo);        audioinfo.record.sample_rate = sample_rate;        audioinfo.record.channels = 1;        audioinfo.record.precision = 16;        audioinfo.record.encoding = AUDIO_ENCODING_LINEAR;        /*audioinfo.record.gain = 0x20;	  audioinfo.record.port = AUDIO_LINE_IN;	  audioinfo.monitor_gain = 0;*/        if (ioctl(fd, AUDIO_SETINFO, &audioinfo) == -1) {		perror("ioctl: AUDIO_SETINFO");		exit (10);        }             if (ioctl(fd, I_FLUSH, FLUSHW) == -1) {		perror("ioctl: I_FLUSH");		exit (10);        }        if (ioctl(fd, AUDIO_GETINFO, &audioinfo2) == -1) {		perror("ioctl: AUDIO_GETINFO");		exit (10);        }        fprintf(stdout, "Audio device: name %s, ver %s, config %s, "		"sampling rate %d\n", audiodev.name, audiodev.version,		audiodev.config, audioinfo.record.sample_rate);	do {		num2 = num = process_buffer(sp = buffer, sizeof(buffer)/sizeof(buffer[0]));		while (num > 0) {			i = write(fd, sp, num*sizeof(sp[0]));			if (i < 0 && errno != EAGAIN) {				perror("write");				exit(4);			}			if (i > 0) {				if (i % sizeof(sp[0]))					fprintf(stderr, "gen: warning: write wrote noninteger number of samples\n");				num -= i / sizeof(sp[0]);			}		}	} while (num2 > 0);	close(fd);}#else /* SUN_AUDIO *//* ---------------------------------------------------------------------- */static void output_sound(unsigned int sample_rate, const char *ifname){        int sndparam;	int fd;	union {		short s[8192];		unsigned char b[8192];	} b;	int i;	short *sp;	unsigned char *bp;	int fmt = 0, num, num2;	if ((fd = open(ifname ? ifname : "/dev/dsp", O_WRONLY)) < 0) {		perror("open");		exit (10);	}        sndparam = AFMT_S16_LE; /* we want 16 bits/sample signed */        /* little endian; works only on little endian systems! */        if (ioctl(fd, SNDCTL_DSP_SETFMT, &sndparam) == -1) {		perror("ioctl: SNDCTL_DSP_SETFMT");		exit (10);	}        if (sndparam != AFMT_S16_LE) {		fmt = 1;		sndparam = AFMT_U8;		if (ioctl(fd, SNDCTL_DSP_SETFMT, &sndparam) == -1) {			perror("ioctl: SNDCTL_DSP_SETFMT");			exit (10);		}		if (sndparam != AFMT_U8) {			perror("ioctl: SNDCTL_DSP_SETFMT");			exit (10);		}        }        sndparam = 0;   /* we want only 1 channel */        if (ioctl(fd, SNDCTL_DSP_STEREO, &sndparam) == -1) {		perror("ioctl: SNDCTL_DSP_STEREO");		exit (10);	}        if (sndparam != 0) {                fprintf(stderr, "gen: Error, cannot set the channel "                        "number to 1\n");                exit (10);        }        sndparam = sample_rate;         if (ioctl(fd, SNDCTL_DSP_SPEED, &sndparam) == -1) {		perror("ioctl: SNDCTL_DSP_SPEED");		exit (10);	}        if ((10*abs(sndparam-sample_rate)) > sample_rate) {		perror("ioctl: SNDCTL_DSP_SPEED");		exit (10);	}        if (sndparam != sample_rate) {                fprintf(stderr, "Warning: Sampling rate is %u, "                        "requested %u\n", sndparam, sample_rate);        }#if 0        sndparam = 4;        if (ioctl(fd, SOUND_PCM_SUBDIVIDE, &sndparam) == -1) {		perror("ioctl: SOUND_PCM_SUBDIVIDE");        }        if (sndparam != 4) {		perror("ioctl: SOUND_PCM_SUBDIVIDE");	}#endif	do {		num2 = num = process_buffer(b.s, sizeof(b.s)/sizeof(b.s[0]));		if (fmt) {			for (bp = b.b, sp = b.s, i = sizeof(b.s)/sizeof(b.s[0]); i > 0; i--, bp++, sp++)				*bp = 0x80 + (*sp >> 8);			bp = b.b;			while (num > 0) {				i = write(fd, bp, num*sizeof(bp[0]));				if (i < 0 && errno != EAGAIN) {					perror("write");					exit(4);				}				if (i > 0) {					if (i % sizeof(bp[0]))						fprintf(stderr, "gen: warning: write wrote noninteger number of samples\n");					num -= i / sizeof(bp[0]);				}			}		} else {			sp = b.s;			while (num > 0) {				i = write(fd, sp, num*sizeof(sp[0]));				if (i < 0 && errno != EAGAIN) {					perror("write");					exit(4);				}				if (i > 0) {					if (i % sizeof(sp[0]))						fprintf(stderr, "gen: warning: write wrote noninteger number of samples\n");					num -= i / sizeof(sp[0]);				}			}		}	} while (num2 > 0);	close(fd);}#endif /* SUN_AUDIO *//* ---------------------------------------------------------------------- */static void output_file(unsigned int sample_rate, const char *fname, const char *type){	struct stat statbuf;	int pipedes[2];	int pid = 0, soxstat;	int fd;	int i, num, num2;	short buffer[8192];		short *sp;	/*	 * if the input type is not raw, sox is started to convert the	 * samples to the requested format	 */	if (!type || !strcmp(type, "raw")) {		if ((fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0777)) < 0) {			perror("open");			exit(10);		}	} else {		if (stat(fname, &statbuf)) {			perror("stat");			exit(10);		}		if (pipe(pipedes)) {			perror("pipe");			exit(10);		}		if (!(pid = fork())) {			char srate[8];			/*			 * child starts here... first set up filedescriptors,			 * then start sox...			 */			snprintf(srate, sizeof(srate), "%d", sample_rate);			close(pipedes[1]); /* close writing pipe end */			close(0); /* close standard input */			if (dup2(pipedes[0], 0) < 0) 				perror("dup2");			close(pipedes[0]); /* close reading pipe end */			execlp("sox", "sox", 			       "-t", "raw",  "-s", "-w", "-r", srate, "-",			       "-t", type, fname,			       NULL);			perror("execlp");			exit(10);		}		if (pid < 0) {			perror("fork");			exit(10);		}		close(pipedes[0]); /* close reading pipe end */		fd = pipedes[1];	}	/*	 * modulate	 */	do {		num2 = num = process_buffer(sp = buffer, sizeof(buffer)/sizeof(buffer[0]));		while (num > 0) {			i = write(fd, sp, num*sizeof(sp[0]));			if (i < 0 && errno != EAGAIN) {				perror("write");				exit(4);			}			if (i > 0) {				if (i % sizeof(sp[0]))					fprintf(stderr, "gen: warning: write wrote noninteger number of samples\n");				num -= i / sizeof(sp[0]);			}		}	} while (num2 > 0);	close(fd);	waitpid(pid, &soxstat, 0);}/* ---------------------------------------------------------------------- */static const char usage_str[] = "gen\n""Generates test signals\n""(C) 1997 by Thomas Sailer HB9JNX/AE4WA\n""  -t <type>  : input file type (any other type than raw requires sox)\n""  -a <ampl>  : amplitude\n""  -d <str>   : encode DTMF string\n""  -z <str>   : encode ZVEI string\n""  -s <freq>  : encode sine\n""  -p <text>  : encode hdlc packet\n";void main(int argc, char *argv[]){	int c;	int errflg = 0;	char **otype;	char *output_type = "hw";	char *cp;	fprintf(stdout, "gen - (C) 1997 by Tom Sailer HB9JNX/AE4WA\n");		while ((c = getopt(argc, argv, "t:a:d:s:z:p:")) != EOF) {		switch (c) {		case '?':			errflg++;			break;					case 't':			for (otype = (char **)allowed_types; *otype; otype++) 				if (!strcmp(*otype, optarg)) {					output_type = *otype;					goto outtypefound;				}			fprintf(stderr, "invalid output type \"%s\"\n"				"allowed types: ", optarg);			for (otype = (char **)allowed_types; *otype; otype++) 				fprintf(stderr, "%s ", *otype);			fprintf(stderr, "\n");			errflg++;		outtypefound:			break;		case 'a':			if (num_gen <= 0) {				fprintf(stderr, "gen: no generator selected\n");				errflg++;			} 			if (!(cp = strstr(optarg, "dB")))				cp = strstr(optarg, "db");			if (cp) {				*cp = '\0';				params[num_gen-1].ampl = 16384.0 * pow(10.0, strtod(optarg, NULL) / 20.0);			} else {				params[num_gen-1].ampl = 16384.0 * strtod(optarg, NULL);			}			break;		case 'd':			num_gen++;			if (num_gen > MAX_GEN) {				fprintf(stderr, "too many generators\n");				errflg++;				break;			}			params[num_gen-1].type = gentype_dtmf;			params[num_gen-1].ampl = 16384;			params[num_gen-1].p.dtmf.duration = MS(100);			params[num_gen-1].p.dtmf.pause = MS(100);			strncpy(params[num_gen-1].p.dtmf.str, optarg, sizeof(params[num_gen-1].p.dtmf.str));			break;		case 's':			num_gen++;			if (num_gen > MAX_GEN) {				fprintf(stderr, "too many generators\n");				errflg++;				break;			}			params[num_gen-1].type = gentype_sine;			params[num_gen-1].ampl = 16384;			params[num_gen-1].p.sine.duration = MS(1000);			params[num_gen-1].p.sine.freq = strtoul(optarg, NULL, 0);			break;		case 'z':			num_gen++;			if (num_gen > MAX_GEN) {				fprintf(stderr, "too many generators\n");				errflg++;				break;			}			params[num_gen-1].type = gentype_zvei;			params[num_gen-1].ampl = 16384;			params[num_gen-1].p.zvei.duration = MS(50);			params[num_gen-1].p.zvei.pause = MS(50);			strncpy(params[num_gen-1].p.zvei.str, optarg, sizeof(params[num_gen-1].p.dtmf.str));			break;		case 'p':			num_gen++;			if (num_gen > MAX_GEN) {				fprintf(stderr, "too many generators\n");				errflg++;				break;			}			params[num_gen-1].type = gentype_hdlc;			params[num_gen-1].ampl = 16384;			params[num_gen-1].p.hdlc.modulation = 0;			params[num_gen-1].p.hdlc.txdelay = 100;			params[num_gen-1].p.hdlc.pkt[0] = ('H') << 1;			params[num_gen-1].p.hdlc.pkt[1] = ('B') << 1;			params[num_gen-1].p.hdlc.pkt[2] = ('9') << 1;			params[num_gen-1].p.hdlc.pkt[3] = ('J') << 1;			params[num_gen-1].p.hdlc.pkt[4] = ('N') << 1;			params[num_gen-1].p.hdlc.pkt[5] = ('X') << 1;			params[num_gen-1].p.hdlc.pkt[6] = (0x00) << 1;			params[num_gen-1].p.hdlc.pkt[7] = ('A') << 1;			params[num_gen-1].p.hdlc.pkt[8] = ('E') << 1;			params[num_gen-1].p.hdlc.pkt[9] = ('4') << 1;			params[num_gen-1].p.hdlc.pkt[10] = ('W') << 1;			params[num_gen-1].p.hdlc.pkt[11] = ('A') << 1;			params[num_gen-1].p.hdlc.pkt[12] = (' ') << 1;			params[num_gen-1].p.hdlc.pkt[13] = ((0x00) << 1) | 1;			params[num_gen-1].p.hdlc.pkt[14] = 0x03;			params[num_gen-1].p.hdlc.pkt[15] = 0xf0;			strncpy(params[num_gen-1].p.hdlc.pkt+16, optarg, 				sizeof(params[num_gen-1].p.hdlc.pkt)-16);			params[num_gen-1].p.hdlc.pktlen = 16 + 				strlen(params[num_gen-1].p.hdlc.pkt+16);		}	}			if (errflg || num_gen <= 0) {		(void)fprintf(stderr, usage_str);		exit(2);	}	memset(state, 0, sizeof(state));	for (c = 0; c < num_gen; c++) {		if (params[c].type >= sizeof(init_procs)/sizeof(init_procs[0]))			break;		if (!init_procs[params[c].type])			break;		init_procs[params[c].type](params+c, state+c);	}	if (!strcmp(output_type, "hw")) {		if ((argc - optind) >= 1)			output_sound(SAMPLE_RATE, argv[optind]);		else 			output_sound(SAMPLE_RATE, NULL);		exit(0);	}	if ((argc - optind) < 1) {		(void)fprintf(stderr, "no destination file specified\n");		exit(4);	}	output_file(SAMPLE_RATE, argv[optind], output_type);	exit(0);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -