void ofxFFT::calc() { //Generate a split complex vector from the real data vDSP_ctoz((COMPLEX *)input, 2, &mDspSplitComplex, 1, mFFTLength); //Take the fft and scale appropriately vDSP_fft_zrip(mSpectrumAnalysis, &mDspSplitComplex, 1, log2n, FFT_FORWARD); // vDSP_fft_zrip(mSpectrumAnalysis, &mDspSplitComplex, 1, log2n, FFT_INVERSE); vDSP_vsmul(mDspSplitComplex.realp, 1, &mFFTNormFactor, mDspSplitComplex.realp, 1, mFFTLength); vDSP_vsmul(mDspSplitComplex.imagp, 1, &mFFTNormFactor, mDspSplitComplex.imagp, 1, mFFTLength); // /* The output signal is now in a split real form. Use the function // * vDSP_ztoc to get a split real vector. */ // vDSP_ztoc(&mDspSplitComplex, 1, (COMPLEX *) output, 2, mFFTLength); // //Zero out the nyquist value mDspSplitComplex.imagp[0] = 0.0; //Convert the fft data to dB vDSP_zvmags(&mDspSplitComplex, 1, amplitude, 1, mFFTLength); //In order to avoid taking log10 of zero, an adjusting factor is added in to make the minimum value equal -128dB float mAdjust0DB = ADJUST_0_DB; vDSP_vsadd(amplitude, 1, &mAdjust0DB, power, 1, mFFTLength); float one = 1; vDSP_vdbcon(power, 1, &one, power, 1, mFFTLength, 0); }
/******************************************************************************* VectorScalarAdd */ Error_t VectorScalarAdd(float *dest, const float *in1, const float scalar, unsigned length) { #ifdef __APPLE__ // Use the Accelerate framework if we have it vDSP_vsadd(in1, 1, &scalar, dest, 1, length); #else // Otherwise do it manually unsigned i; const unsigned end = 4 * (length / 4); for (i = 0; i < end; i+=4) { dest[i] = in1[i] + scalar; dest[i + 1] = in1[i + 1] + scalar; dest[i + 2] = in1[i + 2] + scalar; dest[i + 3] = in1[i + 3] + scalar; } for (i = end; i < length; ++i) { dest[i] = in1[i] + scalar; } #endif return NOERR; }
void CsoundObject_writePVSReadPath(CsoundObject *self, size_t *segmentStartFrames, size_t triangleFilterBandsCount, Matrix32 *warpPaths) { Float32 frameLengthInSeconds = 1./44100. * 256.; for (size_t i = 0; i < triangleFilterBandsCount; ++i) { Float32 startFrameInSeconds = (Float32)segmentStartFrames[i] * frameLengthInSeconds; Float32 *tablePointer; csoundGetTable(self->csound, &tablePointer, (SInt32)(warpPathTableBaseNumber + i)); vDSP_vsadd(Matrix_getRow(warpPaths, i), 1, &startFrameInSeconds, tablePointer, 1, self->analysisSegmentFramesCount); } }
void FFTHelper::ComputeFFT(Float32* inAudioData, Float32* outFFTData) { if (inAudioData == NULL || outFFTData == NULL) return; //Generate a split complex vector from the real data vDSP_ctoz((COMPLEX *)inAudioData, 2, &mDspSplitComplex, 1, mFFTLength); //Take the fft and scale appropriately vDSP_fft_zrip(mSpectrumAnalysis, &mDspSplitComplex, 1, mLog2N, kFFTDirection_Forward); vDSP_vsmul(mDspSplitComplex.realp, 1, &mFFTNormFactor, mDspSplitComplex.realp, 1, mFFTLength); vDSP_vsmul(mDspSplitComplex.imagp, 1, &mFFTNormFactor, mDspSplitComplex.imagp, 1, mFFTLength); //Zero out the nyquist value mDspSplitComplex.imagp[0] = 0.0; //Convert the fft data to dB vDSP_zvmags(&mDspSplitComplex, 1, outFFTData, 1, mFFTLength); //In order to avoid taking log10 of zero, an adjusting factor is added in to make the minimum value equal -128dB vDSP_vsadd(outFFTData, 1, &kAdjust0DB, outFFTData, 1, mFFTLength); Float32 one = 1; vDSP_vdbcon(outFFTData, 1, &one, outFFTData, 1, mFFTLength, 0); Float32 max = -100; int index = -1; for(unsigned long i = 0; i < mFFTLength; i++){ if(outFFTData[i] > max){ max = outFFTData[i]; index = i; } } if(max > -40){ // Filter out anything else, as it is unlikely to be the microwave beep recentMaxIndex = index; //if(index == 181){ // We found the microwave beep //printf("%d %f\n", index, max); }else{ recentMaxIndex = 0; } }
void FFTHelper::ComputeFFT(Float32* inAudioData, Float32* outFFTData) { if (inAudioData == NULL || outFFTData == NULL) return; //Generate a split complex vector from the real data vDSP_ctoz((COMPLEX *)inAudioData, 2, &mDspSplitComplex, 1, mFFTLength); //Take the fft and scale appropriately vDSP_fft_zrip(mSpectrumAnalysis, &mDspSplitComplex, 1, mLog2N, kFFTDirection_Forward); vDSP_vsmul(mDspSplitComplex.realp, 1, &mFFTNormFactor, mDspSplitComplex.realp, 1, mFFTLength); vDSP_vsmul(mDspSplitComplex.imagp, 1, &mFFTNormFactor, mDspSplitComplex.imagp, 1, mFFTLength); //Zero out the nyquist value mDspSplitComplex.imagp[0] = 0.0; //Convert the fft data to dB vDSP_zvmags(&mDspSplitComplex, 1, outFFTData, 1, mFFTLength); //In order to avoid taking log10 of zero, an adjusting factor is added in to make the minimum value equal -128dB vDSP_vsadd(outFFTData, 1, &kAdjust0DB, outFFTData, 1, mFFTLength); Float32 one = 1; vDSP_vdbcon(outFFTData, 1, &one, outFFTData, 1, mFFTLength, 0); }
void DspTableRead4::processDspWithIndex(int fromIndex, int toIndex) { if (table != NULL) { // ensure that there is a table to read from! int bufferLength; float *buffer = table->getBuffer(&bufferLength); if (ArrayArithmetic::hasAccelerate) { #if __APPLE__ //float zero = 0.0f; //float bufferLengthFloat = (float) (bufferLength-2); //vDSP_vclip(inputBuffer+startSampleIndex, 1, &zero, &bufferLengthFloat, // inputBuffer+startSampleIndex, 1, endSampleIndex-startSampleIndex); // NOTE(mhroth): is isn't clear what the clipping behaviour of vDSP_vlint is, but I // *think* that it is doing the right thing (i.e., clipping OOB indicies) vDSP_vsadd(dspBufferAtInlet0+fromIndex, 1, &offset, dspBufferAtOutlet0+fromIndex, 1, toIndex-fromIndex); vDSP_vlint(buffer, dspBufferAtInlet0+fromIndex, 1, dspBufferAtOutlet0+fromIndex, 1, toIndex-fromIndex, bufferLength); #endif } else { int maxIndex = bufferLength-1; for (int i = fromIndex; i < toIndex; i++) { int x = (int) (dspBufferAtInlet0[i] + offset); if (x <= 0) { dspBufferAtOutlet0[i] = buffer[0]; } else if (x >= maxIndex) { dspBufferAtOutlet0[i] = buffer[maxIndex]; } else { // 2-point linear interpolation (basic and fast) float dx = dspBufferAtInlet0[i] - ((float) x); float y0 = buffer[x]; float y1 = buffer[x+1]; float slope = (y1 - y0); dspBufferAtOutlet0[i] = (slope * dx) + y0; } } } } }
void sub( const float *array, float scalar, float *result, size_t length ) { scalar *= -1; vDSP_vsadd( const_cast<float *>( array ), 1, &scalar, result, 1, length ); }
TriangleFilterBank32 *TriangleFilterBank32_new(size_t filterCount, size_t magnitudeFrameSize, size_t samplerate) { TriangleFilterBank32 *self = calloc(1, sizeof(TriangleFilterBank32)); self->filterCount = filterCount; self->filterFrequencyCount = filterCount + 2; self->magnitudeFrameSize = magnitudeFrameSize; self->samplerate = samplerate; self->filterFrequencies = calloc(self->filterFrequencyCount, sizeof(Float32)); self->filterBank = calloc(self->magnitudeFrameSize * self->filterCount, sizeof(Float32)); Float32 *filterTemp = calloc(self->magnitudeFrameSize * self->filterCount, sizeof(Float32)); Float32 one = 2; Float32 zero = 0; vDSP_vgen(&zero, &one, self->filterFrequencies, 1, self->filterFrequencyCount); for (size_t i = 0; i < self->filterFrequencyCount; ++i) { self->filterFrequencies[i] = powf(10, self->filterFrequencies[i]); } Float32 minusFirstElement = -self->filterFrequencies[0]; vDSP_vsadd(self->filterFrequencies, 1, &minusFirstElement, self->filterFrequencies, 1, self->filterFrequencyCount); Float32 maximum = self->filterFrequencies[self->filterFrequencyCount - 1]; vDSP_vsdiv(self->filterFrequencies, 1, &maximum, self->filterFrequencies, 1, self->filterFrequencyCount); Float32 nyquist = self->samplerate / 2; vDSP_vsmul(self->filterFrequencies, 1, &nyquist, self->filterFrequencies, 1, self->filterFrequencyCount); Float32 *magnitudeFrequencies = calloc(self->magnitudeFrameSize, sizeof(Float32)); vDSP_vgen(&zero, &nyquist, magnitudeFrequencies, 1, self->magnitudeFrameSize); Float32 *lower = calloc(self->filterCount, sizeof(Float32)); Float32 *center = calloc(self->filterCount, sizeof(Float32)); Float32 *upper = calloc(self->filterCount, sizeof(Float32)); Float32 *temp1 = (Float32 *)calloc(self->magnitudeFrameSize, sizeof(Float32)); Float32 *temp2 = (Float32 *)calloc(self->magnitudeFrameSize, sizeof(Float32)); cblas_scopy((SInt32)self->filterCount, &self->filterFrequencies[0], 1, lower, 1); cblas_scopy((SInt32)self->filterCount, &self->filterFrequencies[1], 1, center, 1); cblas_scopy((SInt32)self->filterCount, &self->filterFrequencies[2], 1, upper, 1); for (size_t i = 0; i < self->filterCount; ++i) { Float32 negateLowerValue = -lower[i]; vDSP_vsadd(magnitudeFrequencies, 1, &negateLowerValue, temp1, 1, self->magnitudeFrameSize); Float32 divider = center[i] - lower[i]; vDSP_vsdiv(temp1, 1, ÷r, temp1, 1, self->magnitudeFrameSize); for (size_t j = 0; j < self->magnitudeFrameSize; ++j) { if (!(magnitudeFrequencies[j] > lower[i] && magnitudeFrequencies[j] <= center[i])) { temp1[j] = 0; } } Float32 minusOne = -1; vDSP_vsmul(magnitudeFrequencies, 1, &minusOne, temp2, 1, self->magnitudeFrameSize); vDSP_vsadd(temp2, 1, &upper[i], temp2, 1, self->magnitudeFrameSize); divider = upper[i] - center[i]; vDSP_vsdiv(temp2, 1, ÷r, temp2, 1, self->magnitudeFrameSize); for (size_t j = 0; j < self->magnitudeFrameSize; ++j) { if (!(magnitudeFrequencies[j] > center[i] && magnitudeFrequencies[j] <= upper[i])) { temp2[j] = 0; } } vDSP_vadd(temp1, 1, temp2, 1, &filterTemp[i * self->magnitudeFrameSize], 1, self->magnitudeFrameSize); } vDSP_mtrans(filterTemp, 1, self->filterBank, 1, self->magnitudeFrameSize, self->filterCount); free(lower); free(center); free(upper); free(temp1); free(temp2); free(magnitudeFrequencies); free(filterTemp); return self; }
Boolean FFTBufferManager::ComputeFFT(int32_t *outFFTData) { if (HasNewAudioData()) { // for(int i=0;i<mFFTLength;i++) // { // if(mAudioBuffer[i]>0.15) // printf("%f\n",mAudioBuffer[i]); // } //Generate a split complex vector from the real data # define NOISE_FILTER 0.01; for(int i=0;i<4096;i++) { //DENOISE if(mAudioBuffer[i]>0) { mAudioBuffer[i] -= NOISE_FILTER; if(mAudioBuffer[i] < 0) { mAudioBuffer[i] = 0; } } else if(mAudioBuffer[i]<0) { mAudioBuffer[i] += NOISE_FILTER; if(mAudioBuffer[i]>0) { mAudioBuffer[i] = 0; } } else { mAudioBuffer[i] = 0; } } vDSP_ctoz((COMPLEX *)mAudioBuffer, 2, &mDspSplitComplex, 1, mFFTLength); //Take the fft and scale appropriately vDSP_fft_zrip(mSpectrumAnalysis, &mDspSplitComplex, 1, mLog2N, kFFTDirection_Forward); vDSP_vsmul(mDspSplitComplex.realp, 1, &mFFTNormFactor, mDspSplitComplex.realp, 1, mFFTLength); vDSP_vsmul(mDspSplitComplex.imagp, 1, &mFFTNormFactor, mDspSplitComplex.imagp, 1, mFFTLength); //Zero out the nyquist value mDspSplitComplex.imagp[0] = 0.0; //Convert the fft data to dB Float32 tmpData[mFFTLength]; vDSP_zvmags(&mDspSplitComplex, 1, tmpData, 1, mFFTLength); //In order to avoid taking log10 of zero, an adjusting factor is added in to make the minimum value equal -128dB vDSP_vsadd(tmpData, 1, &mAdjust0DB, tmpData, 1, mFFTLength); Float32 one = 1; vDSP_vdbcon(tmpData, 1, &one, tmpData, 1, mFFTLength, 0); //Convert floating point data to integer (Q7.24) vDSP_vsmul(tmpData, 1, &m24BitFracScale, tmpData, 1, mFFTLength); for(UInt32 i=0; i<mFFTLength; ++i) outFFTData[i] = (SInt32) tmpData[i]; for(int i=0;i<mFFTLength/4;i++) { printf("%i:::%i\n",i,outFFTData[i]/16777216+120); } OSAtomicDecrement32Barrier(&mHasAudioData); OSAtomicIncrement32Barrier(&mNeedsAudioData); mAudioBufferCurrentIndex = 0; return true; } else if (mNeedsAudioData == 0) OSAtomicIncrement32Barrier(&mNeedsAudioData); return false; }
bool ofxAudioUnitFftNode::getAmplitude(std::vector<float> &outAmplitude) { getSamplesFromChannel(_sampleBuffer, 0); // return empty if we don't have enough samples yet if(_sampleBuffer.size() < _N) { outAmplitude.clear(); return false; } // normalize input waveform if(_outputSettings.normalizeInput) { float timeDomainMax; vDSP_maxv(&_sampleBuffer[0], 1, &timeDomainMax, _N); vDSP_vsdiv(&_sampleBuffer[0], 1, &timeDomainMax, &_sampleBuffer[0], 1, _N); } PerformFFT(&_sampleBuffer[0], _window, _fftData, _fftSetup, _N); // get amplitude vDSP_zvmags(&_fftData, 1, _fftData.realp, 1, _N/2); // normalize magnitudes float two = 2.0; vDSP_vsdiv(_fftData.realp, 1, &two, _fftData.realp, 1, _N/2); // scale output according to requested settings if(_outputSettings.scale == OFXAU_SCALE_LOG10) { for(int i = 0; i < (_N / 2); i++) { _fftData.realp[i] = log10f(_fftData.realp[i] + 1); } } else if(_outputSettings.scale == OFXAU_SCALE_DECIBEL) { float ref = 1.0; vDSP_vdbcon(_fftData.realp, 1, &ref, _fftData.realp, 1, _N / 2, 1); float dbCorrectionFactor = 0; switch (_outputSettings.window) { case OFXAU_WINDOW_HAMMING: dbCorrectionFactor = DB_CORRECTION_HAMMING; break; case OFXAU_WINDOW_HANNING: dbCorrectionFactor = DB_CORRECTION_HAMMING; break; case OFXAU_WINDOW_BLACKMAN: dbCorrectionFactor = DB_CORRECTION_HAMMING; break; } vDSP_vsadd(_fftData.realp, 1, &dbCorrectionFactor, _fftData.realp, 1, _N / 2); } // restrict minimum to 0 if(_outputSettings.clampMinToZero) { float min = 0.0; float max = INFINITY; vDSP_vclip(_fftData.realp, 1, &min, &max, _fftData.realp, 1, _N / 2); } // normalize output between 0 and 1 if(_outputSettings.normalizeOutput) { float max; vDSP_maxv(_fftData.realp, 1, &max, _N / 2); if(max > 0) { vDSP_vsdiv(_fftData.realp, 1, &max, _fftData.realp, 1, _N / 2); } } outAmplitude.assign(_fftData.realp, _fftData.realp + _N/2); return true; }