diff options
Diffstat (limited to 'noatun/modules/winskin/vis')
-rw-r--r-- | noatun/modules/winskin/vis/Makefile.am | 39 | ||||
-rw-r--r-- | noatun/modules/winskin/vis/WinSkinFFT.mcopclass | 5 | ||||
-rw-r--r-- | noatun/modules/winskin/vis/realFFT.cpp | 156 | ||||
-rw-r--r-- | noatun/modules/winskin/vis/realFFT.h | 69 | ||||
-rw-r--r-- | noatun/modules/winskin/vis/realFFTFilter.cpp | 88 | ||||
-rw-r--r-- | noatun/modules/winskin/vis/realFFTFilter.h | 49 | ||||
-rw-r--r-- | noatun/modules/winskin/vis/visQueue.cpp | 43 | ||||
-rw-r--r-- | noatun/modules/winskin/vis/visQueue.h | 32 | ||||
-rw-r--r-- | noatun/modules/winskin/vis/winSkinFFT_impl.cpp | 148 | ||||
-rw-r--r-- | noatun/modules/winskin/vis/winSkinFFT_impl.h | 62 | ||||
-rw-r--r-- | noatun/modules/winskin/vis/winskinvis.idl | 12 |
11 files changed, 703 insertions, 0 deletions
diff --git a/noatun/modules/winskin/vis/Makefile.am b/noatun/modules/winskin/vis/Makefile.am new file mode 100644 index 00000000..6935d860 --- /dev/null +++ b/noatun/modules/winskin/vis/Makefile.am @@ -0,0 +1,39 @@ +INCLUDES= -I$(kde_includes)/arts $(all_includes) +KDE_OPTIONS = nofinal + +DISTCLEANFILES = winskinvis.h winskinvis.cc + +winskinvis.mcopclass: winskinvis.h +winskinvis.mcoptype: winskinvis.h +winskinvis.cc winskinvis.h : $(srcdir)/winskinvis.idl + $(MCOPIDL) -t -I$(kde_includes)/arts $(srcdir)/winskinvis.idl + +lib_LTLIBRARIES = libwinskinvis.la +libwinskinvis_la_SOURCES= winskinvis.cc \ + winSkinFFT_impl.cpp realFFT.cpp \ + realFFTFilter.cpp visQueue.cpp + + +libwinskinvis_la_LDFLAGS= $(all_libraries) -avoid-version \ + -no-undefined + +libwinskinvis_la_LIBADD = -lkmedia2_idl -lsoundserver_idl -lartsflow +libwinskinvis_la_COMPILE_FIRST = winskinvis.cc +libwinskinvis_la_METASOURCES = AUTO + + + +mcoptypedir = $(libdir)/mcop +mcoptype_DATA = winskinvis.mcoptype winskinvis.mcopclass + +mcopclassdir = $(libdir)/mcop/Noatun +mcopclass_DATA = WinSkinFFT.mcopclass + +noatuninclude_HEADERS = winskinvis.h + +noatunincludedir = $(includedir)/noatun + + +winSkinFFT_impl.lo: winskinvis.h +winskinvis.lo: winskinvis.h + diff --git a/noatun/modules/winskin/vis/WinSkinFFT.mcopclass b/noatun/modules/winskin/vis/WinSkinFFT.mcopclass new file mode 100644 index 00000000..90d21e61 --- /dev/null +++ b/noatun/modules/winskin/vis/WinSkinFFT.mcopclass @@ -0,0 +1,5 @@ +Interface=Noatun::WinSkinFFT,Arts::StereoEffect,Arts::Object +Language=C++ +Library=libwinskinvis.la + + diff --git a/noatun/modules/winskin/vis/realFFT.cpp b/noatun/modules/winskin/vis/realFFT.cpp new file mode 100644 index 00000000..330280ea --- /dev/null +++ b/noatun/modules/winskin/vis/realFFT.cpp @@ -0,0 +1,156 @@ +/* + a FFT class + Copyright (C) 1998 Martin Vogt;Philip VanBaren + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation. + + For more information look at the file COPYRIGHT in this package + + */ + + +#include "realFFT.h" + +/* + * Initialize the Sine table and Twiddle pointers (bit-reversed pointers) + * for the FFT routine. + */ +RealFFT::RealFFT(int fftlen) { + int i; + int temp; + int mask; + + /* + * FFT size is only half the number of data points + * The full FFT output can be reconstructed from this FFT's output. + * (This optimization can be made since the data is real.) + */ + Points = fftlen; + + if((SinTable=(short *)malloc(Points*sizeof(short)))==NULL) + { + puts("Error allocating memory for Sine table."); + exit(1); + } + if((BitReversed=(int *)malloc(Points/2*sizeof(int)))==NULL) + { + puts("Error allocating memory for BitReversed."); + exit(1); + } + + for(i=0;i<Points/2;i++) + { + temp=0; + for(mask=Points/4;mask>0;mask >>= 1) + temp=(temp >> 1) + (i&mask ? Points/2 : 0); + + BitReversed[i]=temp; + } + + for(i=0;i<Points/2;i++) + { + register double s,c; + s=floor(-32768.0*sin(2*M_PI*i/(Points))+0.5); + c=floor(-32768.0*cos(2*M_PI*i/(Points))+0.5); + if(s>32767.5) s=32767; + if(c>32767.5) c=32767; + SinTable[BitReversed[i] ]=(short)s; + SinTable[BitReversed[i]+1]=(short)c; + } + +} + +/* + * Free up the memory allotted for Sin table and Twiddle Pointers + */ +RealFFT::~RealFFT() { + free(BitReversed); + free(SinTable); + Points=0; +} + + +/* + * Actual FFT routine. Must call InitializeFFT(fftlen) first! + * This routine has another parameter list than the other fft's + * But because we want a fast fft on pcm data this routine + * is better than the other two. + * The other two can be useful for inverse FFT. + * The format is an array of floats. (only real parts the img + * part does not exists) + */ +void RealFFT::fft(short* buffer) { + int ButterfliesPerGroup=Points/4; + + endptr1=buffer+Points; + + /* + * Butterfly: + * Ain-----Aout + * \ / + * / \ + * Bin-----Bout + */ + + while(ButterfliesPerGroup>0) + { + A=buffer; + B=buffer+ButterfliesPerGroup*2; + sptr=SinTable; + + while(A<endptr1) + { + register short sin=*sptr; + register short cos=*(sptr+1); + endptr2=B; + while(A<endptr2) + { + long v1=((long)*B*cos + (long)*(B+1)*sin) >> 15; + long v2=((long)*B*sin - (long)*(B+1)*cos) >> 15; + *B=(*A+v1)>>1; + *(A++)=*(B++)-v1; + *B=(*A-v2)>>1; + *(A++)=*(B++)+v2; + } + A=B; + B+=ButterfliesPerGroup*2; + sptr+=2; + } + ButterfliesPerGroup >>= 1; + } + /* + * Massage output to get the output for a real input sequence. + */ + br1=BitReversed+1; + br2=BitReversed+Points/2-1; + + while(br1<=br2) + { + register long temp1,temp2; + short sin=SinTable[*br1]; + short cos=SinTable[*br1+1]; + A=buffer+*br1; + B=buffer+*br2; + HRplus = (HRminus = *A - *B ) + (*B << 1); + HIplus = (HIminus = *(A+1) - *(B+1)) + (*(B+1) << 1); + temp1 = ((long)sin*HRminus - (long)cos*HIplus) >> 15; + temp2 = ((long)cos*HRminus + (long)sin*HIplus) >> 15; + *B = (*A = (HRplus + temp1) >> 1) - temp1; + *(B+1) = (*(A+1) = (HIminus + temp2) >> 1) - HIminus; + + br1++; + br2--; + } + /* + * Handle DC bin separately + */ + buffer[0]+=buffer[1]; + buffer[1]=0; +} + + +int* RealFFT::getBitReversed() { + return BitReversed; +} diff --git a/noatun/modules/winskin/vis/realFFT.h b/noatun/modules/winskin/vis/realFFT.h new file mode 100644 index 00000000..39c6dbfd --- /dev/null +++ b/noatun/modules/winskin/vis/realFFT.h @@ -0,0 +1,69 @@ +/* + a FFT class + Copyright (C) 1998 Martin Vogt;Philip VanBaren + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation. + + For more information look at the file COPYRIGHT in this package + + */ + + + + +#ifndef __REALFFT_H +#define __REALFFT_H + +#include <math.h> +#include <stdlib.h> +#include <stdio.h> + +/** + <pre> + * Program: REALFFTF.C + * Author: Philip VanBaren + * Date: 2 September 1993 + * + * Description: These routines perform an FFT on real data. + * On a 486/33 compiled using Borland C++ 3.1 with full + * speed optimization and a small memory model, a 1024 point + * FFT takes about 16ms. + * This code is for floating point data. + * + * Note: Output is BIT-REVERSED! so you must use the BitReversed to + * get legible output, (i.e. Real_i = buffer[ BitReversed[i] ] + * Imag_i = buffer[ BitReversed[i]+1 ] ) + * Input is in normal order. + </pre> + */ + + + +class RealFFT { + + int* BitReversed; + short* SinTable; + int Points; + + public: + RealFFT(int fftlen); + ~RealFFT(); + + void fft(short* buffer); + int* getBitReversed(); + + private: + + short *A,*B; + short *sptr; + short *endptr1,*endptr2; + int *br1,*br2; + long HRplus,HRminus,HIplus,HIminus; + + +}; + + +#endif diff --git a/noatun/modules/winskin/vis/realFFTFilter.cpp b/noatun/modules/winskin/vis/realFFTFilter.cpp new file mode 100644 index 00000000..13343bce --- /dev/null +++ b/noatun/modules/winskin/vis/realFFTFilter.cpp @@ -0,0 +1,88 @@ +/* + a FFT filter + Copyright (C) 1998 Martin Vogt;Philip VanBaren, 2 September 1993 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation. + + For more information look at the file COPYRIGHT in this package + + */ + + +#include "realFFTFilter.h" + +RealFFTFilter::RealFFTFilter(int fftPoints) { + this->fftPoints = fftPoints; + data=new short[fftPoints*4]; + realFFT= new RealFFT(fftPoints*2); +} + + +RealFFTFilter::~RealFFTFilter() { + delete data; + delete realFFT; +} + + +int RealFFTFilter::getPoints() { + return fftPoints; +} + + +short* RealFFTFilter::getPointPtr() { + return data; +} + + +/* + the array is expected to be a PCM stream (real data) +*/ +int RealFFTFilter::fft16(float* left,float* right,int len) { + int i; + + len=len/4; + + + int mixTmp; + + // take care for no array overflows: + int n=min(len,fftPoints); + + // copy things into fftArray. + + for (i = 0 ; i < n; i++) { + mixTmp=(int) (16384.0*(left[i]+right[i])); + + if (mixTmp < SHRT_MIN) { + data[i]= SHRT_MIN; + } else { + if (mixTmp > SHRT_MAX) { + data[i] = SHRT_MAX; + } else { + data[i]=(short)mixTmp; + } + } + } + + realFFT->fft(data); + return true; +} + + + +int* RealFFTFilter::getBitReversed() { + return realFFT->getBitReversed(); +} + + + +int RealFFTFilter::min(int x1,int x2) { + if (x1 < x2) { + return x1; + } + return x2; +} + + diff --git a/noatun/modules/winskin/vis/realFFTFilter.h b/noatun/modules/winskin/vis/realFFTFilter.h new file mode 100644 index 00000000..255e5191 --- /dev/null +++ b/noatun/modules/winskin/vis/realFFTFilter.h @@ -0,0 +1,49 @@ +/* + a FFT filter + Copyright (C) 1998 Martin Vogt;Philip VanBaren, 2 September 1993 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation. + + For more information look at the file COPYRIGHT in this package + + */ + + + + +#ifndef __REALFFTFILTER_H +#define __REALFFTFILTER_H + + + +#include "realFFT.h" +#include <limits.h> + + + +class RealFFTFilter { + + int fftPoints; + RealFFT* realFFT; + + short* data; + + + public: + RealFFTFilter(int points); + ~RealFFTFilter(); + int fft16(float* left,float* right,int len); + + int* getBitReversed(); + int getPoints(); + short* getPointPtr(); + + private: + int min(int x1,int x2); + +}; + + +#endif diff --git a/noatun/modules/winskin/vis/visQueue.cpp b/noatun/modules/winskin/vis/visQueue.cpp new file mode 100644 index 00000000..370930d2 --- /dev/null +++ b/noatun/modules/winskin/vis/visQueue.cpp @@ -0,0 +1,43 @@ +/* + queue fft samples + Copyright (C) 2001 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 "visQueue.h" + + +VISQueue::VISQueue(int elements) { + this->elements=elements; + + visArrayQueue = new std::vector<float>*[elements]; + for(int i=0;i<elements;i++) + { + visArrayQueue[i]=new std::vector<float>; + } + +} + +VISQueue::~VISQueue() { + for(int i=0;i<elements;i++) { + delete visArrayQueue[i]; + } + delete [] visArrayQueue; +} + +std::vector<float>* VISQueue::getElement(int i) +{ + if ( (i < 0) || (i>elements) ) { + return visArrayQueue[0]; + } + return visArrayQueue[i]; +} + + diff --git a/noatun/modules/winskin/vis/visQueue.h b/noatun/modules/winskin/vis/visQueue.h new file mode 100644 index 00000000..2f737fd1 --- /dev/null +++ b/noatun/modules/winskin/vis/visQueue.h @@ -0,0 +1,32 @@ +/* + queue fft samples + Copyright (C) 2001 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 + + */ + + +#ifndef __VISQUEUE_H +#define __VISQUEUE_H + + +#include <vector> + +class VISQueue { + + int elements; + std::vector<float> **visArrayQueue; + + public: + VISQueue(int elements); + ~VISQueue(); + + std::vector<float>* getElement(int i); + +}; +#endif 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); + +} diff --git a/noatun/modules/winskin/vis/winSkinFFT_impl.h b/noatun/modules/winskin/vis/winSkinFFT_impl.h new file mode 100644 index 00000000..c1a77e45 --- /dev/null +++ b/noatun/modules/winskin/vis/winSkinFFT_impl.h @@ -0,0 +1,62 @@ +/* + 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 + + */ + + +#ifndef __WINSKINFFT_IMPL_H +#define __WINSKINFFT_IMPL_H + +#include <artsflow.h> +#include <stdsynthmodule.h> +#include "winskinvis.h" +#include "realFFTFilter.h" +#include "visQueue.h" + + +using namespace std; +using namespace Arts; + +namespace Noatun { + +class WinSkinFFT_impl : public WinSkinFFT_skel, public StdSynthModule { + + public: + + WinSkinFFT_impl(); + ~WinSkinFFT_impl(); + + void streamInit(); + void streamStart(); + + // in: audio stream inleft, inright; + // out: audio stream outleft, outright; + void calculateBlock(unsigned long samples); + + void bandResolution(float res); + float bandResolution(); + vector<float> *scope(); + + private: + RealFFTFilter* realFFTFilter; + int fftBands_short; + int* fftArray; + VISQueue* visQueue; + int bands; + + int fragCnt; + int writePos; + int readPos; +}; + + +} + +#endif diff --git a/noatun/modules/winskin/vis/winskinvis.idl b/noatun/modules/winskin/vis/winskinvis.idl new file mode 100644 index 00000000..9b6564f4 --- /dev/null +++ b/noatun/modules/winskin/vis/winskinvis.idl @@ -0,0 +1,12 @@ +#include <artsflow.idl> + +module Noatun +{ + +interface WinSkinFFT : Arts::StereoEffect +{ + attribute float bandResolution; + sequence<float> scope(); +}; + +};
\ No newline at end of file |