Jack2  1.9.8
JackNetAPI.cpp
00001 /*
00002 Copyright (C) 2009-2011 Grame
00003 
00004 This program is free software; you can redistribute it and/or modify
00005 it under the terms of the GNU Lesser General Public License as published by
00006 the Free Software Foundation; either version 2.1 of the License, or
00007 (at your option) any later version.
00008 
00009 This program is distributed in the hope that it will be useful,
00010 but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 GNU Lesser General Public License for more details.
00013 
00014 You should have received a copy of the GNU Lesser General Public License
00015 along with this program; if not, write to the Free Software
00016 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00017 
00018 */
00019 
00020 #include <assert.h>
00021 #include <stdarg.h>
00022 #include "JackNetInterface.h"
00023 #include "JackError.h"
00024 #include "JackException.h"
00025 #include "JackAudioAdapterInterface.h"
00026 
00027 #ifdef __cplusplus
00028 extern "C"
00029 {
00030 #endif
00031 
00032     // NetJack common API
00033 
00034     #define MASTER_NAME_SIZE 256
00035 
00036     enum JackNetEncoder {
00037 
00038         JackFloatEncoder = 0,
00039         JackIntEncoder = 1,
00040         JackCeltEncoder = 2,
00041         JackMaxEncoder = 3
00042     };
00043 
00044     typedef struct {
00045 
00046         int audio_input;
00047         int audio_output;
00048         int midi_input;
00049         int midi_output;
00050         int mtu;
00051         int time_out;   // in millisecond, -1 means in infinite
00052         int encoder;    // one of JackNetEncoder
00053         int kbps;       // KB per second for CELT encoder
00054         int latency;    // network cycles
00055 
00056     } jack_slave_t;
00057 
00058     typedef struct {
00059 
00060         int audio_input;
00061         int audio_output;
00062         int midi_input;
00063         int midi_output;
00064         jack_nframes_t buffer_size;
00065         jack_nframes_t sample_rate;
00066         char master_name[MASTER_NAME_SIZE];
00067 
00068     } jack_master_t;
00069 
00070     // NetJack slave API
00071 
00072     typedef struct _jack_net_slave jack_net_slave_t;
00073 
00074     typedef int (* JackNetSlaveProcessCallback) (jack_nframes_t buffer_size,
00075                                             int audio_input,
00076                                             float** audio_input_buffer,
00077                                             int midi_input,
00078                                             void** midi_input_buffer,
00079                                             int audio_output,
00080                                             float** audio_output_buffer,
00081                                             int midi_output,
00082                                             void** midi_output_buffer,
00083                                             void* data);
00084 
00085     typedef int (*JackNetSlaveBufferSizeCallback) (jack_nframes_t nframes, void *arg);
00086     typedef int (*JackNetSlaveSampleRateCallback) (jack_nframes_t nframes, void *arg);
00087     typedef void (*JackNetSlaveShutdownCallback) (void* data);
00088 
00089     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);
00090     SERVER_EXPORT int jack_net_slave_close(jack_net_slave_t* net);
00091 
00092     SERVER_EXPORT int jack_net_slave_activate(jack_net_slave_t* net);
00093     SERVER_EXPORT int jack_net_slave_deactivate(jack_net_slave_t* net);
00094 
00095     SERVER_EXPORT int jack_set_net_slave_process_callback(jack_net_slave_t* net, JackNetSlaveProcessCallback net_callback, void *arg);
00096     SERVER_EXPORT int jack_set_net_slave_buffer_size_callback(jack_net_slave_t* net, JackNetSlaveBufferSizeCallback bufsize_callback, void *arg);
00097     SERVER_EXPORT int jack_set_net_slave_sample_rate_callback(jack_net_slave_t* net, JackNetSlaveSampleRateCallback samplerate_callback, void *arg);
00098     SERVER_EXPORT int jack_set_net_slave_shutdown_callback(jack_net_slave_t* net, JackNetSlaveShutdownCallback shutdown_callback, void *arg);
00099 
00100     // NetJack master API
00101 
00102     typedef struct _jack_net_master jack_net_master_t;
00103 
00104     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);
00105     SERVER_EXPORT int jack_net_master_close(jack_net_master_t* net);
00106 
00107     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);
00108     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);
00109 
00110     // NetJack adapter API
00111 
00112     typedef struct _jack_adapter jack_adapter_t;
00113 
00114     SERVER_EXPORT jack_adapter_t* jack_create_adapter(int input, int output,
00115                                                     jack_nframes_t host_buffer_size,
00116                                                     jack_nframes_t host_sample_rate,
00117                                                     jack_nframes_t adapted_buffer_size,
00118                                                     jack_nframes_t adapted_sample_rate);
00119     SERVER_EXPORT int jack_destroy_adapter(jack_adapter_t* adapter);
00120     SERVER_EXPORT void jack_flush_adapter(jack_adapter_t* adapter);
00121 
00122     SERVER_EXPORT int jack_adapter_push_and_pull(jack_adapter_t* adapter, float** input, float** output, unsigned int frames);
00123     SERVER_EXPORT int jack_adapter_pull_and_push(jack_adapter_t* adapter, float** input, float** output, unsigned int frames);
00124 
00125 #ifdef __cplusplus
00126 }
00127 #endif
00128 
00129 namespace Jack
00130 {
00131 
00132 struct JackNetExtMaster : public JackNetMasterInterface {
00133 
00134     // Data buffers
00135     float** fAudioCaptureBuffer;
00136     float** fAudioPlaybackBuffer;
00137 
00138     JackMidiBuffer** fMidiCaptureBuffer;
00139     JackMidiBuffer** fMidiPlaybackBuffer;
00140 
00141     jack_master_t fRequest;
00142 
00143     JackNetExtMaster(const char* ip,
00144                     int port,
00145                     const char* name,
00146                     jack_master_t* request)
00147     {
00148         fRunning = true;
00149         assert(strlen(ip) < 32);
00150         strcpy(fMulticastIP, ip);
00151         fSocket.SetPort(port);
00152         fRequest.buffer_size = request->buffer_size;
00153         fRequest.sample_rate = request->sample_rate;
00154         fAudioCaptureBuffer = NULL;
00155         fAudioPlaybackBuffer = NULL;
00156         fMidiCaptureBuffer = NULL;
00157         fMidiPlaybackBuffer = NULL;
00158     }
00159 
00160     virtual ~JackNetExtMaster()
00161     {}
00162 
00163     int Open(jack_slave_t* result)
00164     {
00165         // Init socket API (win32)
00166         if (SocketAPIInit() < 0) {
00167             jack_error("Can't init Socket API, exiting...");
00168             return -1;
00169         }
00170 
00171         // Request socket
00172         if (fSocket.NewSocket() == SOCKET_ERROR) {
00173             jack_error("Can't create the network management input socket : %s", StrError(NET_ERROR_CODE));
00174             return -1;
00175         }
00176 
00177         // Bind the socket to the local port
00178         if (fSocket.Bind() == SOCKET_ERROR) {
00179             jack_error("Can't bind the network manager socket : %s", StrError(NET_ERROR_CODE));
00180             fSocket.Close();
00181             return -1;
00182         }
00183 
00184         // Join multicast group
00185         if (fSocket.JoinMCastGroup(fMulticastIP) == SOCKET_ERROR) {
00186             jack_error("Can't join multicast group : %s", StrError(NET_ERROR_CODE));
00187         }
00188 
00189         // Local loop
00190         if (fSocket.SetLocalLoop() == SOCKET_ERROR) {
00191             jack_error("Can't set local loop : %s", StrError(NET_ERROR_CODE));
00192         }
00193 
00194         // Set a timeout on the multicast receive (the thread can now be cancelled)
00195         if (fSocket.SetTimeOut(MANAGER_INIT_TIMEOUT) == SOCKET_ERROR) {
00196             jack_error("Can't set timeout : %s", StrError(NET_ERROR_CODE));
00197         }
00198 
00199          // Main loop, wait for data, deal with it and wait again
00200         int attempt = 0;
00201         int rx_bytes = 0;
00202 
00203         do
00204         {
00205             session_params_t net_params;
00206             rx_bytes = fSocket.CatchHost(&net_params, sizeof(session_params_t), 0);
00207             SessionParamsNToH(&net_params, &fParams);
00208 
00209             if ((rx_bytes == SOCKET_ERROR) && (fSocket.GetError() != NET_NO_DATA)) {
00210                 jack_error("Error in receive : %s", StrError(NET_ERROR_CODE));
00211                 if (++attempt == 10) {
00212                     jack_error("Can't receive on the socket, exiting net manager" );
00213                     goto error;
00214                 }
00215             }
00216 
00217             if (rx_bytes == sizeof(session_params_t ))  {
00218 
00219                 switch (GetPacketType(&fParams)) {
00220 
00221                     case SLAVE_AVAILABLE:
00222                         if (MasterInit() == 0) {
00223                             SessionParamsDisplay(&fParams);
00224                             fRunning = false;
00225                         } else {
00226                             jack_error("Can't init new net master...");
00227                             goto error;
00228                         }
00229                         jack_info("Waiting for a slave...");
00230                         break;
00231 
00232                     case KILL_MASTER:
00233                          break;
00234 
00235                     default:
00236                         break;
00237                 }
00238             }
00239         }
00240         while (fRunning);
00241 
00242         // Set result paramaters
00243         result->audio_input = fParams.fSendAudioChannels;
00244         result->audio_output = fParams.fReturnAudioChannels;
00245         result->midi_input = fParams.fSendMidiChannels;
00246         result->midi_output = fParams.fReturnMidiChannels;
00247         result->mtu = fParams.fMtu;
00248         result->latency = fParams.fNetworkLatency;
00249         return 0;
00250 
00251     error:
00252         fSocket.Close();
00253         return -1;
00254     }
00255 
00256     int MasterInit()
00257     {
00258         // Check MASTER <==> SLAVE network protocol coherency
00259         if (fParams.fProtocolVersion != MASTER_PROTOCOL) {
00260             jack_error("Error : slave is running with a different protocol %s", fParams.fName);
00261             return -1;
00262         }
00263 
00264         // Settings
00265         fSocket.GetName(fParams.fMasterNetName);
00266         fParams.fID = 1;
00267         fParams.fSampleEncoder = JackFloatEncoder;
00268         fParams.fPeriodSize = fRequest.buffer_size;
00269         fParams.fSampleRate = fRequest.sample_rate;
00270 
00271         // Close request socket
00272         fSocket.Close();
00273 
00274         // Network slave init
00275         if (!JackNetMasterInterface::Init()) {
00276             return -1;
00277         }
00278 
00279         // Set global parameters
00280         if (!SetParams()) {
00281             return -1;
00282         }
00283 
00284         AllocPorts();
00285         return 0;
00286     }
00287 
00288     int Close()
00289     {
00290         fSocket.Close();
00291         FreePorts();
00292         return 0;
00293     }
00294 
00295     void AllocPorts()
00296     {
00297         // Set buffers
00298         if (fParams.fSendAudioChannels > 0) {
00299             fAudioCaptureBuffer = new float*[fParams.fSendAudioChannels];
00300             for (int audio_port_index = 0; audio_port_index < fParams.fSendAudioChannels; audio_port_index++) {
00301                 fAudioCaptureBuffer[audio_port_index] = new float[fParams.fPeriodSize];
00302                 fNetAudioCaptureBuffer->SetBuffer(audio_port_index, fAudioCaptureBuffer[audio_port_index]);
00303             }
00304         }
00305 
00306         if (fParams.fSendMidiChannels > 0) {
00307             fMidiCaptureBuffer = new JackMidiBuffer*[fParams.fSendMidiChannels];
00308             for (int midi_port_index = 0; midi_port_index < fParams.fSendMidiChannels; midi_port_index++) {
00309                 fMidiCaptureBuffer[midi_port_index] = (JackMidiBuffer*)new float[fParams.fPeriodSize];
00310                 fNetMidiCaptureBuffer->SetBuffer(midi_port_index, fMidiCaptureBuffer[midi_port_index]);
00311             }
00312         }
00313 
00314         if (fParams.fReturnAudioChannels > 0) {
00315             fAudioPlaybackBuffer = new float*[fParams.fReturnAudioChannels];
00316             for (int audio_port_index = 0; audio_port_index < fParams.fReturnAudioChannels; audio_port_index++) {
00317                 fAudioPlaybackBuffer[audio_port_index] = new float[fParams.fPeriodSize];
00318                 fNetAudioPlaybackBuffer->SetBuffer(audio_port_index, fAudioPlaybackBuffer[audio_port_index]);
00319             }
00320         }
00321 
00322         if (fParams.fReturnMidiChannels > 0) {
00323             fMidiPlaybackBuffer = new JackMidiBuffer*[fParams.fReturnMidiChannels];
00324             for (int midi_port_index = 0; midi_port_index < fParams.fReturnMidiChannels; midi_port_index++) {
00325                 fMidiPlaybackBuffer[midi_port_index] = (JackMidiBuffer*)new float[fParams.fPeriodSize];
00326                 fNetMidiPlaybackBuffer->SetBuffer(midi_port_index, fMidiPlaybackBuffer[midi_port_index]);
00327             }
00328         }
00329     }
00330 
00331     void FreePorts()
00332     {
00333         if (fAudioPlaybackBuffer) {
00334             for (int audio_port_index = 0; audio_port_index < fParams.fSendAudioChannels; audio_port_index++)
00335                 delete[] fAudioPlaybackBuffer[audio_port_index];
00336             delete[] fAudioPlaybackBuffer;
00337             fAudioPlaybackBuffer = NULL;
00338         }
00339 
00340         if (fMidiPlaybackBuffer) {
00341             for (int midi_port_index = 0; midi_port_index < fParams.fSendMidiChannels; midi_port_index++)
00342                 delete[] (fMidiPlaybackBuffer[midi_port_index]);
00343             delete[] fMidiPlaybackBuffer;
00344             fMidiPlaybackBuffer = NULL;
00345         }
00346 
00347         if (fAudioCaptureBuffer) {
00348             for (int audio_port_index = 0; audio_port_index < fParams.fReturnAudioChannels; audio_port_index++)
00349                 delete[] fAudioCaptureBuffer[audio_port_index];
00350             delete[] fAudioCaptureBuffer;
00351             fAudioCaptureBuffer = NULL;
00352         }
00353 
00354         if (fMidiCaptureBuffer) {
00355             for (int midi_port_index = 0; midi_port_index < fParams.fReturnMidiChannels; midi_port_index++)
00356                 delete[] fMidiCaptureBuffer[midi_port_index];
00357             delete[] fMidiCaptureBuffer;
00358             fMidiCaptureBuffer = NULL;
00359         }
00360     }
00361 
00362     int Read(int audio_input, float** audio_input_buffer, int midi_input, void** midi_input_buffer)
00363     {
00364         try {
00365             assert(audio_input == fParams.fReturnAudioChannels);
00366 
00367             for (int audio_port_index = 0; audio_port_index < audio_input; audio_port_index++) {
00368                 fNetAudioPlaybackBuffer->SetBuffer(audio_port_index, audio_input_buffer[audio_port_index]);
00369             }
00370 
00371             for (int midi_port_index = 0; midi_port_index < midi_input; midi_port_index++) {
00372                 fNetMidiPlaybackBuffer->SetBuffer(midi_port_index, ((JackMidiBuffer**)midi_input_buffer)[midi_port_index]);
00373             }
00374 
00375             if (SyncRecv() == SOCKET_ERROR) {
00376                 return 0;
00377             }
00378 
00379             DecodeSyncPacket();
00380             return DataRecv();
00381 
00382         } catch (JackNetException& e) {
00383             jack_error("Connection lost.");
00384             return -1;
00385         }
00386      }
00387 
00388      int Write(int audio_output, float** audio_output_buffer, int midi_output, void** midi_output_buffer)
00389      {
00390         try {
00391             assert(audio_output == fParams.fSendAudioChannels);
00392 
00393             for (int audio_port_index = 0; audio_port_index < audio_output; audio_port_index++) {
00394                 fNetAudioCaptureBuffer->SetBuffer(audio_port_index, audio_output_buffer[audio_port_index]);
00395             }
00396 
00397             for (int midi_port_index = 0; midi_port_index < midi_output; midi_port_index++) {
00398                 fNetMidiCaptureBuffer->SetBuffer(midi_port_index, ((JackMidiBuffer**)midi_output_buffer)[midi_port_index]);
00399             }
00400 
00401             EncodeSyncPacket();
00402 
00403             if (SyncSend() == SOCKET_ERROR) {
00404                 return SOCKET_ERROR;
00405             }
00406 
00407             return DataSend();
00408 
00409         } catch (JackNetException& e) {
00410             jack_error("Connection lost.");
00411             return -1;
00412         }
00413      }
00414 
00415     // Transport
00416     void EncodeTransportData()
00417     {}
00418 
00419     void DecodeTransportData()
00420     {}
00421 
00422 };
00423 
00424 struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterface {
00425 
00426     JackThread fThread;
00427 
00428     JackNetSlaveProcessCallback fProcessCallback;
00429     void* fProcessArg;
00430 
00431     JackNetSlaveShutdownCallback fShutdownCallback;
00432     void* fShutdownArg;
00433 
00434     JackNetSlaveBufferSizeCallback fBufferSizeCallback;
00435     void* fBufferSizeArg;
00436 
00437     JackNetSlaveSampleRateCallback fSampleRateCallback;
00438     void* fSampleRateArg;
00439 
00440     //sample buffers
00441     float** fAudioCaptureBuffer;
00442     float** fAudioPlaybackBuffer;
00443 
00444     JackMidiBuffer** fMidiCaptureBuffer;
00445     JackMidiBuffer** fMidiPlaybackBuffer;
00446 
00447     int fConnectTimeOut;
00448 
00449     JackNetExtSlave(const char* ip,
00450                     int port,
00451                     const char* name,
00452                     jack_slave_t* request)
00453         :fThread(this),
00454         fProcessCallback(NULL),fProcessArg(NULL),
00455         fShutdownCallback(NULL), fShutdownArg(NULL),
00456         fBufferSizeCallback(NULL), fBufferSizeArg(NULL),
00457         fSampleRateCallback(NULL), fSampleRateArg(NULL),
00458         fAudioCaptureBuffer(NULL), fAudioPlaybackBuffer(NULL),
00459         fMidiCaptureBuffer(NULL), fMidiPlaybackBuffer(NULL)
00460     {
00461         char host_name[JACK_CLIENT_NAME_SIZE];
00462 
00463         // Request parameters
00464         assert(strlen(ip) < 32);
00465         strcpy(fMulticastIP, ip);
00466         fParams.fMtu = request->mtu;
00467         fParams.fTransportSync = 0;
00468         fParams.fSendAudioChannels = request->audio_input;
00469         fParams.fReturnAudioChannels = request->audio_output;
00470         fParams.fSendMidiChannels = request->midi_input;
00471         fParams.fReturnMidiChannels = request->midi_output;
00472         fParams.fNetworkLatency = request->latency;
00473         fParams.fSampleEncoder = request->encoder;
00474         fParams.fKBps = request->kbps;
00475         fParams.fSlaveSyncMode = 1;
00476         fConnectTimeOut = request->time_out;
00477 
00478         // Create name with hostname and client name
00479         GetHostName(host_name, JACK_CLIENT_NAME_SIZE);
00480         snprintf(fParams.fName, JACK_CLIENT_NAME_SIZE, "%s_%s", host_name, name);
00481         fSocket.GetName(fParams.fSlaveNetName);
00482 
00483         // Set the socket parameters
00484         fSocket.SetPort(port);
00485         fSocket.SetAddress(fMulticastIP, port);
00486     }
00487 
00488     virtual ~JackNetExtSlave()
00489     {}
00490 
00491     int Open(jack_master_t* result)
00492     {
00493         if (fParams.fNetworkLatency > NETWORK_MAX_LATENCY) {
00494             jack_error("Error : network latency is limited to %d", NETWORK_MAX_LATENCY);
00495             return -1;
00496         }
00497 
00498         // Init network connection
00499         if (!JackNetSlaveInterface::InitConnection(fConnectTimeOut)) {
00500             jack_error("Initing network fails...");
00501             return -1;
00502         }
00503 
00504         // Finish connection...
00505         if (!JackNetSlaveInterface::InitRendering()) {
00506             jack_error("Starting network fails...");
00507             return -1;
00508         }
00509 
00510         // Then set global parameters
00511         if (!SetParams()) {
00512             jack_error("SetParams error...");
00513             return -1;
00514         }
00515 
00516          // Set result
00517          if (result != NULL) {
00518             result->buffer_size = fParams.fPeriodSize;
00519             result->sample_rate = fParams.fSampleRate;
00520             result->audio_input = fParams.fSendAudioChannels;
00521             result->audio_output = fParams.fReturnAudioChannels;
00522             result->midi_input = fParams.fSendMidiChannels;
00523             result->midi_output = fParams.fReturnMidiChannels;
00524             strcpy(result->master_name, fParams.fMasterNetName);
00525         }
00526 
00527         AllocPorts();
00528         return 0;
00529     }
00530 
00531     int Restart()
00532     {
00533         // If shutdown cb is set, then call it
00534         if (fShutdownCallback) {
00535             fShutdownCallback(fShutdownArg);
00536         }
00537 
00538         // Init network connection
00539         if (!JackNetSlaveInterface::InitConnection(fConnectTimeOut)) {
00540             jack_error("Initing network fails...");
00541             return -1;
00542         }
00543 
00544          // Finish connection...
00545         if (!JackNetSlaveInterface::InitRendering()) {
00546             jack_error("Starting network fails...");
00547             return -1;
00548         }
00549 
00550         // Then set global parameters
00551         if (!SetParams()) {
00552             jack_error("SetParams error...");
00553             return -1;
00554         }
00555 
00556         // We need to notify possibly new buffer size and sample rate (see Execute)
00557         if (fBufferSizeCallback) {
00558             fBufferSizeCallback(fParams.fPeriodSize, fBufferSizeArg);
00559         }
00560 
00561         if (fSampleRateCallback) {
00562             fSampleRateCallback(fParams.fSampleRate, fSampleRateArg);
00563         }
00564 
00565         AllocPorts();
00566         return 0;
00567     }
00568 
00569     int Close()
00570     {
00571         fSocket.Close();
00572         FreePorts();
00573         return 0;
00574     }
00575 
00576     void AllocPorts()
00577     {
00578         // Set buffers
00579         fAudioCaptureBuffer = new float*[fParams.fSendAudioChannels];
00580         for (int audio_port_index = 0; audio_port_index < fParams.fSendAudioChannels; audio_port_index++) {
00581             fAudioCaptureBuffer[audio_port_index] = new float[fParams.fPeriodSize];
00582             fNetAudioCaptureBuffer->SetBuffer(audio_port_index, fAudioCaptureBuffer[audio_port_index]);
00583         }
00584 
00585         fMidiCaptureBuffer = new JackMidiBuffer*[fParams.fSendMidiChannels];
00586         for (int midi_port_index = 0; midi_port_index < fParams.fSendMidiChannels; midi_port_index++) {
00587             fMidiCaptureBuffer[midi_port_index] = (JackMidiBuffer*)new float[fParams.fPeriodSize];
00588             fNetMidiCaptureBuffer->SetBuffer(midi_port_index, fMidiCaptureBuffer[midi_port_index]);
00589         }
00590 
00591         fAudioPlaybackBuffer = new float*[fParams.fReturnAudioChannels];
00592         for (int audio_port_index = 0; audio_port_index < fParams.fReturnAudioChannels; audio_port_index++) {
00593             fAudioPlaybackBuffer[audio_port_index] = new float[fParams.fPeriodSize];
00594             fNetAudioPlaybackBuffer->SetBuffer(audio_port_index, fAudioPlaybackBuffer[audio_port_index]);
00595         }
00596 
00597         fMidiPlaybackBuffer = new JackMidiBuffer*[fParams.fReturnMidiChannels];
00598         for (int midi_port_index = 0; midi_port_index < fParams.fReturnMidiChannels; midi_port_index++) {
00599             fMidiPlaybackBuffer[midi_port_index] = (JackMidiBuffer*)new float[fParams.fPeriodSize];
00600             fNetMidiPlaybackBuffer->SetBuffer(midi_port_index, fMidiPlaybackBuffer[midi_port_index]);
00601         }
00602     }
00603 
00604     void FreePorts()
00605     {
00606         if (fAudioCaptureBuffer) {
00607             for (int audio_port_index = 0; audio_port_index < fParams.fSendAudioChannels; audio_port_index++)
00608                 delete[] fAudioCaptureBuffer[audio_port_index];
00609             delete[] fAudioCaptureBuffer;
00610             fAudioCaptureBuffer = NULL;
00611         }
00612 
00613         if (fMidiCaptureBuffer) {
00614             for (int midi_port_index = 0; midi_port_index < fParams.fSendMidiChannels; midi_port_index++)
00615                 delete[] (fMidiCaptureBuffer[midi_port_index]);
00616             delete[] fMidiCaptureBuffer;
00617             fMidiCaptureBuffer = NULL;
00618         }
00619 
00620         if (fAudioPlaybackBuffer) {
00621             for (int audio_port_index = 0; audio_port_index < fParams.fReturnAudioChannels; audio_port_index++)
00622                 delete[] fAudioPlaybackBuffer[audio_port_index];
00623             delete[] fAudioPlaybackBuffer;
00624             fAudioPlaybackBuffer = NULL;
00625         }
00626 
00627         if (fMidiPlaybackBuffer) {
00628             for (int midi_port_index = 0; midi_port_index < fParams.fReturnMidiChannels; midi_port_index++)
00629                 delete[] fMidiPlaybackBuffer[midi_port_index];
00630             delete[] fMidiPlaybackBuffer;
00631             fMidiPlaybackBuffer = NULL;
00632         }
00633     }
00634 
00635     // Transport
00636     void EncodeTransportData()
00637     {}
00638 
00639     void DecodeTransportData()
00640     {}
00641 
00642     bool Init()
00643     {
00644         // Will do "something" on OSX only...
00645         UInt64 period, constraint;
00646         period = constraint = UInt64(1000000000.f * (float(fParams.fPeriodSize) / float(fParams.fSampleRate)));
00647         UInt64 computation = JackTools::ComputationMicroSec(fParams.fPeriodSize) * 1000;
00648         fThread.SetParams(period, computation, constraint);
00649 
00650         return (fThread.AcquireSelfRealTime(80) == 0);      // TODO: get a value from the server
00651     }
00652 
00653     bool Execute()
00654     {
00655         try  {
00656             // Keep running even in case of error
00657             while (fThread.GetStatus() == JackThread::kRunning) {
00658                 if (Process() == SOCKET_ERROR) {
00659                     return false;
00660                 }
00661             }
00662             return false;
00663         } catch (JackNetException& e) {
00664 
00665             // Otherwise just restart...
00666             e.PrintMessage();
00667             fThread.DropRealTime();
00668             fThread.SetStatus(JackThread::kIniting);
00669             FreePorts();
00670             if (Restart() == 0 && Init()) {
00671                 fThread.SetStatus(JackThread::kRunning);
00672                 return true;
00673             } else {
00674                 return false;
00675             }
00676         }
00677     }
00678 
00679     int Read()
00680     {
00681         //receive sync (launch the cycle)
00682         if (SyncRecv() == SOCKET_ERROR) {
00683             return SOCKET_ERROR;
00684         }
00685 
00686         DecodeSyncPacket();
00687         return DataRecv();
00688     }
00689 
00690     int Write()
00691     {
00692         EncodeSyncPacket();
00693 
00694         if (SyncSend() == SOCKET_ERROR) {
00695             return SOCKET_ERROR;
00696         }
00697 
00698         return DataSend();
00699     }
00700 
00701     int Process()
00702     {
00703         // Read data from the network, throw JackNetException in case of network error...
00704         if (Read() == SOCKET_ERROR) {
00705             return SOCKET_ERROR;
00706         }
00707 
00708         fProcessCallback(fParams.fPeriodSize,
00709                         fParams.fSendAudioChannels,
00710                         fAudioCaptureBuffer,
00711                         fParams.fSendMidiChannels,
00712                         (void**)fMidiCaptureBuffer,
00713                         fParams.fReturnAudioChannels,
00714                         fAudioPlaybackBuffer,
00715                         fParams.fReturnMidiChannels,
00716                         (void**)fMidiPlaybackBuffer,
00717                         fProcessArg);
00718 
00719         // Then write data to network, throw JackNetException in case of network error...
00720         if (Write() == SOCKET_ERROR) {
00721             return SOCKET_ERROR;
00722         }
00723 
00724         return 0;
00725     }
00726 
00727     int Start()
00728     {
00729         return (fProcessCallback == 0) ? -1 : fThread.StartSync();
00730     }
00731 
00732     int Stop()
00733     {
00734         return (fProcessCallback == 0) ? -1 : fThread.Kill();
00735     }
00736 
00737     // Callback
00738     int SetProcessCallback(JackNetSlaveProcessCallback net_callback, void *arg)
00739     {
00740         if (fThread.GetStatus() == JackThread::kRunning) {
00741             return -1;
00742         } else {
00743             fProcessCallback = net_callback;
00744             fProcessArg = arg;
00745             return 0;
00746         }
00747     }
00748 
00749     int SetShutdownCallback(JackNetSlaveShutdownCallback shutdown_callback, void *arg)
00750     {
00751         if (fThread.GetStatus() == JackThread::kRunning) {
00752             return -1;
00753         } else {
00754             fShutdownCallback = shutdown_callback;
00755             fShutdownArg = arg;
00756             return 0;
00757         }
00758     }
00759 
00760     int SetBufferSizeCallback(JackNetSlaveBufferSizeCallback bufsize_callback, void *arg)
00761     {
00762         if (fThread.GetStatus() == JackThread::kRunning) {
00763             return -1;
00764         } else {
00765             fBufferSizeCallback = bufsize_callback;
00766             fBufferSizeArg = arg;
00767             return 0;
00768         }
00769     }
00770 
00771     int SetSampleRateCallback(JackNetSlaveSampleRateCallback samplerate_callback, void *arg)
00772     {
00773         if (fThread.GetStatus() == JackThread::kRunning) {
00774             return -1;
00775         } else {
00776             fSampleRateCallback = samplerate_callback;
00777             fSampleRateArg = arg;
00778             return 0;
00779         }
00780     }
00781 
00782 };
00783 
00784 struct JackNetAdapter : public JackAudioAdapterInterface {
00785 
00786     JackNetAdapter(int input, int output,
00787                     jack_nframes_t host_buffer_size,
00788                     jack_nframes_t host_sample_rate,
00789                     jack_nframes_t adapted_buffer_size,
00790                     jack_nframes_t adapted_sample_rate)
00791         :JackAudioAdapterInterface(host_buffer_size, host_sample_rate, adapted_buffer_size, adapted_sample_rate)
00792     {
00793         fCaptureChannels = input;
00794         fPlaybackChannels = output;
00795         Create();
00796     }
00797 
00798     void Create()
00799     {
00800         //ringbuffers
00801 
00802         if (fCaptureChannels > 0) {
00803             fCaptureRingBuffer = new JackResampler*[fCaptureChannels];
00804         }
00805         if (fPlaybackChannels > 0) {
00806             fPlaybackRingBuffer = new JackResampler*[fPlaybackChannels];
00807         }
00808 
00809         if (fAdaptative) {
00810             AdaptRingBufferSize();
00811             jack_info("Ringbuffer automatic adaptative mode size = %d frames", fRingbufferCurSize);
00812         } else {
00813             if (fRingbufferCurSize > DEFAULT_RB_SIZE) {
00814                 fRingbufferCurSize = DEFAULT_RB_SIZE;
00815             }
00816             jack_info("Fixed ringbuffer size = %d frames", fRingbufferCurSize);
00817         }
00818 
00819         for (int i = 0; i < fCaptureChannels; i++ ) {
00820             fCaptureRingBuffer[i] = new JackResampler();
00821             fCaptureRingBuffer[i]->Reset(fRingbufferCurSize);
00822         }
00823         for (int i = 0; i < fPlaybackChannels; i++ ) {
00824             fPlaybackRingBuffer[i] = new JackResampler();
00825             fPlaybackRingBuffer[i]->Reset(fRingbufferCurSize);
00826         }
00827 
00828         if (fCaptureChannels > 0) {
00829             jack_log("ReadSpace = %ld", fCaptureRingBuffer[0]->ReadSpace());
00830         }
00831         if (fPlaybackChannels > 0) {
00832             jack_log("WriteSpace = %ld", fPlaybackRingBuffer[0]->WriteSpace());
00833         }
00834     }
00835 
00836     virtual ~JackNetAdapter()
00837     {
00838         Destroy();
00839     }
00840 
00841     void Flush()
00842     {
00843         for (int i = 0; i < fCaptureChannels; i++ ) {
00844             fCaptureRingBuffer[i]->Reset(fRingbufferCurSize);
00845         }
00846         for (int i = 0; i < fPlaybackChannels; i++ ) {
00847             fPlaybackRingBuffer[i]->Reset(fRingbufferCurSize);
00848         }
00849     }
00850 
00851 };
00852 
00853 
00854 } // end of namespace
00855 
00856 using namespace Jack;
00857 
00858 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)
00859 {
00860     JackNetExtSlave* slave = new JackNetExtSlave(ip, port, name, request);
00861     if (slave->Open(result) == 0) {
00862         return (jack_net_slave_t*)slave;
00863     } else {
00864         delete slave;
00865         return NULL;
00866     }
00867 }
00868 
00869 SERVER_EXPORT int jack_net_slave_close(jack_net_slave_t* net)
00870 {
00871     JackNetExtSlave* slave = (JackNetExtSlave*)net;
00872     slave->Close();
00873     delete slave;
00874     return 0;
00875 }
00876 
00877 SERVER_EXPORT int jack_set_net_slave_process_callback(jack_net_slave_t* net, JackNetSlaveProcessCallback net_callback, void *arg)
00878 {
00879      JackNetExtSlave* slave = (JackNetExtSlave*)net;
00880      return slave->SetProcessCallback(net_callback, arg);
00881 }
00882 
00883 SERVER_EXPORT int jack_net_slave_activate(jack_net_slave_t* net)
00884 {
00885     JackNetExtSlave* slave = (JackNetExtSlave*)net;
00886     return slave->Start();
00887 }
00888 
00889 SERVER_EXPORT int jack_net_slave_deactivate(jack_net_slave_t* net)
00890 {
00891     JackNetExtSlave* slave = (JackNetExtSlave*)net;
00892     return slave->Stop();
00893 }
00894 
00895 SERVER_EXPORT int jack_set_net_slave_buffer_size_callback(jack_net_slave_t *net, JackNetSlaveBufferSizeCallback bufsize_callback, void *arg)
00896 {
00897     JackNetExtSlave* slave = (JackNetExtSlave*)net;
00898     return slave->SetBufferSizeCallback(bufsize_callback, arg);
00899 }
00900 
00901 SERVER_EXPORT int jack_set_net_slave_sample_rate_callback(jack_net_slave_t *net, JackNetSlaveSampleRateCallback samplerate_callback, void *arg)
00902 {
00903     JackNetExtSlave* slave = (JackNetExtSlave*)net;
00904     return slave->SetSampleRateCallback(samplerate_callback, arg);
00905 }
00906 
00907 SERVER_EXPORT int jack_set_net_slave_shutdown_callback(jack_net_slave_t *net, JackNetSlaveShutdownCallback shutdown_callback, void *arg)
00908 {
00909     JackNetExtSlave* slave = (JackNetExtSlave*)net;
00910     return slave->SetShutdownCallback(shutdown_callback, arg);
00911 }
00912 
00913 // Master API
00914 
00915 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)
00916 {
00917     JackNetExtMaster* master = new JackNetExtMaster(ip, port, name, request);
00918     if (master->Open(result) == 0) {
00919         return (jack_net_master_t*)master;
00920     } else {
00921         delete master;
00922         return NULL;
00923     }
00924 }
00925 
00926 SERVER_EXPORT int jack_net_master_close(jack_net_master_t* net)
00927 {
00928     JackNetExtMaster* master = (JackNetExtMaster*)net;
00929     master->Close();
00930     delete master;
00931     return 0;
00932 }
00933 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)
00934 {
00935     JackNetExtMaster* master = (JackNetExtMaster*)net;
00936     return master->Read(audio_input, audio_input_buffer, midi_input, midi_input_buffer);
00937 }
00938 
00939 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)
00940 {
00941     JackNetExtMaster* master = (JackNetExtMaster*)net;
00942     return master->Write(audio_output, audio_output_buffer, midi_output, midi_output_buffer);
00943 }
00944 
00945 // Adapter API
00946 
00947 SERVER_EXPORT jack_adapter_t* jack_create_adapter(int input, int output,
00948                                                 jack_nframes_t host_buffer_size,
00949                                                 jack_nframes_t host_sample_rate,
00950                                                 jack_nframes_t adapted_buffer_size,
00951                                                 jack_nframes_t adapted_sample_rate)
00952 {
00953     try {
00954         return (jack_adapter_t*)new JackNetAdapter(input, output, host_buffer_size, host_sample_rate, adapted_buffer_size, adapted_sample_rate);
00955     } catch (...) {
00956         return NULL;
00957     }
00958 }
00959 
00960 SERVER_EXPORT int jack_destroy_adapter(jack_adapter_t* adapter)
00961 {
00962     delete((JackNetAdapter*)adapter);
00963     return 0;
00964 }
00965 
00966 SERVER_EXPORT void jack_flush_adapter(jack_adapter_t* adapter)
00967 {
00968     JackNetAdapter* slave = (JackNetAdapter*)adapter;
00969     slave->Flush();
00970 }
00971 
00972 SERVER_EXPORT int jack_adapter_push_and_pull(jack_adapter_t* adapter, float** input, float** output, unsigned int frames)
00973 {
00974     JackNetAdapter* slave = (JackNetAdapter*)adapter;
00975     return slave->PushAndPull(input, output, frames);
00976 }
00977 
00978 SERVER_EXPORT int jack_adapter_pull_and_push(jack_adapter_t* adapter, float** input, float** output, unsigned int frames)
00979 {
00980     JackNetAdapter* slave = (JackNetAdapter*)adapter;
00981     return slave->PullAndPush(input, output, frames);
00982 }
00983 
00984 
00985 //#ifdef MY_TARGET_OS_IPHONE
00986 #if 1
00987 
00988 static void jack_format_and_log(int level, const char *prefix, const char *fmt, va_list ap)
00989 {
00990     char buffer[300];
00991     size_t len;
00992 
00993     if (prefix != NULL) {
00994         len = strlen(prefix);
00995         memcpy(buffer, prefix, len);
00996     } else {
00997         len = 0;
00998     }
00999 
01000     vsnprintf(buffer + len, sizeof(buffer) - len, fmt, ap);
01001     printf("%s", buffer);
01002     printf("\n");
01003 }
01004 
01005 SERVER_EXPORT void jack_error(const char *fmt, ...)
01006 {
01007     va_list ap;
01008     va_start(ap, fmt);
01009     jack_format_and_log(LOG_LEVEL_INFO, "Jack: ", fmt, ap);
01010     va_end(ap);
01011 }
01012 
01013 SERVER_EXPORT void jack_info(const char *fmt, ...)
01014 {
01015     va_list ap;
01016     va_start(ap, fmt);
01017     jack_format_and_log(LOG_LEVEL_INFO, "Jack: ", fmt, ap);
01018     va_end(ap);
01019 }
01020 
01021 SERVER_EXPORT void jack_log(const char *fmt, ...)
01022 {
01023     va_list ap;
01024     va_start(ap, fmt);
01025     jack_format_and_log(LOG_LEVEL_INFO, "Jack: ", fmt, ap);
01026     va_end(ap);
01027 }
01028 
01029 #else
01030 
01031 // Empty code for now..
01032 
01033 SERVER_EXPORT void jack_error(const char *fmt, ...)
01034 {}
01035 
01036 SERVER_EXPORT void jack_info(const char *fmt, ...)
01037 {}
01038 
01039 SERVER_EXPORT void jack_log(const char *fmt, ...)
01040 {}
01041 
01042 #endif
01043