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

📄 audbri_utils.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
#ident   "@(#)audbri_utils.c 1.1 92/07/30 SMI"/* * Copyright (C) 1992 by Sun Microsystems, Inc. *//* *  Utility routines for DBRI/MMCODEC audio tests. */#include <stdio.h>#include <fcntl.h>#include <stropts.h>#include <errno.h>#include <math.h>#include <sys/types.h>#include <sys/file.h>#include <sys/ioctl.h>#include <sys/asynch.h>#include <sys/stat.h>#include <sys/mman.h>#include <sys/time.h>/* #include <sun/audioio.h> ...not there yet... */#include "audioio.h"#include "sdrtns.h"#include "../../../lib/include/libonline.h"#include "audbri.h"#include "audbri_msg.h"#include "audbri_g711.h"extern	int	bin_sel;extern	double	lbins[],rbins[],lrms,rrms;/* *  Calculate calibration and loopback offset (in shorts) into signal. */intcalc_offset(auptr)au_data_t	*auptr;{	int	chancnt, offset;	func_name = "calc_offset";	TRACE_IN	if (auptr->channels == MONO) {		chancnt = 1;	}	else {		chancnt = 2;	}	offset = .75 * (chancnt * auptr->sample_rate);	TRACE_OUT	return(offset);}/* *  Calculate signal's RMS value. */doublermscalc(sigptr, sample_cnt)short	*sigptr;int	sample_cnt;{	int	i;	double	sum;	func_name = "rmscalc";	TRACE_IN	/*	 *  Calculate RMS	 */	for (i = 0, sum = 0; i < sample_cnt; sigptr++, i++) {		sum = sum + ((double) *sigptr) * ((double) *sigptr);	}	sum = sum / sample_cnt;	sum = sqrt(sum);	/*	 *  Convert to db.	 */	sum = 20 * log10(sum);	TRACE_OUT	return(sum);}/* *  Returns the maximum fft magnitude for a given frequency range */doublebandrms(magp, fsize, size, start, end, sr)double	*magp;int	fsize;int	size;int	start;int	end;int	sr;{	int	i, lower_slot, upper_slot, tmp_slot;	double	sum, tmp, save;	func_name = "bandrms";	TRACE_IN	/*	 *  Determine starting and ending fft magnitude slots for 	 * this frequency range.	 */	if (start == 0) {		lower_slot = 0;	}	else {		lower_slot = rint((double) (((double) start * 			(double) size) / (double) sr));	}	if (end == END_FREQ) {		upper_slot = fsize;	}	else {		upper_slot = rint((double) (((double) end * 			(double) size) / (double) sr));	}	/*	 *  Determine the RMS for this band.	 */	if (lower_slot > upper_slot) {	    tmp_slot = upper_slot;	    upper_slot = lower_slot;	    lower_slot = tmp_slot;	}	    	sum = 0;	for (i = lower_slot; i <= upper_slot; i++) {		tmp = exp10(magp[i]/20);		sum = sum + (tmp * tmp);	}	sum = sum / (upper_slot - lower_slot + 1);	sum = sqrt(sum);	/*	 *  Convert to db.	 */	sum = 20 * log10(sum);	TRACE_OUT	return(sum);}/* *  Generate a sine wave of given frequency, sample_rate and duration * allocated for the signal (an array of doubles) and pointed to by  * 'signal'.  The signal produced will be scaled to the range  * specified by the value 'maxval'.  'maxval' is the maximum value * the signal have.  */intgensine(freq, srate, dur, sigptr, maxval)int		freq;	/* Hz */int		srate;	/* Hz */int		dur;	/* seconds */short		**sigptr;int		maxval;{	int	i, sample_cnt;	short	*sptr;	double	radians, samples_per_cycle;	func_name = "gensine";	TRACE_IN	if (freq != 0) {		samples_per_cycle = (double) srate / (double) freq;	}	sample_cnt = srate * dur;	/*	 *  get space for the signal	 */	if ((*sigptr = (short *) calloc(sample_cnt, sizeof(short))) == NULL) {		send_message(ERSYS, ERROR, er_mem, 			(sizeof(short)*sample_cnt), SYSMSG);	}	/*	 *  make the signal	 */	for (i = 0, sptr=*sigptr; i < sample_cnt;) {		if (freq == 0) {			*sptr++ = 0;			i++;		}		else {			for (radians = 0; radians < (2*M_PI), i < sample_cnt; 					i++, radians += 					(2*M_PI)/samples_per_cycle ) {				*sptr++ = (short) (sin(radians) * 					(double) maxval);			}		}	}	TRACE_OUT	return(sample_cnt);}/* *  Generate a stereo (2 channel) signal from 2 mono signals.  If a NULL * is passed for either channel then that channel is filled with zeros. */intgenstereo(lsigptr, rsigptr, ssigptr, sample_cnt)short		*lsigptr, *rsigptr;short		**ssigptr;int		sample_cnt;{	int	i, st_sample_cnt;	short	*sptr;	func_name = "genstereo";	TRACE_IN	st_sample_cnt = 2*sample_cnt;	/*	 *  get space for the signal	 */	if ((*ssigptr = (short *) calloc(st_sample_cnt, 			sizeof(short))) == NULL) {		send_message(ERSYS, ERROR, er_mem, 			(sizeof(short)*st_sample_cnt), SYSMSG);	}	/*	 *  make the signal	 */	for (i = 0, sptr=*ssigptr; i < sample_cnt; i++) {		*sptr++ = (lsigptr ? *lsigptr++ : 0);		*sptr++ = (rsigptr ? *rsigptr++ : 0);	}	TRACE_OUT	return(st_sample_cnt);}/* *  Generate a signal to play, either mono or stereo depending upon * the contents of the au_data_t structure. */intgensig(auptr, sigptr, duration)au_data_t	*auptr;short		**sigptr;int		duration;{	short	*lsig, *rsig;	int	sample_cnt;	func_name = "gensig";	TRACE_IN	/*	 *  Generate left channel signal.	 */	sample_cnt = gensine(auptr->lfreq, auptr->sample_rate, 		duration, &lsig, MAXPCM);	/*	 *  MONO signals just use left channel data from the au_data_t.	 */	if (auptr->channels == MONO) {		*sigptr = lsig;	}	/*	 *  Generate right side also if this is STEREO	 */	else {		(void) gensine(auptr->rfreq, auptr->sample_rate, duration, 			&rsig, MAXPCM);		sample_cnt = genstereo(lsig, rsig, sigptr, sample_cnt);	}	TRACE_OUT	return(sample_cnt);}/* *  Split a stereo (2 channel) signal into 2 mono signals. */voidsplitstereo(lsigptr, rsigptr, ssigptr, sample_cnt)short		**lsigptr, **rsigptr;short		*ssigptr;int		sample_cnt;{	int	i;	short	*lptr, *rptr;	func_name = "splitstereo";	TRACE_IN	sample_cnt = sample_cnt / 2;	/*	 *  get space for mono signals	 */	if ((*lsigptr = (short *) calloc(sample_cnt, 			sizeof(short))) == NULL) {		send_message(ERSYS, ERROR, er_mem, 			(sizeof(short)*sample_cnt), SYSMSG);	}	if ((*rsigptr = (short *) calloc(sample_cnt, 			sizeof(short))) == NULL) {		send_message(ERSYS, ERROR, er_mem, 			(sizeof(short)*sample_cnt), SYSMSG);	}	/*	 *  split the signal	 */	for (i = 0, lptr=*lsigptr, rptr=*rsigptr; i < sample_cnt; i++) {		*lptr++ = *ssigptr++;		*rptr++ = *ssigptr++;	}	TRACE_OUT}/* *  Play data.  Doesn't return until the play is completed. */intplay(psig, sample_cnt, precision)caddr_t	psig;int	sample_cnt;int	precision;{	int		i, err, wcnt, write_size, size, count;	audio_info_t	info;	struct timeval  begin_tp, end_tp;	long		time;	func_name = "play";	TRACE_IN	if (precision == 16) {		size = sample_cnt * sizeof(short);	/* we're writing shorts */	}	else {		size = sample_cnt;	}	/*	 *  unpause	 */	AUDIO_INITINFO(&info);	info.play.pause = 0;	if (ioctl(audiofd, AUDIO_SETINFO, &info) < 0) {		send_message(ERSYS, ERROR, er_ioctl, "AUDIO_SETINFO", SYSMSG);	}		/*	 *  play, continue on EINTR	 */	(void) gettimeofday(&begin_tp, NULL);	count = 0;	while (count < size && dc_flag != 4) {		if (play_size > size - count) {			write_size = size - count;		}		else {			write_size = play_size;		}		/*		 *  Restart write if error in EINTR.		 */		do {			wcnt = write(audiofd, psig, write_size);			if (wcnt == -1 && errno != EINTR) {				send_message(ERSYS, ERROR, er_write, SYSMSG);			}		} while(wcnt == -1);		count += wcnt;		psig += wcnt;	}	/*	 *  wait for completion or controls test completion (dc_flag), 	 * continue on EINTR	 */	while (dc_flag != 4 && (err = ioctl(audiofd, 				AUDIO_DRAIN, NULL)) != 0) {		if (err == -1 && errno != EINTR) {			send_message(ERSYS, ERROR, er_ioctl, 				"AUDIO_DRAIN", SYSMSG);		}				}	(void) gettimeofday(&end_tp, NULL);	time = (long) intervalcalc(&begin_tp, &end_tp);	/*	 *  pause play	 */	AUDIO_INITINFO(&info);	info.play.pause = 1;	if (ioctl(audiofd, AUDIO_SETINFO, &info) < 0) {		send_message(ERSYS, ERROR, er_ioctl, "AUDIO_SETINFO", SYSMSG);	}		/*	 *  flush the audio stream	 */	if (ioctl(audiofd, I_FLUSH, FLUSHW) < 0) {		send_message(ERSYS, ERROR, er_ioctl, "I_FLUSH", SYSMSG);	}	TRACE_OUT	return((int) time);}/* *  Play and record data at the same time.  This routine is used * for loopback tests.  This routine expects psig to point to a 16 bit * PCM signal and returns a pointer to a 16 bit PCM signal in *rsig. * *  The variable auptr->encoding determines what type of signal is * actually played and recorded. */voidplayrecord(psig, rsig, sample_cnt, dur, auptr)short	*psig;short	**rsig;int	sample_cnt;int	dur;au_data_t	*auptr;{	aio_result_t	aw_result, ar_result;	struct timeval	timeout;	int		i, sample_size;	audio_info_t	info;	u_char		*play_sig, *record_sig, *tmptr;	short		*sptr;	func_name = "playrecord";	TRACE_IN	/*	 *  Convert play signal to encoding indicated by auptr->encoding	 */	switch (auptr->encoding) {	  case AUDIO_ENCODING_ULAW:		/*		 *  Make sure precision is 8.		 */		if (auptr->precision != 8) {			send_message(ERAUDIO, ERROR, er_precision);		}					/*		 *  get space for the signal		 */		sample_size = sizeof(char);		if ((play_sig = (u_char *) calloc(sample_cnt, 				sample_size)) == NULL) {			send_message(ERSYS, ERROR, er_mem, sample_cnt, SYSMSG);		}		/*		 *  Convert play signal to ulaw.		 */		tmptr = play_sig;		for (i = 0; i < sample_cnt; i++) {			*tmptr++ = audio_s2u(*psig++);		}		break;	  case AUDIO_ENCODING_ALAW:		/*		 *  Make sure precision is 8.		 */		if (auptr->precision != 8) {			send_message(ERAUDIO, ERROR, er_precision);		}					/*		 *  get space for the signal		 */		sample_size = sizeof(char);		if ((play_sig = (u_char *) calloc(sample_cnt, 				sample_size)) == NULL) {			send_message(ERSYS, ERROR, er_mem, sample_cnt, SYSMSG);		}		/*		 *  Convert play signal to alaw.		 */		tmptr = play_sig;		for (i = 0; i < sample_cnt; i++) {			*tmptr++ = audio_s2a(*psig++);		}		break;	  case AUDIO_ENCODING_LINEAR:		play_sig = (u_char *) psig;		sample_size = sizeof(short);		break;	  default:		send_message(ERAUDIO, ERROR, er_encoding);		break;	}	/*	 *  get space for the recorded signal	 */	if ((record_sig = (u_char *) calloc(sample_cnt, sample_size)) == NULL) {		send_message(ERSYS, ERROR, er_mem, 			(sample_size*sample_cnt), SYSMSG);	}	/*	 *  set up unpause	 */	AUDIO_INITINFO(&info);	info.play.pause = 0;	info.record.pause = 0;	/*	 *  initialize aio results	 */	aw_result.aio_return = ar_result.aio_return = AIO_INPROGRESS;	/*	 *  start play	 */	if (aiowrite(audiofd, play_sig, sample_size*sample_cnt, 		0, 0, &aw_result) == -1) {		send_message(ERSYS, ERROR, er_aiowrite, SYSMSG);	}	/*	 *  unpause record and play	 */	if (ioctl(audiofd, AUDIO_SETINFO, &info) < 0) {		send_message(ERSYS, ERROR, er_ioctl, "AUDIO_SETINFO", SYSMSG);	}		/*	 *  start record	 */	if (aioread(audiofd, record_sig, sample_size*sample_cnt, 			0, 0, &ar_result) == -1) {		send_message(ERSYS, ERROR, er_aioread, SYSMSG);	}	/*	 *  wait for completion	 */	i = 0;	do {		timeout.tv_sec = dur;		timeout.tv_usec = 0;		if (aiowait(&timeout) == -1) {			if (errno == EINVAL) {  /* nothing to wait for */				break;			}			send_message(ERSYS, ERROR, er_aiowait, SYSMSG);		}		i++;	} while ((i<aioto_cnt) && (aw_result.aio_return == AIO_INPROGRESS ||	ar_result.aio_return == AIO_INPROGRESS));	/*	 *  wait for play to "drain"	 */	if (ioctl(audiofd, AUDIO_DRAIN, NULL) < 0) {		send_message(ERSYS, ERROR, er_ioctl, "AUDIO_DRAIN", SYSMSG);	}		/*	 *  pause record and play	 */	AUDIO_INITINFO(&info);	info.play.pause = 1;	info.record.pause = 1;	if (ioctl(audiofd, AUDIO_SETINFO, &info) < 0) {		send_message(ERSYS, ERROR, er_ioctl, "AUDIO_SETINFO", SYSMSG);	}		/*	 *  see if aiowrite and aioread completed ok	 */	if (aw_result.aio_return == AIO_INPROGRESS || 			aw_result.aio_return == -1) {		(void) aiocancel(&aw_result);		send_message(ERSYS, ERROR, er_aiowrite, SYSMSG);	}		if (ar_result.aio_return == AIO_INPROGRESS ||			ar_result.aio_return == -1) {		(void) aiocancel(&ar_result);		send_message(ERSYS, ERROR, er_aioread, SYSMSG);	}	/*	 *  See if all data was written	 */	if (aw_result.aio_return != sample_cnt*sample_size) {		send_message(ERAUDIO, ERROR, er_aiowritep, 			aw_result.aio_return, sample_cnt*sample_size);	}	/*	 *  See if all data was read	 */	if (ar_result.aio_return != sample_cnt*sample_size) {		send_message(ERAUDIO, ERROR, er_aioreadp, 			ar_result.aio_return, sample_cnt*sample_size);	}

⌨️ 快捷键说明

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