ftp.nice.ch/pub/next/unix/audio/Cmix.N.s.tar.gz#/cmix/cmd/mix.c

This is mix.c in view mode; [Download] [Up]

/* add zap, clean, layout features */
/* basic mixing program, based on MIX strategy with standard phrase card
   set by setline.  reset sets number of interrupts pr sec for envelope
   updates.  Still have to put exponential curves in setline.
   The only reason to have 4 almost identical routines here is that
   I cant figure out any other way to always load pointers in 
   registers.  but since this program wont be tinkered with much
   I guess it doesnt hurt.
*/
#include <stdio.h>
#include "../H/ugens.h"
#include "../H/sfheader.h"
#include "mix.h"
#include <signal.h>

static SFCODE	ampcode = {
	SF_MAXAMP,
	sizeof(SFMAXAMP) + sizeof(SFCODE)
}; 
extern SFHEADER      sfdesc[NFILES];
extern int  pointer[NFILES]; /* to be used as pointer within sound sndbuf */
extern int  bufsize[NFILES]; /* word length of sndbuf */
extern char *sndbuf[NFILES]; /* address of sndbuf */
extern char peakoff[NFILES];
extern float SR;
extern char *peak[NFILES];

int input,output,non,outch[4],inpch[4];
int inbufsize,outbufsize,nsamps,counter,skip;
float amp,dur,enval;
int clobber;
int test_mix_off = 1;

int lineset = 0;
int relampsign = 0;
float array[SIZE],tabs[2];
int RESET = 200;  /* times per sec to reinitialize envelope */

float begin_line = 0;
float end_line = 0;
int  offset = 0;

relamp(p,n_args)
float *p;
{
	relampsign = n_args ? p[0] : 1;
	if(relampsign) printf("Specified input amplitudes will be relative, based on peak amp in header.\n");
	else printf("Specified input amplitudes will be absolute.\n");
}
reset(p,n_args)
float *p;
{
	if(p[0]) RESET = p[0];
	fprintf(stderr,"Envelope calls set to %d times per sec\n",RESET);
}
global_times(p,n_args)
float *p;
{
	begin_line = p[0]; end_line = p[1];
	printf("Setline will control from file times %f to %f\n",p[0],p[1]);
}
double test_mix(p,n_args)
float *p;
{
	double output;
	double mix();
	test_mix_off = 0;
	output = mix(p,n_args);
	test_mix_off = 1;
	return(output);
}
double gen_to_setline(p,n_args)
float *p;
{
	float *f;
	int i;
	f = floc((int)p[0]);
	if(fsize((int)p[0]) != SIZE) {
		printf("Gen function must have size 1024\n");
		closesf();
		}
	for(i=0; i<SIZE; i++) array[i] = f[i];
	printf("Copied function %d to setline array\n",(int)p[0]);
	lineset = 1;
}

double mix(p,n_args)
float *p;
int n_args;
{
	int jj;
	char *cp,*getsfcode();
	float opeak,*pk;
	double _dur();
	SFMAXAMP sfm;

	input = 0; 
	output = 1;
	if(!p[2]) p[2] = _dur(&p[2],1);
	dur = (p[2] < 0) ? -p[2] : (p[2] - p[0]);

	if(!lineset) {
		for(jj=0; jj<SIZE; jj++) array[jj] = 1;
		fprintf(stderr,"Set phrase curve to all 1's\n");
		lineset = 1;
		}
		 setnote(p[0],dur,input);
	nsamps = setnote(p[1],dur,output);
	_backup(output);
//printf("in mix %f %f %f  %d %d %d\n",p[0],p[1],dur,input,output,nsamps);
	inbufsize = bufsize[input];
	outbufsize = bufsize[output];

	if(end_line) dur = end_line - begin_line;
	tableset(dur,SIZE,tabs);
	if(end_line)   /* this will give us global timefor setline */
		offset = (p[1] - begin_line) * SR;
	else offset = 0;
//printf("dur,offset,end_line,begin_line %f %d %f %f\n",dur,offset,end_line,begin_line);
						

	skip = SR/(float)RESET;  /* number of samples between reinits */
	counter = 0;  /* initialize counter */

	if(!relampsign) amp = p[3];
	else	{
		cp = getsfcode(&sfdesc[input],SF_MAXAMP);
		bcopy(cp + sizeof(SFCODE), (char *) &sfm, sizeof(SFMAXAMP));
		for(jj=0,opeak=0; jj<sfchans(&sfdesc[input]); jj++) 
		if(sfmaxamp(&sfm,jj) > opeak) opeak = sfmaxamp(&sfm,jj);
		printf("Peak amplitude of input file is %e\n",opeak);
		amp = p[3]/opeak;
	}

	non=0;
	for(jj = 0; jj<sfchans(&sfdesc[input]); jj++) {
		if((jj+4) > (n_args - 1)) break;
		if(p[4+jj] >= 0) {
			if((outch[non] = p[4+jj]) >= sfchans(&sfdesc[output])) {
				printf(" Wrong number of channels on output\n");
			closesf(); }
		inpch[non++] = jj;
		}
	}
	pk = (float *)peak[output];

	if(sfclass(&sfdesc[input]) == SHORT) {
		if(sfclass(&sfdesc[output]) == SHORT) {
			mixii();
			return(MAX(pk[0],pk[1]));
		}
		if(sfclass(&sfdesc[output]) == FLOAT) {
			mixif();
			return(MAX(pk[0],pk[1]));
		}
	}
	else {
		if(sfclass(&sfdesc[output]) == SHORT) {
			mixfi();
			return(MAX(pk[0],pk[1]));
		}
		if(sfclass(&sfdesc[output]) == FLOAT) {
			mixff();
			return(MAX(pk[0],pk[1]));
		}
	}
}
mixii()
{
	register short *ibuf,*obuf;
	register loop,jj,ipoint,opoint;
	register inchnl,outchnl;

	ibuf = (short *)sndbuf[input];
	obuf = (short *)sndbuf[output];
	inchnl = sfchans(&sfdesc[input]);
	outchnl = sfchans(&sfdesc[output]);
	opoint=pointer[output];   /* copy to save offset lookups every time*/
	ipoint=pointer[input];
	loop=nsamps;

	if(!clobber) while(loop--) 	{ 
		if(!counter--) {
			enval = tablei(nsamps+1-loop+offset,array,tabs) * amp;
			counter = skip;
			}
		for(jj = 0; jj<non; jj++) 
			    *(obuf + opoint + outch[jj]) += enval * 
			              *(ibuf + ipoint + inpch[jj]); 

		ipoint += inchnl;
		opoint += outchnl;
		if(ipoint >= inbufsize ) {
			ipoint = 0;
			if(_readit(input) == 0) {
			      fprintf(stderr,"reached eof on input\n");
			      goto out;
			}
		}
		if(opoint >= outbufsize ) {
			pointer[output] = opoint;
			if(!peakoff[output]) _chkpeak(output);
			if(test_mix_off) _writeit(output);
			else _forward(output);
			_readit(output);
			_backup(output);
			opoint = 0;
		}
	}
	else while(loop--) 	{ 
		if(!counter--) {
			enval = tablei(nsamps+1-loop+offset,array,tabs) * amp;
			counter = skip;
			}
		for(jj = 0; jj<non; jj++) 
			    *(obuf + opoint + outch[jj]) = enval * 
			              *(ibuf + ipoint + inpch[jj]); 

		ipoint += inchnl;
		opoint += outchnl;

		if(ipoint >= inbufsize ) {
			ipoint = 0;
			if(_readit(input) == 0) {
			      fprintf(stderr,"reached eof on input\n");
			      goto out;
			}
		}
		if(opoint >= outbufsize ) {
			pointer[output] = opoint;
			if(!peakoff[output]) _chkpeak(output);
			if(test_mix_off) _writeit(output); 
				else _forward(output);
			_readit(output);
			_backup(output);
			opoint = 0;
		}
	}
out:    pointer[input] = ipoint;
	pointer[output] = opoint;

	if(test_mix_off){ 
		_writeit(output); 
		endnote(output);
	}	
	else {
		_forward(output);
		endnote(-output);
	}
}
mixif()
{
	register short *ibuf;
	register float *obuf;
	register loop,jj,ipoint,opoint;
	register inchnl,outchnl;

	ibuf = (short *)sndbuf[input];
	obuf = (float *)sndbuf[output];
	inchnl = sfchans(&sfdesc[input]);
	outchnl = sfchans(&sfdesc[output]);
	opoint=pointer[output];   /* copy to save offset lookups every time*/
	ipoint=pointer[input];
	loop=nsamps;

	if(!clobber) while(loop--) 	{ 
		if(!counter--) {
			enval = tablei(nsamps+1-loop+offset,array,tabs) * amp;
			counter = skip;
			}
		for(jj = 0; jj<non; jj++) 
			    *(obuf + opoint + outch[jj]) += enval * 
			              *(ibuf + ipoint + inpch[jj]); 
		ipoint += inchnl;
		opoint += outchnl;

		if(ipoint >= inbufsize ) {
			ipoint = 0;
			if(_readit(input) == 0) {
			      fprintf(stderr,"reached eof on input\n");
			      goto out;
			}
		}
		if(opoint >= outbufsize ) {
			pointer[output] = opoint;
			if(!peakoff[output]) _chkpeak(output);
			if(test_mix_off) _writeit(output); else _forward(output);
			_readit(output);
			_backup(output);
			opoint = 0;
		}
	}
	else while(loop--) 	{ 
		if(!counter--) {
			enval = tablei(nsamps+1-loop+offset,array,tabs) * amp;
			counter = skip;
			}
		for(jj = 0; jj<non; jj++) 
			    *(obuf + opoint + outch[jj]) = enval * 
			              *(ibuf + ipoint + inpch[jj]); 

		ipoint += inchnl;
		opoint += outchnl;

		if(ipoint >= inbufsize ) {
			ipoint = 0;
			if(_readit(input) == 0) {
			      fprintf(stderr,"reached eof on input\n");
			      goto out;
			}
		}
		if(opoint >= outbufsize ) {
			pointer[output] = opoint;
			if(!peakoff[output]) _chkpeak(output);
			if(test_mix_off) _writeit(output); else _forward(output);
			_readit(output);
			_backup(output);
			opoint = 0;
		}
	}
out:    pointer[input] = ipoint;
	pointer[output] = opoint;
	
	if(test_mix_off){ 
		_writeit(output); 
		endnote(output);
	}	
	else {
		_forward(output);
		endnote(-output);
	}
}
mixfi()
{
	register float *ibuf;
	register short *obuf;
	register loop,jj,ipoint,opoint;
	register inchnl,outchnl;

	ibuf = (float *)sndbuf[input];
	obuf = (short *)sndbuf[output];
	inchnl = sfchans(&sfdesc[input]);
	outchnl = sfchans(&sfdesc[output]);
	opoint=pointer[output];   /* copy to save offset lookups every time*/
	ipoint=pointer[input];
	loop=nsamps;

	if(!clobber) while(loop--) 	{ 
		if(!counter--) {
			enval = tablei(nsamps+1-loop+offset,array,tabs) * amp;
			counter = skip;
			}
		for(jj = 0; jj<non; jj++) 
			    *(obuf + opoint + outch[jj]) += enval * 
			              *(ibuf + ipoint + inpch[jj]); 

		ipoint += inchnl;
		opoint += outchnl;

		if(ipoint >= inbufsize ) {
			ipoint = 0;
			if(_readit(input) == 0) {
			      fprintf(stderr,"reached eof on input\n");
			      goto out;
			}
		}
		if(opoint >= outbufsize ) {
			pointer[output] = opoint;
			if(!peakoff[output]) _chkpeak(output);
			if(test_mix_off) _writeit(output); else _forward(output);
			_readit(output);
			_backup(output);
			opoint = 0;
		}
	}
	else while(loop--) 	{ 
		if(!counter--) {
			enval = tablei(nsamps+1-loop+offset,array,tabs) * amp;
			counter = skip;
			}
		for(jj = 0; jj<non; jj++) 
			    *(obuf + opoint + outch[jj]) = enval * 
			              *(ibuf + ipoint + inpch[jj]); 

		ipoint += inchnl;
		opoint += outchnl;

		if(ipoint >= inbufsize ) {
			ipoint = 0;
			if(_readit(input) == 0) {
			      fprintf(stderr,"reached eof on input\n");
			      goto out;
			}
		}
		if(opoint >= outbufsize ) {
			pointer[output] = opoint;
			if(!peakoff[output]) _chkpeak(output);
			if(test_mix_off) _writeit(output); else _forward(output);
			_readit(output);
			_backup(output);
			opoint = 0;
		}
	}
out:    pointer[input] = ipoint;
	pointer[output] = opoint;
	
	if(test_mix_off){ 
		_writeit(output); 
		endnote(output);
	}	
	else {
		_forward(output);
		endnote(-output);
	}
}
mixff()
{
	register float *ibuf,*obuf;
	register loop,jj,ipoint,opoint;
	register inchnl,outchnl;

	ibuf = (float *)sndbuf[input];
	obuf = (float *)sndbuf[output];
	inchnl = sfchans(&sfdesc[input]);
	outchnl = sfchans(&sfdesc[output]);
	opoint=pointer[output];   /* copy to save offset lookups every time*/
	ipoint=pointer[input];
	loop=nsamps;

	if(!clobber) while(loop--) 	{ 
		if(!counter--) {
			enval = tablei(nsamps+1-loop+offset,array,tabs) * amp;
			counter = skip;
			}
		for(jj = 0; jj<non; jj++) 
			    *(obuf + opoint + outch[jj]) += enval * 
			              *(ibuf + ipoint + inpch[jj]); 

		ipoint += inchnl;
		opoint += outchnl;

		if(ipoint >= inbufsize ) {
			ipoint = 0;
			if(_readit(input) == 0) {
			      fprintf(stderr,"reached eof on input\n");
			      goto out;
			}
		}
		if(opoint >= outbufsize ) {
			pointer[output] = opoint;
			if(!peakoff[output]) _chkpeak(output);
			if(test_mix_off) _writeit(output); else _forward(output);
			_readit(output);
			_backup(output);
			opoint = 0;
		}
	}
	else while(loop--) 	{ 
		if(!counter--) {
			enval = tablei(nsamps+1-loop+offset,array,tabs) * amp;
			counter = skip;
			}
		for(jj = 0; jj<non; jj++) 
			    *(obuf + opoint + outch[jj]) = enval * 
			              *(ibuf + ipoint + inpch[jj]); 

		ipoint += inchnl;
		opoint += outchnl;

		if(ipoint >= inbufsize ) {
			ipoint = 0;
			if(_readit(input) == 0) {
			      fprintf(stderr,"reached eof on input\n");
			      goto out;
			}
		}
		if(opoint >= outbufsize ) {
			pointer[output] = opoint;
			if(!peakoff[output]) _chkpeak(output);
			if(test_mix_off) _writeit(output); else _forward(output);
			_readit(output);
			_backup(output);
			opoint = 0;
		}
	}
out:    pointer[input] = ipoint;
	pointer[output] = opoint;
	
	if(test_mix_off){ 
		_writeit(output); 
		endnote(output);
	}	
	else {
		_forward(output);
		endnote(-output);
	}
}

resetline(p,n_args)
float *p;
{
	double increm;
	int i,j,k,points;

	if((n_args % 2) != 0) {
		fprintf(stderr,"Something wrong with phrase, check args\n");
		closesf();
	}

	lineset = 1;   /* initialized array */
	increm = (double)(p[n_args - 2] - p[0])/(double)SIZE;
	for(j=0,i=0; j < (n_args-2); j += 2) {
		points = (int)((double)(p[j+2] - p[j]) / increm +.5);
		if(p[j+2] != p[j]) {
			if(points <= 0) points = 1;
			if((p[j+2] < p[j]) || (points > SIZE)) {
				fprintf(stderr," confusion on phrase card\n");
				closesf();
				}
			for(k=0; k < points; k++) {
				array[i++] *= ((float)k/(float)points)
					* (p[j+3] - p[j+1]) + p[j+1];
				if(i == SIZE) return;
			}
		}
	}
	i--;
	while(++i < SIZE) array[i] = array[i-1]; 
}
double m_setline(p,n_args)
float *p;
{
	double increm;
	int i,j,k,points;

	if((n_args % 2) != 0) {
		fprintf(stderr,"Something wrong with phrase, check args\n");
		closesf();
	}

	lineset = 1;   /* initialized array */
	increm = (double)(p[n_args - 2] - p[0])/(double)SIZE;
	for(j=0,i=0; j < (n_args-2); j += 2) {
		points = (int)((double)(p[j+2] - p[j]) / increm +.5);
		if(p[j+2] != p[j]) {
			if(points <= 0) points = 1;
			if((p[j+2] < p[j]) || (points > SIZE)) {
				fprintf(stderr," confusion on phrase card\n");
				closesf();
				}
			for(k=0; k < points; k++) {
				array[i++] = ((float)k/(float)points)
					* (p[j+3] - p[j+1]) + p[j+1];
				if(i == SIZE) return;
			}
		}
	}
	i--;
	while(++i < SIZE) array[i] = array[i-1]; 
}
m_clobber(p,n_args)
float *p;
{
     fprintf(stderr,"You will be writing over (erasing) all channels.\n");
     clobber = 1;
}
m_add(p,n_args)
float *p;
{
	fprintf(stderr,"You will be adding (mixing) to all channels.\n");
	clobber = 0;
}


These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.