// audiorx.
// A simple and amusing program for testing basic features of ccRTP.
// Copyright (C) 2001,2002  Federico Montesino <fedemp@altern.org>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

// A very simple mu-law encoded audio player.

// This is an introductory example file that illustrates basic usage
// of ccRTP. You will also see a bit on how to use CommonC++ threads and
// TimerPort.

// I am a player of \mu-law encoded RTP audio packets. I
// do not accept any arguments.

#include <cstdio>
#include <cstdlib>
// Some consts common to audiorx and audiotx
#include <audio.h>
// In order to use ccRTP, the RTP stack of CommonC++, you only need to
// include ...
#include <ccrtp/rtp.h>
#include <fcntl.h>

using namespace COMMONCPP_NAMESPACE;
using namespace std;

/**
 * @class ccRTP_AudioReceiver
 * This is the class that will do almost everything.
 */
class ccRTP_AudioReceiver: public Thread, public TimerPort
{
private:
    // This is the file we will write to (/dev/audio)
    int audiooutput;
    // The aforementioned file will be transmitted through this socket
    RTPSession *socket;

public:
    // Constructor
    ccRTP_AudioReceiver() {
        audiooutput=open("/dev/audio",O_WRONLY/*|O_NDELAY*/);

        if( audiooutput > 0 ) {
            cout << "Audio device is ready to play." << endl;
        }else{
            cout << "I could not open /dev/audio " << endl;
            exit();
        }

        socket=NULL;
    }

    // Destructor.
    ~ccRTP_AudioReceiver() {
        terminate();
        delete socket;
        ::close(audiooutput);
    }

    // This method does almost everything.
    void run(void) {
        // redefined from Thread.

        // Before using ccRTP you should learn something about other
        // CommonC++ classes. We need InetHostAddress...

        // Construct loopback address
        InetHostAddress local_ip;
        local_ip = "127.0.0.1";

        // Is that correct?
        if( ! local_ip ) {
        // this is equivalent to `! local_ip.isInetAddress()'
            cerr << ": IP address is not correct!" << endl;
            exit();
        }

        cout << local_ip.getHostname() <<
            " is going to listen to perself through " <<
            local_ip << "..." << endl;

        // ____Here comes the real RTP stuff____

        // Construct the RTP socket
        socket = new RTPSession(local_ip,RECEIVER_BASE,0);

        // Set up receiver's connection
        socket->setSchedulingTimeout(10000);
        if( !socket->addDestination(local_ip,TRANSMITTER_BASE) )
            cerr << "The receiver could not connect.";

        // Let's check the queue (you should read the documentation
        // so that you know what the queue is for).
        socket->startRunning();
        cout << "The RTP queue is ";
        if( socket->isActive() )
            cout << "active." << endl;
        else
            cerr << "not active." << endl;

        cout << "Waiting for audio packets..." << endl;

        // This will be useful for periodic execution.
        TimerPort::setTimer(PERIOD);

        // This is the main loop, where packets are sent and receipt.
        socket->setPayloadFormat(StaticPayloadFormat(sptPCMU));
        for( int i=0 ; true ; i++ ) {
            const AppDataUnit* adu;
            do {
                adu = socket->getData(socket->getFirstTimestamp());
                if ( NULL == adu )
                    Thread::sleep(5);
                else cout << ".";
            }while ( (NULL == adu) || (adu->getSize() <= 0) );


            // This is for buffering some packets at the
            // receiver side, since playing smoothly
            // without any reception buffer is almost
            // impossible.  Try commenting the two lines
            // below, or stop transmission and continue
            // later: you will probably hear noise or
            // cracks.
            if (i==0)
                Thread::sleep(20);

            if(::write(audiooutput,adu->getData(),adu->getSize()) < (ssize_t)adu->getSize())
                break;

            cout << "." << flush;

            // Let's wait for the next cycle
            Thread::sleep(TimerPort::getTimer());
            TimerPort::incTimer(PERIOD);
        }

    } // end of run
};


int main(int argc, char *argv[])
{
    cout << "This is audiorx, a simple test program for ccRTP." << endl;
    cout << "I am waiting for audio packets on port " << RECEIVER_BASE
         << "." << endl;
    cout << "Do you want to hear something? Run audiotx." << endl;
    cout << "Strike [Enter] when you are fed up. Enjoy!." << endl;

    // Construct the main thread.
    ccRTP_AudioReceiver *receiver = new ccRTP_AudioReceiver();

    // Run it.
    receiver->start();

    cin.get();

    cout << endl << "That's all." << endl;

    delete receiver;

    exit(0);
}

/** EMACS **
 * Local variables:
 * mode: c++
 * c-basic-offset: 4
 * End:
 */



