/* Synaescope - a pretty noatun visualization (based on P. Harrison's Synaesthesia) Copyright (C) 1997 Paul Francis Harrison 2001 Charles Samuels 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include #include #include "syna.h" #include Core *core; #define outputs unsigned char *Dlo=(unsigned char*)lastOutputBmp.data; \ unsigned char *Dllo=(unsigned char*)lastLastOutputBmp.data; \ unsigned char *Do=(unsigned char*)outputBmp.data; void Core::setupPalette(double) { interface->setupPalette(); } int Core::bitReverser(int i) { int sum=0,j; for(j=0;j>= 1; } return sum; } void Core::fft(double *x,double *y) { int n2 = NumSamples, n1; int twoToTheK; for(twoToTheK=1;twoToTheK 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 Core::addPixel(int x,int y,int br1,int br2) { if (x < 0 || x >= outWidth || y < 0 || y >= outHeight) return; unsigned char *p = output()+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 Core::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 Core::fadeFade() { unsigned long *ptr = (unsigned long*)output(); 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); ptr++; } //else { // *(ptr++) = (*ptr * 14 >> 4) & 0x0f0f0f0ful; //} else ptr++; } while(--i > 0); } inline void Core::fadePixelWave(int x,int y,int where,int step) { outputs 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) +Dlo[where]; if (!j) { Do[where] = 0; return; } j = j -Dllo[where] -1; if (j < 0) Do[where] = 0; else if (j & (255*256)) Do[where] = 255; else Do[where] = j; } void Core::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> 2) +Dlo[i]; if (!j) { Do[i] = 0; } else { j = j -Dllo[i] -1; if (j < 0) Do[i] = 0; else if (j & (255*256)) Do[i] = 255; else Do[i] = j; } } while(++i < end); } } inline void Core::fadePixelHeat(int x,int y,int where,int step) { outputs 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) +Dlo[where]; if (!j) { Do[where] = 0; return; } j = j -Dllo[where] -1; if (j < 0) Do[where] = 0; else if (j & (255*256)) Do[where] = 255; else Do[where] = j; } void Core::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> 2) +Dlo[i]; if (!j) { Do[i] = 0; } else { j = j -Dllo[i] +(Dllo[i] -Dlo[i]>>2) -1; if (j < 0) Do[i] = 0; else if (j & (255*256)) Do[i] = 255; else Do[i] = j; } } while(++i < end); } } void Core::fade() { switch(fadeMode) { case Stars : fadeFade(); break; case Flame : fadeHeat(); break; case Wave : fadeWave(); break; default: break; } } bool Core::calculate() { double x[NumSamples], y[NumSamples]; double a[NumSamples], b[NumSamples]; int clarity[NumSamples]; //Surround sound int i,j,k; #ifndef LITTLEENDIAN sampleType temp; #endif int brightFactor = int(Brightness * brightnessTwiddler /(starSize+0.01)); int num; if ((num=read(0, data, NumSamples))==0) return false; for(i=0;i> 8) | (temp << 8); x[i] = temp; temp = data[i*2+1]; temp = (temp << 8) | (temp >> 8); y[i] = temp; # endif } fft(x,y); for(i=0 +1;i> 1; // Correct for window size double brightFactor2 = (brightFactor/65536.0/NumSamples)* sqrt(actualHeight*outWidth/(320.0*200.0)); for(i=1;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 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 = output()+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 true; } #undef outputs