summaryrefslogtreecommitdiffstats
path: root/kscd/kscdmagic/core.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kscd/kscdmagic/core.cpp')
-rw-r--r--kscd/kscdmagic/core.cpp410
1 files changed, 410 insertions, 0 deletions
diff --git a/kscd/kscdmagic/core.cpp b/kscd/kscdmagic/core.cpp
new file mode 100644
index 00000000..49fce661
--- /dev/null
+++ b/kscd/kscdmagic/core.cpp
@@ -0,0 +1,410 @@
+/* Synaesthesia - program to display sound graphically
+ Copyright (C) 1997 Paul Francis Harrison
+
+ 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; either version 2 of the License, or (at your
+ option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ The author may be contacted at:
+ pfh@yoyo.cc.monash.edu.au
+ or
+ 27 Bond St., Mt. Waverley, 3149, Melbourne, Australia
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <string.h>
+#include "syna.h"
+
+double cosTable[n], negSinTable[n];
+int bitReverse[n];
+int scaleDown[256];
+int maxStarRadius;
+
+int bitReverser(int i) {
+ int sum=0,j;
+ for(j=0;j<m;j++) {
+ sum = (i&1)+sum*2;
+ i >>= 1;
+ }
+ return sum;
+}
+
+void fft(double *x,double *y) {
+ int n2 = n, n1;
+ int twoToTheK;
+ for(twoToTheK=1;twoToTheK<n;twoToTheK*=2) {
+ n1 = n2;
+ n2 /= 2;
+ for(int j=0;j<n2;j++) {
+ double c = cosTable[j*twoToTheK&(n-1)],
+ s = negSinTable[j*twoToTheK&(n-1)];
+ for(int i=j;i<n;i+=n1) {
+ int l = i+n2;
+ double xt = x[i] - x[l];
+ x[i] = (x[i] + x[l]);
+ double yt = y[i] - y[l];
+ y[i] = (y[i] + y[l]);
+ x[l] = xt*c - yt*s;
+ y[l] = xt*s + yt*c;
+ }
+ }
+ }
+}
+
+void coreInit() {
+ int i;
+
+ for(i=0;i<n;i++) {
+ negSinTable[i] = -sin(3.141592*2.0/n*i);
+ cosTable[i] = cos(3.141592*2.0/n*i);
+ bitReverse[i] = bitReverser(i);
+ }
+}
+
+void setStarSize(double size) {
+ //int factor = (fadeMode == Flame ? 100 :
+ // (fadeMode == Wave ? 150 : 200));
+
+ double fadeModeFudge = (fadeMode == Wave ? 0.4 :
+ (fadeMode == Flame ? 0.6 : 0.78));
+
+ int factor;
+ if (size > 0.0)
+ factor = int(exp(log(fadeModeFudge) / (size*8.0))*255);
+ else
+ factor = 0;
+
+ if (factor > 255) factor = 255;
+
+ for(int i=0;i<256;i++)
+ scaleDown[i] = i*factor>>8;
+
+ maxStarRadius = 1;
+ for(int i=255;i;i = scaleDown[i])
+ maxStarRadius++;
+}
+
+inline void addPixel(int x,int y,int br1,int br2) {
+ if (x < 0 || x >= outWidth || y < 0 || y >= outHeight) return;
+
+ unsigned char *p = ucoutput+x*2+y*outWidth*2;
+ if (p[0] < 255-br1) p[0] += br1; else p[0] = 255;
+ if (p[1] < 255-br2) p[1] += br2; else p[1] = 255;
+ //p += lastOutput-output;
+ //if (p[0] < 255-br1) p[0] += br1; else p[0] = 255;
+ //if (p[1] < 255-br2) p[1] += br2; else p[1] = 255;
+}
+
+inline void addPixelFast(unsigned char *p,int br1,int br2) {
+ if (p[0] < 255-br1) p[0] += br1; else p[0] = 255;
+ if (p[1] < 255-br2) p[1] += br2; else p[1] = 255;
+ //p += lastOutput-output;
+ //if (p[0] < 255-br1) p[0] += br1; else p[0] = 255;
+ //if (p[1] < 255-br2) p[1] += br2; else p[1] = 255;
+}
+
+void fadeFade() {
+ register unsigned long *ptr = (unsigned long*)ucoutput;
+ int i = outWidth*outHeight*2/4;
+ do {
+ //Bytewize version was: *(ptr++) -= *ptr+(*ptr>>1)>>4;
+ if (*ptr)
+ //if (*ptr & 0xf0f0f0f0ul)
+ *(ptr++) -= ((*ptr & 0xf0f0f0f0ul) >> 4) + ((*ptr & 0xe0e0e0e0ul) >> 5);
+ //else {
+ // *(ptr++) = (*ptr * 14 >> 4) & 0x0f0f0f0ful;
+ //}
+ else
+ ptr++;
+ } while(--i > 0);
+}
+
+inline unsigned char getPixel(int x,int y,int where) {
+ if (x < 0 || y < 0 || x >= outWidth || y >= outHeight) return 0;
+ return lastOutput[where];
+}
+
+inline void fadePixelWave(int x,int y,int where,int step) {
+ short j =
+ ( short(getPixel(x-1,y,where-2))+
+ getPixel(x+1,y,where+2)+
+ getPixel(x,y-1,where-step)+
+ getPixel(x,y+1,where+step)
+ >> 2)
+ +lastOutput[where];
+ if (!j) { ucoutput[where] = 0; return; }
+ j = j
+ -lastLastOutput[where]
+ -1;
+ if (j < 0) ucoutput[where] = 0;
+ else if (j & (255*256)) ucoutput[where] = 255;
+ else ucoutput[where] = j;
+}
+
+void fadeWave() {
+ unsigned short *t = lastLastOutputBmp.data;
+ lastLastOutputBmp.data = lastOutputBmp.data;
+ lastOutputBmp.data = outputBmp.data;
+ outputBmp.data = t;
+
+ int x,y,i,j,start,end;
+ int step = outWidth*2;
+ for(x=0,i=0,j=outWidth*(outHeight-1)*2;x<outWidth;x++,i+=2,j+=2) {
+ fadePixelWave(x,0,i,step);
+ fadePixelWave(x,0,i+1,step);
+ fadePixelWave(x,outHeight-1,j,step);
+ fadePixelWave(x,outHeight-1,j+1,step);
+ }
+
+ for(y=1,i=outWidth*2,j=outWidth*4-2;y<outHeight;y++,i+=step,j+=step) {
+ fadePixelWave(0,y,i,step);
+ fadePixelWave(0,y,i+1,step);
+ fadePixelWave(outWidth-1,y,j,step);
+ fadePixelWave(outWidth-1,y,j+1,step);
+ }
+
+ for(y=1,
+ start=outWidth*2+2,
+ end=outWidth*4-2; y<outHeight-1; y++,start+=step,end+=step) {
+ int i = start;
+ do {
+ short j =
+ ( short(lastOutput[i-2])+
+ lastOutput[i+2]+
+ lastOutput[i-step]+
+ lastOutput[i+step]
+ >> 2)
+ +lastOutput[i];
+ if (!j) {
+ ucoutput[i] = 0;
+ } else {
+ j = j
+ -lastLastOutput[i]
+ -1;
+ if (j < 0) ucoutput[i] = 0;
+ else if (j & (255*256)) ucoutput[i] = 255;
+ else ucoutput[i] = j;
+ }
+ } while(++i < end);
+ }
+}
+
+inline void fadePixelHeat(int x,int y,int where,int step) {
+ short j =
+ ( short(getPixel(x-1,y,where-2))+
+ getPixel(x+1,y,where+2)+
+ getPixel(x,y-1,where-step)+
+ getPixel(x,y+1,where+step)
+ >> 2)
+ +lastOutput[where];
+ if (!j) { ucoutput[where] = 0; return; }
+ j = j
+ -lastLastOutput[where]
+ -1;
+ if (j < 0) ucoutput[where] = 0;
+ else if (j & (255*256)) ucoutput[where] = 255;
+ else ucoutput[where] = j;
+}
+
+void fadeHeat() {
+ unsigned short *t = lastLastOutputBmp.data;
+ lastLastOutputBmp.data = lastOutputBmp.data;
+ lastOutputBmp.data = outputBmp.data;
+ outputBmp.data = t;
+
+ int x,y,i,j,start,end;
+ int step = outWidth*2;
+ for(x=0,i=0,j=outWidth*(outHeight-1)*2;x<outWidth;x++,i+=2,j+=2) {
+ fadePixelHeat(x,0,i,step);
+ fadePixelHeat(x,0,i+1,step);
+ fadePixelHeat(x,outHeight-1,j,step);
+ fadePixelHeat(x,outHeight-1,j+1,step);
+ }
+
+ for(y=1,i=outWidth*2,j=outWidth*4-2;y<outHeight;y++,i+=step,j+=step) {
+ fadePixelHeat(0,y,i,step);
+ fadePixelHeat(0,y,i+1,step);
+ fadePixelHeat(outWidth-1,y,j,step);
+ fadePixelHeat(outWidth-1,y,j+1,step);
+ }
+
+ for(y=1,
+ start=outWidth*2+2,
+ end=outWidth*4-2; y<outHeight-1; y++,start+=step,end+=step) {
+ int i = start;
+ do {
+ short j =
+ ( short(lastOutput[i-2])+
+ lastOutput[i+2]+
+ +lastOutput[i-step]
+ +lastOutput[i+step]
+ >> 2)
+ +lastOutput[i];
+ if (!j) {
+ ucoutput[i] = 0;
+ } else {
+ j = j
+ -lastLastOutput[i]
+ +(lastLastOutput[i]
+ -lastOutput[i]>>2)
+ -1;
+ if (j < 0) ucoutput[i] = 0;
+ else if (j & (255*256)) ucoutput[i] = 255;
+ else ucoutput[i] = j;
+ }
+ } while(++i < end);
+ }
+}
+
+void fade() {
+ switch(fadeMode) {
+ case Stars :
+ fadeFade();
+ break;
+ case Flame :
+ fadeHeat();
+ break;
+ case Wave :
+ fadeWave();
+ break;
+ default:
+ break;
+ }
+}
+
+int coreGo() {
+ double x[n], y[n];
+ double a[n], b[n];
+ int clarity[n]; //Surround sound
+ int i,j,k;
+
+ int brightFactor = int(brightness * brightnessTwiddler /(starSize+0.01));
+
+ if (-1 == getNextFragment())
+ {
+ fprintf(stderr, "no frag\n" );
+ return -1;
+ }
+
+ for(i=0;i<n;i++) {
+ x[i] = data[i*2];
+ y[i] = data[i*2+1];
+ }
+
+ fft(x,y);
+
+ for(i=0 +1;i<n;i++) {
+ double x1 = x[bitReverse[i]],
+ y1 = y[bitReverse[i]],
+ x2 = x[bitReverse[n-i]],
+ y2 = y[bitReverse[n-i]],
+ aa,bb;
+ a[i] = sqrt(aa= (x1+x2)*(x1+x2) + (y1-y2)*(y1-y2) );
+ b[i] = sqrt(bb= (x1-x2)*(x1-x2) + (y1+y2)*(y1+y2) );
+ if (aa+bb != 0.0)
+ clarity[i] = (int)(
+ ( (x1+x2) * (x1-x2) + (y1+y2) * (y1-y2) )/(aa+bb) * 256 );
+ else
+ clarity[i] = 0;
+ }
+
+ // Asger Alstrupt's optimized 32 bit fade
+ // (alstrup@diku.dk)
+ /*register unsigned long *ptr = (unsigned long*)output;
+ i = outWidth*outHeight*2/4;
+ do {
+ //Bytewize version was: *(ptr++) -= *ptr+(*ptr>>1)>>4;
+ if (*ptr)
+ if (*ptr & 0xf0f0f0f0ul)
+ *(ptr++) -= ((*ptr & 0xf0f0f0f0ul) >> 4) + ((*ptr & 0xe0e0e0e0ul) >> 5);
+ else {
+ *(ptr++) = (*ptr * 14 >> 4) & 0x0f0f0f0ful;
+ //Should be 29/32 to be consistent. Who cares. This is totally
+ // hacked anyway.
+ //unsigned char *subptr = (unsigned char*)(ptr++);
+ //subptr[0] = (int)subptr[0] * 29 / 32;
+ //subptr[1] = (int)subptr[0] * 29 / 32;
+ //subptr[2] = (int)subptr[0] * 29 / 32;
+ //subptr[3] = (int)subptr[0] * 29 / 32;
+ }
+ else
+ ptr++;
+ } while(--i > 0);
+ */
+
+ int heightFactor = n/2 / outHeight + 1;
+ int actualHeight = n/2/heightFactor;
+ int heightAdd = outHeight + actualHeight >> 1;
+
+ /* Correct for window size */
+ double brightFactor2 = (brightFactor/65536.0/n)*
+ sqrt(actualHeight*outWidth/(320.0*200.0));
+
+ for(i=1;i<n/2;i++) {
+ //int h = (int)( b[i]*280 / (a[i]+b[i]+0.0001)+20 );
+ if (a[i] > 0 || b[i] > 0) {
+ int h = (int)( b[i]*outWidth / (a[i]+b[i]) );
+ int br1, br2, br = (int)(
+ (a[i]+b[i])*i*brightFactor2 );
+ br1 = br*(clarity[i]+128)>>8;
+ br2 = br*(128-clarity[i])>>8;
+ if (br1 < 0) br1 = 0; else if (br1 > 255) br1 = 255;
+ if (br2 < 0) br2 = 0; else if (br2 > 255) br2 = 255;
+ //unsigned char *p = output+ h*2+(164-((i<<8)>>m))*(outWidth*2);
+ int px = h,
+ py = heightAdd - i / heightFactor;
+
+ if (pointsAreDiamonds) {
+ addPixel(px,py,br1,br2);
+ br1=scaleDown[br1];br2=scaleDown[br2];
+
+ //TODO: Use addpixelfast
+ for(j=1;br1>0||br2>0;j++,br1=scaleDown[br1],br2=scaleDown[br2]) {
+ for(k=0;k<j;k++) {
+ addPixel(px-j+k,py-k,br1,br2);
+ addPixel(px+k,py-j+k,br1,br2);
+ addPixel(px+j-k,py+k,br1,br2);
+ addPixel(px-k,py+j-k,br1,br2);
+ }
+ }
+ } else {
+ if (px < maxStarRadius || py < maxStarRadius ||
+ px > outWidth-maxStarRadius || py > outHeight-maxStarRadius) {
+ addPixel(px,py,br1,br2);
+ for(j=1;br1>0||br2>0;j++,br1=scaleDown[br1],br2=scaleDown[br2]) {
+ addPixel(px+j,py,br1,br2);
+ addPixel(px,py+j,br1,br2);
+ addPixel(px-j,py,br1,br2);
+ addPixel(px,py-j,br1,br2);
+ }
+ } else {
+ unsigned char *p = ucoutput+px*2+py*outWidth*2, *p1=p, *p2=p, *p3=p, *p4=p;
+ addPixelFast(p,br1,br2);
+ for(;br1>0||br2>0;br1=scaleDown[br1],br2=scaleDown[br2]) {
+ p1 += 2;
+ addPixelFast(p1,br1,br2);
+ p2 -= 2;
+ addPixelFast(p2,br1,br2);
+ p3 += outWidth*2;
+ addPixelFast(p3,br1,br2);
+ p4 -= outWidth*2;
+ addPixelFast(p4,br1,br2);
+ }
+ }
+ }
+ }
+ }
+ return 0;
+}