audiotx.cpp

00001 // audiotx. 
00002 // A simple and amusing program for testing basic features of ccRTP.
00003 // Copyright (C) 2001,2002  Federico Montesino <fedemp@altern.org>
00004 //  
00005 // This program is free software; you can redistribute it and/or modify
00006 // it under the terms of the GNU General Public License as published by
00007 // the Free Software Foundation; either version 2 of the License, or
00008 // (at your option) any later version.
00009 //  
00010 // This program is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 // GNU General Public License for more details.
00014 //  
00015 // You should have received a copy of the GNU General Public License
00016 // along with this program; if not, write to the Free Software
00017 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018 
00019 
00020 // This is an introductory example file that illustrates basic usage
00021 // of ccRTP. You will also see a bit on how to use CommonC++ threads and
00022 // TimerPort.
00023 
00024 // I am a transmitter of \mu-law encoded RTP audio packets. In order
00025 // to hear what I transmit, you should be running my colleague
00026 // `audiorx'. You can give me the name of a .au file as argument.
00027 
00028 #include <cstdio>
00029 #include <cstdlib>
00030 // Some consts common to audiotx and audiorx
00031 #include <audio.h>
00032 // In order to use ccRTP, the RTP stack of CommonC++, you only need to
00033 // include ...
00034 #include <ccrtp/rtp.h>
00035 
00036 #ifdef  CCXX_NAMESPACES
00037 using namespace ost;
00038 using namespace std;
00039 #endif
00040 
00045 class ccRTP_AudioTransmitter: public Thread, public TimerPort
00046 {
00047 private:
00048         // This is the descriptor of the file we will read from
00049         // (commonly, /dev/audio or a .au file)
00050         int audioinput;
00051 
00052         // If we are sending a .au file
00053         bool sendingfile;
00054 
00055         // The aforementioned file will be transmitted through this socket
00056         RTPSession *socket;
00057 
00058 public:
00059         // Constructor. If it is given a file name, this thread will
00060         // transmit that file. If it is not, /dev/audio input is
00061         // transmitted
00062         ccRTP_AudioTransmitter(char *filename=""){
00063                 
00064                 if( !strcmp(filename,"") ){
00065                         filename="/dev/audio";
00066                         sendingfile = false;
00067                 }else{
00068                         sendingfile = true;
00069                 }
00070                 
00071                 audioinput=open(filename,O_RDONLY|O_NDELAY);
00072                 
00073                 if( audioinput >= 0 ){
00074                         cout << "Ready to transmit " << filename << "." <<endl;
00075                 }else{
00076                         cout << "I could not open " << filename << "." << endl;
00077                         exit();
00078                 }
00079                 
00080                 socket=NULL;
00081         }
00082 
00083         // Destructor. 
00084         ~ccRTP_AudioTransmitter(){
00085                 terminate();
00086                 delete socket;          
00087                 ::close(audioinput);
00088         }
00089         
00090         // This method does almost everything.
00091         void run(void) {
00092                 // redefined from Thread.
00093                 
00094                 // Before using ccRTP you should learn something about other
00095                 // CommonC++ classes. We need InetHostAddress...
00096                 
00097                 // Construct loopback address
00098                 InetHostAddress local_ip;
00099                 local_ip = "127.0.0.1";
00100                 
00101                 // Is that correct?
00102                 if( ! local_ip ){  
00103                         // this is equivalent to `! local_ip.isInetAddress()'
00104                         cerr << ": IP address is not correct!" << endl;
00105                         exit();
00106                 }
00107                 
00108                 cout << local_ip.getHostname() << 
00109                         " is going to transmit audio to perself through " <<
00110                         local_ip << "..." << endl;
00111                 
00112                 // ____Here comes the real RTP stuff____
00113                 
00114                 // Construct the RTP socket.
00115                 socket = new RTPSession(local_ip,TRANSMITTER_BASE);
00116                 
00117                 // Set up connection
00118                 socket->setSchedulingTimeout(10000);
00119                 if( !socket->addDestination(local_ip,RECEIVER_BASE) )
00120                         cerr << "I could not connect.";
00121                 
00122                 socket->setPayloadFormat(StaticPayloadFormat(sptPCMU));
00123 
00124                 socket->startRunning();
00125                 cout << "The RTP queue service thread is ";
00126                 if( socket->isActive() )
00127                         cout << "active." << endl;
00128                 else
00129                         cerr << "not active." << endl;
00130                 
00131                 cout << "Transmitting " << PACKET_SIZE 
00132                      << " octects long packets "
00133                      << "every " << PERIOD << " milliseconds..." << endl;
00134                 
00135                 unsigned char buffer[PACKET_SIZE];
00136                 int count=PACKET_SIZE;
00137                 
00138                 // This will be useful for periodic execution
00139                 TimerPort::setTimer(PERIOD);
00140                 
00141                 setCancel(cancelImmediate);
00142                 // This is the main loop, where packets are transmitted.
00143                 for( int i = 0 ; (!sendingfile || count > 0) ; i++ ){
00144                         
00145                         count = ::read(audioinput,buffer,PACKET_SIZE);
00146                         if( count > 0 ){                                
00147                                 // send an RTP packet, providing timestamp,
00148                                 // payload type and payload.
00149                                 socket->putData(PACKET_SIZE*i,buffer,
00150                                                 PACKET_SIZE);
00151                         }
00152                         cout << "." << flush;
00153 
00154                         // Let's wait for the next cycle
00155                         Thread::sleep(TimerPort::getTimer());
00156                         TimerPort::incTimer(PERIOD);
00157                 }
00158                 cout << endl << "I have got no more data to send. " <<endl;
00159         }
00160 };
00161 
00162 
00163 
00164 int
00165 main(int argc, char *argv[]){
00166         
00167         cout << "This is audiotx, a simple test program for ccRTP." << endl;
00168         cout << "You should have run audiorx (the server/receiver) before."
00169              << endl;
00170         cout << "Strike [Enter] when you are fed up. Enjoy!." << endl; 
00171 
00172 
00173         ccRTP_AudioTransmitter *transmitter;
00174 
00175         // Construct the main thread. It will not run yet.
00176         if ( argc == 2 )
00177                 transmitter = new ccRTP_AudioTransmitter(argv[1]);
00178         else
00179                 transmitter = new ccRTP_AudioTransmitter();
00180         
00181         // Start transmitter thread.
00182         transmitter->start();
00183         
00184         cin.get();
00185 
00186         cout << endl << "That's all." << endl;
00187 
00188         delete transmitter;
00189 
00190         exit(0);
00191 }
00192 

Generated on Sun Sep 14 20:52:48 2008 for ccRTP by  doxygen 1.4.7