FMOD_RESULT bmx_FMOD_System_GetSpectrum(FMOD_SYSTEM *system, BBArray * spectrumArray, int channelOffset, FMOD_DSP_FFT_WINDOW windowType) { int size = spectrumArray->scales[0]; float arr[size]; FMOD_RESULT res = FMOD_System_GetSpectrum(system, &arr[0], size, channelOffset, windowType); float *s=(float*)BBARRAYDATA( spectrumArray, spectrumArray->dims ); for (int i = 0; i < size; i ++) { s[i] = arr[i]; } return res; }
// ---------------------------------------------------------------------------- float * ofxSoundGetSpectrum(int nBands) { ofxSoundInitialize(); // set to 0 for (int i = 0; i < 8192; i++){ fftInterpValues[i] = 0; } // check what the user wants vs. what we can do: if (nBands > 8192){ ofLog(OF_LOG_ERROR, "error in ofxSoundGetSpectrum, the maximum number of bands is 8192 - you asked for %i we will return 8192", nBands); nBands = 8192; } else if (nBands <= 0){ ofLog(OF_LOG_ERROR, "error in ofxSoundSpectrum, you've asked for %i bands, minimum is 1", nBands); return fftInterpValues; } // FMOD needs pow2 int nBandsToGet = ofNextPow2(nBands); if (nBandsToGet < 64) nBandsToGet = 64; // can't seem to get fft of 32, etc from fmodex // get the fft FMOD_System_GetSpectrum(sys, fftSpectrum, nBandsToGet, 0, FMOD_DSP_FFT_WINDOW_HANNING); // convert to db scale for(int i = 0; i < nBandsToGet; i++){ fftValues[i] = 10.0f * (float)log10(1 + fftSpectrum[i]) * 2.0f; } // try to put all of the values (nBandsToGet) into (nBands) // in a way which is accurate and preserves the data: // if (nBandsToGet == nBands){ for(int i = 0; i < nBandsToGet; i++){ fftInterpValues[i] = fftValues[i]; } } else { float step = (float)nBandsToGet / (float)nBands; //float pos = 0; // so for example, if nBands = 33, nBandsToGet = 64, step = 1.93f; int currentBand = 0; for(int i = 0; i < nBandsToGet; i++){ // if I am current band = 0, I care about (0+1) * step, my end pos // if i > endPos, then split i with me and my neighbor if (i >= ((currentBand+1)*step)){ // do some fractional thing here... float fraction = ((currentBand+1)*step) - (i-1); float one_m_fraction = 1 - fraction; fftInterpValues[currentBand] += fraction * fftValues[i]; currentBand++; // safety check: if (currentBand >= nBands){ ofLog(OF_LOG_ERROR, "ofxSoundGetSpectrum - currentBand >= nBands"); } fftInterpValues[currentBand] += one_m_fraction * fftValues[i]; } else { // do normal things fftInterpValues[currentBand] += fftValues[i]; } } // because we added "step" amount per band, divide to get the mean: for (int i = 0; i < nBands; i++){ fftInterpValues[i] /= step; if (fftInterpValues[i] > 1)fftInterpValues[i] = 1; // this seems "wrong" } } return fftInterpValues; }