00001
00002
00003
00077 #include <iostream>
00078 #include <stdio.h>
00079 #include <stdlib.h>
00080 #include <getopt.h>
00081 #include <string.h>
00082 #include <unistd.h>
00083 #include <fcntl.h>
00084 #include <sys/stat.h>
00085 #include <sys/types.h>
00086 #include <signal.h>
00087 #include <assert.h>
00088
00089 #include <config.h>
00090
00091 #include <jutils.h>
00092 #include <generic.h>
00093 #include <jmixer.h>
00094 #include <gui.h>
00095 #include <out_lame.h>
00096 #include <out_vorbis.h>
00097
00098 #ifdef GUI_NIGHTOLO
00099 #include <gtkgui/gtk_gui.h>
00100 #endif
00101
00102 #ifdef GUI_NIGHTOLO2
00103 #include <gtkgui2/gtk2_gui.h>
00104 #endif
00105
00106 #ifdef GUI_RUBIK
00107 #include <ncursesgui/ncurses_gui.h>
00108 #endif
00109
00110 #ifdef UI_XMLRPC
00111 #include <xmlrpc/xmlrpc_ui.h>
00112 #endif
00113
00114 #ifdef HAVE_SCHEDULER
00115 #include "radiosched.h"
00116 #endif
00117
00118
00119
00120
00121 char *version =
00122 "%s version %s http://muse.dyne.org";
00123
00124 char *help =
00125 "Usage: muse [generic options] [-e [encoder options] [stream options] ] [files]\n"
00126 ":: generic options:\n"
00127 " -h --help this help\n"
00128 " -v --version version information\n"
00129 " -D --debug [1-3] debug verbosity level - default 1\n"
00130 " -o --dspout disable souncard output - default on\n"
00131 " -C --cli command line input (no GUI)\n"
00132 " -g --gui specify GUI to use (-g list)\n"
00133 ":: input channels options\n"
00134 " -i --live mic/line soundcard input - default off\n"
00135 " -I --liveamp mic/line volume (1 - 32) - default 1\n"
00136 " -N --number channel number - default 1\n"
00137 " -V --volume channel volume - default 1.0\n"
00138 " -S --position channel starting position - default 0.0\n"
00139 " -P --playmode playmode: play, cont, loop - default cont\n"
00140 ":: output encoders options:\n"
00141 " -e --encoder codec to use [ogg|mp3] - default ogg\n"
00142 " -b --bitrate codec bitrate in Kbit/s - default 24\n"
00143 " -r --frequency encoding frequency - default auto\n"
00144 " -q --quality encoding quality (1-9) - default 4\n"
00145 " -c --channels number of audio channels - default 1\n"
00146 " -f --filedump dump stream to file\n"
00147 ":: broadcast stream options:\n"
00148 " -s --server stream to server[:port] - default port 8000\n"
00149 " -m --mount mounpoint on server - default live\n"
00150 " -l --login login type [ice1|ice2|icy] - default ice1\n"
00151 " -p --pass encoder password on server\n"
00152 " -n --name name of the stream\n"
00153 " -u --url descriptive url of the stream\n"
00154 " -d --desc description of the stream\n"
00155 "\n";
00156
00157 static const struct option long_options[] = {
00158 { "help", no_argument, NULL, 'h' },
00159 { "version", no_argument, NULL, 'v' },
00160 { "debug", required_argument, NULL, 'D' },
00161 { "live", no_argument, NULL, 'i' },
00162 { "liveamp", required_argument, NULL, 'I' },
00163 { "dspout", no_argument, NULL, 'o' },
00164 { "cli", no_argument, NULL, 'C' },
00165 { "number", required_argument, NULL, 'N' },
00166 { "volume", required_argument, NULL, 'V' },
00167 { "position", required_argument, NULL, 'S' },
00168 { "playmode", required_argument, NULL, 'P' },
00169 { "encoder", required_argument, NULL, 'e' },
00170 { "bitrate", required_argument, NULL, 'b' },
00171 { "frequency", required_argument, NULL, 'r' },
00172 { "quality", required_argument, NULL, 'q' },
00173 { "channels", required_argument, NULL, 'c' },
00174 { "filedump", required_argument, NULL, 'f' },
00175 { "gui", required_argument, NULL, 'g' },
00176 { "server", required_argument, NULL, 's' },
00177 { "port", required_argument, NULL, 'p' },
00178 { "mount", required_argument, NULL, 'm' },
00179 { "login", required_argument, NULL, 'l' },
00180 { "pass",required_argument, NULL, 'p' },
00181 { "name",required_argument, NULL, 'n' },
00182 { "url",required_argument, NULL, 'u' },
00183 { "desc", required_argument, NULL, 'd' },
00184 { 0, 0, 0, 0 }
00185 };
00186
00187 char *short_options = "-hvD:ioCN:V:S:P:e:b:r:q:c:f:g:s:m:l:p:n:u:d:";
00188
00189
00190 #define MAX_CLI_CHARS 9182
00191 int debug = 1;
00192 bool daemon_mode = false;
00193 char *queue_file = NULL;
00194
00195 int lfreq = 0;
00196 float quality = 1.0f;
00197 int channels = 1;
00198
00199 int thegui = -1;
00200 enum interface { CLI, GTK1, GTK2, NCURSES };
00201
00202
00203 int number = 0;
00204 int playmode = PLAYMODE_CONT;
00205
00206 bool has_playlist = false;
00207 bool dspout = true;
00208 bool micrec = false;
00209 int micvol = 16;
00210 bool snddev = false;
00211
00212 Stream_mixer *mix = NULL;
00213 GUI *gui = NULL;
00214
00215 OutChannel *outch = NULL;
00216 int encid = 0;
00217
00218 Shouter *ice = NULL;
00219 int iceid = 0;
00220
00221
00222 void quitproc (int Sig);
00223 void fsigpipe (int Sig);
00224 bool got_sigpipe;
00225
00226
00227 bool take_args(int argc, char **argv) {
00228 int res;
00229
00230 MuseSetDebug(1);
00231
00232 do {
00233 res = getopt_long(argc, argv, short_options, long_options, NULL);
00234
00235 switch(res) {
00236
00237 case 'h':
00238 fprintf(stderr,"%s",help);
00239 exit(0);
00240
00241 case 'v':
00242
00243 notice("GTK2 GUI by Antonino \"nightolo\" Radici <night@freaknet.org>");
00244 notice("Ncurses console by Luca \"rubik\" Profico <rubik@olografix.org>");
00245 act(" ");
00246 notice("BIG UP \\o/ dyne.org / FreakNet / RASTASOFT / Metro Olografix");
00247 act(" ");
00248 act("part of the redistributed code is copyright by the respective authors,");
00249 act("please refer to the AUTHORS file and to the sourcecode for complete");
00250 act("information.");
00251 act(" ");
00252 act("This source code is free software; you can redistribute it and/or");
00253 act("modify it under the terms of the GNU Public License as published");
00254 act("by the Free Software Foundation; either version 2 of the License,");
00255 act("or (at your option) any later version.");
00256 act(" ");
00257 act("This source code is distributed in the hope that it will be useful,");
00258 act("but WITHOUT ANY WARRANTY; without even the implied warranty of");
00259 act("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.");
00260 act("Please refer to the GNU Public License for more details.");
00261 act(" ");
00262 act("You should have received a copy of the GNU Public License along with");
00263 act("this source code; if not, write to:");
00264 act("Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.");
00265 exit(0);
00266
00267 case 'D':
00268 MuseSetDebug( atoi(optarg) );
00269 break;
00270
00271 case 'o':
00272
00273
00274
00275
00276
00277
00278 dspout = false;
00279 break;
00280
00281 case 'i':
00282
00283
00284
00285
00286
00287
00288 micrec = true;
00289 mix->set_mic_volume(micvol);
00290 notice("CLI: recording from mic/linein");
00291 break;
00292
00293 case 'I':
00294 micvol = atoi(optarg);
00295 if(micvol < 1 || micvol > 32)
00296 error("invalid mic/line volume value, must be a approx between 1 and 32");
00297 else {
00298 mix->set_mic_volume(micvol);
00299 act("CLI: mic/linein volume gain %i",micvol);
00300 }
00301 break;
00302
00303 case 'e':
00304 encid = 0;
00305
00306 #ifdef HAVE_VORBIS
00307 if (strncasecmp("ogg",optarg,3) == 0) {
00308 encid = mix->create_enc(OGG);
00309 notice("CLI: created Ogg encoder");
00310 }
00311 #endif
00312
00313 #ifdef HAVE_LAME
00314 if (strncasecmp("mp3",optarg,3) == 0) {
00315 encid = mix->create_enc(MP3);
00316 notice("CLI: created Mp3 encoder");
00317 }
00318 #endif
00319
00320 if(encid>0) outch = mix->get_enc(encid);
00321 if(outch) break;
00322
00323 error("you can specify an encoder with the -e option");
00324 act("supported encoders are:");
00325 #ifdef HAVE_VORBIS
00326 act(" OGG - Ogg/Vorbis codec");
00327 #endif
00328 #ifdef HAVE_LAME
00329 act(" MP3 - Lame MP3 codec");
00330 #endif
00331 exit(0);
00332
00333 case 'b':
00334 if(!outch) {
00335 error("invalid command line argument: bps");
00336 error("you must specify a codec first with the -e option");
00337 break;
00338 }
00339 outch->bps( atoi(optarg) );
00340 act("CLI: bitrate set to %iKbit/s",outch->bps());
00341 break;
00342
00343 case 'r':
00344 if(!outch) {
00345 error("invalid command line argument: frequency");
00346 error("you must specify a codec first with the -e option");
00347 break;
00348 }
00349 lfreq = atoi(optarg);
00350 if(lfreq != 0 &&
00351 lfreq != 11000 &&
00352 lfreq != 16000 &&
00353 lfreq != 22050 &&
00354 lfreq != 32000 &&
00355 lfreq != 44100) {
00356 error("invalid frequency %i",lfreq);
00357 error("must be 0, 11000, 16000, 22050, 32000 or 44100 Hz!");
00358 act("CLI: falling back to auto");
00359 lfreq = 0;
00360 }
00361 outch->freq(lfreq);
00362 act("CLI: frequency set to %iKhz",outch->freq());
00363 break;
00364
00365 case 'q':
00366 if(!outch) {
00367 error("invalid command line argument: quality");
00368 error("you must specify a codec first with the -e option");
00369 break;
00370 }
00371 if( sscanf(optarg,"%f",&quality) ) {
00372
00373
00374
00375
00376
00377
00378 act("CLI: quality set to %s",outch->quality(quality));
00379 } else error("invalid quality value");
00380 break;
00381
00382 case 'c':
00383 if(!outch) {
00384 error("invalid command line argument: channels");
00385 error("you must specify a codec first with the -e option");
00386 break;
00387 }
00388
00389 channels = atoi(optarg);
00390 if(channels>2 | channels<1) {
00391 error("audio channels can be only 1 (mono) or 2 (stereo)");
00392 act("falling back to default: 1 (mono)");
00393 channels = 1;
00394 }
00395 outch->channels(channels);
00396 act("CLI: encoding %i channel(s)",channels);
00397 break;
00398
00399 case 'f':
00400 if(!outch) {
00401 error("invalid command line argument: file dump");
00402 error("you must specify a codec first with the -e option");
00403 break;
00404 }
00405 outch->dump_start( optarg );
00406 act("CLI: file saving to %s",optarg);
00407 break;
00408
00409 case 'C':
00410 thegui = 0;
00411 break;
00412
00413 case 'N':
00414 number = atoi(optarg);
00415 number = (number<0) ? 0 : (number>=MAX_CHANNELS) ? MAX_CHANNELS-1 : number;
00416
00417 if(!mix->chan[number]) {
00418 if(!mix->create_channel(number)) {
00419 error("got problems creating channel %i",number);
00420 } else {
00421 notice("CLI: created channel %i",number);
00422 mix->set_playmode(number,playmode);
00423 }
00424 }
00425 break;
00426
00427 case 'V':
00428 float vol;
00429 if(sscanf(optarg,"%f",&vol)==EOF)
00430 error("CLI: invalid volume for channel %i",number);
00431 else {
00432 vol = (vol>1.0) ? 1.0 : (vol < 0.0) ? 0.0 : vol;
00433 mix->set_volume(number,vol);
00434 act("CLI: volume set to %.2f",vol);
00435 }
00436 break;
00437
00438 case 'S':
00439 float pos;
00440 if(sscanf(optarg,"%f",&pos)==EOF)
00441 error("CLI: invalid position for channel %i",number);
00442 else {
00443 pos = (pos>1.0) ? 1.0 : (pos < 0.0) ? 0.0 : pos;
00444 mix->set_position(number,pos);
00445 act("CLI: starting from position %.2f",pos);
00446 }
00447 break;
00448
00449 case 'P':
00450 playmode = 0;
00451 if(strncasecmp(optarg,"play",4)==0) playmode=PLAYMODE_PLAY;
00452 if(strncasecmp(optarg,"cont",4)==0) playmode=PLAYMODE_CONT;
00453 if(strncasecmp(optarg,"loop",4)==0) playmode=PLAYMODE_LOOP;
00454 if(!playmode)
00455 error("invalid playmode %s",optarg);
00456 else
00457
00458 act("CLI: set playmode \"%s\" for following channels",optarg);
00459 break;
00460
00461 case 'g':
00462 #ifdef GUI_NIGHTOLO
00463 if(strcasecmp(optarg,"gtk")==0) thegui=GTK1;
00464 #endif
00465 #ifdef GUI_NIGHTOLO2
00466 if(strcasecmp(optarg,"gtk2")==0) thegui=GTK2;
00467 #endif
00468 #ifdef GUI_RUBIK
00469 if(strcasecmp(optarg,"ncurses")==0) thegui=NCURSES;
00470 #endif
00471 if(strcasecmp(optarg,"cli")==0) thegui=CLI;
00472
00473 if(thegui>=0) break;
00474
00475 notice("listing available user interfaces:");
00476 #ifdef GUI_NIGHTOLO
00477 act("[gtk] - Xwin graphical interactive clicky clicky");
00478 #endif
00479 #ifdef GUI_NIGHTOLO2
00480 act("[gtk2] - new graphical interactive, experimental with languages");
00481 #endif
00482 #ifdef GUI_RUBIK
00483 act("[ncurses] - 0ld sch00l l33t console display");
00484 #endif
00485 act("[cli] - command line interface, not interactive");
00486 exit(0);
00487
00488 case 's':
00489 if(!outch) {
00490 error("invalid command line argument: server");
00491 error("you must specify a codec first with the -e option");
00492 break;
00493 }
00494
00495 iceid = outch->create_ice();
00496 if(iceid<0) {
00497 error("could'nt create icecast shouter");
00498 break;
00499 } else func("created icecast shouter ID %i",iceid);
00500 ice = outch->get_ice(iceid);
00501
00502 char *p;
00503 p = strstr(optarg,":");
00504 if(p) {
00505 ice->port( atoi(p+1) );
00506 *p = '\0';
00507 } else ice->port(8000);
00508 ice->host(optarg);
00509 notice("CLI: created streamer to %s %i",
00510 ice->host(), ice->port());
00511
00512 break;
00513
00514 case 'l':
00515 if(!outch) {
00516 error("invalid command line argument: server login type");
00517 error("you must specify a codec first with the -e option");
00518 break;
00519 }
00520 if(!iceid) {
00521 error("invalid command line argument: server login type");
00522 error("you must specify a server first with the -s option");
00523 break;
00524 }
00525 int ltype;
00526 if(strncasecmp(optarg,"ice1",4)==0)
00527 ltype = SHOUT_PROTOCOL_XAUDIOCAST;
00528 else if(strncasecmp(optarg,"ice2",4)==0)
00529 ltype = SHOUT_PROTOCOL_HTTP;
00530 else if(strncasecmp(optarg,"icy",4)==0)
00531 ltype = SHOUT_PROTOCOL_ICY;
00532 else {
00533 error("unrecognized login type: %s",optarg);
00534 error("please use one of the following:");
00535 error("ice1 = icecast 1, darwin and litestream");
00536 error("ice2 = icecast 2 server");
00537 error("icy = shoutcast server");
00538 break;
00539 }
00540 ice = outch->get_ice(iceid);
00541 ice->login(ltype);
00542 act("CLI: login type set to %s",optarg);
00543 break;
00544
00545 case 'p':
00546 if(!outch) {
00547 error("invalid command line argument: server password");
00548 error("you must specify a codec first with the -e option");
00549 break;
00550 }
00551 if(!iceid) {
00552 error("invalid command line argument: server password");
00553 error("you must specify a server first with the -s option");
00554 break;
00555 }
00556 ice = outch->get_ice(iceid);
00557 ice->pass(optarg);
00558 act("CLI: stream password set");
00559 break;
00560
00561 case 'm':
00562 if(!outch) {
00563 error("invalid command line argument: server mountpoint");
00564 error("you must specify a codec first with the -e option");
00565 break;
00566 }
00567 if(!iceid) {
00568 error("invalid command line argument: server mountpoint");
00569 error("you must specify a server first with the -s option");
00570 break;
00571 }
00572 ice = outch->get_ice(iceid);
00573 ice->mount(optarg);
00574 act("CLI: stream mountpoint %s",ice->mount());
00575 break;
00576
00577 case 'n':
00578 if(!outch) {
00579 error("invalid command line argument: stream name");
00580 error("you must specify a codec first with the -e option");
00581 break;
00582 }
00583 if(!iceid) {
00584 error("invalid command line argument: stream name");
00585 error("you must specify a server first with the -s option");
00586 break;
00587 }
00588 ice = outch->get_ice(iceid);
00589 ice->name(optarg);
00590 act("CLI: stream descriptive name: %s",ice->name());
00591 break;
00592
00593 case 'u':
00594 if(!outch) {
00595 error("CLI: invalid command line argument: stream url");
00596 error("you must specify a codec first with the -e option");
00597 break;
00598 }
00599 if(!iceid) {
00600 error("CLI: invalid command line argument: stream url");
00601 error("you must specify a server first with the -s option");
00602 break;
00603 }
00604 ice = outch->get_ice(iceid);
00605 ice->url(optarg);
00606 act("CLI: stream descriptive: url %s",ice->url());
00607 break;
00608
00609 case 'd':
00610 if(!outch) {
00611 error("CLI: invalid command line argument: stream description");
00612 error("you must specify a codec first with the -e option");
00613 break;
00614 }
00615 if(!iceid) {
00616 error("CLI: invalid command line argument: stream description");
00617 error("you must specify a server first with the -s option");
00618 break;
00619 }
00620 ice = outch->get_ice(iceid);
00621 ice->desc(optarg);
00622 act("CLI: stream description: %s",ice->desc());
00623 break;
00624
00625 case 1:
00626 act("CLI: queue %s on channel %i",optarg,number);
00627 if(!mix->chan[number])
00628 if(!mix->create_channel(number)) {
00629 error("CLI: can't create channel %i",number);
00630 break;
00631 } else {
00632 notice("CLI: created channel %i",number);
00633 mix->set_playmode(number,playmode);
00634 }
00635 if(!mix->add_to_playlist(number,optarg))
00636 error("CLI: can't add %s to channel %1",optarg,number);
00637 break;
00638
00639 default:
00640 break;
00641 }
00642 } while(res > 0);
00643 return true;
00644 }
00645
00646 bool check_config() {
00647
00648
00649 char temp[MAX_PATH_SIZE];
00650 char *home = getenv("HOME");
00651 sprintf(temp,"%s/.muse",home);
00652 mkdir(temp,0744);
00653 return(true);
00654 }
00655
00656 int main(int argc, char **argv) {
00657
00658 notice(version,PACKAGE,VERSION);
00659 act("by Denis \"jaromil\" Rojo http://rastasoft.org");
00660 act("--");
00661
00662
00663 if (signal (SIGINT, quitproc) == SIG_ERR) {
00664 error ("Couldn't install SIGINT handler"); exit (0);
00665 }
00666
00667 if (signal (SIGQUIT, quitproc) == SIG_ERR) {
00668 error ("Couldn't install SIGQUIT handler"); exit (0);
00669 }
00670
00671 if (signal (SIGTERM, quitproc) == SIG_ERR) {
00672 error ("Couldn't install SIGTERM handler"); exit (0);
00673 }
00674 got_sigpipe = false;
00675 if (signal (SIGPIPE, fsigpipe) == SIG_ERR) {
00676 error ("Couldn't install SIGPIPE handler"); exit (0);
00677 }
00678
00679 mix = new Stream_mixer();
00680 #ifdef HAVE_SCHEDULER
00681 rscheduler = new Scheduler_xml( sched_file_path() );
00682 mix->register_sched( rscheduler );
00683 rscheduler->register_mixer(mix);
00684 rscheduler->lock();
00685 rscheduler->start();
00686 rscheduler->wait();
00687 rscheduler->unlock();
00688
00689 #endif
00690
00691 if( !take_args(argc, argv) ) goto QUIT;
00692
00693 check_config();
00694
00695
00696 mix->set_live(micrec);
00697 mix->set_lineout(dspout);
00698
00699
00700
00701
00702
00703
00704 if(thegui==GTK1 || thegui==GTK2)
00705 if(!getenv("DISPLAY")) {
00706 error("DISPLAY not found, falling back to console");
00707 thegui=-1;
00708 }
00709
00710 if(thegui<0) {
00711 if(getenv("DISPLAY")) {
00712 #ifdef GUI_NIGHTOLO
00713 thegui=GTK1;
00714 #elif GUI_NIGHTOLO2
00715 thegui=GTK2;
00716 #endif
00717 }
00718 if(thegui<0) {
00719 #ifdef GUI_RUBIK
00720 thegui = NCURSES;
00721 #else
00722 thegui=CLI;
00723 #endif
00724 }
00725 }
00726
00727 switch(thegui) {
00728 case GTK1:
00729 #ifdef GUI_NIGHTOLO
00730 notice("spawning the GTK-1.2 GUI");
00731 act("by nightolo <night@freaknet.org>");
00732 warning("GTK-1.2 should be upgraded to GTK 2 on your system");
00733 warning("this old version of the interface is much unstable");
00734 gui = new GTK_GUI(argc,argv,mix);
00735 #else
00736 error("the Gtk-1.2 interface is not compiled in");
00737 #endif
00738 break;
00739 case GTK2:
00740 #ifdef GUI_NIGHTOLO2
00741 notice("spawning the GTK-2 GUI");
00742 act("by Antonino \"nightolo\" Radici <night@freaknet.org>");
00743 gui = new GTK2_GUI(argc,argv,mix);
00744 #else
00745 error("the Gtk2 interface is not compiled in");
00746 #endif
00747 break;
00748 case NCURSES:
00749 #ifdef GUI_RUBIK
00750 notice("spawning the NCURSES console user interface");
00751 act("by Luca \"rubik\" Profico <rubik@olografix.org>");
00752
00753 gui = new NCURSES_GUI(argc,argv,mix);
00754 MuseSetLog("muse.log");
00755 #else
00756 error("the ncurses console interface is not compiled in");
00757 #endif
00758 break;
00759 default:
00760 notice("using commandline interface (non interactive)");
00761 thegui=CLI;
00762 }
00763
00764 if(thegui<0) error("no interface selected, this should never happen");
00765
00766 if(thegui!=CLI) {
00767 gui->start();
00768 mix->register_gui(gui);
00769 set_guimsg(gui);
00770 notice("%s version %s",PACKAGE,VERSION);
00771 }
00772
00773
00774 outch = (OutChannel*)mix->outchans.begin();
00775 while(outch) {
00776
00777 if( (outch->icelist.len() == 0)
00778 && !outch->fd) {
00779 error("codec %s [%u] has no server neither filedump configured",
00780 outch->name,outch->id);
00781 mix->delete_enc(outch->id);
00782 error("encoder removed");
00783
00784 } else if(mix->apply_enc( outch->id )) outch->start();
00785
00786 if(!outch) break;
00787 outch = (OutChannel*) outch->next;
00788 }
00789
00790 if(thegui==CLI) {
00791
00792 int c;
00793 for(c=0;c<MAX_CHANNELS;c++)
00794 if(mix->chan[c])
00795 if(!mix->set_channel(c,1))
00796 error("CLI: error in set_channel(%i,1)",c);
00797 else
00798 if(!mix->play_channel(c))
00799 error("CLI: error in play_channel(%i)",c);
00800 else
00801 has_playlist = true;
00802 }
00803
00804 if((!has_playlist && !micrec) && (thegui==CLI)) {
00805 warning("nothing to play, you must specify at least songs or live input");
00806 act("see --help switch for more information");
00807 goto QUIT;
00808 }
00809
00810
00811
00812 while(!mix->quit)
00813 mix->cafudda();
00814
00815
00816
00817 QUIT:
00818 notice("quitting MuSE");
00819
00820 if(thegui!=CLI) gui->quit = true;
00821
00822 set_guimsg(NULL);
00823
00824 #ifdef HAVE_SCHEDULER
00825 rscheduler->stop();
00826 rscheduler->quit = true;
00827 jsleep(0,50);
00828 delete rscheduler; rscheduler = NULL;
00829 #endif
00830 if(mix) {
00831 act("stopping mixer...");
00832
00833
00834 jsleep(0,50);
00835 delete mix;
00836 }
00837
00838 if(thegui!=CLI) {
00839 act("quitting graphic interface");
00840 delete gui;
00841 }
00842
00843 act("cya on http://muse.dyne.org");
00844 MuseCloseLog();
00845 exit(0);
00846 }
00847
00848
00849 void quitproc (int Sig) {
00850 func("received signal %u on process %u",Sig,getpid());
00851 if(thegui!=CLI) gui->quit = true;
00852 mix->quit = true;
00853 }
00854
00855 void fsigpipe (int Sig) {
00856 warning("received signal SIGPIPE (%u) on process %u",Sig,getpid());
00857 got_sigpipe = true;
00858 }