muse.cpp Source File

Main Page Modules Class Hierarchy Compound List File List Compound Members File Members

# muse.cpp

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