blob: 33ed45d58b8142ed4ebbac2176ad6726e41451da [file] [log] [blame]
Emeric Vigier2f625822012-08-06 11:09:52 -04001// audiotx.
2// A simple and amusing program for testing basic features of ccRTP.
3// Copyright (C) 2001,2002 Federico Montesino <fedemp@altern.org>
4//
5// This program is free software; you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation; either version 2 of the License, or
8// (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program; if not, write to the Free Software
17// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19
20// This is an introductory example file that illustrates basic usage
21// of ccRTP. You will also see a bit on how to use CommonC++ threads and
22// TimerPort.
23
24// I am a transmitter of \mu-law encoded RTP audio packets. In order
25// to hear what I transmit, you should be running my colleague
26// `audiorx'. You can give me the name of a .au file as argument.
27
28#include <cstdio>
29#include <cstdlib>
30// Some consts common to audiotx and audiorx
31#include <audio.h>
32// In order to use ccRTP, the RTP stack of CommonC++, you only need to
33// include ...
34#include <ccrtp/rtp.h>
35
36#ifdef CCXX_NAMESPACES
37using namespace ost;
38using namespace std;
39#endif
40
41/**
42 * @class ccRTP_AudioTransmitter
43 * This is the class that will do almost everything.
44 */
45class ccRTP_AudioTransmitter: public Thread, public TimerPort
46{
47private:
48 // This is the descriptor of the file we will read from
49 // (commonly, /dev/audio or a .au file)
50 int audioinput;
51
52 // If we are sending a .au file
53 bool sendingfile;
54
55 // The aforementioned file will be transmitted through this socket
56 RTPSession *socket;
57
58public:
59 // Constructor. If it is given a file name, this thread will
60 // transmit that file. If it is not, /dev/audio input is
61 // transmitted
62 ccRTP_AudioTransmitter(char *filename=(char *)"") {
63
64 if( !strcmp(filename,"") ) {
65 filename=(char *)"/dev/audio";
66 sendingfile = false;
67 }else{
68 sendingfile = true;
69 }
70
71 audioinput=open(filename,O_RDONLY|O_NDELAY);
72
73 if( audioinput >= 0 ) {
74 cout << "Ready to transmit " << filename << "." <<endl;
75 }else{
76 cout << "I could not open " << filename << "." << endl;
77 exit();
78 }
79
80 socket=NULL;
81 }
82
83 // Destructor.
84 ~ccRTP_AudioTransmitter() {
85 terminate();
86 delete socket;
87 ::close(audioinput);
88 }
89
90 // This method does almost everything.
91 void run(void) {
92 // redefined from Thread.
93
94 // Before using ccRTP you should learn something about other
95 // CommonC++ classes. We need InetHostAddress...
96
97 // Construct loopback address
98 InetHostAddress local_ip;
99 local_ip = "127.0.0.1";
100
101 // Is that correct?
102 if( ! local_ip ){
103 // this is equivalent to `! local_ip.isInetAddress()'
104 cerr << ": IP address is not correct!" << endl;
105 exit();
106 }
107
108 cout << local_ip.getHostname() <<
109 " is going to transmit audio to perself through " <<
110 local_ip << "..." << endl;
111
112 // ____Here comes the real RTP stuff____
113
114 // Construct the RTP socket.
115 socket = new RTPSession(local_ip,TRANSMITTER_BASE);
116
117 // Set up connection
118 socket->setSchedulingTimeout(10000);
119 if( !socket->addDestination(local_ip,RECEIVER_BASE) )
120 cerr << "I could not connect.";
121
122 socket->setPayloadFormat(StaticPayloadFormat(sptPCMU));
123
124 socket->startRunning();
125 cout << "The RTP queue service thread is ";
126 if( socket->isActive() )
127 cout << "active." << endl;
128 else
129 cerr << "not active." << endl;
130
131 cout << "Transmitting " << PACKET_SIZE
132 << " octects long packets "
133 << "every " << PERIOD << " milliseconds..." << endl;
134
135 unsigned char buffer[PACKET_SIZE];
136 int count=PACKET_SIZE;
137
138 // This will be useful for periodic execution
139 TimerPort::setTimer(PERIOD);
140
141 setCancel(cancelImmediate);
142 // This is the main loop, where packets are transmitted.
143 for( int i = 0 ; (!sendingfile || count > 0) ; i++ ) {
144
145 count = ::read(audioinput,buffer,PACKET_SIZE);
146 if( count > 0 ) {
147 // send an RTP packet, providing timestamp,
148 // payload type and payload.
149 socket->putData(PACKET_SIZE*i,buffer,
150 PACKET_SIZE);
151 }
152 cout << "." << flush;
153
154 // Let's wait for the next cycle
155 Thread::sleep(TimerPort::getTimer());
156 TimerPort::incTimer(PERIOD);
157 }
158 cout << endl << "I have got no more data to send. " <<endl;
159 }
160};
161
162int main(int argc, char *argv[])
163{
164 cout << "This is audiotx, a simple test program for ccRTP." << endl;
165 cout << "You should have run audiorx (the server/receiver) before." << endl;
166 cout << "Strike [Enter] when you are fed up. Enjoy!." << endl;
167
168 ccRTP_AudioTransmitter *transmitter;
169
170 // Construct the main thread. It will not run yet.
171 if ( argc == 2 )
172 transmitter = new ccRTP_AudioTransmitter(argv[1]);
173 else
174 transmitter = new ccRTP_AudioTransmitter();
175
176 // Start transmitter thread.
177 transmitter->start();
178
179 cin.get();
180
181 cout << endl << "That's all." << endl;
182
183 delete transmitter;
184
185 exit(0);
186}
187
188/** EMACS **
189 * Local variables:
190 * mode: c++
191 * c-basic-offset: 4
192 * End:
193 */
194
195
196
197