| 
							- /*
 - Copyright (C) 2009-2011 Grame
 - 
 - This program is free software; you can redistribute it and/or modify
 - it under the terms of the GNU Lesser General Public License as published by
 - the Free Software Foundation; either version 2.1 of the License, or
 - (at your option) any later version.
 - 
 - This program is distributed in the hope that it will be useful,
 - but WITHOUT ANY WARRANTY; without even the implied warranty of
 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 - GNU Lesser General Public License for more details.
 - 
 - You should have received a copy of the GNU Lesser General Public License
 - along with this program; if not, write to the Free Software
 - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 - 
 - */
 - 
 - #include <assert.h>
 - #include <stdarg.h>
 - #include "JackNetInterface.h"
 - #include "JackError.h"
 - #include "JackException.h"
 - #include "JackAudioAdapterInterface.h"
 - 
 - #ifdef __cplusplus
 - extern "C"
 - {
 - #endif
 - 
 -     // NetJack common API
 - 
 -     #define MASTER_NAME_SIZE 256
 - 
 -     enum JackNetEncoder {
 - 
 -         JackFloatEncoder = 0,
 -         JackIntEncoder = 1,
 -         JackCeltEncoder = 2,
 -         JackMaxEncoder = 3
 -     };
 - 
 -     typedef struct {
 - 
 -         int audio_input;
 -         int audio_output;
 -         int midi_input;
 -         int midi_output;
 -         int mtu;
 -         int time_out;   // in millisecond, -1 means in infinite
 -         int encoder;    // one of JackNetEncoder
 -         int kbps;       // KB per second for CELT encoder
 -         int latency;    // network cycles
 - 
 -     } jack_slave_t;
 - 
 -     typedef struct {
 - 
 -         int audio_input;
 -         int audio_output;
 -         int midi_input;
 -         int midi_output;
 -         jack_nframes_t buffer_size;
 -         jack_nframes_t sample_rate;
 -         char master_name[MASTER_NAME_SIZE];
 - 
 -     } jack_master_t;
 - 
 -     // NetJack slave API
 - 
 -     typedef struct _jack_net_slave jack_net_slave_t;
 - 
 -     typedef int (* JackNetSlaveProcessCallback) (jack_nframes_t buffer_size,
 -                                             int audio_input,
 -                                             float** audio_input_buffer,
 -                                             int midi_input,
 -                                             void** midi_input_buffer,
 -                                             int audio_output,
 -                                             float** audio_output_buffer,
 -                                             int midi_output,
 -                                             void** midi_output_buffer,
 -                                             void* data);
 - 
 -     typedef int (*JackNetSlaveBufferSizeCallback) (jack_nframes_t nframes, void *arg);
 -     typedef int (*JackNetSlaveSampleRateCallback) (jack_nframes_t nframes, void *arg);
 -     typedef void (*JackNetSlaveShutdownCallback) (void* data);
 - 
 -     SERVER_EXPORT jack_net_slave_t* jack_net_slave_open(const char* ip, int port, const char* name, jack_slave_t* request, jack_master_t* result);
 -     SERVER_EXPORT int jack_net_slave_close(jack_net_slave_t* net);
 - 
 -     SERVER_EXPORT int jack_net_slave_activate(jack_net_slave_t* net);
 -     SERVER_EXPORT int jack_net_slave_deactivate(jack_net_slave_t* net);
 - 
 -     SERVER_EXPORT int jack_set_net_slave_process_callback(jack_net_slave_t* net, JackNetSlaveProcessCallback net_callback, void *arg);
 -     SERVER_EXPORT int jack_set_net_slave_buffer_size_callback(jack_net_slave_t* net, JackNetSlaveBufferSizeCallback bufsize_callback, void *arg);
 -     SERVER_EXPORT int jack_set_net_slave_sample_rate_callback(jack_net_slave_t* net, JackNetSlaveSampleRateCallback samplerate_callback, void *arg);
 -     SERVER_EXPORT int jack_set_net_slave_shutdown_callback(jack_net_slave_t* net, JackNetSlaveShutdownCallback shutdown_callback, void *arg);
 - 
 -     // NetJack master API
 - 
 -     typedef struct _jack_net_master jack_net_master_t;
 - 
 -     SERVER_EXPORT jack_net_master_t* jack_net_master_open(const char* ip, int port, const char* name, jack_master_t* request, jack_slave_t* result);
 -     SERVER_EXPORT int jack_net_master_close(jack_net_master_t* net);
 - 
 -     SERVER_EXPORT int jack_net_master_recv(jack_net_master_t* net, int audio_input, float** audio_input_buffer, int midi_input, void** midi_input_buffer);
 -     SERVER_EXPORT int jack_net_master_send(jack_net_master_t* net, int audio_output, float** audio_output_buffer, int midi_output, void** midi_output_buffer);
 - 
 -     // NetJack adapter API
 - 
 -     typedef struct _jack_adapter jack_adapter_t;
 - 
 -     SERVER_EXPORT jack_adapter_t* jack_create_adapter(int input, int output,
 -                                                     jack_nframes_t host_buffer_size,
 -                                                     jack_nframes_t host_sample_rate,
 -                                                     jack_nframes_t adapted_buffer_size,
 -                                                     jack_nframes_t adapted_sample_rate);
 -     SERVER_EXPORT int jack_destroy_adapter(jack_adapter_t* adapter);
 -     SERVER_EXPORT void jack_flush_adapter(jack_adapter_t* adapter);
 - 
 -     SERVER_EXPORT int jack_adapter_push_and_pull(jack_adapter_t* adapter, float** input, float** output, unsigned int frames);
 -     SERVER_EXPORT int jack_adapter_pull_and_push(jack_adapter_t* adapter, float** input, float** output, unsigned int frames);
 - 
 - #ifdef __cplusplus
 - }
 - #endif
 - 
 - namespace Jack
 - {
 - 
 - struct JackNetExtMaster : public JackNetMasterInterface {
 - 
 -     // Data buffers
 -     float** fAudioCaptureBuffer;
 -     float** fAudioPlaybackBuffer;
 - 
 -     JackMidiBuffer** fMidiCaptureBuffer;
 -     JackMidiBuffer** fMidiPlaybackBuffer;
 - 
 -     jack_master_t fRequest;
 - 
 -     JackNetExtMaster(const char* ip,
 -                     int port,
 -                     const char* name,
 -                     jack_master_t* request)
 -     {
 -         fRunning = true;
 -         assert(strlen(ip) < 32);
 -         strcpy(fMulticastIP, ip);
 -         fSocket.SetPort(port);
 -         fRequest.buffer_size = request->buffer_size;
 -         fRequest.sample_rate = request->sample_rate;
 -         fAudioCaptureBuffer = NULL;
 -         fAudioPlaybackBuffer = NULL;
 -         fMidiCaptureBuffer = NULL;
 -         fMidiPlaybackBuffer = NULL;
 -     }
 - 
 -     virtual ~JackNetExtMaster()
 -     {}
 - 
 -     int Open(jack_slave_t* result)
 -     {
 -         // Init socket API (win32)
 -         if (SocketAPIInit() < 0) {
 -             jack_error("Can't init Socket API, exiting...");
 -             return -1;
 -         }
 - 
 -         // Request socket
 -         if (fSocket.NewSocket() == SOCKET_ERROR) {
 -             jack_error("Can't create the network management input socket : %s", StrError(NET_ERROR_CODE));
 -             return -1;
 -         }
 - 
 -         // Bind the socket to the local port
 -         if (fSocket.Bind() == SOCKET_ERROR) {
 -             jack_error("Can't bind the network manager socket : %s", StrError(NET_ERROR_CODE));
 -             fSocket.Close();
 -             return -1;
 -         }
 - 
 -         // Join multicast group
 -         if (fSocket.JoinMCastGroup(fMulticastIP) == SOCKET_ERROR) {
 -             jack_error("Can't join multicast group : %s", StrError(NET_ERROR_CODE));
 -         }
 - 
 -         // Local loop
 -         if (fSocket.SetLocalLoop() == SOCKET_ERROR) {
 -             jack_error("Can't set local loop : %s", StrError(NET_ERROR_CODE));
 -         }
 - 
 -         // Set a timeout on the multicast receive (the thread can now be cancelled)
 -         if (fSocket.SetTimeOut(MANAGER_INIT_TIMEOUT) == SOCKET_ERROR) {
 -             jack_error("Can't set timeout : %s", StrError(NET_ERROR_CODE));
 -         }
 - 
 -          // Main loop, wait for data, deal with it and wait again
 -         int attempt = 0;
 -         int rx_bytes = 0;
 - 
 -         do
 -         {
 -             session_params_t net_params;
 -             rx_bytes = fSocket.CatchHost(&net_params, sizeof(session_params_t), 0);
 -             SessionParamsNToH(&net_params, &fParams);
 - 
 -             if ((rx_bytes == SOCKET_ERROR) && (fSocket.GetError() != NET_NO_DATA)) {
 -                 jack_error("Error in receive : %s", StrError(NET_ERROR_CODE));
 -                 if (++attempt == 10) {
 -                     jack_error("Can't receive on the socket, exiting net manager" );
 -                     goto error;
 -                 }
 -             }
 - 
 -             if (rx_bytes == sizeof(session_params_t ))  {
 - 
 -                 switch (GetPacketType(&fParams)) {
 - 
 -                     case SLAVE_AVAILABLE:
 -                         if (MasterInit() == 0) {
 -                             SessionParamsDisplay(&fParams);
 -                             fRunning = false;
 -                         } else {
 -                             jack_error("Can't init new net master...");
 -                             goto error;
 -                         }
 -                         jack_info("Waiting for a slave...");
 -                         break;
 - 
 -                     case KILL_MASTER:
 -                          break;
 - 
 -                     default:
 -                         break;
 -                 }
 -             }
 -         }
 -         while (fRunning);
 - 
 -         // Set result paramaters
 -         result->audio_input = fParams.fSendAudioChannels;
 -         result->audio_output = fParams.fReturnAudioChannels;
 -         result->midi_input = fParams.fSendMidiChannels;
 -         result->midi_output = fParams.fReturnMidiChannels;
 -         result->mtu = fParams.fMtu;
 -         result->latency = fParams.fNetworkLatency;
 -         return 0;
 - 
 -     error:
 -         fSocket.Close();
 -         return -1;
 -     }
 - 
 -     int MasterInit()
 -     {
 -         // Check MASTER <==> SLAVE network protocol coherency
 -         if (fParams.fProtocolVersion != MASTER_PROTOCOL) {
 -             jack_error("Error : slave is running with a different protocol %s", fParams.fName);
 -             return -1;
 -         }
 - 
 -         // Settings
 -         fSocket.GetName(fParams.fMasterNetName);
 -         fParams.fID = 1;
 -         fParams.fSampleEncoder = JackFloatEncoder;
 -         fParams.fPeriodSize = fRequest.buffer_size;
 -         fParams.fSampleRate = fRequest.sample_rate;
 - 
 -         // Close request socket
 -         fSocket.Close();
 - 
 -         // Network slave init
 -         if (!JackNetMasterInterface::Init()) {
 -             return -1;
 -         }
 - 
 -         // Set global parameters
 -         if (!SetParams()) {
 -             return -1;
 -         }
 - 
 -         AllocPorts();
 -         return 0;
 -     }
 - 
 -     int Close()
 -     {
 -         fSocket.Close();
 -         FreePorts();
 -         return 0;
 -     }
 - 
 -     void AllocPorts()
 -     {
 -         // Set buffers
 -         if (fParams.fSendAudioChannels > 0) {
 -             fAudioCaptureBuffer = new float*[fParams.fSendAudioChannels];
 -             for (int audio_port_index = 0; audio_port_index < fParams.fSendAudioChannels; audio_port_index++) {
 -                 fAudioCaptureBuffer[audio_port_index] = new float[fParams.fPeriodSize];
 -                 fNetAudioCaptureBuffer->SetBuffer(audio_port_index, fAudioCaptureBuffer[audio_port_index]);
 -             }
 -         }
 - 
 -         if (fParams.fSendMidiChannels > 0) {
 -             fMidiCaptureBuffer = new JackMidiBuffer*[fParams.fSendMidiChannels];
 -             for (int midi_port_index = 0; midi_port_index < fParams.fSendMidiChannels; midi_port_index++) {
 -                 fMidiCaptureBuffer[midi_port_index] = (JackMidiBuffer*)new float[fParams.fPeriodSize];
 -                 fNetMidiCaptureBuffer->SetBuffer(midi_port_index, fMidiCaptureBuffer[midi_port_index]);
 -             }
 -         }
 - 
 -         if (fParams.fReturnAudioChannels > 0) {
 -             fAudioPlaybackBuffer = new float*[fParams.fReturnAudioChannels];
 -             for (int audio_port_index = 0; audio_port_index < fParams.fReturnAudioChannels; audio_port_index++) {
 -                 fAudioPlaybackBuffer[audio_port_index] = new float[fParams.fPeriodSize];
 -                 fNetAudioPlaybackBuffer->SetBuffer(audio_port_index, fAudioPlaybackBuffer[audio_port_index]);
 -             }
 -         }
 - 
 -         if (fParams.fReturnMidiChannels > 0) {
 -             fMidiPlaybackBuffer = new JackMidiBuffer*[fParams.fReturnMidiChannels];
 -             for (int midi_port_index = 0; midi_port_index < fParams.fReturnMidiChannels; midi_port_index++) {
 -                 fMidiPlaybackBuffer[midi_port_index] = (JackMidiBuffer*)new float[fParams.fPeriodSize];
 -                 fNetMidiPlaybackBuffer->SetBuffer(midi_port_index, fMidiPlaybackBuffer[midi_port_index]);
 -             }
 -         }
 -     }
 - 
 -     void FreePorts()
 -     {
 -         if (fAudioPlaybackBuffer) {
 -             for (int audio_port_index = 0; audio_port_index < fParams.fSendAudioChannels; audio_port_index++)
 -                 delete[] fAudioPlaybackBuffer[audio_port_index];
 -             delete[] fAudioPlaybackBuffer;
 -             fAudioPlaybackBuffer = NULL;
 -         }
 - 
 -         if (fMidiPlaybackBuffer) {
 -             for (int midi_port_index = 0; midi_port_index < fParams.fSendMidiChannels; midi_port_index++)
 -                 delete[] (fMidiPlaybackBuffer[midi_port_index]);
 -             delete[] fMidiPlaybackBuffer;
 -             fMidiPlaybackBuffer = NULL;
 -         }
 - 
 -         if (fAudioCaptureBuffer) {
 -             for (int audio_port_index = 0; audio_port_index < fParams.fReturnAudioChannels; audio_port_index++)
 -                 delete[] fAudioCaptureBuffer[audio_port_index];
 -             delete[] fAudioCaptureBuffer;
 -             fAudioCaptureBuffer = NULL;
 -         }
 - 
 -         if (fMidiCaptureBuffer) {
 -             for (int midi_port_index = 0; midi_port_index < fParams.fReturnMidiChannels; midi_port_index++)
 -                 delete[] fMidiCaptureBuffer[midi_port_index];
 -             delete[] fMidiCaptureBuffer;
 -             fMidiCaptureBuffer = NULL;
 -         }
 -     }
 - 
 -     int Read(int audio_input, float** audio_input_buffer, int midi_input, void** midi_input_buffer)
 -     {
 -         try {
 -             assert(audio_input == fParams.fReturnAudioChannels);
 - 
 -             for (int audio_port_index = 0; audio_port_index < audio_input; audio_port_index++) {
 -                 fNetAudioPlaybackBuffer->SetBuffer(audio_port_index, audio_input_buffer[audio_port_index]);
 -             }
 - 
 -             for (int midi_port_index = 0; midi_port_index < midi_input; midi_port_index++) {
 -                 fNetMidiPlaybackBuffer->SetBuffer(midi_port_index, ((JackMidiBuffer**)midi_input_buffer)[midi_port_index]);
 -             }
 - 
 -             if (SyncRecv() == SOCKET_ERROR) {
 -                 return 0;
 -             }
 - 
 -             DecodeSyncPacket();
 -             return DataRecv();
 - 
 -         } catch (JackNetException& e) {
 -             jack_error("Connection lost.");
 -             return -1;
 -         }
 -      }
 - 
 -      int Write(int audio_output, float** audio_output_buffer, int midi_output, void** midi_output_buffer)
 -      {
 -         try {
 -             assert(audio_output == fParams.fSendAudioChannels);
 - 
 -             for (int audio_port_index = 0; audio_port_index < audio_output; audio_port_index++) {
 -                 fNetAudioCaptureBuffer->SetBuffer(audio_port_index, audio_output_buffer[audio_port_index]);
 -             }
 - 
 -             for (int midi_port_index = 0; midi_port_index < midi_output; midi_port_index++) {
 -                 fNetMidiCaptureBuffer->SetBuffer(midi_port_index, ((JackMidiBuffer**)midi_output_buffer)[midi_port_index]);
 -             }
 - 
 -             EncodeSyncPacket();
 - 
 -             if (SyncSend() == SOCKET_ERROR) {
 -                 return SOCKET_ERROR;
 -             }
 - 
 -             return DataSend();
 - 
 -         } catch (JackNetException& e) {
 -             jack_error("Connection lost.");
 -             return -1;
 -         }
 -      }
 - 
 -     // Transport
 -     void EncodeTransportData()
 -     {}
 - 
 -     void DecodeTransportData()
 -     {}
 - 
 - };
 - 
 - struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterface {
 - 
 -     JackThread fThread;
 - 
 -     JackNetSlaveProcessCallback fProcessCallback;
 -     void* fProcessArg;
 - 
 -     JackNetSlaveShutdownCallback fShutdownCallback;
 -     void* fShutdownArg;
 - 
 -     JackNetSlaveBufferSizeCallback fBufferSizeCallback;
 -     void* fBufferSizeArg;
 - 
 -     JackNetSlaveSampleRateCallback fSampleRateCallback;
 -     void* fSampleRateArg;
 - 
 -     //sample buffers
 -     float** fAudioCaptureBuffer;
 -     float** fAudioPlaybackBuffer;
 - 
 -     JackMidiBuffer** fMidiCaptureBuffer;
 -     JackMidiBuffer** fMidiPlaybackBuffer;
 - 
 -     int fConnectTimeOut;
 - 
 -     JackNetExtSlave(const char* ip,
 -                     int port,
 -                     const char* name,
 -                     jack_slave_t* request)
 -         :fThread(this),
 -         fProcessCallback(NULL),fProcessArg(NULL),
 -         fShutdownCallback(NULL), fShutdownArg(NULL),
 -         fBufferSizeCallback(NULL), fBufferSizeArg(NULL),
 -         fSampleRateCallback(NULL), fSampleRateArg(NULL),
 -         fAudioCaptureBuffer(NULL), fAudioPlaybackBuffer(NULL),
 -         fMidiCaptureBuffer(NULL), fMidiPlaybackBuffer(NULL)
 -     {
 -         char host_name[JACK_CLIENT_NAME_SIZE];
 - 
 -         // Request parameters
 -         assert(strlen(ip) < 32);
 -         strcpy(fMulticastIP, ip);
 -         fParams.fMtu = request->mtu;
 -         fParams.fTransportSync = 0;
 -         fParams.fSendAudioChannels = request->audio_input;
 -         fParams.fReturnAudioChannels = request->audio_output;
 -         fParams.fSendMidiChannels = request->midi_input;
 -         fParams.fReturnMidiChannels = request->midi_output;
 -         fParams.fNetworkLatency = request->latency;
 -         fParams.fSampleEncoder = request->encoder;
 -         fParams.fKBps = request->kbps;
 -         fParams.fSlaveSyncMode = 1;
 -         fConnectTimeOut = request->time_out;
 - 
 -         // Create name with hostname and client name
 -         GetHostName(host_name, JACK_CLIENT_NAME_SIZE);
 -         snprintf(fParams.fName, JACK_CLIENT_NAME_SIZE, "%s_%s", host_name, name);
 -         fSocket.GetName(fParams.fSlaveNetName);
 - 
 -         // Set the socket parameters
 -         fSocket.SetPort(port);
 -         fSocket.SetAddress(fMulticastIP, port);
 -     }
 - 
 -     virtual ~JackNetExtSlave()
 -     {}
 - 
 -     int Open(jack_master_t* result)
 -     {
 -         if (fParams.fNetworkLatency > NETWORK_MAX_LATENCY) {
 -             jack_error("Error : network latency is limited to %d", NETWORK_MAX_LATENCY);
 -             return -1;
 -         }
 - 
 -         // Init network connection
 -         if (!JackNetSlaveInterface::InitConnection(fConnectTimeOut)) {
 -             jack_error("Initing network fails...");
 -             return -1;
 -         }
 - 
 -         // Finish connection...
 -         if (!JackNetSlaveInterface::InitRendering()) {
 -             jack_error("Starting network fails...");
 -             return -1;
 -         }
 - 
 -         // Then set global parameters
 -         if (!SetParams()) {
 -             jack_error("SetParams error...");
 -             return -1;
 -         }
 - 
 -          // Set result
 -          if (result != NULL) {
 -             result->buffer_size = fParams.fPeriodSize;
 -             result->sample_rate = fParams.fSampleRate;
 -             result->audio_input = fParams.fSendAudioChannels;
 -             result->audio_output = fParams.fReturnAudioChannels;
 -             result->midi_input = fParams.fSendMidiChannels;
 -             result->midi_output = fParams.fReturnMidiChannels;
 -             strcpy(result->master_name, fParams.fMasterNetName);
 -         }
 - 
 -         AllocPorts();
 -         return 0;
 -     }
 - 
 -     int Restart()
 -     {
 -         // If shutdown cb is set, then call it
 -         if (fShutdownCallback) {
 -             fShutdownCallback(fShutdownArg);
 -         }
 - 
 -         // Init network connection
 -         if (!JackNetSlaveInterface::InitConnection(fConnectTimeOut)) {
 -             jack_error("Initing network fails...");
 -             return -1;
 -         }
 - 
 -          // Finish connection...
 -         if (!JackNetSlaveInterface::InitRendering()) {
 -             jack_error("Starting network fails...");
 -             return -1;
 -         }
 - 
 -         // Then set global parameters
 -         if (!SetParams()) {
 -             jack_error("SetParams error...");
 -             return -1;
 -         }
 - 
 -         // We need to notify possibly new buffer size and sample rate (see Execute)
 -         if (fBufferSizeCallback) {
 -             fBufferSizeCallback(fParams.fPeriodSize, fBufferSizeArg);
 -         }
 - 
 -         if (fSampleRateCallback) {
 -             fSampleRateCallback(fParams.fSampleRate, fSampleRateArg);
 -         }
 - 
 -         AllocPorts();
 -         return 0;
 -     }
 - 
 -     int Close()
 -     {
 -         fSocket.Close();
 -         FreePorts();
 -         return 0;
 -     }
 - 
 -     void AllocPorts()
 -     {
 -         // Set buffers
 -         fAudioCaptureBuffer = new float*[fParams.fSendAudioChannels];
 -         for (int audio_port_index = 0; audio_port_index < fParams.fSendAudioChannels; audio_port_index++) {
 -             fAudioCaptureBuffer[audio_port_index] = new float[fParams.fPeriodSize];
 -             fNetAudioCaptureBuffer->SetBuffer(audio_port_index, fAudioCaptureBuffer[audio_port_index]);
 -         }
 - 
 -         fMidiCaptureBuffer = new JackMidiBuffer*[fParams.fSendMidiChannels];
 -         for (int midi_port_index = 0; midi_port_index < fParams.fSendMidiChannels; midi_port_index++) {
 -             fMidiCaptureBuffer[midi_port_index] = (JackMidiBuffer*)new float[fParams.fPeriodSize];
 -             fNetMidiCaptureBuffer->SetBuffer(midi_port_index, fMidiCaptureBuffer[midi_port_index]);
 -         }
 - 
 -         fAudioPlaybackBuffer = new float*[fParams.fReturnAudioChannels];
 -         for (int audio_port_index = 0; audio_port_index < fParams.fReturnAudioChannels; audio_port_index++) {
 -             fAudioPlaybackBuffer[audio_port_index] = new float[fParams.fPeriodSize];
 -             fNetAudioPlaybackBuffer->SetBuffer(audio_port_index, fAudioPlaybackBuffer[audio_port_index]);
 -         }
 - 
 -         fMidiPlaybackBuffer = new JackMidiBuffer*[fParams.fReturnMidiChannels];
 -         for (int midi_port_index = 0; midi_port_index < fParams.fReturnMidiChannels; midi_port_index++) {
 -             fMidiPlaybackBuffer[midi_port_index] = (JackMidiBuffer*)new float[fParams.fPeriodSize];
 -             fNetMidiPlaybackBuffer->SetBuffer(midi_port_index, fMidiPlaybackBuffer[midi_port_index]);
 -         }
 -     }
 - 
 -     void FreePorts()
 -     {
 -         if (fAudioCaptureBuffer) {
 -             for (int audio_port_index = 0; audio_port_index < fParams.fSendAudioChannels; audio_port_index++)
 -                 delete[] fAudioCaptureBuffer[audio_port_index];
 -             delete[] fAudioCaptureBuffer;
 -             fAudioCaptureBuffer = NULL;
 -         }
 - 
 -         if (fMidiCaptureBuffer) {
 -             for (int midi_port_index = 0; midi_port_index < fParams.fSendMidiChannels; midi_port_index++)
 -                 delete[] (fMidiCaptureBuffer[midi_port_index]);
 -             delete[] fMidiCaptureBuffer;
 -             fMidiCaptureBuffer = NULL;
 -         }
 - 
 -         if (fAudioPlaybackBuffer) {
 -             for (int audio_port_index = 0; audio_port_index < fParams.fReturnAudioChannels; audio_port_index++)
 -                 delete[] fAudioPlaybackBuffer[audio_port_index];
 -             delete[] fAudioPlaybackBuffer;
 -             fAudioPlaybackBuffer = NULL;
 -         }
 - 
 -         if (fMidiPlaybackBuffer) {
 -             for (int midi_port_index = 0; midi_port_index < fParams.fReturnMidiChannels; midi_port_index++)
 -                 delete[] fMidiPlaybackBuffer[midi_port_index];
 -             delete[] fMidiPlaybackBuffer;
 -             fMidiPlaybackBuffer = NULL;
 -         }
 -     }
 - 
 -     // Transport
 -     void EncodeTransportData()
 -     {}
 - 
 -     void DecodeTransportData()
 -     {}
 - 
 -     bool Init()
 -     {
 -         // Will do "something" on OSX only...
 -         UInt64 period, constraint;
 -         period = constraint = UInt64(1000000000.f * (float(fParams.fPeriodSize) / float(fParams.fSampleRate)));
 -         UInt64 computation = JackTools::ComputationMicroSec(fParams.fPeriodSize) * 1000;
 -         fThread.SetParams(period, computation, constraint);
 - 
 -         return (fThread.AcquireSelfRealTime(80) == 0);      // TODO: get a value from the server
 -     }
 - 
 -     bool Execute()
 -     {
 -         try  {
 -             // Keep running even in case of error
 -             while (fThread.GetStatus() == JackThread::kRunning) {
 -                 if (Process() == SOCKET_ERROR) {
 -                     return false;
 -                 }
 -             }
 -             return false;
 -         } catch (JackNetException& e) {
 - 
 -             // Otherwise just restart...
 -             e.PrintMessage();
 -             fThread.DropRealTime();
 -             fThread.SetStatus(JackThread::kIniting);
 -             FreePorts();
 -             if (Restart() == 0 && Init()) {
 -                 fThread.SetStatus(JackThread::kRunning);
 -                 return true;
 -             } else {
 -                 return false;
 -             }
 -         }
 -     }
 - 
 -     int Read()
 -     {
 -         //receive sync (launch the cycle)
 -         if (SyncRecv() == SOCKET_ERROR) {
 -             return SOCKET_ERROR;
 -         }
 - 
 -         DecodeSyncPacket();
 -         return DataRecv();
 -     }
 - 
 -     int Write()
 -     {
 -         EncodeSyncPacket();
 - 
 -         if (SyncSend() == SOCKET_ERROR) {
 -             return SOCKET_ERROR;
 -         }
 - 
 -         return DataSend();
 -     }
 - 
 -     int Process()
 -     {
 -         // Read data from the network, throw JackNetException in case of network error...
 -         if (Read() == SOCKET_ERROR) {
 -             return SOCKET_ERROR;
 -         }
 - 
 -         fProcessCallback(fParams.fPeriodSize,
 -                         fParams.fSendAudioChannels,
 -                         fAudioCaptureBuffer,
 -                         fParams.fSendMidiChannels,
 -                         (void**)fMidiCaptureBuffer,
 -                         fParams.fReturnAudioChannels,
 -                         fAudioPlaybackBuffer,
 -                         fParams.fReturnMidiChannels,
 -                         (void**)fMidiPlaybackBuffer,
 -                         fProcessArg);
 - 
 -         // Then write data to network, throw JackNetException in case of network error...
 -         if (Write() == SOCKET_ERROR) {
 -             return SOCKET_ERROR;
 -         }
 - 
 -         return 0;
 -     }
 - 
 -     int Start()
 -     {
 -         return (fProcessCallback == 0) ? -1 : fThread.StartSync();
 -     }
 - 
 -     int Stop()
 -     {
 -         return (fProcessCallback == 0) ? -1 : fThread.Kill();
 -     }
 - 
 -     // Callback
 -     int SetProcessCallback(JackNetSlaveProcessCallback net_callback, void *arg)
 -     {
 -         if (fThread.GetStatus() == JackThread::kRunning) {
 -             return -1;
 -         } else {
 -             fProcessCallback = net_callback;
 -             fProcessArg = arg;
 -             return 0;
 -         }
 -     }
 - 
 -     int SetShutdownCallback(JackNetSlaveShutdownCallback shutdown_callback, void *arg)
 -     {
 -         if (fThread.GetStatus() == JackThread::kRunning) {
 -             return -1;
 -         } else {
 -             fShutdownCallback = shutdown_callback;
 -             fShutdownArg = arg;
 -             return 0;
 -         }
 -     }
 - 
 -     int SetBufferSizeCallback(JackNetSlaveBufferSizeCallback bufsize_callback, void *arg)
 -     {
 -         if (fThread.GetStatus() == JackThread::kRunning) {
 -             return -1;
 -         } else {
 -             fBufferSizeCallback = bufsize_callback;
 -             fBufferSizeArg = arg;
 -             return 0;
 -         }
 -     }
 - 
 -     int SetSampleRateCallback(JackNetSlaveSampleRateCallback samplerate_callback, void *arg)
 -     {
 -         if (fThread.GetStatus() == JackThread::kRunning) {
 -             return -1;
 -         } else {
 -             fSampleRateCallback = samplerate_callback;
 -             fSampleRateArg = arg;
 -             return 0;
 -         }
 -     }
 - 
 - };
 - 
 - struct JackNetAdapter : public JackAudioAdapterInterface {
 - 
 -     JackNetAdapter(int input, int output,
 -                     jack_nframes_t host_buffer_size,
 -                     jack_nframes_t host_sample_rate,
 -                     jack_nframes_t adapted_buffer_size,
 -                     jack_nframes_t adapted_sample_rate)
 -         :JackAudioAdapterInterface(host_buffer_size, host_sample_rate, adapted_buffer_size, adapted_sample_rate)
 -     {
 -         fCaptureChannels = input;
 -         fPlaybackChannels = output;
 -         Create();
 -     }
 - 
 -     void Create()
 -     {
 -         //ringbuffers
 - 
 -         if (fCaptureChannels > 0) {
 -             fCaptureRingBuffer = new JackResampler*[fCaptureChannels];
 -         }
 -         if (fPlaybackChannels > 0) {
 -             fPlaybackRingBuffer = new JackResampler*[fPlaybackChannels];
 -         }
 - 
 -         if (fAdaptative) {
 -             AdaptRingBufferSize();
 -             jack_info("Ringbuffer automatic adaptative mode size = %d frames", fRingbufferCurSize);
 -         } else {
 -             if (fRingbufferCurSize > DEFAULT_RB_SIZE) {
 -                 fRingbufferCurSize = DEFAULT_RB_SIZE;
 -             }
 -             jack_info("Fixed ringbuffer size = %d frames", fRingbufferCurSize);
 -         }
 - 
 -         for (int i = 0; i < fCaptureChannels; i++ ) {
 -             fCaptureRingBuffer[i] = new JackResampler();
 -             fCaptureRingBuffer[i]->Reset(fRingbufferCurSize);
 -         }
 -         for (int i = 0; i < fPlaybackChannels; i++ ) {
 -             fPlaybackRingBuffer[i] = new JackResampler();
 -             fPlaybackRingBuffer[i]->Reset(fRingbufferCurSize);
 -         }
 - 
 -         if (fCaptureChannels > 0) {
 -             jack_log("ReadSpace = %ld", fCaptureRingBuffer[0]->ReadSpace());
 -         }
 -         if (fPlaybackChannels > 0) {
 -             jack_log("WriteSpace = %ld", fPlaybackRingBuffer[0]->WriteSpace());
 -         }
 -     }
 - 
 -     virtual ~JackNetAdapter()
 -     {
 -         Destroy();
 -     }
 - 
 -     void Flush()
 -     {
 -         for (int i = 0; i < fCaptureChannels; i++ ) {
 -             fCaptureRingBuffer[i]->Reset(fRingbufferCurSize);
 -         }
 -         for (int i = 0; i < fPlaybackChannels; i++ ) {
 -             fPlaybackRingBuffer[i]->Reset(fRingbufferCurSize);
 -         }
 -     }
 - 
 - };
 - 
 - 
 - } // end of namespace
 - 
 - using namespace Jack;
 - 
 - SERVER_EXPORT jack_net_slave_t* jack_net_slave_open(const char* ip, int port, const char* name, jack_slave_t* request, jack_master_t* result)
 - {
 -     JackNetExtSlave* slave = new JackNetExtSlave(ip, port, name, request);
 -     if (slave->Open(result) == 0) {
 -         return (jack_net_slave_t*)slave;
 -     } else {
 -         delete slave;
 -         return NULL;
 -     }
 - }
 - 
 - SERVER_EXPORT int jack_net_slave_close(jack_net_slave_t* net)
 - {
 -     JackNetExtSlave* slave = (JackNetExtSlave*)net;
 -     slave->Close();
 -     delete slave;
 -     return 0;
 - }
 - 
 - SERVER_EXPORT int jack_set_net_slave_process_callback(jack_net_slave_t* net, JackNetSlaveProcessCallback net_callback, void *arg)
 - {
 -      JackNetExtSlave* slave = (JackNetExtSlave*)net;
 -      return slave->SetProcessCallback(net_callback, arg);
 - }
 - 
 - SERVER_EXPORT int jack_net_slave_activate(jack_net_slave_t* net)
 - {
 -     JackNetExtSlave* slave = (JackNetExtSlave*)net;
 -     return slave->Start();
 - }
 - 
 - SERVER_EXPORT int jack_net_slave_deactivate(jack_net_slave_t* net)
 - {
 -     JackNetExtSlave* slave = (JackNetExtSlave*)net;
 -     return slave->Stop();
 - }
 - 
 - SERVER_EXPORT int jack_set_net_slave_buffer_size_callback(jack_net_slave_t *net, JackNetSlaveBufferSizeCallback bufsize_callback, void *arg)
 - {
 -     JackNetExtSlave* slave = (JackNetExtSlave*)net;
 -     return slave->SetBufferSizeCallback(bufsize_callback, arg);
 - }
 - 
 - SERVER_EXPORT int jack_set_net_slave_sample_rate_callback(jack_net_slave_t *net, JackNetSlaveSampleRateCallback samplerate_callback, void *arg)
 - {
 -     JackNetExtSlave* slave = (JackNetExtSlave*)net;
 -     return slave->SetSampleRateCallback(samplerate_callback, arg);
 - }
 - 
 - SERVER_EXPORT int jack_set_net_slave_shutdown_callback(jack_net_slave_t *net, JackNetSlaveShutdownCallback shutdown_callback, void *arg)
 - {
 -     JackNetExtSlave* slave = (JackNetExtSlave*)net;
 -     return slave->SetShutdownCallback(shutdown_callback, arg);
 - }
 - 
 - // Master API
 - 
 - SERVER_EXPORT jack_net_master_t* jack_net_master_open(const char* ip, int port, const char* name, jack_master_t* request, jack_slave_t* result)
 - {
 -     JackNetExtMaster* master = new JackNetExtMaster(ip, port, name, request);
 -     if (master->Open(result) == 0) {
 -         return (jack_net_master_t*)master;
 -     } else {
 -         delete master;
 -         return NULL;
 -     }
 - }
 - 
 - SERVER_EXPORT int jack_net_master_close(jack_net_master_t* net)
 - {
 -     JackNetExtMaster* master = (JackNetExtMaster*)net;
 -     master->Close();
 -     delete master;
 -     return 0;
 - }
 - SERVER_EXPORT int jack_net_master_recv(jack_net_master_t* net, int audio_input, float** audio_input_buffer, int midi_input, void** midi_input_buffer)
 - {
 -     JackNetExtMaster* master = (JackNetExtMaster*)net;
 -     return master->Read(audio_input, audio_input_buffer, midi_input, midi_input_buffer);
 - }
 - 
 - SERVER_EXPORT int jack_net_master_send(jack_net_master_t* net, int audio_output, float** audio_output_buffer, int midi_output, void** midi_output_buffer)
 - {
 -     JackNetExtMaster* master = (JackNetExtMaster*)net;
 -     return master->Write(audio_output, audio_output_buffer, midi_output, midi_output_buffer);
 - }
 - 
 - // Adapter API
 - 
 - SERVER_EXPORT jack_adapter_t* jack_create_adapter(int input, int output,
 -                                                 jack_nframes_t host_buffer_size,
 -                                                 jack_nframes_t host_sample_rate,
 -                                                 jack_nframes_t adapted_buffer_size,
 -                                                 jack_nframes_t adapted_sample_rate)
 - {
 -     try {
 -         return (jack_adapter_t*)new JackNetAdapter(input, output, host_buffer_size, host_sample_rate, adapted_buffer_size, adapted_sample_rate);
 -     } catch (...) {
 -         return NULL;
 -     }
 - }
 - 
 - SERVER_EXPORT int jack_destroy_adapter(jack_adapter_t* adapter)
 - {
 -     delete((JackNetAdapter*)adapter);
 -     return 0;
 - }
 - 
 - SERVER_EXPORT void jack_flush_adapter(jack_adapter_t* adapter)
 - {
 -     JackNetAdapter* slave = (JackNetAdapter*)adapter;
 -     slave->Flush();
 - }
 - 
 - SERVER_EXPORT int jack_adapter_push_and_pull(jack_adapter_t* adapter, float** input, float** output, unsigned int frames)
 - {
 -     JackNetAdapter* slave = (JackNetAdapter*)adapter;
 -     return slave->PushAndPull(input, output, frames);
 - }
 - 
 - SERVER_EXPORT int jack_adapter_pull_and_push(jack_adapter_t* adapter, float** input, float** output, unsigned int frames)
 - {
 -     JackNetAdapter* slave = (JackNetAdapter*)adapter;
 -     return slave->PullAndPush(input, output, frames);
 - }
 - 
 - 
 - //#ifdef MY_TARGET_OS_IPHONE
 - #if 1
 - 
 - static void jack_format_and_log(int level, const char *prefix, const char *fmt, va_list ap)
 - {
 -     char buffer[300];
 -     size_t len;
 - 
 -     if (prefix != NULL) {
 -         len = strlen(prefix);
 -         memcpy(buffer, prefix, len);
 -     } else {
 -         len = 0;
 -     }
 - 
 -     vsnprintf(buffer + len, sizeof(buffer) - len, fmt, ap);
 -     printf("%s", buffer);
 -     printf("\n");
 - }
 - 
 - SERVER_EXPORT void jack_error(const char *fmt, ...)
 - {
 -     va_list ap;
 -     va_start(ap, fmt);
 -     jack_format_and_log(LOG_LEVEL_INFO, "Jack: ", fmt, ap);
 -     va_end(ap);
 - }
 - 
 - SERVER_EXPORT void jack_info(const char *fmt, ...)
 - {
 -     va_list ap;
 -     va_start(ap, fmt);
 -     jack_format_and_log(LOG_LEVEL_INFO, "Jack: ", fmt, ap);
 -     va_end(ap);
 - }
 - 
 - SERVER_EXPORT void jack_log(const char *fmt, ...)
 - {
 -     va_list ap;
 -     va_start(ap, fmt);
 -     jack_format_and_log(LOG_LEVEL_INFO, "Jack: ", fmt, ap);
 -     va_end(ap);
 - }
 - 
 - #else
 - 
 - // Empty code for now..
 - 
 - SERVER_EXPORT void jack_error(const char *fmt, ...)
 - {}
 - 
 - SERVER_EXPORT void jack_info(const char *fmt, ...)
 - {}
 - 
 - SERVER_EXPORT void jack_log(const char *fmt, ...)
 - {}
 - 
 - #endif
 
 
  |