📄 nplay.c
字号:
/* play stuff for Surfboard with Ariel module *//* * 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 = "@(#)nplay.c 1.3 10/9/91 ATT/ESI/ERL";#include <Objects.h>#include <sys/ioctl.h>#include <dsp32c.h>#include <vme32c.h>#include <signal.h>#include <esps/epaths.h>#define HOST_RESPONSE (1234)#define STARTUP_CODE (1)#define PARAM_CODE (2)#define DATA_CODE (3)#define DSP_COMPLETE (7)/* At initialization 32c tells host where a buffer can be put and howmuch space is available. Host sends initial batch of data to 32cDRAM; tells 32c how much was sent; and then starts the main 32c outputprocess. 32c sends an interrupt to host when it starts using the mostrecently sent buffer. At this time 32c tells host where data can beput and how much. Host decides how much to actually output in thenext chunk; copies data to DRAM; and notifies 32c. *//* 32c will use DRAM as a large circular buffer for sampled data. Itsets a sample count and base address and issues an interrupt to thehost when some data is ready. Host service routine writes data todisk or array, then sends a done flag to the 32c. 32c never changesbase and count until after host acknowledge, but if buffer overrunoccurs, a distinguished flag will be set. *//* Here is the parameter exchange block in shared DRAM: */typedef struct header { long count, /* size of buff. sent from host */ base, /* byte offset to host buff re DPM start */ oops, /* flag (from DSP): loss of real time */ host_done, /* set by host after buffer sent */ chunk; /* Minimum size of transfer buffer. */} Head;char *dsp_program[] = { "play32", "a2d12", "a2d12"};int channel=1, shifts;int da_done, da_location;void (*sig_save[3])();extern char *DSP_io, *DSP_SharedMemory;Head *header = NULL;int dpm_size = 0x100000, sizeof_sample = 2*sizeof(short), /* size of each (possibly stereo) sample on host */ sizeof_dsp_sample = 2*sizeof(short),/* size of each sample (always stereo) exchanged with DSP*/ infd = -1, maxsamps, sent=0, error_at, amax, amin;extern int dsp32c[], dsp32c_io, dsp32c_sm;short *inbuff=NULL;static struct ioctlio dcmd;/*************************************************************************//* Not only does this detect the bounding values of the buffer at"start," it also compresses two-channel data into one channel whenchannel != 0. *//*get_signal_max(start, nshorts, amax, amin, channel) int *amax, *amin, channel; register int nshorts; register short *start;{ register short t, smax = *amax, smin = *amin; if(!channel) { for( ;nshorts-- ; ) if((t = *start++) > smax) smax = t; else if(t < smin) smin = t; } else { register short *from; for(from = start + channel -1; nshorts-- ; from += 2) if((*start++ = t = *from) > smax) smax = t; else if(t < smin) smin = t; } *amax = smax; *amin = smin;}*//*************************************************************************/static stop_da(sig) int sig;{ error_at = sent; completion();}/*************************************************************************/static scale(data, nsamps, channel, shift) register int nsamps, channel, shift; short *data;{ register short *to, *from; to = data + nsamps*sizeof(short) - 1; from = (channel)? data + nsamps -1 : to; if(channel == 2) for( ;nsamps--; ) { *to-- = *from-- << shift; *to-- = 0; } if(channel == 1) for( ;nsamps--; ) { *to-- = 0; *to-- = *from-- << shift; } if(!channel) for( ;nsamps--; ) { *to-- = *from-- << shift; *to-- = *from-- << shift; }}/*************************************************************************/static dsp_handle(sig) int sig;{ static int startup=0; if(!sig) startup = 0; if(sig && (startup > 1) && header->oops) { /* loss of real time? */ error_at = sent; printf("Lost real time operation near sample %d.\n", sent); goto da_quit; } if(header->host_done == HOST_RESPONSE) { /* should be changed by 32c */ printf("Unexplained interrupt at %d\n", sent); error_at = sent; goto da_quit; } if((sent + header->count) > maxsamps) header->count = maxsamps - sent; if(header->count > header->chunk) header->count = header->chunk; if(infd >= 0) { /* samples from unix file? */ int to_read, nready, nread, pinx; short *start; if((to_read = (dpm_size - header->base)/((channel)? 2 : 1)) > (nready = header->count*sizeof_sample)) to_read = nready; start = (short*)(DSP_SharedMemory + header->base); if((nread = read(infd, start, to_read)) != to_read) { printf("Read1 error at %d(%d:%d)\n",sent,to_read,nread); error_at = sent; goto da_quit; } scale(start,nread/sizeof_sample,channel,shifts); sent += nread/sizeof_sample; da_location += nread/sizeof_sample; if(nread < nready) { to_read = nready - nread; start = (short*)(DSP_SharedMemory+sizeof(Head)); if((nread = read(infd, start, to_read)) != to_read) { printf("Read2 error at %d(%d:%d)\n",sent,to_read,nread); error_at = sent; goto da_quit; } scale(start,nread/sizeof_sample,channel,shifts); sent += nread/sizeof_sample; da_location += nread/sizeof_sample; } } else { /* must come from a memory buffer */ register int first_copy, /* # stereo samples copyable in first pass */ to_copy, /* total # of stereo samples to copy */ i, nshifts=shifts; register short *from, *to, smax, smin; int poff; poff = (channel)? channel - 1 : 0; if((first_copy = (dpm_size - header->base)/sizeof_dsp_sample) > (to_copy = header->count)) first_copy = to_copy; if(channel) { /* mono */ i=first_copy; to = (short*)(DSP_SharedMemory+header->base); from = inbuff; if(poff) for(; i--; ) { *to++ = 0; *to++ = (*from++)<<nshifts; } else for(; i--; ) { *to++ = (*from++)<<nshifts; *to++ = 0; } if(to_copy > first_copy) { i = to_copy-first_copy; to = (short*)(DSP_SharedMemory+sizeof(Head)); if(poff) for(; i--; ) { *to++ = 0; *to++ = (*from++)<<nshifts; } else for(; i--; ) { *to++ = (*from++)<<nshifts; *to++ = 0; } } } else { /* stereo */ for(i=first_copy, to = (short*)(DSP_SharedMemory+header->base), from = inbuff; i--; ) { *to++ = (*from++)<<nshifts; *to++ = (*from++)<<nshifts; } if(to_copy > first_copy) for(i = to_copy-first_copy, to = (short*)(DSP_SharedMemory+sizeof(Head)); i-- ; ) { *to++ = (*from++)<<nshifts; *to++ = (*from++)<<nshifts; } } sent += header->count; da_location += header->count; inbuff += to_copy; } header->host_done = HOST_RESPONSE; startup++; dcgets2(0,DC_PIO_PIRL); /* clear the interrupt flag */ dcgets2(0,DC_PIO_PIRH); if(header->count <= 0) { /* wait for A/D completion of last buffer */ int waiting;da_quit: dcgets2(0,DC_PIO_PDRL); /* let 32c know interaction is done */ dcgets2(0,DC_PIO_PDRH); waiting = 100000; while(waiting-- && (dcgets2(0,DC_PIO_PDRL) != DSP_COMPLETE)) dcgets2(0,DC_PIO_PDRH); completion(); return; } if (ioctl(dsp32c[0], DC_SIG, &dcmd) != 0) { printf("DC_SIG rejected in dsp_handle()\n"); error_at = sent; goto da_quit; } if (ioctl(dsp32c[0], DC_ENBPIF, &dcmd) != 0) { /* reenable interrupt */ printf("DC_ENBPIF rejected in dsp_handle()\n"); error_at = sent; goto da_quit; } dcgets2(0,DC_PIO_PDRL); /* let 32c know data was written */ dcgets2(0,DC_PIO_PDRH); return;}/*************************************************************************/dadc_32C(){return(-1);}/*************************************************************************/static completion(){ int chip; if(!da_done) { da_done = TRUE; /* Disable interrupt from 32c. */ if (ioctl(dsp32c[0], DC_DISPIF, &dcmd) != 0) { printf("DC_DISPIF rejected in dac()\n"); } /* Turn off the chips. */ for(chip = 0; chip < 3; chip ++) dcinit(dsp32c[chip],0); /* Restore the original signal handlers. */ signal(SIGDSP,sig_save[0]); signal(SIGINT,sig_save[1]); signal(SIGQUIT,sig_save[2]); /* close the devices */ close_dsp32cs(); close_io_mem(); }}/*************************************************************************/dac_32C(inputfile, inbuffer, sig_size, freq, sigmax) int inputfile, sig_size, sigmax; short *inbuffer; double *freq;{ int chip; /* Initialize all host variables. */ sent = 0; error_at = -1; shifts = 0; if(!sigmax) sigmax = 32767; if(sigmax < 16384) while((sigmax << shifts) < 16384) shifts++; if(channel) sizeof_sample = sizeof(short); else sizeof_sample = sizeof(int); if((maxsamps = sig_size) <= 0) { printf("Bogus sample count sent to dac(%d)\n",sig_size); return(-1); } if(inputfile >= 0) { /* input from either a file OR a memory buffer */ infd = inputfile; inbuff = NULL; } else if(inbuffer) { infd = -1; inbuff = inbuffer; } else { printf("Bogus input file and buffer specified to dac()\n"); return(-1); } /* Initialize the DSP's */ { char dsname[200]; for(chip = 0; chip < 3; chip++) { sprintf(dsname,"/dev/dc0%d",chip); if((dsp32c[chip] < 0) && ((dsp32c[chip] = dcopen(dsname)) < 0)) { printf("Couldn't open %s",dsname); return(-1); } if (ioctl(dsp32c[chip], DC_RESET, (char*)NULL) != 0) { printf ("Couldn't reset %s in dac()\n",dsname); return(-1); } dcinit(dsp32c[chip], 0); } } /* Set the sample rate. */ if(set_sam_rate(freq,"a")) { /* Setup the signal handlers. */ sig_save[0] = signal(SIGDSP, dsp_handle); sig_save[1] = signal( SIGINT, stop_da); sig_save[2] = signal( SIGQUIT, stop_da); /* Load the DSP programs. */ { char *path; for(chip=0; chip < 3; chip++ ){ path = FIND_SURF_BIN(NULL,dsp_program[chip]); if(!path) { printf("Can't find DSP program %s\n",dsp_program[chip]); return(-1); } if(dcld(dsp32c[chip], path)) { printf("Problems loading %s to DSP %d\n",path,chip); return(-1); } free(path); } } /* Map in the DRAM and register file. */ if(!(open_32c_io("/dev/dc0io") && open_32c_sm("/dev/dc0mem"))) { printf("mmap() problems in dac()\n"); completion(); return(-1); } header = (Head*)DSP_SharedMemory; /* Start the DSP's. */ dcrun(dsp32c[2]); dcrun(dsp32c[0]); dcrun(dsp32c[1]); /* The maximum chunk size is determined by sample frequency. */ header->count = header->chunk = 0.5 * *freq; /* 500ms for now... */ header->host_done = 0; header->oops = 0; header->base = sizeof(Head); dsp_handle(0); /* Send first buffer to dsp and start interrupts. */ /* This starts the actual A/D process on the 32c. */ if(dsp_wait(0, 1000, STARTUP_CODE) < 1000) { /* Wait for samples to be output. */ da_done = FALSE;#ifndef FOR_SUNVIEW while(!da_done && (error_at < 0)) { sleep(1); } if(error_at >= 0) completion();#endif } else { completion(); printf("32C failed to respond in dac()\n"); error_at = 0; } if(error_at >= 0) return(error_at); else return(sent); } else printf("Failure while setting sample rate in dac()\n"); return(-1);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -