コード例 #1
0
ファイル: minout.c プロジェクト: djtopper/RTcmix
off_t
outrepos(int samps, int fno)
{
        int seeking,amt;

        if(!status[fno]) {
                fprintf(stderr,"file %d is write protected!\n",fno);
                perror("write");
                closesf();
                }

        amt = samps * sfchans(&sfdesc[fno]) + pointer[fno];

        if ( (amt >= 0) && (amt < bufsize[fno]) ) {
                pointer[fno] = amt;     /* inside current buffer        */
                return(pointer[fno]);
                }
        
        if(wipe_is_off[fno]) _backup(fno);
        if(!peakoff[fno]) _chkpeak(fno);
        _writeit(fno);          /* write out current buffer */
        seeking = (amt - bufsize[fno]) * sfclass(&sfdesc[fno]);

        if ( (filepointer[fno] = lseek(sfd[fno],seeking,1)) == -1 ) {
                fprintf(stderr,"CMIX: bad outrepos lseek, file: %d\n",fno);
                closesf();
                }
        
        if(wipe_is_off[fno]) _readit(fno);
        pointer[fno] = 0;
        return(filepointer[fno]);
}
コード例 #2
0
ファイル: resetamp.c プロジェクト: CreativeInquiry/RTcmix
double
resetamp(float p[], int n_args)
{
	int i;	
	int fno;
	fno = p[0];
	if(!isopen[fno]) {
		printf("File number %d has not been opened\n",fno);
		return -1.0;
	}
	for(i = 0; i<sfchans(&sfdesc[fno]); i++) {
		sfmaxamp(&sfm[fno],i) = 0;
		sfmaxamploc(&sfm[fno],i) = 0;
	}
	if((filepointer[fno] = lseek(sfd[fno],0L,0)) < 0) {
		fprintf(stderr,"Bad lseek to beginning of file\n");
		perror("lseek");
		closesf();
	}

	putsfcode(&sfdesc[fno],(char *)&sfm[fno],&ampcode);

	if(wheader(sfd[fno],(char *)&sfdesc[fno])) {
		fprintf(stderr,"Bad header write\n");
		perror("write");
		closesf();
	}
	printf("reset header amplitudes to 0 in file %d\n",fno);

	return 0.0;
}
コード例 #3
0
ファイル: minc_info.cpp プロジェクト: djtopper/RTcmix
/* Note: the old versions of the peak info functions copy peak stats from
   the file header in memory into the sfm[fno] array maintained in sound.c.
   This seems unnecessary, since both are initialized on opening any file
   and updated on endnote. When would they ever be different from the
   perspective of these info functions, which can't be called from Minc
   in the *middle* of an instrument run? Are they also called internally,
   like m_dur?  -JGG
*/ 
double
m_peak(float p[], int n_args)
{
	int      n, fno;
	float    peak, chanpeak;

	fno = (int) p[0];
	if (!isopen[fno]) {
		fprintf(stderr, "You haven't opened file %d yet!\n", fno);
		closesf();
	}

	peak = 0.0;

	if (sfmaxamptime(&sfm[fno]) > 0L) {
		for (n = 0; n < sfchans(&sfdesc[fno]); n++) {
			chanpeak = sfmaxamp(&sfm[fno], n);
			if (chanpeak > peak)
				peak = chanpeak;
		}
	}
	else
		fprintf(stderr, "File %d has no peak stats!\n", fno);

	return peak;
}
コード例 #4
0
ファイル: sfcopy.c プロジェクト: CreativeInquiry/RTcmix
double
sfcopy(float p[], int n_args)
{
	int maxread,n,input,output,bytes,jj;

	if(!n_args) fprintf(stderr,"(sfcopy(input_fno,output_fno,input_skip,output_skip,dur)\n");
	input = (int)p[0];
	output = (int)p[1];
	if((sfclass(&sfdesc[input]) != sfclass(&sfdesc[output])) ||
	   (sfchans(&sfdesc[input]) != sfchans(&sfdesc[output]))) {
		fprintf(stderr,
		 "Input and output specifications do not match. Canot copy.\n");
		closesf();
	}
	bytes = setnote(p[2],p[4],input) * 
		 sfchans(&sfdesc[input]) * sfclass(&sfdesc[input]);

	setnote(p[3],p[4],output);
	_backup(input);
	_backup(output);

	fprintf(stderr,"Copy %d bytes\n",bytes);

	while(bytes) {
		maxread = (bytes > nbytes) ? nbytes : bytes;
		if((n = read(sfd[input],sndbuf[input],maxread)) <= 0) {
			fprintf(stderr,"Apparent eof on input\n");
			return -1.0;
		}
		if((jj = write(sfd[output],sndbuf[input],n)) <= 0) {
			fprintf(stderr,"Trouble writing output file\n");
			closesf();
		}
		bytes -= n;
		filepointer[input] += n;
		filepointer[output] += n;
	}
	if(fsync(sfd[output]) < 0 ) {
		fprintf(stderr,"trouble fsyncing file");
		closesf();
	}
	fprintf(stderr,"Copy completed\n");

	return 0.0;
}
コード例 #5
0
ファイル: sound.c プロジェクト: CreativeInquiry/RTcmix
int
setnote(float start, float dur, int fno)
{
	int nsamps,offset;
	int i;

	if(!isopen[fno]) {
		rtcmix_warn("setnote","You haven't opened file %d yet!\n",fno);
		closesf();
	}
	if(start > 0.) /* if start < 0 it indicates number of samples to skip*/
	        offset = (int) (start * SR() + .5) * sfchans(&sfdesc[fno])
	    		* sfclass(&sfdesc[fno]);

	else    offset = -start * sfchans(&sfdesc[fno]) * sfclass(&sfdesc[fno]);

		/* make sure it falls on channel/block boundary */
	offset -= offset % (sfchans(&sfdesc[fno]) * sfclass(&sfdesc[fno]));
	offset = (offset < 0) ? 0 : offset;

	nsamps = (dur > 0.) ? (int)((start+dur) * SR() -
	(offset/(sfchans(&sfdesc[fno])*sfclass(&sfdesc[fno])))+ .5) : (int)-dur;

	if(!istape[fno]) {
		if((filepointer[fno] = 
		   lseek(sfd[fno],offset+headersize[fno],0)) == -1) {
			rtcmix_warn("setnote", "CMIX: bad lseek in setnote\n");
			closesf();
		}
	}
	pointer[fno] = 0;

	_readit(fno);   /* read in first buffer */

	for(i=0; i<(sfchans(&sfdesc[fno]) * FLOAT); i++)
		*(peak[fno] + i) = 0;

	wipe_is_off[fno] = 1;          /* for wipeout */

	starttime[fno] = (start<0) ? -start/SR() : start;

	times(&clockin[fno]);       /* read in starting time */

	return(nsamps);
}
コード例 #6
0
ファイル: minc_info.cpp プロジェクト: djtopper/RTcmix
double m_chans(float *p, int n_args)
{	
  if(!isopen[(int)p[0]]) {
    fprintf(stderr, "You haven't opened file %d yet!\n", (int)p[0]);
    closesf();
  }
  
  return(sfchans(&sfdesc[(int)p[0]]));
}
コード例 #7
0
ファイル: sound.c プロジェクト: CreativeInquiry/RTcmix
float
getpeakval(float peakflag, int fno)
{
	float opeak;
	int i;
	float *pk;
	pk = (float *)peak[fno];

	if(peakflag < 0) {
		for(i=0,opeak=0; i<sfchans(&sfdesc[fno]); i++)
			if(pk[i] > opeak) 
					opeak=pk[i];
	}
	else if(peakflag == 0) {
		for(i=0,opeak=0; i<sfchans(&sfdesc[fno]); i++)
			if((float)sfmaxamp(&sfm[fno],i) > opeak) 
					opeak=sfmaxamp(&sfm[fno],i);
	}
	else opeak = peakflag;
/*	printf("peakflag=%f, peakval=%f\n",peakflag,opeak); */
	return(opeak);
}
コード例 #8
0
ファイル: minc_info.cpp プロジェクト: djtopper/RTcmix
double m_dur(float *p, int n_args)
{
	int i;
	float dur;
	i = (int) p[0];
	if(!isopen[i]) {
		fprintf(stderr, "You haven't opened file %d yet!\n", i);
		closesf();
	}
	dur = (float)(sfst[i].st_size - headersize[i])
		 /(float)sfclass(&sfdesc[i])/(float)sfchans(&sfdesc[i])
		 /sfsrate(&sfdesc[i]);
	return(dur);
}
コード例 #9
0
ファイル: getsample.c プロジェクト: CreativeInquiry/RTcmix
static int
getfsample(double sampleno, float *c, int input)
{
	int RECSIZE = bufsize[input];
	int BPREC = RECSIZE * sizeof(float);
	int BPFRAME = sfchans(&sfdesc[input]) * sizeof(float);
	int FPREC = RECSIZE/(float)sfchans(&sfdesc[input]);

	int sample,i,j,nbytes;
	float *array = (float *)sndbuf[input];
	float fraction,tempfloat1,tempfloat2;
	static int oldsample = 0;
	static int endsample = 0;
	extern float swapfloat();

	sample = (int)sampleno;
	fraction = sampleno - (double)sample;
	if(!((sample >= oldsample) && (sample < endsample))) {
		/* sflseek (sfheader.h) assumes header size, so can't use it */
		if(lseek(sfd[input], (sample * BPFRAME) + headersize[input],
							SEEK_SET) <= 0) {
			rterror(NULL,"badlseek on inputfile\n");
			closesf();
		}
		nbytes = read(sfd[input], (char *)array, BPREC);
		if (nbytes == -1) {
			perror("getfsample: read");
			return 0;
		}
		if (nbytes == 0) {
			rterror(NULL, "reached eof on input file\n");
			return 0;
		}
		if (nbytes < BPREC)     /* zero out rest of sndbuf */
			for (i = nbytes; i < BPREC; i++)
				sndbuf[input][i] = 0;
		oldsample = sample;
		endsample = oldsample + FPREC - 1;
		}
	for(i = (sample-oldsample)*sfchans(&sfdesc[input]),j=0; 
					j<sfchans(&sfdesc[input]); i++,j++)  {
	  if (swap_bytes[input]) {
	    tempfloat1 = *(array+i);
	    byte_reverse4(&tempfloat1);
	    tempfloat2 = (*(array+i+sfchans(&sfdesc[input])));
	    byte_reverse4(&tempfloat2)
	      *(c+j) = tempfloat1 + fraction * (tempfloat2-tempfloat1);
	  }
	  else {
	    *(c+j) = *(array+i) + fraction * 
	      (*(array+i+sfchans(&sfdesc[input])) - *(array+i));
	  }
	}
	return(1);
}
コード例 #10
0
ファイル: sound.c プロジェクト: CreativeInquiry/RTcmix
void
_chkpeak(int fno)
{
	register int i,incr;
	register short *ibuf,*bufend;
	register float *fbuf,*fbufend,*pk;
	short *ibufx;
	float *fbufx;
	long *pkloc,currentloc;

	pk = (float *)peak[fno];
	incr = sfchans(&sfdesc[fno]);
	pkloc = (long *)peakloc[fno];

	if(sfclass(&sfdesc[fno]) == SHORT) {
		ibufx = ibuf = (short *)sndbuf[fno];
		bufend = ibuf + pointer[fno]; /* to allow for final check */
		currentloc = (long)
				((filepointer[fno]-headersize[fno])/(SHORT * incr));
		while(ibuf<bufend)  {
			for(i=0; i<incr; i++)  {
				if(ABS(*(ibuf + i)) > (int)*(pk+i)) {
					*(pk+i) = ABS(*(ibuf + i)); 
					*(pkloc+i) = currentloc + 
					(long)((ibuf - ibufx)/incr);
				}
			}
			ibuf += incr;
		}
	}
	else {
		fbufx = fbuf = (float *)sndbuf[fno];
		fbufend = fbuf + pointer[fno];
		currentloc = (long)
				((filepointer[fno]-headersize[fno])/(FLOAT * incr));
		while(fbuf<fbufend) {
			for(i=0; i<incr; i++)  {
				if(ABS(*(fbuf + i)) > *(pk+i)) {
					*(pk+i) = ABS(*(fbuf + i));
					*(pkloc+i) = currentloc +
					(long)((fbuf - fbufx)/incr);
				}
			}
			fbuf += incr;	
		} 
	} 
}
コード例 #11
0
ファイル: sound.c プロジェクト: CreativeInquiry/RTcmix
static int
_fgetin(float *in, int fno)
{
	register int i;
	register int ipoint = pointer[fno];
	register int incr = sfchans(&sfdesc[fno]);
	register float *fbuf;

	for(i=0,fbuf = (float *)sndbuf[fno] + ipoint; i<incr; i++) {
	  *(in+i) =  *(fbuf + i);
	}
	if((pointer[fno] += i) >= bufsize[fno] ) {
		pointer[fno] = 0;
		return(_readit(fno));
	}
	return(nbytes);
}
コード例 #12
0
ファイル: sound.c プロジェクト: CreativeInquiry/RTcmix
static int
_igetin(float *in, int fno)
{
	int i;
	int ipoint = pointer[fno];
	int incr = sfchans(&sfdesc[fno]);
	short *ibuf;

	for(i=0,ibuf = (short *)sndbuf[fno] + ipoint; i<incr; i++) {
	  *(in+i) = *(ibuf + i);
	}
	if((pointer[fno] += i) >= bufsize[fno] ) {
		pointer[fno] = 0;
		return(_readit(fno));
	}
	return(nbytes);
}
コード例 #13
0
ファイル: sound.c プロジェクト: CreativeInquiry/RTcmix
void
blayout(float *out, int *chlist, int fno, int size)
{
	register int i,j;
	register short *ibuf;
	register float *fbuf;
	register int todo;
	register int nchans;
	int len = bufsize[fno]; 

	nchans = sfchans(&sfdesc[fno]);

refill:	todo = ((pointer[fno] + size) > len) 
				? len - pointer[fno] : size;
	if(sfclass(&sfdesc[fno]) == SF_SHORT) {
	  for(i=0,ibuf = (short *)sndbuf[fno] + pointer[fno];i<todo;i += nchans) {
	    for(j=0; j<nchans; j++,ibuf++,out++) {
	      if(chlist[j]) {
		*ibuf = (short) *out;	
	      }
	    }
	  }
	}
	else {
	  for(i=0,fbuf = (float *)sndbuf[fno] + pointer[fno];i<todo;i += nchans) {
	    for(j=0; j<nchans; j++,fbuf++,out++) {
	      if(chlist[j]) {
		*fbuf = *out;
	      }
	    }
	  }
	}
	pointer[fno] += todo;

	if(pointer[fno] == len) {
		_backup(fno);
		if(!peakoff[fno])
			_chkpeak(fno);
		_writeit(fno);
		_readit(fno);
		pointer[fno] = 0;
	}

	if(size -= todo) goto refill;
}
コード例 #14
0
ファイル: sound.c プロジェクト: CreativeInquiry/RTcmix
static int
_faddout(float *out, int fno)
{
	register int i;
	register int ipoint = pointer[fno];
	register int incr = sfchans(&sfdesc[fno]);
	register float *fbuf;

	for(i=0,fbuf = (float *)sndbuf[fno] + ipoint; i<incr; i++) {
	  *(fbuf + i) +=  *(out+i);
	}
	if((pointer[fno] += i) >= bufsize[fno] ) {
	  _backup(fno);
	  if(!peakoff[fno]) _chkpeak(fno);
	  _writeit(fno);
	  _readit(fno);
	  pointer[fno] = 0;
	}
	return 0;
}
コード例 #15
0
ファイル: sound.c プロジェクト: CreativeInquiry/RTcmix
static int
_ilayout(float *out, int *chlist, int fno)
{
	register int i;
	register int ipoint = pointer[fno];
	register int incr = sfchans(&sfdesc[fno]);
	register short *ibuf;

	for(i=0,ibuf = (short *)sndbuf[fno] + ipoint; i<incr; i++) {
	  if(chlist[i]) {
	      *(ibuf + i) = *(out+i); 
	  }
	}
	if((pointer[fno] += i) >= bufsize[fno] ) {
		_backup(fno);
		if(!peakoff[fno]) _chkpeak(fno);
		_writeit(fno);
		_readit(fno);
		pointer[fno] = 0;
	}
	return 0;
}
コード例 #16
0
ファイル: sound.c プロジェクト: CreativeInquiry/RTcmix
static int
_fwipeout(float *out, int fno)   /* to force destructive writes */ 
{
	register int i;
	register int ipoint = pointer[fno];
	register int incr = sfchans(&sfdesc[fno]);
	register float *fbuf;

	for(i=0,fbuf = (float *)sndbuf[fno] + ipoint; i<incr; i++) {
	  *(fbuf + i) =  *(out+i);
	}
	if((pointer[fno] += i) >= bufsize[fno] ) {
		if(wipe_is_off[fno]) {   /*setnot positions after first read*/
			_backup(fno);
			wipe_is_off[fno] = 0;
			}
		if(!peakoff[fno])
			_chkpeak(fno);
		_writeit(fno);
		pointer[fno] = 0;
	}
	return 0;
}
コード例 #17
0
ファイル: minout.c プロジェクト: djtopper/RTcmix
off_t
inrepos(int samps, int fno)
{
        int seeking,amt;

        amt = samps * sfchans(&sfdesc[fno]) + pointer[fno];

        if ( (amt >= 0) && (amt < bufsize[fno]) ) {
                pointer[fno] = amt;     /* reposition inside buffer */
                return(pointer[fno]);
                }
        
        seeking = (amt - bufsize[fno]) * sfclass(&sfdesc[fno]);

        if ( (filepointer[fno] = lseek(sfd[fno],seeking,1)) == -1 ) {
                fprintf(stderr,"CMIX: Bad inrepos lseek, file: %d\n",fno);
                closesf();
                }

        _readit(fno);
        pointer[fno] = 0;
        return(filepointer[fno]);
}
コード例 #18
0
ファイル: sound.c プロジェクト: CreativeInquiry/RTcmix
void
m_zapout(int fno, char *buffer, int nwrite, int *chlist)
{
	float *fbuf;
	int i,j,nchunks,chans;
	short *ibuf;

	chans = sfchans(&sfdesc[fno]);

	if(sfclass(&sfdesc[fno]) == SF_SHORT) {
		ibuf = (short *) buffer;
		nchunks = nwrite/SF_SHORT;
		for(i=0; i<nchunks; i += chans)
			for(j=0; j<chans; j++)
				if(chlist[j]) *(ibuf+j+i) = 0;
	}
	else {
		fbuf = (float *) buffer;
		nchunks = nwrite/SF_FLOAT;
		for(i=0; i<nchunks; i += chans) 
			for(j=0; j<chans; j++)
				if(chlist[j]) *(fbuf+j+i) = 0;
	}
}
コード例 #19
0
ファイル: sgran.c プロジェクト: RTcmix/RTcmix
double
sgran(float p[], int n_args)
{
	long n,bgrainsamps,bgraindist,bgrainslide;
	long i,nsamps,gstt_var,count;
	long egrainsamps,egraindist,egrainslide;
	long grainsamps,grainslide,graindistdiff;
	float si=0.0,phase,val=0.0,amp,out[2],chb,freq;
	float tabs[2],tab[2],tab2[2],tab3[2],tab4[2],tab5[2];
	double *array,*wave,*envel,*rate_shape,*dur_shape,*loc_shape,*freq_shape;
	float gdist_inc;
	double gstt_per,lo,mid,hi,ti,slodiff,smiddiff,shidiff,stidiff;
	double dlodiff,dmiddiff,dhidiff,dtidiff;
	double llodiff,lmiddiff,lhidiff,ltidiff;
	double flodiff,fmiddiff,fhidiff,ftidiff;
	int len,j,z,chans,randflag=0;

#ifdef EMBEDDED
	int outrepos();
#endif
	float rrand();
	void srrand();
	double prob();

	if (p[37] > 0)
		srrand(p[37]);
   else
		srrand(3);

	nsamps = setnote(p[0],p[1],1); /* set file position */

	array = floc(1);             /* used to be setline  -JGG */
	if (array) {
		int amplen = fsize(1);
		tableset(SR(), p[1], amplen, tabs);
	}
	else
		rtcmix_advise("sgran", "Setting phrase curve to all 1's.");

	wave = floc(6); /* finds starting loc. of waveform */
	if (wave == NULL)
		die("sgran", "You haven't made the oscillator waveform (table 6).");
	len = fsize(6); /* length of playing waveform function */

	envel = floc(8);  /* NOTE: used to be floc(1), now stolen by setline  -JGG */
	if (envel == NULL)
		die("sgran", "You haven't made the grain envelope (table 8).");
	/* NOTE: fsize(8) called in loop below */

	bgrainsamps = grainsamps = p[14] * SR();
	bgraindist = p[3] * SR();
	bgrainslide = grainslide = bgraindist - bgrainsamps;

	egrainsamps = p[18] * SR();
	egraindist = p[4] * SR();
	egrainslide = egraindist - egrainsamps;

	graindistdiff = egraindist - bgraindist;

	rate_shape = floc(2);
	if (rate_shape == NULL)
		die("sgran", "You haven't made the grain density function (table 2).");
	tableset(SR(), p[1]-p[4],fsize(2),tab2);

	dur_shape = floc(3);
	if (dur_shape == NULL)
		die("sgran", "You haven't made the grain duration function (table 3).");
	tableset(SR(), p[1]-p[4],fsize(3),tab3);

	loc_shape = floc(4);
	if (loc_shape == NULL)
		die("sgran", "You haven't made the grain location function (table 4).");
	tableset(SR(), p[1]-p[4],fsize(4),tab4);

	freq_shape = floc(5);
	if (freq_shape == NULL)
		die("sgran", "You haven't made the grain frequency function (table 5).");
	tableset(SR(), p[1]-p[4],fsize(5),tab5);

	slodiff = (double)(p[9]-p[5])/nsamps; /* get stt zero/one differences */
	smiddiff = (double)(p[10]-p[6])/nsamps;
	shidiff = (double)(p[11]-p[7])/nsamps;
	stidiff = (double)(p[12]-p[8])/nsamps;

	dlodiff = (double)(p[17]-p[13]); /*get dur zero/one differences */
	dmiddiff = (double)(p[18]-p[14]);
	dhidiff = (double)(p[19]-p[15]);
	dtidiff = (double)(p[20]-p[16]);

	llodiff = (double)(p[25]-p[21]); /*get loc zero/one differences */
	lmiddiff = (double)(p[26]-p[22]);
	lhidiff = (double)(p[27]-p[23]);
	ltidiff = (double)(p[28]-p[24]);
	chb = p[21];

	if (p[29] < 0) 		/* if negative, noise is the input */
		randflag = 1;

	flodiff = (double)(p[33]-p[29]); /*freq zero/one differences */
	fmiddiff = (double)(p[34]-p[30]);
	fhidiff = (double)(p[35]-p[31]);
	ftidiff = (double)(p[36]-p[32]);

	z = 2;

	chans = sfchans(&sfdesc[1]); /* get file number of channels */
	amp = p[2];
	gstt_var = 0;
	count = 0;

	j = 0; /* "branch once a cycle" loop for amp envelope */

	for(i = 0; i < nsamps; i++) {
		count++;
		phase = 0;
		tableset(SR(), grainsamps/SR(),fsize(8),tab);
		if(!randflag) {
			lo = p[29] + flodiff*tablei(i,freq_shape,tab5);
			mid = p[30] + fmiddiff*tablei(i,freq_shape,tab5);
			hi = p[31] + fhidiff*tablei(i,freq_shape,tab5);
			ti = p[32] + ftidiff*tablei(i,freq_shape,tab5);
			lo = (lo > mid) ? mid : lo;
			hi = (hi < mid) ? mid : hi;
			ti = (ti < 0) ? 0 : ti; 
			freq = prob(lo, mid, hi, ti);
			si = freq * (float)len/SR(); 
		}

/*
	fprintf(stderr,"i: %ld, grainsamps: %ld, grainslide: %ld\n",i,grainsamps,grainslide);
*/

		for (n = 0; n < grainsamps; n++) {
			while (!j--) {   /* branch in here when j reaches 0 */
				float tmp = 1.0;
				if (array)
					tmp = tablei(i,array,tabs);
				val = amp * tablei(n,envel,tab) * tmp;
				j = ((grainsamps-n) > z) ? z : (grainsamps-n);
			}
			if(randflag)
				out[0] = rrand()*val;
			else
				out[0] =  oscili(val,si,wave,len,&phase);

			if (chans > 1) { /* stereo */
				out[1] = (1.0 - chb) * out[0];
				out[0] *= chb;
			}
			ADDOUT(out,1);
		}

		if((i+grainslide+gstt_var+grainsamps) < 0) {
			outrepos((grainslide),1);
			i += grainsamps;
			i += grainslide;
		}	
		else {
			outrepos((grainslide+gstt_var),1);
			i += grainsamps;
			i += grainslide;
			i += gstt_var;
		}

		lo = p[13] + dlodiff*tablei(i,dur_shape,tab3);
		mid = p[14] + dmiddiff*tablei(i,dur_shape,tab3);
		hi = p[15] + dhidiff*tablei(i,dur_shape,tab3);
		ti = p[16] + dtidiff*tablei(i,dur_shape,tab3);
		lo = (lo > mid) ? mid : lo;
		hi = (hi < mid) ? mid : hi;
		ti = (ti < 0) ? 0 : ti; 
		grainsamps = (long)(prob(lo, mid, hi, ti)*SR());


		/*	get percentage to vary next stt of grain */
		lo = p[5] + slodiff*i;
		mid = p[6] + smiddiff*i;
		hi = p[7] + shidiff*i;
		ti = p[8] + stidiff*i;
		lo = (lo > mid) ? mid : lo;
		hi = (hi < mid) ? mid : hi;
		ti = (ti < 0) ? 0 : ti; 
		gstt_per = prob(lo, mid, hi, ti);
		gstt_var = (long)(gstt_per*(grainsamps+grainslide)); 

/* calculate grainslide */
		gdist_inc = tablei(i,rate_shape,tab2);
		grainslide = (float)bgraindist + (float)graindistdiff*gdist_inc - grainsamps;

		lo = p[21] + llodiff*tablei(i,loc_shape,tab4);
		mid = p[22] + lmiddiff*tablei(i,loc_shape,tab4);
		hi = p[23] + lhidiff*tablei(i,loc_shape,tab4);
		ti = p[24] + ltidiff*tablei(i,loc_shape,tab4);
		lo = (lo > mid) ? mid : lo;
		hi = (hi < mid) ? mid : hi;
		ti = (ti < 0) ? 0 : ti; 
		chb = prob(lo, mid, hi, ti);
	}
	printf("\n%ld grains\n",count);
	endnote(1);

	return(0.0);
}
コード例 #20
0
int
main(int argc, char *argv[])
{
	int sf;
	int comment = 0;
	struct stat sfst;
	SFHEADER sfh;
	SFMAXAMP sfm;
	SFCOMMENT sfcm;
	SFCODE *sizer;
	FILE *fcom;
	char *sfname,*cp,*getsfcode();
	int length,newchans,newclass,newpeak,result,i,n,tfd,tn,nchars=MINCOMM;
	float newsrate;
	int zap;

	zap = newchans = newclass = newsrate = newpeak = 0;
	length = 1;

	if(argc > 1) {
		if(*argv[1] != '-') {
			printf("usage: \"sfhedit -r [srate] -[i=int;f=float] -c [nchans] -p [peak] -w [comment] -z\"\n");
			exit(1);
		}
	}
	else if(argc == 1) {
		printf("usage: \"sfhedit -r [srate] -[i=int;f=float] -c [nchans] -p [peak] -w [comment] -z\"\n");
		exit(1);
	}

	while((*++argv)[0] == '-') {
		argc -= 2; /* Take away two args */
		for(cp = argv[0]+1; *cp; cp++) {
			switch(*cp) { /* Grap options */
			case 'r': 
				newsrate = atof(*++argv);
				break;
			case 'i': 
				newclass = SF_SHORT;
				break;
			case 'f':
				newclass = SF_FLOAT;
				break;
			case 'c': 
				newchans = atoi(*++argv);
				if(newchans > 4) {
					printf(" Sorry, maximum is 4 channels\n");
					exit(1);
				}
				break;
			case 'p':
				newpeak = 1;
				break;
			case 'w':
				comment = 1;
				break;
			case 'z':
				zap = 1;
				break;
			case 'l':
				length = 1;
				break;
			default:  
				printf("don't know about option %c\n",*cp);
			}
		}
	}
	sfname = argv[0];
	rwopensf(sfname,sf,sfh,sfst,"sfhedit",result,2);
	if(result < 0) {
		exit(1);
	}
	printsf(&sfh);
	if(newchans) {
		sfchans(&sfh) = newchans;
		printf("-->Channels reset to %d\n",newchans);
	}
	if(newsrate) {
		sfsrate(&sfh) = newsrate;
		printf("-->Sampling rate reset to %5.0f\n",newsrate);
	}
	if(newclass) {
		sfclass(&sfh) = newclass;
		printf("-->Class reset to %d\n",newclass);
	}		
	if(newpeak) {
		for(i=0; i<sfchans(&sfh); i++) {
			printf("Enter peak and time for channel %d\t",i);
			scanf("%f %ld",&sfmaxamp(&sfm,i),&sfmaxamploc(&sfm,i));
		}
		sfmaxamptime(&sfm) = time(NULL);

		putsfcode(&sfh,(char *)&sfm,&ampcode);
	}
	if(zap) {
	 	if(ftruncate(sf,0) < 0) 
			printf("Bad truncation\n");
		for(i=0; i<sfchans(&sfh); i++) {
			sfmaxamp(&sfm,i) = sfmaxamploc(&sfm,i) = 0;
		putsfcode(&sfh,(char *)&sfm,&ampcode);
		putlength(sfname,sf,&sfh);
		}
		printf("file truncated to 0, and header adjusted\n");
	}
	if(comment) {
		cp = getsfcode(&sfh,SF_COMMENT);
		if(cp == NULL) {
			printf("No comment found. Adding a new one..\n");
			system("vi /tmp/comment");
			fcom = fopen("/tmp/comment","r");
			i=0;
			while ( (sfcomm(&sfcm,i) = getc(fcom)) != EOF ) {
				if (++i > MAXCOMM) {
					printf("Gimme a break! I can only take %d characters\n",MAXCOMM);
					printf("comment truncated to %d characters\n",MAXCOMM);
					commentcode.bsize = MAXCOMM + sizeof(SFCODE);
					break;
				}
			}
			sfcomm(&sfcm,i) = '\0';
			system("rm /tmp/comment");
			if (nchars > MINCOMM)
				commentcode.bsize = nchars + sizeof(SFCODE);
			if (i > nchars)
				commentcode.bsize = i + sizeof(SFCODE);
			if (putsfcode(&sfh,(char *)&sfcm,&commentcode) < 0) {
				printf("comment didn't get written, sorry!\n");
				exit(1);
			}
			goto skip;
		}

		strncpy((char *)&sfcm, sfcommentstr(&sfh), MAXCOMM - 1);
		sfcm.comment[MAXCOMM - 1] = '\0';

		tfd = open("/tmp/tmpcom",O_CREAT|O_RDWR,0644);
		tn = write(tfd, &sfcomm(&sfcm,0), strlen(&sfcomm(&sfcm,0)));
		close(tfd);
		system("vi /tmp/tmpcom");
		tfd = open("/tmp/tmpcom",0);
		n = read(tfd,&sfcomm(&sfcm,0),MAXCOMM);
		system("rm /tmp/tmpcom");
		if (n < tn) {
			for (i = n; i <= tn; i++) {
				sfcomm(&sfcm,i) = '\0';
			}
		}
		if (putsfcode(&sfh,(char *)&sfcm,&commentcode) < 0) {
			printf("comment didn't get written, sorry!\n");
			exit(1);
		}
	}

skip:	lseek(sf,0,0);
	if(wheader(sf,(char *)&sfh)) {
	       printf("Can't seem to write header on file %s\n",sfname);
		perror("main");
		exit(1);
	}

	if (length) {      /* do this last, after wheader */
		putlength(sfname,sf,&sfh);
	}

	return 0;
}
コード例 #21
0
ファイル: sound.c プロジェクト: CreativeInquiry/RTcmix
int
endnote(int xno)
{
	struct timeval tp;	
	struct timezone tzp;	
	int i,j,final_bytes,fno;
	float notepeak,*pk;
	double total;
	long *pkloc;
	struct tms timbuf;
	float peakval;
	struct stat st;
	short tisamp,*tibuf;
	float tfsamp,*tfbuf;

	fno = ABS(xno);  /* if fno is negative it means don't write
					final buffer,just pretend to */
	if(wipe_is_off[fno]) 
		_backup(fno); 
	/* else _flushbuf(fno); */
	if(!peakoff[fno]) _chkpeak(fno);
	final_bytes =  pointer[fno]  * sfclass(&sfdesc[fno]);
	
	/* This was DS's and PL's version of real time */
	/* Not used in this version */
#ifdef OLDRT

	/*  SHOULD NOT PLAY HERE -- LAST BUFFERS ALREADY PLAYED */
	if ((sfclass(&sfdesc[fno]) == SF_SHORT) && play_is_on)
		playbuf(sndbuf[fno],final_bytes/SF_SHORT);
	else if ((sfclass(&sfdesc[fno]) == SF_FLOAT) && play_is_on) {
		peakval = getpeakval(peakflag,fno);
		playfbuf(sndbuf[fno],peakval,swap[fno],nbytes/SF_FLOAT);
	}
#endif

	/* write out only fractional part of last record, god bless unix!*/
	if(pointer[fno] && (play_is_on < 2)) {
		if(xno >= 0) {
			/* Swap bytes if necessary */
			if(final_bytes && swap_bytes[fno]) {
				/* SHORT file */
				if(sfclass(&sfdesc[fno]) == SF_SHORT) {
					tibuf = (short *)sndbuf[fno]; 
					for (i=0;i<final_bytes/SF_SHORT;i++) {
						tisamp = *(tibuf+i);
						*(tibuf+i) = reverse_int2(&tisamp);
					}
				}
				/* FLOAT file */
				if(sfclass(&sfdesc[fno]) == SF_FLOAT) {
					tfbuf = (float *)sndbuf[fno]; 
					for (i=0;i<final_bytes/SF_FLOAT;i++) {
						/* 	byte_reverse4(tfbuf+i); */
						/* 	tfsamp = *(tfbuf+i); */
						/* 	*(tfbuf+i) = (float)reverse_int4(&tfsamp); */
					  	tfsamp = *(tfbuf+i);
						byte_reverse4(&tfsamp);
					  	*(tfbuf+i) = tfsamp;
					}
				}
   			}
   			if((i = write(sfd[fno],sndbuf[fno],final_bytes)) 
											!= final_bytes) {
				rtcmix_warn("CMIX", "Bad UNIX write, file %d, nbytes = %d\n",
					fno,i);
				perror("write");
				closesf();
   			}
   		}
   		if((filepointer[fno] += final_bytes) > originalsize[fno]) 
   		if(xno >0)  originalsize[fno] = filepointer[fno];
	}
	/* DT: 	if(play_is_on) flush_buffers(); */
	
	pk = (float *)peak[fno];
	pkloc = (long *)peakloc[fno];
	total = ((double)filepointer[fno]-headersize[fno])
					/((double)sfclass(&sfdesc[fno]))
					/(double)sfchans(&sfdesc[fno])/SR();
	
	/* _writeit(fno);  write out final record */

	for(i = 0,notepeak=0; i<sfchans(&sfdesc[fno]); i++) { 
		if(*(pk+i) > sfmaxamp(&sfm[fno],i)) {
			sfmaxamp(&sfm[fno],i) = *(pk+i);
			sfmaxamploc(&sfm[fno],i) = *(pkloc+i);
		}
		if(*(pk+i) > notepeak) notepeak = *(pk+i);
	}
	
	gettimeofday(&tp,&tzp);
	sfmaxamptime(&sfm[fno]) = tp.tv_sec;
		
	if((filepointer[fno] = lseek(sfd[fno],0L,0)) < 0) {
		rtcmix_warn("CMIX", "Bad lseek to beginning of file\n");
		perror("lseek");
		closesf();
	}


	times(&timbuf);

#ifndef MAXMSP // this really isn't used...
	printf("\n(%6.2f)",(float)(
					(timbuf.tms_stime-clockin[fno].tms_stime)+
					(timbuf.tms_utime-clockin[fno].tms_utime))/60.);
	printf(" %9.4f .. %9.4f MM ",starttime[fno],total);
	
	if(!peakoff[fno]) {
		for(j=0;j<sfchans(&sfdesc[fno]);j++)
			printf(" c%d=%e",j,*(pk+j));
		printf("\n");
		if(punch[fno]) {
			printf("alter(%e,%e,%e/%e",
						(double)starttime[fno],(double)(total-starttime[fno]),
						punch[fno],notepeak);
			for(i=0; i<sfchans(&sfdesc[fno]); i++)
				printf(",1 ");
			printf(")\n");
			printf("mix(%g,%g,%g,%g/%g",
							(double)starttime[fno],(double)starttime[fno],-(double)(total-starttime[fno]),punch[fno],notepeak);
			for(i=0; i<sfchans(&sfdesc[fno]); i++)
				printf(",%d ",i);
			printf(")\n");
		}
	}
#endif // MAXMSP

	/* Copy the updated peak stats into the SFHEADER struct for this
	   output file. (No swapping necessary.)
	*/
	memcpy(&(sfmaxampstruct(&sfdesc[fno])), &sfm[fno], sizeof(SFMAXAMP));

	/* Write header to file. */
	if (wheader(sfd[fno], &sfdesc[fno])) {
		rtcmix_warn("endnote", "bad header write\n");
		perror("write");
		closesf();
	}
	return 0;
}
コード例 #22
0
ファイル: getsample.c プロジェクト: CreativeInquiry/RTcmix
static int
getisample(double sampleno, float *c, int input)
{

	ssize_t RECSIZE = bufsize[input];
	ssize_t BPREC = RECSIZE * sizeof(short);
	ssize_t BPFRAME = sfchans(&sfdesc[input]) * sizeof(short);
	ssize_t FPREC = RECSIZE/sfchans(&sfdesc[input]);

	int sample,i,j;
    ssize_t nbytes;
	signed short *array = (short *)sndbuf[input];
	float tempsample1;
	float tempsample2;
	float fraction;
	static int oldsample = 0;
	static int endsample = 0;

	sample = (int)sampleno;
	fraction = sampleno - (double)sample;
	if(!((sample >= oldsample) && (sample < endsample))) {
		/* sflseek (sfheader.h) assumes header size, so can't use it */
		if(lseek(sfd[input], (sample * BPFRAME) + headersize[input],
							SEEK_SET) <= 0) {
			rterror(NULL, "badlseek on inputfile\n");
			closesf();
		}
		nbytes = read(sfd[input], (char *)array, BPREC);
		if (nbytes == -1) {
			perror("getisample: read");
			return 0;
		}
		if (nbytes == 0) {
			rterror(NULL, "reached eof on input file\n");
			return 0;
		}
		if (nbytes < BPREC) {    /* zero out rest of sndbuf */
			ssize_t n;
			for (n = nbytes; n < BPREC; n++)
				sndbuf[input][n] = 0;
		}
		oldsample = sample;
		endsample = oldsample + FPREC - 1;
		}
	for(i=(sample-oldsample)*sfchans(&sfdesc[input]),j=0; 
	    j<sfchans(&sfdesc[input]); i++,j++)  {
	  
	  if (swap_bytes[input]) {
	    tempsample1 = (signed short)reverse_int2(array+i);
	    tempsample2 = (signed short)reverse_int2(array+i+sfchans(&sfdesc[input]));
	    *(c+j) = tempsample1 + fraction * 
	      ((float)((signed short)tempsample2 - tempsample1));
	  }
	  else {
	    *(c+j) = (float)*(array+i) + fraction * 
	      ((float) *(array+i+sfchans(&sfdesc[input])) - 
	       (float) *(array+i));
	  }
	}
	return(1);

}
コード例 #23
0
ファイル: sound.c プロジェクト: CreativeInquiry/RTcmix
double
m_clean(float p[], int n_args) /* a fast clean of file, after header */
{
/* if p1-> = 0, clean whole file, else skip=p1, dur=p2, ch-on? p3--> */
	int i;
	off_t n, nwrite, todo;
	char *point;
	int fno,segment,chlist[4];
	int skipbytes;

	fno = (int) p[0];
	skipbytes = 0;
	if(!status[fno]) {
		rtcmix_warn(NULL,"fno %d is write-protected!\n",fno);
		closesf();
	}
	todo = originalsize[fno] - headersize[fno];

	segment = (n_args > 1) ? 1 : 0;

	if(segment) {
		skipbytes = (p[1] > 0) ? p[1] * sfclass(&sfdesc[fno]) *
			    SR() * sfchans(&sfdesc[fno]) 
			    : -p[1] * sfclass(&sfdesc[fno]) * 
							 sfchans(&sfdesc[fno]);
		todo =  (p[2] > 0) ? p[2] * sfclass(&sfdesc[fno]) * 
			SR() * sfchans(&sfdesc[fno])
			: -p[2] * sfclass(&sfdesc[fno]) * 
						sfchans(&sfdesc[fno]);
		for(i=0; i<sfchans(&sfdesc[fno]); i++) chlist[i] = p[i+3];
	}
	point = (char *)sndbuf[fno];
	if(!segment) for(i=0; i<nbytes; i++) *(point+i) = 0;

	if((filepointer[fno] = 
	   lseek(sfd[fno],skipbytes+headersize[fno],0)) == -1) {
		rtcmix_warn("CMIX", "bad sflseek in clean\n");
		closesf();
	}
#ifdef MINGW
	// no %11 in Win libc, have to use %I64 instead:
	// http://stackoverflow.com/questions/13590735/printf-long-long-int-in-c-with-gcc?
	printf("Clean %I64d bytes\n",(long long)todo);
#else
	printf("Clean %lld bytes\n",(long long)todo);
#endif
	while(todo) {
		nwrite = (todo > nbytes) ? nbytes : todo;
		if(segment) {
			if((n = read(sfd[fno],sndbuf[fno],nwrite)) 
					== 0) { /* allow for fractional reads*/
				fprintf(stderr, "CMIX: Apparent eof in clean\n");
				return -1.0;
			}
			if(lseek(sfd[fno],-n,1) < 0) {
				fprintf(stderr,"Bad UNIX lseek in clean\n");
				closesf();
			}
			m_zapout(fno,sndbuf[fno],n,chlist);
			nwrite = n;
		}
		if((n = write(sfd[fno],sndbuf[fno],nwrite)) == 0) {
			fprintf(stderr, "CMIX: Apparent eof in clean\n");
	        	closesf();
		}
		todo -= n;
	}
	if(!segment) {
		if((lseek(sfd[fno],0,0)) == -1) {
			fprintf(stderr,"CMIX: bad lseek in clean\n");
			closesf();
		}

		for(i = 0; i<sfchans(&sfdesc[fno]); i++) { 
			sfmaxamp(&sfm[fno],i) = 0;
			sfmaxamploc(&sfm[fno],i) = 0;
		}

		putsfcode(&sfdesc[fno],(char *)&sfm[fno],&ampcode);

		if(wheader(sfd[fno],(char *)&sfdesc[fno])) {
			fprintf(stderr,"Bad header write\n");
			perror("write");
			closesf();
		}
	}
	else 
		if((lseek(sfd[fno],headersize[fno],0)) == -1) {
			fprintf(stderr,"CMIX: bad lseek in clean\n");
			closesf();
		}
	filepointer[fno] = headersize[fno];
	printf("Clean successfully finished.\n");

   return 0.0;
}
コード例 #24
0
ファイル: stgran.c プロジェクト: eriser/rtcmix-android
double
stgran(float p[], int n_args)
{
   int inchans, outchans, inchan;
   float indur, outdur, insk, outsk;
   long bgrainsamps, bgraindist, bgrainslide, inbgraindist;
   long i, nsamps, gstt_var, in_gstt_var, count, outcount, branch, skip;
   long s;                      /* sample number */
   long egrainsamps, egraindist, egrainslide, inegraindist;
   long grainsamps, grainslide, graindistdiff;
   long ingrainsamps, ingrainslide, ingraindistdiff;
   long  maxinsamps, maxoutsamps;
   float val, amp, aamp;
   float gdist_inc, in_gdist_inc;
   float tab1[2], tab2[2], tab3[2], tab4[2], tab5[2], tab6[2], tab7[2], tab8[2];
   double *in_rate_shape, *rate_shape, *dur_shape, *transp_shape, *amp_shape;
   double *loc_shape, *envel, *slarray;
   float *inarr, *outarr;
   double gstt_per, in_gstt_per, lo, mid, hi, ti, sig, table_val;
   double slodiff, smiddiff, shidiff, stidiff;
   double ilodiff, imiddiff, ihidiff, itidiff;
   double dlodiff, dmiddiff, dhidiff, dtidiff;
   double alodiff, amiddiff, ahidiff, atidiff, grainamp;
   double tlodiff, tmiddiff, thidiff, ttidiff;
   double llodiff, lmiddiff, lhidiff, ltidiff, pctleft = 0.0;
   double tlobeg, tmidbeg, thibeg, tloend, tmidend, thiend;
   double voldsig = 0.0, oldsig, newsig, interval, increment;
   double counter = 0., frac;
   register int incount = 1, getflag = 1;

   outsk = p[0];
   insk = p[1];
   outdur = p[2];
   indur = p[3];
   amp = p[4];

   setnote(insk, indur, INPUT);
   nsamps = setnote(outsk, outdur, OUTPUT);

   tlobeg = (double) octpch(p[33]);
   tmidbeg = (double) octpch(p[34]);
   thibeg = (double) octpch(p[35]);
   tloend = (double) octpch(p[37]);
   tmidend = (double) octpch(p[38]);
   thiend = (double) octpch(p[39]);

   inchan = (int) p[58];
   inchans = sfchans(&sfdesc[INPUT]);
   if (inchan >= inchans)
      die("stgran", "You asked for channel %d of a %d-channel file.",
                                                          inchan, inchans);
   outchans = sfchans(&sfdesc[OUTPUT]);
   if (outchans > 2)
      die("stgran", "Output file must be either mono or stereo.");

   /* allocate input and output buffers */
   interval = MAX(thibeg, thiend);      /* maximum transp. value (lin oct) */
   increment = cpsoct(10.0 + interval) / cpsoct(10.0);
   hi = MAX(p[31], p[27]) * SR();         /* maximum grain duration */
   maxinsamps = (long) (hi * increment + 1.0);
   inarr = malloc(maxinsamps * inchans * sizeof(float));
   if (inarr == NULL)
      die("stgran", "Can't allocate input buffer.");
   maxoutsamps = (long) (hi + 1.0);
   outarr = malloc(maxoutsamps * outchans * sizeof(float));
   if (outarr == NULL)
      die("stgran", "Can't allocate output buffer.");

   bgrainsamps = grainsamps = p[26] * SR();
   bgraindist = p[7] * SR();
   bgrainslide = grainslide = bgraindist - bgrainsamps;
   egrainsamps = p[30] * SR();
   egraindist = p[8] * SR();
   egrainslide = egraindist - egrainsamps;
   graindistdiff = egraindist - bgraindist;

   inbgraindist = p[5] * SR();
   inegraindist = p[6] * SR();
   ingraindistdiff = inegraindist - inbgraindist;

   in_rate_shape = floc(2);
	if (in_rate_shape == NULL)
		die("stgran",
				"You haven't made the grain input rate function (table 2).");
   tableset(SR(), indur - p[6], fsize(2), tab2);

   rate_shape = floc(3);
	if (rate_shape == NULL)
		die("stgran",
				"You haven't made the grain output rate function (table 3).");
   tableset(SR(), outdur - p[8], fsize(3), tab3);

   dur_shape = floc(4);
	if (dur_shape == NULL)
		die("stgran", "You haven't made the grain duration function (table 4).");
   tableset(SR(), outdur - p[8], fsize(4), tab4);

   transp_shape = floc(5);
	if (transp_shape == NULL)
		die("stgran",
				"You haven't made the grain transposition function (table 5).");
   tableset(SR(), outdur - p[8], fsize(5), tab5);

   amp_shape = floc(6);
	if (amp_shape == NULL)
		die("stgran", "You haven't made the grain amplitude function (table 6).");
   tableset(SR(), outdur - p[8], fsize(6), tab6);

   loc_shape = floc(7);
	if (loc_shape == NULL)
		die("stgran",
				"You haven't made the grain stereo location function (table 7).");
   tableset(SR(), outdur - p[8], fsize(7), tab7);

   envel = floc(8);           /* tableset in sample loop */
	if (envel == NULL)
		die("stgran", "You haven't made the grain envelope (table 8).");

   /* get infile stt var zero/one differences */
   ilodiff = (double) (p[13] - p[9]) / nsamps;
   imiddiff = (double) (p[14] - p[10]) / nsamps;
   ihidiff = (double) (p[15] - p[11]) / nsamps;
   itidiff = (double) (p[16] - p[12]) / nsamps;

   /* get outfile stt var zero/one differences */
   slodiff = (double) (p[21] - p[17]) / nsamps;
   smiddiff = (double) (p[22] - p[18]) / nsamps;
   shidiff = (double) (p[23] - p[19]) / nsamps;
   stidiff = (double) (p[24] - p[20]) / nsamps;

   /* get dur zero/one differences */
   dlodiff = (double) (p[29] - p[25]);
   dmiddiff = (double) (p[30] - p[26]);
   dhidiff = (double) (p[31] - p[27]);
   dtidiff = (double) (p[32] - p[28]);

   /* transp zero/one differences */
   tlodiff = tloend - tlobeg;
   tmiddiff = tmidend - tmidbeg;
   thidiff = thiend - thibeg;
   ttidiff = (double) (p[40] - p[36]);

   /* amp zero/one differences */
   alodiff = (double) (p[45] - p[41]);
   amiddiff = (double) (p[46] - p[42]);
   ahidiff = (double) (p[47] - p[43]);
   atidiff = (double) (p[48] - p[44]);

   /* loc zero/one differences */
   llodiff = (double) (p[53] - p[49]);
   lmiddiff = (double) (p[54] - p[50]);
   lhidiff = (double) (p[55] - p[51]);
   ltidiff = (double) (p[56] - p[52]);

   if (p[57] > 0)
      srrand(p[57]);
   else
      srrand(.3);    /* JGG: srrand takes unsigned int! */

   skip = SR() / (float) resetval;               /* control rate for amp curve */

   gstt_var = in_gstt_var = 0;
   count = 0;

   aamp = amp;                       /* in case there is no setline function */
   slarray = floc(1);
   if (slarray) {
      int len = fsize(1);
      tableset(SR(), outdur, len, tab1);
   }
   else
      rtcmix_advise("stgran", "Setting phrase curve to all 1's.");

   for (i = 0; i < nsamps; i++) {
      count++;
      table_val = (double) tablei(i, transp_shape, tab5);
      lo = tlobeg + (tlodiff * table_val);
      mid = tmidbeg + (tmiddiff * table_val);
      hi = thibeg + (thidiff * table_val);
      ti = p[36] + (ttidiff * table_val);
      lo = (lo > mid) ? mid : lo;
      hi = (hi < mid) ? mid : hi;
      interval = prob(lo, mid, hi, ti);                      /* in lin oct */
      increment = cpsoct(10.0 + interval) / cpsoct(10.0);    /* samp incr. */

      /* calculate next grain duration */
      table_val = (double) tablei(i, dur_shape, tab4);
      lo = p[25] + (dlodiff * table_val);
      mid = p[26] + (dmiddiff * table_val);
      hi = p[27] + (dhidiff * table_val);
      ti = p[28] + (dtidiff * table_val);
      lo = (lo > mid) ? mid : lo;
      hi = (hi < mid) ? mid : hi;
      grainsamps = (long) (prob(lo, mid, hi, ti) * SR());
      tableset(SR(), grainsamps / SR(), fsize(8), tab8);

      /* calculate grain amplitude */
      table_val = (double) tablei(i, amp_shape, tab6);
      lo = p[41] + (alodiff * table_val);
      mid = p[42] + (amiddiff * table_val);
      hi = p[43] + (ahidiff * table_val);
      ti = p[44] + (atidiff * table_val);
      lo = (lo > mid) ? mid : lo;
      hi = (hi < mid) ? mid : hi;
      grainamp = prob(lo, mid, hi, ti);

      /* calculate grain stereo location */
      if (outchans > 1) {
         table_val = (double) tablei(i, amp_shape, tab7);
         lo = p[49] + (llodiff * table_val);
         mid = p[50] + (lmiddiff * table_val);
         hi = p[51] + (lhidiff * table_val);
         ti = p[52] + (ltidiff * table_val);
         lo = (lo > mid) ? mid : lo;
         hi = (hi < mid) ? mid : hi;
         pctleft = prob(lo, mid, hi, ti);
      }

      /* get percentage to vary next stt of grain */
      lo = p[17] + slodiff * i;
      mid = p[18] + smiddiff * i;
      hi = p[19] + shidiff * i;
      ti = p[20] + stidiff * i;
      lo = (lo > mid) ? mid : lo;
      hi = (hi < mid) ? mid : hi;
      gstt_per = prob(lo, mid, hi, ti);
      gstt_var = (long) (gstt_per * (grainsamps + grainslide));

      /* calculate grainslide */
      gdist_inc = tablei(i, rate_shape, tab3);
      grainslide = (float) bgraindist
                     + (float) graindistdiff * gdist_inc - grainsamps;

      ingrainsamps = grainsamps * increment;

#ifdef DEBUG
      printf("ingrainsamps: %ld, maxinsamps: %ld\n", ingrainsamps, maxinsamps);
      assert(ingrainsamps <= maxinsamps);
      assert(grainsamps <= maxoutsamps);
#endif

      bgetin(inarr, INPUT, ingrainsamps * inchans);  /* read in grain */

      ingrainslide = ((float) inbgraindist) * increment
                      + (float) ingraindistdiff * increment - ingrainsamps;

      /* transpose the grain and write it to output file */
      oldsig = inarr[inchan];
      newsig = inarr[inchans + inchan];
      incount = 1;
      outcount = 0;
      counter = 0;
      branch = 0;
      for (s = 0; s < grainsamps; s++) {
         while (getflag) {
            voldsig = oldsig;
            oldsig = newsig;
            newsig = inarr[(incount * inchans) + inchan];
            incount++;
            if ((counter - (float) incount) < 0.5) {
               getflag = 0;
            }
         }
         /* update overall amp envelope at control rate */
         while (!branch--) {
            if (slarray)
               aamp = tablei(i, slarray, tab1) * amp;
            branch = skip;
         }
         /* update grain envelope on every sample */
         val = tablei(s, envel, tab8) * grainamp * aamp;

         frac = counter - incount + 2.0;               /* the interp value */

         sig = interp(voldsig, oldsig, newsig, frac) * val;

         if (outchans == 2) {
            outarr[outcount] = sqrt(pctleft) * sig;
            outarr[outcount + 1] = sqrt(1.0 - pctleft) * sig;
         }
         else
            outarr[outcount] = sig;

         counter += increment;            /* keeps track of interp pointer */
         if ((counter - (float) incount) >= -0.5) {
            getflag = 1;
         }
         outcount += outchans;
      }
      baddout(outarr, OUTPUT, grainsamps * outchans);
      inrepos(ingrainslide, INPUT);

      if ((i + grainslide + gstt_var + grainsamps) < 0) {
         outrepos(grainslide, OUTPUT);
         i += grainsamps;
         i += grainslide;
      }
      else {
         outrepos((grainslide + gstt_var), OUTPUT);
         i += grainsamps;
         i += grainslide;
         i += gstt_var;
      }
   }
   printf("\n%ld grains\n", count);
   endnote(OUTPUT);

   free(inarr);
   free(outarr);

   return 0.0;
}
コード例 #25
0
ファイル: sound.c プロジェクト: CreativeInquiry/RTcmix
double m_open(float *p, short n_args, double *pp) 
{
	char  *name,*cp,*getsfcode();
	int   fno,i,inew;
	float *opk;

	name = DOUBLE_TO_STRING(pp[0]);
	fno = p[1];
// JGG: will name ptr be valid for entire program run? Is its memory held by
// parser? If not, we should malloc sfname[fno] below (with other mallocs)
	sfname[fno] = name;
	status[fno] = (n_args == 3) ? (int)p[2] : 2;

	if((fno >=  NFILES) || (fno < 0)) {
		rtcmix_warn("m_open", "Only %d files allowed\n", NFILES);
		closesf();
		}
	inew = 0;
	if(isopen[fno]) {
		close(sfd[fno]);
	}
	else inew = 1;

	istape[fno] = (n_args == 4) ? 1 : 0;
			/* in the case of a tape, there will be a 
			   4th argument listing the file number */

	rwopensf(name,sfd[fno],sfdesc[fno],sfst[fno],"CMIX",i,status[fno]);
	if (i < 0)
		closesf();

	if (status[fno] == O_RDWR
			&& !WRITEABLE_HEADER_TYPE(sfheadertype(&sfdesc[fno]))) {
		rtcmix_warn("m_open", "can't write this type of header.\n");
		closesf();
	}

	isopen[fno] = 1;

	swap_bytes[fno] = swap;  /* swap and isNext set in rwopensf */
	is_Next[fno] = isNext;
	headersize[fno] = getheadersize(&sfdesc[fno]);

	rtcmix_advise(NULL, "name: %s   sr: %.3f  nchans: %d  class: %d\n",name,
		sfsrate(&sfdesc[fno]),sfchans(&sfdesc[fno]), sfclass(&sfdesc[fno]));
	rtcmix_advise(NULL, "Soundfile type: %s\n",
			mus_header_type_name(sfheadertype(&sfdesc[fno])));
	rtcmix_advise(NULL, "   data format: %s\n",
			mus_data_format_name(sfdataformat(&sfdesc[fno])));
	rtcmix_advise(NULL, "Duration of file is %f seconds.\n",
		(float)(sfst[fno].st_size - headersize[fno])/(float)sfclass(&sfdesc[fno])/(float)sfchans(&sfdesc[fno])/sfsrate(&sfdesc[fno]));

	originalsize[fno] = istape[fno] ? 999999999 : sfst[fno].st_size;
	/*
	sfstats(sfd[fno]);
	*/
	if(inew) {
		if((sndbuf[fno] = (char *)malloc((unsigned)nbytes)) == NULL) {
			rtcmix_warn("CMIX", "malloc sound buffer error\n");
			closesf();
		}
		if((peakloc[fno] = (char *)malloc((unsigned)(sfchans(&sfdesc[fno]) * 
			LONG))) == NULL) {
			rtcmix_warn("CMIX", "malloc ovpeak buffer error\n");
			closesf();
		}
		if((peak[fno] = 
			(char *)malloc((unsigned)(sfchans(&sfdesc[fno])* FLOAT))) 
			== NULL) {
			rtcmix_warn("CMIX", "malloc peak buffer error!\n");
			closesf();
		}
		peakoff[fno] = 0; /* default to peakcheckon when opening file*/
		punch[fno] = 0; /* default to no punch when opening file*/
	}
	if(sfclass(&sfdesc[fno]) == SHORT) {
		addoutpointer[fno] = _iaddout;
		layoutpointer[fno] = _ilayout;
		wipeoutpointer[fno] = _iwipeout;
		getinpointer[fno] = _igetin;
	}
	else 			        {   
		addoutpointer[fno] = _faddout;
		layoutpointer[fno] = _flayout;
		wipeoutpointer[fno] = _fwipeout;
		getinpointer[fno] = _fgetin;
	}

	if(!SR()) set_SR(sfsrate(&sfdesc[fno]));	

	if(sfsrate(&sfdesc[fno])!= SR())
		rtcmix_advise("CMIX", "Note--> SR reset to %f\n",SR());

	/* read in former peak amplitudes, make sure zero'ed out to start.*/

	/* In the sndlib version, we store peak stats differently. See
	   comments in sndlibsupport.c for an explanation. The sndlib
	   version of rwopensf reads peak stats, so here we just have to
	   copy these into the sfm[fno] array. (No swapping necessary.)
	*/
	memcpy(&sfm[fno], &(sfmaxampstruct(&sfdesc[fno])), sizeof(SFMAXAMP));

	for(opk = (float *)peak[fno], i = 0; i<sfchans(&sfdesc[fno]); i++) 
		*(opk+i) = sfmaxamp(&sfm[fno],i);
	bufsize[fno] = nbytes / sfclass(&sfdesc[fno]);/* set size in words */

	return 0.0;
}