1 /* Synaesthesia - program to display sound graphically
2 Copyright (C) 1997 Paul Francis Harrison
3 Copyright (C) 2009 RafaĆ Rzepecki <divided.mind@gmail.com>
5 This program is free software; you can redistribute it and/or modify it
6 under the terms of the GNU General Public License as published by the
7 Free Software Foundation; either version 2 of the License, or (at your
8 option) any later version.
10 This program is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 The author may be contacted at:
20 pfh@yoyo.cc.monash.edu.au
22 27 Bond St., Mt. Waverley, 3149, Melbourne, Australia
31 #include <sys/types.h>
38 /* Config and globals =============================================== */
44 int outWidth
, outHeight
;
45 Bitmap
<unsigned short> outputBmp
, lastOutputBmp
, lastLastOutputBmp
;
47 PolygonEngine
<unsigned short,Combiner
,2> polygonEngine
;
49 void allocOutput(int w
,int h
) {
52 delete[] lastLastOutput;
53 output = new unsigned char[w*h*2];
54 lastOutput = new unsigned char[w*h*2];
55 lastLastOutput = new unsigned char[w*h*2];
56 memset(output,32,w*h*2);
57 memset(lastOutput,32,w*h*2);
62 lastOutputBmp
.size(w
,h
);
63 lastLastOutputBmp
.size(w
,h
);
64 polygonEngine
.size(w
,h
);
69 SymbolID state
= NoCD
;
70 int track
= 1, frames
= 0;
71 double trackProgress
= 0.0;
74 int playListLength
, playListPosition
;
77 bool pointsAreDiamonds
;
79 double brightnessTwiddler
;
83 double fgRedSlider
, fgGreenSlider
, bgRedSlider
, bgGreenSlider
;
85 static SoundSource soundSource
;
87 static int windX
, windY
, windWidth
, windHeight
;
88 static char dspName
[80];
89 static char mixerName
[80];
90 static char cdromName
[80];
92 void setStateToDefaults() {
94 pointsAreDiamonds
= true;
96 brightnessTwiddler
= 0.3;
106 setStateToDefaults();
109 windWidth
= DefaultWidth
;
110 windHeight
= DefaultHeight
;
111 strcpy(dspName
, "/dev/dsp");
112 strcpy(mixerName
, "/dev/mixer");
113 strcpy(cdromName
, "/dev/cdrom");
115 //Should i free this? Manual is unclear
116 struct passwd
*passWord
= getpwuid(getuid());
117 if (passWord
== 0) return false;
119 char *fileName
= new char[strlen(passWord
->pw_dir
) + 20];
120 strcpy(fileName
,passWord
->pw_dir
);
121 strcat(fileName
,"/.synaesthesia");
122 FILE *f
= fopen(fileName
,"rt");
127 while(0 != fgets(line
,80,f
)) {
128 sscanf(line
,"x %d",&windX
);
129 sscanf(line
,"y %d",&windY
);
130 sscanf(line
,"width %d",&windWidth
);
131 sscanf(line
,"height %d",&windHeight
);
132 sscanf(line
,"brightness %lf",&brightnessTwiddler
);
133 sscanf(line
,"pointsize %lf",&starSize
);
134 sscanf(line
,"fgred %lf",&fgRedSlider
);
135 sscanf(line
,"fggreen %lf",&fgGreenSlider
);
136 sscanf(line
,"bgred %lf",&bgRedSlider
);
137 sscanf(line
,"bggreen %lf",&bgGreenSlider
);
138 sscanf(line
,"dsp %s",dspName
);
139 sscanf(line
,"mixer %s",mixerName
);
140 sscanf(line
,"cdrom %s",cdromName
);
141 if (strncmp(line
,"fade",4) == 0) fadeMode
= Stars
;
142 if (strncmp(line
,"wave",4) == 0) fadeMode
= Wave
;
143 if (strncmp(line
,"heat",4) == 0) fadeMode
= Flame
;
144 if (strncmp(line
,"stars",5) == 0) pointsAreDiamonds
= false;
145 if (strncmp(line
,"diamonds",8) == 0) pointsAreDiamonds
= true;
150 windWidth
= DefaultWidth
;
152 windHeight
= DefaultHeight
;
156 if (v < 0.0) v = 0.0; \
157 if (v > 1.0) v = 1.0;
159 bound(brightnessTwiddler
)
175 //Should i free this? Manual is unclear
176 struct passwd
*passWord
= getpwuid(getuid());
178 fprintf(stderr
,"Couldn't work out where to put config file.\n");
182 char *fileName
= new char[strlen(passWord
->pw_dir
) + 20];
183 strcpy(fileName
,passWord
->pw_dir
);
184 strcat(fileName
,"/.synaesthesia");
185 FILE *f
= fopen(fileName
,"wt");
189 fprintf(f
,"# Synaesthesia config file\n");
190 fprintf(f
,"x %d\n",windX
);
191 fprintf(f
,"y %d\n",windY
);
192 fprintf(f
,"width %d\n",outWidth
);
193 fprintf(f
,"height %d\n",outHeight
);
195 fprintf(f
,"# Point style: either diamonds or stars\n");
196 fprintf(f
,"%s\n",pointsAreDiamonds
? "diamonds" : "stars");
198 fprintf(f
,"# Fade style: either fade, wave or heat\n");
199 fprintf(f
,"%s\n",fadeMode
==Stars
? "fade" : (fadeMode
==Wave
? "wave" : "heat"));
201 fprintf(f
,"brightness %f\n",brightnessTwiddler
);
202 fprintf(f
,"pointsize %f\n",starSize
);
203 fprintf(f
,"fgred %f\n",fgRedSlider
);
204 fprintf(f
,"fggreen %f\n",fgGreenSlider
);
205 fprintf(f
,"bgred %f\n",bgRedSlider
);
206 fprintf(f
,"bggreen %f\n",bgGreenSlider
);
207 fprintf(f
,"dsp %s\n",dspName
);
208 fprintf(f
,"mixer %s\n",mixerName
);
209 fprintf(f
,"cdrom %s\n",cdromName
);
212 fprintf(stderr
,"Couldn't open config file to save settings.\n");
216 void chomp(int &argc
,char **argv
,int argNum
) {
218 for(int i
=argNum
;i
<argc
;i
++)
222 int main(int argc
, char **argv
) {
227 printf("SYNAESTHESIA " VERSION
"\n\n"
229 " synaesthesia cd\n - listen to a CD\n"
230 " synaesthesia line\n - listen to line input\n"
233 " synaesthesia esd\n - listen to EsounD output (eg for use with XMMS)\n"
236 " synaesthesia <track> <track> <track>...\n"
237 " - play these CD tracks one after the other\n"
238 " <another program> |synaesthesia pipe <frequency>\n"
239 " - send output of program to sound card as well as displaying it.\n"
240 " (must be 16-bit stereo sound)\n"
241 " example: mpg123 -s file.mp3 |synaesthesia pipe 44100\n\n"
242 "The following optional flags may be used\n"
245 " --use-sdl force use of Simple DirectMedia Layer\n"
247 #ifndef X_DISPLAY_MISSING
248 " --use-x force use of X-Windows\n"
251 " --use-svga force use of SVGALib\n"
253 " --raw-output nn output raw frames on stdout at that many fps\n"
254 " --fullscreen try to take over the whole screen\n"
255 " --width nnn make the window this wide\n"
256 " --height nnn make the window this high\n\n"
257 "For more information, see http://logarithmic.net/pfh/Synaesthesia\n\n"
264 bool fullscreen
= false, useSDL
= true, useX
= true, useSVGA
= true, outputRaw
= false;
267 if (strcmp(argv
[i
],"--use-sdl") == 0) {
271 } else if (strcmp(argv
[i
],"--use-x") == 0) {
275 } else if (strcmp(argv
[i
],"--use-svga") == 0) {
279 } else if (strcmp(argv
[i
],"--output-raw") == 0) {
289 } else if (strcmp(argv
[i
],"--fullscreen") == 0) {
292 } else if (strcmp(argv
[i
],"--width") == 0) {
294 windWidth
= atoi(argv
[i
]);
296 windWidth
= DefaultWidth
;
299 } else if (strcmp(argv
[i
],"--height") == 0) {
301 windHeight
= atoi(argv
[i
]);
303 windHeight
= DefaultHeight
;
308 int configPlayTrack
= -1;
309 int inFrequency
= Frequency
;
313 if (strcmp(argv
[1],"line") == 0) soundSource
= SourceLine
;
314 else if (strcmp(argv
[1],"cd") == 0) soundSource
= SourceCD
;
317 else if (strcmp(argv
[1],"esd") == 0) soundSource
= SourceESD
;
320 else if (strcmp(argv
[1],"pipe") == 0) {
321 if (argc
< 3 || sscanf(argv
[2],"%d",&inFrequency
) != 1)
322 error("frequency not specified");
323 soundSource
= SourcePipe
;
325 if (sscanf(argv
[1],"%d",&configPlayTrack
) != 1)
326 error("comprehending user's bizzare requests");
328 soundSource
= SourceCD
;
330 playListPosition
= 0;
331 playListLength
= argc
-1;
334 if (soundSource
== SourceCD
)
339 if (configPlayTrack
!= -1) {
343 openSound(soundSource
, inFrequency
, dspName
, mixerName
);
347 //if (volume > 0.0) {
348 // brightnessTwiddler /= volume;
350 //if (brightnessTwiddler > 1.0)
351 // brightnessTwiddler = 1.0;
352 //else if (brightnessTwiddler < 0.0)
353 // brightnessTwiddler = 0.0;
357 //else if (volume < 0.0)
363 if (!screen
&& useSDL
) {
364 screen
= new SdlScreen
;
365 if (!screen
->init(windX
,windY
,windWidth
,windHeight
,fullscreen
))
370 #ifndef X_DISPLAY_MISSING
371 if (!screen
&& useX
) {
372 screen
= new XScreen
;
373 if (!screen
->init(windX
,windY
,windWidth
,windHeight
,fullscreen
))
379 if (!screen
&& useSVGA
) {
380 screen
= new SvgaScreen
;
381 if (!screen
->init(windX
,windY
,windWidth
,windHeight
,fullscreen
))
386 if (!screen
&& outputRaw
) {
387 screen
= new RawScreen(fps
);
388 if (!screen
->init(windX
,windY
,windWidth
,windHeight
,fullscreen
))
393 error("opening any kind of display device");
395 allocOutput(outWidth
,outHeight
);
399 setStarSize(starSize
);
403 time_t timer
= time(NULL
);
412 if (interfaceGo()) break;
419 timer
= time(NULL
) - timer
;
423 // if (configPlayTrack != -1)
426 if (soundSource
== SourceCD
)
435 printf("Frames per second: %f\n", double(frames
) / timer
);
440 void error(char *str
, bool syscall
) {
441 fprintf(stderr
, "synaesthesia: Error %s\n",str
);
443 fprintf(stderr
,"(reason for error: %s)\n",strerror(errno
));
446 void warning(char *str
, bool syscall
) {
447 fprintf(stderr
, "synaesthesia: Possible error %s\n",str
);
449 fprintf(stderr
,"(reason for error: %s)\n",strerror(errno
));