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

📄 audbri_utils.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
	/*	 *  flush the audio stream	 */	if (ioctl(audiofd, I_FLUSH, FLUSHRW) < 0) {		send_message(ERSYS, ERROR, er_ioctl, "I_FLUSH", SYSMSG);	}	/*	 *  Convert recorded signal to linear encoding (unless it's	 * already linear).	 */	switch (auptr->encoding) {	  case AUDIO_ENCODING_ULAW:		/*		 *  get space for the signal		 */		if ((*rsig = (short *) calloc(sample_cnt, 				sizeof(short))) == NULL) {			send_message(ERSYS, ERROR, er_mem, 				sample_cnt*sizeof(short), SYSMSG);		}		/*		 *  Convert recorded signal to 16 bit PCM.		 */		tmptr = record_sig;		sptr = *rsig;		for (i = 0; i < sample_cnt; i++) {			*sptr++ = audio_u2s(*tmptr++);		}		free(play_sig);		free(record_sig);		break;	  case AUDIO_ENCODING_ALAW:		/*		 *  get space for the signal		 */		if ((*rsig = (short *) calloc(sample_cnt, 				sizeof(short))) == NULL) {			send_message(ERSYS, ERROR, er_mem, 				sample_cnt*sizeof(short), SYSMSG);		}		/*		 *  Convert recorded signal to 16 bit PCM.		 */		sptr = *rsig;		tmptr = record_sig;		for (i = 0; i < sample_cnt; i++) {			*sptr++ = audio_a2s(*tmptr++);		}		free(play_sig);		free(record_sig);		break;	  case AUDIO_ENCODING_LINEAR:		*rsig = (short *) record_sig;		break;	  default:		send_message(ERAUDIO, ERROR, er_encoding);		break;	}	TRACE_OUT}/* *  Release reference file resources. */unset_ref(){	func_name = "unset_ref";	TRACE_IN	(void) munmap(refptr, ref_mapsize);	refname = NULL;	refptr = NULL;	TRACE_OUT}/* *  This routine is called if the calibration test is not being * run.  It attempts to open the reference file pointed to by * 'refname' if refname is non-NULL, otherwise, the file opened is * derived from the loopback "type". */intset_ref(){	int		fd;	struct stat	statbuf;	func_name = "set_ref";	TRACE_IN	if (refname[0] < 'A') {		strcpy(refname,ldata[ltype].refname);	}	/*	 *	open the file, get it's size and map it	 */	if ((fd = open(refname, O_RDONLY)) == -1 ) {		send_message(ERSYS, ERROR, er_open, refname, SYSMSG);	}	if (fstat(fd, &statbuf) == -1) {		send_message(ERSYS, ERROR, er_stat, SYSMSG);	}	ref_mapsize = statbuf.st_size;	if ((refptr = (ref_data_t *)mmap((caddr_t) 0, ref_mapsize, 			PROT_READ, MAP_SHARED, 			fd, (off_t) 0)) == (ref_data_t *)-1 ) {		send_message(ERSYS, ERROR, er_mmap, SYSMSG);	}	close(fd);	TRACE_OUT}/* *  Get number of elements in an band_data_t array. */intgetbdsiz(bdptr)band_data_t	*bdptr;{	int	i=0;	while (bdptr->type != NULL) {		i++;		bdptr++;	}	return(i);}/* *  Get number of elements in an au_data_t array. */intgetausiz(auptr)au_data_t	*auptr;{	int	i=0;	while (auptr->sample_rate != NULL) {		i++;		auptr++;	}	return(i);}/* *  Determine the size of the reference file, open and map it. */voidmap_ref(fname, auptr)char		*fname;au_data_t	*auptr;{	int	fd, fftsize, rdsize;	double	rms;	func_name = "map_ref";	TRACE_IN	/*	 *	open the file	 */	if ((fd = open(fname, O_CREAT | O_RDWR, 0666)) == -1 ) {		send_message(ERSYS, ERROR, er_open, fname, SYSMSG);	}	/*	 *  The reference file has space for left/right channel data	 * even if the au_data_t says MONO.  This makes coding a bit	 * easier.	 */	fftsize = ref_size/2 + 1;	rdsize = fftsize * sizeof(double) + sizeof(ref_data_t);	ref_mapsize = getausiz(auptr) * rdsize * 2;	if (ftruncate(fd, ref_mapsize) == -1 ) {		send_message(ERSYS, ERROR, er_truncate, SYSMSG);	}	/*	 *  map the fft magnitude file	 */	if ((refptr = (ref_data_t *) mmap ((caddr_t) 0, ref_mapsize,			(PROT_READ | PROT_WRITE), 			MAP_SHARED, fd, (off_t) 0)) == (ref_data_t *)-1 ) {		send_message(ERSYS, ERROR, er_mmap, SYSMSG);	}	close(fd);}/* *  Performs RMS and fft calculations and saves RMS, gain and fft * magnitude data in a file as reference data for further tests. */voidcalc_ref(sigptr, size, pgain, rgain, refp)short	*sigptr;int	size;int	pgain;int	rgain;ref_data_t *refp;{	int	fftsize;	double	rms;	func_name = "calc_ref";	TRACE_IN	/*	 *  perform RMS calculation and write rms and gain	 */	rms = rmscalc(sigptr, size);	if (bin_sel == LEFT) lrms = rms;	else		     rrms = rms;	refp->rms = rms;	refp->play_gain = pgain;	refp->record_gain = rgain;	/*	 *  perform fft and write magnitude data	 */	fftsize = size/2+1;	bin_sel = LEFT;	if (fftmag(sigptr, size, &refp->mag) != fftsize) {		send_message(ERAUDIO, ERROR, er_fftmag);	}	send_message(0, DEBUG, ref_msg, pgain, rgain, rms);	TRACE_OUT}/* *  Generate reference data and get it into the reference file. */voidgenref(sigptr, sample_cnt, pgain, auptr, aud_index)short   	*sigptr;int		sample_cnt;int		pgain;au_data_t	*auptr;int		aud_index;{	int	i, fftsize, rdsize;	short	*lsig, *rsig;	ref_data_t *refp;	func_name = "genref";	TRACE_IN	/*	 *  Calculate size of reference data (per sample) and	 * get a pointer into the mapped reference file.	 */	fftsize = sample_cnt/2 + 1;	rdsize = fftsize * sizeof(double) + sizeof(ref_data_t);	refp = (ref_data_t *) ((caddr_t) refptr + (rdsize * 2 * aud_index));	if (auptr->channels == MONO) {		calc_ref(sigptr, sample_cnt, pgain, auptr->cal_rgain, refp);		if (dump_signals) {			dump_sig(sigptr, sample_cnt, 				aufname("ref-rec-mono", auptr));		}	}	else {		splitstereo(&lsig, &rsig, sigptr, 2*sample_cnt);		calc_ref(lsig, sample_cnt, pgain, auptr->cal_rgain, refp);		if (dump_signals) {			dump_sig(lsig, sample_cnt, 				aufname("ref-rec-left", auptr));			dump_sig(rsig, sample_cnt, 				aufname("ref-rec-right", auptr));		}		refp = (ref_data_t *) ((caddr_t) refptr + 			(rdsize * 2 * aud_index) + rdsize);		calc_ref(rsig, sample_cnt, pgain, auptr->cal_rgain, refp);		free(lsig);		free(rsig);	}	TRACE_OUT}/* *  Returns the maximum fft magnitude for a given frequency range */doublemaxmag(magp, fsize, size, start, end, sr)double	*magp;int	fsize;int	size;int	start;int	end;int	sr;{	int	i, lower_slot, upper_slot;	double	max;	func_name = "maxmag";	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));	}	/*	 *  Find biggest value and return it.	 */	max = 0;	for (i = lower_slot; i <= upper_slot; i++) {		if (magp[i] > max) {			max = magp[i];		}	}	TRACE_OUT	return(max);}/* *  Calculate the thresholds for a given signal and reference data. * We just malloc some space for a bunch of doubles and put all the * threshold values there. */calc_threshold(refp, sample_cnt, auptr, thdata)ref_data_t	*refp;int		sample_cnt;au_data_t	*auptr;thresh_data_t	*thdata;{	int		i, bcnt, fftsize, rdsize;	double		*lrefmag, *rrefmag, lref_bandrms, rref_bandrms;	double		tmp_rms, tmp_mag, ref_bandrms;	ref_data_t	*lrefp, *rrefp;	func_name = "calc_threshold";	TRACE_IN	/*	 *  Get some space for the rms limits (upper and lower for	 * each channel).	 */	if ((thdata->lrms = (double *) calloc(2, sizeof(double))) == NULL) {		send_message(ERSYS, ERROR, er_mem, (sizeof(double)* 2), SYSMSG);	}	if ((thdata->rrms = (double *) calloc(2, sizeof(double))) == NULL) {		send_message(ERSYS, ERROR, er_mem, (sizeof(double)* 2), SYSMSG);	}	/*	 *  Get some space for FFT band threshold values (number of	 * bands * 2 channels).	 */	bcnt = getbdsiz(auptr->bdata);	/* number of freq bands */	if ((thdata->lmag = (double *) calloc(bcnt, sizeof(double))) == NULL) {		send_message(ERSYS, ERROR, er_mem, 			(sizeof(double)*bcnt), SYSMSG);	}	if ((thdata->rmag = (double *) calloc(bcnt, sizeof(double))) == NULL) {		send_message(ERSYS, ERROR, er_mem, 			(sizeof(double)*bcnt), SYSMSG);	}	fftsize = sample_cnt/2+1;	/* offsets for ref data */	rdsize = fftsize * sizeof(double) + sizeof(ref_data_t);	lrefp = refp;		/* left and right chan ref ptrs */	rrefp = (ref_data_t *) ((caddr_t) refp + rdsize);	lrefmag = &lrefp->mag;	/* left and right ref fft mags */	rrefmag = &rrefp->mag;	/*	 *  RMS limit and fft magnitude threshold calculation for 	 * mono signals.  The rms limits and fft magnitude thresholds 	 * for mono signals are placed in the left channel "slot".	 * Right channel slots are filled with zero.	 *	 */	if (auptr->channels == MONO) {		/*		 *  set RMS limits		 */		thdata->lrms[0] = lrefp->rms + aurms_tol;		thdata->lrms[1] = lrefp->rms - aurms_tol;		thdata->rrms[0] = 0;		thdata->rrms[1] = 0;		/*		 *  Set FFT magnitude thresholds for each band.		 */		for (i = 0; i < bcnt; i++) {			ref_bandrms = bandrms(lrefmag, fftsize, sample_cnt, 				auptr->bdata[i].start_freq, 				auptr->bdata[i].end_freq, 				auptr->sample_rate);			if (auptr->bdata[i].type == BAND_FUND) {				thdata->lmag[i] = ref_bandrms - aumag_tol;				thdata->rmag[i] = 0;			}			else {				thdata->lmag[i] = ref_bandrms + aumag_tol;				thdata->rmag[i] = 0;			}		}	}	/*	 *  RMS limit and fft magnitude threshold calculation for 	 * stereo signal with both channels.	 */	else if (auptr->lfreq && auptr->rfreq) {		/*		 *  Set RMS limits, use the average of the left and		 * right channels as the basis.		 */		tmp_rms = 20*log10((exp10(lrefp->rms/20) + 			exp10(rrefp->rms/20))/2);		send_message(0, DEBUG, tmprms_msg, tmp_rms);		thdata->lrms[0] = tmp_rms + aurms_tol;		thdata->lrms[1] = tmp_rms - aurms_tol;		thdata->rrms[0] = tmp_rms + aurms_tol;		thdata->rrms[1] = tmp_rms - aurms_tol;		/*		 *  Set FFT magnitude thresholds for each band.		 */		for (i = 0; i < bcnt; i++) {			lref_bandrms = bandrms(lrefmag, fftsize, sample_cnt, 				auptr->bdata[i].start_freq, 				auptr->bdata[i].end_freq, 				auptr->sample_rate);			rref_bandrms = bandrms(rrefmag, fftsize, sample_cnt, 				auptr->bdata[i].start_freq, 				auptr->bdata[i].end_freq, 				auptr->sample_rate);			tmp_mag = 20*log10((exp10(lref_bandrms/20) + 				exp10(rref_bandrms/20))/2);			send_message(0, DEBUG, tmpmag_msg, tmp_mag);			if (auptr->bdata[i].type == BAND_FUND) {				thdata->lmag[i] = tmp_mag - aumag_tol;				thdata->rmag[i] = tmp_mag - aumag_tol;			}			else {				thdata->lmag[i] = tmp_mag + aumag_tol;				thdata->rmag[i] = tmp_mag + aumag_tol;			}		}	}	/*	 *  RMS limit and fft magnitude threshold calculation for 	 * stereo signal with one channel driven.	 *	 *  If only one channel is driven then the threshold for the	 * non-driven channel will be the difference between the	 * the left and right channels in the reference signal 	 * plus some offset.	 *	 *  In this case, the number calculated below for the non-	 * driven channel's RMS and FFT mag is not the actual 	 * threshold but a value to subtracted from the test signal's	 * driven channel RMS or FFT mag.  (confused yet?)  The 	 * actual threshold will be calculated when when get the 	 * test signal's RMS and SST values in chksig().	 *	 *  The idea is that the threshold for the non-driven channel	 * should be:	 *	D(test) - [D(ref) - ND(ref) - tolerance]	 *	 * where D(test) = driven channel from test, D(ref) =	 * driven channel from reference and ND(ref) = non-	 * driven channel from reference.	 *	 */	else {		/*		 *  Set RMS limits.		 */		if (auptr->lfreq) {			thdata->lrms[0] = lrefp->rms + aurms_tol;			thdata->lrms[1] = lrefp->rms - aurms_tol;		}		else {			tmp_rms = rrefp->rms - lrefp->rms;			send_message(0, DEBUG, tmprms_msg, tmp_rms);			thdata->lrms[0] = tmp_rms - aurms_tol;			thdata->lrms[1] = 0;		}		if (auptr->rfreq) {			thdata->rrms[0] = rrefp->rms + aurms_tol;			thdata->rrms[1] = rrefp->rms - aurms_tol;		}		else {			tmp_rms = lrefp->rms - rrefp->rms;			send_message(0, DEBUG, tmprms_msg, tmp_rms);			thdata->rrms[0] = tmp_rms - aurms_tol;			thdata->rrms[1] = 0;		}		/*		 *  Set FFT magnitude thresholds for each band.		 */		for (i = 0; i < bcnt; i++) {			lref_bandrms = bandrms(lrefmag, fftsize, sample_cnt, 				auptr->bdata[i].start_freq, 				auptr->bdata[i].end_freq, 				auptr->sample_rate);			rref_bandrms = bandrms(rrefmag, fftsize, sample_cnt, 				auptr->bdata[i].start_freq, 				auptr->bdata[i].end_freq, 				auptr->sample_rate);			if (auptr->bdata[i].type == BAND_FUND) {				if (auptr->lfreq) {					thdata->lmag[i] = 						lref_bandrms - aumag_tol;				}				else {					tmp_mag = rref_bandrms - lref_bandrms;					send_message(0, DEBUG, tmpmag_msg, 						tmp_mag);					thdata->lmag[i] = tmp_mag - aumag_tol;				}				if (auptr->rfreq) {					thdata->rmag[i] = 						rref_bandrms - aumag_tol;				}				else {					tmp_mag = lref_bandrms - rref_bandrms;					send_message(0, DEBUG, tmpmag_msg, 						tmp_mag);					thdata->rmag[i] = tmp_mag - aumag_tol;				}			}			else {				if (auptr->lfreq) {					thdata->lmag[i] = 						lref_bandrms + aumag_tol;				}				else {					tmp_mag = rref_bandrms - lref_bandrms;					send_message(0, DEBUG, tmpmag_msg, 						tmp_mag);					thdata->lmag[i] = tmp_mag - aumag_tol;				}				if (auptr->rfreq) {					thdata->rmag[i] = 						rref_bandrms + aumag_tol;				}				else {					tmp_mag = lref_bandrms - rref_bandrms;					send_message(0, DEBUG, tmpmag_msg, 						tmp_mag);					thdata->rmag[i] = tmp_mag - aumag_tol;				}			}		}	}	TRACE_OUT}/* *  returns whether or not a signal is valid. */intsig_valid(refp, test_sig, sample_cnt, auptr)ref_data_t	*refp;short		*test_sig;int		sample_cnt;au_data_t	*auptr;{	int	i, fftsize, rdsize;	short	*lsig, *rsig;	double	*thptr, *rmsptr, *lmag, *rmag;	thresh_data_t   thdata;	func_name = "sig_valid";	TRACE_IN	/*	 *  Calculate RMS and FFT magnitude thresholds.	 */	calc_threshold(refp, sample_cnt, auptr, &thdata);	/*	 *  Check mono signal.	 */	if (auptr->channels == MONO) {		fftsize = sample_cnt/2 + 1;		rdsize = fftsize * sizeof(double) + sizeof(ref_data_t);		if (dump_signals) {

⌨️ 快捷键说明

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