blob: 211954ec2f64ee788c250ad5adb3cd4370089886 [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>
Alexandre Lisionddd731e2014-01-31 11:50:08 -050035#include <fcntl.h>
Emeric Vigier2f625822012-08-06 11:09:52 -040036
Emeric Vigier2f625822012-08-06 11:09:52 -040037using namespace ost;
38using namespace std;
Alexandre Lisionddd731e2014-01-31 11:50:08 -050039
40// TODO: a temporary fix....just to allow building on broken platforms...
41#ifndef O_NDELAY
42#define O_NDELAY 0
Emeric Vigier2f625822012-08-06 11:09:52 -040043#endif
44
45/**
46 * @class ccRTP_AudioTransmitter
47 * This is the class that will do almost everything.
48 */
49class ccRTP_AudioTransmitter: public Thread, public TimerPort
50{
51private:
52 // This is the descriptor of the file we will read from
53 // (commonly, /dev/audio or a .au file)
54 int audioinput;
55
56 // If we are sending a .au file
57 bool sendingfile;
58
59 // The aforementioned file will be transmitted through this socket
60 RTPSession *socket;
61
62public:
63 // Constructor. If it is given a file name, this thread will
64 // transmit that file. If it is not, /dev/audio input is
65 // transmitted
66 ccRTP_AudioTransmitter(char *filename=(char *)"") {
67
68 if( !strcmp(filename,"") ) {
69 filename=(char *)"/dev/audio";
70 sendingfile = false;
71 }else{
72 sendingfile = true;
73 }
74
75 audioinput=open(filename,O_RDONLY|O_NDELAY);
76
77 if( audioinput >= 0 ) {
78 cout << "Ready to transmit " << filename << "." <<endl;
79 }else{
80 cout << "I could not open " << filename << "." << endl;
81 exit();
82 }
83
84 socket=NULL;
85 }
86
87 // Destructor.
88 ~ccRTP_AudioTransmitter() {
89 terminate();
90 delete socket;
91 ::close(audioinput);
92 }
93
94 // This method does almost everything.
95 void run(void) {
96 // redefined from Thread.
97
98 // Before using ccRTP you should learn something about other
99 // CommonC++ classes. We need InetHostAddress...
100
101 // Construct loopback address
102 InetHostAddress local_ip;
103 local_ip = "127.0.0.1";
104
105 // Is that correct?
106 if( ! local_ip ){
107 // this is equivalent to `! local_ip.isInetAddress()'
108 cerr << ": IP address is not correct!" << endl;
109 exit();
110 }
111
112 cout << local_ip.getHostname() <<
113 " is going to transmit audio to perself through " <<
114 local_ip << "..." << endl;
115
116 // ____Here comes the real RTP stuff____
117
118 // Construct the RTP socket.
119 socket = new RTPSession(local_ip,TRANSMITTER_BASE);
120
121 // Set up connection
122 socket->setSchedulingTimeout(10000);
123 if( !socket->addDestination(local_ip,RECEIVER_BASE) )
124 cerr << "I could not connect.";
125
126 socket->setPayloadFormat(StaticPayloadFormat(sptPCMU));
127
128 socket->startRunning();
129 cout << "The RTP queue service thread is ";
130 if( socket->isActive() )
131 cout << "active." << endl;
132 else
133 cerr << "not active." << endl;
134
135 cout << "Transmitting " << PACKET_SIZE
136 << " octects long packets "
137 << "every " << PERIOD << " milliseconds..." << endl;
138
139 unsigned char buffer[PACKET_SIZE];
140 int count=PACKET_SIZE;
141
142 // This will be useful for periodic execution
143 TimerPort::setTimer(PERIOD);
144
Emeric Vigier2f625822012-08-06 11:09:52 -0400145 // This is the main loop, where packets are transmitted.
146 for( int i = 0 ; (!sendingfile || count > 0) ; i++ ) {
147
148 count = ::read(audioinput,buffer,PACKET_SIZE);
149 if( count > 0 ) {
150 // send an RTP packet, providing timestamp,
151 // payload type and payload.
152 socket->putData(PACKET_SIZE*i,buffer,
153 PACKET_SIZE);
154 }
155 cout << "." << flush;
156
157 // Let's wait for the next cycle
158 Thread::sleep(TimerPort::getTimer());
159 TimerPort::incTimer(PERIOD);
160 }
161 cout << endl << "I have got no more data to send. " <<endl;
162 }
163};
164
165int main(int argc, char *argv[])
166{
167 cout << "This is audiotx, a simple test program for ccRTP." << endl;
168 cout << "You should have run audiorx (the server/receiver) before." << endl;
169 cout << "Strike [Enter] when you are fed up. Enjoy!." << endl;
170
171 ccRTP_AudioTransmitter *transmitter;
172
173 // Construct the main thread. It will not run yet.
174 if ( argc == 2 )
175 transmitter = new ccRTP_AudioTransmitter(argv[1]);
176 else
177 transmitter = new ccRTP_AudioTransmitter();
178
179 // Start transmitter thread.
180 transmitter->start();
181
182 cin.get();
183
184 cout << endl << "That's all." << endl;
185
186 delete transmitter;
187
188 exit(0);
189}
190
191/** EMACS **
192 * Local variables:
193 * mode: c++
194 * c-basic-offset: 4
195 * End:
196 */
197
198
199
200