12 #include <Accelerate/Accelerate.h>
14 #ifndef NS_RETURNS_INNER_POINTER
15 #define NS_RETURNS_INNER_POINTER
17 #import <Cocoa/Cocoa.h>
18 #undef NS_RETURNS_INNER_POINTER
26 "Accelerate.framework"
45 - (
VuoReal *) frequenciesForSampleData:(
float *) sampleData numFrames:(
int)frames mode:(
VuoAudioBinAverageType)frequencyMode outputCount:(
unsigned int *)count newSumming:(
bool)newSumming;
46 - (id) initWithSize:(
unsigned int)frameSize windowing:(
VuoWindowing)windowMode;
55 - (id) initWithSize:(
unsigned int)frameSize windowing:(
VuoWindowing)windowMode
57 if (
self = [super init])
60 _fftSetup = vDSP_create_fftsetup( log2f(frameSize), kFFTRadix2 );
65 _frequency = (
float*)calloc(
sizeof(
float)*frameSize * 2, 1);
76 case VuoWindowing_Hamming:
77 _window = (
float *) malloc(
sizeof(
float) * frameSize);
78 vDSP_hamm_window(
_window, frameSize, 0);
81 case VuoWindowing_Hann:
82 _window = (
float *) malloc(
sizeof(
float) * frameSize);
83 vDSP_hann_window(
_window, frameSize, 0);
86 case VuoWindowing_Blackman:
87 _window = (
float *) malloc(
sizeof(
float) * frameSize);
88 vDSP_blkman_window(
_window, frameSize, 0);
100 static void VuoDsp_showFrequencies(
int frameCount,
VuoAudioBinAverageType mode,
int lowBin,
int highBin,
int displayBin)
103 double width = nyquist / (frameCount/2);
105 double lowFrequency = ( lowBin - .5) * width;
106 double highFrequency = (highBin + .5) * width;
107 double centerFrequency = (((double)lowBin + highBin) / 2.) * width;
109 VUserLog(
"Bin %4d %8.2f Hz ± %7.2f Hz (%8.2f Hz to %8.2f Hz)", displayBin, centerFrequency, (highFrequency - lowFrequency) / 2., lowFrequency, highFrequency);
115 - (
VuoReal *)frequenciesForSampleData:(
float *)sampleData numFrames:(
int)frames mode:(
VuoAudioBinAverageType)frequencyMode outputCount:(
unsigned int *)count newSumming:(
bool)newSumming
117 bool showTable =
false;
130 vDSP_vmul(sampleData, 1,
_window, 1, sampleData, 1, frames);
133 unsigned int offset = 0;
135 DSPSplitComplex lSplit =
_split;
137 for( i=0; i < frames/2; ++i)
139 lSplit.realp[i] = sampleData[offset];
141 lSplit.imagp[i] = sampleData[offset];
149 if(
_window == NULL || newSumming)
152 const float scale = 1.0f/frames;
154 vDSP_vsmul( lSplit.realp, 1, &scale, lSplit.realp, 1, frames/2 );
155 vDSP_vsmul( lSplit.imagp, 1, &scale, lSplit.imagp, 1, frames/2 );
163 vDSP_zvabs( &lSplit, 1, lFrequency, 1, frames/2 );
165 switch(frequencyMode)
170 for( i=1; i<frames/2; ++i )
171 freqChannel[i-1] = lFrequency[i];
173 for( i=1; i<frames/2; ++i )
174 freqChannel[i-1] = lFrequency[i] * ((
float)sqrtf(i)*2.f + 1.f);
175 *count = frames/2 - 1;
178 for (i = 1; i < frames/2; ++i)
179 VuoDsp_showFrequencies(frames, frequencyMode, i, i, i);
183 case VuoAudioBinAverageType_Quadratic:
185 int lowerFrequency = 1, upperFrequency;
192 upperFrequency = lowerFrequency + i;
194 if( upperFrequency >= frames/2 )
196 upperFrequency = frames/2-1;
199 for( k=lowerFrequency; k<=upperFrequency; ++k )
200 sum += lFrequency[k];
201 sum /= (float)(upperFrequency-lowerFrequency+1);
202 sum *= (float)i*2.f + 1.f;
203 freqChannel[i] = sum;
206 VuoDsp_showFrequencies(frames, frequencyMode, lowerFrequency, upperFrequency, i + 1);
208 lowerFrequency = upperFrequency + 1;
214 case VuoAudioBinAverageType_Logarithmic:
216 const float log2FrameSize = log2f(
_frameSize);
217 int numBuckets = log2FrameSize;
218 int lowerFrequency, upperFrequency;
221 for( i=0; i<numBuckets; ++i)
223 lowerFrequency = (frames/2) / powf(2.f,log2FrameSize-i )+1;
224 upperFrequency = (frames/2) / powf(2.f,log2FrameSize-i-1);
226 if(upperFrequency>=frames/2)
227 upperFrequency=frames/2-1;
228 for( k=lowerFrequency; k<=upperFrequency; ++k )
229 sum += lFrequency[k];
230 sum /= (float)(upperFrequency-lowerFrequency+1);
231 sum *= (float)powf(i,1.5f) + 1.f;
232 freqChannel[i] = sum;
235 VuoDsp_showFrequencies(frames, frequencyMode, lowerFrequency, upperFrequency, i + 1);
282 float* vals = (
float*)malloc(
sizeof(
float)*sampleCount);
283 for(
int i = 0; i < sampleCount; i++) vals[i] = (
float)audio[i];