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 #include <fcntl.h>
00036 
00037 using namespace ost;
00038 using namespace std;
00039 
00040 // TODO: a temporary fix....just to allow building on broken platforms...
00041 #ifndef O_NDELAY
00042 #define O_NDELAY 0
00043 #endif
00044 
00049 class ccRTP_AudioTransmitter: public Thread, public TimerPort
00050 {
00051 private:
00052     // This is the descriptor of the file we will read from
00053     // (commonly, /dev/audio or a .au file)
00054     int audioinput;
00055 
00056     // If we are sending a .au file
00057     bool sendingfile;
00058 
00059     // The aforementioned file will be transmitted through this socket
00060     RTPSession *socket;
00061 
00062 public:
00063     // Constructor. If it is given a file name, this thread will
00064     // transmit that file. If it is not, /dev/audio input is
00065     // transmitted
00066     ccRTP_AudioTransmitter(char *filename=(char *)"") {
00067 
00068         if( !strcmp(filename,"") ) {
00069             filename=(char *)"/dev/audio";
00070             sendingfile = false;
00071         }else{
00072             sendingfile = true;
00073         }
00074 
00075         audioinput=open(filename,O_RDONLY|O_NDELAY);
00076 
00077         if( audioinput >= 0 ) {
00078             cout << "Ready to transmit " << filename << "." <<endl;
00079         }else{
00080             cout << "I could not open " << filename << "." << endl;
00081             exit();
00082         }
00083 
00084         socket=NULL;
00085     }
00086 
00087     // Destructor.
00088     ~ccRTP_AudioTransmitter() {
00089         terminate();
00090         delete socket;
00091         ::close(audioinput);
00092     }
00093 
00094     // This method does almost everything.
00095     void run(void) {
00096         // redefined from Thread.
00097 
00098         // Before using ccRTP you should learn something about other
00099         // CommonC++ classes. We need InetHostAddress...
00100 
00101         // Construct loopback address
00102         InetHostAddress local_ip;
00103         local_ip = "127.0.0.1";
00104 
00105         // Is that correct?
00106         if( ! local_ip ){
00107             // this is equivalent to `! local_ip.isInetAddress()'
00108             cerr << ": IP address is not correct!" << endl;
00109             exit();
00110         }
00111 
00112         cout << local_ip.getHostname() <<
00113             " is going to transmit audio to perself through " <<
00114             local_ip << "..." << endl;
00115 
00116         // ____Here comes the real RTP stuff____
00117 
00118         // Construct the RTP socket.
00119         socket = new RTPSession(local_ip,TRANSMITTER_BASE);
00120 
00121         // Set up connection
00122         socket->setSchedulingTimeout(10000);
00123         if( !socket->addDestination(local_ip,RECEIVER_BASE) )
00124             cerr << "I could not connect.";
00125 
00126         socket->setPayloadFormat(StaticPayloadFormat(sptPCMU));
00127 
00128         socket->startRunning();
00129         cout << "The RTP queue service thread is ";
00130         if( socket->isActive() )
00131             cout << "active." << endl;
00132         else
00133             cerr << "not active." << endl;
00134 
00135         cout << "Transmitting " << PACKET_SIZE
00136              << " octects long packets "
00137              << "every " << PERIOD << " milliseconds..." << endl;
00138 
00139         unsigned char buffer[PACKET_SIZE];
00140         int count=PACKET_SIZE;
00141 
00142         // This will be useful for periodic execution
00143         TimerPort::setTimer(PERIOD);
00144 
00145         // This is the main loop, where packets are transmitted.
00146         for( int i = 0 ; (!sendingfile || count > 0) ; i++ ) {
00147 
00148             count = ::read(audioinput,buffer,PACKET_SIZE);
00149             if( count > 0 ) {
00150                 // send an RTP packet, providing timestamp,
00151                 // payload type and payload.
00152                 socket->putData(PACKET_SIZE*i,buffer,
00153                         PACKET_SIZE);
00154             }
00155             cout << "." << flush;
00156 
00157             // Let's wait for the next cycle
00158             Thread::sleep(TimerPort::getTimer());
00159             TimerPort::incTimer(PERIOD);
00160         }
00161         cout << endl << "I have got no more data to send. " <<endl;
00162     }
00163 };
00164 
00165 int 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." << endl;
00169     cout << "Strike [Enter] when you are fed up. Enjoy!." << endl;
00170 
00171     ccRTP_AudioTransmitter *transmitter;
00172 
00173     // Construct the main thread. It will not run yet.
00174     if ( argc == 2 )
00175         transmitter = new ccRTP_AudioTransmitter(argv[1]);
00176     else
00177         transmitter = new ccRTP_AudioTransmitter();
00178 
00179     // Start transmitter thread.
00180     transmitter->start();
00181 
00182     cin.get();
00183 
00184     cout << endl << "That's all." << endl;
00185 
00186     delete transmitter;
00187 
00188     exit(0);
00189 }
00190 

Generated on 14 Aug 2013 for ccRTP by  doxygen 1.4.7