static int readsf(CSOUND *csound, MYFLT *inbuf, int inbufsize) { int i, n; (void) csound; n = inbufsize / (int) sizeof(MYFLT); i = (int) sf_read_MYFLT(STA(infile), inbuf, n); if (UNLIKELY(i < 0)) return inbufsize; memset(&inbuf[i], 0, (n-i)*sizeof(MYFLT)); return inbufsize; }
/* special handling of sound input to accomodate reads thru pipes & net * where nbytes rcvd can be < n requested * * extra arg passed for filetyp testing on POST-HEADER reads of audio samples */ static int sreadin(CSOUND *csound, SNDFILE *infd, MYFLT *inbuf, int nsamples, SOUNDIN *p) { /* return the number of samples read */ int n, ntot = 0; do { n = sf_read_MYFLT(infd, inbuf + ntot, nsamples - ntot); if (UNLIKELY(n < 0)) csound->Die(csound, Str("soundfile read error")); } while (n > 0 && (ntot += n) < nsamples); if (p->audrem > (int64_t) 0) { if ((int64_t) ntot > p->audrem) /* chk haven't exceeded */ ntot = (int) p->audrem; /* limit of audio data */ p->audrem -= (int64_t) ntot; return ntot; } return 0; }
static int filegrain_process(CSOUND *csound, filegrain *p) { MYFLT sig[DGRAIN_MAXCHAN], pitch, amp, grsize, envincr, period, fperiod, prate; MYFLT **output = p->output; MYFLT *datap = (MYFLT *) p->buffer.auxp; MYFLT *ftable = p->efunc->ftable; int *streamon = (int *) p->streamon.auxp; float start = p->start, frac = p->frac, jump; double *index = (double *) p->index.auxp; double *envindex = (double *) p->envindex.auxp; uint32_t offset = p->h.insdshead->ksmps_offset; uint32_t early = p->h.insdshead->ksmps_no_end; uint32_t vecpos, vecsize=CS_KSMPS; int firststream = p->firststream; int numstreams = p->numstreams, olaps = p->olaps; int count = p->count, i,j, newstream; int datasize, hdatasize, envtablesize = p->envtablesize; int dataframes = p->dataframes, hdataframes = p->dataframes/2; int read1 = p->read1, read2 = p->read2; int items, chans = p->nChannels, tndx,endx,n; uint32 pos = p->pos; int32 negpos, flen = p->flen; float trigger = p->trigger, incr; memset(sig, 0, DGRAIN_MAXCHAN*sizeof(MYFLT)); datasize = dataframes*chans; hdatasize = hdataframes*chans; pitch = *p->pitch; fperiod = FABS(CS_ESR/(*p->fr)); //if (UNLIKELY(fperiod < FL(0.0))) fperiod = -fperiod; amp = *p->amp; grsize = CS_ESR * *p->grsize; if (UNLIKELY(grsize<1)) goto err1; if (grsize > hdataframes) grsize = hdataframes; envincr = envtablesize/grsize; prate = *p->prate; if (UNLIKELY(offset)) memset(output, '\0', offset*sizeof(MYFLT)); if (UNLIKELY(early)) { vecsize -= early; memset(&output[vecsize], '\0', early*sizeof(MYFLT)); } for (vecpos = offset; vecpos < vecsize; vecpos++) { /* sig = (MYFLT) 0; */ /* if a grain has finished, clean up */ if (UNLIKELY((!streamon[firststream]) && (numstreams) )) { numstreams--; /* decrease the no of streams */ firststream=(firststream+1)%olaps; /* first stream is the next */ } /* if a fund period has elapsed */ /* start a new grain */ period = fperiod - frac; if (count ==0 || count >= period) { if (count) frac = count - period; newstream =(firststream+numstreams)%olaps; streamon[newstream] = 1; envindex[newstream] = 0.0; index[newstream] = start; numstreams++; count = 0; incr = prate*grsize; start += (incr); trigger += (incr); jump = grsize*(pitch > 0 ? pitch : -pitch); if (incr >= 0) { if (trigger >= (dataframes - jump)) { trigger -= (dataframes); if (!read1) { pos += hdataframes; sf_seek(p->sf,pos,SEEK_SET); items = sf_read_MYFLT(p->sf,datap,hdatasize); if (items < hdatasize) { sf_seek(p->sf, 0, 0); sf_read_MYFLT(p->sf,datap+items, hdatasize-items); } for (n=0; n < chans; n++) datap[hdatasize+n] = datap[hdatasize-chans+n]; read1 = 1; read2 = 0; } } else if (trigger >= (hdataframes - jump)) { if (!read2) { pos += hdataframes; sf_seek(p->sf,pos,SEEK_SET); items = sf_read_MYFLT(p->sf,datap+hdatasize, hdatasize); if (items < hdatasize) { sf_seek(p->sf, 0, SEEK_SET); sf_read_MYFLT(p->sf,datap+items+hdatasize, hdatasize-items); } for (n=0; n < chans; n++) datap[datasize+n] = datap[datasize-chans+n]; read2 = 1; read1 = 0; } } } else { if (trigger < jump) { trigger += (dataframes); if (!read1) { /*this roundabout code is to allow us to use an unsigned long to hold the file position whilst allowing for pos to go negative */ negpos = pos; negpos -= hdataframes; if (negpos < 0) { while(negpos < 0) negpos += flen; pos = negpos; } else pos -= hdataframes; /* pos -= hdataframes; if (pos < 0) pos += flen; */ sf_seek(p->sf,pos,SEEK_SET); items = sf_read_MYFLT(p->sf,datap+hdatasize,hdatasize); if (items < hdatasize) { sf_seek(p->sf,items-hdatasize,SEEK_END); items = sf_read_MYFLT(p->sf,datap+hdatasize+items, hdatasize-items); } for (n=0; n < chans; n++) datap[datasize+n] = datap[datasize-chans+n]; read1 = 1; read2 = 0; } } else if (trigger <= (hdataframes + jump)) { if (!read2) { negpos = pos; negpos -= hdataframes; if (negpos < 0) { while(negpos < 0) negpos += flen; pos = negpos; } else pos -= hdataframes; /* pos -= hdataframes; if (pos < 0) pos += flen; */ sf_seek(p->sf,pos,SEEK_SET); items = sf_read_MYFLT(p->sf,datap,hdatasize); if (items < hdatasize) { sf_seek(p->sf,items-hdatasize,SEEK_END); items = sf_read_MYFLT(p->sf,datap+items,hdatasize-items); } for (n=0; n < chans; n++) datap[hdatasize+n] = datap[hdatasize-chans+n]; read2 = 1; read1 = 0; } } } if (start >= dataframes) start -= dataframes; if (start < 0) start += dataframes; } for (i=numstreams, j=firststream; i; i--, j=(j+1)%olaps) { /* modulus */ if (index[j] >= dataframes) index[j] -= dataframes; if (index[j] < 0) index[j] += dataframes; /* sum all the grain streams */ tndx = (int)index[j]*chans; endx = (int) envindex[j]; /* sig[0] = sig[1] = sig[2] = sig[3] = 0.0; */ for (n=0; n < chans; n++) { sig[n] += ((datap[tndx+n] + (index[j] - (int)index[j])* (datap[tndx+n+chans] - datap[tndx+n]) ) * (ftable[endx] + (envindex[j] - endx)* (ftable[endx+1] - ftable[endx]) ) ); } /* increment the indexes */ /* for each grain */ index[j] += (pitch); envindex[j] += envincr; /* if the envelope is finished */ /* the grain is also finished */ if (envindex[j] > envtablesize) streamon[j] = 0; } /* increment the period counter */ count++; /* scale the output */ for (n=0; n < chans; n++) { output[n][vecpos] = sig[n]*amp; sig[n] = 0; } } p->firststream = firststream; p->numstreams = numstreams; p->count = count; p->start = start; p->frac = frac; p->trigger = trigger; p->read1 = read1; p->read2 = read2; p->pos = pos; return OK; err1: return csound->PerfError(csound, p->h.insdshead, Str("grain size smaller than 1 sample\n")); }
static int filegrain_init(CSOUND *csound, filegrain *p) { int size; void *fd; MYFLT *buffer; SF_INFO sfinfo; char *fname = p->fname->data; p->nChannels = (int) (p->OUTOCOUNT); if (UNLIKELY(p->nChannels < 1 || p->nChannels > DGRAIN_MAXCHAN)) { return csound->InitError(csound, Str("diskgrain: invalid number of channels")); } p->efunc = csound->FTnp2Find(csound, p->ifn2); if (UNLIKELY(p->efunc == NULL)) return NOTOK; p->olaps = (int) *p->ols + 1; p->dataframes = (int)(*p->max*CS_ESR*4); if (p->dataframes < MINFBUFSIZE) p->dataframes = MINFBUFSIZE; if (UNLIKELY(p->olaps < 2)) p->olaps = 2; size = (p->olaps) * sizeof(double); if (p->index.auxp == NULL || p->index.size < (unsigned int)size) csound->AuxAlloc(csound, size, &p->index); if (p->envindex.auxp == NULL || p->envindex.size < (unsigned int)size) csound->AuxAlloc(csound, size, &p->envindex); size = (p->olaps) * sizeof(int); if (p->streamon.auxp == NULL || p->streamon.size < (unsigned int)size) csound->AuxAlloc(csound, size, &p->streamon); if (p->buffer.auxp == NULL || p->buffer.size < (p->dataframes+1)*sizeof(MYFLT)*p->nChannels) csound->AuxAlloc(csound, (p->dataframes+1)*sizeof(MYFLT)*p->nChannels, &p->buffer); buffer = (MYFLT *) p->buffer.auxp; /* open file and read the first block using *p->ioff */ fd = csound->FileOpen2(csound, &(p->sf), CSFILE_SND_R, fname, &sfinfo, "SFDIR;SSDIR", CSFTYPE_UNKNOWN_AUDIO, 0); memset(buffer, 0,p->buffer.size); if (UNLIKELY(fd == NULL)) { return csound->InitError(csound, Str("diskgrain: could not open file\n")); } if (UNLIKELY(sfinfo.channels != p->nChannels)) { return csound->InitError(csound, Str("diskgrain: soundfile channel numbers " "do not match the number of outputs \n")); } if (*p->ioff >= 0) sf_seek(p->sf,*p->ioff * CS_ESR, SEEK_SET); if (LIKELY(sf_read_MYFLT(p->sf,buffer,p->dataframes*p->nChannels/2) != 0)) { p->read1 = 1; p->read2 = 0; } else { return csound->InitError(csound, Str("diskgrain: could not read file \n")); } /* -===- */ p->count = 0; /* sampling period counter */ p->numstreams = 0; /* curr num of streams */ p->firststream = 0; /* streams index (first stream) */ p->envtablesize = p->efunc->flen; /* size of envtable */ p->start = 0.0f; p->frac = 0.0f; p->pos = *p->ioff*CS_ESR; p->trigger = 0.0f; p->flen = sfinfo.frames; return OK; }