blob: 0eb1ae087d93e0ab1a1084652ca2d15f3a75c726 [file] [log] [blame]
Emeric Vigier2f625822012-08-06 11:09:52 -04001// audiorx.
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// A very simple mu-law encoded audio player.
20
21// This is an introductory example file that illustrates basic usage
22// of ccRTP. You will also see a bit on how to use CommonC++ threads and
23// TimerPort.
24
25// I am a player of \mu-law encoded RTP audio packets. I
26// do not accept any arguments.
27
28#include <cstdio>
29#include <cstdlib>
30// Some consts common to audiorx and audiotx
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
Alexandre Lisionddd731e2014-01-31 11:50:08 -050037using namespace COMMONCPP_NAMESPACE;
Emeric Vigier2f625822012-08-06 11:09:52 -040038using namespace std;
Emeric Vigier2f625822012-08-06 11:09:52 -040039
40/**
41 * @class ccRTP_AudioReceiver
42 * This is the class that will do almost everything.
43 */
44class ccRTP_AudioReceiver: public Thread, public TimerPort
45{
46private:
47 // This is the file we will write to (/dev/audio)
48 int audiooutput;
49 // The aforementioned file will be transmitted through this socket
50 RTPSession *socket;
51
52public:
53 // Constructor
54 ccRTP_AudioReceiver() {
55 audiooutput=open("/dev/audio",O_WRONLY/*|O_NDELAY*/);
56
57 if( audiooutput > 0 ) {
58 cout << "Audio device is ready to play." << endl;
59 }else{
60 cout << "I could not open /dev/audio " << endl;
61 exit();
62 }
63
64 socket=NULL;
65 }
66
67 // Destructor.
68 ~ccRTP_AudioReceiver() {
69 terminate();
70 delete socket;
71 ::close(audiooutput);
72 }
73
74 // This method does almost everything.
75 void run(void) {
76 // redefined from Thread.
77
78 // Before using ccRTP you should learn something about other
79 // CommonC++ classes. We need InetHostAddress...
80
81 // Construct loopback address
82 InetHostAddress local_ip;
83 local_ip = "127.0.0.1";
84
85 // Is that correct?
86 if( ! local_ip ) {
87 // this is equivalent to `! local_ip.isInetAddress()'
88 cerr << ": IP address is not correct!" << endl;
89 exit();
90 }
91
92 cout << local_ip.getHostname() <<
93 " is going to listen to perself through " <<
94 local_ip << "..." << endl;
95
96 // ____Here comes the real RTP stuff____
97
98 // Construct the RTP socket
99 socket = new RTPSession(local_ip,RECEIVER_BASE,0);
100
101 // Set up receiver's connection
102 socket->setSchedulingTimeout(10000);
103 if( !socket->addDestination(local_ip,TRANSMITTER_BASE) )
104 cerr << "The receiver could not connect.";
105
106 // Let's check the queue (you should read the documentation
107 // so that you know what the queue is for).
108 socket->startRunning();
109 cout << "The RTP queue is ";
110 if( socket->isActive() )
111 cout << "active." << endl;
112 else
113 cerr << "not active." << endl;
114
115 cout << "Waiting for audio packets..." << endl;
116
117 // This will be useful for periodic execution.
118 TimerPort::setTimer(PERIOD);
119
Emeric Vigier2f625822012-08-06 11:09:52 -0400120 // This is the main loop, where packets are sent and receipt.
121 socket->setPayloadFormat(StaticPayloadFormat(sptPCMU));
122 for( int i=0 ; true ; i++ ) {
123 const AppDataUnit* adu;
124 do {
125 adu = socket->getData(socket->getFirstTimestamp());
126 if ( NULL == adu )
127 Thread::sleep(5);
128 else cout << ".";
129 }while ( (NULL == adu) || (adu->getSize() <= 0) );
130
131
132 // This is for buffering some packets at the
133 // receiver side, since playing smoothly
134 // without any reception buffer is almost
135 // impossible. Try commenting the two lines
136 // below, or stop transmission and continue
137 // later: you will probably hear noise or
138 // cracks.
139 if (i==0)
140 Thread::sleep(20);
141
142 if(::write(audiooutput,adu->getData(),adu->getSize()) < (ssize_t)adu->getSize())
143 break;
144
145 cout << "." << flush;
146
147 // Let's wait for the next cycle
148 Thread::sleep(TimerPort::getTimer());
149 TimerPort::incTimer(PERIOD);
150 }
151
152 } // end of run
153};
154
155
156int main(int argc, char *argv[])
157{
158 cout << "This is audiorx, a simple test program for ccRTP." << endl;
159 cout << "I am waiting for audio packets on port " << RECEIVER_BASE
160 << "." << endl;
161 cout << "Do you want to hear something? Run audiotx." << endl;
162 cout << "Strike [Enter] when you are fed up. Enjoy!." << endl;
163
164 // Construct the main thread.
165 ccRTP_AudioReceiver *receiver = new ccRTP_AudioReceiver();
166
167 // Run it.
168 receiver->start();
169
170 cin.get();
171
172 cout << endl << "That's all." << endl;
173
174 delete receiver;
175
176 exit(0);
177}
178
179/** EMACS **
180 * Local variables:
181 * mode: c++
182 * c-basic-offset: 4
183 * End:
184 */
185
186
187