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