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

shouter.cpp

00001 /* MuSE - Multiple Streaming Engine
00002  * Copyright (C) 2000-2003 Denis Rojo aka jaromil <jaromil@dyne.org>
00003  *
00004  * This source code is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU Public License as published 
00006  * by the Free Software Foundation; either version 2 of the License,
00007  * or (at your option) any later version.
00008  *
00009  * This source code is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00012  * Please refer to the GNU Public License for more details.
00013  *
00014  * You should have received a copy of the GNU Public License along with
00015  * this source code; if not, write to:
00016  * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00017  *
00018  * "$Id: shouter.cpp,v 1.5 2004/12/15 18:18:06 jaromil Exp $"
00019  *
00020  */
00021 
00022 #include <shouter.h>
00023 #include <jutils.h>
00024 #include <generic.h>
00025 #include <config.h>
00026 
00027 extern bool got_sigpipe;
00028 
00029 Shouter::Shouter()
00030   : Entry() {
00031 
00032   /*
00033   int vermaj,vermin,verpat;
00034   shout_version(&vermaj,&vermin,&verpat);
00035   func("Shouter::Shouter() using libshout version %i.%i.%i",vermaj,vermin,verpat);
00036   */
00037 
00038   ice = shout_new();
00039   
00040   //  to do this, more of the code must be changed
00041   //  shout_set_nonblocking(ice,1);
00042 
00043   running = false;
00044   retry = 0;
00045   errors = 0;
00046 
00047   /* setup defaults */
00048   host("localhost");
00049   ip("127.0.0.1");
00050   port(8000);
00051   pass("hackme");
00052   mount("live");
00053   login(SHOUT_PROTOCOL_HTTP); // defaults to icecast 2 login now
00054   name("Streaming with MuSE");
00055   url("http://muse.dyne.org");
00056   desc("Free Software Multiple Streaming Engine");
00057   bps("24000");
00058   freq("22050");
00059   channels("1");
00060 
00061   profile_changed = true;
00062 }
00063 
00064 Shouter::~Shouter() {
00065   func("Shouter::~Shouter");
00066   stop();
00067   shout_free(ice);
00068 }
00069 
00070 bool Shouter::start() {
00071   int res;
00072   char srv[64];
00073   switch(login()) {
00074   case SHOUT_PROTOCOL_HTTP: sprintf(srv,"icecast2"); break;
00075   case SHOUT_PROTOCOL_ICY: sprintf(srv,"shoutcast"); break;
00076   default: sprintf(srv,"icecast 1"); break;
00077   }
00078 
00079   if(shout_get_connected(ice)) {
00080     // if allready connected, reconnect
00081     func("icecast still connected: disconnecting");
00082     shout_close(ice);
00083     shout_sync(ice);
00084   }
00085   
00086   notice("Contacting %s server %s on port %u",srv,host(),port());
00087   
00088   res = shout_open(ice);
00089   func("Shouter::start() shout_open returns %i",res);
00090   shout_sync(ice);
00091   
00092   if(res==SHOUTERR_SUCCESS) {
00093     notice("started streaming on %s",streamurl);
00094     running = true;
00095   } else {
00096     error("shout_open: %s",shout_get_error(ice));
00097     shout_close(ice);
00098     shout_sync(ice);
00099     running = false;
00100   }
00101   
00102   return(running);
00103 }
00104 
00105 bool Shouter::stop() {
00106   if(running) {
00107     notice("closed stream to %s",streamurl);
00108     shout_close(ice);
00109     running = false;
00110   }
00111   return true;
00112 }
00113 
00114 bool Shouter::apply_profile() {
00115   char temp[256];
00116   func("Shouter::apply_profile() on shouter id %i",id);
00117 
00118   bool was_running = running, res = true;
00119   if(was_running) stop();
00120 
00121   if(shout_set_host(ice,host()))
00122     error("shout_set_host: %s",shout_get_error(ice));
00123   
00124   if( shout_set_port(ice,port()) )
00125     error("shout_set_port: %s",shout_get_error(ice));
00126   
00127   if( shout_set_password(ice,pass()) )
00128     error("shout_set_password: %s",shout_get_error(ice));
00129 
00130   // === fixes the format of the mountpoint
00131   if((mount())[0]!='/') {
00132     char tmp[MAX_VALUE_SIZE];
00133     sprintf(tmp,"/%s",mount());
00134     mount(tmp);
00135   }
00136 
00137   // use a .ogg termination on ogg streams
00138   // this fixes stream codec recognization in xmms et al.
00139   if(format == SHOUT_FORMAT_VORBIS)
00140     if(!strstr(mount(),".ogg")) {
00141       char tmp[MAX_VALUE_SIZE];
00142       sprintf(tmp,"%s.ogg",mount());
00143       mount(tmp);
00144     }
00145   
00146 
00147   if( shout_set_mount(ice,mount()) )
00148     error("shout_set_mount: %s",shout_get_error(ice));
00149 
00150   if( shout_set_name(ice,name()) )
00151     error("shout_set_name: %s",shout_get_error(ice));
00152 
00153   if( shout_set_url(ice,url()) )
00154     error("shout_set_url: %s",shout_get_error(ice));
00155 
00156   if( shout_set_description(ice,desc()) )
00157     error("shout_set_description: %s",shout_get_error(ice));
00158 
00159   
00160   //if( shout_set_bitrate(ice,_bps) )
00161   //  error("shout_set_bitrate: %s",shout_get_error(ice));
00162   
00163   if( shout_set_audio_info(ice, SHOUT_AI_BITRATE, bps()) )
00164     error("shout_set_audio_info %s: %s",SHOUT_AI_BITRATE, bps());
00165 
00166   if( shout_set_audio_info(ice, SHOUT_AI_SAMPLERATE, freq()) )
00167     error("shout_set_audio_info %s: %s",SHOUT_AI_SAMPLERATE, freq());
00168   
00169   if( shout_set_audio_info(ice, SHOUT_AI_CHANNELS, channels()) )
00170     error("shout_set_audio_info %s: %s",SHOUT_AI_CHANNELS, channels());
00171 
00172   func("Shouter audio info: %sKbp/s %sHz %s channels %sq",
00173        shout_get_audio_info(ice, SHOUT_AI_BITRATE),
00174        shout_get_audio_info(ice, SHOUT_AI_SAMPLERATE),
00175        shout_get_audio_info(ice, SHOUT_AI_CHANNELS));
00176 
00177   if( shout_set_protocol(ice,login()) )
00178     error("shout_set_protocol %i: %s",login(),shout_get_error(ice));
00179 
00180   if( shout_set_format(ice,format) )
00181     error("shout_set_format: %s",shout_get_error(ice));
00182 
00183   if( shout_set_user(ice,"source") )
00184     error("shout_set_user: %s",shout_get_error(ice));
00185 
00186   snprintf(temp,256,"%s ver. %s",PACKAGE,VERSION);
00187   if( shout_set_agent(ice,temp) )
00188     error("shout_set_agent: %s",shout_get_error(ice));
00189   
00190   snprintf(streamurl,MAX_VALUE_SIZE,
00191            "http://%s:%i%s",host(),port(),mount());
00192   
00193   if(was_running) { res = start(); }
00194   profile_changed = false;
00195   return res; 
00196 }
00197 
00198 int Shouter::send(short int *buf, unsigned int enc) {
00199   int res = 0;
00200   if(!running) return(0);
00201   if(enc<1) return res;
00202 
00203   shout_sync(ice);
00204 
00205   res = shout_send(ice,(unsigned char*) buf, enc);
00206   if(res) {
00207     error("shout_send: %s",shout_get_error(ice));
00208     if (got_sigpipe && (res==SHOUTERR_SOCKET)) {
00209       errors++;
00210       got_sigpipe = false;
00211       if(errors>10) {
00212         res = -2;
00213         errors = 0;
00214       }
00215     } else res = -1;
00216   } else errors = 0;
00217 
00218   return(res);
00219 }

Generated on Thu Dec 16 12:28:21 2004 for MuSE by doxygen1.3