📄 playrec.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 + -