summaryrefslogtreecommitdiffstats
path: root/noatun/modules/winskin/vis
diff options
context:
space:
mode:
Diffstat (limited to 'noatun/modules/winskin/vis')
-rw-r--r--noatun/modules/winskin/vis/Makefile.am39
-rw-r--r--noatun/modules/winskin/vis/WinSkinFFT.mcopclass5
-rw-r--r--noatun/modules/winskin/vis/realFFT.cpp156
-rw-r--r--noatun/modules/winskin/vis/realFFT.h69
-rw-r--r--noatun/modules/winskin/vis/realFFTFilter.cpp88
-rw-r--r--noatun/modules/winskin/vis/realFFTFilter.h49
-rw-r--r--noatun/modules/winskin/vis/visQueue.cpp43
-rw-r--r--noatun/modules/winskin/vis/visQueue.h32
-rw-r--r--noatun/modules/winskin/vis/winSkinFFT_impl.cpp148
-rw-r--r--noatun/modules/winskin/vis/winSkinFFT_impl.h62
-rw-r--r--noatun/modules/winskin/vis/winskinvis.idl12
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