#import "../H/ugens.h"
#import <objc/objc.h>
#import "../objc/Comb.h"
#import "../objc/Reson.h"
#import "../H/sfheader.h"

#define SIZE 1024
#define MAXDEL 8192
int NBYTES = 32768;
#define NCOMBS 12
extern SFHEADER sfdesc[NFILES];
int ncombs=0;
float maxrev;
float zero = 0.;

float array[SIZE],wait[NCOMBS],combtime[NCOMBS],combrevtime[NCOMBS],amp[NCOMBS];

double multicomb(p,n_args)
float *p;
{
        id combl[NCOMBS];
        int k,j,count,input,output,nsamps,save_nsamps,i;
        int nchans;
        float atten,tabs[2],xin[2],out[2];
        float sig,oldl[NCOMBS],gain,envelope;
        double pow();
        /* p0=start, p1=dur, p2=inskip p3=input gain, p4=overall rvt*/
        for(i=0; i<ncombs; i++) {
                combl[i] = [Comb create];
                [combl[i] loopt:combtime[i] sRate:SR revTime:combrevtime[i]];
        }
        input = 0; output = 1;
        nsamps = setnote(p[0],p[1],output);
        setnote(p[2],p[1],input);
        gain = p[3];
        tableset(p[1]+p[4],SIZE,tabs);
        count = SR/200;
        zero = 0;

        for(j=i=0; i<nsamps; i++) {
                while(!j--) {
                        j=count;
                        envelope = tablei(i,array,tabs);
                }
                if(!GETIN(xin,input)) break;

                for(out[0]=k=0; k<ncombs; k++)
                        out[0] += [combl[k] bang:xin[0]] * amp[k];
                out[0] +=  xin[0] * gain;

                out[0] *= envelope;
                ADDOUT(out,output);
        }
        save_nsamps = i;
        nsamps = p[4] ?  p[4] * SR : maxrev * SR;
        for(j=i=0; i<nsamps; i++) {
                while(!j--) {
                        j=count;
                        envelope = tablei(i+save_nsamps,array,tabs);
                }
                for(out[0]=k=0; k<ncombs; k++) 
                        out[0] += [combl[k] bang:zero] * amp[k];

                out[0] *= envelope;

                ADDOUT(out,output);
        }
        endnote(output);
}

double setcombs(p,n_args)
float *p;
{
        int j;
        if(n_args > (NCOMBS*3)) {
                printf("You can specify a maximum of NCOMBS combs\n");
                closesf();
                }
        for(maxrev=j=ncombs=0; j<n_args; ncombs++,j += 3) {
                combtime[ncombs] = p[j];
                if(combtime[ncombs] > 10) {
                        printf("you have to specify the comb frequencies in 1/hz, not hz (or cps).  Try again\n");
                        closesf();
                        }
                combrevtime[ncombs] = p[j+1];
                if(combrevtime[ncombs] > maxrev) maxrev = combrevtime[ncombs];
                amp[ncombs] = p[j+2];
        }
        for(j=0; j<ncombs; j++) printf("comb:%d, looptime=%g(%g),\t reverbtime=%g, amp=%g\n",j,combtime[j],1/combtime[j],combrevtime[j],amp[j]);
        return(ncombs);
}

double sl(p,n_args)
float *p;
{
        int i;
        setline(p,n_args,SIZE,array);
}
profile()
{
        int i;
        for(i=0; i<SIZE; i++) array[i]=1;
        UG_INTRO("setcombs",setcombs);
        UG_INTRO("setcomb",setcombs);
        UG_INTRO("envelope",sl);
        UG_INTRO("multicomb",multicomb);
        UG_INTRO("multicombs",multicomb);

}
