This is FFTControl.m in view mode; [Download] [Up]
/* Generated by Interface Builder */
#import "FFTControl.h"
#define LOGBOTTOM 6.9077552
extern rfft();
@implementation FFTControl
- setModView:anObject
{
modView = anObject;
[modView setDisplayMode:DISCRETE];
return self;
}
- setPhiView:anObject
{
phiView = anObject;
return self;
}
- setWaveView:anObject
{
int i;
waveView = anObject;
dataLength = [waveView tableLength];
fprintf(stderr,"dataLength %d\n",dataLength);
FFTData = (float*) calloc(dataLength,sizeof(float));
for(i=0;i<4;i++)
storeTable[i] = (float*) calloc(dataLength,sizeof(float));
for(i=0;i<2;i++)
swap[i] = (float*) calloc(dataLength,sizeof(float));
PHIData = (float*) calloc(dataLength/2,sizeof(float));
MODData = (float*) calloc(dataLength/2,sizeof(float));
currentBuffer = 0;
return self;
}
- setConvView:anObject
{
convView = anObject;
return self;
}
- setMod:(float*)data
{
int i;
float *indData, *indFFT, *indMod, *indPhi,maxValue,minValue,Value;
[self storeCurrent:self];
indFFT = FFTData;
indData = data;
indMod = MODData;
indPhi = PHIData;
if(logDisplay)
for(i=0;i<dataLength/2;i++)
{
float value;
value = *(indMod++) = *(indData++) ;
value = exp((value - 1)* LOGBOTTOM );
if (value - .00101 <= 0) value = 0;
*(indFFT++) = value * cos((*indPhi -.5)*2*M_PI);
*(indFFT++) = value * sin((*indPhi++ -.5)*2*M_PI);
}
else
for(i=0;i<dataLength/2;i++)
{
float value;
value = *(indMod++) = *(indData++) ;
*(indFFT++) = value * cos((*indPhi -.5)*2*M_PI);
*(indFFT++) = value * sin((*indPhi++ -.5)*2*M_PI);
}
FFTData[0] = MODData[0] * cos(phizero);
FFTData[1] = MODData[0] * sin(phizero);
rfft(FFTData,dataLength/2,FALSE);
indFFT = FFTData;
for(i=0,maxValue= -10000.,minValue = 10000. ;i<dataLength;i++)
{
Value = *(indFFT++);
maxValue = MAX(Value,maxValue);
minValue = MIN(Value,minValue);
}
if((minValue<0 || maxValue>1) && minValue - maxValue < 0)
{
maxValue -= minValue;
for(i=0,indFFT = FFTData;i<dataLength;i++,indFFT++)
*(indFFT) = (*(indFFT) - minValue) / maxValue;
}
[waveView setFuncTable:FFTData length:dataLength offset:0];
[waveView draw:self];
[waveView setSound:self];
return self;
}
- setPhi:(float*)data
{
int i;
float *indData, *indFFT, *indMod, *indPhi,maxValue,minValue,Value;
[self storeCurrent:self];
indFFT = FFTData;
indData = data;
indMod = MODData;
indPhi = PHIData;
if(logDisplay)
for(i=0;i<dataLength/2;i++)
{
float value;
*(indPhi++) = *(indData);
value = exp((*(indMod++) - 1) * LOGBOTTOM) ;
if (value - .00101 <= 0) value = 0;
*(indFFT++) = value * cos((*indData - .5)*2*M_PI);
*(indFFT++) = value * sin((*indData++ - .5)*2*M_PI);
}
else
for(i=0;i<dataLength/2;i++)
{
float value;
*(indPhi++) = *(indData);
value = *(indMod++);
*(indFFT++) = value * cos((*indData - .5)*2*M_PI);
*(indFFT++) = value * sin((*indData++ - .5)*2*M_PI);
}
FFTData[0] = MODData[0] * cos(phizero);
FFTData[1] = MODData[0] * sin(phizero);
rfft(FFTData,dataLength/2,FALSE);
indFFT = FFTData;
for(i=0,maxValue= -10000.,minValue = 10000. ;i<dataLength;i++)
{
Value = *(indFFT++);
maxValue = MAX(Value,maxValue);
minValue = MIN(Value,minValue);
}
if((minValue<0 || maxValue>1) && minValue - maxValue < 0)
{
maxValue -= minValue;
for(i=0,indFFT = FFTData;i<dataLength;i++,indFFT++)
*(indFFT) = (*(indFFT) - minValue) / ((maxValue -1 < 0) ? 1 : maxValue);
}
[waveView setFuncTable:FFTData length:dataLength offset:0];
[waveView draw:self];
[waveView setSound:self];
return self;
}
- receiveData:(float*)data length:(int)aLength
{
int i;
float *indData, *indFFT, *indMod, *indPhi,maxValue,Value;
indFFT = FFTData;
indData = data;
indMod = MODData;
indPhi = PHIData;
for(i=0;i<dataLength;i++)
*(indFFT++) = *(indData++);
rfft(FFTData,dataLength/2,TRUE);
indFFT = FFTData;
phizero = atan2(*(indFFT+1),*(indFFT)) ;
for(i=0,maxValue=0;i<dataLength/2;i++,indFFT+=2)
{
Value = *(indMod++) = hypot(*(indFFT),*(indFFT+1));
if(i) maxValue = MAX(Value,maxValue);
}
// for(i=0;i<20;i++)
// fprintf(stderr,"Phase[%d] = %f\n",i*dataLength/20,FFTData[i*dataLength/20]);
indFFT = FFTData;
for(i=0,indMod = MODData;i<dataLength/2;i++,indFFT+=2)
{
float value;
if(maxValue != 0) *(indMod) /= maxValue;
if(*(indMod) - 1e-4 > 0)
*(indPhi++) = .5 + atan2(*(indFFT+1),*(indFFT)) / 2 / M_PI;
else *(indPhi++) = *(indPhi - 1);
if(logDisplay == YES) *(indMod) = log(MAX(*(indMod),.001))/LOGBOTTOM + 1;
indMod ++;
}
[modView setFuncTable:MODData length:(dataLength/2) offset:0];
[phiView setFuncTable:PHIData length:(dataLength/2) offset:0];
[modView draw:self];
[phiView draw:self];
return self;
}
- convolve:sender
{
int i;
float *indData,*indMod,maxvalue;
indData = [convView table];
indMod = MODData;
for(i=0,maxvalue = 0;i<dataLength/2;i++)
{
float value = *(indData++);
maxvalue = MAX(maxvalue,value);
}
indData = [convView table];
if(logDisplay)
for(i=0;i<dataLength/2;i++,indMod++)
{
float value1 = *(indData++);
float value2 = *(indMod);
*(indMod) = MAX(0, value2 + value1 - maxvalue);
}
else
for(i=0;i<dataLength/2;i++)
{
*(indMod++) *= *(indData++);
}
[modView setFuncTable:MODData length:(dataLength/2) offset:0];
[modView draw:self];
[self setMod:MODData];
return self;
}
- setLogDisplay:sender
{
logDisplay = [sender intValue];
[self receiveData:[waveView table] length:[waveView tableLength]];
return self;
}
- multiply:sender
{
int i;
float *indMult,*indWave,*indWavesup;
[self storeCurrent:self];
indMult = [convView table] + dataLength/2 -1;
indWave = [waveView table];
indWavesup = indWave + dataLength -1 ;
for(i=0;i<dataLength/2;i++)
{
*(indWave) = (*(indWave++) - .5) * *(indMult) + .5;
*(indWavesup) = (*(indWavesup--) -.5) * *(indMult--) + .5;
}
[waveView draw:self];
[waveView setSound:sender];
[self receiveData:[waveView table] length:dataLength];
return self;
}
- saveTable:sender
{
int i;
float *storeInd,*indData;
storeInd = storeTable[[[sender selectedCell] tag]];
indData = [waveView table];
for(i=0;i<dataLength;i++)
*(storeInd++) = *(indData++);
return self;
}
- restoreTable:sender
{
int i;
float *storeInd,*indData;
[self storeCurrent:self];
storeInd = storeTable[[[sender selectedCell] tag]];
[waveView setFuncTable:storeInd length:dataLength offset:0];
[waveView draw:self];
[waveView setSound:sender];
[self receiveData:storeInd length:dataLength];
return self;
}
-storeCurrent:sender
{
float *indData, *indSwap;
int i;
indData = [waveView table];
indSwap = swap[currentBuffer];
for(i=0;i<dataLength;i++)
*(indSwap++) = *(indData++);
return self;
}
-previous:sender
{
currentBuffer = 1 - currentBuffer;
[self storeCurrent:self];
[waveView setFuncTable:swap[1-currentBuffer] length:dataLength offset:0];
[waveView draw:self];
[waveView setSound:sender];
[self receiveData:swap[1-currentBuffer] length:dataLength];
return self;
}
@end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.