summaryrefslogtreecommitdiffstats
path: root/noatun/modules/winskin/vis/winSkinFFT_impl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'noatun/modules/winskin/vis/winSkinFFT_impl.cpp')
-rw-r--r--noatun/modules/winskin/vis/winSkinFFT_impl.cpp148
1 files changed, 148 insertions, 0 deletions
diff --git a/noatun/modules/winskin/vis/winSkinFFT_impl.cpp b/noatun/modules/winskin/vis/winSkinFFT_impl.cpp
new file mode 100644
index 00000000..5396ac3c
--- /dev/null
+++ b/noatun/modules/winskin/vis/winSkinFFT_impl.cpp
@@ -0,0 +1,148 @@
+/*
+ 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 <audiosubsys.h>
+#include <cstring>
+
+#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<float>* 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<float>* WinSkinFFT_impl::scope() {
+ int delay=writePos+1;
+ if (delay >= fragCnt) delay=0;
+
+
+ vector<float>* visAnalyserArray=visQueue->getElement(delay);
+
+ return new vector<float>(*visAnalyserArray);
+}
+
+
+REGISTER_IMPLEMENTATION(WinSkinFFT_impl);
+
+}