[Git]Ignore work files.
[synaesthesia.git] / main.cc
bloba88fc3b3fa589e73fd2508a2537fe1be55477be2
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
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <errno.h>
28 #include <time.h>
29 #include <unistd.h>
30 #include <fcntl.h>
31 #include <sys/types.h>
32 #include <pwd.h>
33 #include <string.h>
34 #include "syna.h"
36 //void setupIcons();
38 /* Config and globals =============================================== */
40 BaseScreen *screen;
42 sampleType *data;
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) {
50 /*delete[] output;
51 delete[] lastOutput;
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);
58 outWidth = w;
59 outHeight = h;*/
61 outputBmp.size(w,h);
62 lastOutputBmp.size(w,h);
63 lastLastOutputBmp.size(w,h);
64 polygonEngine.size(w,h);
65 outWidth = w;
66 outHeight = h;
69 SymbolID state = NoCD;
70 int track = 1, frames = 0;
71 double trackProgress = 0.0;
73 char **playList;
74 int playListLength, playListPosition;
76 SymbolID fadeMode;
77 bool pointsAreDiamonds;
79 double brightnessTwiddler;
80 double starSize;
81 double volume = 0.5;
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() {
93 fadeMode = Stars;
94 pointsAreDiamonds = true;
96 brightnessTwiddler = 0.3;
97 starSize = 0.5;
99 fgRedSlider=0.0;
100 fgGreenSlider=0.5;
101 bgRedSlider=0.75;
102 bgGreenSlider=0.4;
105 bool loadConfig() {
106 setStateToDefaults();
107 windX=10;
108 windY=30;
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");
123 delete fileName;
125 if (f) {
126 char line[80];
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;
147 fclose(f);
149 if (windWidth < 1)
150 windWidth = DefaultWidth;
151 if (windHeight < 1)
152 windHeight = DefaultHeight;
153 windWidth &= ~3;
155 # define bound(v) \
156 if (v < 0.0) v = 0.0; \
157 if (v > 1.0) v = 1.0;
159 bound(brightnessTwiddler)
160 bound(starSize)
161 bound(fgRedSlider)
162 bound(fgGreenSlider)
163 bound(bgRedSlider)
164 bound(bgGreenSlider)
166 # undef bound
168 return true;
169 } else
170 return false;
174 void saveConfig() {
175 //Should i free this? Manual is unclear
176 struct passwd *passWord = getpwuid(getuid());
177 if (passWord == 0) {
178 fprintf(stderr,"Couldn't work out where to put config file.\n");
179 return;
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");
186 delete fileName;
188 if (f) {
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);
210 fclose(f);
211 } else {
212 fprintf(stderr,"Couldn't open config file to save settings.\n");
216 void chomp(int &argc,char **argv,int argNum) {
217 argc--;
218 for(int i=argNum;i<argc;i++)
219 argv[i] = argv[i+1];
222 int main(int argc, char **argv) {
223 if (!loadConfig())
224 saveConfig();
226 if (argc == 1) {
227 printf("SYNAESTHESIA " VERSION "\n\n"
228 "Usage:\n"
229 " synaesthesia cd\n - listen to a CD\n"
230 " synaesthesia line\n - listen to line input\n"
232 #if HAVE_LIBESD
233 " synaesthesia esd\n - listen to EsounD output (eg for use with XMMS)\n"
234 #endif
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"
244 #if HAVE_SDL
245 " --use-sdl force use of Simple DirectMedia Layer\n"
246 #endif
247 #ifndef X_DISPLAY_MISSING
248 " --use-x force use of X-Windows\n"
249 #endif
250 #if HAVE_LIBVGA
251 " --use-svga force use of SVGALib\n"
252 #endif
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"
258 "Enjoy!\n"
260 return 1;
263 //Do flags
264 bool fullscreen = false, useSDL = true, useX = true, useSVGA = true, outputRaw = false;
265 int fps;
266 for(int i=0;i<argc;)
267 if (strcmp(argv[i],"--use-sdl") == 0) {
268 useX = false;
269 useSVGA = false;
270 chomp(argc,argv,i);
271 } else if (strcmp(argv[i],"--use-x") == 0) {
272 useSDL = false;
273 useSVGA = false;
274 chomp(argc,argv,i);
275 } else if (strcmp(argv[i],"--use-svga") == 0) {
276 useSDL = false;
277 useX = false;
278 chomp(argc,argv,i);
279 } else if (strcmp(argv[i],"--output-raw") == 0) {
280 useSDL = false;
281 useX = false;
282 useSVGA = false;
283 outputRaw = true;
284 chomp(argc,argv,i);
285 fps = atoi(argv[i]);
286 if (fps < 1)
287 fps = 25;
288 chomp(argc,argv,i);
289 } else if (strcmp(argv[i],"--fullscreen") == 0) {
290 fullscreen = true;
291 chomp(argc,argv,i);
292 } else if (strcmp(argv[i],"--width") == 0) {
293 chomp(argc,argv,i);
294 windWidth = atoi(argv[i]);
295 if (windWidth < 1)
296 windWidth = DefaultWidth;
297 windWidth &= ~3;
298 chomp(argc,argv,i);
299 } else if (strcmp(argv[i],"--height") == 0) {
300 chomp(argc,argv,i);
301 windHeight = atoi(argv[i]);
302 if (windHeight < 1)
303 windHeight = DefaultHeight;
304 chomp(argc,argv,i);
305 } else
306 i++;
308 int configPlayTrack = -1;
309 int inFrequency = Frequency;
311 playListLength = 0;
313 if (strcmp(argv[1],"line") == 0) soundSource = SourceLine;
314 else if (strcmp(argv[1],"cd") == 0) soundSource = SourceCD;
316 #if HAVE_LIBESD
317 else if (strcmp(argv[1],"esd") == 0) soundSource = SourceESD;
318 #endif
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;
324 } else
325 if (sscanf(argv[1],"%d",&configPlayTrack) != 1)
326 error("comprehending user's bizzare requests");
327 else {
328 soundSource = SourceCD;
329 playList = argv+1;
330 playListPosition = 0;
331 playListLength = argc-1;
334 if (soundSource == SourceCD)
335 cdOpen(cdromName);
336 else
337 state = Plug;
339 if (configPlayTrack != -1) {
340 cdStop();
343 openSound(soundSource, inFrequency, dspName, mixerName);
345 setupMixer(volume);
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;
355 //if (volume > 1.0)
356 // volume = 1.0;
357 //else if (volume < 0.0)
358 // volume = 0.0;
360 screen = 0;
362 #if HAVE_SDL
363 if (!screen && useSDL) {
364 screen = new SdlScreen;
365 if (!screen->init(windX,windY,windWidth,windHeight,fullscreen))
366 screen = 0;
368 #endif
370 #ifndef X_DISPLAY_MISSING
371 if (!screen && useX) {
372 screen = new XScreen;
373 if (!screen->init(windX,windY,windWidth,windHeight,fullscreen))
374 screen = 0;
376 #endif
378 #if HAVE_LIBVGA
379 if (!screen && useSVGA) {
380 screen = new SvgaScreen;
381 if (!screen->init(windX,windY,windWidth,windHeight,fullscreen))
382 screen = 0;
384 #endif
386 if (!screen && outputRaw) {
387 screen = new RawScreen(fps);
388 if (!screen->init(windX,windY,windWidth,windHeight,fullscreen))
389 screen = 0;
392 if (!screen)
393 error("opening any kind of display device");
395 allocOutput(outWidth,outHeight);
397 coreInit();
399 setStarSize(starSize);
401 interfaceInit();
403 time_t timer = time(NULL);
405 int frames = 0;
406 for(;;) {
407 fade();
409 if (-1 == coreGo())
410 break;
412 if (interfaceGo()) break;
414 screen->show();
416 frames++;
419 timer = time(NULL) - timer;
421 interfaceEnd();
423 // if (configPlayTrack != -1)
424 // cdStop();
426 if (soundSource == SourceCD)
427 cdClose();
429 closeSound();
431 screen->end();
432 delete screen;
434 if (timer > 10)
435 printf("Frames per second: %f\n", double(frames) / timer);
437 return 0;
440 void error(char *str, bool syscall) {
441 fprintf(stderr, "synaesthesia: Error %s\n",str);
442 if (syscall)
443 fprintf(stderr,"(reason for error: %s)\n",strerror(errno));
444 exit(1);
446 void warning(char *str, bool syscall) {
447 fprintf(stderr, "synaesthesia: Possible error %s\n",str);
448 if (syscall)
449 fprintf(stderr,"(reason for error: %s)\n",strerror(errno));