/* implementation for winskin fft Copyright (C) 2000 Martin Vogt This program is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation. For more information look at the file COPYRIGHT in this package */ #include "winSkinFFT_impl.h" #include #include #define __BANDS 75 namespace Noatun { WinSkinFFT_impl::WinSkinFFT_impl() { fftBands_short=256; realFFTFilter= new RealFFTFilter(fftBands_short); fftArray=new int[fftBands_short]; bands=0; fragCnt=(int)(AudioSubSystem::the()->fragmentCount()); visQueue=new VISQueue(fragCnt); writePos=0; } WinSkinFFT_impl::~WinSkinFFT_impl(){ delete realFFTFilter; delete fftArray; delete visQueue; } void WinSkinFFT_impl::streamInit() { } void WinSkinFFT_impl::streamStart() { } void WinSkinFFT_impl::calculateBlock(unsigned long samples) { unsigned long i; // monitoring only tasks can't be done with that StereoEffect // interface nicely - copy input to output until there is // something better // (when?) int n=sizeof(float)*samples; memcpy(outleft,inleft,n); memcpy(outright,inright,n); if (realFFTFilter->fft16(inleft,inright,samples) == false) { return; } // // The following modifications have nothing to do // with an fft, they only make the output look nice. // (mostly scaling) short* fftPtr; int* bitReversed; fftPtr=realFFTFilter->getPointPtr(); bitReversed=realFFTFilter->getBitReversed(); int pos=0; int step=realFFTFilter->getPoints()/__BANDS; int re; int im; int tmp; float max=0.0; float avg=0.0; for (i=0;i<__BANDS;i++) { re=(int)fftPtr[bitReversed[pos]]; im=(int)fftPtr[bitReversed[pos]+1]; tmp=re*re+im*im; // Here I check a new idea. We remove all low values // and all values over xyz to xyz. fftArray[pos]=(int)(::sqrt(::sqrt(tmp))); if (fftArray[pos]<=15) { max+=fftArray[pos]; } else { max+=15+fftArray[pos]/2; } pos=pos+step; } avg=0.65*max/(float)__BANDS; pos=0; vector* visAnalyserArray=visQueue->getElement(writePos); visAnalyserArray->clear(); visAnalyserArray->reserve(__BANDS); for (i=0;i<__BANDS;i++) { float val=(float)(fftArray[pos]-avg); visAnalyserArray->push_back(val); pos=pos+step; } writePos++; if (writePos >= fragCnt) writePos=0; } void WinSkinFFT_impl::bandResolution(float res) { bands=(int)res; } float WinSkinFFT_impl::bandResolution() { return (float)bands; } vector* WinSkinFFT_impl::scope() { int delay=writePos+1; if (delay >= fragCnt) delay=0; vector* visAnalyserArray=visQueue->getElement(delay); return new vector(*visAnalyserArray); } REGISTER_IMPLEMENTATION(WinSkinFFT_impl); }