Logo Search packages:      
Sourcecode: jacktrip version File versions  Download package

void UdpDataProtocol::run (  ) [virtual]

Implements the Thread Loop. To start the thread, call start() ( DO NOT CALL run() )

This function creats and binds all the socket and start the connection loop thread.

Implements DataProtocol.

Definition at line 222 of file UdpDataProtocol.cpp.

References bindSocket(), DataProtocol::getAudioPacketSizeInBites(), mAudioPacket, mFullPacket, DataProtocol::mJackTrip, mPeerAddress, mRunMode, DataProtocol::mStopped, mUdpRedundancyFactor, receivePacket(), receivePacketRedundancy(), DataProtocol::RECEIVER, DataProtocol::SENDER, sendPacketRedundancy(), signalWatingTooLong(), and waitForReady().

{
  mStopped = false;
  
  // Creat and bind sockets
  QUdpSocket UdpSocket;
  bindSocket(UdpSocket); // Bind Socket
  QHostAddress PeerAddress;
  PeerAddress = mPeerAddress;

  // Setup Audio Packet buffer 
  size_t audio_packet_size = getAudioPacketSizeInBites();
  //cout << "audio_packet_size: " << audio_packet_size << endl;
  mAudioPacket = new int8_t[audio_packet_size];
  std::memset(mAudioPacket, 0, audio_packet_size); // set buffer to 0
  
  // Setup Full Packet buffer
  int full_packet_size = mJackTrip->getPacketSizeInBytes();
  //cout << "full_packet_size: " << full_packet_size << endl;
  mFullPacket = new int8_t[full_packet_size];
  std::memset(mFullPacket, 0, full_packet_size); // set buffer to 0

  bool timeout = false; // Time out flag for packets that arrive too late
  
  // Put header in first packet
  mJackTrip->putHeaderInPacket(mFullPacket, mAudioPacket);

  // Redundancy Variables
  // (Algorithm explained at the end of this file)
  // ---------------------------------------------
  int full_redundant_packet_size = full_packet_size * mUdpRedundancyFactor;
  int8_t* full_redundant_packet;
  full_redundant_packet = new int8_t[full_redundant_packet_size];
  std::memset(full_redundant_packet, 0, full_redundant_packet_size); // Initialize to 0

  // Set realtime priority (function in jacktrip_globals.h)
  set_crossplatform_realtime_priority();

  // Connect signals and slots for packets arriving too late notifications
  QObject::connect(this, SIGNAL(signalWatingTooLong(int)),
                   this, SLOT(printUdpWaitedTooLong(int)),
                   Qt::QueuedConnection);

  switch ( mRunMode )
  {
  case RECEIVER : {
      //----------------------------------------------------------------------------------- 
      // Wait for the first packet to be ready and obtain address
      // from that packet
      std::cout << "Waiting for Peer..." << std::endl;
      // This blocks waiting for the first packet
      while ( !UdpSocket.hasPendingDatagrams() ) { QThread::msleep(100); }
      int first_packet_size = UdpSocket.pendingDatagramSize();
      // The following line is the same as
      // int8_t* first_packet = new int8_t[first_packet_size];
      // but avoids memory leaks
      std::tr1::shared_ptr<int8_t> first_packet(new int8_t[first_packet_size]);
      receivePacket( UdpSocket, reinterpret_cast<char*>(first_packet.get()), first_packet_size);
      // Check that peer has the same audio settings
      mJackTrip->checkPeerSettings(first_packet.get());
      mJackTrip->parseAudioPacket(mFullPacket, mAudioPacket);
      std::cout << "Received Connection for Peer!" << std::endl;

      // Redundancy Variables
      // --------------------
      // NOTE: These types need to be the same unsigned integer as the sequence
      // number in the header. That way, they wrap around in the "same place"
      uint16_t current_seq_num = 0; // Store current sequence number
      uint16_t last_seq_num = 0;    // Store last package sequence number
      uint16_t newer_seq_num = 0;   // Store newer sequence number

      while ( !mStopped )
      {
        // Timer to report packets arriving too late
        // This QT method gave me a lot of trouble, so I replaced it with my own 'waitForReady'
        // that uses signals and slots and can also report with packets have not
        // arrive for a longer time
        //timeout = UdpSocket.waitForReadyRead(30);
        timeout = waitForReady(UdpSocket, 60000); //60 seconds

        // OLD CODE WITHOUT REDUNDANCY----------------------------------------------------
        /*
        // This is blocking until we get a packet...
        receivePacket( UdpSocket, reinterpret_cast<char*>(mFullPacket), full_packet_size);

        mJackTrip->parseAudioPacket(mFullPacket, mAudioPacket);

        // ...so we want to send the packet to the buffer as soon as we get in from
        // the socket, i.e., non-blocking
        //mRingBuffer->insertSlotNonBlocking(mAudioPacket);
        mJackTrip->writeAudioBuffer(mAudioPacket);
        */
        //----------------------------------------------------------------------------------
        receivePacketRedundancy(UdpSocket,
                               full_redundant_packet,
                               full_redundant_packet_size,
                               full_packet_size,
                               current_seq_num,
                               last_seq_num,
                               newer_seq_num);
      }
      break; }

  case SENDER : {
      //----------------------------------------------------------------------------------- 
      while ( !mStopped )
      {
        // OLD CODE WITHOUT REDUNDANCY -----------------------------------------------------
        /*
        // We block until there's stuff available to read
        mJackTrip->readAudioBuffer( mAudioPacket );
        mJackTrip->putHeaderInPacket(mFullPacket, mAudioPacket);
        // This will send the packet immediately
        //int bytes_sent = sendPacket( reinterpret_cast<char*>(mFullPacket), full_packet_size);
        sendPacket( UdpSocket, PeerAddress, reinterpret_cast<char*>(mFullPacket), full_packet_size);
        */
        //----------------------------------------------------------------------------------
        sendPacketRedundancy(UdpSocket,
                             PeerAddress,
                             full_redundant_packet,
                             full_redundant_packet_size,
                             full_packet_size);
      }
      break; }
  }
}

Here is the call graph for this function:


Generated by  Doxygen 1.6.0   Back to index