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

📄 unixinput.c

📁 DTMF编解码程序,linux环境下
💻 C
字号:
/* *      unixinput.c -- input sound samples * *      Copyright (C) 1996   *          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 "multimon.h"#include <stdio.h>#include <stdarg.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <unistd.h>#include <errno.h>#include <string.h>#include <sys/wait.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 *//* ---------------------------------------------------------------------- */static const char *allowed_types[] = {	"raw", "aiff", "au", "hcom", "sf", "voc", "cdr", "dat", 	"smp", "wav", "maud", "vwe", NULL};/* ---------------------------------------------------------------------- */static const struct demod_param *dem[] = { ALL_DEMOD };#define NUMDEMOD (sizeof(dem)/sizeof(dem[0]))static struct demod_state dem_st[NUMDEMOD];static unsigned int dem_mask[(NUMDEMOD+31)/32];#define MASK_SET(n) dem_mask[(n)>>5] |= 1<<((n)&0x1f)#define MASK_RESET(n) dem_mask[(n)>>5] &= ~(1<<((n)&0x1f))#define MASK_ISSET(n) (dem_mask[(n)>>5] & 1<<((n)&0x1f))/* ---------------------------------------------------------------------- */static int verbose_level = 0;/* ---------------------------------------------------------------------- */void verbprintf(int verb_level, const char *fmt, ...){        va_list args;                va_start(args, fmt);        if (verb_level <= verbose_level)                vfprintf(stdout, fmt, args);        va_end(args);}/* ---------------------------------------------------------------------- */static void process_buffer(float *buf, unsigned int len){	int i;	for (i = 0; i <  NUMDEMOD; i++) 		if (MASK_ISSET(i) && dem[i]->demod)			dem[i]->demod(dem_st+i, buf, len);}/* ---------------------------------------------------------------------- */#ifdef SUN_AUDIOstatic void input_sound(unsigned int sample_rate, unsigned int overlap,			const char *ifname){        audio_info_t audioinfo;        audio_info_t audioinfo2;	audio_device_t audiodev;	int fd;	short buffer[8192];	float fbuf[16384];	unsigned int fbuf_cnt = 0;	int i;	short *sp;	if ((fd = open(ifname ? ifname : "/dev/audio", O_RDONLY)) < 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, FLUSHR) == -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);	for (;;) {		i = read(fd, sp = buffer, sizeof(buffer));		if (i < 0 && errno != EAGAIN) {			perror("read");			exit(4);		}		if (!i)			break;		if (i > 0) {			for (; i >= sizeof(buffer[0]); i -= sizeof(buffer[0]), sp++)				fbuf[fbuf_cnt++] = (*sp) * (1.0/32768.0);			if (i)				fprintf(stderr, "warning: noninteger number of samples read\n");			if (fbuf_cnt > overlap) {				process_buffer(fbuf, fbuf_cnt-overlap);				memmove(fbuf, fbuf+fbuf_cnt-overlap, overlap*sizeof(fbuf[0]));				fbuf_cnt = overlap;			}		}	}	close(fd);}#else /* SUN_AUDIO *//* ---------------------------------------------------------------------- */static void input_sound(unsigned int sample_rate, unsigned int overlap,			const char *ifname){        int sndparam;	int fd;	union {		short s[8192];		unsigned char b[8192];	} b;	float fbuf[16384];	unsigned int fbuf_cnt = 0;	int i;	short *sp;	unsigned char *bp;	int fmt = 0;	if ((fd = open(ifname ? ifname : "/dev/dsp", O_RDONLY)) < 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, "soundif: 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	for (;;) {		if (fmt) {			i = read(fd, bp = b.b, sizeof(b.b));			if (i < 0 && errno != EAGAIN) {				perror("read");				exit(4);			}			if (!i)				break;			if (i > 0) {				for (; i >= sizeof(b.b[0]); i -= sizeof(b.b[0]), sp++)					fbuf[fbuf_cnt++] = ((int)(*bp)-0x80) * (1.0/128.0);				if (i)					fprintf(stderr, "warning: noninteger number of samples read\n");				if (fbuf_cnt > overlap) {					process_buffer(fbuf, fbuf_cnt-overlap);					memmove(fbuf, fbuf+fbuf_cnt-overlap, overlap*sizeof(fbuf[0]));					fbuf_cnt = overlap;				}			}		} else {			i = read(fd, sp = b.s, sizeof(b.s));			if (i < 0 && errno != EAGAIN) {				perror("read");				exit(4);			}			if (!i)				break;			if (i > 0) {				for (; i >= sizeof(b.s[0]); i -= sizeof(b.s[0]), sp++)					fbuf[fbuf_cnt++] = (*sp) * (1.0/32768.0);				if (i)					fprintf(stderr, "warning: noninteger number of samples read\n");				if (fbuf_cnt > overlap) {					process_buffer(fbuf, fbuf_cnt-overlap);					memmove(fbuf, fbuf+fbuf_cnt-overlap, overlap*sizeof(fbuf[0]));					fbuf_cnt = overlap;				}			}		}	}	close(fd);}#endif /* SUN_AUDIO *//* ---------------------------------------------------------------------- */static void input_file(unsigned int sample_rate, unsigned int overlap,		       const char *fname, const char *type){	struct stat statbuf;	int pipedes[2];	int pid = 0, soxstat;	int fd;	int i;	short buffer[8192];	float fbuf[16384];	unsigned int fbuf_cnt = 0;	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_RDONLY)) < 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...			 */			sprintf(srate, "%d", sample_rate);			close(pipedes[0]); /* close reading pipe end */			close(1); /* close standard output */			if (dup2(pipedes[1], 1) < 0) 				perror("dup2");			close(pipedes[1]); /* close writing pipe end */			execlp("sox", "sox", 			       "-t", type, fname,			       "-t", "raw", "-s", "-w", "-r", srate, "-",			       NULL);			perror("execlp");			exit(10);		}		if (pid < 0) {			perror("fork");			exit(10);		}		close(pipedes[1]); /* close writing pipe end */		fd = pipedes[0];	}	/*	 * demodulate	 */	for (;;) {		i = read(fd, sp = buffer, sizeof(buffer));		if (i < 0 && errno != EAGAIN) {			perror("read");			exit(4);		}		if (!i)			break;		if (i > 0) {			for (; i >= sizeof(buffer[0]); i -= sizeof(buffer[0]), sp++)				fbuf[fbuf_cnt++] = (*sp) * (1.0/32768.0);			if (i)				fprintf(stderr, "warning: noninteger number of samples read\n");			if (fbuf_cnt > overlap) {				process_buffer(fbuf, fbuf_cnt-overlap);				memmove(fbuf, fbuf+fbuf_cnt-overlap, overlap*sizeof(fbuf[0]));				fbuf_cnt = overlap;			}		}	}	close(fd);	waitpid(pid, &soxstat, 0);}/* ---------------------------------------------------------------------- */static const char usage_str[] = "multimod\n""Demodulates many different radio transmission formats\n""(C) 1996 by Thomas Sailer HB9JNX/AE4WA\n""  -t <type>  : input file type (any other type than raw requires sox)\n""  -a <demod> : add demodulator\n""  -s <demod> : subtract demodulator\n";int main(int argc, char *argv[]){	int c;	int errflg = 0;	int i;	char **itype;	int mask_first = 1;	int sample_rate = -1;	unsigned int overlap = 0;	char *input_type = "hw";	fprintf(stdout, "multimod  (C) 1996/1997 by Tom Sailer HB9JNX/AE4WA\n"		"available demodulators:");	for (i = 0; i < NUMDEMOD; i++) 		fprintf(stdout, " %s", dem[i]->name);	fprintf(stdout, "\n");	while ((c = getopt(argc, argv, "t:a:s:v:")) != EOF) {		switch (c) {		case '?':			errflg++;			break;		case 'v':			verbose_level = strtoul(optarg, 0, 0);			break;		case 't':			for (itype = (char **)allowed_types; *itype; itype++) 				if (!strcmp(*itype, optarg)) {					input_type = *itype;					goto intypefound;				}			fprintf(stderr, "invalid input type \"%s\"\n"				"allowed types: ", optarg);			for (itype = (char **)allowed_types; *itype; itype++) 				fprintf(stderr, "%s ", *itype);			fprintf(stderr, "\n");			errflg++;		intypefound:			break;				case 'a':			if (mask_first)				memset(dem_mask, 0, sizeof(dem_mask));			mask_first = 0;			for (i = 0; i < NUMDEMOD; i++)				if (!strcasecmp(optarg, dem[i]->name)) {					MASK_SET(i);					break;				}			if (i >= NUMDEMOD) {				fprintf(stderr, "invalid mode \"%s\"\n", optarg);				errflg++;			}			break;		case 's':			if (mask_first)				memset(dem_mask, 0xff, sizeof(dem_mask));			mask_first = 0;			for (i = 0; i < NUMDEMOD; i++)				if (!strcasecmp(optarg, dem[i]->name)) {					MASK_RESET(i);					break;				}			if (i >= NUMDEMOD) {				fprintf(stderr, "invalid mode \"%s\"\n", optarg);				errflg++;			}			break;					}	}	if (errflg) {		(void)fprintf(stderr, usage_str);		exit(2);	}	if (mask_first)		memset(dem_mask, 0xff, sizeof(dem_mask));	fprintf(stdout, "Enabled demodulators:");	for (i = 0; i < NUMDEMOD; i++) 		if (MASK_ISSET(i)) {			fprintf(stdout, " %s", dem[i]->name);			memset(dem_st+i, 0, sizeof(dem_st[i]));			dem_st[i].dem_par = dem[i];			if (dem[i]->init)				dem[i]->init(dem_st+i);			if (sample_rate == -1)				sample_rate = dem[i]->samplerate;			else if (sample_rate != dem[i]->samplerate) {				fprintf(stdout, "\n");				fprintf(stderr, "Error: Current sampling rate %d, "					" demodulator \"%s\" requires %d\n",					sample_rate, dem[i]->name, dem[i]->samplerate);				exit(3);			}			if (dem[i]->overlap > overlap)				overlap = dem[i]->overlap;		}	fprintf(stdout, "\n");	if (!strcmp(input_type, "hw")) {		if ((argc - optind) >= 1)			input_sound(sample_rate, overlap, argv[optind]);		else 			input_sound(sample_rate, overlap, NULL);		exit(0);	}	if ((argc - optind) < 1) {		(void)fprintf(stderr, "no source files specified\n");		exit(4);	}	for (i = optind; i < argc; i++)		input_file(sample_rate, overlap, argv[i], input_type);	exit(0);}/* ---------------------------------------------------------------------- */

⌨️ 快捷键说明

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