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

📄 playrec.c

📁 speech signal process tools
💻 C
字号:
/* playrec.c *//* * This material contains unpublished, proprietary software of  * Entropic Research Laboratory, Inc. Any reproduction, distribution,  * or publication of this work must be authorized in writing by Entropic  * Research Laboratory, Inc., and must bear the notice:  * *    "Copyright (c) 1987-1990  AT&T, Inc. *    "Copyright (c) 1986-1990  Entropic Speech, Inc.  *    "Copyright (c) 1990-1991  Entropic Research Laboratory, Inc.  *                   All rights reserved" * * The copyright notice above does not evidence any actual or intended  * publication of this source code.      * * Written by:   * Checked by: * Revised by: * * Brief description: * */static char *sccs_id = "@(#)playrec.c	1.4	6/28/91	ATT/ESI/ERL";/*	play and record subroutine for DSP32/VME board * *	uses output buffering in PGA DSP32 ( 8 Buffers with 1024 samples ) * *	dac(file,buffer,size,freq,amp) * *	file:	open file descriptor or zero (no file) *	buffer:	pointer to sample buffer (shorts) or zero *	size:	number of samples to play (dac will quit on eof) *	*freq:	double precision sampling freq.; will be converted to integer                to access '(freq)to' and 'to(freq)'; exact freq. used is returned *		sample rate converter programs *      amp:    the absolute maximum in the signal for D/A * *	keyboard intr signal will kill playing * * *	dadc(file,buffer,inputfile,inputbuffer,size,freq,amax,amin,mode) * *	this entry will play and also record (e.g. for impulse response meas.) *	inputfile:	file pointer to writable file *	inputbuffer:	pointer to buffer for input *      amax, amin      return limits encountered during recording *                      dadc() returns the number of samples written *      mode		Determines play-only, play-record, or record-only *			(see setrate.c). * *//* 3/30/88:mcb - `dadc' sends (up to) 8 buffers to dsp and leaves one in *		readiness.  `irq' then grabs the remaining data one buffer *		at a time.  `dadc' was fixed so that `ocnt' now reflects *              data SENT TO THE BOARD and *not* data read from file or *		buffer.  A delay of 1/3 second was added to the abort *		code in `irq' to prevent stopping before playing a buffer. */#include <stdio.h>#include <signal.h>#include <dsplock.h>#include <dsp32.h>#define	DSP_PCR	DMA_MODE#define	DSP_RUN	(EMR_DEF<<16|DSP_PCR)#define	DSPBUF	0x2000	/* dsp output buffer hardwired in dsp prog. */#define	NBUF	1024	/* transfer size to dpr ... ditto */#define	NBYTES	(2*NBUF)static	short*	dpr;	/* pointer to dual ported ram */static	int	ofd;	/* file pointer for output */static	int	ifd;static	short*	optr;	/* pointer to current buffer location */static	short*	iptr;static	int	ocnt;	/* total count */static	int	icnt;	/* input count */static	int	qcnt;	/* buffers in queue */static	int	iwait;	/* void input buffers */static	int	atime=0;	/* time for alarm */static  int     lastpir;	/* error from dsp */static  int     smax, smin;	/* maintain limits if A/D performed */static	short	obuf[NBUF];static	short	tobuf[NBUF];static  short   shift;	/* for scaling to max during D/A */extern	int	debug_level;#ifdef FOR_SUNVIEWextern int  da_location, da_done;static alarm(time) { da_done = time; }stop_da() { atime = 0; }#endifextern int  use_dsp32;int	    dsp32_wait = 5;static int  locked = 0;		/* lock file set? *//*************************************************************************/adc(infd,inbuf,size,freq,amax,amin)     short *inbuf;     int infd, size, *amax, *amin;     double *freq;{     short *data = (short *)calloc(size*sizeof(short));     return(dadc(0, data, infd, inbuf, size, freq, 16000, amax, amin, 2));}     /*************************************************************************/dac_32(outfd,outbuf,size,freq,amp)short *outbuf;int outfd, size, amp;double *freq;{  int amax, amin;  dadc(outfd, outbuf, 0, (short*) 0, size, freq, amp, &amax, &amin, 0);}/*************************************************************************/dadc(outfd, outbuf, inpfd, inpbuf, size, freq, amp, amax, amin, mode)short *outbuf;short *inpbuf;int outfd, inpfd, size, amp, *amax, *amin, mode;double *freq;{  int i, j, dspaddr;  int timeout(), irq();  void (*sigsav[3])();  if(! use_dsp32) {    fprintf(stderr,"DSP-32 is not available or not enabled.\n");    exit(1);  }  if (debug_level) fprintf(stderr,"Inside of dadc.\n");  if ( (ofd=outfd)<=0 ) {	/* must have readable file or (short*) */    ofd=0;    if ( !outbuf || ((long)outbuf&1) ) return -1;  }  if ( (ifd=inpfd)<=0 )		/* A/D if file or short array available */    ifd=0;  iptr = inpbuf;  if ( ifd > 0 || ( iptr && !((long)iptr&1) ) )    icnt = size;  else	icnt = 0;  iwait = 2;  lastpir = 0;  smax = smin = 0;		/* assumes A/D centered around zero! */  if (debug_level)    fprintf(stderr,"dadc: ofd=%d ocnt=size=%d #buf=%d\n",ofd,size,(size+1023)/1024);    switch (DSP_LOCK(dsp32_wait))  {  case LCKFIL_OK:      break;  case LCKFIL_INUSE:      printf("%s: dsp board in use.\n", "dadc");      return;      break;  case LCKFIL_ERR:      printf("%s: error trying to secure exclusive access to dsp board.\n",	     "dadc");      return;      break;  }  locked = 1;  dsprg(0,C_CSR|C_WRITE,CSR_RESET);	/* reset all (resets sio transfer) */  dsprg(0,C_CSR|C_WRITE,CSR_DEFAULT);  dsprg(0,C_STOP);		/* now we must stop them all */  dsprg(1,C_STOP);  dsprg(2,C_STOP);  if ( atime ) dsprg(0, C_CLRSIG);	/* indicates last play didn't finish */  /* now we can download the data */  if ( setrate(NULL,freq,NULL, mode) < 0 )  {      (void) DSP_UNLOCK;      locked = 0;      return -1;  }  atime = 1;			/* should depend on sampling freq. */  ocnt = size;			/* number of samples to play */  dspaddr = DSPBUF;		/* PGA dsp buffer start */  if(!amp) amp = 32767;  shift = 0;  if(amp < 16384)    while((amp << shift) < 16384) shift++;  if(debug_level) fprintf(stderr,"max:%d  shift:%d\n",amp,shift);  for( i=0, j=1, qcnt=1; ; i++ ) {    if ( ofd ) {      if ( j ) {	j = read(ofd, optr=obuf, (ocnt>NBUF)? NBYTES : ocnt<<1)/2;      }    } else {      optr = outbuf;      j = (ocnt > NBUF) ? NBUF : ocnt;    }    ocnt -= j;    if ( ocnt ) qcnt++;    if (debug_level) fprintf(stderr,"# ocnt=%d i=%d j=%d\n",ocnt,i,j);    if ( i == 8 ) {      ocnt += j;	/* doesn't really get copied yet */      break;		/* 8 buffers are in and optr is set */    }    cpy(optr, obuf, j, NBUF);    dspwr(0, dspaddr, obuf, NBYTES);	/* write to PGA memory */    if(outbuf) outbuf += NBUF;    dspaddr += NBYTES;  }  signal( SIGDSP, irq);			/* catch dsp irq's */#ifndef FOR_SUNVIEW  sigsav[0] = (void*)signal( SIGALRM, timeout);  sigsav[1] = (void*)signal( SIGINT, timeout);  sigsav[2] = (void*)signal( SIGQUIT, timeout);#endif  if ( !dpr ) dpr = (short*)dspmap();	/* get pointer to dual ported ram */  dsprg(1,C_RUN,DSP_RUN);	/* start DIP dsp32's */  dsprg(2,C_RUN,DSP_RUN);  irq(0);			/* start irq routine */  dsprg(0,C_RUN,DSP_RUN|PCR_ENI); /* start PGA dsp, enable irq */#ifndef FOR_SUNVIEW  while( atime ) {      pause();    if ( debug_level )      fprintf(stderr, " ocnt %d icnt %d qcnt %d\n", ocnt, icnt, qcnt);    }  dsprg(0,C_STOP);		/* halt dsp#0 */  dsprg(0,C_CLRSIG);		/* clear pending signals */  signal( SIGALRM, sigsav[0]);	/* restore signal handlers */  signal( SIGINT, sigsav[1]);  signal( SIGQUIT, sigsav[2]);  *amax = smax;  *amin = smin;  if (locked)  {      DSP_UNLOCK;      locked = 0;  }  return(size-icnt);		/* returns number of samples written */#else  return 0;#endif}/*************************************************************************/static irq(signal){  register int n;  register short *p = dpr, lmax = smax, lmin = smin, stemp, nw;				/* input data */  if ( iwait )    iwait--;			/* wait for first real input */  else {    if ( (n=icnt) > 0 ) {	/* read input data from dpr */      if ( n > NBUF ) n = NBUF;      if ( ifd ) {	cpymaxmin(dpr,tobuf,n);	nw = write(ifd,tobuf,NBYTES);	if(debug_level)	  fprintf(stderr,"w%d",nw);      }      else {	cpy(dpr, iptr, n, n);	iptr += n;      }            icnt -= n;    }  }  if ( atime == 0 ) goto abort;	/* shall we abort? */				/* now do output */  if ( (n=ocnt) > NBUF )    n = NBUF;  cpy(optr,dpr,n,NBUF);		/* load new data into dual ported ram */  ocnt -= n;#ifdef FOR_SUNVIEW  da_location += n;#endif  if(optr) optr += n;  if ( (n=(short)dsprg(0,C_PIR)) <= 0 ) /* check buffer queue */    if ( signal ) {      lastpir = n;      goto abort;    }  if ( ocnt > 0 ) qcnt = n;   if ( ofd && ocnt > 0 ) {	/* reload buffer */    n=read(ofd,optr=obuf,NBYTES)/2;    if ( n < NBUF ) ocnt = n;  }  if ( ocnt <= 0 )    /* if record is active we       will wait a little longer */    if ( --qcnt < ( (icnt)? -3 : -2)  ) {    abort:      alarm(0);      atime=0;      usleep(333333);	/* 1/3 second for buffers to clear */      dsprg(0, C_STOP);      if (locked)      {	  DSP_UNLOCK;	  locked = 0;      }      return;    }  alarm(atime);  if (dsprg(0,C_SIG) == -1)  ;}/*************************************************************************/static timeout(signal){  if ( (signal == SIGINT) || (signal == SIGQUIT) )    fprintf(stderr,"\nINTR\n");  else {    fprintf(stderr,"\nTIMEOUT");    if ( lastpir )      fprintf(stderr," pir:0x%x",lastpir&0xffff);    fprintf(stderr,"\n");  }  atime = 0;}/*************************************************************************/static cpy(from,to,size,bufsize)	/* copy and zero padding */register short *from;register short *to;{  register int cnt = size, sh = shift;  if ( cnt > 0 ) {    if(from)      do { *to++ = (*from++) << sh; } while ( --cnt );    else      do { *to++ = 0; } while ( --cnt );  }  if ( size < bufsize ) {    cnt = (size > 0)? (bufsize-size) : bufsize;    do { *to++ = 0; } while ( --cnt );  }}/*************************************************************************/static cpymaxmin(from,to,size)		/* copy and zero padding and maxmin*/register short *from;register short *to;{	register int cnt = size;	register int max = 0;	register short c;	if ( cnt ) 		do {			*to++ = c = *from++;			if ( c > smax ) smax = c;			else				if ( c < smin ) smin = c;		} while ( --cnt );}

⌨️ 快捷键说明

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