// ---------------------------------------------------------------------------- float * ofOpenALSoundPlayer::getSystemSpectrum(int bands){ initSystemFFT(bands); systemBins.assign(systemBins.size(),0); if(players.empty()) return &systemBins[0]; int signalSize = (bands-1)*2; if(int(systemWindowedSignal.size())!=signalSize){ systemWindowedSignal.resize(signalSize); } systemWindowedSignal.assign(systemWindowedSignal.size(),0); set<ofOpenALSoundPlayer*>::iterator it; for(it=players.begin();it!=players.end();it++){ if(!(*it)->getIsPlaying()) continue; float * buffer = (*it)->getCurrentBufferSum(signalSize); for(int i=0;i<signalSize;i++){ systemWindowedSignal[i]+=buffer[i]; } } float normalizer = 2. / windowSum; runWindow(systemWindowedSignal); kiss_fftr(systemFftCfg, &systemWindowedSignal[0], &systemCx_out[0]); for(int i= 0; i < bands; i++) { systemBins[i] += sqrtf(systemCx_out[i].r * systemCx_out[i].r + systemCx_out[i].i * systemCx_out[i].i) * normalizer; } return &systemBins[0]; }
void ofxFftBasic::fft(float *input, float *output) { int Half = bins/2; if(!ready) { ofLog(OF_LOG_ERROR, "setup() must be called before fft()\n"); return; } /* processing variables*/ float *in_real = new float[bins]; float *in_img = new float[bins]; float *out_real = new float[bins]; float *out_img = new float[bins]; for (int i = 0; i < bins; i++) { in_real[i] = input[i]; } runWindow(in_real); RealFFT(bins, in_real, out_real, out_img); float normalizer = 2. / windowSum; for(int i = 1; i < Half; i++) { output[i] = cartesianToAmplitude(out_real[i], out_img[i]) * normalizer; } delete [] in_real; delete [] in_img; delete [] out_real; delete [] out_img; }
void ofxFftw::executeFft() { memcpy(fftIn, signal, sizeof(float) * signalSize); runWindow(fftIn); fftwf_execute(fftPlan); // explanation of halfcomplex format: // http://www.fftw.org/fftw3_doc/The-Halfcomplex_002dformat-DFT.html copyReal(fftOut); imag[0] = 0; for (int i = 1; i < binSize; i++) imag[i] = fftOut[signalSize - i]; cartesianUpdated = true; }
// ---------------------------------------------------------------------------- float * ofOpenALSoundPlayer::getSpectrum(int bands){ initFFT(bands); bins.assign(bins.size(),0); if(sources.empty()) return &bins[0]; int signalSize = (bands-1)*2; getCurrentBufferSum(signalSize); float normalizer = 2. / windowSum; runWindow(windowedSignal); kiss_fftr(fftCfg, &windowedSignal[0], &cx_out[0]); for(int i= 0; i < bands; i++) { bins[i] += sqrtf(cx_out[i].r * cx_out[i].r + cx_out[i].i * cx_out[i].i) * normalizer; } return &bins[0]; }
float* ofxFftw::fft(float* input, fftMode mode) { memcpy(fftIn, input, sizeof(float) * signalSize); runWindow(fftIn); fftwf_execute(fftPlan); // explanation of halfcomplex format: // http://www.fftw.org/fftw3_doc/The-Halfcomplex_002dformat-DFT.html setReal(fftOut); // will only copy the first half imag[0] = 0; for(int i = 1; i < bins; i++) imag[i] = fftOut[signalSize - i]; cartesianReady = true; polarReady = false; if(mode == OF_FFT_CARTESIAN) return getReal(); else if(mode == OF_FFT_POLAR) return getAmplitude(); }
/* Calculate the power spectrum */ void ofxFftBasic::powerSpectrum(int start, int half, float *data, int bins,float *magnitude,float *phase, float *power, float *avg_power) { if(!ready) { ofLog(OF_LOG_ERROR, "setup() must be called first!\n"); return; } int i; float total_power = 0.0f; /* processing variables*/ float *in_real = new float[bins]; float *in_img = new float[bins]; float *out_real = new float[bins]; float *out_img = new float[bins]; for (i = 0; i < bins; i++) { in_real[i] = data[start + i]; } runWindow(in_real); RealFFT(bins, in_real, out_real, out_img); for (i = 0; i < half; i++) { /* compute power */ power[i] = out_real[i]*out_real[i] + out_img[i]*out_img[i]; total_power += power[i]; /* compute magnitude and phase */ magnitude[i] = 2.0*sqrt(power[i]); phase[i] = atan2(out_img[i],out_real[i]); } /* calculate average power */ *(avg_power) = total_power / (float) half; delete[]in_real; delete[]in_img; delete[]out_real; delete[]out_img; }
void ofxFftBasic::inversePowerSpectrum(int start, int half, int bins, float *output,float *magnitude,float *phase) { if(!ready) { ofLog(OF_LOG_ERROR, "setup() must be called first!\n"); return; } /* processing variables*/ float *in_real = new float[bins]; float *in_img = new float[bins]; float *out_real = new float[bins]; float *out_img = new float[bins]; /* get real and imag part */ for (int i = 0; i < half; i++) { in_real[i] = magnitude[i]*cos(phase[i]); in_img[i] = magnitude[i]*sin(phase[i]); } /* zero negative frequencies */ for (int i = half; i < bins; i++) { in_real[i] = 0.0; in_img[i] = 0.0; } FFT(bins, 1, in_real, in_img, out_real, out_img); // second parameter indicates inverse transform runWindow(out_real); for (int i = 0; i < bins; i++) { output[start + i] += out_real[i]; } delete[]in_real; delete[]in_img; delete[]out_real; delete[]out_img; }
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,PSTR szCmdLine,int iCmdShow) { HWND hWnd; MSG msg; WNDCLASS wndClass; wndClass.style=CS_HREDRAW|CS_VREDRAW; wndClass.lpfnWndProc=WndProc; wndClass.cbClsExtra=0; wndClass.cbWndExtra=0; wndClass.hInstance=hInstance; wndClass.hIcon=LoadIcon(NULL,IDI_APPLICATION); wndClass.hCursor=LoadCursor(NULL,IDC_ARROW); wndClass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH); wndClass.lpszMenuName=NULL; wndClass.lpszClassName=szName; if(!RegisterClass(&wndClass)) { MessageBox(NULL,TEXT("Can not create!"),szName,MB_ICONERROR); return 0; } hWnd=CreateWindow(szName,TEXT("Soft Render"),WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,CW_USEDEFAULT,SCREEN_WIDTH,SCREEN_HEIGHT, NULL,NULL,hInstance,NULL); hdc=GetDC(hWnd); checkDisplayMode(hdc); createPalette(hdc); dibDC=CreateCompatibleDC(hdc); swidth=SCREEN_WIDTH; sheight=SCREEN_HEIGHT; init(); ShowWindow(hWnd,iCmdShow); UpdateWindow(hWnd); willExit=false; memset(&msg,0,sizeof(MSG)); if(hPalette) { SelectPalette(hdc,hPalette,FALSE); RealizePalette(hdc); } while(!willExit) { if(PeekMessage(&msg,NULL,0,0,PM_REMOVE)) { if(msg.message==WM_QUIT) willExit=true; else { TranslateMessage(&msg); DispatchMessage(&msg); } } else { runWindow(); draw(); BitBlt(hdc,0,0,swidth,sheight,dibDC,0,0,SRCCOPY); } } releasePalette(); releaseDIB(dibDC); DeleteDC(dibDC); ReleaseDC(hWnd,hdc); killWindow(hWnd,hInstance,wndClass); return msg.wParam; }