12 #include <Accelerate/Accelerate.h>
15 #import <Foundation/Foundation.h>
23 "Accelerate.framework"
34 DSPSplitComplex _split;
36 unsigned int _frameSize;
42 - (
VuoReal *) frequenciesForSampleData:(
float *) sampleData numFrames:(
int)frames mode:(
VuoAudioBinAverageType)frequencyMode outputCount:(
unsigned int *)count newSumming:(
bool)newSumming;
43 - (id) initWithSize:(
unsigned int)frameSize windowing:(
VuoWindowing)windowMode;
52 - (id) initWithSize:(
unsigned int)frameSize windowing:(
VuoWindowing)windowMode
54 if (
self = [super init])
57 _fftSetup = vDSP_create_fftsetup( log2f(frameSize), kFFTRadix2 );
62 _frequency = (
float*)calloc(
sizeof(
float)*frameSize * 2, 1);
63 _split.realp = _frequency + frameSize;
64 _split.imagp = _split.realp + frameSize / 2;
65 _frameSize = frameSize;
73 case VuoWindowing_Hamming:
74 _window = (
float *) malloc(
sizeof(
float) * frameSize);
75 vDSP_hamm_window(_window, frameSize, 0);
78 case VuoWindowing_Hann:
79 _window = (
float *) malloc(
sizeof(
float) * frameSize);
80 vDSP_hann_window(_window, frameSize, 0);
83 case VuoWindowing_Blackman:
84 _window = (
float *) malloc(
sizeof(
float) * frameSize);
85 vDSP_blkman_window(_window, frameSize, 0);
97 static void VuoDsp_showFrequencies(
int frameCount,
VuoAudioBinAverageType mode,
int lowBin,
int highBin,
int displayBin)
100 double width = nyquist / (frameCount/2);
102 double lowFrequency = ( lowBin - .5) * width;
103 double highFrequency = (highBin + .5) * width;
104 double centerFrequency = (((double)lowBin + highBin) / 2.) * width;
106 VUserLog(
"Bin %4d %8.2f Hz ± %7.2f Hz (%8.2f Hz to %8.2f Hz)", displayBin, centerFrequency, (highFrequency - lowFrequency) / 2., lowFrequency, highFrequency);
112 - (
VuoReal *)frequenciesForSampleData:(
float *)sampleData numFrames:(
int)frames mode:(
VuoAudioBinAverageType)frequencyMode outputCount:(
unsigned int *)count newSumming:(
bool)newSumming
114 bool showTable =
false;
127 vDSP_vmul(sampleData, 1, _window, 1, sampleData, 1, frames);
130 unsigned int offset = 0;
132 DSPSplitComplex lSplit = _split;
134 for( i=0; i < frames/2; ++i)
136 lSplit.realp[i] = sampleData[offset];
138 lSplit.imagp[i] = sampleData[offset];
143 vDSP_fft_zrip( _fftSetup, &lSplit, 1, log2f(_frameSize), kFFTDirection_Forward );
146 if(_window == NULL || newSumming)
149 const float scale = 1.0f/frames;
151 vDSP_vsmul( lSplit.realp, 1, &scale, lSplit.realp, 1, frames/2 );
152 vDSP_vsmul( lSplit.imagp, 1, &scale, lSplit.imagp, 1, frames/2 );
159 float *lFrequency = _frequency;
160 vDSP_zvabs( &lSplit, 1, lFrequency, 1, frames/2 );
162 switch(frequencyMode)
167 for( i=1; i<frames/2; ++i )
168 freqChannel[i-1] = lFrequency[i];
170 for( i=1; i<frames/2; ++i )
171 freqChannel[i-1] = lFrequency[i] * ((float)sqrtf(i)*2.f + 1.f);
172 *count = frames/2 - 1;
175 for (i = 1; i < frames/2; ++i)
176 VuoDsp_showFrequencies(frames, frequencyMode, i, i, i);
180 case VuoAudioBinAverageType_Quadratic:
182 int lowerFrequency = 1, upperFrequency;
189 upperFrequency = lowerFrequency + i;
191 if( upperFrequency >= frames/2 )
193 upperFrequency = frames/2-1;
196 for( k=lowerFrequency; k<=upperFrequency; ++k )
197 sum += lFrequency[k];
198 sum /= (float)(upperFrequency-lowerFrequency+1);
199 sum *= (float)i*2.f + 1.f;
200 freqChannel[i] = sum;
203 VuoDsp_showFrequencies(frames, frequencyMode, lowerFrequency, upperFrequency, i + 1);
205 lowerFrequency = upperFrequency + 1;
211 case VuoAudioBinAverageType_Logarithmic:
213 const float log2FrameSize = log2f(_frameSize);
214 int numBuckets = log2FrameSize;
215 int lowerFrequency, upperFrequency;
218 for( i=0; i<numBuckets; ++i)
220 lowerFrequency = (frames/2) / powf(2.f,log2FrameSize-i )+1;
221 upperFrequency = (frames/2) / powf(2.f,log2FrameSize-i-1);
223 if(upperFrequency>=frames/2)
224 upperFrequency=frames/2-1;
225 for( k=lowerFrequency; k<=upperFrequency; ++k )
226 sum += lFrequency[k];
227 sum /= (float)(upperFrequency-lowerFrequency+1);
228 sum *= (float)powf(i,1.5f) + 1.f;
229 freqChannel[i] = sum;
232 VuoDsp_showFrequencies(frames, frequencyMode, lowerFrequency, upperFrequency, i + 1);
247 vDSP_destroy_fftsetup(_fftSetup);
280 float* vals = (
float*)malloc(
sizeof(
float)*sampleCount);
281 for(
int i = 0; i < sampleCount; i++) vals[i] = (
float)audio[i];