
/* Generated by Interface Builder */

#import "Wave.h"
#define LOG10 2.3025
#define MAXVALUE 0.9

@implementation Wave

- setFftView:anObject
{
    fftView = anObject;
    return self;
}

+ newFrame:(NXRect *) frameRect
{
    self = [super newFrame:frameRect];
    anOrch = [Orchestra new];
  
    [anOrch open] ;
    
    [anOrch setFastResponse:YES];	
    
    // Create one oscillator with table lookup.
    
    osc = [anOrch allocUnitGenerator:[OscgafiUGxyxy class]];
    stereoOut = [anOrch allocUnitGenerator:[Out2sumUGx class]];
    outPatchpoint = [anOrch allocPatchpoint:MK_xPatch];
    tableLook = [anOrch allocSynthData:MK_yData length:tableLength];
    ampinp = [anOrch allocPatchpoint:MK_yPatch];
    freqinp = [anOrch allocPatchpoint:MK_xPatch];
	
    [osc setOutput:outPatchpoint];
    [osc setAmpInput:ampinp];
    [osc setIncInput:freqinp];
    
    DSPTable = (DSPDatum*) calloc(tableLength,sizeof(DSPDatum));
//    [self sine:self];
        
    [osc setTable:tableLook length:tableLength];
    [freqinp setToConstant:DSP_FLOAT_TO_INT([osc incAtFreq:100.])];
    [ampinp setToConstant:DSP_FLOAT_TO_INT(.1)];
    
    [osc run]; 
    [stereoOut run]; 
    [tableLook run]; 
    [outPatchpoint run]; 
    [freqinp run];
    [ampinp run];
    [stereoOut setInput:outPatchpoint];
    
    [anOrch run];
    DPSSetTracking(0);   //Tells the window server to coalesce mouse dragged events
    return self;
}

- mouseDown:(NXEvent *) anEvent
{
    [fftView storeCurrent:self];
    [super mouseDown:anEvent];
    return self;
}

- sawTooth:sender
{
 int i;

    for(i=0;i<tableLength;i++)
    {
	FuncTable[i] = (float)i/tableLength;
	DSPTable[i] = DSP_FLOAT_TO_INT(MAXVALUE*(2*FuncTable[i] -1));  
    }
    [tableLook setData:DSPTable];           
    [self display];
    [fftView receiveData:FuncTable length:tableLength];
    return self;
}

- triangle:sender
{
{
int i;

    for(i=0;i<tableLength;i++)
    {
	FuncTable[i] = ((i < tableLength/2) ? (float)i/tableLength*2 
	:  1. - (float)(i - tableLength /2) / tableLength * 2 );
	DSPTable[i] = DSP_FLOAT_TO_INT(MAXVALUE*(2*FuncTable[i]-1));  
    }
    [tableLook setData:DSPTable];           
    [self display];
    [fftView receiveData:FuncTable length:tableLength];
    return self;
}
}

- sine:sender
{
int i;

    for(i=0;i<tableLength;i++)
    {
	FuncTable[i] = .5 + 0.5*sin((float)i/tableLength*2*M_PI) ;
	DSPTable[i] = DSP_FLOAT_TO_INT(MAXVALUE*(2*FuncTable[i]-1));  
    }
    [tableLook setData:DSPTable];           
    [self display];
    [fftView receiveData:FuncTable length:tableLength];
    return self;
}

- square:sender
{
int i;

    for(i=0;i<tableLength;i++)
    {
	FuncTable[i] = (float)(i < tableLength/2) ;  
	DSPTable[i] = DSP_FLOAT_TO_INT(MAXVALUE*(2*FuncTable[i]-1));  
    }
    [tableLook setData:DSPTable];           
    [self display];
    [fftView receiveData:FuncTable length:tableLength];
    return self;
}

- afterDrag:(float*)data length:(int)aLength offset:(int)anOffset
{
int i;

    for(i=anOffset;i<anOffset + aLength;i++)
    {
	DSPTable[i] = DSP_FLOAT_TO_INT (MAXVALUE*(2*data[i] - 1));
    }
    
    [tableLook setData:(DSPTable+anOffset) length:aLength offset:anOffset];
    return self;
}

- afterUp:(float*)data length:(int)aLength
{
    
    fprintf(stderr,"AFTER UP!\n");
    [fftView receiveData:data length:aLength];
    
return self;
}

-sendFreq:sender
{
float fin;

    fin = 10 * exp ([sender floatValue] * LOG10);
    [freqinp setToConstant:DSP_FLOAT_TO_INT([osc incAtFreq:fin])];
}

-sendAmp:sender
{
float fin;

    fin = .1 * exp ([sender floatValue]);
    [ampinp setToConstant:DSP_FLOAT_TO_INT(fin)];
}

- setSound:sender
{
int i;

    for(i=0;i<tableLength;i++)
	DSPTable[i] = DSP_FLOAT_TO_INT(MAXVALUE*(2*FuncTable[i]-1));  
    [tableLook setData:DSPTable length:tableLength offset:0];
return self;
}


@end
