[SCM] jacktrip/master: Imported Upstream version 1.1~repack

umlaeute at users.alioth.debian.org umlaeute at users.alioth.debian.org
Sun Jun 28 20:58:41 UTC 2015


The following commit has been merged in the master branch:
commit c666435c5848ef17cabca8bd7f7ad5642171aef8
Author: IOhannes m zmölnig <zmoelnig at umlautQ.umlaeute.mur.at>
Date:   Sun Jun 28 21:44:36 2015 +0200

    Imported Upstream version 1.1~repack

diff --git a/CHANGESLOG.txt b/CHANGESLOG.txt
index 1849861..446e7e5 100644
--- a/CHANGESLOG.txt
+++ b/CHANGESLOG.txt
@@ -1,4 +1,11 @@
 ---
+1.1
+- (added) Support for RtAudio. Jacktrip can now be used without Jack
+- (added) DNS Look-up support, now one machine can have a private IP (but still needs to have UDP ports open)
+- (added) New port to Windows XP and Windows Vista (experimental and not tested for a long time, only when using jacktrip as a library)
+- (added) Multiclient Server (experimental and not exposed in the executable)
+
+---
 1.0.5
 - (added) Compatibility with JamLink boxes (restricted at the moment to 48KHz, 64 buffer size and 1 channel)
 - (added) New port structure that allows the communication between a public server and a local client
diff --git a/INSTALL.txt b/INSTALL.txt
index cc95c0f..81f3d67 100644
--- a/INSTALL.txt
+++ b/INSTALL.txt
@@ -1,69 +1,116 @@
-Jacktrip : Build Instructions for Linux and MacOS X
-
-JackTrip: A System for High-Quality Audio Network Performance over the Internet.
-
----
-MacOS X (10.3.9 or higher) Installation:
-
-If you are installing on MacOS X, a universal binary is provided.  You just need to have JackOSX installed on your machine
-http://www.jackosx.com/
-
-To install (using Terminal): go to bin/ directory and type:
-
-   sudo cp jacktrip /usr/bin/
-   (enter your password when prompted)
-
-   sudo chmod 755 /usr/bin/jacktrip
-   (now you can run jacktrip from any directory using Terminal)
-
-
----
-Dependencies:
-
-You need to have installed the libraries in your system:
-qt4-devel
-jack-audio-connection-kit-devel
-
-If you are using yum (in Fedora 8 or later) you can just install them (as root) with:
-   yum install qt4-devel jack-audio-connection-kit-devel
-
-If you want to build on MacOS X, you need JackOSX
-http://www.jackosx.com/
-and Qt 4.5 or higher. 
-http://trolltech.com/products/qt/
-
-
----
-Build:
-
-If you're on Mac OS X or Fedora Linux and have all the dependencies installed,
-you can build by simply going to the /src directory and typing the following:
-    ./build
-
-
-If the previous script doesn't work on a different Linux flavor, try building
-the Makfiles yourself. You'd need qmake (e.g., on Fedora, this command is called
-qmake-qt4). Then you can build by:
-    qmake jacktrip.pro
-    make release
-
-
-If you want to install install (using Terminal): on the /src directory type:
-
-   sudo cp jacktrip /usr/bin/
-   (enter your password when prompted)
-
-   sudo chmod 755 /usr/bin/jacktrip
-   (now you can run jacktrip from any directory using Terminal)
-
-
----
-Post Configuration
-Detailed instructions at 
-http://ccrma.stanford.edu/groups/soundwire/software/jacktrip/
-
-
----
-Using JackTrip
-Detailed instructions at 
-http://ccrma.stanford.edu/groups/soundwire/software/jacktrip/
+Jacktrip : Build Instructions for Linux and MacOS X
+
+JackTrip: A System for High-Quality Audio Network Performance over the Internet.
+
+---
+MacOS X (10.9 or higher) Installation:
+
+If you are installing on MacOS X, a binary is provided.  You just need to have JackOSX installed on your machine
+http://www.jackosx.com/
+
+To install (using Terminal): go to bin/ directory and type:
+
+   sudo cp jacktrip /usr/bin/
+   (enter your password when prompted)
+
+   sudo chmod 755 /usr/bin/jacktrip
+   (now you can run jacktrip from any directory using Terminal)
+
+
+---
+Dependencies:
+
+You need to have installed the libraries in your system:
+Qt 5.3 or higher
+jack-audio-connection-kit-devel
+
+If you are using yum (in Fedora 8 or later) you can just install them (as root) with:
+   yum install jack-audio-connection-kit-devel
+and install qt from the qt site.
+
+If you want to build on MacOS X, you need JackOSX
+http://www.jackosx.com/
+and Qt 5.3 or higher. 
+
+It is also possible to build without jack, see below.
+
+---
+Build:
+
+If you're on Mac OS X or Fedora Linux and have all the dependencies installed,
+you can build by simply going to the /src directory and typing the following:
+    ./build
+
+If you want to build without Jack support (meaning that you won't need jack installed
+to use the app) type the following:
+   ./build nojack
+
+If the previous script doesn't work on a different Linux flavor, try building
+the Makfiles yourself. You'd need qmake (e.g., on Fedora, this command is called
+qmake-qt4). Then you can build by:
+    qmake jacktrip.pro
+    make release
+
+Or without Jack support:
+   qmake -config nojack jacktrip.pro
+   make release
+
+
+If you want to install install (using Terminal): on the /src directory type:
+
+   sudo cp jacktrip /usr/bin/
+   (enter your password when prompted)
+
+   sudo chmod 755 /usr/bin/jacktrip
+   (now you can run jacktrip from any directory using Terminal)
+
+-----------------------------
+WINDOWS (XP and later) 
+
+Dependencies:
+
+- ASIO4all audio driver is required even with Audio interfaces that support ASIO: www.asio4all.com
+
+Installation:
+
+Simply Run the setup file Jacktrip-1.1.exe, which will unpack Jacktrip in the directory of your choice,
+the default is Program Files/Jacktrip.
+
+The installer also adds the executable Jacktrip.exe in the System32 directory, so that it can be executed
+from a command prompt from any working directory.
+
+This executable (jacktrip.exe) can be found in the bin directory, along with the Dynamic 
+Link Libraries (DLLs) it links to.
+
+
+Building:
+
+The easiest way to build is to download the free Qt Creator IDE from http://qt.nokia.com/products/ 
+
+Make a copy of the src and externals directories into a new directory of your choice, open the jacktrip.pro 
+file in src, and build the project.
+
+You can alternatively download the MinGW (Minimalist GNU for Windows), a Windows port of the GNU
+compiler from http://www.mingw.org/ and use mingw32-make from a command terminal to build the makefile.
+
+Building is not supported with Microsoft Visual Studio Compilers.
+
+Note: compiling with modifications in the .pro file (like adding a new source or header file) requires 
+qmake which is only available in the Qt Creator package.
+
+---
+
+BUILD WARNING 
+
+Always keep the /src and /externals directories under the same directory.
+
+---
+Post Configuration
+Detailed instructions at 
+http://ccrma.stanford.edu/groups/soundwire/software/jacktrip/
+
+
+---
+Using JackTrip
+Detailed instructions at 
+http://ccrma.stanford.edu/groups/soundwire/software/jacktrip/
diff --git a/documentation/documentation.cpp b/documentation/documentation.cpp
index 54908c2..4783844 100644
--- a/documentation/documentation.cpp
+++ b/documentation/documentation.cpp
@@ -61,7 +61,7 @@ It is currently being developed and actively tested at CCRMA by the SoundWIRE gr
 \section install_sec Installation
 
 Download the latest release:
-<a href="https://sourceforge.net/project/showfiles.php?group_id=236811">Download</a>
+<a href="http://code.google.com/p/jacktrip/">Download</a>
 
 Please read the documentation inside the packet to install.
 
diff --git a/jacktrip_doxygen b/jacktrip_doxygen
index 61e6740..8682067 100644
--- a/jacktrip_doxygen
+++ b/jacktrip_doxygen
@@ -282,7 +282,7 @@ EXTRACT_ALL            = YES
 # If the EXTRACT_PRIVATE tag is set to YES all private members of a class 
 # will be included in the documentation.
 
-EXTRACT_PRIVATE        = YES
+EXTRACT_PRIVATE        = NO
 
 # If the EXTRACT_STATIC tag is set to YES all static members of a file 
 # will be included in the documentation.
diff --git a/src/AudioInterface.cpp b/src/AudioInterface.cpp
new file mode 100644
index 0000000..dfea25f
--- /dev/null
+++ b/src/AudioInterface.cpp
@@ -0,0 +1,397 @@
+//*****************************************************************
+/*
+  JackTrip: A System for High-Quality Audio Network Performance
+  over the Internet
+
+  Copyright (c) 2008 Juan-Pablo Caceres, Chris Chafe.
+  SoundWIRE group at CCRMA, Stanford University.
+
+  Permission is hereby granted, free of charge, to any person
+  obtaining a copy of this software and associated documentation
+  files (the "Software"), to deal in the Software without
+  restriction, including without limitation the rights to use,
+  copy, modify, merge, publish, distribute, sublicense, and/or sell
+  copies of the Software, and to permit persons to whom the
+  Software is furnished to do so, subject to the following
+  conditions:
+
+  The above copyright notice and this permission notice shall be
+  included in all copies or substantial portions of the Software.
+
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+  OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+  OTHER DEALINGS IN THE SOFTWARE.
+*/
+//*****************************************************************
+
+/**
+ * \file AudioInterface.cpp
+ * \author Juan-Pablo Caceres
+ * \date July 2009
+ */
+
+#include "AudioInterface.h"
+#include "JackTrip.h"
+#include <iostream>
+#include <cmath>
+
+using std::cout; using std::endl;
+
+//*******************************************************************************
+AudioInterface::AudioInterface(JackTrip* jacktrip,
+                               int NumInChans, int NumOutChans,
+                               audioBitResolutionT AudioBitResolution) :
+mJackTrip(jacktrip),
+mNumInChans(NumInChans), mNumOutChans(NumOutChans),
+mAudioBitResolution(AudioBitResolution*8),
+mBitResolutionMode(AudioBitResolution),
+mSampleRate(gDefaultSampleRate), mBufferSizeInSamples(gDefaultBufferSizeInSamples),
+mInputPacket(NULL), mOutputPacket(NULL)
+{
+  // Set pointer to NULL
+  for (int i = 0; i < mNumInChans; i++) {
+    mInProcessBuffer[i] = NULL;
+  }
+  for (int i = 0; i < mNumOutChans; i++) {
+    mOutProcessBuffer[i] = NULL;
+  }
+}
+
+
+//*******************************************************************************
+AudioInterface::~AudioInterface()
+{
+  delete[] mInputPacket;
+  delete[] mOutputPacket;
+  for (int i = 0; i < mNumInChans; i++) {
+    delete[] mInProcessBuffer[i];
+  }
+
+  for (int i = 0; i < mNumOutChans; i++) {
+    delete[] mOutProcessBuffer[i];
+  }
+}
+
+
+//*******************************************************************************
+void AudioInterface::setup()
+{
+  // Allocate buffer memory to read and write
+  mSizeInBytesPerChannel = getSizeInBytesPerChannel();
+  int size_input  = mSizeInBytesPerChannel * getNumInputChannels();
+  int size_output = mSizeInBytesPerChannel * getNumOutputChannels();
+  mInputPacket = new int8_t[size_input];
+  mOutputPacket = new int8_t[size_output];
+
+  // Initialize and asign memory for ProcessPlugins Buffers
+  mInProcessBuffer.resize(mNumInChans);
+  mOutProcessBuffer.resize(mNumOutChans);
+
+  int nframes = getBufferSizeInSamples();
+  for (int i = 0; i < mNumInChans; i++) {
+    mInProcessBuffer[i] = new sample_t[nframes];
+    // set memory to 0
+    std::memset(mInProcessBuffer[i], 0, sizeof(sample_t) * nframes);
+  }
+  for (int i = 0; i < mNumOutChans; i++) {
+    mOutProcessBuffer[i] = new sample_t[nframes];
+    // set memory to 0
+    std::memset(mOutProcessBuffer[i], 0, sizeof(sample_t) * nframes);
+  }
+}
+
+
+//*******************************************************************************
+size_t AudioInterface::getSizeInBytesPerChannel() const
+{
+  return (getBufferSizeInSamples() * getAudioBitResolution()/8);
+}
+
+
+//*******************************************************************************
+void AudioInterface::callback(QVarLengthArray<sample_t*>& in_buffer,
+                              QVarLengthArray<sample_t*>& out_buffer,
+                              unsigned int n_frames)
+{
+  // Allocate the Process Callback
+  //-------------------------------------------------------------------
+  // 1) First, process incoming packets
+  // ----------------------------------
+  computeProcessFromNetwork(out_buffer, n_frames);
+
+  // 2) Dynamically allocate ProcessPlugin processes
+  // -----------------------------------------------
+  // The processing will be done in order of allocation
+  /// \todo Implement for more than one process plugin, now it just works propertely with one.
+  /// do it chaining outputs to inputs in the buffers. May need a tempo buffer
+  for (int i = 0; i < mNumInChans; i++) {
+    std::memset(mInProcessBuffer[i], 0, sizeof(sample_t) * n_frames);
+    std::memcpy(mInProcessBuffer[i], out_buffer[i], sizeof(sample_t) * n_frames);
+  }
+  for (int i = 0; i < mNumOutChans; i++) {
+    std::memset(mOutProcessBuffer[i], 0, sizeof(sample_t) * n_frames);
+  }
+
+  for (int i = 0; i < mProcessPlugins.size(); i++) {
+    mProcessPlugins[i]->compute(n_frames, mInProcessBuffer.data(), mOutProcessBuffer.data());
+  }
+
+  // 3) Finally, send packets to peer
+  // --------------------------------
+  computeProcessToNetwork(in_buffer, n_frames);
+
+
+  ///************PROTORYPE FOR CELT**************************
+  ///********************************************************
+  /*
+  CELTMode* mode;
+  int* error;
+  mode = celt_mode_create(48000, 2, 64, error);
+  */
+  //celt_mode_create(48000, 2, 64, NULL);
+  //unsigned char* compressed;
+  //CELTEncoder* celtEncoder;
+  //celt_encode_float(celtEncoder, mInBuffer, NULL, compressed, );
+
+  ///********************************************************
+  ///********************************************************
+
+}
+
+
+//*******************************************************************************
+// Before sending and reading to Jack, we have to round to the sample resolution
+// that the program is using. Jack uses 32 bits (gJackBitResolution in globals.h)
+// by default
+void AudioInterface::computeProcessFromNetwork(QVarLengthArray<sample_t*>& out_buffer,
+                                               unsigned int n_frames)
+{
+  /// \todo cast *mInBuffer[i] to the bit resolution
+  // Output Process (from NETWORK to JACK)
+  // ----------------------------------------------------------------
+  // Read Audio buffer from RingBuffer (read from incoming packets)
+  mJackTrip->receiveNetworkPacket( mOutputPacket );
+
+  // Extract separate channels to send to Jack
+  for (int i = 0; i < mNumOutChans; i++) {
+    //--------
+    // This should be faster for 32 bits
+    //std::memcpy(mOutBuffer[i], &mOutputPacket[i*mSizeInBytesPerChannel],
+    //		mSizeInBytesPerChannel);
+    //--------
+    sample_t* tmp_sample = out_buffer[i]; //sample buffer for channel i
+    for (unsigned int j = 0; j < n_frames; j++) {
+      // Change the bit resolution on each sample
+      fromBitToSampleConversion(
+          &mOutputPacket[(i*mSizeInBytesPerChannel) + (j*mBitResolutionMode)],
+          &tmp_sample[j], mBitResolutionMode );
+    }
+  }
+}
+
+
+//*******************************************************************************
+void AudioInterface::computeProcessToNetwork(QVarLengthArray<sample_t*>& in_buffer,
+                                             unsigned int n_frames)
+{
+  // Input Process (from JACK to NETWORK)
+  // ----------------------------------------------------------------
+  // Concatenate  all the channels from jack to form packet
+  for (int i = 0; i < mNumInChans; i++) {
+    //--------
+    // This should be faster for 32 bits
+    //std::memcpy(&mInputPacket[i*mSizeInBytesPerChannel], mInBuffer[i],
+    //		mSizeInBytesPerChannel);
+    //--------
+    sample_t* tmp_sample = in_buffer[i]; //sample buffer for channel i
+    sample_t* tmp_process_sample = mOutProcessBuffer[i]; //sample buffer from the output process
+    sample_t tmp_result;
+    for (unsigned int j = 0; j < n_frames; j++) {
+      // Change the bit resolution on each sample
+      // Add the input jack buffer to the buffer resulting from the output process
+      tmp_result = tmp_sample[j] + tmp_process_sample[j];
+      fromSampleToBitConversion(
+          &tmp_result,
+          &mInputPacket[(i*mSizeInBytesPerChannel) + (j*mBitResolutionMode)],
+          mBitResolutionMode );
+    }
+  }
+  // Send Audio buffer to Network
+  mJackTrip->sendNetworkPacket( mInputPacket );
+}
+
+
+//*******************************************************************************
+// This function quantize from 32 bit to a lower bit resolution
+// 24 bit is not working yet
+void AudioInterface::fromSampleToBitConversion
+    (const sample_t* const input,
+     int8_t* output,
+     const AudioInterface::audioBitResolutionT targetBitResolution)
+{
+  int8_t tmp_8;
+  uint8_t tmp_u8; // unsigned to quantize the remainder in 24bits
+  int16_t tmp_16;
+  sample_t tmp_sample;
+  sample_t tmp_sample16;
+  sample_t tmp_sample8;
+  switch (targetBitResolution)
+    {
+    case BIT8 :
+      // 8bit integer between -128 to 127
+      tmp_sample = floor( (*input) * 128.0 ); // 2^7 = 128.0
+      tmp_8 = static_cast<int8_t>(tmp_sample);
+      std::memcpy(output, &tmp_8, 1); // 8bits = 1 bytes
+      break;
+    case BIT16 :
+      // 16bit integer between -32768 to 32767
+      tmp_sample = floor( (*input) * 32768.0 ); // 2^15 = 32768.0
+      tmp_16 = static_cast<int16_t>(tmp_sample);
+      std::memcpy(output, &tmp_16, 2); // 16bits = 2 bytes
+      break;
+    case BIT24 :
+      // To convert to 24 bits, we first quantize the number to 16bit
+      tmp_sample = (*input) * 32768.0; // 2^15 = 32768.0
+      tmp_sample16 = floor(tmp_sample);
+      tmp_16 = static_cast<int16_t>(tmp_sample16);
+
+      // Then we compute the remainder error, and quantize that part into an 8bit number
+      // Note that this remainder is always positive, so we use an unsigned integer
+      tmp_sample8 = floor ((tmp_sample - tmp_sample16)  //this is a positive number, between 0.0-1.0
+         * 256.0);
+      tmp_u8 = static_cast<uint8_t>(tmp_sample8);
+
+      // Finally, we copy the 16bit number in the first 2 bytes,
+      // and the 8bit number in the third bite
+      std::memcpy(output, &tmp_16, 2); // 16bits = 2 bytes
+      std::memcpy(output+2, &tmp_u8, 1); // 8bits = 1 bytes
+      break;
+    case BIT32 :
+      std::memcpy(output, input, 4); // 32bit = 4 bytes
+      break;
+    }
+}
+
+
+//*******************************************************************************
+void AudioInterface::fromBitToSampleConversion
+    (const int8_t* const input,
+     sample_t* output,
+     const AudioInterface::audioBitResolutionT sourceBitResolution)
+{
+  int8_t tmp_8;
+  uint8_t tmp_u8;
+  int16_t tmp_16;
+  sample_t tmp_sample;
+  sample_t tmp_sample16;
+  sample_t tmp_sample8;
+  switch (sourceBitResolution)
+    {
+    case BIT8 :
+      tmp_8 = *input;
+      tmp_sample = static_cast<sample_t>(tmp_8) / 128.0;
+      std::memcpy(output, &tmp_sample, 4); // 4 bytes
+      break;
+    case BIT16 :
+      tmp_16 = *( reinterpret_cast<const int16_t*>(input) ); // *((int16_t*) input);
+      tmp_sample = static_cast<sample_t>(tmp_16) / 32768.0;
+      std::memcpy(output, &tmp_sample, 4); // 4 bytes
+      break;
+    case BIT24 :
+      // We first extract the 16bit and 8bit number from the 3 bytes
+      tmp_16 = *( reinterpret_cast<const int16_t*>(input) );
+      tmp_u8 = *( reinterpret_cast<const uint8_t*>(input+2) );
+
+      // Then we recover the number
+      tmp_sample16 = static_cast<sample_t>(tmp_16);
+      tmp_sample8 = static_cast<sample_t>(tmp_u8) / 256.0;
+      tmp_sample =  (tmp_sample16 +  tmp_sample8) / 32768.0;
+      std::memcpy(output, &tmp_sample, 4); // 4 bytes
+      break;
+    case BIT32 :
+      std::memcpy(output, input, 4); // 4 bytes
+      break;
+    }
+}
+
+
+//*******************************************************************************
+void AudioInterface::appendProcessPlugin(ProcessPlugin* plugin)
+{
+  /// \todo check that channels in ProcessPlugins are less or same that jack channels
+  if ( plugin->getNumInputs() ) {}
+  mProcessPlugins.append(plugin);
+}
+
+
+//*******************************************************************************
+AudioInterface::samplingRateT AudioInterface::getSampleRateType() const
+{
+  uint32_t rate = getSampleRate();
+
+  if      ( rate == 22050 ) {
+    return AudioInterface::SR22; }
+  else if ( rate == 32000 ) {
+    return AudioInterface::SR32; }
+  else if ( rate == 44100 ) {
+    return AudioInterface::SR44; }
+  else if ( rate == 48000 ) {
+    return AudioInterface::SR48; }
+  else if ( rate == 88200 ) {
+    return AudioInterface::SR88; }
+  else if ( rate == 96000 ) {
+    return AudioInterface::SR96; }
+  else if ( rate == 19200 ) {
+    return AudioInterface::SR192; }
+
+  return AudioInterface::UNDEF;
+}
+
+//*******************************************************************************
+int AudioInterface::getSampleRateFromType(samplingRateT rate_type)
+{
+  int sample_rate = 0;
+  switch (rate_type)
+    {
+    case SR22 :
+      sample_rate = 22050;
+      return sample_rate;
+      break;
+    case SR32 :
+      sample_rate = 32000;
+      return sample_rate;
+      break;
+    case SR44 :
+      sample_rate = 44100;
+      return sample_rate;
+      break;
+    case SR48 :
+      sample_rate = 48000;
+      return sample_rate;
+      break;
+    case SR88 :
+      sample_rate = 88200;
+      return sample_rate;
+      break;
+    case SR96 :
+      sample_rate = 96000;
+      return sample_rate;
+      break;
+    case SR192 :
+      sample_rate = 192000;
+      return sample_rate;
+      break;
+    default:
+      return sample_rate;
+      break;
+    }
+
+  return sample_rate;
+}
+
+
diff --git a/src/AudioInterface.h b/src/AudioInterface.h
new file mode 100644
index 0000000..b35b5cd
--- /dev/null
+++ b/src/AudioInterface.h
@@ -0,0 +1,212 @@
+//*****************************************************************
+/*
+  JackTrip: A System for High-Quality Audio Network Performance
+  over the Internet
+
+  Copyright (c) 2008 Juan-Pablo Caceres, Chris Chafe.
+  SoundWIRE group at CCRMA, Stanford University.
+
+  Permission is hereby granted, free of charge, to any person
+  obtaining a copy of this software and associated documentation
+  files (the "Software"), to deal in the Software without
+  restriction, including without limitation the rights to use,
+  copy, modify, merge, publish, distribute, sublicense, and/or sell
+  copies of the Software, and to permit persons to whom the
+  Software is furnished to do so, subject to the following
+  conditions:
+
+  The above copyright notice and this permission notice shall be
+  included in all copies or substantial portions of the Software.
+
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+  OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+  OTHER DEALINGS IN THE SOFTWARE.
+*/
+//*****************************************************************
+
+/**
+ * \file AudioInterface.h
+ * \author Juan-Pablo Caceres
+ * \date July 2009
+ */
+
+#ifndef __AUDIOINTERFACE_H__
+#define __AUDIOINTERFACE_H__
+
+#include "ProcessPlugin.h"
+#include "jacktrip_types.h"
+
+#include <QVarLengthArray>
+#include <QVector>
+//#include "jacktrip_globals.h"
+
+// Forward declarations
+class JackTrip;
+
+//using namespace JackTripNamespace;
+
+
+/** \brief Base Class that provides an interface with audio
+ */
+class AudioInterface
+{
+public:
+
+  /// \brief Enum for Audio Resolution in bits
+  enum audioBitResolutionT {
+    BIT8  = 1, ///< 8 bits
+    BIT16 = 2, ///< 16 bits (default)
+    BIT24 = 3, ///< 24 bits
+    BIT32 = 4  ///< 32 bits
+          };
+
+  /// \brief Sampling Rates supported by JACK
+  enum samplingRateT {
+    SR22, ///<  22050 Hz
+    SR32, ///<  32000 Hz
+    SR44, ///<  44100 Hz
+    SR48, ///<  48000 Hz
+    SR88, ///<  88200 Hz
+    SR96, ///<  96000 Hz
+    SR192, ///< 192000 Hz
+    UNDEF ///< Undefined
+  };
+
+  /** \brief The class constructor
+   * \param jacktrip Pointer to the JackTrip class that connects all classes (mediator)
+   * \param NumInChans Number of Input Channels
+   * \param NumOutChans Number of Output Channels
+   * \param AudioBitResolution Audio Sample Resolutions in bits
+   */
+  AudioInterface(JackTrip* jacktrip,
+                 int NumInChans, int NumOutChans,
+                 AudioInterface::audioBitResolutionT AudioBitResolution =
+                 AudioInterface::BIT16);
+  /// \brief The class destructor
+  virtual ~AudioInterface();
+
+  /** \brief Setup the client. This function should be called just before
+    *
+    * starting the audio processes, it will setup the audio client with
+    * the class parameters, like Sampling Rate,
+    * Packet Size, Bit Resolution, etc... Sub-classes should also call the parent
+    * method to ensure correct inizialization.
+    */
+  virtual void setup();
+  /// \brief Tell the audio server that we are ready to roll. The
+  /// process-callback will start running. This runs on its own thread.
+  /// \return 0 on success, otherwise a non-zero error code
+  virtual int startProcess() const = 0;
+  /// \brief Stops the process-callback thread
+  /// \return 0 on success, otherwise a non-zero error code
+  virtual int stopProcess() const = 0;
+  /** \brief Process callback. Subclass should call this callback after obtaining the
+    in_buffer and out_buffer pointers.
+    * \param in_buffer Array of input audio samplers for each channel. The user
+    * is reponsible to check that each channel has n_frames samplers
+    * \param in_buffer Array of output audio samplers for each channel. The user
+    * is reponsible to check that each channel has n_frames samplers
+    */
+  virtual void callback(QVarLengthArray<sample_t*>& in_buffer,
+                        QVarLengthArray<sample_t*>& out_buffer,
+                        unsigned int n_frames);
+  /** \brief Append a ProcessPlugin. The order of processing is determined by
+   * the order by which appending is done.
+   * \param plugin a ProcesPlugin smart pointer. Create the object instance
+   * using something like:\n
+   * <tt>std::tr1::shared_ptr<ProcessPluginName> loopback(new ProcessPluginName);</tt>
+   */
+  virtual void appendProcessPlugin(ProcessPlugin* plugin);
+  virtual void connectDefaultPorts() = 0;
+  /** \brief Convert a 32bit number (sample_t) into one of the bit resolution
+   * supported (audioBitResolutionT).
+   *
+   * The result is stored in an int_8 array of the
+   * appropriate size to hold the value. The caller is responsible to allocate
+   * enough space to store the result.
+   */
+  static void fromSampleToBitConversion(const sample_t* const input,
+                                        int8_t* output,
+                                        const AudioInterface::audioBitResolutionT targetBitResolution);
+  /** \brief Convert a audioBitResolutionT bit resolution number into a
+   * 32bit number (sample_t)
+   *
+   * The result is stored in an sample_t array of the
+   * appropriate size to hold the value. The caller is responsible to allocate
+   * enough space to store the result.
+   */
+  static void fromBitToSampleConversion(const int8_t* const input,
+                                        sample_t* output,
+                                        const AudioInterface::audioBitResolutionT sourceBitResolution);
+
+  //--------------SETTERS---------------------------------------------
+  virtual void setNumInputChannels(int nchannels)
+  { mNumInChans = nchannels; }
+  virtual void setNumOutputChannels(int nchannels)
+  { mNumOutChans = nchannels; }
+  virtual void setSampleRate(uint32_t sample_rate)
+  { mSampleRate = sample_rate; }
+  virtual void setBufferSizeInSamples(uint32_t buf_size)
+  { mBufferSizeInSamples = buf_size; }
+  /// \brief Set Client Name to something different that the default (JackTrip)
+  virtual void setClientName(const char* ClientName) = 0;
+  //------------------------------------------------------------------
+
+  //--------------GETTERS---------------------------------------------
+  /// \brief Get Number of Input Channels
+  virtual int getNumInputChannels() const { return mNumInChans; }
+  /// \brief Get Number of Output Channels
+  virtual int getNumOutputChannels() const  { return mNumOutChans; }
+  virtual uint32_t getBufferSizeInSamples() const
+  { return mBufferSizeInSamples; }
+  virtual size_t getSizeInBytesPerChannel() const;
+  /// \brief Get the Jack Server Sampling Rate, in samples/second
+  virtual uint32_t getSampleRate() const
+  { return mSampleRate; }
+  /// \brief Get the Jack Server Sampling Rate Enum Type samplingRateT
+  /// \return  AudioInterface::samplingRateT enum type
+  virtual samplingRateT getSampleRateType() const;
+  /** \brief Get the Audio Bit Resolution, in bits
+   *
+   * This is one of the audioBitResolutionT set in construction
+   */
+  virtual int getAudioBitResolution() const { return mAudioBitResolution; }
+  /** \brief Helper function to get the sample rate (in Hz) for a
+   * JackAudioInterface::samplingRateT
+   * \param rate_type  JackAudioInterface::samplingRateT enum type
+   * \return Sample Rate in Hz
+   */
+  static int getSampleRateFromType(samplingRateT rate_type);
+  //------------------------------------------------------------------
+
+
+private:
+
+  /// \brief Compute the process to receive packets
+  void computeProcessFromNetwork(QVarLengthArray<sample_t*>& out_buffer,
+                                 unsigned int n_frames);
+  /// \brief Compute the process to send packets
+  void computeProcessToNetwork(QVarLengthArray<sample_t*>& in_buffer,
+                               unsigned int n_frames);
+
+  JackTrip* mJackTrip; ///< JackTrip Mediator Class pointer
+  int mNumInChans;///< Number of Input Channels
+  int mNumOutChans; ///<  Number of Output Channels
+  int mAudioBitResolution; ///< Bit resolution in audio samples
+  AudioInterface::audioBitResolutionT mBitResolutionMode; ///< Bit resolution (audioBitResolutionT) mode
+  uint32_t mSampleRate; ///< Sampling Rate
+  uint32_t mBufferSizeInSamples; ///< Buffer size in samples
+  size_t mSizeInBytesPerChannel; ///< Size in bytes per audio channel
+  QVector<ProcessPlugin*> mProcessPlugins; ///< Vector of ProcesPlugin<EM>s</EM>
+  QVarLengthArray<sample_t*> mInProcessBuffer;///< Vector of Input buffers/channel for ProcessPlugin
+  QVarLengthArray<sample_t*> mOutProcessBuffer;///< Vector of Output buffers/channel for ProcessPlugin
+  int8_t* mInputPacket; ///< Packet containing all the channels to read from the RingBuffer
+  int8_t* mOutputPacket;  ///< Packet containing all the channels to send to the RingBuffer
+};
+
+#endif // __AUDIOINTERFACE_H__
diff --git a/src/DataProtocol.h b/src/DataProtocol.h
index 9f9d2bc..53f2790 100644
--- a/src/DataProtocol.h
+++ b/src/DataProtocol.h
@@ -38,14 +38,23 @@
 #ifndef __DATAPROTOCOL_H__
 #define __DATAPROTOCOL_H__
 
-//#include <sys/socket.h> //basic socket definitions
+#ifdef __WIN_32__
+#include <winsock.h>
+#endif
+
+#ifndef __WIN_32__
 #include <netinet/in.h> //sockaddr_in{} and other Internet defns
 #include <arpa/inet.h> //inet(3) functions
 #include <netdb.h>
-#include <tr1/memory> //for shared_ptr
+//#include <tr1/memory> //for shared_ptr
+#endif
+
+#include <iostream>
 
 #include <QThread>
 #include <QHostAddress>
+#include <QMutex>
+#include <QMutexLocker>
 
 class JackTrip; // forward declaration
 
@@ -82,6 +91,8 @@ class JackTrip; // forward declaration
  */
 class DataProtocol : public QThread
 {
+  Q_OBJECT;
+
 public:
 
   //----------ENUMS------------------------------------------
@@ -123,17 +134,20 @@ public:
   virtual void run() = 0;
 
   /// \brief Stops the execution of the Thread
-  virtual void stop() { mStopped = true; };
+  virtual void stop() {
+    QMutexLocker lock(&mMutex);
+    mStopped = true;
+  }
 
   /** \brief Sets the size of the audio part of the packets
    * \param size_bytes Size in bytes
    */
-  void setAudioPacketSize(const size_t size_bytes){ mAudioPacketSize = size_bytes; };
+  void setAudioPacketSize(const size_t size_bytes){ mAudioPacketSize = size_bytes; }
 
   /** \brief Get the size of the audio part of the packets
    * \return size_bytes Size in bytes
    */
-  size_t getAudioPacketSizeInBites() { return(mAudioPacketSize); };
+  size_t getAudioPacketSizeInBites() { return(mAudioPacketSize); }
 
   /** \brief Set the peer address
    * \param peerHostOrIP IPv4 number or host name
@@ -150,12 +164,19 @@ public:
   //virtual void getPeerAddressFromFirstPacket(QHostAddress& peerHostAddress,
   //				     uint16_t& port) = 0;
 
+
+signals:
+
+  void signalError(const char* error_message);
+  void signalReceivedConnectionFromPeer();
+
+
 protected:
 
   /** \brief Get the Run Mode of the object
    * \return SENDER or RECEIVER
    */
-  runModeT getRunMode() const { return mRunMode; };
+  runModeT getRunMode() const { return mRunMode; }
 
   /// Boolean stop the execution of the thread
   volatile bool mStopped;
@@ -163,6 +184,7 @@ protected:
   volatile bool mHasPeerAddress;
   /// Boolean that indicates if a packet was received
   volatile bool mHasPacketsToReceive;
+  QMutex mMutex;
 
 
 private:
diff --git a/src/JackAudioInterface.cpp b/src/JackAudioInterface.cpp
index 5ca3ba3..3c8c0ca 100644
--- a/src/JackAudioInterface.cpp
+++ b/src/JackAudioInterface.cpp
@@ -62,47 +62,38 @@ QMutex JackAudioInterface::sJackMutex;
 
 //*******************************************************************************
 JackAudioInterface::JackAudioInterface(JackTrip* jacktrip,
-				       int NumInChans, int NumOutChans,
-               audioBitResolutionT AudioBitResolution,
-               const char* ClienName) :
-  mNumInChans(NumInChans), mNumOutChans(NumOutChans), 
-  mAudioBitResolution(AudioBitResolution*8), mBitResolutionMode(AudioBitResolution),
-  mClient(NULL),
-  mClientName(ClienName),
-  mJackTrip(jacktrip)
-{
-  //setupClient();
-  //setProcessCallback();
-}
+                                       int NumInChans, int NumOutChans,
+                                       AudioInterface::audioBitResolutionT AudioBitResolution,
+                                       const char* ClienName) :
+AudioInterface(jacktrip,
+               NumInChans, NumOutChans,
+               AudioBitResolution),
+mNumInChans(NumInChans), mNumOutChans(NumOutChans),
+//mAudioBitResolution(AudioBitResolution*8),
+mBitResolutionMode(AudioBitResolution),
+mClient(NULL),
+mClientName(ClienName),
+mJackTrip(jacktrip)
+{}
 
 
 //*******************************************************************************
 JackAudioInterface::~JackAudioInterface()
-{
-  delete[] mInputPacket;
-  delete[] mOutputPacket;
-
-  for (int i = 0; i < mNumInChans; i++) {
-    delete[] mInProcessBuffer[i];
-  }
-
-  for (int i = 0; i < mNumOutChans; i++) {
-    delete[] mOutProcessBuffer[i];
-  }
-}
+{}
 
 
 //*******************************************************************************
 void JackAudioInterface::setup()
 {
   setupClient();
+  AudioInterface::setup();
   setProcessCallback();
 }
 
 
 //*******************************************************************************
 void JackAudioInterface::setupClient()
-{
+{  
   const char* client_name = mClientName;
   const char* server_name = NULL;
   jack_options_t options = JackNoStartServer;
@@ -141,35 +132,12 @@ void JackAudioInterface::setupClient()
   // Create input and output channels
   createChannels();
 
-  // Allocate buffer memory to read and write
-  mSizeInBytesPerChannel = getSizeInBytesPerChannel();
-  int size_input  = mSizeInBytesPerChannel * getNumInputChannels();
-  int size_output = mSizeInBytesPerChannel * getNumOutputChannels();
-  mInputPacket = new int8_t[size_input];
-  mOutputPacket = new int8_t[size_output];
-
   // Buffer size member
   mNumFrames = getBufferSizeInSamples(); 
 
   // Initialize Buffer array to read and write audio
   mInBuffer.resize(mNumInChans);
   mOutBuffer.resize(mNumOutChans);
-
-  // Initialize and asign memory for ProcessPlugins Buffers
-  mInProcessBuffer.resize(mNumInChans);
-  mOutProcessBuffer.resize(mNumOutChans);
-
-  int nframes = getBufferSizeInSamples();
-  for (int i = 0; i < mNumInChans; i++) {
-    mInProcessBuffer[i] = new sample_t[nframes];
-    // set memory to 0
-    std::memset(mInProcessBuffer[i], 0, sizeof(sample_t) * nframes);
-  }
-  for (int i = 0; i < mNumOutChans; i++) {
-    mOutProcessBuffer[i] = new sample_t[nframes];
-    // set memory to 0
-    std::memset(mOutProcessBuffer[i], 0, sizeof(sample_t) * nframes);
-  }
 }
 
 
@@ -208,72 +176,6 @@ uint32_t JackAudioInterface::getSampleRate() const
 
 
 //*******************************************************************************
-JackAudioInterface::samplingRateT JackAudioInterface::getSampleRateType() const
-{
-  uint32_t rate = jack_get_sample_rate(mClient);
-
-  if      ( rate == 22050 ) {
-    return JackAudioInterface::SR22; }
-  else if ( rate == 32000 ) {
-    return JackAudioInterface::SR32; }
-  else if ( rate == 44100 ) {
-    return JackAudioInterface::SR44; }
-  else if ( rate == 48000 ) {
-    return JackAudioInterface::SR48; }
-  else if ( rate == 88200 ) {
-    return JackAudioInterface::SR88; }
-  else if ( rate == 96000 ) {
-    return JackAudioInterface::SR96; }
-  else if ( rate == 19200 ) {
-    return JackAudioInterface::SR192; }
-
-  return JackAudioInterface::UNDEF;
-}
-
-
-//*******************************************************************************
-int JackAudioInterface::getSampleRateFromType(samplingRateT rate_type)
-{
-  int sample_rate = 0;
-  switch (rate_type)
-    {
-    case SR22 :
-      sample_rate = 22050;
-      return sample_rate;
-      break;
-    case SR32 :
-      sample_rate = 32000;
-      return sample_rate;
-      break;
-    case SR44 :
-      sample_rate = 44100;
-      return sample_rate;
-      break;
-    case SR48 :
-      sample_rate = 48000;
-      return sample_rate;
-      break;
-    case SR88 :
-      sample_rate = 88200;
-      return sample_rate;
-      break;
-    case SR96 :
-      sample_rate = 96000;
-      return sample_rate;
-      break;
-    case SR192 :
-      sample_rate = 192000;
-      return sample_rate;
-      break;
-    default:
-      return sample_rate;
-      break;
-    }
-
-  return sample_rate;
-}
-
-//*******************************************************************************
 uint32_t JackAudioInterface::getBufferSizeInSamples() const 
 {
   return jack_get_buffer_size(mClient);
@@ -281,27 +183,6 @@ uint32_t JackAudioInterface::getBufferSizeInSamples() const
 
 
 //*******************************************************************************
-int JackAudioInterface::getAudioBitResolution() const
-{
-  return mAudioBitResolution;
-}
-
-
-//*******************************************************************************
-int JackAudioInterface::getNumInputChannels() const
-{
-  return mNumInChans;
-}
-
-
-//*******************************************************************************
-int JackAudioInterface::getNumOutputChannels() const
-{
-  return mNumOutChans;
-}
-
-
-//*******************************************************************************
 size_t JackAudioInterface::getSizeInBytesPerChannel() const
 {
   return (getBufferSizeInSamples() * getAudioBitResolution()/8);
@@ -345,7 +226,8 @@ int JackAudioInterface::startProcess() const
 int JackAudioInterface::stopProcess() const
 {
   QMutexLocker locker(&sJackMutex);
-  if ( int code = (jack_client_close(mClient)) )
+  int code = (jack_client_close(mClient));
+  if ( code != 0  )
     {
       std::cerr << "Cannot disconnect client" << std::endl;
       return(code);
@@ -364,87 +246,109 @@ void JackAudioInterface::jackShutdown (void*)
 }
 
 
+
 //*******************************************************************************
-/*
-void JackAudioInterface::setRingBuffers
-(const std::tr1::shared_ptr<RingBuffer> InRingBuffer,
- const std::tr1::shared_ptr<RingBuffer> OutRingBuffer)
+int JackAudioInterface::processCallback(jack_nframes_t nframes)
 {
-  mInRingBuffer = InRingBuffer;
-  mOutRingBuffer = OutRingBuffer;
+  // Get input and output buffers from JACK
+  //-------------------------------------------------------------------
+  for (int i = 0; i < mNumInChans; i++) {
+    // Input Ports are READ ONLY
+    mInBuffer[i] = (sample_t*) jack_port_get_buffer(mInPorts[i], nframes);
+  }
+  for (int i = 0; i < mNumOutChans; i++) {
+    // Output Ports are WRITABLE
+    mOutBuffer[i] = (sample_t*) jack_port_get_buffer(mOutPorts[i], nframes);
+  }
+  //-------------------------------------------------------------------
+  // TEST: Loopback
+  // To test, uncomment and send audio to client input. The same audio
+  // should come out as output in the first channel
+  //memcpy (mOutBuffer[0], mInBuffer[0], sizeof(sample_t) * nframes);
+  //memcpy (mOutBuffer[1], mInBuffer[1], sizeof(sample_t) * nframes);
+  //-------------------------------------------------------------------
+
+  AudioInterface::callback(mInBuffer, mOutBuffer, nframes);
+  return 0;
 }
-*/
 
 
 //*******************************************************************************
-// Before sending and reading to Jack, we have to round to the sample resolution
-// that the program is using. Jack uses 32 bits (gJackBitResolution in globals.h)
-// by default
-void JackAudioInterface::computeNetworkProcessFromNetwork()
+int JackAudioInterface::wrapperProcessCallback(jack_nframes_t nframes, void *arg) 
 {
-  /// \todo cast *mInBuffer[i] to the bit resolution
-  //cout << mNumFrames << endl;
-  // Output Process (from NETWORK to JACK)
-  // ----------------------------------------------------------------
-  // Read Audio buffer from RingBuffer (read from incoming packets)
-  //mOutRingBuffer->readSlotNonBlocking( mOutputPacket );
-  mJackTrip->receiveNetworkPacket( mOutputPacket );
-
-  // Extract separate channels to send to Jack
-  for (int i = 0; i < mNumOutChans; i++) {
-    //--------
-    // This should be faster for 32 bits
-    //std::memcpy(mOutBuffer[i], &mOutputPacket[i*mSizeInBytesPerChannel],
-    //		mSizeInBytesPerChannel);
-    //--------
-    sample_t* tmp_sample = mOutBuffer[i]; //sample buffer for channel i
-    for (int j = 0; j < mNumFrames; j++) {
-      //std::memcpy(&tmp_sample[j], &mOutputPacket[(i*mSizeInBytesPerChannel) + (j*4)], 4);
-      // Change the bit resolution on each sample
-      //cout << tmp_sample[j] << endl;
-      fromBitToSampleConversion(&mOutputPacket[(i*mSizeInBytesPerChannel) 
-					       + (j*mBitResolutionMode)],
-				&tmp_sample[j],
-				mBitResolutionMode);
-    }
-  }
+  return static_cast<JackAudioInterface*>(arg)->processCallback(nframes);
 }
 
 
 //*******************************************************************************
-void JackAudioInterface::computeNetworkProcessToNetwork()
+void JackAudioInterface::connectDefaultPorts()
 {
-  // Input Process (from JACK to NETWORK)
-  // ----------------------------------------------------------------
-  // Concatenate  all the channels from jack to form packet
-  for (int i = 0; i < mNumInChans; i++) {  
-    //--------
-    // This should be faster for 32 bits
-    //std::memcpy(&mInputPacket[i*mSizeInBytesPerChannel], mInBuffer[i],
-    //		mSizeInBytesPerChannel);
-    //--------
-    sample_t* tmp_sample = mInBuffer[i]; //sample buffer for channel i
-    sample_t* tmp_process_sample = mOutProcessBuffer[i]; //sample buffer from the output process
-    sample_t tmp_result;
-    for (int j = 0; j < mNumFrames; j++) {
-      //std::memcpy(&tmp_sample[j], &mOutputPacket[(i*mSizeInBytesPerChannel) + (j*4)], 4);
-      // Change the bit resolution on each sample
+  const char** ports;
 
-      // Add the input jack buffer to the buffer resulting from the output process
-      tmp_result = tmp_sample[j] + tmp_process_sample[j];
-      fromSampleToBitConversion(&tmp_result,
-				&mInputPacket[(i*mSizeInBytesPerChannel)
-					      + (j*mBitResolutionMode)],
-				mBitResolutionMode);
+  // Get physical output (capture) ports
+  if ( (ports =
+        jack_get_ports (mClient, NULL, NULL,
+                        JackPortIsPhysical | JackPortIsOutput)) == NULL)
+  {
+    cout << "WARING: Cannot find any physical capture ports" << endl;
+  }
+  else
+  {
+    // Connect capure ports to jacktrip send
+    for (int i = 0; i < mNumInChans; i++)
+    {
+      // Check that we don't run out of capture ports
+      if ( ports[i] != NULL ) {
+        jack_connect(mClient, ports[i], jack_port_name(mInPorts[i]));
+      }
     }
+    std::free(ports);
+  }
+  
+  // Get physical input (playback) ports
+  if ( (ports =
+        jack_get_ports (mClient, NULL, NULL,
+                        JackPortIsPhysical | JackPortIsInput)) == NULL)
+  {
+    cout << "WARING: Cannot find any physical playback ports" << endl;
+  }
+  else 
+  {
+    // Connect playback ports to jacktrip receive
+    for (int i = 0; i < mNumOutChans; i++)
+    {
+      // Check that we don't run out of capture ports
+      if ( ports[i] != NULL ) {
+        jack_connect(mClient, jack_port_name(mOutPorts[i]), ports[i]);
+      }
+    }
+    std::free(ports);
   }
-  // Send Audio buffer to RingBuffer (these goes out as outgoing packets)
-  //mInRingBuffer->insertSlotNonBlocking( mInputPacket );
-  mJackTrip->sendNetworkPacket( mInputPacket );
 }
 
 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+// OLD CODE
+// ==============================================================================
+
 //*******************************************************************************
+/*
 int JackAudioInterface::processCallback(jack_nframes_t nframes)
 {
   // Get input and output buffers from JACK
@@ -495,8 +399,7 @@ int JackAudioInterface::processCallback(jack_nframes_t nframes)
   // 3) Finally, send packets to peer
   // --------------------------------
   computeNetworkProcessToNetwork();
-
-  
+*/
   ///************PROTORYPE FOR CELT**************************
   ///********************************************************
   /*
@@ -508,116 +411,99 @@ int JackAudioInterface::processCallback(jack_nframes_t nframes)
   //unsigned char* compressed;
   //CELTEncoder* celtEncoder;
   //celt_encode_float(celtEncoder, mInBuffer, NULL, compressed, );
-  
+
   ///********************************************************
   ///********************************************************
+//  return 0;
+//}
 
 
 
-  return 0;
-}
-
-
 //*******************************************************************************
-int JackAudioInterface::wrapperProcessCallback(jack_nframes_t nframes, void *arg) 
+/*
+void JackAudioInterface::setRingBuffers
+(const std::tr1::shared_ptr<RingBuffer> InRingBuffer,
+ const std::tr1::shared_ptr<RingBuffer> OutRingBuffer)
 {
-  return static_cast<JackAudioInterface*>(arg)->processCallback(nframes);
+  mInRingBuffer = InRingBuffer;
+  mOutRingBuffer = OutRingBuffer;
 }
+*/
 
 
 //*******************************************************************************
-// This function quantize from 32 bit to a lower bit resolution
-// 24 bit is not working yet
-void JackAudioInterface::fromSampleToBitConversion(const sample_t* const input,
-						   int8_t* output,
-						   const audioBitResolutionT targetBitResolution)
+// Before sending and reading to Jack, we have to round to the sample resolution
+// that the program is using. Jack uses 32 bits (gJackBitResolution in globals.h)
+// by default
+/*
+void JackAudioInterface::computeNetworkProcessFromNetwork()
 {
-  int8_t tmp_8;
-  uint8_t tmp_u8; // unsigned to quantize the remainder in 24bits
-  int16_t tmp_16;
-  sample_t tmp_sample;
-  sample_t tmp_sample16;
-  sample_t tmp_sample8;
-  switch (targetBitResolution)
-    {
-    case BIT8 : 
-      // 8bit integer between -128 to 127
-      tmp_sample = floor( (*input) * 128.0 ); // 2^7 = 128.0
-      tmp_8 = static_cast<int8_t>(tmp_sample);
-      std::memcpy(output, &tmp_8, 1); // 8bits = 1 bytes
-      break;
-    case BIT16 :
-      // 16bit integer between -32768 to 32767
-      tmp_sample = floor( (*input) * 32768.0 ); // 2^15 = 32768.0
-      tmp_16 = static_cast<int16_t>(tmp_sample);
-      std::memcpy(output, &tmp_16, 2); // 16bits = 2 bytes
-      break;
-    case BIT24 :
-      // To convert to 24 bits, we first quantize the number to 16bit
-      tmp_sample = (*input) * 32768.0; // 2^15 = 32768.0
-      tmp_sample16 = floor(tmp_sample);
-      tmp_16 = static_cast<int16_t>(tmp_sample16);
-
-      // Then we compute the remainder error, and quantize that part into an 8bit number
-      // Note that this remainder is always positive, so we use an unsigned integer
-      tmp_sample8 = floor ((tmp_sample - tmp_sample16)  //this is a positive number, between 0.0-1.0
-			   * 256.0);
-      tmp_u8 = static_cast<uint8_t>(tmp_sample8);
-
-      // Finally, we copy the 16bit number in the first 2 bytes,
-      // and the 8bit number in the third bite
-      std::memcpy(output, &tmp_16, 2); // 16bits = 2 bytes
-      std::memcpy(output+2, &tmp_u8, 1); // 8bits = 1 bytes
-      break;
-    case BIT32 :
-      std::memcpy(output, input, 4); // 32bit = 4 bytes
-      break;
+  /// \todo cast *mInBuffer[i] to the bit resolution
+  //cout << mNumFrames << endl;
+  // Output Process (from NETWORK to JACK)
+  // ----------------------------------------------------------------
+  // Read Audio buffer from RingBuffer (read from incoming packets)
+  //mOutRingBuffer->readSlotNonBlocking( mOutputPacket );
+  mJackTrip->receiveNetworkPacket( mOutputPacket );
+
+  // Extract separate channels to send to Jack
+  for (int i = 0; i < mNumOutChans; i++) {
+    //--------
+    // This should be faster for 32 bits
+    //std::memcpy(mOutBuffer[i], &mOutputPacket[i*mSizeInBytesPerChannel],
+    //		mSizeInBytesPerChannel);
+    //--------
+    sample_t* tmp_sample = mOutBuffer[i]; //sample buffer for channel i
+    for (int j = 0; j < mNumFrames; j++) {
+      //std::memcpy(&tmp_sample[j], &mOutputPacket[(i*mSizeInBytesPerChannel) + (j*4)], 4);
+      // Change the bit resolution on each sample
+      //cout << tmp_sample[j] << endl;
+      fromBitToSampleConversion(&mOutputPacket[(i*mSizeInBytesPerChannel)
+                 + (j*mBitResolutionMode)],
+        &tmp_sample[j],
+        mBitResolutionMode);
     }
+  }
 }
-
+*/
 
 //*******************************************************************************
-void JackAudioInterface::fromBitToSampleConversion(const int8_t* const input,
-						   sample_t* output,
-						   const audioBitResolutionT sourceBitResolution)
+/*
+void JackAudioInterface::computeNetworkProcessToNetwork()
 {
-  int8_t tmp_8;
-  uint8_t tmp_u8;
-  int16_t tmp_16;
-  sample_t tmp_sample;
-  sample_t tmp_sample16;
-  sample_t tmp_sample8;
-  switch (sourceBitResolution)
-    {
-    case BIT8 : 
-      tmp_8 = *input;
-      tmp_sample = static_cast<sample_t>(tmp_8) / 128.0;
-      std::memcpy(output, &tmp_sample, 4); // 4 bytes
-      break;
-    case BIT16 :
-      tmp_16 = *( reinterpret_cast<const int16_t*>(input) ); // *((int16_t*) input);
-      tmp_sample = static_cast<sample_t>(tmp_16) / 32768.0;
-      std::memcpy(output, &tmp_sample, 4); // 4 bytes
-      break;
-    case BIT24 :
-      // We first extract the 16bit and 8bit number from the 3 bytes
-      tmp_16 = *( reinterpret_cast<const int16_t*>(input) );
-      tmp_u8 = *( reinterpret_cast<const uint8_t*>(input+2) );
-
-      // Then we recover the number
-      tmp_sample16 = static_cast<sample_t>(tmp_16);
-      tmp_sample8 = static_cast<sample_t>(tmp_u8) / 256.0;
-      tmp_sample =  (tmp_sample16 +  tmp_sample8) / 32768.0;
-      std::memcpy(output, &tmp_sample, 4); // 4 bytes
-      break;
-    case BIT32 :
-      std::memcpy(output, input, 4); // 4 bytes
-      break;
+  // Input Process (from JACK to NETWORK)
+  // ----------------------------------------------------------------
+  // Concatenate  all the channels from jack to form packet
+  for (int i = 0; i < mNumInChans; i++) {
+    //--------
+    // This should be faster for 32 bits
+    //std::memcpy(&mInputPacket[i*mSizeInBytesPerChannel], mInBuffer[i],
+    //		mSizeInBytesPerChannel);
+    //--------
+    sample_t* tmp_sample = mInBuffer[i]; //sample buffer for channel i
+    sample_t* tmp_process_sample = mOutProcessBuffer[i]; //sample buffer from the output process
+    sample_t tmp_result;
+    for (int j = 0; j < mNumFrames; j++) {
+      //std::memcpy(&tmp_sample[j], &mOutputPacket[(i*mSizeInBytesPerChannel) + (j*4)], 4);
+      // Change the bit resolution on each sample
+
+      // Add the input jack buffer to the buffer resulting from the output process
+      tmp_result = tmp_sample[j] + tmp_process_sample[j];
+      fromSampleToBitConversion(&tmp_result,
+        &mInputPacket[(i*mSizeInBytesPerChannel)
+                + (j*mBitResolutionMode)],
+        mBitResolutionMode);
     }
+  }
+  // Send Audio buffer to RingBuffer (these goes out as outgoing packets)
+  //mInRingBuffer->insertSlotNonBlocking( mInputPacket );
+  mJackTrip->sendNetworkPacket( mInputPacket );
 }
+*/
 
 
 //*******************************************************************************
+/*
 //void JackAudioInterface::appendProcessPlugin(const std::tr1::shared_ptr<ProcessPlugin> plugin)
 void JackAudioInterface::appendProcessPlugin(ProcessPlugin* plugin)
 {
@@ -625,51 +511,4 @@ void JackAudioInterface::appendProcessPlugin(ProcessPlugin* plugin)
   if ( plugin->getNumInputs() ) {}
   mProcessPlugins.append(plugin);
 }
-
-
-
-//*******************************************************************************
-void JackAudioInterface::connectDefaultPorts()
-{
-  const char** ports;
-
-  // Get physical output (capture) ports
-  if ( (ports =
-       jack_get_ports (mClient, NULL, NULL,
-		       JackPortIsPhysical | JackPortIsOutput)) == NULL)
-    {
-      cout << "WARING: Cannot find any physical capture ports" << endl;
-    }
-  else
-    {
-      // Connect capure ports to jacktrip send
-      for (int i = 0; i < mNumInChans; i++) 
-	{
-	  // Check that we don't run out of capture ports
-	  if ( ports[i] != NULL ) {
-	    jack_connect(mClient, ports[i], jack_port_name(mInPorts[i]));
-	  }
-	}
-      std::free(ports);
-    }
-  
-  // Get physical input (playback) ports
-  if ( (ports =
-	jack_get_ports (mClient, NULL, NULL,
-		       JackPortIsPhysical | JackPortIsInput)) == NULL)
-    {
-      cout << "WARING: Cannot find any physical playback ports" << endl;
-    }
-  else 
-    {
-      // Connect playback ports to jacktrip receive
-      for (int i = 0; i < mNumOutChans; i++) 
-	{
-	  // Check that we don't run out of capture ports
-	  if ( ports[i] != NULL ) {
-	    jack_connect(mClient, jack_port_name(mOutPorts[i]), ports[i]);
-	  }
-	}
-      std::free(ports);
-    }
-}
+*/
diff --git a/src/JackAudioInterface.h b/src/JackAudioInterface.h
index 2b01ff2..39ddd0c 100644
--- a/src/JackAudioInterface.h
+++ b/src/JackAudioInterface.h
@@ -40,7 +40,7 @@
 #define __JACKAUDIOINTERFACE_H__
 
 #include <iostream>
-#include <tr1/memory> //for shared_ptr
+//#include <tr1/memory> //for shared_ptr
 #include <functional> //for mem_fun_ref
 #include <jack/jack.h>
 
@@ -51,8 +51,9 @@
 
 #include "jacktrip_types.h"
 #include "ProcessPlugin.h"
+#include "AudioInterface.h"
 
-class JackTrip; //forward declaration
+//class JackTrip; //forward declaration
 
 
 /** \brief Class that provides an interface with the Jack Audio Server
@@ -60,31 +61,10 @@ class JackTrip; //forward declaration
  * \todo implement srate_callback
  * \todo automatically starts jack with buffer and sample rate settings specified by the user
  */
-class JackAudioInterface
+class JackAudioInterface : public AudioInterface
 {
 public:
 
-  /// \brief Enum for Audio Resolution in bits
-  /// \todo implement this into the class, now it's using jack default of 32 bits
-  enum audioBitResolutionT {
-    BIT8  = 1, ///< 8 bits
-    BIT16 = 2, ///< 16 bits (default)
-    BIT24 = 3, ///< 24 bits
-    BIT32 = 4  ///< 32 bits
-  };
-  
-  /// \brief Sampling Rates supported by JACK
-  enum samplingRateT {
-    SR22, ///<  22050 Hz
-    SR32, ///<  32000 Hz
-    SR44, ///<  44100 Hz
-    SR48, ///<  48000 Hz
-    SR88, ///<  88200 Hz
-    SR96, ///<  96000 Hz
-    SR192, ///< 192000 Hz
-    UNDEF ///< Undefined
-  };
-
   /** \brief The class constructor
    * \param jacktrip Pointer to the JackTrip class that connects all classes (mediator)
    * \param NumInChans Number of Input Channels
@@ -93,123 +73,47 @@ public:
    * \param ClientName Client name in Jack
    */
   JackAudioInterface(JackTrip* jacktrip,
-		     int NumInChans, int NumOutChans,
-         audioBitResolutionT AudioBitResolution = BIT16,
-         const char* ClientName = "JackTrip");
-
-  /** \brief The class destructor
-   */
+                     int NumInChans, int NumOutChans,
+                     AudioInterface::audioBitResolutionT AudioBitResolution = AudioInterface::BIT16,
+                     const char* ClientName = "JackTrip");
+  /// \brief The class destructor
   virtual ~JackAudioInterface();
 
-  /** \brief Setup the client
-   */
-  void setup();
-
-  /** \brief Get the Jack Server Sampling Rate, in samples/second
-   */
-  uint32_t getSampleRate() const;
-
-  /** \brief Get the Jack Server Sampling Rate Enum Type samplingRateT
-   * \return  JackAudioInterface::samplingRateT enum type
-   */
-  samplingRateT getSampleRateType() const;
-
-  /** \brief Helper function to get the sample rate (in Hz) for a
-   * JackAudioInterface::samplingRateT
-   * \param rate_type  JackAudioInterface::samplingRateT enum type
-   * \return Sample Rate in Hz
-   */
-  static int getSampleRateFromType(samplingRateT rate_type);
-
-  /** \brief Get the Jack Server Buffer Size, in samples
-   */
-  uint32_t getBufferSizeInSamples() const;
-
-  /** \brief Get the Jack Server Buffer Size, in bytes
-   */
-  uint32_t getBufferSizeInBytes() const 
-  { 
-    return (getBufferSizeInSamples() * getAudioBitResolution()/8);
-  }
-  
-  /** \brief Get the Audio Bit Resolution, in bits
-   *
-   * This is one of the audioBitResolutionT set in construction
-   */
-  int getAudioBitResolution() const;
-
-  /// \brief Get Number of Input Channels
-  int getNumInputChannels() const;
-
-  /// \brief Get Number of Output Channels
-  int getNumOutputChannels() const;
-
-  /// \brief Get size of each audio per channel, in bytes
-  size_t getSizeInBytesPerChannel() const;
-
+  /// \brief Setup the client
+  virtual void setup();
   /** \brief Tell the JACK server that we are ready to roll. The
    * process-callback will start running. This runs on its own thread.
    * \return 0 on success, otherwise a non-zero error code
    */
-  int startProcess() const;
-
+  virtual int startProcess() const;
   /** \brief Stops the process-callback thread
    * \return 0 on success, otherwise a non-zero error code
    */
-  int stopProcess() const;
-
-  /** \brief Set the pointer to the Input and Output RingBuffer
-   * that'll be use to read and write audio
-   *
-   * These RingBuffer<EM>s</EM> are used to read and write audio samples on 
-   * each JACK callback.
-   * \todo If the RingBuffer is blocked, the callback should stay
-   * on the last buffer, as in JackTrip (wavetable synth) 
-   * \param InRingBuffer RingBuffer to read samples <B>from</B>
-   * \param OutRingBuffer RingBuffer to write samples <B>to</B>
-   */
-  /*
-  void setRingBuffers(const std::tr1::shared_ptr<RingBuffer> InRingBuffer,
-		      const std::tr1::shared_ptr<RingBuffer> OutRingBuffer);
-  */
-
-  /** \brief Append a ProcessPlugin. The order of processing is determined by
-   * the order by which appending is done.
-   * \param plugin a ProcesPlugin smart pointer. Create the object instance
-   * using something like:\n
-   * <tt>std::tr1::shared_ptr<ProcessPluginName> loopback(new ProcessPluginName);</tt>
-   */
-  //void appendProcessPlugin(const std::tr1::shared_ptr<ProcessPlugin> plugin);
-  void appendProcessPlugin(ProcessPlugin* plugin);
-
-  /** \brief Convert a 32bit number (sample_t) into one of the bit resolution
-   * supported (audioBitResolutionT).
-   *
-   * The result is stored in an int_8 array of the
-   * appropriate size to hold the value. The caller is responsible to allocate 
-   * enough space to store the result.
-   */
-  static void fromSampleToBitConversion(const sample_t* const input,
-					int8_t* output,
-					const audioBitResolutionT targetBitResolution);
-
-  /** \brief Convert a audioBitResolutionT bit resolution number into a 
-   * 32bit number (sample_t)
-   *
-   * The result is stored in an sample_t array of the
-   * appropriate size to hold the value. The caller is responsible to allocate 
-   * enough space to store the result.
-   */
-  static void fromBitToSampleConversion(const int8_t* const input,
-					sample_t* output,
-					const audioBitResolutionT sourceBitResolution);
-
+  virtual int stopProcess() const;
   /// \brief Connect the default ports, capture to sends, and receives to playback
   void connectDefaultPorts();
 
+  //--------------SETTERS---------------------------------------------
   /// \brief Set Client Name to something different that the default (JackTrip)
-  void setClientName(const char* ClientName)
+  virtual void setClientName(const char* ClientName)
   { mClientName = ClientName; }
+  virtual void setSampleRate(uint32_t /*sample_rate*/)
+  { std::cout << "WARING: Setting the Sample Rate in Jack mode has no effect." << std::endl; }
+  virtual void setBufferSizeInSamples(uint32_t /*buf_size*/)
+  { std::cout << "WARING: Setting the Sample Rate in Jack mode has no effect." << std::endl; }
+  //------------------------------------------------------------------
+
+  //--------------GETTERS---------------------------------------------
+  /// \brief Get the Jack Server Sampling Rate, in samples/second
+  virtual uint32_t getSampleRate() const;
+  /// \brief Get the Jack Server Buffer Size, in samples
+  virtual uint32_t getBufferSizeInSamples() const;
+  /// \brief Get the Jack Server Buffer Size, in bytes
+  virtual uint32_t getBufferSizeInBytes() const
+  { return (getBufferSizeInSamples() * getAudioBitResolution()/8); }
+  /// \brief Get size of each audio per channel, in bytes
+  virtual size_t getSizeInBytesPerChannel() const;
+  //------------------------------------------------------------------
 
 private:
 
@@ -222,30 +126,16 @@ private:
    *  - Creates the appropriate number of input and output channels
    */
   void setupClient();
-
-  /** \brief Creates input and output channels in the Jack client
-   */
+  /// \brief Creates input and output channels in the Jack client
   void createChannels();
- 
   /** \brief JACK calls this shutdown_callback if the server ever shuts down or
    * decides to disconnect the client.
    */
   static void jackShutdown(void*);
-  
-  /// \brief Sets the part of the process callback that sends and receive packets
-  //void computeNetworkProcess();
-
-  /// \brief Compute the process to receive packets to JACK
-  void computeNetworkProcessFromNetwork();
-
-  /// \brief Compute the process from JACK to send packets
-  void computeNetworkProcessToNetwork();
-
   /** \brief Set the process callback of the member function processCallback.
    * This process will be called by the JACK server whenever there is work to be done.
    */
   void setProcessCallback();
-
   /** \brief JACK process callback
    * 
    * This is the function to be called to process audio. This function is 
@@ -257,7 +147,6 @@ private:
    * for more details
    */
   int processCallback(jack_nframes_t nframes);
-  
   /** \brief Wrapper to cast the member processCallback to a static function pointer
    * that can be used with <tt>jack_set_process_callback</tt>
    *
@@ -272,32 +161,21 @@ private:
   // reference : http://article.gmane.org/gmane.comp.audio.jackit/12873
   static int wrapperProcessCallback(jack_nframes_t nframes, void *arg) ;
 
-
   int mNumInChans;///< Number of Input Channels
   int mNumOutChans; ///<  Number of Output Channels
   int mNumFrames; ///< Buffer block size, in samples
-  int mAudioBitResolution; ///< Bit resolution in audio samples
-  audioBitResolutionT mBitResolutionMode; ///< Bit resolution (audioBitResolutionT) mode
+  //int mAudioBitResolution; ///< Bit resolution in audio samples
+  AudioInterface::audioBitResolutionT mBitResolutionMode; ///< Bit resolution (audioBitResolutionT) mode
 
   jack_client_t* mClient; ///< Jack Client
   const char* mClientName; ///< Jack Client Name
   QVarLengthArray<jack_port_t*> mInPorts; ///< Vector of Input Ports (Channels)
   QVarLengthArray<jack_port_t*> mOutPorts; ///< Vector of Output Ports (Channels)
-  //jack_port_t** mInPorts; ///< Vector of Input Ports (Channels)
-  //jack_port_t** mOutPorts; ///< Vector of Output Ports (Channels)
   QVarLengthArray<sample_t*> mInBuffer; ///< Vector of Input buffers/channel read from JACK
   QVarLengthArray<sample_t*> mOutBuffer; ///< Vector of Output buffer/channel to write to JACK
-
-  QVarLengthArray<sample_t*> mInProcessBuffer;///< Vector of Input buffers/channel for ProcessPlugin
-  QVarLengthArray<sample_t*> mOutProcessBuffer;///< Vector of Output buffers/channel for ProcessPlugin
-
-  int8_t* mInputPacket; ///< Packet containing all the channels to read from the RingBuffer
-  int8_t* mOutputPacket;  ///< Packet containing all the channels to send to the RingBuffer
   size_t mSizeInBytesPerChannel; ///< Size in bytes per audio channel
-
   QVector<ProcessPlugin*> mProcessPlugins; ///< Vector of ProcesPlugin<EM>s</EM>
   JackTrip* mJackTrip; ///< JackTrip mediator class
-
   static QMutex sJackMutex; ///< Mutex to make thread safe jack functions that are not
 };
 
diff --git a/src/JackTrip.cpp b/src/JackTrip.cpp
index 6384504..0ae9f39 100644
--- a/src/JackTrip.cpp
+++ b/src/JackTrip.cpp
@@ -39,6 +39,10 @@
 #include "UdpDataProtocol.h"
 #include "RingBufferWavetable.h"
 #include "jacktrip_globals.h"
+#include "JackAudioInterface.h"
+#ifdef __RT_AUDIO__
+#include "RtAudioInterface.h"
+#endif
 
 #include <iostream>
 //#include <unistd.h> // for usleep, sleep
@@ -47,10 +51,18 @@
 
 #include <QHostAddress>
 #include <QThread>
+#include <QTcpSocket>
 
 using std::cout; using std::endl;
 
-
+//the following function has to remain outside the Jacktrip class definition
+//its purpose is to close the app when control c is hit by the user in rtaudio/asio4all mode
+#if defined __WIN_32__
+void sigint_handler(int sig)
+    {
+     exit(0);
+    }
+#endif
 
 //*******************************************************************************
 JackTrip::JackTrip(jacktripModeT JacktripMode,
@@ -58,7 +70,7 @@ JackTrip::JackTrip(jacktripModeT JacktripMode,
        int NumChans,
        int BufferQueueLength,
        unsigned int redundancy,
-       JackAudioInterface::audioBitResolutionT AudioBitResolution,
+       AudioInterface::audioBitResolutionT AudioBitResolution,
        DataProtocol::packetHeaderTypeT PacketHeaderType,
        underrunModeT UnderRunMode,
        int receiver_bind_port, int sender_bind_port,
@@ -66,14 +78,15 @@ JackTrip::JackTrip(jacktripModeT JacktripMode,
   mJackTripMode(JacktripMode),
   mDataProtocol(DataProtocolType),
   mPacketHeaderType(PacketHeaderType),
+  mAudiointerfaceMode(JackTrip::JACK),
   mNumChans(NumChans),
   mBufferQueueLength(BufferQueueLength),
-  mSampleRate(0),
-  mAudioBufferSize(0),
+  mSampleRate(gDefaultSampleRate),
+  mAudioBufferSize(gDefaultBufferSizeInSamples),
   mAudioBitResolution(AudioBitResolution),
   mDataProtocolSender(NULL),
   mDataProtocolReceiver(NULL),
-  mJackAudio(NULL),
+  mAudioInterface(NULL),
   mPacketHeader(NULL),
   mUnderRunMode(UnderRunMode),
   mSendRingBuffer(NULL),
@@ -82,17 +95,25 @@ JackTrip::JackTrip(jacktripModeT JacktripMode,
   mSenderPeerPort(sender_peer_port),
   mSenderBindPort(sender_bind_port),
   mReceiverPeerPort(receiver_peer_port),
+  mTcpServerPort(4464),
   mRedundancy(redundancy),
-  mJackClientName("JackTrip")
-{}
+  mJackClientName("JackTrip"),
+  mConnectionMode(JackTrip::NORMAL),
+  mReceivedConnection(false),
+  mTcpConnectionError(false),
+  mStopped(false)
+{
+  createHeader(mPacketHeaderType);
+}
 
 
 //*******************************************************************************
 JackTrip::~JackTrip()
 {
+  wait();
   delete mDataProtocolSender;
   delete mDataProtocolReceiver;
-  delete mJackAudio;
+  delete mAudioInterface;
   delete mPacketHeader;
   delete mSendRingBuffer;
   delete mReceiveRingBuffer;
@@ -100,28 +121,70 @@ JackTrip::~JackTrip()
 
 
 //*******************************************************************************
-void JackTrip::setupJackAudio()
+void JackTrip::setupAudio()
 {
-  // Create JackAudioInterface Client Object
-  mJackAudio = new JackAudioInterface(this, mNumChans, mNumChans, mAudioBitResolution);
-  mJackAudio->setClientName(mJackClientName);
-  mJackAudio->setup();
-  mSampleRate = mJackAudio->getSampleRate();
+  // Check if mAudioInterface has already been created or not
+  if (mAudioInterface != NULL)  { // if it has been created, disconnet it from JACK and delete it
+    cout << "WARINING: JackAudio interface was setup already:" << endl;
+    cout << "It will be errased and setup again." << endl;
+    cout << gPrintSeparator << endl;
+    closeAudio();
+  }
+
+  // Create AudioInterface Client Object
+  if ( mAudiointerfaceMode == JackTrip::JACK ) {
+#ifndef __NO_JACK__
+    mAudioInterface = new JackAudioInterface(this, mNumChans, mNumChans, mAudioBitResolution);
+    mAudioInterface->setClientName(mJackClientName);
+    mAudioInterface->setup();
+    mSampleRate = mAudioInterface->getSampleRate();
+    mAudioBufferSize = mAudioInterface->getBufferSizeInSamples();
+#endif //__NON_JACK__
+#ifdef __NO_JACK__ /// \todo FIX THIS REPETITION OF CODE
+#ifdef __RT_AUDIO__
+    cout << "Warning: using non jack version, RtAudio will be used instead" << endl;
+    mAudioInterface = new RtAudioInterface(this, mNumChans, mNumChans, mAudioBitResolution);
+    mAudioInterface->setSampleRate(mSampleRate);
+    mAudioInterface->setBufferSizeInSamples(mAudioBufferSize);
+    mAudioInterface->setup();
+#endif
+#endif
+  }
+  else if ( mAudiointerfaceMode == JackTrip::RTAUDIO ) {
+#ifdef __RT_AUDIO__
+    mAudioInterface = new RtAudioInterface(this, mNumChans, mNumChans, mAudioBitResolution);
+    mAudioInterface->setSampleRate(mSampleRate);
+    mAudioInterface->setBufferSizeInSamples(mAudioBufferSize);
+    mAudioInterface->setup();
+#endif
+  }
+
   std::cout << "The Sampling Rate is: " << mSampleRate << std::endl;
   std::cout << gPrintSeparator << std::endl;
-  mAudioBufferSize = mJackAudio->getBufferSizeInSamples();
   int AudioBufferSizeInBytes = mAudioBufferSize*sizeof(sample_t);
   std::cout << "The Audio Buffer Size is: " << mAudioBufferSize << " samples" << std::endl;
-  std::cout << "                      or: " << AudioBufferSizeInBytes 
-	    << " bytes" << std::endl;
+  std::cout << "                      or: " << AudioBufferSizeInBytes
+      << " bytes" << std::endl;
   std::cout << gPrintSeparator << std::endl;
-  cout << "The Number of Channels is: " << mJackAudio->getNumInputChannels() << endl;
+  cout << "The Number of Channels is: " << mAudioInterface->getNumInputChannels() << endl;
   std::cout << gPrintSeparator << std::endl;
   QThread::usleep(100);
 }
 
 
 //*******************************************************************************
+void JackTrip::closeAudio()
+{
+  //mAudioInterface->close();
+  if ( mAudioInterface != NULL ) {
+    mAudioInterface->stopProcess();
+    delete mAudioInterface;
+    mAudioInterface = NULL;
+  }
+}
+
+
+//*******************************************************************************
 void JackTrip::setupDataProtocol()
 {
   // Create DataProtocol Objects
@@ -150,10 +213,12 @@ void JackTrip::setupDataProtocol()
   }
   
   // Set Audio Packet Size
-  mDataProtocolSender->setAudioPacketSize
-    (mJackAudio->getSizeInBytesPerChannel() * mNumChans);
-  mDataProtocolReceiver->setAudioPacketSize
-    (mJackAudio->getSizeInBytesPerChannel() * mNumChans);
+  //mDataProtocolSender->setAudioPacketSize
+  //  (mAudioInterface->getSizeInBytesPerChannel() * mNumChans);
+  //mDataProtocolReceiver->setAudioPacketSize
+  //  (mAudioInterface->getSizeInBytesPerChannel() * mNumChans);
+  mDataProtocolSender->setAudioPacketSize(getTotalAudioPacketSizeInBytes());
+  mDataProtocolReceiver->setAudioPacketSize(getTotalAudioPacketSizeInBytes());
 }
 
 
@@ -162,19 +227,34 @@ void JackTrip::setupRingBuffers()
 {
   // Create RingBuffers with the apprioprate size
   /// \todo Make all this operations cleaner
+  //int total_audio_packet_size = getTotalAudioPacketSizeInBytes();
+  int slot_size = getRingBuffersSlotSize();
+
   switch (mUnderRunMode) {
   case WAVETABLE:
-    mSendRingBuffer = new RingBufferWavetable(mJackAudio->getSizeInBytesPerChannel() * mNumChans,
-					      gDefaultOutputQueueLength);
-    mReceiveRingBuffer = new RingBufferWavetable(mJackAudio->getSizeInBytesPerChannel() * mNumChans,
-						 mBufferQueueLength);
+    mSendRingBuffer = new RingBufferWavetable(slot_size,
+                                              gDefaultOutputQueueLength);
+    mReceiveRingBuffer = new RingBufferWavetable(slot_size,
+                                                 mBufferQueueLength);
+    /*
+    mSendRingBuffer = new RingBufferWavetable(mAudioInterface->getSizeInBytesPerChannel() * mNumChans,
+                gDefaultOutputQueueLength);
+    mReceiveRingBuffer = new RingBufferWavetable(mAudioInterface->getSizeInBytesPerChannel() * mNumChans,
+             mBufferQueueLength);
+             */
     
     break;
   case ZEROS:
-    mSendRingBuffer = new RingBuffer(mJackAudio->getSizeInBytesPerChannel() * mNumChans,
-				     gDefaultOutputQueueLength);
-    mReceiveRingBuffer = new RingBuffer(mJackAudio->getSizeInBytesPerChannel() * mNumChans,
-					mBufferQueueLength);
+    mSendRingBuffer = new RingBuffer(slot_size,
+                                     gDefaultOutputQueueLength);
+    mReceiveRingBuffer = new RingBuffer(slot_size,
+                                        mBufferQueueLength);
+    /*
+    mSendRingBuffer = new RingBuffer(mAudioInterface->getSizeInBytesPerChannel() * mNumChans,
+             gDefaultOutputQueueLength);
+    mReceiveRingBuffer = new RingBuffer(mAudioInterface->getSizeInBytesPerChannel() * mNumChans,
+          mBufferQueueLength);
+          */
     break;
   default:
     throw std::invalid_argument("Underrun Mode undefined");
@@ -194,48 +274,82 @@ void JackTrip::setPeerAddress(const char* PeerHostOrIP)
 void JackTrip::appendProcessPlugin(ProcessPlugin* plugin)
 {
   mProcessPlugins.append(plugin);
-  //mJackAudio->appendProcessPlugin(plugin);
+  //mAudioInterface->appendProcessPlugin(plugin);
 }
 
 
 //*******************************************************************************
-void JackTrip::start()
-{
+void JackTrip::startProcess() throw(std::invalid_argument)
+{ //signal that catches ctrl c in rtaudio-asio mode
+#if defined (__WIN_32__)
+    if (signal(SIGINT, sigint_handler) == SIG_ERR) {
+          perror("signal");
+            exit(1);
+        }
+#endif
   // Check if ports are already binded by another process on this machine
+  // ------------------------------------------------------------------
   checkIfPortIsBinded(mReceiverBindPort);
   checkIfPortIsBinded(mSenderBindPort);
-
   // Set all classes and parameters
-  setupJackAudio();
+  // ------------------------------
+  setupAudio();
   createHeader(mPacketHeaderType);
   setupDataProtocol();
   setupRingBuffers();
+  // Connect Signals and Slots
+  // -------------------------
+  QObject::connect(mPacketHeader, SIGNAL(signalError(const char*)),
+                   this, SLOT(slotStopProcesses()), Qt::QueuedConnection);
+  QObject::connect(mDataProtocolReceiver, SIGNAL(signalReceivedConnectionFromPeer()),
+                   this, SLOT(slotReceivedConnectionFromPeer()),
+                   Qt::QueuedConnection);
+  QObject::connect(this, SIGNAL(signalUdpTimeOut()),
+                   this, SLOT(slotStopProcesses()), Qt::QueuedConnection);
+
+  //QObject::connect(mDataProtocolSender, SIGNAL(signalError(const char*)),
+  //                 this, SLOT(slotStopProcesses()), Qt::QueuedConnection);
+  //QObject::connect(mDataProtocolReceiver, SIGNAL(signalError(const char*)),
+  //                 this, SLOT(slotStopProcesses()), Qt::QueuedConnection);
 
   // Start the threads for the specific mode
+  // ---------------------------------------
   switch ( mJackTripMode )
-    {
-    case CLIENT :
-      clientStart();
-      break;
-    case SERVER :
-      serverStart();
-      break;
-    case CLIENTTOPINGSERVER :
-      clientPingToServerStart();
-      break;
-    default: 
-      throw std::invalid_argument("Jacktrip Mode  undefined");
-      break;
+  {
+  case CLIENT :
+    clientStart();
+    break;
+  case SERVER :
+    serverStart();
+    break;
+  case CLIENTTOPINGSERVER :
+    if ( clientPingToServerStart() == -1 ) { // if error on server start (-1) we return inmediatly
+      mTcpConnectionError = true;
+      slotStopProcesses();
+      return;
     }
-  
+    break;
+  case SERVERPINGSERVER :
+    if ( serverStart(true) == -1 ) { // if error on server start (-1) we return inmediatly
+      slotStopProcesses();
+      return;
+    }
+    break;
+  default:
+    throw std::invalid_argument("Jacktrip Mode  undefined");
+    break;
+  }
+
   // Start Threads
-  mJackAudio->startProcess();
+  mAudioInterface->startProcess();
+
   for (int i = 0; i < mProcessPlugins.size(); ++i) {
-    mJackAudio->appendProcessPlugin(mProcessPlugins[i]);
+    mAudioInterface->appendProcessPlugin(mProcessPlugins[i]);
   }
-  mJackAudio->connectDefaultPorts();
-  mDataProtocolSender->start();
+  mAudioInterface->connectDefaultPorts();
   mDataProtocolReceiver->start();
+  QThread::msleep(1);
+  mDataProtocolSender->start();
 }
 
 
@@ -250,8 +364,9 @@ void JackTrip::stop()
   mDataProtocolReceiver->stop();
   mDataProtocolReceiver->wait();
 
-  // Stop the jack process callback
-  mJackAudio->stopProcess();
+  // Stop the audio processes
+  //mAudioInterface->stopProcess();
+  closeAudio();
 
   cout << "JackTrip Processes STOPPED!" << endl;
   cout << gPrintSeparator << endl;
@@ -260,8 +375,9 @@ void JackTrip::stop()
   emit signalProcessesStopped();
 }
 
+
 //*******************************************************************************
-void JackTrip::wait()
+void JackTrip::waitThreads()
 {
   mDataProtocolSender->wait();
   mDataProtocolReceiver->wait();
@@ -269,14 +385,13 @@ void JackTrip::wait()
 
 
 //*******************************************************************************
-void JackTrip::clientStart()
+void JackTrip::clientStart() throw(std::invalid_argument)
 {
   // For the Client mode, the peer (or server) address has to be specified by the user
   if ( mPeerAddress.isEmpty() ) {
     throw std::invalid_argument("Peer Address has to be set if you run in CLIENT mode");
   }
   else {
-    // Set the peer address
     mDataProtocolSender->setPeerAddress( mPeerAddress.toLatin1().data() );
     mDataProtocolReceiver->setPeerAddress( mPeerAddress.toLatin1().data() );
     cout << "Peer Address set to: " << mPeerAddress.toStdString() << std::endl;
@@ -286,12 +401,15 @@ void JackTrip::clientStart()
 
 
 //*******************************************************************************
-void JackTrip::serverStart()
+int JackTrip::serverStart(bool timeout, int udpTimeout)
+    throw(std::invalid_argument, std::runtime_error)
 {
   // Set the peer address
   if ( !mPeerAddress.isEmpty() ) {
     std::cout << "WARNING: SERVER mode: Peer Address was set but will be deleted." << endl;
+    //throw std::invalid_argument("Peer Address has to be set if you run in CLIENT mode");
     mPeerAddress.clear();
+    //return;
   }
 
   // Get the client address when it connects
@@ -304,10 +422,29 @@ void JackTrip::serverStart()
   if ( !UdpSockTemp.bind(QHostAddress::Any, mReceiverBindPort,
                          QUdpSocket::DefaultForPlatform) )
   {
+    std::cerr << "in JackTrip: Could not bind UDP socket. It may be already binded." << endl;
     throw std::runtime_error("Could not bind UDP socket. It may be already binded.");
   }
   // Listen to client
-  while ( !UdpSockTemp.hasPendingDatagrams() ) { QThread::usleep(100000); }
+  int sleepTime = 100; // ms
+  int elapsedTime = 0;
+  if (timeout) {
+    while ( (!UdpSockTemp.hasPendingDatagrams()) && (elapsedTime <= udpTimeout) ) {
+      if (mStopped == true) { emit signalUdpTimeOut(); UdpSockTemp.close(); return -1; }
+      QThread::msleep(sleepTime);
+      elapsedTime += sleepTime;
+    }
+    if (!UdpSockTemp.hasPendingDatagrams()) {
+      emit signalUdpTimeOut();
+      cout << "JackTrip Server Timed Out!" << endl;
+      return -1;
+    }
+  } else {
+    while ( !UdpSockTemp.hasPendingDatagrams() ) {
+      if (mStopped == true) { emit signalUdpTimeOut(); return -1; }
+      QThread::msleep(sleepTime);
+    }
+  }
   char buf[1];
   // set client address
   UdpSockTemp.readDatagram(buf, 1, &peerHostAddress, &peer_port);
@@ -321,7 +458,7 @@ void JackTrip::serverStart()
   // Set the peer address to send packets (in the protocol sender)
   mDataProtocolSender->setPeerAddress( mPeerAddress.toLatin1().constData() );
   mDataProtocolReceiver->setPeerAddress( mPeerAddress.toLatin1().constData() );
-  // We reply to the same port the peer sent the packets
+  // We reply to the same port the peer sent the packets from
   // This way we can go through NAT
   // Because of the NAT traversal scheme, the portn need to be
   // "symetric", e.g.:
@@ -330,40 +467,122 @@ void JackTrip::serverStart()
   mDataProtocolSender->setPeerPort(peer_port);
   mDataProtocolReceiver->setPeerPort(peer_port);
   setPeerPorts(peer_port);
+  return 0;
 }
 
+
 //*******************************************************************************
-void JackTrip::clientPingToServerStart()
+int JackTrip::clientPingToServerStart() throw(std::invalid_argument)
 {
+  //mConnectionMode = JackTrip::KSTRONG;
+  //mConnectionMode = JackTrip::JAMTEST;
+
+  // Set Peer (server in this case) address
+  // --------------------------------------
   // For the Client mode, the peer (or server) address has to be specified by the user
   if ( mPeerAddress.isEmpty() ) {
     throw std::invalid_argument("Peer Address has to be set if you run in CLIENTTOPINGSERVER mode");
+    return -1;
+  }
+
+  // Creat Socket Objects
+  // --------------------
+  QTcpSocket tcpClient;
+  QHostAddress serverHostAddress;
+  serverHostAddress.setAddress(mPeerAddress);
+
+  // Connect Socket to Server and wait for response
+  // ----------------------------------------------
+  tcpClient.connectToHost(serverHostAddress, mTcpServerPort);
+  cout << "Connecting to TCP Server..." << endl;
+  if (!tcpClient.waitForConnected()) {
+    std::cerr << "TCP Socket ERROR: " << tcpClient.errorString().toStdString() <<  endl;
+    //std::exit(1);
+    return -1;
+  }
+  cout << "TCP Socket Connected to Server!" << endl;
+  emit signalTcpClientConnected();
+
+  // Send Client Port Number to Server
+  // ---------------------------------
+  char port_buf[sizeof(mReceiverBindPort)];
+  std::memcpy(port_buf, &mReceiverBindPort, sizeof(mReceiverBindPort));
+
+  tcpClient.write(port_buf, sizeof(mReceiverBindPort));
+  while ( tcpClient.bytesToWrite() > 0 ) {
+    tcpClient.waitForBytesWritten(-1);
   }
+  cout << "Port sent to Client" << endl;
+
+  // Read the size of the package
+  // ----------------------------
+  cout << "Reading UDP port from Server..." << endl;
+  while (tcpClient.bytesAvailable() < (int)sizeof(uint16_t)) {
+    if (!tcpClient.waitForReadyRead()) {
+      std::cerr << "TCP Socket ERROR: " << tcpClient.errorString().toStdString() <<  endl;
+      //std::exit(1);
+      return -1;
+    }
+  }
+  cout << "Ready To Read From Socket!" << endl;
+
+  // Read UDP Port Number from Server
+  // --------------------------------
+  uint32_t udp_port;
+  int size = sizeof(udp_port);
+  //char port_buf[size];
+  tcpClient.read(port_buf, size);
+  std::memcpy(&udp_port, port_buf, size);
+  //cout << "Received UDP Port Number: " << udp_port << endl;
+
+  // Close the TCP Socket
+  // --------------------
+  tcpClient.close(); // Close the socket
+  //cout << "TCP Socket Closed!" << endl;
+  cout << "Connection Succesfull!" << endl;
+
+  // Set with the received UDP port
+  // ------------------------------
+  setPeerPorts(udp_port);
+  mDataProtocolReceiver->setPeerAddress( mPeerAddress.toLatin1().data() );
+  mDataProtocolSender->setPeerAddress( mPeerAddress.toLatin1().data() );
+  mDataProtocolSender->setPeerPort(udp_port);
+  mDataProtocolReceiver->setPeerPort(udp_port);
+  cout << "Server Address set to: " << mPeerAddress.toStdString() << " Port: " << udp_port << std::endl;
+  cout << gPrintSeparator << endl;
+  return 0;
+
+  /*
   else {
     // Set the peer address
     mDataProtocolSender->setPeerAddress( mPeerAddress.toLatin1().data() );
   }
 
-  // Start Threads
-  mJackAudio->startProcess();
-  //mJackAudio->connectDefaultPorts();    
+  // Start the Sender Threads
+  // ------------------------
+  mAudioInterface->startProcess();
   mDataProtocolSender->start();
-  //cout << "STARTED DATA PROTOCOL SENDER-----------------------------" << endl;
-  //mDataProtocolReceiver->start();
+  // block until mDataProtocolSender thread starts
+  while ( !mDataProtocolSender->isRunning() ) { QThread::msleep(100); }
 
+  // Create a Socket to listen to Server's answer
+  // --------------------------------------------
   QHostAddress serverHostAddress;
   QUdpSocket UdpSockTemp;// Create socket to wait for server answer
   uint16_t server_port;
 
   // Bind the socket
+  //bindReceiveSocket(UdpSockTemp, mReceiverBindPort,
+  //                  mPeerAddress, peer_port);
   if ( !UdpSockTemp.bind(QHostAddress::Any,
-			 mReceiverBindPort,
-			 QUdpSocket::DefaultForPlatform) ) {
-    throw std::runtime_error("Could not bind UDP socket. It may be already binded.");
+                         mReceiverBindPort,
+                         QUdpSocket::ShareAddress) ) {
+    //throw std::runtime_error("Could not bind PingToServer UDP socket. It may be already binded.");
   }
+
   // Listen to server response
   cout << "Waiting for server response..." << endl;
-  while ( !UdpSockTemp.hasPendingDatagrams() ) { QThread::usleep(100000); }
+  while ( !UdpSockTemp.hasPendingDatagrams() ) { QThread::msleep(100); }
   cout << "Received response from server!" << endl;
   char buf[1];
   // set client address
@@ -373,27 +592,80 @@ void JackTrip::clientPingToServerStart()
   // Stop the sender thread to change server port
   mDataProtocolSender->stop();
   mDataProtocolSender->wait(); // Wait for the thread to terminate
-  /*
-  while ( mDataProtocolSender->isRunning() ) 
-    { 
-      cout << "IS RUNNING!" << endl;
-      QThread::usleep(100000);
-    }
-  */
-  cout << "Server port now set to: " << server_port-1 << endl;  
+
+  cout << "Server port now set to: " << server_port << endl;
   cout << gPrintSeparator << endl;
-  mDataProtocolSender->setPeerPort(server_port-1);
+  mDataProtocolSender->setPeerPort(server_port);
   
   // Start Threads
-  //mJackAudio->connectDefaultPorts();
+  //mAudioInterface->connectDefaultPorts();
   mDataProtocolSender->start();
   mDataProtocolReceiver->start();
+  */
 }
 
 
 //*******************************************************************************
+/*
+void JackTrip::bindReceiveSocket(QUdpSocket& UdpSocket, int bind_port,
+                                 QHostAddress PeerHostAddress, int peer_port)
+throw(std::runtime_error)
+{
+  // Creat socket descriptor
+  int sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
+
+  // Set local IPv4 Address
+  struct sockaddr_in local_addr;
+  ::bzero(&local_addr, sizeof(local_addr));
+  local_addr.sin_family = AF_INET; //AF_INET: IPv4 Protocol
+  local_addr.sin_addr.s_addr = htonl(INADDR_ANY); //INADDR_ANY: let the kernel decide the active address
+  local_addr.sin_port = htons(bind_port); //set bind port
+
+  // Set socket to be reusable, this is platform dependent
+  int one = 1;
+#if defined ( __LINUX__ )
+  ::setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
+#endif
+#if defined ( __MAC_OSX__ )
+  // This option is not avialable on Linux, and without it MAC OS X
+  // has problems rebinding a socket
+  ::setsockopt(sock_fd, SOL_SOCKET, SO_REUSEPORT, &one, sizeof(one));
+#endif
+
+  // Bind the Socket
+  if ( (::bind(sock_fd, (struct sockaddr *) &local_addr, sizeof(local_addr))) < 0 )
+  { throw std::runtime_error("ERROR: UDP Socket Bind Error"); }
+
+  // To be able to use the two UDP sockets bound to the same port number,
+  // we connect the receiver and issue a SHUT_WR.
+  // Set peer IPv4 Address
+  struct sockaddr_in peer_addr;
+  bzero(&peer_addr, sizeof(peer_addr));
+  peer_addr.sin_family = AF_INET; //AF_INET: IPv4 Protocol
+  peer_addr.sin_addr.s_addr = htonl(INADDR_ANY); //INADDR_ANY: let the kernel decide the active address
+  peer_addr.sin_port = htons(peer_port); //set local port
+  // Connect the socket and issue a Write shutdown (to make it a
+  // reader socket only)
+  if ( (::inet_pton(AF_INET, PeerHostAddress.toString().toLatin1().constData(),
+                    &peer_addr.sin_addr)) < 1 )
+  { throw std::runtime_error("ERROR: Invalid address presentation format"); }
+  if ( (::connect(sock_fd, (struct sockaddr *) &peer_addr, sizeof(peer_addr))) < 0)
+  { throw std::runtime_error("ERROR: Could not connect UDP socket"); }
+  if ( (::shutdown(sock_fd,SHUT_WR)) < 0)
+  { throw std::runtime_error("ERROR: Could suntdown SHUT_WR UDP socket"); }
+
+  UdpSocket.setSocketDescriptor(sock_fd, QUdpSocket::ConnectedState,
+                                QUdpSocket::ReadOnly);
+  cout << "UDP Socket Receiving in Port: " << bind_port << endl;
+  cout << gPrintSeparator << endl;
+}
+*/
+
+
+//*******************************************************************************
 void JackTrip::createHeader(const DataProtocol::packetHeaderTypeT headertype)
 {
+  delete mPacketHeader; //Just in case it has already been allocated
   switch (headertype) {
   case DataProtocol::DEFAULT :
     mPacketHeader = new DefaultHeader(this);
@@ -419,17 +691,20 @@ void JackTrip::putHeaderInPacket(int8_t* full_packet, int8_t* audio_packet)
   
   int8_t* audio_part;
   audio_part = full_packet + mPacketHeader->getHeaderSizeInBytes();
-  //std::memcpy(audio_part, audio_packet, mJackAudio->getBufferSizeInBytes());
-  std::memcpy(audio_part, audio_packet, mJackAudio->getSizeInBytesPerChannel() * mNumChans);
+  //std::memcpy(audio_part, audio_packet, mAudioInterface->getBufferSizeInBytes());
+  //std::memcpy(audio_part, audio_packet, mAudioInterface->getSizeInBytesPerChannel() * mNumChans);
+  std::memcpy(audio_part, audio_packet, getTotalAudioPacketSizeInBytes());
 }
 
 
 //*******************************************************************************
-int JackTrip::getPacketSizeInBytes() const
+int JackTrip::getPacketSizeInBytes()
 {
-  //return (mJackAudio->getBufferSizeInBytes() + mPacketHeader->getHeaderSizeInBytes());
-  return (mJackAudio->getSizeInBytesPerChannel() * mNumChans  +
-	  mPacketHeader->getHeaderSizeInBytes());
+  //return (mAudioInterface->getBufferSizeInBytes() + mPacketHeader->getHeaderSizeInBytes());
+  //return (mAudioInterface->getSizeInBytesPerChannel() * mNumChans  +
+  //mPacketHeader->getHeaderSizeInBytes());
+  return (getTotalAudioPacketSizeInBytes()  +
+          mPacketHeader->getHeaderSizeInBytes());
 }
 
 
@@ -438,8 +713,9 @@ void JackTrip::parseAudioPacket(int8_t* full_packet, int8_t* audio_packet)
 {
   int8_t* audio_part;
   audio_part = full_packet + mPacketHeader->getHeaderSizeInBytes();
-  //std::memcpy(audio_packet, audio_part, mJackAudio->getBufferSizeInBytes());
-  std::memcpy(audio_packet, audio_part, mJackAudio->getSizeInBytesPerChannel() * mNumChans);
+  //std::memcpy(audio_packet, audio_part, mAudioInterface->getBufferSizeInBytes());
+  //std::memcpy(audio_packet, audio_part, mAudioInterface->getSizeInBytesPerChannel() * mNumChans);
+  std::memcpy(audio_packet, audio_part, getTotalAudioPacketSizeInBytes());
 }
 
 
diff --git a/src/JackTrip.h b/src/JackTrip.h
index 69576f2..9084290 100644
--- a/src/JackTrip.h
+++ b/src/JackTrip.h
@@ -38,17 +38,24 @@
 #ifndef __JACKTRIP_H__
 #define __JACKTRIP_H__
 
-#include <tr1/memory> //for shared_ptr
+//#include <tr1/memory> //for shared_ptr
+#include <stdexcept>
 
 #include <QObject>
 #include <QString>
+#include <QUdpSocket>
 
 #include "DataProtocol.h"
+#include "AudioInterface.h"
+
+#ifndef __NO_JACK__
 #include "JackAudioInterface.h"
+#endif //__NO_JACK__
+
 #include "PacketHeader.h"
 #include "RingBuffer.h"
 
-
+#include <signal.h>
 /** \brief Main class to creates a SERVER (to listen) or a CLIENT (to connect
  * to a listening server) to send audio streams in the network.
  *
@@ -56,6 +63,7 @@
  * This class also acts as a Mediator between all the other class.
  * Classes that uses JackTrip methods need to register with it.
  */
+
 class JackTrip : public QThread
 {
   Q_OBJECT;
@@ -74,7 +82,8 @@ public:
   enum jacktripModeT {
     SERVER, ///< Run in Server Mode
     CLIENT,  ///< Run in Client Mode
-    CLIENTTOPINGSERVER ///< Client of the Ping Server Mode
+    CLIENTTOPINGSERVER, ///< Client of the Ping Server Mode
+    SERVERPINGSERVER ///< Server of the MultiThreaded JackTrip
   };
 
   /// \brief Enum for the JackTrip Underrun Mode, when packets
@@ -82,6 +91,19 @@ public:
     WAVETABLE, ///< Loops on the last received packet
     ZEROS  ///< Set new buffers to zero if there are no new ones
   };
+
+  /// \brief Enum for Audio Interface Mode
+  enum audiointerfaceModeT {
+    JACK, ///< Jack Mode
+    RTAUDIO  ///< RtAudio Mode
+  };
+
+  /// \brief Enum for Connection Mode (useful for connections to MultiClient Server)
+  enum connectionModeT {
+    NORMAL, ///< Normal Mode
+    KSTRONG,  ///< Karplus Strong
+    JAMTEST  ///< Karplus Strong
+  };
   //---------------------------------------------------------
 
 
@@ -95,11 +117,11 @@ public:
    */
   JackTrip(jacktripModeT JacktripMode = CLIENT,
 	   dataProtocolT DataProtocolType = UDP,
-	   int NumChans = 2,
-	   int BufferQueueLength = 8,
-	   unsigned int redundancy = 1,
-	   JackAudioInterface::audioBitResolutionT AudioBitResolution = 
-	   JackAudioInterface::BIT16,
+     int NumChans = gDefaultNumInChannels,
+     int BufferQueueLength = gDefaultQueueLength,
+     unsigned int redundancy = gDefaultRedundancy,
+     AudioInterface::audioBitResolutionT AudioBitResolution =
+     AudioInterface::BIT16,
 	   DataProtocol::packetHeaderTypeT PacketHeaderType = 
 	   DataProtocol::DEFAULT,
 	   underrunModeT UnderRunMode = WAVETABLE,
@@ -111,63 +133,62 @@ public:
   /// \brief The class destructor
   virtual ~JackTrip();
 
+  /// \brief Starting point for the thread
+  virtual void run() {}
+
   /// \brief Set the Peer Address for jacktripModeT::CLIENT mode only
-  void setPeerAddress(const char* PeerHostOrIP);
+  virtual void setPeerAddress(const char* PeerHostOrIP);
 
   /** \brief Append a process plugin. Processes will be appended in order
    * \param plugin Pointer to ProcessPlugin Class
    */
   //void appendProcessPlugin(const std::tr1::shared_ptr<ProcessPlugin> plugin);
-  void appendProcessPlugin(ProcessPlugin* plugin);
+  virtual void appendProcessPlugin(ProcessPlugin* plugin);
 
   /// \brief Start the processing threads
-  void start();
+  virtual void startProcess() throw(std::invalid_argument);
 
   /// \brief Stop the processing threads
-  void stop();
+  virtual void stop();
 
   /// \brief Wait for all the threads to finish. This functions is used when JackTrip is 
   /// run as a thread
-  void wait();
+  virtual void waitThreads();
 
   /// \brief Check if UDP port is already binded
   /// \param port Port number
-  void checkIfPortIsBinded(int port);
+  virtual void checkIfPortIsBinded(int port);
   
   //------------------------------------------------------------------------------------
-  /// \name Methods to change parameters after construction
+  /// \name Getters and Setters Methods to change parameters after construction
   //@{
   // 
   /// \brief Sets (override) JackTrip Mode after construction
-  void setJackTripMode(jacktripModeT JacktripMode)
+  virtual void setJackTripMode(jacktripModeT JacktripMode)
   { mJackTripMode = JacktripMode; }
   /// \brief Sets (override) DataProtocol Type after construction
-  void setDataProtocoType(dataProtocolT DataProtocolType)
+  virtual void setDataProtocoType(dataProtocolT DataProtocolType)
   { mDataProtocol = DataProtocolType; }
   /// \brief Sets the Packet header type
-  void setPacketHeaderType(DataProtocol::packetHeaderTypeT PacketHeaderType)
+  virtual void setPacketHeaderType(DataProtocol::packetHeaderTypeT PacketHeaderType)
   { 
     mPacketHeaderType = PacketHeaderType;
     delete mPacketHeader;
     mPacketHeader = NULL;
     createHeader(mPacketHeaderType);
   }
-  /// \brief Sets (override) Number of Channels after construction
-  /// \todo implement this, not working right now because channels cannot be changed after construction
-  //void setNumChannels(int NumChans)
-  //{ mNumChans=NumChans; }
   /// \brief Sets (override) Buffer Queue Length Mode after construction
-  void setBufferQueueLength(int BufferQueueLength)
+  virtual void setBufferQueueLength(int BufferQueueLength)
   { mBufferQueueLength = BufferQueueLength; }
   /// \brief Sets (override) Audio Bit Resolution after construction
-  void setAudioBitResolution(JackAudioInterface::audioBitResolutionT AudioBitResolution)
+  virtual void setAudioBitResolution(AudioInterface::audioBitResolutionT AudioBitResolution)
   { mAudioBitResolution = AudioBitResolution; }
   /// \brief Sets (override) Underrun Mode
-  void setUnderRunMode(underrunModeT UnderRunMode)
+  virtual void setUnderRunMode(underrunModeT UnderRunMode)
   { mUnderRunMode = UnderRunMode; }
   /// \brief Sets port numbers for the local and peer machine.
   /// Receive port is <tt>port</tt>
-  void setAllPorts(int port)
+  virtual void setAllPorts(int port)
   {
     mReceiverBindPort = port;
     mSenderPeerPort = port;
@@ -175,20 +196,84 @@ public:
     mReceiverPeerPort = port;
   }
   /// \brief Sets port numbers to bind in RECEIVER and SENDER sockets.
-  void setBindPorts(int port)
+  virtual void setBindPorts(int port)
   {
     mReceiverBindPort = port;
     mSenderBindPort = port;
   }
   /// \brief Sets port numbers for the peer (remote) machine.
-  void setPeerPorts(int port)
+  virtual void setPeerPorts(int port)
   {
     mSenderPeerPort = port;
     mReceiverPeerPort = port;
   }
   /// \brief Set Client Name to something different that the default (JackTrip)
-  void setClientName(char* ClientName)
+  virtual void setClientName(const char* ClientName)
   { mJackClientName = ClientName; }
+  /// \brief Set the number of audio channels
+  virtual void setNumChannels(int num_chans)
+  { mNumChans = num_chans; }
+
+  virtual int getReceiverBindPort() const
+  { return mReceiverBindPort; }
+  virtual int getSenderPeerPort() const
+  { return mSenderPeerPort; }
+  virtual int getSenderBindPort() const
+  { return mSenderBindPort; }
+  virtual int getReceiverPeerPort() const
+  { return mReceiverPeerPort; }
+
+  virtual DataProtocol* getDataProtocolSender() const
+  { return mDataProtocolSender; }
+  virtual DataProtocol* getDataProtocolReceiver() const
+  { return mDataProtocolReceiver; }
+  virtual void setDataProtocolSender(DataProtocol* const DataProtocolSender)
+  { mDataProtocolSender = DataProtocolSender; }
+  virtual void setDataProtocolReceiver(DataProtocol* const DataProtocolReceiver)
+  { mDataProtocolReceiver = DataProtocolReceiver; }
+
+  virtual RingBuffer* getSendRingBuffer() const
+  { return mSendRingBuffer; }
+  virtual RingBuffer* getReceiveRingBuffer() const
+  { return mReceiveRingBuffer; }
+  virtual void setSendRingBuffer(RingBuffer* const SendRingBuffer)
+  { mSendRingBuffer = SendRingBuffer; }
+  virtual void setReceiveRingBuffer(RingBuffer* const ReceiveRingBuffer)
+  { mReceiveRingBuffer = ReceiveRingBuffer; }
+
+  virtual void setPacketHeader(PacketHeader* const PacketHeader)
+  { mPacketHeader = PacketHeader; }
+
+  virtual int getRingBuffersSlotSize()
+  { return getTotalAudioPacketSizeInBytes(); }
+
+  virtual void setAudiointerfaceMode(JackTrip::audiointerfaceModeT audiointerface_mode)
+  { mAudiointerfaceMode = audiointerface_mode; }
+  virtual void setAudioInterface(AudioInterface* const AudioInterface)
+  { mAudioInterface = AudioInterface; }
+
+
+  void setSampleRate(uint32_t sample_rate)
+  { mSampleRate = sample_rate; }
+  void setAudioBufferSizeInSamples(uint32_t buf_size)
+  { mAudioBufferSize = buf_size; }
+
+  JackTrip::connectionModeT getConnectionMode() const
+  { return mConnectionMode; }
+  void setConnectionMode(JackTrip::connectionModeT connection_mode)
+  { mConnectionMode = connection_mode; }
+
+  JackTrip::jacktripModeT getJackTripMode() const
+  { return mJackTripMode; }
+
+  QString getPeerAddress() const
+  { return mPeerAddress; }
+
+  bool receivedConnectionFromPeer()
+  { return mReceivedConnection; }
+
+  bool tcpConnectionError()
+  { return mTcpConnectionError; }
   //@}
   //------------------------------------------------------------------------------------
 
@@ -197,49 +282,88 @@ public:
   /// \name Mediator Functions
   //@{
   /// \todo Document all these functions
-  void createHeader(const DataProtocol::packetHeaderTypeT headertype);
+  virtual void createHeader(const DataProtocol::packetHeaderTypeT headertype);
   void putHeaderInPacket(int8_t* full_packet, int8_t* audio_packet);
-  int getPacketSizeInBytes() const;
+  virtual int getPacketSizeInBytes();
   void parseAudioPacket(int8_t* full_packet, int8_t* audio_packet);
-  void sendNetworkPacket(const int8_t* ptrToSlot)
+  virtual void sendNetworkPacket(const int8_t* ptrToSlot)
   { mSendRingBuffer->insertSlotNonBlocking(ptrToSlot); }
-  void receiveNetworkPacket(int8_t* ptrToReadSlot)
+  virtual void receiveNetworkPacket(int8_t* ptrToReadSlot)
   { mReceiveRingBuffer->readSlotNonBlocking(ptrToReadSlot); }
-  void readAudioBuffer(int8_t* ptrToReadSlot)
+  virtual void readAudioBuffer(int8_t* ptrToReadSlot)
   { mSendRingBuffer->readSlotBlocking(ptrToReadSlot); }
-  void writeAudioBuffer(const int8_t* ptrToSlot)
+  virtual void writeAudioBuffer(const int8_t* ptrToSlot)
   { mReceiveRingBuffer->insertSlotNonBlocking(ptrToSlot); }
   uint32_t getBufferSizeInSamples() const
-  { return mJackAudio->getBufferSizeInSamples(); }
-  JackAudioInterface::samplingRateT getSampleRateType() const
-  { return mJackAudio->getSampleRateType(); }
+  { return mAudioBufferSize; /*return mAudioInterface->getBufferSizeInSamples();*/ }
+
+  AudioInterface::samplingRateT getSampleRateType() const
+  { return mAudioInterface->getSampleRateType(); }
+  int getSampleRate() const
+  { return mSampleRate; /*return mAudioInterface->getSampleRate();*/ }
+
   uint8_t getAudioBitResolution() const
-  { return mJackAudio->getAudioBitResolution(); }
-  int getNumInputChannels() const
-  { return mJackAudio->getNumInputChannels(); }
-  int getNumOutputChannels() const
-  {return mJackAudio->getNumOutputChannels(); }
-  void checkPeerSettings(int8_t* full_packet);
+  { return mAudioBitResolution*8; /*return mAudioInterface->getAudioBitResolution();*/ }
+  unsigned int getNumInputChannels() const
+  { return mNumChans; /*return mAudioInterface->getNumInputChannels();*/ }
+  unsigned int getNumOutputChannels() const
+  { return mNumChans; /*return mAudioInterface->getNumOutputChannels();*/ }
+  unsigned int getNumChannels() const
+  {
+    if (getNumInputChannels() == getNumOutputChannels())
+    { return getNumInputChannels(); }
+    else { return 0; }
+  }
+  virtual void checkPeerSettings(int8_t* full_packet);
   void increaseSequenceNumber()
   { mPacketHeader->increaseSequenceNumber(); }
   int getSequenceNumber() const
   { return mPacketHeader->getSequenceNumber(); }
-  int getPeerSequenceNumber(int8_t* full_packet) const
+
+  uint64_t getPeerTimeStamp(int8_t* full_packet) const
+  { return mPacketHeader->getPeerTimeStamp(full_packet); }
+
+  uint16_t getPeerSequenceNumber(int8_t* full_packet) const
   { return mPacketHeader->getPeerSequenceNumber(full_packet); }
+
+  uint16_t getPeerBufferSize(int8_t* full_packet) const
+  { return mPacketHeader->getPeerBufferSize(full_packet); }
+
+  uint8_t getPeerSamplingRate(int8_t* full_packet) const
+  { return mPacketHeader->getPeerSamplingRate(full_packet); }
+
+  uint8_t getPeerBitResolution(int8_t* full_packet) const
+  { return mPacketHeader->getPeerBitResolution(full_packet); }
+
+  uint8_t  getPeerNumChannels(int8_t* full_packet) const
+  { return mPacketHeader->getPeerNumChannels(full_packet); }
+
+  uint8_t  getPeerConnectionMode(int8_t* full_packet) const
+  { return mPacketHeader->getPeerConnectionMode(full_packet); }
+
+  size_t getSizeInBytesPerChannel() const
+  { return mAudioInterface->getSizeInBytesPerChannel(); }
+  int getHeaderSizeInBytes() const
+  { return mPacketHeader->getHeaderSizeInBytes(); }
+  virtual int getTotalAudioPacketSizeInBytes() const
+  { return mAudioInterface->getSizeInBytesPerChannel() * mNumChans; }
   //@}
   //------------------------------------------------------------------------------------
 
+  void printTextTest() {std::cout << "=== JackTrip PRINT ===" << std::endl;}
+  void printTextTest2() {std::cout << "=== JackTrip PRINT2 ===" << std::endl;}
 
 public slots:
   /// \brief Slot to stop all the processes and threads
-  void slotStopProcesses()
+  virtual void slotStopProcesses()
   {
     std::cout << "Stopping JackTrip..." << std::endl;
-    stop();
-  };
+    mStopped = true;
+    this->stop();
+  }
 
   /** \brief This slot emits in turn the signal signalNoUdpPacketsForSeconds
-   * when UDP is waited for more than 30 seconds.
+   * when UDP has waited for more than 30 seconds.
    * 
    * It is used to remove the thread from the server.
    */
@@ -251,46 +375,67 @@ public slots:
       emit signalNoUdpPacketsForSeconds();
     }
   }
-  
+  void slotPrintTest()
+  { std::cout << "=== TESTING ===" << std::endl; }
+  void slotReceivedConnectionFromPeer()
+  { mReceivedConnection = true; }
+
 
 signals:
-  /// \brieg Signal emitted when all the processes and threads are stopped
+
+  void signalUdpTimeOut();
+  /// \brief Signal emitted when all the processes and threads are stopped
   void signalProcessesStopped();
-  /// \brieg Signal emitted when no UDP Packets have been received for a while
+  /// \brief Signal emitted when no UDP Packets have been received for a while
   void signalNoUdpPacketsForSeconds();
+  void signalTcpClientConnected();
 
 
-private:
+public:
 
-  /// \brief Set the JackAudioInteface object
-  void setupJackAudio();
+  /// \brief Set the AudioInteface object
+  virtual void setupAudio();
+  /// \brief Close the JackAudioInteface and disconnects it from JACK
+  void closeAudio();
   /// \brief Set the DataProtocol objects
-  void setupDataProtocol();
+  virtual void setupDataProtocol();
   /// \brief Set the RingBuffer objects
   void setupRingBuffers();
   /// \brief Starts for the CLIENT mode
-  void clientStart();
+  void clientStart() throw(std::invalid_argument);
   /// \brief Starts for the SERVER mode
-  void serverStart();
+  /// \param timout Set the server to timeout after 2 seconds if no client connections are received.
+  /// Usefull for the multithreaded server
+  /// \return 0 on success, -1 on error
+  int serverStart(bool timeout = false, int udpTimeout = gTimeOutMultiThreadedServer)
+      throw(std::invalid_argument, std::runtime_error);
   /// \brief Stats for the Client to Ping Server
-  void clientPingToServerStart();
+  /// \return -1 on error, 0 on success
+  virtual int clientPingToServerStart() throw(std::invalid_argument);
+
+private:
+  //void bindReceiveSocket(QUdpSocket& UdpSocket, int bind_port,
+  //                       QHostAddress PeerHostAddress, int peer_port)
+  //throw(std::runtime_error);
+
 
   jacktripModeT mJackTripMode; ///< JackTrip::jacktripModeT
   dataProtocolT mDataProtocol; ///< Data Protocol Tipe
   DataProtocol::packetHeaderTypeT mPacketHeaderType; ///< Packet Header Type
+  JackTrip::audiointerfaceModeT mAudiointerfaceMode;
 
   int mNumChans; ///< Number of Channels (inputs = outputs)
   int mBufferQueueLength; ///< Audio Buffer from network queue length
   uint32_t mSampleRate; ///< Sample Rate
   uint32_t mAudioBufferSize; ///< Audio buffer size to process on each callback
-  JackAudioInterface::audioBitResolutionT mAudioBitResolution; ///< Audio Bit Resolutions
+  AudioInterface::audioBitResolutionT mAudioBitResolution; ///< Audio Bit Resolutions
   QString mPeerAddress; ///< Peer Address to use in jacktripModeT::CLIENT Mode
 
   /// Pointer to Abstract Type DataProtocol that sends packets
   DataProtocol* mDataProtocolSender;
-  ///< Pointer to Abstract Type DataProtocol that receives packets
+  /// Pointer to Abstract Type DataProtocol that receives packets
   DataProtocol* mDataProtocolReceiver;
-  JackAudioInterface* mJackAudio; ///< Interface to Jack Client
+  AudioInterface* mAudioInterface; ///< Interface to Jack Client
   PacketHeader* mPacketHeader; ///< Pointer to Packet Header
   underrunModeT mUnderRunMode; ///< underrunModeT Mode
 
@@ -303,11 +448,20 @@ private:
   int mSenderPeerPort; ///< Incoming (receiving) port for peer machine
   int mSenderBindPort; ///< Outgoing (sending) port for local machine
   int mReceiverPeerPort; ///< Outgoing (sending) port for peer machine
+  int mTcpServerPort;
 
   unsigned int mRedundancy; ///< Redundancy factor in network data
   const char* mJackClientName; ///< JackAudio Client Name
 
+  JackTrip::connectionModeT mConnectionMode; ///< Connection Mode
+
   QVector<ProcessPlugin*> mProcessPlugins; ///< Vector of ProcesPlugin<EM>s</EM>
+
+  volatile bool mReceivedConnection; ///< Bool of received connection from peer
+  volatile bool mTcpConnectionError;
+  volatile bool mStopped;
 };
 
 #endif
+
+
diff --git a/src/JackTripThread.h b/src/JackTripThread.h
index 6825386..06a85c7 100644
--- a/src/JackTripThread.h
+++ b/src/JackTripThread.h
@@ -47,11 +47,11 @@
 class JackTripThread : public QThread
 {
 public:
-  JackTripThread(JackTrip::jacktripModeT JacktripMode) : mJackTripMode(JacktripMode) {};
-  virtual ~JackTripThread(){};
+  JackTripThread(JackTrip::jacktripModeT JacktripMode) : mJackTripMode(JacktripMode) {}
+  virtual ~JackTripThread(){}
   void run();
 
-  void setPort(int port_num) { mPortNum = port_num; } ;
+  void setPort(int port_num) { mPortNum = port_num; }
   void setPeerAddress(const char* PeerHostOrIP) { mPeerAddress = PeerHostOrIP; }
 
 private:
diff --git a/src/JackTripWorker.cpp b/src/JackTripWorker.cpp
index e20c4ba..b83b5c7 100644
--- a/src/JackTripWorker.cpp
+++ b/src/JackTripWorker.cpp
@@ -40,12 +40,16 @@
 
 #include <QTimer>
 #include <QMutexLocker>
+#include <QWaitCondition>
 
 #include "JackTripWorker.h"
 #include "JackTrip.h"
 #include "UdpMasterListener.h"
 #include "NetKS.h"
 #include "LoopBack.h"
+#ifdef __JAMTEST__
+#include "JamTest.h"
+#endif
 
 using std::cout; using std::endl;
 
@@ -73,8 +77,7 @@ JackTripWorker::JackTripWorker(UdpMasterListener* udpmasterlistener) :
 //*******************************************************************************
 JackTripWorker::~JackTripWorker()
 {
-  delete mUdpMasterListener;
-  
+  //delete mUdpMasterListener;
 }
 
 
@@ -89,7 +92,8 @@ void JackTripWorker::setJackTrip(int id, uint32_t client_address,
   }
   mID = id;
   // Set the jacktrip address and ports
-  mClientAddress.setAddress(client_address);
+  //mClientAddress.setAddress(client_address);
+  mClientAddress = client_address;
   mServerPort = server_port;
   mClientPort = client_port;
   mNumChans = num_channels;
@@ -99,74 +103,160 @@ void JackTripWorker::setJackTrip(int id, uint32_t client_address,
 //*******************************************************************************
 void JackTripWorker::run()
 {
-  /*
-    NOTE: This is the message that qt prints when an exception is thrown:
+  /* NOTE: This is the message that qt prints when an exception is thrown:
     'Qt Concurrent has caught an exception thrown from a worker thread.
     This is not supported, exceptions thrown in worker threads must be
-    caught before control returns to Qt Concurrent.'
-  */
-  
+    caught before control returns to Qt Concurrent.'*/
+
+  { QMutexLocker locker(&mMutex); mSpawning = true; }
+
+  QHostAddress ClientAddress;
+
   // Try catching any exceptions that come from JackTrip
   try 
-    {
-      // Local event loop. this is necesary because QRunnables don't have their own as QThreads
-      QEventLoop event_loop;
-      
-      // Create and setup JackTrip Object
-      JackTrip jacktrip(JackTrip::CLIENT, JackTrip::UDP, mNumChans, 2);
-      jacktrip.setPeerAddress( mClientAddress.toString().toLatin1().data() );
-      jacktrip.setBindPorts(mServerPort);
-      jacktrip.setPeerPorts(mClientPort-1);
-
-      // Connect signals and slots
-      // -------------------------
-      QObject::connect(&jacktrip, SIGNAL(signalNoUdpPacketsForSeconds()),
-		       &jacktrip, SLOT(slotStopProcesses()), Qt::QueuedConnection);
-
-      // Connection to terminate the local eventloop when jacktrip is done
-      QObject::connect(&jacktrip, SIGNAL(signalProcessesStopped()),
-      		       &event_loop, SLOT(quit()), Qt::QueuedConnection);
-
-      // Karplus Strong String
-      NetKS netks;
-      jacktrip.appendProcessPlugin(&netks);
-      // Play the String
-      QTimer timer;
-      QObject::connect(&timer, SIGNAL(timeout()), &netks, SLOT(exciteString()),
-		       Qt::QueuedConnection);
-      timer.start(300);
-      
-      // Start Threads and event loop
-      jacktrip.start();
-      
-      { // Thread is already spawning, so release the lock
-	QMutexLocker locker(&mMutex);
-	mSpawning = false;
-      }
-      
-      event_loop.exec(); // Excecution will block here until exit() the QEventLoop
-      //--------------------------------------------------------------------------
-      
-      // wait for jacktrip to be done before exiting the Worker Thread
-      jacktrip.wait();
-      
+  {
+    // Local event loop. this is necesary because QRunnables don't have their own as QThreads
+    QEventLoop event_loop;
+
+    // Create and setup JackTrip Object
+    //JackTrip jacktrip(JackTrip::SERVER, JackTrip::UDP, mNumChans, 2);
+    cout << "---> JackTripWorker: Creating jacktip objects..." << endl;
+#ifndef __JAMTEST__
+    JackTrip jacktrip(JackTrip::SERVERPINGSERVER, JackTrip::UDP, mNumChans, 2);
+#endif
+#ifdef __JAMTEST__
+    JamTest jacktrip(JackTrip::SERVERPINGSERVER); // ########### JamTest #################
+    //JackTrip jacktrip(JackTrip::SERVERPINGSERVER, JackTrip::UDP, mNumChans, 2);
+#endif
+
+    // Connect signals and slots
+    // -------------------------
+    cout << "---> JackTripWorker: Connecting signals and slots..." << endl;
+    // Connection to terminate JackTrip when packets haven't arrive for
+    // a certain amount of time
+    QObject::connect(&jacktrip, SIGNAL(signalNoUdpPacketsForSeconds()),
+                     &jacktrip, SLOT(slotStopProcesses()), Qt::QueuedConnection);
+    // Connection to terminate the local eventloop when jacktrip is done
+    QObject::connect(&jacktrip, SIGNAL(signalProcessesStopped()),
+                     &event_loop, SLOT(quit()), Qt::QueuedConnection);
+    QObject::connect(this, SIGNAL(signalRemoveThread()),
+                     &jacktrip, SLOT(slotStopProcesses()), Qt::QueuedConnection);
+
+    ClientAddress.setAddress(mClientAddress);
+    // If I don't type this line, I get a bus error in the next line.
+    // I still haven't figure out why
+    ClientAddress.toString().toLatin1().constData();
+    jacktrip.setPeerAddress(ClientAddress.toString().toLatin1().constData());
+    jacktrip.setBindPorts(mServerPort);
+    //jacktrip.setPeerPorts(mClientPort);
+
+    cout << "---> JackTripWorker: setJackTripFromClientHeader..." << endl;
+    int PeerConnectionMode = setJackTripFromClientHeader(jacktrip);
+    if ( PeerConnectionMode == -1 ) {
+      mUdpMasterListener->releaseThread(mID);
+      { QMutexLocker locker(&mMutex); mSpawning = false; }
+      return;
     }
+
+    // Start Threads and event loop
+    cout << "---> JackTripWorker: startProcess..." << endl;
+    jacktrip.startProcess();
+    cout << "---> JackTripWorker: start..." << endl;
+    jacktrip.start(); // ########### JamTest Only #################
+
+    // Thread is already spawning, so release the lock
+    { QMutexLocker locker(&mMutex); mSpawning = false; }
+
+    event_loop.exec(); // Excecution will block here until exit() the QEventLoop
+    //--------------------------------------------------------------------------
+
+    { QMutexLocker locker(&mMutex); mSpawning = true; }
+
+    // wait for jacktrip to be done before exiting the Worker Thread
+    jacktrip.wait();
+
+  }
   catch ( const std::exception & e )
-    {
-      std::cerr << "Couldn't send thread to the Pool" << endl;
-      std::cerr << e.what() << endl;
-      std::cerr << gPrintSeparator << endl;
-    }
+  {
+    std::cerr << "Couldn't send thread to the Pool" << endl;
+    std::cerr << e.what() << endl;
+    std::cerr << gPrintSeparator << endl;
+    mUdpMasterListener->releaseThread(mID);
+    { QMutexLocker locker(&mMutex); mSpawning = false; }
+    return;
+  }
   
-  mUdpMasterListener->releasePort(mID);
+  {
+    QMutexLocker locker(&mMutex);
+    mUdpMasterListener->releaseThread(mID);
+  }
+
+  cout << "JackTrip ID = " << mID << " released from the THREAD POOL" << endl;
+  cout << gPrintSeparator << endl;
   { 
     // Thread is already spawning, so release the lock
     QMutexLocker locker(&mMutex);
     mSpawning = false;
   }
+}
 
-  cout << "JackTrip ID = " << mID << " released from the THREAD POOL" << endl;
-  cout << gPrintSeparator << endl;
+
+//*******************************************************************************
+// returns -1 on error
+int JackTripWorker::setJackTripFromClientHeader(JackTrip& jacktrip)
+{
+  //QHostAddress peerHostAddress;
+  //uint16_t peer_port;
+  QUdpSocket UdpSockTemp;// Create socket to wait for client
+
+  // Bind the socket
+  if ( !UdpSockTemp.bind(QHostAddress::Any, mServerPort,
+                         QUdpSocket::DefaultForPlatform) )
+  {
+    std::cerr << "in JackTripWorker: Could not bind UDP socket. It may be already binded." << endl;
+    throw std::runtime_error("Could not bind UDP socket. It may be already binded.");
+  }
+
+  // Listen to client
+  QWaitCondition sleep; // time is in milliseconds
+  QMutex mutex;
+  int sleepTime = 100; // ms
+  int udpTimeout = gTimeOutMultiThreadedServer; // gTimeOutMultiThreadedServer mseconds
+  int elapsedTime = 0;
+  {
+    QMutexLocker lock(&mutex);
+    while ( (!UdpSockTemp.hasPendingDatagrams()) && (elapsedTime <= udpTimeout) ) {
+      sleep.wait(&mutex,sleepTime);
+      elapsedTime += sleepTime;
+      //cout << "---------> ELAPSED TIME: " << elapsedTime << endl;
+    }
+  }
+  // Check if we time out or not
+  if (!UdpSockTemp.hasPendingDatagrams()) {
+    std::cerr << "--->JackTripWorker: is not receiving Datagrams (timeout)" << endl;
+    UdpSockTemp.close();
+    return -1;
+  }
+  int packet_size = UdpSockTemp.pendingDatagramSize();
+  char packet[packet_size];
+  UdpSockTemp.readDatagram(packet, packet_size);
+  UdpSockTemp.close(); // close the socket
+  int8_t* full_packet = reinterpret_cast<int8_t*>(packet);
+
+  int PeerBufferSize = jacktrip.getPeerBufferSize(full_packet);
+  int PeerSamplingRate = jacktrip.getPeerSamplingRate(full_packet);
+  int PeerBitResolution = jacktrip.getPeerBitResolution(full_packet);
+  int PeerNumChannels = jacktrip.getPeerNumChannels(full_packet);
+  int PeerConnectionMode = jacktrip.getPeerConnectionMode(full_packet);
+
+  cout << "--->JackTripWorker: getPeerBufferSize = " << PeerBufferSize << endl;
+  cout << "--->JackTripWorker: getPeerSamplingRate = " << PeerSamplingRate << endl;
+  cout << "--->JackTripWorker: getPeerBitResolution = " << PeerBitResolution << endl;
+  cout << "--->JackTripWorker: getPeerNumChannels = " << PeerNumChannels << endl;
+  cout << "--->JackTripWorker: getPeerConnectionMode = " << PeerConnectionMode << endl;
+
+  jacktrip.setNumChannels(PeerNumChannels);
+  return PeerConnectionMode;
 }
 
 
@@ -176,3 +266,11 @@ bool JackTripWorker::isSpawning()
   QMutexLocker locker(&mMutex);
   return mSpawning;
 }
+
+
+//*******************************************************************************
+void JackTripWorker::stopThread()
+{
+  QMutexLocker locker(&mMutex);
+  emit signalRemoveThread();
+}
diff --git a/src/JackTripWorker.h b/src/JackTripWorker.h
index 8df371e..adf1602 100644
--- a/src/JackTripWorker.h
+++ b/src/JackTripWorker.h
@@ -46,9 +46,9 @@
 #include <QHostAddress>
 #include <QMutex>
 
-#include "jacktrip_types.h"
+#include "JackTrip.h"
 
-class JackTrip; // forward declaration
+//class JackTrip; // forward declaration
 class UdpMasterListener; // forward declaration
 
 
@@ -70,40 +70,45 @@ class JackTripWorker : public QObject, public QRunnable
 public:
   /// \brief The class constructor
   JackTripWorker(UdpMasterListener* udpmasterlistener);
-
   /// \brief The class destructor
   virtual ~JackTripWorker();
   
-  /** \brief Implements the Thread Loop.
-   * To start the thread, call start() ( DO NOT CALL run() ). 
-   */
+  /// \brief Implements the Thread Loop.
+  /// To start the thread, call start() ( DO NOT CALL run() ).
   void run();
-
-  /** \brief Check if the Thread is Spawning
-   * \return true is it is spawning, false if it's already running
-   */
+  /// \brief Check if the Thread is Spawning
+  /// \return true is it is spawning, false if it's already running
   bool isSpawning();
-
-  /** \brief Sets the JackTripWorker properties
-   * \param id ID number
-   * \param address 
-   */
+  /// \brief Sets the JackTripWorker properties
+  /// \param id ID number
+  /// \param address
   void setJackTrip(int id, uint32_t client_address,
 		   uint16_t server_port, uint16_t client_port,
 		   int num_channels);
+  /// Stop and remove thread from pool
+  void stopThread();
+  int getID()
+  {
+    return mID;
+  }
 
 
 private slots:
   void slotTest()
-  {
-    std::cout << "--- JackTripWorker TEST SLOT ---" << std::endl;
-  }
+  { std::cout << "--- JackTripWorker TEST SLOT ---" << std::endl; }
+
+
+signals:
+  void signalRemoveThread();
 
 
 private:
+  int setJackTripFromClientHeader(JackTrip& jacktrip);
+  JackTrip::connectionModeT getConnectionModeFromHeader();
 
   UdpMasterListener* mUdpMasterListener; ///< Master Listener Socket
-  QHostAddress mClientAddress; ///< Client Address
+  //QHostAddress mClientAddress; ///< Client Address
+  uint32_t mClientAddress;
   uint16_t mServerPort; ///< Server Ephemeral Incomming Port to use with Client
 
   /// Client Outgoing Port. By convention, the receving port will be <tt>mClientPort -1</tt> 
diff --git a/src/LoopBack.cpp b/src/LoopBack.cpp
index f22197b..b8a698e 100644
--- a/src/LoopBack.cpp
+++ b/src/LoopBack.cpp
@@ -40,6 +40,10 @@
 #include "jacktrip_types.h"
 
 #include <cstring> // for memcpy
+#include <iostream>
+
+using std::cout; using std::endl;
+//using namespace JackTripNamespace;
 
 
 //*******************************************************************************
diff --git a/src/NetKS.h b/src/NetKS.h
index 2d09c4b..864be52 100644
--- a/src/NetKS.h
+++ b/src/NetKS.h
@@ -39,7 +39,7 @@
 #define __NETKS_H__
 
 #include <iostream>
-#include <unistd.h>
+//#include <unistd.h>
 
 #include <QTimer>
 
@@ -73,7 +73,7 @@ private slots:
     std::cout << "========= EXTICING STRING ===========" << std::endl;
     fbutton0 = 1.0;
     //std::cout << fbutton0 << std::endl;
-    usleep(280000); /// \todo Define this number based on the sampling rate and buffer size
+    QThread::usleep(280000); /// \todo Define this number based on the sampling rate and buffer size
     fbutton0 = 0.0;
     //std::cout << fbutton0 << std::endl;
   }
diff --git a/src/PacketHeader.cpp b/src/PacketHeader.cpp
index 1a37556..41e41dc 100644
--- a/src/PacketHeader.cpp
+++ b/src/PacketHeader.cpp
@@ -46,6 +46,29 @@
 using std::cout; using std::endl;
 
 
+// below is the gettimeofday definition for windows: this function is not defined in sys/time.h as it is in unix
+// for more info check: http://www.halcode.com/archives/2008/08/26/retrieving-system-time-gettimeofday/
+#if defined __WIN_32__
+#ifdef __cplusplus
+void GetSystemTimeAsFileTime(FILETIME*);
+inline int gettimeofday(struct timeval* p, void* tz /* IGNORED */)
+{
+  union {
+    long long ns100; /*time since 1 Jan 1601 in 100ns units */
+    FILETIME ft;
+  } now;
+  GetSystemTimeAsFileTime( &(now.ft) );
+  p->tv_usec=(long)((now.ns100 / 10LL) % 1000000LL );
+  p->tv_sec= (long)((now.ns100-(116444736000000000LL))/10000000LL);
+  return 0;
+}
+#else
+/* Must be defined somewhere else */
+int gettimeofday(struct timeval* p, void* tz /* IGNORED */);
+#endif
+#endif
+
+
 //#######################################################################
 //####################### PacketHeader ##################################
 //#######################################################################
@@ -79,23 +102,22 @@ DefaultHeader::DefaultHeader(JackTrip* jacktrip) :
   mHeader.BufferSize = 0; 
   mHeader.SamplingRate = 0;
   mHeader.BitResolution = 0;
-  mHeader.NumInChannels = 0;
-  mHeader.NumOutChannels = 0;
-  //mHeader.Dummy = 0;
+  //mHeader.NumInChannels = 0;
+  //mHeader.NumOutChannels = 0;
+  mHeader.NumChannels = 0;
+  mHeader.ConnectionMode = 0;
 }
 
 
 //***********************************************************************
 void DefaultHeader::fillHeaderCommonFromAudio()
 {
+  mHeader.TimeStamp = PacketHeader::usecTime();
   mHeader.BufferSize = mJackTrip->getBufferSizeInSamples();
   mHeader.SamplingRate = mJackTrip->getSampleRateType ();
-  mHeader.NumInChannels = mJackTrip->getNumInputChannels();
   mHeader.BitResolution = mJackTrip->getAudioBitResolution();
-  mHeader.NumOutChannels = mJackTrip->getNumOutputChannels();
-  //mHeader.SeqNumber = 0;
-  mHeader.TimeStamp = PacketHeader::usecTime();
-  //cout << mHeader.TimeStamp << endl;
+  mHeader.NumChannels = mJackTrip->getNumChannels();
+  mHeader.ConnectionMode = static_cast<int>(mJackTrip->getConnectionMode());
   //printHeader();
 }
 
@@ -120,17 +142,17 @@ void DefaultHeader::checkPeerSettings(int8_t* full_packet)
 
   // Check Sampling Rate
   if ( peer_header->SamplingRate != mHeader.SamplingRate ) 
-    {
-      std::cerr << "ERROR: Peer Sampling Rate is  : " << 
-	JackAudioInterface::getSampleRateFromType
-	( static_cast<JackAudioInterface::samplingRateT>(peer_header->SamplingRate) ) << endl;
-      std::cerr << "       Local Sampling Rate is  : " << 
-	JackAudioInterface::getSampleRateFromType
-	( static_cast<JackAudioInterface::samplingRateT>(mHeader.SamplingRate) ) << endl;
-      std::cerr << "Make sure both machines use the same Sampling Rate" << endl;
-      std::cerr << gPrintSeparator << endl;
-      error = true;
-    }
+  {
+    std::cerr << "ERROR: Peer Sampling Rate is   : " <<
+        AudioInterface::getSampleRateFromType
+        ( static_cast<AudioInterface::samplingRateT>(peer_header->SamplingRate) ) << endl;
+    std::cerr << "       Local Sampling Rate is  : " <<
+        AudioInterface::getSampleRateFromType
+        ( static_cast<AudioInterface::samplingRateT>(mHeader.SamplingRate) ) << endl;
+    std::cerr << "Make sure both machines use the same Sampling Rate" << endl;
+    std::cerr << gPrintSeparator << endl;
+    error = true;
+  }
 
   // Check Audio Bit Resolution
   if ( peer_header->BitResolution != mHeader.BitResolution ) 
@@ -149,7 +171,8 @@ void DefaultHeader::checkPeerSettings(int8_t* full_packet)
     {
       //std::cerr << "Exiting program..." << endl;
       //std::exit(1);
-      throw std::logic_error("Local and Peer Settings don't match");
+      //throw std::logic_error("Local and Peer Settings don't match");
+      emit signalError("Local and Peer Settings don't match");
     }
   /// \todo Check number of channels and other parameters
 }
@@ -160,18 +183,30 @@ void DefaultHeader::printHeader() const
 {
   cout << "Default Packet Header:" << endl;
   cout << "Buffer Size               = " << static_cast<int>(mHeader.BufferSize) << endl;
-  // Get the sample rate in Hz form the JackAudioInterface::samplingRateT
+  // Get the sample rate in Hz form the AudioInterface::samplingRateT
   int sample_rate = 
-    JackAudioInterface::getSampleRateFromType
-    ( static_cast<JackAudioInterface::samplingRateT>(mHeader.SamplingRate) );
+    AudioInterface::getSampleRateFromType
+    ( static_cast<AudioInterface::samplingRateT>(mHeader.SamplingRate) );
   cout << "Sampling Rate             = " << sample_rate << endl;
   cout << "Audio Bit Resolutions     = " << static_cast<int>(mHeader.BitResolution) << endl;
-  cout << "Number of Input Channels  = " << static_cast<int>(mHeader.NumInChannels) << endl;
-  cout << "Number of Output Channels = " << static_cast<int>(mHeader.NumOutChannels) << endl;
+  //cout << "Number of Input Channels  = " << static_cast<int>(mHeader.NumInChannels) << endl;
+  //cout << "Number of Output Channels = " << static_cast<int>(mHeader.NumOutChannels) << endl;
+  cout << "Number of Channels        = " << static_cast<int>(mHeader.NumChannels) << endl;
   cout << "Sequence Number           = " << static_cast<int>(mHeader.SeqNumber) << endl;
   cout << "Time Stamp                = " << mHeader.TimeStamp << endl;
+  cout << "Connection Mode           = " << static_cast<int>(mHeader.ConnectionMode) << endl;
   cout << gPrintSeparator << endl;
-  cout << sizeof(mHeader) << endl;
+  //cout << sizeof(mHeader) << endl;
+}
+
+
+
+//***********************************************************************
+uint64_t DefaultHeader::getPeerTimeStamp(int8_t* full_packet) const
+{
+  DefaultHeaderStruct* peer_header;
+  peer_header =  reinterpret_cast<DefaultHeaderStruct*>(full_packet);
+  return peer_header->TimeStamp;
 }
 
 
@@ -184,6 +219,49 @@ uint16_t DefaultHeader::getPeerSequenceNumber(int8_t* full_packet) const
 }
 
 
+//***********************************************************************
+uint16_t DefaultHeader::getPeerBufferSize(int8_t* full_packet) const
+{
+  DefaultHeaderStruct* peer_header;
+  peer_header =  reinterpret_cast<DefaultHeaderStruct*>(full_packet);
+  return peer_header->BufferSize;
+}
+
+
+//***********************************************************************
+uint8_t  DefaultHeader::getPeerSamplingRate(int8_t* full_packet) const
+{
+  DefaultHeaderStruct* peer_header;
+  peer_header =  reinterpret_cast<DefaultHeaderStruct*>(full_packet);
+  return peer_header->SamplingRate;
+}
+
+
+//***********************************************************************
+uint8_t DefaultHeader::getPeerBitResolution(int8_t* full_packet) const
+{
+  DefaultHeaderStruct* peer_header;
+  peer_header =  reinterpret_cast<DefaultHeaderStruct*>(full_packet);
+  return peer_header->BitResolution;
+}
+
+
+//***********************************************************************
+uint8_t DefaultHeader::getPeerNumChannels(int8_t* full_packet) const
+{
+  DefaultHeaderStruct* peer_header;
+  peer_header =  reinterpret_cast<DefaultHeaderStruct*>(full_packet);
+  return peer_header->NumChannels;
+}
+
+
+//***********************************************************************
+uint8_t DefaultHeader::getPeerConnectionMode(int8_t* full_packet) const
+{
+  DefaultHeaderStruct* peer_header;
+  peer_header =  reinterpret_cast<DefaultHeaderStruct*>(full_packet);
+  return static_cast<uint8_t>(peer_header->ConnectionMode);
+}
 
 
 
@@ -212,41 +290,48 @@ void JamLinkHeader::fillHeaderCommonFromAudio()
     //std::cerr << "ERROR: JamLink only support ONE channel. Run JackTrip using only one channel"
     //	      << endl;
     //std::exit(1);
-    throw std::logic_error("JamLink only support ONE channel. Run JackTrip using only one channel");
+    //std::cerr << "WARINING: JamLink only support ONE channel. Run JackTrip using only one channel" << endl;
+    //throw std::logic_error("JamLink only support ONE channel. Run JackTrip using only one channel");
+    emit signalError("JamLink only support ONE channel. Run JackTrip using only one channel");
+
   }
   
   // Sampling Rate
   int rate_type = mJackTrip->getSampleRateType();
-  if ( rate_type != JackAudioInterface::SR48 ) {
-    throw std::logic_error("ERROR: JamLink only support 48kHz for communication with JackTrip at the moment.");
+  if ( rate_type != AudioInterface::SR48 ) {
+    //std::cerr << "WARINING: JamLink only support 48kHz for communication with JackTrip at the moment." << endl;
+    //throw std::logic_error("ERROR: JamLink only support 48kHz for communication with JackTrip at the moment.");
+    emit signalError("ERROR: JamLink only support 48kHz for communication with JackTrip at the moment.");
   }
 
   // Check Buffer Size
   int buf_size = mJackTrip->getBufferSizeInSamples();
-  if ( buf_size != 64 )
-    {
-      throw std::logic_error("ERROR: JamLink only support 64 buffer size for communication with JackTrip at the moment.");
-    }
+  if ( buf_size != 64 ) {
+    //std::cerr << "WARINING: JamLink only support 64 buffer size for communication with JackTrip at the moment." << endl;
+    //throw std::logic_error("ERROR: JamLink only support 64 buffer size for communication with JackTrip at the moment.");
+    emit signalError("ERROR: JamLink only support 64 buffer size for communication with JackTrip at the moment.");
+  }
 
   mHeader.Common = (ETX_MONO | ETX_16BIT | ETX_XTND) + 64;
   switch (rate_type)
     {
-    case JackAudioInterface::SR48 :
+    case AudioInterface::SR48 :
       mHeader.Common = (mHeader.Common | ETX_48KHZ);
       break;
-    case JackAudioInterface::SR44 :
+    case AudioInterface::SR44 :
       mHeader.Common = (mHeader.Common | ETX_44KHZ);
       break;
-    case JackAudioInterface::SR32 :
+    case AudioInterface::SR32 :
       mHeader.Common = (mHeader.Common | ETX_32KHZ);
       break;
-    case JackAudioInterface::SR22 :
+    case AudioInterface::SR22 :
       mHeader.Common = (mHeader.Common | ETX_22KHZ);
       break;
     default:
       //std::cerr << "ERROR: Sample rate not supported by JamLink" << endl;
       //std::exit(1);
-      throw std::out_of_range("Sample rate not supported by JamLink");
+      //throw std::out_of_range("Sample rate not supported by JamLink");
+      emit signalError("Sample rate not supported by JamLink.");
       break;
     }
 }
diff --git a/src/PacketHeader.h b/src/PacketHeader.h
index 73cf979..3988039 100644
--- a/src/PacketHeader.h
+++ b/src/PacketHeader.h
@@ -39,9 +39,12 @@
 #define __PACKETHEADER_H__
 
 #include <iostream>
-#include <tr1/memory> // for shared_ptr
+//#include <tr1/memory> // for shared_ptr
 #include <cstring>
 
+#include <QObject>
+#include <QString>
+
 #include "jacktrip_types.h"
 #include "jacktrip_globals.h"
 class JackTrip; // Forward Declaration
@@ -60,9 +63,10 @@ public:
   uint16_t BufferSize; ///< Buffer Size in Samples
   uint8_t  SamplingRate; ///< Sampling Rate in JackAudioInterface::samplingRateT
   uint8_t BitResolution; ///< Audio Bit Resolution
-  uint8_t  NumInChannels; ///< Number of Input Channels
-  uint8_t  NumOutChannels; ///<  Number of Output Channels
-  //uint8_t  Dummy; ///< Dummy value to byte padding alignment 
+  //uint8_t  NumInChannels; ///< Number of Input Channels
+  //uint8_t  NumOutChannels; ///<  Number of Output Channels
+  uint8_t  NumChannels; ///< Number of Channels, we assume input and outputs are the same
+  uint8_t  ConnectionMode;
 };
 
 //---------------------------------------------------------
@@ -103,70 +107,67 @@ struct JamLinkHeaderStuct : public HeaderStruct
 };
 
 
+
 //#######################################################################
 //####################### PacketHeader ##################################
 //#######################################################################
 /** \brief Base class for header type. Subclass this struct to
  * create a new header.
  */
-class PacketHeader
+class PacketHeader : public QObject
 {
+  Q_OBJECT;
+
 public:
   /// \brief The class Constructor
   PacketHeader(JackTrip* jacktrip);
   /// \brief The class Destructor
-  virtual ~PacketHeader() {};
+  virtual ~PacketHeader() {}
   
-  /** \brief Return a time stamp in microseconds
-   * \return Time stamp: microseconds since midnight (0 hour), January 1, 1970
-   */
+  /// \brief Return a time stamp in microseconds
+  /// \return Time stamp: microseconds since midnight (0 hour), January 1, 1970
   static uint64_t usecTime();
-
   /// \todo Implement this using a JackTrip Method (Mediator) member instead of the 
   /// reference to JackAudio
   virtual void fillHeaderCommonFromAudio() = 0;
-
-  /* \brief Parse the packet header and take appropriate measures (like change settings, or 
-   * quit the program if peer settings don't match)
-   */
+  /// \brief Parse the packet header and take appropriate measures (like change settings, or
+  /// quit the program if peer settings don't match)
   virtual void parseHeader() = 0;
-
   virtual void checkPeerSettings(int8_t* full_packet) = 0;
+
+  virtual uint64_t getPeerTimeStamp(int8_t* full_packet) const = 0;
   virtual uint16_t getPeerSequenceNumber(int8_t* full_packet) const = 0;
+  virtual uint16_t getPeerBufferSize(int8_t* full_packet) const = 0;
+  virtual uint8_t  getPeerSamplingRate(int8_t* full_packet) const = 0;
+  virtual uint8_t getPeerBitResolution(int8_t* full_packet) const = 0;
+  virtual uint8_t  getPeerNumChannels(int8_t* full_packet) const = 0;
+  virtual uint8_t  getPeerConnectionMode(int8_t* full_packet) const = 0;
 
-  /* \brief Increase sequence number for counter, a 16bit number
-   */
+  /// \brief Increase sequence number for counter, a 16bit number
   virtual void increaseSequenceNumber()
-  {
-    mSeqNumber++;
-  };
-
-  /* \brief Returns the current sequence number
-   * \return 16bit Sequence number
-   */
+  { mSeqNumber++; }
+  /// \brief Returns the current sequence number
+  /// \return 16bit Sequence number
   virtual uint16_t getSequenceNumber() const
-  {
-    return mSeqNumber;
-  }
-
-  /* \brief Get the header size in bytes
-   */
+  { return mSeqNumber; }
+  /// \brief Get the header size in bytes
   virtual int getHeaderSizeInBytes() const = 0;
-
-
   virtual void putHeaderInPacketBaseClass(int8_t* full_packet,
 				       const HeaderStruct& header_struct)
   {
     std::memcpy(full_packet, reinterpret_cast<const void*>(&header_struct),
 		getHeaderSizeInBytes() );
-  };
-
-  /* \brief Put the header in buffer pointed by full_packet
-   * \param full_packet Pointer to full packet (audio+header). Size must be
-   * sizeof(header part) + sizeof(audio part)
-   */
+  }
+  /// \brief Put the header in buffer pointed by full_packet
+  /// \param full_packet Pointer to full packet (audio+header). Size must be
+  /// sizeof(header part) + sizeof(audio part)
   virtual void putHeaderInPacket(int8_t* full_packet) = 0;
 
+
+signals:
+  void signalError(const char* error_message);
+
+
 private:
   uint16_t mSeqNumber;
   JackTrip* mJackTrip; ///< JackTrip mediator class
@@ -183,48 +184,37 @@ private:
 class DefaultHeader : public PacketHeader
 {
 public:
-  /*
-  //----------STRUCT-----------------------------------------
-  /// \brief Default Header Struct
-  struct DefaultHeaderStruct
-  {
-    // watch out for alignment...
-    uint64_t TimeStamp; ///< Time Stamp
-    uint16_t SeqNumber; ///< Sequence Number
-    uint16_t BufferSize; ///< Buffer Size in Samples
-    uint8_t  SamplingRate; ///< Sampling Rate in JackAudioInterface::samplingRateT
-    uint8_t  NumInChannels; ///< Number of Input Channels
-    uint8_t  NumOutChannels; ///<  Number of Output Channels
-    // uint8_t BitResolution; ///< \todo implement this part
-  };
-  //---------------------------------------------------------
-  */
+
   DefaultHeader(JackTrip* jacktrip);
-  virtual ~DefaultHeader() {};
+  virtual ~DefaultHeader() {}
+
   virtual void fillHeaderCommonFromAudio();
-  virtual void parseHeader() {};
+  virtual void parseHeader() {}
   virtual void checkPeerSettings(int8_t* full_packet);
   virtual void increaseSequenceNumber()
-  {
-    mHeader.SeqNumber++;
-    //std::cout << "Sequence Number = " << static_cast<int>(mHeader.SeqNumber) << std::endl;
-  };
+  { mHeader.SeqNumber++; }
   virtual uint16_t getSequenceNumber() const
-  {
-    return mHeader.SeqNumber;
-  }
-  virtual uint16_t getPeerSequenceNumber(int8_t* full_packet) const;
-  virtual int getHeaderSizeInBytes() const { return sizeof(mHeader); };
+  { return mHeader.SeqNumber; }
+  virtual int getHeaderSizeInBytes() const { return sizeof(mHeader); }
   virtual void putHeaderInPacket(int8_t* full_packet)
-  {
-    putHeaderInPacketBaseClass(full_packet, mHeader);
-    //std::memcpy(full_packet, reinterpret_cast<const void*>(&mHeader),
-    //	getHeaderSizeInBytes() );
-  };
+  { putHeaderInPacketBaseClass(full_packet, mHeader); }
   void printHeader() const;
+  uint8_t getConnectionMode() const
+  { return mHeader.ConnectionMode; }
+  uint8_t getNumChannels() const
+  { return mHeader.NumChannels; }
+
+
+  virtual uint64_t getPeerTimeStamp(int8_t* full_packet) const;
+  virtual uint16_t getPeerSequenceNumber(int8_t* full_packet) const;
+  virtual uint16_t getPeerBufferSize(int8_t* full_packet) const;
+  virtual uint8_t  getPeerSamplingRate(int8_t* full_packet) const;
+  virtual uint8_t getPeerBitResolution(int8_t* full_packet) const;
+  virtual uint8_t  getPeerNumChannels(int8_t* full_packet) const;
+  virtual uint8_t  getPeerConnectionMode(int8_t* full_packet) const;
+
 
 private:
-  //DefaultHeaderStruct mHeader; ///< Header Struct
   DefaultHeaderStruct mHeader;///< Default Header Struct
   JackTrip* mJackTrip; ///< JackTrip mediator class
 };
@@ -243,18 +233,24 @@ class JamLinkHeader : public PacketHeader
 public:
   
   JamLinkHeader(JackTrip* jacktrip);
-  virtual ~JamLinkHeader() {};
+  virtual ~JamLinkHeader() {}
 
   virtual void fillHeaderCommonFromAudio();
-  virtual void parseHeader() {};
+  virtual void parseHeader() {}
   virtual void checkPeerSettings(int8_t* /*full_packet*/) {}
-  virtual uint16_t getPeerSequenceNumber(int8_t* /*full_packet*/) const { /*\todo IMPLEMENT*/ return 0; }
-  virtual void increaseSequenceNumber() {};
-  virtual int getHeaderSizeInBytes() const { return sizeof(mHeader); };
+
+  virtual uint64_t getPeerTimeStamp(int8_t* /*full_packet*/) const { return 0; }
+  virtual uint16_t getPeerSequenceNumber(int8_t* /*full_packet*/) const { return 0; }
+  virtual uint16_t getPeerBufferSize(int8_t* /*full_packet*/) const { return 0; }
+  virtual uint8_t  getPeerSamplingRate(int8_t* /*full_packet*/) const { return 0; }
+  virtual uint8_t getPeerBitResolution(int8_t* /*full_packet*/) const { return 0; }
+  virtual uint8_t  getPeerNumChannels(int8_t* /*full_packet*/) const { return 0; }
+  virtual uint8_t  getPeerConnectionMode(int8_t* /*full_packet*/) const { return 0; }
+
+  virtual void increaseSequenceNumber() {}
+  virtual int getHeaderSizeInBytes() const { return sizeof(mHeader); }
   virtual void putHeaderInPacket(int8_t* full_packet)
-  {
-    putHeaderInPacketBaseClass(full_packet, mHeader);
-  };
+  { putHeaderInPacketBaseClass(full_packet, mHeader); }
 
 private:
   JamLinkHeaderStuct mHeader; ///< JamLink Header Struct
@@ -274,15 +270,23 @@ class EmptyHeader : public PacketHeader
 public:
   
   EmptyHeader(JackTrip* jacktrip);
-  virtual ~EmptyHeader() {};
+  virtual ~EmptyHeader() {}
 
-  virtual void fillHeaderCommonFromAudio() {};
-  virtual void parseHeader() {};
+  virtual void fillHeaderCommonFromAudio() {}
+  virtual void parseHeader() {}
   virtual void checkPeerSettings(int8_t* /*full_packet*/) {}
-  virtual uint16_t getPeerSequenceNumber(int8_t* /*full_packet*/) const { return 0; /*\todo IMPLEMENT*/}
-  virtual void increaseSequenceNumber() {};
-  virtual int getHeaderSizeInBytes() const { return 0; };
-  virtual void putHeaderInPacket(int8_t* /*full_packet*/) {};
+  virtual void increaseSequenceNumber() {}
+  virtual int getHeaderSizeInBytes() const { return 0; }
+
+  virtual uint64_t getPeerTimeStamp(int8_t* /*full_packet*/) const { return 0; }
+  virtual uint16_t getPeerSequenceNumber(int8_t* /*full_packet*/) const { return 0; }
+  virtual uint16_t getPeerBufferSize(int8_t* /*full_packet*/) const { return 0; }
+  virtual uint8_t  getPeerSamplingRate(int8_t* /*full_packet*/) const { return 0; }
+  virtual uint8_t getPeerBitResolution(int8_t* /*full_packet*/) const { return 0; }
+  virtual uint8_t  getPeerNumChannels(int8_t* /*full_packet*/) const { return 0; }
+  virtual uint8_t  getPeerConnectionMode(int8_t* /*full_packet*/) const { return 0; }
+
+  virtual void putHeaderInPacket(int8_t* /*full_packet*/) {}
 
 private:
   JackTrip* mJackTrip; ///< JackTrip mediator class
diff --git a/src/ProcessPlugin.h b/src/ProcessPlugin.h
index 70533c8..4c0cae8 100644
--- a/src/ProcessPlugin.h
+++ b/src/ProcessPlugin.h
@@ -39,7 +39,7 @@
 #define __PROCESSPLUGIN_H__
 
 #include <jack/jack.h>
-#include <QObject>
+#include <QThread>
 
 /** \brief Interface for the process plugins to add to the JACK callback process in 
  * JackAudioInterface
@@ -49,7 +49,7 @@
  * except init, which is optional for processing that are sampling rate dependent or 
  * that need specific initialization.
  */
-class ProcessPlugin : public QObject
+class ProcessPlugin : public QThread
 {
 public:
 
diff --git a/src/RingBuffer.h b/src/RingBuffer.h
index e3cf986..9a5cab6 100644
--- a/src/RingBuffer.h
+++ b/src/RingBuffer.h
@@ -44,6 +44,8 @@
 
 #include "jacktrip_types.h"
 
+//using namespace JackTripNamespace;
+
 
 /** \brief Provides a ring-buffer (or circular-buffer) that can be written to and read from
  * asynchronously (blocking) or synchronously (non-blocking).
diff --git a/src/RtAudioInterface.cpp b/src/RtAudioInterface.cpp
new file mode 100644
index 0000000..3add762
--- /dev/null
+++ b/src/RtAudioInterface.cpp
@@ -0,0 +1,452 @@
+//*****************************************************************
+/*
+  JackTrip: A System for High-Quality Audio Network Performance
+  over the Internet
+
+  Copyright (c) 2008 Juan-Pablo Caceres, Chris Chafe.
+  SoundWIRE group at CCRMA, Stanford University.
+
+  Permission is hereby granted, free of charge, to any person
+  obtaining a copy of this software and associated documentation
+  files (the "Software"), to deal in the Software without
+  restriction, including without limitation the rights to use,
+  copy, modify, merge, publish, distribute, sublicense, and/or sell
+  copies of the Software, and to permit persons to whom the
+  Software is furnished to do so, subject to the following
+  conditions:
+
+  The above copyright notice and this permission notice shall be
+  included in all copies or substantial portions of the Software.
+
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+  OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+  OTHER DEALINGS IN THE SOFTWARE.
+*/
+//*****************************************************************
+
+/**
+ * \file RtAudioInterface.cpp
+ * \author Juan-Pablo Caceres
+ * \date July 2009
+ */
+
+#include "RtAudioInterface.h"
+#include "JackTrip.h"
+#include "jacktrip_globals.h"
+
+#include <cstdlib>
+
+
+using std::cout; using std::endl;
+
+
+//*******************************************************************************
+RtAudioInterface::RtAudioInterface(JackTrip* jacktrip,
+                                   int NumInChans, int NumOutChans,
+                                   audioBitResolutionT AudioBitResolution) :
+AudioInterface(jacktrip,
+               NumInChans, NumOutChans,
+               AudioBitResolution),
+mJackTrip(jacktrip),
+mRtAudio(NULL)
+{}
+
+
+//*******************************************************************************
+RtAudioInterface::~RtAudioInterface()
+{
+  delete mRtAudio;
+}
+
+
+//*******************************************************************************
+void RtAudioInterface::setup()
+{
+  // Initialize Buffer array to read and write audio and members
+  mNumInChans = getNumInputChannels();
+  mNumOutChans = getNumOutputChannels();
+  mInBuffer.resize(getNumInputChannels());
+  mOutBuffer.resize(getNumOutputChannels());
+
+  cout << "Settin Up Default RtAudio Interface" << endl;
+  cout << gPrintSeparator << endl;
+  mRtAudio = new RtAudio;
+  if ( mRtAudio->getDeviceCount() < 1 ) {
+    cout << "No audio devices found!" << endl;
+    std::exit(0);
+  }
+
+  // Get and print default devices
+  RtAudio::DeviceInfo info_input;
+  RtAudio::DeviceInfo info_output;
+
+  int deviceId_input; int deviceId_output;
+  // use default devices
+  deviceId_input = mRtAudio->getDefaultInputDevice();
+  deviceId_output = mRtAudio->getDefaultOutputDevice();
+
+  cout << "DEFAULT INPUT DEVICE  : " << endl;
+  printDeviceInfo(deviceId_input);
+  cout << gPrintSeparator << endl;
+  cout << "DEFAULT OUTPUT DEVICE : " << endl;
+  printDeviceInfo(deviceId_output);
+  cout << gPrintSeparator << endl;
+
+  RtAudio::StreamParameters in_params, out_params;
+  in_params.deviceId = mRtAudio->getDefaultInputDevice();
+  out_params.deviceId = mRtAudio->getDefaultOutputDevice();
+  in_params.nChannels = getNumInputChannels();
+  out_params.nChannels = getNumOutputChannels();
+
+  RtAudio::StreamOptions options;
+  //The second flag affects linux and mac only
+  options.flags = RTAUDIO_NONINTERLEAVED | RTAUDIO_SCHEDULE_REALTIME;
+#ifdef __WIN_32__
+  options.flags = options.flags | RTAUDIO_MINIMIZE_LATENCY;
+#endif
+  //linux only
+  options.priority = 99;
+
+  unsigned int sampleRate = getSampleRate();//mSamplingRate;
+  unsigned int bufferFrames = getBufferSizeInSamples();//mBufferSize;
+
+  try {
+    // IMPORTANT NOTE: It's VERY important to remember to pass this
+    // as the user data in the process callback, otherwise memeber won't
+    // be accessible
+    mRtAudio->openStream(&out_params, &in_params, RTAUDIO_FLOAT32,
+                         sampleRate, &bufferFrames,
+                         &RtAudioInterface::wrapperRtAudioCallback, this, &options);
+  }
+  catch ( RtError& e ) {
+    std::cout << '\n' << e.getMessage() << '\n' << std::endl;
+    exit( 0 );
+  }
+
+  // Setup parent class
+  AudioInterface::setup();
+}
+
+
+//*******************************************************************************
+void RtAudioInterface::listAllInterfaces()
+{
+  RtAudio rtaudio;
+  if ( rtaudio.getDeviceCount() < 1 ) {
+    cout << "No audio devices found!" << endl; }
+  else {
+    for (unsigned int i = 0; i < rtaudio.getDeviceCount(); i++) {
+      printDeviceInfo(i);
+      cout << gPrintSeparator << endl;
+    }
+  }
+}
+
+
+//*******************************************************************************
+void RtAudioInterface::printDeviceInfo(unsigned int deviceId)
+{
+  RtAudio rtaudio;
+  RtAudio::DeviceInfo info;
+  int i = deviceId;
+  info = rtaudio.getDeviceInfo(i);
+  std::vector<unsigned int> sampleRates;
+  cout << "Audio Device  [" << i << "] : "  << info.name << endl;
+  cout << "  Output Channels : " << info.outputChannels << endl;
+  cout << "  Input Channels  : " << info.inputChannels << endl;
+  sampleRates = info.sampleRates;
+  cout << "  Supported Sampling Rates: ";
+  for (unsigned int ii = 0; ii<sampleRates.size();ii++) {
+    cout << sampleRates[ii] << " ";
+  }
+  cout << endl;
+  if (info.isDefaultOutput) {
+    cout << "  --Default Output Device--" << endl; }
+  if (info.isDefaultInput) {
+    cout << "  --Default Intput Device--" << endl; }
+  if (info.probed) {
+    cout << "  --Probed Successful--" << endl; }
+}
+
+
+//*******************************************************************************
+int RtAudioInterface::RtAudioCallback(void *outputBuffer, void *inputBuffer,
+                                      unsigned int nFrames,
+                                      double /*streamTime*/, RtAudioStreamStatus /*status*/)
+{
+  sample_t* inputBuffer_sample = (sample_t*) inputBuffer;
+  sample_t* outputBuffer_sample = (sample_t*) outputBuffer;
+
+  // Get input and output buffers
+  //-------------------------------------------------------------------
+  for (int i = 0; i < mNumInChans; i++) {
+    // Input Ports are READ ONLY
+    mInBuffer[i] = inputBuffer_sample+(nFrames*i);
+  }
+  for (int i = 0; i < mNumOutChans; i++) {
+    // Output Ports are WRITABLE
+    mOutBuffer[i] = outputBuffer_sample+(nFrames*i);
+  }
+
+  AudioInterface::callback(mInBuffer, mOutBuffer, nFrames);
+  return 0;
+}
+
+
+//*******************************************************************************
+int RtAudioInterface::wrapperRtAudioCallback(void *outputBuffer, void *inputBuffer,
+                                             unsigned int nFrames, double streamTime,
+                                             RtAudioStreamStatus status, void *userData)
+{
+  return static_cast<RtAudioInterface*>(userData)->RtAudioCallback(outputBuffer,inputBuffer,
+                                                              nFrames,
+                                                              streamTime, status);
+}
+
+
+//*******************************************************************************
+int RtAudioInterface::startProcess() const
+{
+  try { mRtAudio->startStream(); }
+  catch ( RtError& e ) {
+    std::cout << '\n' << e.getMessage() << '\n' << std::endl;
+    return(-1);
+  }
+  return(0);
+}
+
+
+//*******************************************************************************
+int RtAudioInterface::stopProcess() const
+{
+  try { mRtAudio->closeStream(); }
+  catch ( RtError& e ) {
+    std::cout << '\n' << e.getMessage() << '\n' << std::endl;
+    return(-1);
+  }
+  return 0;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+// OLD CODE
+// =============================================================================
+
+/*
+int RtAudioInterface::processCallback(jack_nframes_t nframes)
+{
+  mJackTrip->printTextTest();
+  return JackAudioInterface::processCallback(nframes);
+}
+*/
+
+
+//*******************************************************************************
+//int RtAudioInterface::RtAudioCallback(void *outputBuffer, void *inputBuffer,
+//                                      unsigned int nFrames,
+//                                      double /*streamTime*/, RtAudioStreamStatus /*status*/)
+//{
+/*
+  mInBuffer[0] = (sample_t*) inputBuffer;
+  mOutBuffer[0] = (sample_t*) outputBuffer;
+  //AudioInterface::callback(mInBuffer, mOutBuffer, mInputPacket, mOutputPacket,
+  //                         nFrames, mInProcessBuffer, mOutProcessBuffer);
+
+
+  // Output Process (from NETWORK to JACK)
+  // ----------------------------------------------------------------
+  // Read Audio buffer from RingBuffer (read from incoming packets)
+  //mOutRingBuffer->readSlotNonBlocking( mOutputPacket );
+  mJackTrip->receiveNetworkPacket( mOutputPacket );
+
+
+  // Extract separate channels to send to Jack
+  for (int i = 0; i < getNumOutputChannels(); i++) {
+    //--------
+    // This should be faster for 32 bits
+    //std::memcpy(mOutBuffer[i], &mOutputPacket[i*mSizeInBytesPerChannel],
+    //		mSizeInBytesPerChannel);
+    //--------
+    sample_t* tmp_sample = mOutBuffer[i]; //sample buffer for channel i
+    for (unsigned int j = 0; j < nFrames; j++) {
+      //std::memcpy(&tmp_sample[j], &mOutputPacket[(i*mSizeInBytesPerChannel) + (j*4)], 4);
+      // Change the bit resolution on each sample
+      //cout << tmp_sample[j] << endl;
+      AudioInterface::fromBitToSampleConversion(&mOutputPacket[(i*getSizeInBytesPerChannel())
+                 + (j*BIT16)],
+        &tmp_sample[j],
+        BIT16);
+    }
+  }
+
+
+
+  // Input Process (from JACK to NETWORK)
+  // ----------------------------------------------------------------
+  // Concatenate  all the channels from jack to form packet
+  for (int i = 0; i < getNumInputChannels(); i++) {
+    //--------
+    // This should be faster for 32 bits
+    //std::memcpy(&mInputPacket[i*getSizeInBytesPerChannel()], mInBuffer[i],
+    //		mSizeInBytesPerChannel);
+    //--------
+    sample_t* tmp_sample = mInBuffer[i]; //sample buffer for channel i
+    sample_t tmp_result;
+    for (unsigned int j = 0; j < nFrames; j++) {
+      // Add the input jack buffer to the buffer resulting from the output process
+      tmp_result = tmp_sample[j];
+      AudioInterface::fromSampleToBitConversion(&tmp_result,
+                                                    &mInputPacket[(i*getSizeInBytesPerChannel())
+                                                                  + (j*BIT16)],
+                                                    BIT16);
+    }
+  }
+  // Send Audio buffer to RingBuffer (these goes out as outgoing packets)
+  //mInRingBuffer->insertSlotNonBlocking( mInputPacket );
+  mJackTrip->sendNetworkPacket( mInputPacket );
+
+*/
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+  //mTestJackTrip->printTextTest();
+
+  //if (mJackTrip != NULL)
+  //  cout << "(mJackTrip != NULL)" << endl;
+
+
+  //if (mJackTrip == NULL) { cout << " === JACKTRIPNULL === " << endl; }
+
+  //const int8_t* caca;
+  //mJackTrip->sendNetworkPacket( mInputPacket );
+
+  //in_buffer = mInBuffer.data();
+  //mInBuffer.data() = (float*) inputBuffer;
+
+  //mInBuffer[0] = static_cast<float*>(outputBuffer);
+  //mOutBuffer[0] = static_cast<sample_t*>(inputBuffer);
+  //float* in_buffer = static_cast<float*>(inputBuffer);
+  //float* out_buffer = static_cast<float*>(outputBuffer);
+
+
+  //cout << "nFrames = ==================== = = = = = = = ======== " << this->getBufferSizeInSamples() << endl;
+  //int8_t* input_packet = new int8_t[nFrames*2];
+
+  //tmp_sample = floor( (*input) * 32768.0 ); // 2^15 = 32768.0
+
+  //JackAudioInterface::fromSampleToBitConversion(in_buffer, input_packet, BIT16);
+  //for (int i = 0; i<nFrames; i++) {
+  //  cout << in_buffer[i] << endl;
+  //}
+  //mJackTrip->sendNetworkPacket(input_packet);
+  //cout << mJackTrip->getRingBuffersSlotSize() << endl;
+  //delete[] input_packet;
+
+
+  //mOutputPacket = static_cast<int8_t*>(inputBuffer);
+  //mInputPacket = static_cast<int8_t*>(outputBuffer);
+
+  // Allocate the Process Callback
+  //-------------------------------------------------------------------
+  // 1) First, process incoming packets
+  // ----------------------------------
+  /*
+  mJackTrip->receiveNetworkPacket( mOutputPacket );
+  // Extract separate channels to send to Jack
+  for (int i = 0; i < getNumInputChannels(); i++) {
+    sample_t* tmp_sample = mOutBuffer[i]; //sample buffer for channel i
+    for (int j = 0; j < mBufferSize; j++) {
+      fromBitToSampleConversion(&mOutputPacket[(i*getSizeInBytesPerChannel()) + (j*BIT16)],
+                                &tmp_sample[j],
+                                BIT16);
+    }
+  }
+  */
+
+
+  // 3) Finally, send packets to peer
+  // --------------------------------
+  // Input Process (from JACK to NETWORK)
+  // ----------------------------------------------------------------
+  // Concatenate  all the channels from jack to form packet
+  /*
+  for (int i = 0; i < getNumOutputChannels(); i++) {
+    //--------
+    // This should be faster for 32 bits
+    //std::memcpy(&mInputPacket[i*mSizeInBytesPerChannel], mInBuffer[i],
+    //		mSizeInBytesPerChannel);
+    //--------
+    float* tmp_sample = in_buffer; //sample buffer for channel i
+    //sample_t* tmp_process_sample = mOutProcessBuffer[i]; //sample buffer from the output process
+    sample_t tmp_result;
+    for (int j = 0; j < mBufferSize; j++) {
+      //std::memcpy(&tmp_sample[j], &mOutputPacket[(i*mSizeInBytesPerChannel) + (j*4)], 4);
+      // Change the bit resolution on each sample
+
+      // Add the input jack buffer to the buffer resulting from the output process
+      //tmp_result = tmp_sample[j] + tmp_process_sample[j];
+
+      fromSampleToBitConversion(tmp_sample,
+                                &mInputPacket[(i*getSizeInBytesPerChannel())
+                                              + (j*BIT16)],
+                                BIT16);
+
+
+
+    }
+  }
+  // Send Audio buffer to RingBuffer (these goes out as outgoing packets)
+  //mInRingBuffer->insertSlotNonBlocking( mInputPacket );
+  mJackTrip->sendNetworkPacket( mInputPacket );
+  */
+  //return 0;
+//}
+
diff --git a/src/RtAudioInterface.h b/src/RtAudioInterface.h
new file mode 100644
index 0000000..a176e78
--- /dev/null
+++ b/src/RtAudioInterface.h
@@ -0,0 +1,97 @@
+//*****************************************************************
+/*
+  JackTrip: A System for High-Quality Audio Network Performance
+  over the Internet
+
+  Copyright (c) 2008 Juan-Pablo Caceres, Chris Chafe.
+  SoundWIRE group at CCRMA, Stanford University.
+
+  Permission is hereby granted, free of charge, to any person
+  obtaining a copy of this software and associated documentation
+  files (the "Software"), to deal in the Software without
+  restriction, including without limitation the rights to use,
+  copy, modify, merge, publish, distribute, sublicense, and/or sell
+  copies of the Software, and to permit persons to whom the
+  Software is furnished to do so, subject to the following
+  conditions:
+
+  The above copyright notice and this permission notice shall be
+  included in all copies or substantial portions of the Software.
+
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+  OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+  OTHER DEALINGS IN THE SOFTWARE.
+*/
+//*****************************************************************
+
+/**
+ * \file RtAudioInterface.h
+ * \author Juan-Pablo Caceres
+ * \date July 2009
+ */
+
+#ifndef __RTAUDIOINTERFACE_H__
+#define __RTAUDIOINTERFACE_H__
+
+#include "RtAudio.h"
+
+#include "AudioInterface.h"
+#include "jacktrip_globals.h"
+class JackTrip; // Forward declaration
+
+/// \brief Base Class that provides an interface with RtAudio
+class RtAudioInterface : public AudioInterface
+{
+public:
+
+  /** \brief The class constructor
+   * \param jacktrip Pointer to the JackTrip class that connects all classes (mediator)
+   * \param NumInChans Number of Input Channels
+   * \param NumOutChans Number of Output Channels
+   * \param AudioBitResolution Audio Sample Resolutions in bits
+   */
+  RtAudioInterface(JackTrip* jacktrip,
+                   int NumInChans = gDefaultNumInChannels,
+                   int NumOutChans = gDefaultNumOutChannels,
+                   audioBitResolutionT AudioBitResolution = BIT16);
+  /// \brief The class destructor
+  virtual ~RtAudioInterface();
+
+  /// \brief List all avialable audio interfaces, with its properties
+  virtual void listAllInterfaces();
+  virtual void setup();
+  virtual int startProcess() const;
+  virtual int stopProcess() const;
+  /// \brief This has no effect in RtAudio
+  virtual void connectDefaultPorts() {}
+
+  //--------------SETTERS---------------------------------------------
+  /// \brief This has no effect in RtAudio
+  virtual void setClientName(const char* /*ClientName*/) {}
+  //------------------------------------------------------------------
+
+  //--------------GETTERS---------------------------------------------
+  //------------------------------------------------------------------
+
+
+private:
+  int RtAudioCallback(void *outputBuffer, void *inputBuffer, unsigned int nFrames,
+                      double streamTime, RtAudioStreamStatus status);
+  static int wrapperRtAudioCallback(void *outputBuffer, void *inputBuffer, unsigned int nFrames,
+                                    double streamTime, RtAudioStreamStatus status, void *userData);
+  void printDeviceInfo(unsigned int deviceId);
+
+  JackTrip* mJackTrip; ///< JackTrip Mediator Class pointer
+  int mNumInChans;///< Number of Input Channels
+  int mNumOutChans; ///<  Number of Output Channels
+  QVarLengthArray<float*> mInBuffer; ///< Vector of Input buffers/channel read from JACK
+  QVarLengthArray<float*> mOutBuffer; ///< Vector of Output buffer/channel to write to JACK
+  RtAudio* mRtAudio; ///< RtAudio class
+};
+
+#endif // __RTAUDIOINTERFACE_H__
diff --git a/src/Settings.cpp b/src/Settings.cpp
index 5b764da..21d9601 100644
--- a/src/Settings.cpp
+++ b/src/Settings.cpp
@@ -55,220 +55,275 @@ int gVerboseFlag = 0;
 
 //*******************************************************************************
 Settings::Settings() :
-  mJackTrip(NULL),
-  mJackTripMode(JackTrip::SERVER),
-  mDataProtocol(JackTrip::UDP),
-  mNumChans(2),
-  mBufferQueueLength(gDefaultQueueLength),
-  mAudioBitResolution(JackAudioInterface::BIT16),
-  mPortNum(gDefaultPort),
-  mClientName(NULL),
-  mUnderrrunZero(false),
-  mLoopBack(false),
-  mJamLink(false),
-  mEmptyHeader(false),
-  mJackTripServer(false),
-  mRedundancy(1)
+    mJackTrip(NULL),
+    mJackTripMode(JackTrip::SERVER),
+    mDataProtocol(JackTrip::UDP),
+    mNumChans(2),
+    mBufferQueueLength(gDefaultQueueLength),
+    mAudioBitResolution(AudioInterface::BIT16),
+    mBindPortNum(gDefaultPort), mPeerPortNum(gDefaultPort),
+    mClientName(NULL),
+    mUnderrrunZero(false),
+    mLoopBack(false),
+    mJamLink(false),
+    mEmptyHeader(false),
+    mJackTripServer(false),
+    mLocalAddress(gDefaultLocalAddress),
+    mRedundancy(1),
+    mUseJack(true),
+    mChanfeDefaultSR(false),
+    mChanfeDefaultBS(false)
 {}
 
 //*******************************************************************************
 Settings::~Settings()
 {
-  stopJackTrip();
-  delete mJackTrip;
+    stopJackTrip();
+    delete mJackTrip;
 }
 
 //*******************************************************************************
 void Settings::parseInput(int argc, char** argv)
 {
-  // If no command arguments are given, print instructions
-  if(argc == 1) {
-    printUsage();
-    std::exit(0);
-  }
-
-  // Usage example at:
-  // http://www.gnu.org/software/libc/manual/html_node/Getopt-Long-Option-Example.html#Getopt-Long-Option-Example
-  // options descriptor
-  //----------------------------------------------------------------------------
-  static struct option longopts[] = {
-    // These options set a flag, has to be sepcified as a long option --verbose
-    { "verbose", no_argument, &gVerboseFlag, 1 },
-    // These options don't set a flag.
-    { "numchannels", required_argument, NULL, 'n' }, // Number of input and output channels
-    { "server", no_argument, NULL, 's' }, // Run in server mode
-    { "client", required_argument, NULL, 'c' }, // Run in client mode, set server IP address
-    { "jacktripserver", no_argument, NULL, 'S' }, // Run in JamLink mode
-    { "pingtoserver", required_argument, NULL, 'C' }, // Run in ping to server mode, set server IP address
-    { "portoffset", required_argument, NULL, 'o' }, // Port Offset from 4464
-    { "queue", required_argument, NULL, 'q' }, // Queue Length
-    { "redundancy", required_argument, NULL, 'r' }, // Redundancy
-    { "bitres", required_argument, NULL, 'b' }, // Audio Bit Resolution
-    { "zerounderrun", no_argument, NULL, 'z' }, // Use Underrun to Zeros Mode
-    { "loopback", no_argument, NULL, 'l' }, // Run in loopback mode
-    { "jamlink", no_argument, NULL, 'j' }, // Run in JamLink mode
-    { "emptyheader", no_argument, NULL, 'e' }, // Run in JamLink mode
-    { "clientname", required_argument, NULL, 'J' }, // Run in JamLink mode
-    { "version", no_argument, NULL, 'v' }, // Version Number
-    { "help", no_argument, NULL, 'h' }, // Print Help
-    { NULL, 0, NULL, 0 }
-  };
-
-  // Parse Command Line Arguments
-  //----------------------------------------------------------------------------
-  /// \todo Specify mandatory arguments
-  int ch;
-  while ( (ch = getopt_long(argc, argv, "n:sc:SC:o:q:r:b:zljeJ:vh", longopts, NULL)) != -1 )
-    switch (ch) {
-      
-    case 'n': // Number of input and output channels
-      //-------------------------------------------------------
-      mNumChans = atoi(optarg);
-      break;
-    case 's': // Run in server mode
-      //-------------------------------------------------------
-      mJackTripMode = JackTrip::SERVER;
-      break;
-    case 'S': // Run in jacktripserver mode
-      //-------------------------------------------------------
-      mJackTripServer = true;
-      break;
-    case 'c': // Client mode
-      //-------------------------------------------------------
-      mJackTripMode = JackTrip::CLIENT;
-      mPeerAddress = optarg;
-      break;
-    case 'C': // Ping to server
-      //-------------------------------------------------------
-      mJackTripMode = JackTrip::CLIENTTOPINGSERVER;
-      mPeerAddress = optarg;
-      break;
-    case 'o': // Port Offset
-      //-------------------------------------------------------
-      mPortNum += atoi(optarg);
-      break;
-    case 'b':
-      //-------------------------------------------------------
-      if      ( atoi(optarg) == 8 ) {
-	mAudioBitResolution = JackAudioInterface::BIT8; }
-      else if ( atoi(optarg) == 16 ) {
-	mAudioBitResolution = JackAudioInterface::BIT16; }
-      else if ( atoi(optarg) == 24 ) {
-	mAudioBitResolution = JackAudioInterface::BIT24; }
-      else if ( atoi(optarg) == 32 ) {
-	mAudioBitResolution = JackAudioInterface::BIT32; }
-      else {
-	std::cerr << "--bitres ERROR: Wrong bit resolutions: " 
-		  << atoi(optarg) << " is not supported." << endl;
-	printUsage();
-	std::exit(1); }
-      break;
-    case 'q':
-      //-------------------------------------------------------
-      if ( atoi(optarg) <= 0 ) {
-	std::cerr << "--queue ERROR: The queue has to be a positive integer" << endl;
-	printUsage();
-	std::exit(1); }
-      else {
-	mBufferQueueLength = atoi(optarg);
-      }
-      break;
-    case 'r':
-      //-------------------------------------------------------
-      if ( atoi(optarg) <= 0 ) {
-	std::cerr << "--queue ERROR: The queue has to be a positive integer" << endl;
-	printUsage();
-	std::exit(1); }
-      else {
-	mRedundancy = atoi(optarg);
-      }
-      break;
-    case 'z': // underrun to zero
-      //-------------------------------------------------------
-      mUnderrrunZero = true;
-      break;
-    case 'l': // loopback
-      //-------------------------------------------------------
-      mLoopBack = true;
-      break;
-    case 'e': // jamlink
-      //-------------------------------------------------------
-      mEmptyHeader = true;
-      break;
-    case 'j': // jamlink
-      //-------------------------------------------------------
-      mJamLink = true;
-      break;
-    case 'J':
-      //-------------------------------------------------------
-      mClientName = optarg;
-      break;
-    case 'v':
-      //-------------------------------------------------------
-      cout << "JackTrip VERSION: " << gVersion << endl;
-      cout << "Copyright (c) 2008-2009 Juan-Pablo Caceres, Chris Chafe." << endl;
-      cout << "SoundWIRE group at CCRMA, Stanford University" << endl;
-      cout << "" << endl;
-      std::exit(0);
-      break;
-    case 'h':
-      //-------------------------------------------------------
-      printUsage();
-      std::exit(0);
-      break;
-    default:
-      //-------------------------------------------------------
-      printUsage();
-      std::exit(0);
-      break;
+    // If no command arguments are given, print instructions
+    if(argc == 1) {
+        printUsage();
+        std::exit(0);
     }
 
-  // Warn user if undefined options where entered
-  //----------------------------------------------------------------------------
-  if (optind < argc) {
-    cout << gPrintSeparator << endl;
-    cout << "WARINING: The following entered options have no effect" << endl;
-    cout << "          They will be ignored!" << endl;
-    cout << "          Type jacktrip to see options." << endl;
-    for( ; optind < argc; optind++) {
-      printf("argument: %s\n", argv[optind]);
+    // Usage example at:
+    // http://www.gnu.org/software/libc/manual/html_node/Getopt-Long-Option-Example.html#Getopt-Long-Option-Example
+    // options descriptor
+    //----------------------------------------------------------------------------
+    static struct option longopts[] = {
+        // These options set a flag, has to be sepcified as a long option --verbose
+        { "verbose", no_argument, &gVerboseFlag, 1 },
+        // These options don't set a flag.
+        { "numchannels", required_argument, NULL, 'n' }, // Number of input and output channels
+        { "server", no_argument, NULL, 's' }, // Run in server mode
+        { "client", required_argument, NULL, 'c' }, // Run in client mode, set server IP address
+        { "localaddress", required_argument, NULL, 'L' }, // set local address e.g., 127.0.0.2 for second instance on same host
+        { "jacktripserver", no_argument, NULL, 'S' }, // Run in JamLink mode
+        { "pingtoserver", required_argument, NULL, 'C' }, // Run in ping to server mode, set server IP address
+        { "portoffset", required_argument, NULL, 'o' }, // Port Offset from 4464
+        { "bindport", required_argument, NULL, 'B' }, // Port Offset from 4464
+        { "peerport", required_argument, NULL, 'P' }, // Port Offset from 4464
+        { "queue", required_argument, NULL, 'q' }, // Queue Length
+        { "redundancy", required_argument, NULL, 'r' }, // Redundancy
+        { "bitres", required_argument, NULL, 'b' }, // Audio Bit Resolution
+        { "zerounderrun", no_argument, NULL, 'z' }, // Use Underrun to Zeros Mode
+        { "loopback", no_argument, NULL, 'l' }, // Run in loopback mode
+        { "jamlink", no_argument, NULL, 'j' }, // Run in JamLink mode
+        { "emptyheader", no_argument, NULL, 'e' }, // Run in JamLink mode
+        { "clientname", required_argument, NULL, 'J' }, // Run in JamLink mode
+        { "rtaudio", no_argument, NULL, 'R' }, // Run in JamLink mode
+        { "srate", required_argument, NULL, 'T' }, // Set Sample Rate
+        { "bufsize", required_argument, NULL, 'F' }, // Set buffer Size
+        { "version", no_argument, NULL, 'v' }, // Version Number
+        { "help", no_argument, NULL, 'h' }, // Print Help
+        { NULL, 0, NULL, 0 }
+    };
+
+    // Parse Command Line Arguments
+    //----------------------------------------------------------------------------
+    /// \todo Specify mandatory arguments
+    int ch;
+    while ( (ch = getopt_long(argc, argv,
+                              "n:sc:SC:o:B:P:q:r:b:zljeJ:RT:F:vh", longopts, NULL)) != -1 )
+        switch (ch) {
+
+        case 'n': // Number of input and output channels
+            //-------------------------------------------------------
+            mNumChans = atoi(optarg);
+            break;
+        case 's': // Run in server mode
+            //-------------------------------------------------------
+            mJackTripMode = JackTrip::SERVER;
+            break;
+        case 'S': // Run in jacktripserver mode
+            //-------------------------------------------------------
+            mJackTripServer = true;
+            break;
+        case 'c': // Client mode
+            //-------------------------------------------------------
+            mJackTripMode = JackTrip::CLIENT;
+            mPeerAddress = optarg;
+            break;
+        case 'L': // set optional local host address
+            //-------------------------------------------------------
+            mLocalAddress = optarg;
+            break;
+        case 'C': // Ping to server
+            //-------------------------------------------------------
+            mJackTripMode = JackTrip::CLIENTTOPINGSERVER;
+            mPeerAddress = optarg;
+            break;
+        case 'o': // Port Offset
+            //-------------------------------------------------------
+            mBindPortNum += atoi(optarg);
+            mPeerPortNum += atoi(optarg);
+            break;
+        case 'B': // Bind Port
+            //-------------------------------------------------------
+            mBindPortNum = atoi(optarg);
+            break;
+        case 'P': // Peer Port
+            //-------------------------------------------------------
+            mPeerPortNum = atoi(optarg);
+            break;
+        case 'b':
+            //-------------------------------------------------------
+            if      ( atoi(optarg) == 8 ) {
+                mAudioBitResolution = AudioInterface::BIT8; }
+            else if ( atoi(optarg) == 16 ) {
+                mAudioBitResolution = AudioInterface::BIT16; }
+            else if ( atoi(optarg) == 24 ) {
+                mAudioBitResolution = AudioInterface::BIT24; }
+            else if ( atoi(optarg) == 32 ) {
+                mAudioBitResolution = AudioInterface::BIT32; }
+            else {
+                std::cerr << "--bitres ERROR: Wrong bit resolutions: "
+                          << atoi(optarg) << " is not supported." << endl;
+                printUsage();
+                std::exit(1); }
+            break;
+        case 'q':
+            //-------------------------------------------------------
+            if ( atoi(optarg) <= 0 ) {
+                std::cerr << "--queue ERROR: The queue has to be equal or greater that 2" << endl;
+                printUsage();
+                std::exit(1); }
+            else {
+                mBufferQueueLength = atoi(optarg);
+            }
+            break;
+        case 'r':
+            //-------------------------------------------------------
+            if ( atoi(optarg) <= 0 ) {
+                std::cerr << "--redundancy ERROR: The reduncancy has to be a positive integer" << endl;
+                printUsage();
+                std::exit(1); }
+            else {
+                mRedundancy = atoi(optarg);
+            }
+            break;
+        case 'z': // underrun to zero
+            //-------------------------------------------------------
+            mUnderrrunZero = true;
+            break;
+        case 'l': // loopback
+            //-------------------------------------------------------
+            mLoopBack = true;
+            break;
+        case 'e': // jamlink
+            //-------------------------------------------------------
+            mEmptyHeader = true;
+            break;
+        case 'j': // jamlink
+            //-------------------------------------------------------
+            mJamLink = true;
+            break;
+        case 'J': // Set client Name
+            //-------------------------------------------------------
+            mClientName = optarg;
+            break;
+        case 'R': // RtAudio
+            //-------------------------------------------------------
+            mUseJack = false;
+            break;
+        case 'T': // Sampling Rate
+            //-------------------------------------------------------
+            mChanfeDefaultSR = true;
+            mSampleRate = atoi(optarg);
+            break;
+        case 'F': // Buffer Size
+            //-------------------------------------------------------
+            mChanfeDefaultBS = true;
+            mAudioBufferSize = atoi(optarg);
+            break;
+        case 'v':
+            //-------------------------------------------------------
+            cout << "JackTrip VERSION: " << gVersion << endl;
+            cout << "Copyright (c) 2008-2009 Juan-Pablo Caceres, Chris Chafe." << endl;
+            cout << "SoundWIRE group at CCRMA, Stanford University" << endl;
+            cout << "" << endl;
+            std::exit(0);
+            break;
+        case 'h':
+            //-------------------------------------------------------
+            printUsage();
+            std::exit(0);
+            break;
+        default:
+            //-------------------------------------------------------
+            printUsage();
+            std::exit(0);
+            break;
+        }
+
+    // Warn user if undefined options where entered
+    //----------------------------------------------------------------------------
+    if (optind < argc) {
+        cout << gPrintSeparator << endl;
+        cout << "WARINING: The following entered options have no effect" << endl;
+        cout << "          They will be ignored!" << endl;
+        cout << "          Type jacktrip to see options." << endl;
+        for( ; optind < argc; optind++) {
+            printf("argument: %s\n", argv[optind]);
+        }
+        cout << gPrintSeparator << endl;
     }
-    cout << gPrintSeparator << endl;
-  }
 }
 
 
 //*******************************************************************************
 void Settings::printUsage()
 {
-  cout << "" << endl;
-  cout << "JackTrip: A System for High-Quality Audio Network Performance" << endl;
-  cout << "over the Internet" << endl;
-  cout << "Copyright (c) 2008-2009 Juan-Pablo Caceres, Chris Chafe." << endl;
-  cout << "SoundWIRE group at CCRMA, Stanford University" << endl;
-  cout << "VERSION: " << gVersion << endl;
-  cout << "-----------------------------------------------------------------------------" << endl;
-  cout << "" << endl;
-  cout << "Usage: jacktrip [-s|-c host] [options]" << endl;
-  cout << "" << endl;
-  cout << "Options: " << endl;
-  cout << " -s, --server                             Run in Server Mode" << endl;
-  cout << " -c, --client      <peer_host_IP_number>  Run in Client Mode" << endl;
-  cout << " -n, --numchannels #                      Number of Input and Output Channels (default "
-       << 2 << ")" << endl;
-  cout << " -q, --queue       # (1 or more)          Queue Buffer Length, in Packet Size (default " 
-       << gDefaultQueueLength << ")" << endl;
-  cout << " -r, --redundancy  # (1 or more)          Packet Redundancy to avoid glitches with packet losses (defaul 1)" 
-       << endl;
-  cout << " -o, --portoffset  #                      Receiving port offset from base port " << gDefaultPort << endl;
-  cout << " -b, --bitres      # (8, 16, 24, 32)      Audio Bit Rate Resolutions (default 16)" << endl;
-  cout << " -z, --zerounderrun                       Set buffer to zeros when underrun occurs (defaults to wavetable)" << endl;
-  cout << " -l, --loopback                           Run in Loop-Back Mode" << endl;
-  cout << " -j, --jamlink                            Run in JamLink Mode (Connect to a JamLink Box)" << endl;
-  cout << " --clientname                             Change default client name (default is JackTrip)" << endl;
-  cout << " -v, --version                            Prints Version Number" << endl;
-  cout << " -h, --help                               Prints this Help" << endl;
-  cout << "" << endl;
+    cout << "" << endl;
+    cout << "JackTrip: A System for High-Quality Audio Network Performance" << endl;
+    cout << "over the Internet" << endl;
+    cout << "Copyright (c) 2008-2015 Juan-Pablo Caceres, Chris Chafe." << endl;
+    cout << "SoundWIRE group at CCRMA, Stanford University" << endl;
+    cout << "VERSION: " << gVersion << endl;
+    cout << "-----------------------------------------------------------------------------" << endl;
+    cout << "" << endl;
+    cout << "Usage: jacktrip [-s|-c host] [options]" << endl;
+    cout << "" << endl;
+    cout << "Options: " << endl;
+    cout << "REQUIRED ARGUMENTS: " << endl;
+    cout << "===================" << endl;
+    cout << " -s, --server                             Run in Server Mode" << endl;
+    cout << " -c, --client      <peer_host_IP_number>  Run in Client Mode" << endl;
+    cout << endl;
+    cout << "OPTIONAL ARGUMENTS: " << endl;
+    cout << "===================" << endl;
+    cout << " -n, --numchannels #                      Number of Input and Output Channels (default "
+         << 2 << ")" << endl;
+    cout << " -q, --queue       # (2 or more)          Queue Buffer Length, in Packet Size (default "
+         << gDefaultQueueLength << ")" << endl;
+    cout << " -r, --redundancy  # (1 or more)          Packet Redundancy to avoid glitches with packet losses (defaul 1)"
+         << endl;
+    cout << " -o, --portoffset  #                      Receiving port offset from base port " << gDefaultPort << endl;
+    cout << " --bindport        #                      Set only the bind port number (default to 4464)" << endl;
+    cout << " --peerport        #                      Set only the Peer port number (default to 4464)" << endl;
+    cout << " -b, --bitres      # (8, 16, 24, 32)      Audio Bit Rate Resolutions (default 16)" << endl;
+    cout << " -z, --zerounderrun                       Set buffer to zeros when underrun occurs (defaults to wavetable)" << endl;
+    cout << " -l, --loopback                           Run in Loop-Back Mode" << endl;
+    cout << " -j, --jamlink                            Run in JamLink Mode (Connect to a JamLink Box)" << endl;
+    cout << " --clientname                             Change default client name (default is JackTrip)" << endl;
+    cout << " --localaddress                           Change default local host IP address (127.0.0.1)" << endl;
+    cout << endl;
+    cout << "ARGUMENTS TO USE IT WITHOUT JACK:" << endl;
+    cout << "=================================" << endl;
+    cout << " --rtaudio                                Use defaul sound system instead of Jack" << endl;
+    cout << "   --srate         #                      Set the sampling rate, works on --rtaudio mode only (defaults 48000)" << endl;
+    cout << "   --bufsize       #                      Set the buffer size, works on --rtaudio mode only (defaults 128)" << endl;
+    cout << endl;
+    cout << "HELP ARGUMENTS: " << endl;
+    cout << "===============" << endl;
+    cout << " -v, --version                            Prints Version Number" << endl;
+    cout << " -h, --help                               Prints this Help" << endl;
+    cout << "" << endl;
 }
 
 
@@ -276,13 +331,13 @@ void Settings::printUsage()
 void Settings::startJackTrip()
 {
 
-  ///\todo Change this, just here to test
-  if ( mJackTripServer ) {
-    UdpMasterListener* udpmaster = new UdpMasterListener;
-    udpmaster->start();
-    
-    //---Thread Pool Test--------------------------------------------
-    /*
+    /// \todo Change this, just here to test
+    if ( mJackTripServer ) {
+        UdpMasterListener* udpmaster = new UdpMasterListener;
+        udpmaster->start();
+
+        //---Thread Pool Test--------------------------------------------
+        /*
     cout << "BEFORE START" << endl;
     ThreadPoolTest* thtest = new ThreadPoolTest();
     // QThreadPool takes ownership and deletes 'hello' automatically
@@ -293,84 +348,112 @@ void Settings::startJackTrip()
     thtest->stop();
     QThreadPool::globalInstance()->waitForDone();
     */
-    //---------------------------------------------------------------
-  }
-  
-  else {
-    
-    //JackTrip jacktrip(mJackTripMode, mDataProtocol, mNumChans,
-    //	    mBufferQueueLength, mAudioBitResolution);
-    mJackTrip = new JackTrip(mJackTripMode, mDataProtocol, mNumChans,
-			     mBufferQueueLength, mRedundancy, mAudioBitResolution);
-    
-    // Change client name if different from default
-    if (mClientName != NULL) {
-      mJackTrip->setClientName(mClientName);
+        //---------------------------------------------------------------
     }
 
-    // Set buffers to zero when underrun
-    if ( mUnderrrunZero ) {
-      cout << "Setting buffers to zero when underrun..." << endl;
-      cout << gPrintSeparator << std::endl;
-      mJackTrip->setUnderRunMode(JackTrip::ZEROS);
-    }
-    
-    // Set peer address in server mode
-    if ( mJackTripMode == JackTrip::CLIENT || mJackTripMode == JackTrip::CLIENTTOPINGSERVER ) {
-      mJackTrip->setPeerAddress(mPeerAddress.toLatin1().data()); }
-    
-    // Set Ports
-    cout << "SETTING ALL PORTS" << endl;
-    mJackTrip->setAllPorts(mPortNum);
-
-    // Set in JamLink Mode
-    if ( mJamLink ) {
-      cout << "Running in JamLink Mode..." << endl;
-      cout << gPrintSeparator << std::endl;
-      mJackTrip->setPacketHeaderType(DataProtocol::JAMLINK);
-    }
+    else {
 
-    // Set in EmptyHeader Mode
-    if ( mEmptyHeader ) {
-      cout << "Running in EmptyHeader Mode..." << endl;
-      cout << gPrintSeparator << std::endl;
-      mJackTrip->setPacketHeaderType(DataProtocol::EMPTY);
-    }
+        //JackTrip jacktrip(mJackTripMode, mDataProtocol, mNumChans,
+        //	    mBufferQueueLength, mAudioBitResolution);
+        mJackTrip = new JackTrip(mJackTripMode, mDataProtocol, mNumChans,
+                                 mBufferQueueLength, mRedundancy, mAudioBitResolution);
 
-    // Add Plugins
-    if ( mLoopBack ) {
-      cout << "Running in Loop-Back Mode..." << endl;
-      cout << gPrintSeparator << std::endl;
-      //std::tr1::shared_ptr<LoopBack> loopback(new LoopBack(mNumChans));
-      //mJackTrip->appendProcessPlugin(loopback.get());
-
-      LoopBack* loopback = new LoopBack(mNumChans);
-      mJackTrip->appendProcessPlugin(loopback);
-
-      // ----- Test Karplus Strong -----------------------------------
-      //std::tr1::shared_ptr<NetKS> loopback(new NetKS());
-      //mJackTrip->appendProcessPlugin(loopback);
-      //loopback->play();
-      //NetKS* netks = new NetKS;
-      //mJackTrip->appendProcessPlugin(netks);
-      //netks->play();
-      // -------------------------------------------------------------
-    }
-    
-    // Start JackTrip
-    mJackTrip->start();
-    
-    /* 
+        // Connect Signals and Slots
+        QObject::connect(mJackTrip, SIGNAL( signalProcessesStopped() ),
+                         this, SLOT( slotExitProgram() ));
+
+        // Change client name if different from default
+        if (mClientName != NULL) {
+            mJackTrip->setClientName(mClientName);
+        }
+
+        // Set buffers to zero when underrun
+        if ( mUnderrrunZero ) {
+            cout << "Setting buffers to zero when underrun..." << endl;
+            cout << gPrintSeparator << std::endl;
+            mJackTrip->setUnderRunMode(JackTrip::ZEROS);
+        }
+
+        // Set peer address in server mode
+        if ( mJackTripMode == JackTrip::CLIENT || mJackTripMode == JackTrip::CLIENTTOPINGSERVER ) {
+            mJackTrip->setPeerAddress(mPeerAddress.toLatin1().data()); }
+
+//        if(mLocalAddress!=QString()) // default
+//            mJackTrip->setLocalAddress(QHostAddress(mLocalAddress.toLatin1().data()));
+//        else
+//            mJackTrip->setLocalAddress(QHostAddress::Any);
+
+        // Set Ports
+        //cout << "SETTING ALL PORTS" << endl;
+        mJackTrip->setBindPorts(mBindPortNum);
+        mJackTrip->setPeerPorts(mPeerPortNum);
+
+        // Set in JamLink Mode
+        if ( mJamLink ) {
+            cout << "Running in JamLink Mode..." << endl;
+            cout << gPrintSeparator << std::endl;
+            mJackTrip->setPacketHeaderType(DataProtocol::JAMLINK);
+        }
+
+        // Set in EmptyHeader Mode
+        if ( mEmptyHeader ) {
+            cout << "Running in EmptyHeader Mode..." << endl;
+            cout << gPrintSeparator << std::endl;
+            mJackTrip->setPacketHeaderType(DataProtocol::EMPTY);
+        }
+
+        // Set RtAudio
+#ifdef __RT_AUDIO__
+        if (!mUseJack) {
+            mJackTrip->setAudiointerfaceMode(JackTrip::RTAUDIO);
+        }
+#endif
+
+        // Chanfe default Sampling Rate
+        if (mChanfeDefaultSR) {
+            mJackTrip->setSampleRate(mSampleRate);
+        }
+
+        // Chanfe default Buffer Size
+        if (mChanfeDefaultBS) {
+            mJackTrip->setAudioBufferSizeInSamples(mAudioBufferSize);
+        }
+
+        // Add Plugins
+        if ( mLoopBack ) {
+            cout << "Running in Loop-Back Mode..." << endl;
+            cout << gPrintSeparator << std::endl;
+            //std::tr1::shared_ptr<LoopBack> loopback(new LoopBack(mNumChans));
+            //mJackTrip->appendProcessPlugin(loopback.get());
+
+            LoopBack* loopback = new LoopBack(mNumChans);
+            mJackTrip->appendProcessPlugin(loopback);
+
+            // ----- Test Karplus Strong -----------------------------------
+            //std::tr1::shared_ptr<NetKS> loopback(new NetKS());
+            //mJackTrip->appendProcessPlugin(loopback);
+            //loopback->play();
+            //NetKS* netks = new NetKS;
+            //mJackTrip->appendProcessPlugin(netks);
+            //netks->play();
+            // -------------------------------------------------------------
+        }
+
+        // Start JackTrip
+        mJackTrip->startProcess();
+        mJackTrip->start();
+
+        /*
        sleep(10);
        cout << "Stoping JackTrip..." << endl;
        mJackTrip->stop();
     */
-  }
+    }
 }
 
 
 //*******************************************************************************
 void Settings::stopJackTrip()
 {
-  mJackTrip->stop();
+    mJackTrip->stop();
 }
diff --git a/src/Settings.h b/src/Settings.h
index 5c08808..90eea26 100644
--- a/src/Settings.h
+++ b/src/Settings.h
@@ -39,14 +39,22 @@
 #ifndef __SETTINGS_H__
 #define __SETTINGS_H__
 
+#include <cstdlib>
+
 #include "DataProtocol.h"
+
+#ifndef __NO_JACK__
 #include "JackAudioInterface.h"
+#endif //__NO_JACK__
+
 #include "JackTrip.h"
 
 /** \brief Class to set usage options and parse settings from input
  */
-class Settings
+class Settings : public QThread
 {
+  Q_OBJECT;
+
 public:
   Settings();
   virtual ~Settings();
@@ -60,7 +68,15 @@ public:
   /// \brief Prints usage help
   void printUsage();
 
-  bool getLoopBack() { return mLoopBack; };
+  bool getLoopBack() { return mLoopBack; }
+
+
+public slots:
+  void slotExitProgram()
+  {
+    std::cerr << "Exiting JackTrip..." << std::endl;
+    std::exit(1);
+  }
 
 private:
   JackTrip* mJackTrip; ///< JackTrip class
@@ -68,17 +84,24 @@ private:
   JackTrip::dataProtocolT mDataProtocol; ///< Data Protocol
   int mNumChans; ///< Number of Channels (inputs = outputs)
   int mBufferQueueLength; ///< Audio Buffer from network queue length
-  JackAudioInterface::audioBitResolutionT mAudioBitResolution;
+  AudioInterface::audioBitResolutionT mAudioBitResolution;
   QString mPeerAddress; ///< Peer Address to use in jacktripModeT::CLIENT Mode
-  int mPortNum; ///< Port Number
-  char* mClientName;
+  int mBindPortNum; ///< Bind Port Number
+  int mPeerPortNum; ///< Peer Port Number
+  char* mClientName; ///< JackClient Name
   bool mUnderrrunZero; ///< Use Underrun to Zero mode
 
   bool mLoopBack; ///< Loop-back mode
   bool mJamLink; ///< JamLink mode
   bool mEmptyHeader; ///< EmptyHeader mode
   bool mJackTripServer; ///< JackTrip Server mode
+  QString mLocalAddress; ///< Local Address
   unsigned int mRedundancy; ///< Redundancy factor for data in the network
+  bool mUseJack; ///< Use or not JackAduio
+  bool mChanfeDefaultSR; ///< Change Default Sampling Rate
+  bool mChanfeDefaultBS; ///< Change Default Buffer Size
+  unsigned int mSampleRate;
+  unsigned int mAudioBufferSize;
 };
 
 #endif
diff --git a/src/UdpDataProtocol.cpp b/src/UdpDataProtocol.cpp
index 9e2275f..0cd1369 100644
--- a/src/UdpDataProtocol.cpp
+++ b/src/UdpDataProtocol.cpp
@@ -39,12 +39,19 @@
 #include "jacktrip_globals.h"
 #include "JackTrip.h"
 
+#include <QHostInfo>
+
 #include <cstring>
 #include <iostream>
 #include <cstdlib>
 #include <cerrno>
 #include <stdexcept>
+#ifdef __WIN_32__
+#include <winsock.h>
+#endif
+#if defined (__LINUX__) || (__MAC__OSX__)
 #include <sys/socket.h> // for POSIX Sockets
+#endif
 
 using std::cout; using std::endl;
 
@@ -65,6 +72,7 @@ mRunMode(runmode),
 mAudioPacket(NULL), mFullPacket(NULL),
 mUdpRedundancyFactor(udp_redundancy_factor)
 {
+  mStopped = false;
   if (mRunMode == RECEIVER) {
     QObject::connect(this, SIGNAL(signalWatingTooLong(int)),
                      jacktrip, SLOT(slotUdpWatingTooLong(int)), Qt::QueuedConnection);
@@ -82,14 +90,26 @@ UdpDataProtocol::~UdpDataProtocol()
 
 
 //*******************************************************************************
-void UdpDataProtocol::setPeerAddress(const char* peerHostOrIP)
+void UdpDataProtocol::setPeerAddress(const char* peerHostOrIP) throw(std::invalid_argument)
 {
-  mPeerAddress.setAddress(peerHostOrIP);
+  // Get DNS Address
+  QHostInfo info = QHostInfo::fromName(peerHostOrIP);
+  if (!info.addresses().isEmpty()) {
+    // use the first IP address
+    mPeerAddress = info.addresses().first();
+    //cout << "UdpDataProtocol::setPeerAddress IP Address Number: "
+    //    << mPeerAddress.toString().toStdString() << endl;
+  }
+
   // check if the ip address is valid
   if ( mPeerAddress.isNull() ) {
-    std::cerr << "ERROR: Incorrect presentation format address" << endl;
-    std::cerr << "'" << peerHostOrIP <<"' does not seem to be a valid IP address" << endl;
-    throw std::invalid_argument("");
+    QString error_message = "Incorrect presentation format address\n '";
+    error_message.append(peerHostOrIP);
+    error_message.append("' is not a valid IP address or Host Name");
+    //std::cerr << "ERROR: Incorrect presentation format address" << endl;
+    //std::cerr << "'" << peerHostOrIP <<"' does not seem to be a valid IP address" << endl;
+    //throw std::invalid_argument("Incorrect presentation format address");
+    throw std::invalid_argument( error_message.toStdString());
   }
   /*
   else {
@@ -103,16 +123,51 @@ void UdpDataProtocol::setPeerAddress(const char* peerHostOrIP)
 
 
 //*******************************************************************************
-void UdpDataProtocol::bindSocket(QUdpSocket& UdpSocket)
+void UdpDataProtocol::bindSocket(QUdpSocket& UdpSocket) throw(std::runtime_error)
 {
   QMutexLocker locker(&sUdpMutex);
 
+#if defined __WIN_32__
+  WORD wVersionRequested;
+  WSADATA wsaData;
+  int err;
+
+  wVersionRequested = MAKEWORD( 1, 1 );
+
+  err = WSAStartup( wVersionRequested, &wsaData );
+  if ( err != 0 ) {
+    // Tell the user that we couldn't find a useable
+    // winsock.dll.
+
+    return;
+  }
+
+  // Confirm that the Windows Sockets DLL supports 1.1. or higher
+
+  if ( LOBYTE( wsaData.wVersion ) != 1 ||
+       HIBYTE( wsaData.wVersion ) != 1 ) {
+    // Tell the user that we couldn't find a useable
+    // winsock.dll.
+    WSACleanup( );
+    return;
+  }
+
   // Creat socket descriptor
-  int sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
+  SOCKET sock_fd;
+  SOCKADDR_IN local_addr;
+#endif
 
-  // Set local IPv4 Address
+#if defined ( __LINUX__ ) || (__MAC_OSX__)
+  int sock_fd;
+  //Set local IPv4 Address
   struct sockaddr_in local_addr;
-  ::bzero(&local_addr, sizeof(local_addr));
+#endif
+
+  // Creat socket descriptor
+  sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
+
+  //::bzero(&local_addr, sizeof(local_addr));
+  std::memset(&local_addr, 0, sizeof(local_addr)); // set buffer to 0
   local_addr.sin_family = AF_INET; //AF_INET: IPv4 Protocol
   local_addr.sin_addr.s_addr = htonl(INADDR_ANY); //INADDR_ANY: let the kernel decide the active address
   local_addr.sin_port = htons(mBindPort); //set local port
@@ -127,10 +182,22 @@ void UdpDataProtocol::bindSocket(QUdpSocket& UdpSocket)
   // has problems rebinding a socket
   ::setsockopt(sock_fd, SOL_SOCKET, SO_REUSEPORT, &one, sizeof(one));
 #endif
+#if defined (__WIN_32__)
+  //make address/port reusable
+  setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, (char*)&one, sizeof(one));
+#endif
 
   // Bind the Socket
+#if defined ( __LINUX__ ) || ( __MAC_OSX__ )
   if ( (::bind(sock_fd, (struct sockaddr *) &local_addr, sizeof(local_addr))) < 0 )
   { throw std::runtime_error("ERROR: UDP Socket Bind Error"); }
+#endif
+#if defined (__WIN_32__)
+  //int bound;
+  //bound = bind(sock_fd, (SOCKADDR *) &local_addr, sizeof(local_addr));
+  if ( (bind(sock_fd, (SOCKADDR *) &local_addr, sizeof(local_addr))) == SOCKET_ERROR )
+  { throw std::runtime_error("ERROR: UDP Socket Bind Error"); }
+#endif
 
   // To be able to use the two UDP sockets bound to the same port number,
   // we connect the receiver and issue a SHUT_WR.
@@ -140,6 +207,7 @@ void UdpDataProtocol::bindSocket(QUdpSocket& UdpSocket)
                                   QUdpSocket::WriteOnly);
   }
   else if (mRunMode == RECEIVER) {
+#if defined (__LINUX__) || (__MAC_OSX__)
     // Set peer IPv4 Address
     struct sockaddr_in peer_addr;
     bzero(&peer_addr, sizeof(peer_addr));
@@ -155,6 +223,31 @@ void UdpDataProtocol::bindSocket(QUdpSocket& UdpSocket)
     { throw std::runtime_error("ERROR: Could not connect UDP socket"); }
     if ( (::shutdown(sock_fd,SHUT_WR)) < 0)
     { throw std::runtime_error("ERROR: Could suntdown SHUT_WR UDP socket"); }
+#endif
+#if defined __WIN_32__
+    // Set peer IPv4 Address
+    SOCKADDR_IN peer_addr;
+    std::memset(&peer_addr, 0, sizeof(peer_addr)); // set buffer to 0
+    peer_addr.sin_family = AF_INET; //AF_INET: IPv4 Protocol
+    peer_addr.sin_addr.s_addr = htonl(INADDR_ANY); //INADDR_ANY: let the kernel decide the active address
+    peer_addr.sin_port = htons(mPeerPort); //set local port
+    // Connect the socket and issue a Write shutdown (to make it a
+    // reader socket only)
+    peer_addr.sin_addr.s_addr = inet_addr(mPeerAddress.toString().toLatin1().constData());
+    int con = (::connect(sock_fd, (struct sockaddr *) &peer_addr, sizeof(peer_addr)));
+    if ( con < 0)
+    {
+      fprintf(stderr, "ERROR: Could not connect UDP socket");
+      throw std::runtime_error("ERROR: Could not connect UDP socket");
+    }
+    //cout<<"connect returned: "<<con<<endl;
+    int shut_sr = shutdown(sock_fd, SD_SEND);  //shut down sender's receive function
+    if ( shut_sr< 0)
+    {
+      fprintf(stderr, "ERROR: Could not shutdown SD_SEND UDP socket");
+      throw std::runtime_error("ERROR: Could not shutdown SD_SEND UDP socket");
+    }
+#endif
 
     UdpSocket.setSocketDescriptor(sock_fd, QUdpSocket::ConnectedState,
                                   QUdpSocket::ReadOnly);
@@ -221,11 +314,20 @@ void UdpDataProtocol::getPeerAddressFromFirstPacket(QUdpSocket& UdpSocket,
 //*******************************************************************************
 void UdpDataProtocol::run()
 {
-  mStopped = false;
-  
+  //QObject::connect(this, SIGNAL(signalError(const char*)),
+  //                 mJackTrip, SLOT(slotStopProcesses()),
+  //                 Qt::QueuedConnection);
+
   // Creat and bind sockets
   QUdpSocket UdpSocket;
-  bindSocket(UdpSocket); // Bind Socket
+  try {
+    bindSocket(UdpSocket); // Bind Socket
+  } catch ( const std::exception & e ) {
+    emit signalError( e.what() );
+    return;
+  }
+
+
   QHostAddress PeerAddress;
   PeerAddress = mPeerAddress;
 
@@ -257,30 +359,34 @@ void UdpDataProtocol::run()
   // 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 : {
+      // Connect signals and slots for packets arriving too late notifications
+      QObject::connect(this, SIGNAL(signalWatingTooLong(int)),
+                       this, SLOT(printUdpWaitedTooLong(int)),
+                       Qt::QueuedConnection);
       //----------------------------------------------------------------------------------- 
       // 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); }
+      while ( !UdpSocket.hasPendingDatagrams() ) {
+        if (mStopped) { return; }
+        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];
+      int8_t* first_packet = new int8_t[first_packet_size];
+      /// \todo fix this to avoid memory leaks
       // 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);
+      //std::tr1::shared_ptr<int8_t> first_packet(new int8_t[first_packet_size]);
+      receivePacket( UdpSocket, reinterpret_cast<char*>(first_packet), first_packet_size);
       // Check that peer has the same audio settings
-      mJackTrip->checkPeerSettings(first_packet.get());
+      mJackTrip->checkPeerSettings(first_packet);
       mJackTrip->parseAudioPacket(mFullPacket, mAudioPacket);
       std::cout << "Received Connection for Peer!" << std::endl;
+      emit signalReceivedConnectionFromPeer();
 
       // Redundancy Variables
       // --------------------
@@ -357,7 +463,7 @@ bool UdpDataProtocol::waitForReady(QUdpSocket& UdpSocket, int timeout_msec)
 
   while ( ( !(UdpSocket.hasPendingDatagrams()) && (ellaped_time_usec <= timeout_usec) )
     && !mStopped ){
-    //cout << mStopped << endl;
+    if (mStopped) { return false; }
     QThread::usleep(loop_resolution_usec);
     ellaped_time_usec += loop_resolution_usec;
     
@@ -380,7 +486,7 @@ void UdpDataProtocol::printUdpWaitedTooLong(int wait_msec)
 {
   int wait_time = 30; // msec
   if ( !(wait_msec%wait_time) ) {
-    std::cerr << "UDP is waited too long (more than " << wait_time << "ms)..." << endl;
+    std::cerr << "UDP waiting too long (more than " << wait_time << "ms)..." << endl;
   }
 }
 
@@ -409,7 +515,7 @@ void UdpDataProtocol::receivePacketRedundancy(QUdpSocket& UdpSocket,
   for (unsigned int i = 1; i<mUdpRedundancyFactor; i++) {
     // Check if the package we receive is the next one expected, i.e.,
     // current_seq_num == (last_seq_num+1)
-    if ( (current_seq_num == (last_seq_num+1))) { break; }
+    if ( current_seq_num == (last_seq_num+1) ) { break; }
 
     // if it's not, check the next one until it is the corresponding packet
     // or there aren't more available packets
diff --git a/src/UdpDataProtocol.h b/src/UdpDataProtocol.h
index fbce562..4015023 100644
--- a/src/UdpDataProtocol.h
+++ b/src/UdpDataProtocol.h
@@ -38,9 +38,12 @@
 #ifndef __UDPDATAPROTOCOL_H__
 #define __UDPDATAPROTOCOL_H__
 
+#include <stdexcept>
+
 #include <QThread>
 #include <QUdpSocket>
 #include <QHostAddress>
+#include <QMutex>
 
 #include "DataProtocol.h"
 #include "jacktrip_types.h"
@@ -84,7 +87,7 @@ public:
   /** \brief Set the Peer address to connect to
    * \param peerHostOrIP IPv4 number or host name
    */
-  void setPeerAddress(const char* peerHostOrIP);
+  void setPeerAddress(const char* peerHostOrIP) throw(std::invalid_argument);
 
   /** \brief Receives a packet. It blocks until a packet is received
    *
@@ -146,11 +149,12 @@ signals:
   void signalWatingTooLong(int wait_msec);
 
 
-private:
+//private:
+protected:
 
   /** \brief Binds the UDP socket to the available address and specified port
    */
-  void bindSocket(QUdpSocket& UdpSocket);
+  void bindSocket(QUdpSocket& UdpSocket) throw(std::runtime_error);
  
   /** \brief This function blocks until data is available for reading in the 
    * QUdpSocket. The function will timeout after timeout_msec microseconds.
@@ -165,21 +169,24 @@ private:
 
   /** \brief Redundancy algorythm at the receiving end
     */
-  void receivePacketRedundancy(QUdpSocket& UdpSocket,
-                               int8_t* full_redundant_packet,
-                               int full_redundant_packet_size,
-                               int full_packet_size,
-                               uint16_t& current_seq_num,
-                               uint16_t& last_seq_num,
-                               uint16_t& newer_seq_num);
-
-  /** \brief Redundancy algorythm at the sender  end
+  virtual void receivePacketRedundancy(QUdpSocket& UdpSocket,
+                                       int8_t* full_redundant_packet,
+                                       int full_redundant_packet_size,
+                                       int full_packet_size,
+                                       uint16_t& current_seq_num,
+                                       uint16_t& last_seq_num,
+                                       uint16_t& newer_seq_num);
+
+  /** \brief Redundancy algorythm at the sender's end
     */
-  void sendPacketRedundancy(QUdpSocket& UdpSocket,
-                            QHostAddress& PeerAddress,
-                            int8_t* full_redundant_packet,
-                            int full_redundant_packet_size,
-                            int full_packet_size);
+  virtual void sendPacketRedundancy(QUdpSocket& UdpSocket,
+                                    QHostAddress& PeerAddress,
+                                    int8_t* full_redundant_packet,
+                                    int full_redundant_packet_size,
+                                    int full_packet_size);
+
+
+private:
 
   int mBindPort; ///< Local Port number to Bind
   int mPeerPort; ///< Peer Port number
diff --git a/src/UdpMasterListener.cpp b/src/UdpMasterListener.cpp
index 874eda4..6650eaa 100644
--- a/src/UdpMasterListener.cpp
+++ b/src/UdpMasterListener.cpp
@@ -38,6 +38,12 @@
 #include <iostream>
 #include <cstdlib>
 #include <stdexcept>
+#include <cstring>
+
+#include <QTcpServer>
+#include <QTcpSocket>
+#include <QStringList>
+#include <QMutexLocker>
 
 #include "UdpMasterListener.h"
 #include "JackTripWorker.h"
@@ -48,13 +54,20 @@ using std::cout; using std::endl;
 
 //*******************************************************************************
 UdpMasterListener::UdpMasterListener(int server_port) :
-    mJTWorker(NULL),
+    //mJTWorker(NULL),
     mServerPort(server_port),
     mStopped(false),
     mTotalRunningThreads(0)
 {
   // Register JackTripWorker with the master listener
-  mJTWorker = new JackTripWorker(this);
+  //mJTWorker = new JackTripWorker(this);
+  mJTWorkers = new QVector<JackTripWorker*>;
+  for (int i = 0; i<gMaxThreads; i++) {
+    mJTWorkers->insert(i, NULL);
+  }
+
+
+  //mJTWorkers = new JackTripWorker(this);
   mThreadPool.setExpiryTimeout(3000); // msec (-1) = forever
   // Inizialize IP addresses
   for (int i = 0; i<gMaxThreads; i++) { 
@@ -63,23 +76,138 @@ UdpMasterListener::UdpMasterListener(int server_port) :
   }
   // Set the base dynamic port
   // The Dynamic and/or Private Ports are those from 49152 through 65535
-  mBasePort = ( random() % ( (65535 - gMaxThreads) - 49152 ) ) + 49152;
+  // mBasePort = ( rand() % ( (65535 - gMaxThreads) - 49152 ) ) + 49152;
+
+  // SoundWIRE ports open are UDP 61000-62000
+  mBasePort = 61000;
 }
 
 
 //*******************************************************************************
 UdpMasterListener::~UdpMasterListener()
 {
-  mThreadPool.waitForDone ();
-  delete mJTWorker;
+  QMutexLocker lock(&mMutex);
+  mThreadPool.waitForDone();
+  //delete mJTWorker;
+  for (int i = 0; i<gMaxThreads; i++) {
+    delete mJTWorkers->at(i);
+  }
+  delete mJTWorkers;
 }
 
 
 //*******************************************************************************
+// Now that the first handshake is with TCP server, if the addreess/peer port of
+// the client is already on the thread pool, it means that a new connection is
+// requested (the old was desconnected). So we have to remove that thread from
+// the pool and then connect again.
 void UdpMasterListener::run()
 {
   mStopped = false;
 
+  QHostAddress PeerAddress; // Object to store peer address
+  int peer_udp_port; // Peer listening port
+  int server_udp_port; // Server assigned udp port
+
+  // Create and bind the TCP server
+  // ------------------------------
+  QTcpServer TcpServer;
+  if ( !TcpServer.listen(QHostAddress::Any, mServerPort) ) {
+    std::cerr << "TCP Socket Server ERROR: " << TcpServer.errorString().toStdString() <<  endl;
+    std::exit(1);
+  }
+
+  const int tcpTimeout = 5*1000;
+
+
+  cout << "JackTrip MULTI-THREADED SERVER: TCP Server Listening in Port = " << TcpServer.serverPort() << endl;
+  while ( !mStopped )
+  {
+    cout << "JackTrip MULTI-THREADED SERVER: Waiting for client connections..." << endl;
+    cout << "=======================================================" << endl;
+    while ( !TcpServer.waitForNewConnection(1000) )
+    { if (mStopped) { return; } } // block until a new connection is received
+    cout << "JackTrip MULTI-THREADED SERVER: Client Connection Received!" << endl;
+
+    // Control loop to be able to exit if UDPs or TCPs error ocurr
+    for (int dum = 0; dum<1; dum++) {
+      QTcpSocket *clientConnection = TcpServer.nextPendingConnection();
+      if ( !clientConnection->waitForConnected(tcpTimeout) ) {
+        std::cerr << clientConnection->errorString().toStdString() << endl;
+        break;
+      }
+      PeerAddress = clientConnection->peerAddress();
+      cout << "JackTrip MULTI-THREADED SERVER: Client Connect Received from Address : "
+          << PeerAddress.toString().toStdString() << endl;
+
+      // Get UDP port from client
+      // ------------------------
+      peer_udp_port = readClientUdpPort(clientConnection);
+      if ( peer_udp_port == 0 ) { break; }
+      cout << "JackTrip MULTI-THREADED SERVER: Client UDP Port is = " << peer_udp_port << endl;
+
+      // Check is client is new or not
+      // -----------------------------
+      // Check if Address is not already in the thread pool
+      // check by comparing 32-bit addresses
+      int id = isNewAddress(PeerAddress.toIPv4Address(), peer_udp_port);
+      // If the address is not new, we need to remove the client from the pool
+      // before re-starting the connection
+      if (id == -1) {
+        int id_remove;
+        id_remove = getPoolID(PeerAddress.toIPv4Address(), peer_udp_port);
+        // stop the thread
+        mJTWorkers->at(id_remove)->stopThread();
+        // block until the thread has been removed from the pool
+        while ( isNewAddress(PeerAddress.toIPv4Address(), peer_udp_port) == -1 ) {
+          cout << "JackTrip MULTI-THREADED SERVER: Removing JackTripWorker from pool..." << endl;
+          QThread::msleep(10);
+        }
+        // Get a new ID for this client
+        //id = isNewAddress(PeerAddress.toIPv4Address(), peer_udp_port);
+        id = getPoolID(PeerAddress.toIPv4Address(), peer_udp_port);
+      }
+      // Assign server port and send it to Client
+      server_udp_port = mBasePort+id;
+      if ( sendUdpPort(clientConnection, server_udp_port) == 0 ) {
+        clientConnection->close();
+        delete clientConnection;
+        releaseThread(id);
+        break;
+      }
+
+      // Close and Delete the socket
+      // ---------------------------
+      clientConnection->close();
+      delete clientConnection;
+      cout << "JackTrip MULTI-THREADED SERVER: Client TCP Socket Closed!" << endl;
+
+      // Spawn Thread to Pool
+      // --------------------
+      // Register JackTripWorker with the master listener
+      delete mJTWorkers->at(id); // just in case the Worker was previously created
+      mJTWorkers->replace(id, new JackTripWorker(this));
+      // redirect port and spawn listener
+      cout << "---> JackTrip MULTI-THREADED SERVER: Spawning Listener..." << endl;
+      {
+        QMutexLocker lock(&mMutex);
+        mJTWorkers->at(id)->setJackTrip(id, mActiveAddress[id][0],
+                                        server_udp_port, mActiveAddress[id][1],
+                                        1); /// \todo temp default to 1 channel
+      }
+      //send one thread to the pool
+      cout << "---> JackTrip MULTI-THREADED SERVER: Starting Thread..." << endl;
+      mThreadPool.start(mJTWorkers->at(id), QThread::TimeCriticalPriority);
+      // wait until one is complete before another spawns
+      while (mJTWorkers->at(id)->isSpawning()) { QThread::msleep(10); }
+      //mTotalRunningThreads++;
+      cout << "JackTrip MULTI-THREADED SERVER: Total Running Threads:  " << mTotalRunningThreads << endl;
+      cout << "===============================================================" << endl;
+      QThread::msleep(100);
+    }
+  }
+
+  /*
   // Create objects on the stack
   QUdpSocket MasterUdpSocket;
   QHostAddress PeerAddress;
@@ -93,59 +221,110 @@ void UdpMasterListener::run()
   cout << "Waiting for client..." << endl;
   cout << "=======================================================" << endl;
   while ( !mStopped )
+  {
+    //cout << "WAITING........................." << endl;
+    while ( MasterUdpSocket.hasPendingDatagrams() )
     {
-      //cout << "WAITING........................." << endl;
-      while ( MasterUdpSocket.hasPendingDatagrams() ) 
-	{
-	  //cout << "Received request from Client!" << endl;
-	  // Get Client IP Address and outgoing port from packet
-	  int rv = MasterUdpSocket.readDatagram(buf, 1, &PeerAddress, &peer_port);
-	  //cout << "Peer Port in Server ==== " << peer_port << endl;
-	  if (rv < 0) { std::cerr << "ERROR: Bad UDP packet read..." << endl; }
-
-	  /// \todo Get number of channels in the client from header
-
-	  // check by comparing 32-bit addresses
-	  /// \todo Add the port number in the comparison
-	  int id = isNewAddress(PeerAddress.toIPv4Address(), peer_port);
-
-	  //cout << "IDIDIDIDIDDID === " << id << endl;
-
-	  // If the address is new, create a new thread in the pool
-	  if (id >= 0) // old address is -1
-	    {
-	      // redirect port and spawn listener
-	      sendToPoolPrototype(id);
-	      // wait until one is complete before another spawns
-	      while (mJTWorker->isSpawning()) { QThread::msleep(1); }
-	      mTotalRunningThreads++;
-	      cout << "Total Running Threads:  " << mTotalRunningThreads << endl;
-	      cout << "=======================================================" << endl;
-	    }
-	  //cout << "ENDDDDDDDDDDDDDDDDDd === " << id << endl;
-	}
-      QThread::msleep(100);
+      cout << "Received request from Client!" << endl;
+      // Get Client IP Address and outgoing port from packet
+      int rv = MasterUdpSocket.readDatagram(buf, 1, &PeerAddress, &peer_port);
+      cout << "Peer Port in Server ==== " << peer_port << endl;
+      if (rv < 0) { std::cerr << "ERROR: Bad UDP packet read..." << endl; }
+
+      /// \todo Get number of channels in the client from header
+
+      // check by comparing 32-bit addresses
+      /// \todo Add the port number in the comparison
+      cout << "peer_portpeer_portpeer_port === " << peer_port << endl;
+      int id = isNewAddress(PeerAddress.toIPv4Address(), peer_port);
+
+      //cout << "IDIDIDIDIDDID === " << id << endl;
+
+      // If the address is new, create a new thread in the pool
+      if (id >= 0) // old address is -1
+      {
+        // redirect port and spawn listener
+        sendToPoolPrototype(id);
+        // wait until one is complete before another spawns
+        while (mJTWorker->isSpawning()) { QThread::msleep(10); }
+        mTotalRunningThreads++;
+        cout << "Total Running Threads:  " << mTotalRunningThreads << endl;
+        cout << "=======================================================" << endl;
+      }
+      //cout << "ENDDDDDDDDDDDDDDDDDd === " << id << endl;
+    }
+    QThread::msleep(100);
+  }
+  */
+}
+
+
+//*******************************************************************************
+// Returns 0 on error
+int UdpMasterListener::readClientUdpPort(QTcpSocket* clientConnection)
+{
+  // Read the size of the package
+  // ----------------------------
+  //tcpClient.waitForReadyRead();
+  cout << "Reading UDP port from Server..." << endl;
+  while (clientConnection->bytesAvailable() < (int)sizeof(uint16_t)) {
+    if (!clientConnection->waitForReadyRead()) {
+      std::cerr << "TCP Socket ERROR: " << clientConnection->errorString().toStdString() <<  endl;
+      return 0;
+    }
+  }
+
+  cout << "Ready To Read From Socket!" << endl;
+  // Read UDP Port Number from Server
+  // --------------------------------
+  int udp_port;
+  int size = sizeof(udp_port);
+  char port_buf[size];
+  clientConnection->read(port_buf, size);
+  std::memcpy(&udp_port, port_buf, size);
+  return udp_port;
+}
+
+
+//*******************************************************************************
+int UdpMasterListener::sendUdpPort(QTcpSocket* clientConnection, int udp_port)
+{
+  // Send Port Number to Client
+  // --------------------------
+  char port_buf[sizeof(udp_port)];
+  std::memcpy(port_buf, &udp_port, sizeof(udp_port));
+  clientConnection->write(port_buf, sizeof(udp_port));
+  while ( clientConnection->bytesToWrite() > 0 ) {
+    if ( clientConnection->state() == QAbstractSocket::ConnectedState ) {
+      clientConnection->waitForBytesWritten(-1);
     }
+    else {
+      return 0;
+    }
+  }
+  return 1;
+  cout << "Port sent to Client" << endl;
 }
 
 
 //*******************************************************************************
+/*
 void UdpMasterListener::sendToPoolPrototype(int id)
 {
-  cout << "id ID **********@@@@@@@@@@@@@@@@@@@@@************** " << id <<  endl;
   mJTWorker->setJackTrip(id, mActiveAddress[id][0],
-			 mBasePort+(2*id), mActiveAddress[id][1],
-			 1); /// \todo temp default to 1 channel
+                         mBasePort+(2*id), mActiveAddress[id][1],
+                         1); /// \todo temp default to 1 channel
   mThreadPool.start(mJTWorker, QThread::TimeCriticalPriority); //send one thread to the pool
 }
+*/
 
 
 //*******************************************************************************
-void UdpMasterListener::bindUdpSocket(QUdpSocket& udpsocket, int port)
+void UdpMasterListener::bindUdpSocket(QUdpSocket& udpsocket, int port) throw(std::runtime_error)
 {
   // QHostAddress::Any : let the kernel decide the active address
   if ( !udpsocket.bind(QHostAddress::Any,
-			port, QUdpSocket::DefaultForPlatform) ) {
+                       port, QUdpSocket::DefaultForPlatform) ) {
     //std::cerr << "ERROR: could not bind UDP socket" << endl;
     //std::exit(1);
     throw std::runtime_error("Could not bind UDP socket. It may be already binded.");
@@ -160,27 +339,73 @@ void UdpMasterListener::bindUdpSocket(QUdpSocket& udpsocket, int port)
 // check by comparing 32-bit addresses
 int UdpMasterListener::isNewAddress(uint32_t address, uint16_t port)
 {
-  /// \todo Add the port number in the comparison, i.e., compart IP/port pair
-  
+  QMutexLocker lock(&mMutex);
   bool busyAddress = false;
   int id = 0;
+
+  /*
   while ( !busyAddress && (id<mThreadPool.activeThreadCount()) )
-    {
-      if ( address==mActiveAddress[id][0] &&  port==mActiveAddress[id][1]) { busyAddress = true; }
-      id++;
-    }      
-  if ( !busyAddress ) { 
+  {
+    if ( address==mActiveAddress[id][0] &&  port==mActiveAddress[id][1]) { busyAddress = true; }
+    id++;
+  }
+  */
+  for (int i = 0; i<gMaxThreads; i++) {
+    if ( address==mActiveAddress[i][0] &&  port==mActiveAddress[i][1]) {
+      id = i;
+      busyAddress = true;
+    }
+  }
+  if ( !busyAddress ) {
+    /*
     mActiveAddress[id][0] = address;
     mActiveAddress[id][1] = port;
+  } else {
+  */
+    id = 0;
+    bool foundEmptyAddress = false;
+    while ( !foundEmptyAddress && (id<gMaxThreads) ) {
+      if ( (mActiveAddress[id][0] == 0) &&  (mActiveAddress[id][1] == 0) ) {
+        foundEmptyAddress = true;
+        mActiveAddress[id][0] = address;
+        mActiveAddress[id][1] = port;
+      }  else {
+        id++;
+      }
+    }
+  }
+  if (!busyAddress) {
+    mTotalRunningThreads++;
   }
   return ((busyAddress) ? -1 : id);
 }
 
 
 //*******************************************************************************
-int UdpMasterListener::releasePort(int id)
+int UdpMasterListener::getPoolID(uint32_t address, uint16_t port)
+{
+  QMutexLocker lock(&mMutex);
+  //for (int id = 0; id<mThreadPool.activeThreadCount(); id++ )
+  for (int id = 0; id<gMaxThreads; id++ )
+  {
+    if ( address==mActiveAddress[id][0] &&  port==mActiveAddress[id][1])
+    { return id; }
+  }
+  return -1;
+}
+
+
+//*******************************************************************************
+int UdpMasterListener::releaseThread(int id)
 { 
+  QMutexLocker lock(&mMutex);
   mActiveAddress[id][0] = 0;
   mActiveAddress[id][1] = 0;
+  mTotalRunningThreads--;
   return 0; /// \todo Check if we really need to return an argument here
 }
+
+
+// TODO:
+// USE bool QAbstractSocket::isValid () const to check if socket is connect. if not, exit loop
+
diff --git a/src/UdpMasterListener.h b/src/UdpMasterListener.h
index 338229e..184176d 100644
--- a/src/UdpMasterListener.h
+++ b/src/UdpMasterListener.h
@@ -39,11 +39,15 @@
 #define __UDPMASTERLISTENER_H__
 
 #include <iostream>
+#include <stdexcept>
 
 #include <QThread>
 #include <QThreadPool>
 #include <QUdpSocket>
 #include <QHostAddress>
+#include <QTcpSocket>
+#include <QTcpServer>
+#include <QMutex>
 
 #include "jacktrip_types.h"
 #include "jacktrip_globals.h"
@@ -63,25 +67,23 @@ public:
   UdpMasterListener(int server_port = gServerUdpPort);
   virtual ~UdpMasterListener();
   
-  /** \brief Implements the Thread Loop. To start the thread, call start()
-   * ( DO NOT CALL run() )
-   */
+  /// \brief Implements the Thread Loop. To start the thread, call start()
+  /// ( DO NOT CALL run() )
   void run();
 
   /// \brief Stops the execution of the Thread
-  void stop() { mStopped = true; };
+  void stop() { mStopped = true; }
 
-  int releasePort(int id);
+  int releaseThread(int id);
 
 private slots:
-  void testRecieve()
-  {
-    std::cout << "========= TEST RECEIVE SLOT ===========" << std::endl;
-  }
+  void testReceive()
+  { std::cout << "========= TEST RECEIVE SLOT ===========" << std::endl; }
 
 signals:
   void Listening();
   void ClientAddressSet();
+  void signalRemoveThread(int id);
 
 
 private:
@@ -89,13 +91,17 @@ private:
    * \param udpsocket a QUdpSocket
    * \param port Port number
    */
-  static void bindUdpSocket(QUdpSocket& udpsocket, int port);
+  static void bindUdpSocket(QUdpSocket& udpsocket, int port) throw(std::runtime_error);
+
+  int readClientUdpPort(QTcpSocket* clientConnection);
+  int sendUdpPort(QTcpSocket* clientConnection, int udp_port);
 
-  /* \brief Send the JackTripWorker to the thread pool. This will run
+
+  /** \brief Send the JackTripWorker to the thread pool. This will run
    * until it's done. We still have control over the prototype class.
    * \param id Identification Number
    */
-  void sendToPoolPrototype(int id);
+  //void sendToPoolPrototype(int id);
 
   /** \brief Check if address is already handled, if not add to array
    * \param IPv4 address as a number
@@ -103,10 +109,16 @@ private:
    */ 
   int isNewAddress(uint32_t address, uint16_t port);
 
-  QUdpSocket mUdpMasterSocket; ///< The UDP socket
-  QHostAddress mPeerAddress; ///< The Peer Address
+  /** \brief Returns the ID of the client in the pool. If the client
+    * is not in the pool yet, returns -1.
+    */
+  int getPoolID(uint32_t address, uint16_t port);
+
+  //QUdpSocket mUdpMasterSocket; ///< The UDP socket
+  //QHostAddress mPeerAddress; ///< The Peer Address
 
-  JackTripWorker* mJTWorker; ///< Class that will be used as prototype
+  //JackTripWorker* mJTWorker; ///< Class that will be used as prototype
+  QVector<JackTripWorker*>* mJTWorkers; ///< Vector of JackTripWorker s
   QThreadPool mThreadPool; ///< The Thread Pool
 
   int mServerPort; //< Server known port number
@@ -117,6 +129,7 @@ private:
   /// Boolean stop the execution of the thread
   volatile bool mStopped;
   int mTotalRunningThreads; ///< Number of Threads running in the pool
+  QMutex mMutex;
 };
 
 
diff --git a/src/build b/src/build
index 546567d..18f47fa 100755
--- a/src/build
+++ b/src/build
@@ -14,12 +14,32 @@ fi
 
 # Set qmake command name
 if [[ $platform == 'linux' ]]; then
-    QCMD=qmake-qt4
+    if hash qmake-qt5 2>/dev/null; then
+	echo "Using qmake-qt5"
+	QCMD=qmake-qt5
+    elif hash qmake-qt4 2>/dev/null; then
+	echo "Using qmake-qt4"
+	QCMD=qmake-qt4
+    elif hash qmake 2>/dev/null; then #in case qt was compiled by user
+	echo "Using qmake"
+	QCMD=qmake
+    fi
+    QSPEC=linux-g++
 elif [[ $platform == 'macosx' ]]; then
     QCMD=qmake
+    QSPEC=macx-g++
 fi
 
 # Build
-$QCMD jacktrip.pro
-make clean
-make release
+if [[ $1 == 'nojack' ]]; then
+    echo "Building without Jack"
+    $QCMD -spec $QSPEC -config nojack jacktrip.pro
+    make clean
+    $QCMD -spec $QSPEC -config nojack jacktrip.pro
+    make release
+else
+    $QCMD -spec $QSPEC jacktrip.pro
+    make clean
+    $QCMD -spec $QSPEC jacktrip.pro
+    make release
+fi
diff --git a/src/jacktrip-1.0.5.diff b/src/jacktrip-1.0.5.diff
deleted file mode 100644
index 30292b9..0000000
--- a/src/jacktrip-1.0.5.diff
+++ /dev/null
@@ -1,26 +0,0 @@
-Index: src/JackTripWorker.h
-===================================================================
---- src/JackTripWorker.h	(revision 495)
-+++ src/JackTripWorker.h	(working copy)
-@@ -46,6 +46,8 @@
- #include <QHostAddress>
- #include <QMutex>
- 
-+#include "jacktrip_types.h"
-+
- class JackTrip; // forward declaration
- class UdpMasterListener; // forward declaration
- 
-Index: src/jacktrip_globals.cpp
-===================================================================
---- src/jacktrip_globals.cpp	(revision 495)
-+++ src/jacktrip_globals.cpp	(working copy)
-@@ -38,6 +38,8 @@
- #include "jacktrip_globals.h"
- #include "jacktrip_types.h"
- 
-+#include <stdio.h>
-+
- #if defined ( __LINUX__ )
- #include <sched.h>
- #endif //__LINUX__
diff --git a/src/jacktrip.pro b/src/jacktrip.pro
index b92e69d..bd95a2b 100644
--- a/src/jacktrip.pro
+++ b/src/jacktrip.pro
@@ -10,28 +10,75 @@ CONFIG(debug, debug|release) {
   }
 QT -= gui
 QT += network
-INCLUDEPATH+=/usr/local/include
-LIBS += -ljack -lm
+# http://wiki.qtcentre.org/index.php?title=Undocumented_qmake#Custom_tools
+DEFINES += __RT_AUDIO__
+# Configuration without Jack
+nojack {
+  DEFINES += __NO_JACK__
+}
+!win32 {
+  INCLUDEPATH+=/usr/local/include
+  LIBS += -L/usr/local/lib -ljack -lm
+  nojack {
+    message(Building NONJACK)
+    LIBS -= -ljack
+  }
+}
+
 macx {
   message(MAC OS X)
+  QMAKE_CXXFLAGS += -D__MACOSX_CORE__ #-D__UNIX_JACK__ #RtAudio Flags
+  QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.9
+  QMAKE_MAC_SDK = macosx10.9
   CONFIG -= app_bundle
-  CONFIG += x86 #ppc
-  LIBS += -framework CoreAudio
+  #CONFIG += x86 #ppc #### If you have both libraries installed, you
+  # can change between 32bits (x86) or 64bits(x86_64) Change this to go back to 32 bits (x86)
+  LIBS += -framework CoreAudio -framework CoreFoundation
   DEFINES += __MAC_OSX__
   }
 linux-g++ {
   message(Linux)
+  LIBS += -lasound
+  QMAKE_CXXFLAGS += -D__LINUX_ALSA__ #-D__LINUX_OSS__ #RtAudio Flags
+  QMAKE_CXXFLAGS += -g -O2
+  DEFINES += __LINUX__
+  }
+linux-g++-64 {
+  message(Linux 64bit)
+  LIBS += -lasound
+  QMAKE_CXXFLAGS += -fPIC -D__LINUX_ALSA__ #-D__LINUX_OSS__ #RtAudio Flags
   QMAKE_CXXFLAGS += -g -O2
   DEFINES += __LINUX__
   }
+win32 {
+  message(win32)
+  CONFIG += x86 console
+  QMAKE_CXXFLAGS += -D__WINDOWS_ASIO__ #-D__UNIX_JACK__ #RtAudio Flags
+  LIBS += -lWs2_32 -lOle32 #needed by rtaudio/asio
+  LIBS += "../externals/includes/QTWindows/libjack.lib"
+  DEFINES += __WIN_32__
+  DEFINES -= UNICODE #RtAudio for Qt
+}
+
+
+
+
 DESTDIR = .
-QMAKE_CLEAN += ./jacktrip ./jacktrip_debug
+QMAKE_CLEAN += -r ./jacktrip ./jacktrip_debug ./release ./debug
 target.path = /usr/bin
 INSTALLS += target
 
+#INCLUDEPATH += ../externals/includes/rtaudio-4.0.7
+#DEPENDPATH += ../externals/includes/rtaudio-4.0.7
+win32 {
+  INCLUDEPATH += ../externals/includes/rtaudio-4.0.7/include
+  INCLUDEPATH += ../externals/includes
+  DEPENDPATH += ../externals/includes/rtaudio-4.0.7/include
+  DEPENDPATH += ../externals/includes
+}
+
 # Input
 HEADERS += DataProtocol.h \
-           JackAudioInterface.h \
            JackTrip.h \
            jacktrip_globals.h \
            jacktrip_types.h \
@@ -49,9 +96,13 @@ HEADERS += DataProtocol.h \
            ThreadPoolTest.h \
            UdpDataProtocol.h \
            UdpMasterListener.h \
-           jacktrip_tests.cpp
+           AudioInterface.h \
+           RtAudioInterface.h
+           #JamTest.h
+!nojack {
+SOURCES += JackAudioInterface.h
+}
 SOURCES += DataProtocol.cpp \
-           JackAudioInterface.cpp \
            JackTrip.cpp \
            jacktrip_globals.cpp \
            jacktrip_main.cpp \
@@ -63,6 +114,30 @@ SOURCES += DataProtocol.cpp \
            ProcessPlugin.cpp \
            RingBuffer.cpp \
            Settings.cpp \
-           tests.cpp \
+           #tests.cpp \
            UdpDataProtocol.cpp \
-           UdpMasterListener.cpp
+           UdpMasterListener.cpp \
+           AudioInterface.cpp \
+           RtAudioInterface.cpp
+!nojack {
+SOURCES += JackAudioInterface.cpp
+}
+
+# RtAduio Input
+HEADERS += ../externals/includes/rtaudio-4.0.7/RtAudio.h \
+           ../externals/includes/rtaudio-4.0.7/RtError.h
+SOURCES += ../externals/includes/rtaudio-4.0.7/RtAudio.cpp
+win32 {
+HEADERS += asio.h \
+           asiodrivers.h \
+           asiolist.h \
+           asiodrvr.h \
+           asiosys.h \
+           ginclude.h \
+           iasiodrv.h \
+           iasiothiscallresolver.h
+SOURCES += asio.cpp \
+           asiodrivers.cpp \
+           asiolist.cpp \
+           iasiothiscallresolver.cpp
+}
diff --git a/src/jacktrip_globals.cpp b/src/jacktrip_globals.cpp
index df5c24d..feb5191 100644
--- a/src/jacktrip_globals.cpp
+++ b/src/jacktrip_globals.cpp
@@ -35,13 +35,17 @@
  * \date August 2008
  */
 
+#include <iostream>
+#include <cstring>
+#include <cstdio>
+
 #include "jacktrip_globals.h"
 #include "jacktrip_types.h"
 
-#include <stdio.h>
-
 #if defined ( __LINUX__ )
 #include <sched.h>
+#include <unistd.h>
+#include <sys/types.h>
 #endif //__LINUX__
 
 #if defined ( __MAC_OSX__ )
@@ -183,6 +187,25 @@ int set_realtime_priority (void)
 }
 #endif //__LINUX__
 
+
+#if defined ( __WIN_32__ )
+int win_priority()
+{
+  if (SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS) == 0)
+  {
+    printf("set Priority Class failed \n");
+    return -1;
+  }
+  if(SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL) == 0)
+  {
+    printf("set Thread Priority failed \n");
+    return -1;
+  }
+  return GetThreadPriority(GetCurrentThread());
+}
+#endif //__WIN_32__
+
+
 void set_crossplatform_realtime_priority()
 {
 #if defined ( __LINUX__ )
@@ -191,6 +214,10 @@ void set_crossplatform_realtime_priority()
 #if defined ( __MAC_OSX__ )
   set_realtime(1250000,60000,90000);
 #endif //__MAC_OSX__
+#if defined __WIN_32__
+  win_priority();
+#endif
+
 }
 
 
diff --git a/src/jacktrip_globals.h b/src/jacktrip_globals.h
index f9d2d76..3f87dac 100644
--- a/src/jacktrip_globals.h
+++ b/src/jacktrip_globals.h
@@ -38,22 +38,31 @@
 #ifndef __JACKTRIP_GLOBALS_H__
 #define __JACKTRIP_GLOBALS_H__
 
-#include "JackAudioInterface.h"
+#include "AudioInterface.h"
+//#include "JackAudioInterface.h"
 
+/// \todo Add this namespace
+//namespace JackTrip
 
-//namespace JackTrip/// \todo Add this namespace
-
-const char* const gVersion = "1.0.5"; ///< JackTrip version
+const char* const gVersion = "1.1"; ///< JackTrip version
 
 //*******************************************************************************
 /// \name Default Values
 //@{
 const int gDefaultNumInChannels = 2;
 const int gDefaultNumOutChannels = 2;
-const JackAudioInterface::audioBitResolutionT gDefaultBitResolutionMode = 
-  JackAudioInterface::BIT16;
+//const JackAudioInterface::audioBitResolutionT gDefaultBitResolutionMode =
+//    JackAudioInterface::BIT16;
+const AudioInterface::audioBitResolutionT gDefaultBitResolutionMode =
+    AudioInterface::BIT16;
 const int gDefaultQueueLength = 4;
 const int gDefaultOutputQueueLength = 4;
+const uint32_t gDefaultSampleRate = 48000;
+const uint32_t gDefaultBufferSizeInSamples = 128;
+const QString gDefaultLocalAddress = QString();
+const int gDefaultRedundancy = 1;
+const int gTimeOutMultiThreadedServer = 5000; // seconds
+const int gWaitCounter = 60;
 //@}
 
 
@@ -110,7 +119,13 @@ int set_realtime_priority (void);
 int set_realtime(int period, int computation, int constraint);
 #endif //__MAC_OSX__ 
 //@}
-  
+
+//@{
+// Windows Specific Functions
+#if defined ( __WIN_32__ )
+int win_priority();
+#endif //__WIN_32__
+//@}
 
 //*******************************************************************************
 /// \name JackTrip Server parameters
diff --git a/src/jacktrip_main.cpp b/src/jacktrip_main.cpp
index e0d4203..96159d2 100644
--- a/src/jacktrip_main.cpp
+++ b/src/jacktrip_main.cpp
@@ -47,11 +47,11 @@
 //#include "TestRingBuffer.h"
 #include "LoopBack.h"
 #include "PacketHeader.h"
-#include "JackTripThread.h"
+//#include "JackTripThread.h"
+#include "RtAudioInterface.h"
 #include "jacktrip_tests.cpp"
 
 #include "jacktrip_globals.h"
-
 using std::cout; using std::endl;
 
 
@@ -59,14 +59,30 @@ int main(int argc, char** argv)
 {
   QCoreApplication app(argc, argv);
 
-  //--------TESTS--------------------------
-  //main_tests(argc, argv); // test functions
-  //while (true) sleep(9999);
-  //---------------------------------------
+  bool testing = false;
+  if ( argc > 1 ) {
+    if ( !strcmp(argv[1], "test") ) {
+      testing = true;
+    }
+  }
+
+  if ( testing ) {
+    cout << "=========TESTING=========" << endl;
+    //main_tests(argc, argv); // test functions
+    JackTrip jacktrip;
+    RtAudioInterface rtaudio(&jacktrip);
+    //rtaudio.setup();
+    rtaudio.listAllInterfaces();
+    //rtaudio.printDeviceInfo(0);
 
-  // Get Settings from user
-  // ----------------------
-  try 
+    //while (true) sleep(9999);
+  }
+  else {
+    //---------------------------------------
+
+    // Get Settings from user
+    // ----------------------
+    try
     {
       // Get Settings from user
       // ----------------------
@@ -74,7 +90,7 @@ int main(int argc, char** argv)
       settings->parseInput(argc, argv);
       settings->startJackTrip();
     }
-  catch ( const std::exception & e )
+    catch ( const std::exception & e )
     {
       std::cerr << "ERROR:" << endl;
       std::cerr << e.what() << endl;
@@ -82,5 +98,7 @@ int main(int argc, char** argv)
       std::cerr << gPrintSeparator << endl;
       return -1;
     }
+  }
+
   return app.exec();
 }
diff --git a/src/jacktrip_types.h b/src/jacktrip_types.h
index 08bfe87..f9f10f0 100644
--- a/src/jacktrip_types.h
+++ b/src/jacktrip_types.h
@@ -39,47 +39,51 @@
 #ifndef __JACKTRIP_TYPES_H__
 #define __JACKTRIP_TYPES_H__
 
-#include <jack/types.h>
+//#include <jack/types.h>
 #include <QtGlobal> //For QT4 types
 
-//-------------------------------------------------------------------------------
-/** \name Audio typedefs
+//namespace JackTripNamespace
+//{
+
+  //-------------------------------------------------------------------------------
+  /** \name Audio typedefs
  *
  */
-//-------------------------------------------------------------------------------
-//@{
-/// Audio sample type
-typedef jack_default_audio_sample_t sample_t; 
-//@}
+  //-------------------------------------------------------------------------------
+  //@{
+  /// Audio sample type
+  //typedef jack_default_audio_sample_t sample_t;
+  typedef float sample_t;
+  //@}
 
 
-//-------------------------------------------------------------------------------
-/** \name Typedefs that guaranty some specific bit length
+  //-------------------------------------------------------------------------------
+  /** \name Typedefs that guaranty some specific bit length
  *
  * It uses the QT4 types. This can be changed in the future, keeping
  * compatibility for the rest of the code.
  */
-//-------------------------------------------------------------------------------
-//@{
-/// Typedef for <tt>unsigned char</tt>. This type is guaranteed to be 8-bit.
-typedef quint8 uint8_t;
-/// Typedef for <tt>unsigned short</tt>. This type is guaranteed to be 16-bit.
-typedef quint16 uint16_t;
-/// Typedef for <tt>unsigned int</tt>. This type is guaranteed to be 32-bit.
-typedef quint32 uint32_t;
-/// \brief Typedef for <tt>unsigned long long int</tt>. This type is guaranteed to 
-/// be 64-bit.
-//typedef quint64 uint64_t;
-/// Typedef for <tt>signed char</tt>. This type is guaranteed to be 8-bit.
-typedef qint8 int8_t;
-/// Typedef for <tt>signed short</tt>. This type is guaranteed to be 16-bit.
-typedef qint16 int16_t;
-/// Typedef for <tt>signed int</tt>. This type is guaranteed to be 32-bit.
-typedef qint32 int32_t;
-/// \brief Typedef for <tt>long long int</tt>. This type is guaranteed to 
-/// be 64-bit.
-//typedef qint64 int64_t;
-//@}
-
+  //-------------------------------------------------------------------------------
+  //@{
+  /// Typedef for <tt>unsigned char</tt>. This type is guaranteed to be 8-bit.
+  typedef quint8 uint8_t;
+  /// Typedef for <tt>unsigned short</tt>. This type is guaranteed to be 16-bit.
+  typedef quint16 uint16_t;
+  /// Typedef for <tt>unsigned int</tt>. This type is guaranteed to be 32-bit.
+  typedef quint32 uint32_t;
+  /// \brief Typedef for <tt>unsigned long long int</tt>. This type is guaranteed to
+  /// be 64-bit.
+  //typedef quint64 uint64_t;
+  /// Typedef for <tt>signed char</tt>. This type is guaranteed to be 8-bit.
+  typedef qint8 int8_t;
+  /// Typedef for <tt>signed short</tt>. This type is guaranteed to be 16-bit.
+  typedef qint16 int16_t;
+  /// Typedef for <tt>signed int</tt>. This type is guaranteed to be 32-bit.
+  typedef qint32 int32_t;
+  /// \brief Typedef for <tt>long long int</tt>. This type is guaranteed to
+  /// be 64-bit.
+  //typedef qint64 int64_t;
+  //@}
+//} // end of namespace JackTripNamespace
 
 #endif
diff --git a/src/tests.cpp b/src/tests.cpp
deleted file mode 100644
index 6582563..0000000
--- a/src/tests.cpp
+++ /dev/null
@@ -1,122 +0,0 @@
-//*****************************************************************
-/*
-  JackTrip: A System for High-Quality Audio Network Performance
-  over the Internet
-
-  Copyright (c) 2008 Juan-Pablo Caceres, Chris Chafe.
-  SoundWIRE group at CCRMA, Stanford University.
-  
-  Permission is hereby granted, free of charge, to any person
-  obtaining a copy of this software and associated documentation
-  files (the "Software"), to deal in the Software without
-  restriction, including without limitation the rights to use,
-  copy, modify, merge, publish, distribute, sublicense, and/or sell
-  copies of the Software, and to permit persons to whom the
-  Software is furnished to do so, subject to the following
-  conditions:
-  
-  The above copyright notice and this permission notice shall be
-  included in all copies or substantial portions of the Software.
-  
-  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-  OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-  OTHER DEALINGS IN THE SOFTWARE.
-*/
-//*****************************************************************
-
-/**
- * \file tests.cpp
- * \author Juan-Pablo Caceres
- * \date June 2008
- */
-#include <iostream>
-#include <unistd.h>
-#include <getopt.h>
-
-
-#include "JackAudioInterface.h"
-#include "UdpDataProtocol.h"
-#include "RingBuffer.h"
-#include "JackTrip.h"
-#include "Settings.h"
-#include "TestRingBuffer.h"
-#include "jacktrip_globals.h"
-
-using namespace std;
-
-void tests()
-{
-  // Test JackTrip
-  //================================================================
-  //JackTrip jacktrip1;
-  //jacktrip1.startThreads();
-
-  //JackTrip jacktrip2;
-  //jacktrip2.startThreads();
- 
-  /*
-  // TestRingBuffer
-  //================================================================
-  TestRingBufferWrite tw;
-  TestRingBufferRead tr;
-  tr.start();
-  tw.start();
-  */
-
-  /*
-  // Test RingBuffer
-  //================================================================
-  RingBuffer rb(2,2);
-
-  int8_t* writeSlot;
-  writeSlot = new int8_t[2];
-  writeSlot[0] = *"a";
-  writeSlot[1] = *"b";
-  std::cout << *writeSlot << std::endl;
-  std::cout << writeSlot[0] << std::endl;
-  std::cout << writeSlot[1] << std::endl;
-  std::cout << *(writeSlot+1) << std::endl;
-  rb.writeSlot(writeSlot);
-
-  int8_t* readSlot;
-  readSlot = new int8_t[2];
-  rb.readSlot(readSlot);
-  std::cout << *(readSlot) << std::endl;
-  std::cout << *(readSlot+1) << std::endl;
-  */
-
-
-  /*
-  // Test UDP Socket
-  //================================================================
-  UdpDataProtocol udp_rec(RECEIVER, "192.168.1.4");
-  UdpDataProtocol udp_send(SENDER, "192.168.1.4");
-  udp_rec.start();
-  udp_send.start();
-  */
-
-  /*
-  // Test JackAudioInterface
-  //================================================================
-  JackAudioInterface jack_test(4);
-  cout << "SR: " << jack_test.getSampleRate() << endl;
-  cout << "Buffer Size: " << jack_test.getBufferSize() << endl;
-  jack_test.setProcessCallback(process);
-  jack_test.startProcess();
-  */
-
-
-  while (true)
-    {
-      //cout << "SR: " << test.getSampleRate() << endl;
-      //cout << "Buffer Size: " << test.getBufferSize() << endl;
-      usleep(1000000);
-      //usleep(1);
-    }
-
-}

-- 
jacktrip packaging



More information about the pkg-multimedia-commits mailing list