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

📄 playrec.c

📁 speech signal process tools
💻 C
字号:
/* Copyright (c) 1995 Entropic Research Laboratory, Inc. *//* 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-1993  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.3	9/26/95	ATT/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 fab2_quit *		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)#define  TRUE 1#define FALSE 0static	short*	dpr;	/* pointer to dual ported ram */static	int	ofd;	/* file pointer for output */static  int   have_ofd;  /* indicate data comes from a file. */static	int	ifd;static  void    *v32_head, /* args for read_any_file */                *v32_stream;static	short*	optr;	/* pointer to current buffer location */static	short*	iptr;	int	fab2_maxsamps,	/* total requested count */                fab2_sent = 0,	/* number actually sent */                fab2_error_at = -1; /* non-negative indicates error at sample */static	int	icnt;	/* input count */static	int	qcnt;	/* buffers in queue */static	int	iwait;	/* void input buffers */static	int	atime=0;	/* means something like "interrupts active" */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;extern int  da_location, da_done;stop_fab2_da() {  fab2_completion();}extern int  use_dsp32;extern int  dsp32_wait;static int  locked = 0;		/* lock file set? */extern short  *dspmap();/*************************************************************************/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 );}/*************************************************************************/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 fab2_quit;				/* now do output */  if ( (n=fab2_maxsamps) > NBUF )    n = NBUF;  cpy(optr,dpr,n,NBUF);		/* load new data into dual ported ram */  fab2_maxsamps -= n;  da_location += n;  fab2_sent += n;  if(optr) optr += n;  if ( (n=(short)dsprg(0,C_PIR)) <= 0 ) /* check buffer queue */    if ( signal ) {      lastpir = n;      fab2_error_at = fab2_sent;      goto fab2_quit;    }  if ( fab2_maxsamps > 0 ) qcnt = n;   if ( have_ofd && fab2_maxsamps > 0 ) {	/* reload buffer */    /*     n=read(ofd,optr=obuf,NBYTES)/2; */    n=read_any_file(optr=obuf,sizeof(short),NBYTES/sizeof(short),v32_stream,	   v32_head,ofd);    if ( n < NBUF ) fab2_maxsamps = n;  }  if ( fab2_maxsamps <= 0 )    /* if record is active we       will wait a little longer */    if ( --qcnt < ( (icnt)? -3 : -2)  ) {    fab2_quit:      fab2_completion();      return;    }  if (dsprg(0,C_SIG) == -1)  ;	/* who knows what this once did... */}/*************************************************************************/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;}/*************************************************************************/staticdadc(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;  void (*sigsav[3])();  if(! use_dsp32) {    fprintf(stderr,"DSP-32 is not available or not enabled.\n");    return;  }  /* must have readable file or an input array of shorts */  if ( ((ofd=outfd) < 0) && !v32_stream ) {    have_ofd = FALSE;    if ( !outbuf || ((long)outbuf&1) ) return -1;  } else    have_ofd = TRUE;  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 v32_stream=%x v32_head=%x fab2_maxsamps=size=%d #buf=%d\n",	   ofd,v32_stream,v32_head,size,(size+1023)/1024);    switch (DSP_LOCK(dsp32_wait)) {  case LCKFIL_OK:      break;  case LCKFIL_INUSE:      fprintf(stderr,"%s: dsp board in use.\n", "dadc");      return;      break;  case LCKFIL_ERR:      fprintf(stderr,"%s: error in trying to secure exclusive access to dsp board");      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;    fab2_maxsamps = 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 ( have_ofd ) {      if ( j ) {/*	j = read(ofd, optr=obuf, (fab2_maxsamps>NBUF)? NBYTES : fab2_maxsamps<<1)/2;*/	j = read_any_file(optr=obuf, sizeof(short), ((fab2_maxsamps>NBUF)? NBYTES : fab2_maxsamps<<1)/sizeof(short),v32_stream,v32_head,ofd);      }    } else {      optr = outbuf;      j = (fab2_maxsamps > NBUF) ? NBUF : fab2_maxsamps;    }    fab2_maxsamps -= j;    if ( fab2_maxsamps ) qcnt++;    if (debug_level)      fprintf(stderr,"# to go=%d i=%d j=%d\n",fab2_maxsamps,i,j);    if ( i == 8 ) {      fab2_maxsamps += 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 */  set_fab2_dac_callbacks();  if ( !dpr )    dpr = 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 */  da_done = FALSE;}/*************************************************************************/static adc(infd,inbuf,size,freq,amax,amin)     short *inbuf;     int infd, size, *amax, *amin;     double *freq;{     return(dadc(0, NULL, infd, inbuf, size, freq, 16000, amax, amin, 2));}     /*************************************************************************/dacmaster_32(outfd,outbuf,size,freq,amp,strm,ehead)     short *outbuf;     int outfd, size, amp;     double *freq;     void *strm, *ehead;{  int amax, amin;  v32_stream = strm;  v32_head = ehead;  dadc(outfd, outbuf, 0, (short*) 0, size, freq, amp, &amax, &amin, 0);}/*************************************************************************/dac_32(outfd,outbuf,size,freq,amp)short *outbuf;int outfd, size, amp;double *freq;{  int amax, amin;  v32_stream = NULL;  v32_head = NULL;  dadc(outfd, outbuf, 0, (short*) 0, size, freq, amp, &amax, &amin, 0);}/*************************************************************************/fab2_completion(){  da_done = TRUE;  atime=0;#if defined(SUN4) && !defined(OS5)  usleep(333333);		/* 1/3 second for buffers to clear */#else  fprintf(stderr,	  "%s: This statement shouldn't be executed on non-Sun machines.\n",	  "irq (playrec.c) DSP-dependent code");#endif  /* usleep not available on some systems (e.g. DecStation 3100). */  dsprg(0, C_STOP);  if (locked) {      DSP_UNLOCK;      locked = 0;    }  clear_fab2_dac_callbacks();}

⌨️ 快捷键说明

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