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