Jack2  1.9.8
JackNetAPI.cpp
1 /*
2 Copyright (C) 2009-2011 Grame
3 
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as published by
6 the Free Software Foundation; either version 2.1 of the License, or
7 (at your option) any later version.
8 
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
13 
14 You should have received a copy of the GNU Lesser General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 
18 */
19 
20 #include <assert.h>
21 #include <stdarg.h>
22 #include "JackNetInterface.h"
23 #include "JackError.h"
24 #include "JackException.h"
25 #include "JackAudioAdapterInterface.h"
26 
27 #ifdef __cplusplus
28 extern "C"
29 {
30 #endif
31 
32  // NetJack common API
33 
34  #define MASTER_NAME_SIZE 256
35 
36  enum JackNetEncoder {
37 
38  JackFloatEncoder = 0,
39  JackIntEncoder = 1,
40  JackCeltEncoder = 2,
41  JackMaxEncoder = 3
42  };
43 
44  typedef struct {
45 
46  int audio_input;
47  int audio_output;
48  int midi_input;
49  int midi_output;
50  int mtu;
51  int time_out; // in millisecond, -1 means in infinite
52  int encoder; // one of JackNetEncoder
53  int kbps; // KB per second for CELT encoder
54  int latency; // network cycles
55 
56  } jack_slave_t;
57 
58  typedef struct {
59 
60  int audio_input;
61  int audio_output;
62  int midi_input;
63  int midi_output;
64  jack_nframes_t buffer_size;
65  jack_nframes_t sample_rate;
66  char master_name[MASTER_NAME_SIZE];
67 
68  } jack_master_t;
69 
70  // NetJack slave API
71 
72  typedef struct _jack_net_slave jack_net_slave_t;
73 
74  typedef int (* JackNetSlaveProcessCallback) (jack_nframes_t buffer_size,
75  int audio_input,
76  float** audio_input_buffer,
77  int midi_input,
78  void** midi_input_buffer,
79  int audio_output,
80  float** audio_output_buffer,
81  int midi_output,
82  void** midi_output_buffer,
83  void* data);
84 
85  typedef int (*JackNetSlaveBufferSizeCallback) (jack_nframes_t nframes, void *arg);
86  typedef int (*JackNetSlaveSampleRateCallback) (jack_nframes_t nframes, void *arg);
87  typedef void (*JackNetSlaveShutdownCallback) (void* data);
88 
89  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);
90  SERVER_EXPORT int jack_net_slave_close(jack_net_slave_t* net);
91 
92  SERVER_EXPORT int jack_net_slave_activate(jack_net_slave_t* net);
93  SERVER_EXPORT int jack_net_slave_deactivate(jack_net_slave_t* net);
94 
95  SERVER_EXPORT int jack_set_net_slave_process_callback(jack_net_slave_t* net, JackNetSlaveProcessCallback net_callback, void *arg);
96  SERVER_EXPORT int jack_set_net_slave_buffer_size_callback(jack_net_slave_t* net, JackNetSlaveBufferSizeCallback bufsize_callback, void *arg);
97  SERVER_EXPORT int jack_set_net_slave_sample_rate_callback(jack_net_slave_t* net, JackNetSlaveSampleRateCallback samplerate_callback, void *arg);
98  SERVER_EXPORT int jack_set_net_slave_shutdown_callback(jack_net_slave_t* net, JackNetSlaveShutdownCallback shutdown_callback, void *arg);
99 
100  // NetJack master API
101 
102  typedef struct _jack_net_master jack_net_master_t;
103 
104  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);
105  SERVER_EXPORT int jack_net_master_close(jack_net_master_t* net);
106 
107  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);
108  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);
109 
110  // NetJack adapter API
111 
112  typedef struct _jack_adapter jack_adapter_t;
113 
114  SERVER_EXPORT jack_adapter_t* jack_create_adapter(int input, int output,
115  jack_nframes_t host_buffer_size,
116  jack_nframes_t host_sample_rate,
117  jack_nframes_t adapted_buffer_size,
118  jack_nframes_t adapted_sample_rate);
119  SERVER_EXPORT int jack_destroy_adapter(jack_adapter_t* adapter);
120  SERVER_EXPORT void jack_flush_adapter(jack_adapter_t* adapter);
121 
122  SERVER_EXPORT int jack_adapter_push_and_pull(jack_adapter_t* adapter, float** input, float** output, unsigned int frames);
123  SERVER_EXPORT int jack_adapter_pull_and_push(jack_adapter_t* adapter, float** input, float** output, unsigned int frames);
124 
125 #ifdef __cplusplus
126 }
127 #endif
128 
129 namespace Jack
130 {
131 
133 
134  // Data buffers
135  float** fAudioCaptureBuffer;
136  float** fAudioPlaybackBuffer;
137 
138  JackMidiBuffer** fMidiCaptureBuffer;
139  JackMidiBuffer** fMidiPlaybackBuffer;
140 
141  jack_master_t fRequest;
142 
143  JackNetExtMaster(const char* ip,
144  int port,
145  const char* name,
146  jack_master_t* request)
147  {
148  fRunning = true;
149  assert(strlen(ip) < 32);
150  strcpy(fMulticastIP, ip);
151  fSocket.SetPort(port);
152  fRequest.buffer_size = request->buffer_size;
153  fRequest.sample_rate = request->sample_rate;
154  fAudioCaptureBuffer = NULL;
155  fAudioPlaybackBuffer = NULL;
156  fMidiCaptureBuffer = NULL;
157  fMidiPlaybackBuffer = NULL;
158  }
159 
160  virtual ~JackNetExtMaster()
161  {}
162 
163  int Open(jack_slave_t* result)
164  {
165  // Init socket API (win32)
166  if (SocketAPIInit() < 0) {
167  jack_error("Can't init Socket API, exiting...");
168  return -1;
169  }
170 
171  // Request socket
172  if (fSocket.NewSocket() == SOCKET_ERROR) {
173  jack_error("Can't create the network management input socket : %s", StrError(NET_ERROR_CODE));
174  return -1;
175  }
176 
177  // Bind the socket to the local port
178  if (fSocket.Bind() == SOCKET_ERROR) {
179  jack_error("Can't bind the network manager socket : %s", StrError(NET_ERROR_CODE));
180  fSocket.Close();
181  return -1;
182  }
183 
184  // Join multicast group
185  if (fSocket.JoinMCastGroup(fMulticastIP) == SOCKET_ERROR) {
186  jack_error("Can't join multicast group : %s", StrError(NET_ERROR_CODE));
187  }
188 
189  // Local loop
190  if (fSocket.SetLocalLoop() == SOCKET_ERROR) {
191  jack_error("Can't set local loop : %s", StrError(NET_ERROR_CODE));
192  }
193 
194  // Set a timeout on the multicast receive (the thread can now be cancelled)
195  if (fSocket.SetTimeOut(MANAGER_INIT_TIMEOUT) == SOCKET_ERROR) {
196  jack_error("Can't set timeout : %s", StrError(NET_ERROR_CODE));
197  }
198 
199  // Main loop, wait for data, deal with it and wait again
200  int attempt = 0;
201  int rx_bytes = 0;
202 
203  do
204  {
205  session_params_t net_params;
206  rx_bytes = fSocket.CatchHost(&net_params, sizeof(session_params_t), 0);
207  SessionParamsNToH(&net_params, &fParams);
208 
209  if ((rx_bytes == SOCKET_ERROR) && (fSocket.GetError() != NET_NO_DATA)) {
210  jack_error("Error in receive : %s", StrError(NET_ERROR_CODE));
211  if (++attempt == 10) {
212  jack_error("Can't receive on the socket, exiting net manager" );
213  goto error;
214  }
215  }
216 
217  if (rx_bytes == sizeof(session_params_t )) {
218 
219  switch (GetPacketType(&fParams)) {
220 
221  case SLAVE_AVAILABLE:
222  if (MasterInit() == 0) {
223  SessionParamsDisplay(&fParams);
224  fRunning = false;
225  } else {
226  jack_error("Can't init new net master...");
227  goto error;
228  }
229  jack_info("Waiting for a slave...");
230  break;
231 
232  case KILL_MASTER:
233  break;
234 
235  default:
236  break;
237  }
238  }
239  }
240  while (fRunning);
241 
242  // Set result paramaters
243  result->audio_input = fParams.fSendAudioChannels;
244  result->audio_output = fParams.fReturnAudioChannels;
245  result->midi_input = fParams.fSendMidiChannels;
246  result->midi_output = fParams.fReturnMidiChannels;
247  result->mtu = fParams.fMtu;
248  result->latency = fParams.fNetworkLatency;
249  return 0;
250 
251  error:
252  fSocket.Close();
253  return -1;
254  }
255 
256  int MasterInit()
257  {
258  // Check MASTER <==> SLAVE network protocol coherency
259  if (fParams.fProtocolVersion != MASTER_PROTOCOL) {
260  jack_error("Error : slave is running with a different protocol %s", fParams.fName);
261  return -1;
262  }
263 
264  // Settings
265  fSocket.GetName(fParams.fMasterNetName);
266  fParams.fID = 1;
267  fParams.fSampleEncoder = JackFloatEncoder;
268  fParams.fPeriodSize = fRequest.buffer_size;
269  fParams.fSampleRate = fRequest.sample_rate;
270 
271  // Close request socket
272  fSocket.Close();
273 
274  // Network slave init
275  if (!JackNetMasterInterface::Init()) {
276  return -1;
277  }
278 
279  // Set global parameters
280  if (!SetParams()) {
281  return -1;
282  }
283 
284  AllocPorts();
285  return 0;
286  }
287 
288  int Close()
289  {
290  fSocket.Close();
291  FreePorts();
292  return 0;
293  }
294 
295  void AllocPorts()
296  {
297  // Set buffers
298  if (fParams.fSendAudioChannels > 0) {
299  fAudioCaptureBuffer = new float*[fParams.fSendAudioChannels];
300  for (int audio_port_index = 0; audio_port_index < fParams.fSendAudioChannels; audio_port_index++) {
301  fAudioCaptureBuffer[audio_port_index] = new float[fParams.fPeriodSize];
302  fNetAudioCaptureBuffer->SetBuffer(audio_port_index, fAudioCaptureBuffer[audio_port_index]);
303  }
304  }
305 
306  if (fParams.fSendMidiChannels > 0) {
307  fMidiCaptureBuffer = new JackMidiBuffer*[fParams.fSendMidiChannels];
308  for (int midi_port_index = 0; midi_port_index < fParams.fSendMidiChannels; midi_port_index++) {
309  fMidiCaptureBuffer[midi_port_index] = (JackMidiBuffer*)new float[fParams.fPeriodSize];
310  fNetMidiCaptureBuffer->SetBuffer(midi_port_index, fMidiCaptureBuffer[midi_port_index]);
311  }
312  }
313 
314  if (fParams.fReturnAudioChannels > 0) {
315  fAudioPlaybackBuffer = new float*[fParams.fReturnAudioChannels];
316  for (int audio_port_index = 0; audio_port_index < fParams.fReturnAudioChannels; audio_port_index++) {
317  fAudioPlaybackBuffer[audio_port_index] = new float[fParams.fPeriodSize];
318  fNetAudioPlaybackBuffer->SetBuffer(audio_port_index, fAudioPlaybackBuffer[audio_port_index]);
319  }
320  }
321 
322  if (fParams.fReturnMidiChannels > 0) {
323  fMidiPlaybackBuffer = new JackMidiBuffer*[fParams.fReturnMidiChannels];
324  for (int midi_port_index = 0; midi_port_index < fParams.fReturnMidiChannels; midi_port_index++) {
325  fMidiPlaybackBuffer[midi_port_index] = (JackMidiBuffer*)new float[fParams.fPeriodSize];
326  fNetMidiPlaybackBuffer->SetBuffer(midi_port_index, fMidiPlaybackBuffer[midi_port_index]);
327  }
328  }
329  }
330 
331  void FreePorts()
332  {
333  if (fAudioPlaybackBuffer) {
334  for (int audio_port_index = 0; audio_port_index < fParams.fSendAudioChannels; audio_port_index++)
335  delete[] fAudioPlaybackBuffer[audio_port_index];
336  delete[] fAudioPlaybackBuffer;
337  fAudioPlaybackBuffer = NULL;
338  }
339 
340  if (fMidiPlaybackBuffer) {
341  for (int midi_port_index = 0; midi_port_index < fParams.fSendMidiChannels; midi_port_index++)
342  delete[] (fMidiPlaybackBuffer[midi_port_index]);
343  delete[] fMidiPlaybackBuffer;
344  fMidiPlaybackBuffer = NULL;
345  }
346 
347  if (fAudioCaptureBuffer) {
348  for (int audio_port_index = 0; audio_port_index < fParams.fReturnAudioChannels; audio_port_index++)
349  delete[] fAudioCaptureBuffer[audio_port_index];
350  delete[] fAudioCaptureBuffer;
351  fAudioCaptureBuffer = NULL;
352  }
353 
354  if (fMidiCaptureBuffer) {
355  for (int midi_port_index = 0; midi_port_index < fParams.fReturnMidiChannels; midi_port_index++)
356  delete[] fMidiCaptureBuffer[midi_port_index];
357  delete[] fMidiCaptureBuffer;
358  fMidiCaptureBuffer = NULL;
359  }
360  }
361 
362  int Read(int audio_input, float** audio_input_buffer, int midi_input, void** midi_input_buffer)
363  {
364  try {
365  assert(audio_input == fParams.fReturnAudioChannels);
366 
367  for (int audio_port_index = 0; audio_port_index < audio_input; audio_port_index++) {
368  fNetAudioPlaybackBuffer->SetBuffer(audio_port_index, audio_input_buffer[audio_port_index]);
369  }
370 
371  for (int midi_port_index = 0; midi_port_index < midi_input; midi_port_index++) {
372  fNetMidiPlaybackBuffer->SetBuffer(midi_port_index, ((JackMidiBuffer**)midi_input_buffer)[midi_port_index]);
373  }
374 
375  if (SyncRecv() == SOCKET_ERROR) {
376  return 0;
377  }
378 
379  DecodeSyncPacket();
380  return DataRecv();
381 
382  } catch (JackNetException& e) {
383  jack_error("Connection lost.");
384  return -1;
385  }
386  }
387 
388  int Write(int audio_output, float** audio_output_buffer, int midi_output, void** midi_output_buffer)
389  {
390  try {
391  assert(audio_output == fParams.fSendAudioChannels);
392 
393  for (int audio_port_index = 0; audio_port_index < audio_output; audio_port_index++) {
394  fNetAudioCaptureBuffer->SetBuffer(audio_port_index, audio_output_buffer[audio_port_index]);
395  }
396 
397  for (int midi_port_index = 0; midi_port_index < midi_output; midi_port_index++) {
398  fNetMidiCaptureBuffer->SetBuffer(midi_port_index, ((JackMidiBuffer**)midi_output_buffer)[midi_port_index]);
399  }
400 
401  EncodeSyncPacket();
402 
403  if (SyncSend() == SOCKET_ERROR) {
404  return SOCKET_ERROR;
405  }
406 
407  return DataSend();
408 
409  } catch (JackNetException& e) {
410  jack_error("Connection lost.");
411  return -1;
412  }
413  }
414 
415  // Transport
416  void EncodeTransportData()
417  {}
418 
419  void DecodeTransportData()
420  {}
421 
422 };
423 
425 
426  JackThread fThread;
427 
428  JackNetSlaveProcessCallback fProcessCallback;
429  void* fProcessArg;
430 
431  JackNetSlaveShutdownCallback fShutdownCallback;
432  void* fShutdownArg;
433 
434  JackNetSlaveBufferSizeCallback fBufferSizeCallback;
435  void* fBufferSizeArg;
436 
437  JackNetSlaveSampleRateCallback fSampleRateCallback;
438  void* fSampleRateArg;
439 
440  //sample buffers
441  float** fAudioCaptureBuffer;
442  float** fAudioPlaybackBuffer;
443 
444  JackMidiBuffer** fMidiCaptureBuffer;
445  JackMidiBuffer** fMidiPlaybackBuffer;
446 
447  int fConnectTimeOut;
448 
449  JackNetExtSlave(const char* ip,
450  int port,
451  const char* name,
452  jack_slave_t* request)
453  :fThread(this),
454  fProcessCallback(NULL),fProcessArg(NULL),
455  fShutdownCallback(NULL), fShutdownArg(NULL),
456  fBufferSizeCallback(NULL), fBufferSizeArg(NULL),
457  fSampleRateCallback(NULL), fSampleRateArg(NULL),
458  fAudioCaptureBuffer(NULL), fAudioPlaybackBuffer(NULL),
459  fMidiCaptureBuffer(NULL), fMidiPlaybackBuffer(NULL)
460  {
461  char host_name[JACK_CLIENT_NAME_SIZE];
462 
463  // Request parameters
464  assert(strlen(ip) < 32);
465  strcpy(fMulticastIP, ip);
466  fParams.fMtu = request->mtu;
467  fParams.fTransportSync = 0;
468  fParams.fSendAudioChannels = request->audio_input;
469  fParams.fReturnAudioChannels = request->audio_output;
470  fParams.fSendMidiChannels = request->midi_input;
471  fParams.fReturnMidiChannels = request->midi_output;
472  fParams.fNetworkLatency = request->latency;
473  fParams.fSampleEncoder = request->encoder;
474  fParams.fKBps = request->kbps;
475  fParams.fSlaveSyncMode = 1;
476  fConnectTimeOut = request->time_out;
477 
478  // Create name with hostname and client name
479  GetHostName(host_name, JACK_CLIENT_NAME_SIZE);
480  snprintf(fParams.fName, JACK_CLIENT_NAME_SIZE, "%s_%s", host_name, name);
481  fSocket.GetName(fParams.fSlaveNetName);
482 
483  // Set the socket parameters
484  fSocket.SetPort(port);
485  fSocket.SetAddress(fMulticastIP, port);
486  }
487 
488  virtual ~JackNetExtSlave()
489  {}
490 
491  int Open(jack_master_t* result)
492  {
493  if (fParams.fNetworkLatency > NETWORK_MAX_LATENCY) {
494  jack_error("Error : network latency is limited to %d", NETWORK_MAX_LATENCY);
495  return -1;
496  }
497 
498  // Init network connection
499  if (!JackNetSlaveInterface::InitConnection(fConnectTimeOut)) {
500  jack_error("Initing network fails...");
501  return -1;
502  }
503 
504  // Finish connection...
505  if (!JackNetSlaveInterface::InitRendering()) {
506  jack_error("Starting network fails...");
507  return -1;
508  }
509 
510  // Then set global parameters
511  if (!SetParams()) {
512  jack_error("SetParams error...");
513  return -1;
514  }
515 
516  // Set result
517  if (result != NULL) {
518  result->buffer_size = fParams.fPeriodSize;
519  result->sample_rate = fParams.fSampleRate;
520  result->audio_input = fParams.fSendAudioChannels;
521  result->audio_output = fParams.fReturnAudioChannels;
522  result->midi_input = fParams.fSendMidiChannels;
523  result->midi_output = fParams.fReturnMidiChannels;
524  strcpy(result->master_name, fParams.fMasterNetName);
525  }
526 
527  AllocPorts();
528  return 0;
529  }
530 
531  int Restart()
532  {
533  // If shutdown cb is set, then call it
534  if (fShutdownCallback) {
535  fShutdownCallback(fShutdownArg);
536  }
537 
538  // Init network connection
539  if (!JackNetSlaveInterface::InitConnection(fConnectTimeOut)) {
540  jack_error("Initing network fails...");
541  return -1;
542  }
543 
544  // Finish connection...
545  if (!JackNetSlaveInterface::InitRendering()) {
546  jack_error("Starting network fails...");
547  return -1;
548  }
549 
550  // Then set global parameters
551  if (!SetParams()) {
552  jack_error("SetParams error...");
553  return -1;
554  }
555 
556  // We need to notify possibly new buffer size and sample rate (see Execute)
557  if (fBufferSizeCallback) {
558  fBufferSizeCallback(fParams.fPeriodSize, fBufferSizeArg);
559  }
560 
561  if (fSampleRateCallback) {
562  fSampleRateCallback(fParams.fSampleRate, fSampleRateArg);
563  }
564 
565  AllocPorts();
566  return 0;
567  }
568 
569  int Close()
570  {
571  fSocket.Close();
572  FreePorts();
573  return 0;
574  }
575 
576  void AllocPorts()
577  {
578  // Set buffers
579  fAudioCaptureBuffer = new float*[fParams.fSendAudioChannels];
580  for (int audio_port_index = 0; audio_port_index < fParams.fSendAudioChannels; audio_port_index++) {
581  fAudioCaptureBuffer[audio_port_index] = new float[fParams.fPeriodSize];
582  fNetAudioCaptureBuffer->SetBuffer(audio_port_index, fAudioCaptureBuffer[audio_port_index]);
583  }
584 
585  fMidiCaptureBuffer = new JackMidiBuffer*[fParams.fSendMidiChannels];
586  for (int midi_port_index = 0; midi_port_index < fParams.fSendMidiChannels; midi_port_index++) {
587  fMidiCaptureBuffer[midi_port_index] = (JackMidiBuffer*)new float[fParams.fPeriodSize];
588  fNetMidiCaptureBuffer->SetBuffer(midi_port_index, fMidiCaptureBuffer[midi_port_index]);
589  }
590 
591  fAudioPlaybackBuffer = new float*[fParams.fReturnAudioChannels];
592  for (int audio_port_index = 0; audio_port_index < fParams.fReturnAudioChannels; audio_port_index++) {
593  fAudioPlaybackBuffer[audio_port_index] = new float[fParams.fPeriodSize];
594  fNetAudioPlaybackBuffer->SetBuffer(audio_port_index, fAudioPlaybackBuffer[audio_port_index]);
595  }
596 
597  fMidiPlaybackBuffer = new JackMidiBuffer*[fParams.fReturnMidiChannels];
598  for (int midi_port_index = 0; midi_port_index < fParams.fReturnMidiChannels; midi_port_index++) {
599  fMidiPlaybackBuffer[midi_port_index] = (JackMidiBuffer*)new float[fParams.fPeriodSize];
600  fNetMidiPlaybackBuffer->SetBuffer(midi_port_index, fMidiPlaybackBuffer[midi_port_index]);
601  }
602  }
603 
604  void FreePorts()
605  {
606  if (fAudioCaptureBuffer) {
607  for (int audio_port_index = 0; audio_port_index < fParams.fSendAudioChannels; audio_port_index++)
608  delete[] fAudioCaptureBuffer[audio_port_index];
609  delete[] fAudioCaptureBuffer;
610  fAudioCaptureBuffer = NULL;
611  }
612 
613  if (fMidiCaptureBuffer) {
614  for (int midi_port_index = 0; midi_port_index < fParams.fSendMidiChannels; midi_port_index++)
615  delete[] (fMidiCaptureBuffer[midi_port_index]);
616  delete[] fMidiCaptureBuffer;
617  fMidiCaptureBuffer = NULL;
618  }
619 
620  if (fAudioPlaybackBuffer) {
621  for (int audio_port_index = 0; audio_port_index < fParams.fReturnAudioChannels; audio_port_index++)
622  delete[] fAudioPlaybackBuffer[audio_port_index];
623  delete[] fAudioPlaybackBuffer;
624  fAudioPlaybackBuffer = NULL;
625  }
626 
627  if (fMidiPlaybackBuffer) {
628  for (int midi_port_index = 0; midi_port_index < fParams.fReturnMidiChannels; midi_port_index++)
629  delete[] fMidiPlaybackBuffer[midi_port_index];
630  delete[] fMidiPlaybackBuffer;
631  fMidiPlaybackBuffer = NULL;
632  }
633  }
634 
635  // Transport
636  void EncodeTransportData()
637  {}
638 
639  void DecodeTransportData()
640  {}
641 
642  bool Init()
643  {
644  // Will do "something" on OSX only...
645  UInt64 period, constraint;
646  period = constraint = UInt64(1000000000.f * (float(fParams.fPeriodSize) / float(fParams.fSampleRate)));
647  UInt64 computation = JackTools::ComputationMicroSec(fParams.fPeriodSize) * 1000;
648  fThread.SetParams(period, computation, constraint);
649 
650  return (fThread.AcquireSelfRealTime(80) == 0); // TODO: get a value from the server
651  }
652 
653  bool Execute()
654  {
655  try {
656  // Keep running even in case of error
657  while (fThread.GetStatus() == JackThread::kRunning) {
658  if (Process() == SOCKET_ERROR) {
659  return false;
660  }
661  }
662  return false;
663  } catch (JackNetException& e) {
664 
665  // Otherwise just restart...
666  e.PrintMessage();
667  fThread.DropRealTime();
668  fThread.SetStatus(JackThread::kIniting);
669  FreePorts();
670  if (Restart() == 0 && Init()) {
671  fThread.SetStatus(JackThread::kRunning);
672  return true;
673  } else {
674  return false;
675  }
676  }
677  }
678 
679  int Read()
680  {
681  //receive sync (launch the cycle)
682  if (SyncRecv() == SOCKET_ERROR) {
683  return SOCKET_ERROR;
684  }
685 
686  DecodeSyncPacket();
687  return DataRecv();
688  }
689 
690  int Write()
691  {
692  EncodeSyncPacket();
693 
694  if (SyncSend() == SOCKET_ERROR) {
695  return SOCKET_ERROR;
696  }
697 
698  return DataSend();
699  }
700 
701  int Process()
702  {
703  // Read data from the network, throw JackNetException in case of network error...
704  if (Read() == SOCKET_ERROR) {
705  return SOCKET_ERROR;
706  }
707 
708  fProcessCallback(fParams.fPeriodSize,
709  fParams.fSendAudioChannels,
710  fAudioCaptureBuffer,
711  fParams.fSendMidiChannels,
712  (void**)fMidiCaptureBuffer,
713  fParams.fReturnAudioChannels,
714  fAudioPlaybackBuffer,
715  fParams.fReturnMidiChannels,
716  (void**)fMidiPlaybackBuffer,
717  fProcessArg);
718 
719  // Then write data to network, throw JackNetException in case of network error...
720  if (Write() == SOCKET_ERROR) {
721  return SOCKET_ERROR;
722  }
723 
724  return 0;
725  }
726 
727  int Start()
728  {
729  return (fProcessCallback == 0) ? -1 : fThread.StartSync();
730  }
731 
732  int Stop()
733  {
734  return (fProcessCallback == 0) ? -1 : fThread.Kill();
735  }
736 
737  // Callback
738  int SetProcessCallback(JackNetSlaveProcessCallback net_callback, void *arg)
739  {
740  if (fThread.GetStatus() == JackThread::kRunning) {
741  return -1;
742  } else {
743  fProcessCallback = net_callback;
744  fProcessArg = arg;
745  return 0;
746  }
747  }
748 
749  int SetShutdownCallback(JackNetSlaveShutdownCallback shutdown_callback, void *arg)
750  {
751  if (fThread.GetStatus() == JackThread::kRunning) {
752  return -1;
753  } else {
754  fShutdownCallback = shutdown_callback;
755  fShutdownArg = arg;
756  return 0;
757  }
758  }
759 
760  int SetBufferSizeCallback(JackNetSlaveBufferSizeCallback bufsize_callback, void *arg)
761  {
762  if (fThread.GetStatus() == JackThread::kRunning) {
763  return -1;
764  } else {
765  fBufferSizeCallback = bufsize_callback;
766  fBufferSizeArg = arg;
767  return 0;
768  }
769  }
770 
771  int SetSampleRateCallback(JackNetSlaveSampleRateCallback samplerate_callback, void *arg)
772  {
773  if (fThread.GetStatus() == JackThread::kRunning) {
774  return -1;
775  } else {
776  fSampleRateCallback = samplerate_callback;
777  fSampleRateArg = arg;
778  return 0;
779  }
780  }
781 
782 };
783 
785 
786  JackNetAdapter(int input, int output,
787  jack_nframes_t host_buffer_size,
788  jack_nframes_t host_sample_rate,
789  jack_nframes_t adapted_buffer_size,
790  jack_nframes_t adapted_sample_rate)
791  :JackAudioAdapterInterface(host_buffer_size, host_sample_rate, adapted_buffer_size, adapted_sample_rate)
792  {
793  fCaptureChannels = input;
794  fPlaybackChannels = output;
795  Create();
796  }
797 
798  void Create()
799  {
800  //ringbuffers
801 
802  if (fCaptureChannels > 0) {
803  fCaptureRingBuffer = new JackResampler*[fCaptureChannels];
804  }
805  if (fPlaybackChannels > 0) {
806  fPlaybackRingBuffer = new JackResampler*[fPlaybackChannels];
807  }
808 
809  if (fAdaptative) {
810  AdaptRingBufferSize();
811  jack_info("Ringbuffer automatic adaptative mode size = %d frames", fRingbufferCurSize);
812  } else {
813  if (fRingbufferCurSize > DEFAULT_RB_SIZE) {
814  fRingbufferCurSize = DEFAULT_RB_SIZE;
815  }
816  jack_info("Fixed ringbuffer size = %d frames", fRingbufferCurSize);
817  }
818 
819  for (int i = 0; i < fCaptureChannels; i++ ) {
820  fCaptureRingBuffer[i] = new JackResampler();
821  fCaptureRingBuffer[i]->Reset(fRingbufferCurSize);
822  }
823  for (int i = 0; i < fPlaybackChannels; i++ ) {
824  fPlaybackRingBuffer[i] = new JackResampler();
825  fPlaybackRingBuffer[i]->Reset(fRingbufferCurSize);
826  }
827 
828  if (fCaptureChannels > 0) {
829  jack_log("ReadSpace = %ld", fCaptureRingBuffer[0]->ReadSpace());
830  }
831  if (fPlaybackChannels > 0) {
832  jack_log("WriteSpace = %ld", fPlaybackRingBuffer[0]->WriteSpace());
833  }
834  }
835 
836  virtual ~JackNetAdapter()
837  {
838  Destroy();
839  }
840 
841  void Flush()
842  {
843  for (int i = 0; i < fCaptureChannels; i++ ) {
844  fCaptureRingBuffer[i]->Reset(fRingbufferCurSize);
845  }
846  for (int i = 0; i < fPlaybackChannels; i++ ) {
847  fPlaybackRingBuffer[i]->Reset(fRingbufferCurSize);
848  }
849  }
850 
851 };
852 
853 
854 } // end of namespace
855 
856 using namespace Jack;
857 
858 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)
859 {
860  JackNetExtSlave* slave = new JackNetExtSlave(ip, port, name, request);
861  if (slave->Open(result) == 0) {
862  return (jack_net_slave_t*)slave;
863  } else {
864  delete slave;
865  return NULL;
866  }
867 }
868 
869 SERVER_EXPORT int jack_net_slave_close(jack_net_slave_t* net)
870 {
871  JackNetExtSlave* slave = (JackNetExtSlave*)net;
872  slave->Close();
873  delete slave;
874  return 0;
875 }
876 
877 SERVER_EXPORT int jack_set_net_slave_process_callback(jack_net_slave_t* net, JackNetSlaveProcessCallback net_callback, void *arg)
878 {
879  JackNetExtSlave* slave = (JackNetExtSlave*)net;
880  return slave->SetProcessCallback(net_callback, arg);
881 }
882 
883 SERVER_EXPORT int jack_net_slave_activate(jack_net_slave_t* net)
884 {
885  JackNetExtSlave* slave = (JackNetExtSlave*)net;
886  return slave->Start();
887 }
888 
889 SERVER_EXPORT int jack_net_slave_deactivate(jack_net_slave_t* net)
890 {
891  JackNetExtSlave* slave = (JackNetExtSlave*)net;
892  return slave->Stop();
893 }
894 
895 SERVER_EXPORT int jack_set_net_slave_buffer_size_callback(jack_net_slave_t *net, JackNetSlaveBufferSizeCallback bufsize_callback, void *arg)
896 {
897  JackNetExtSlave* slave = (JackNetExtSlave*)net;
898  return slave->SetBufferSizeCallback(bufsize_callback, arg);
899 }
900 
901 SERVER_EXPORT int jack_set_net_slave_sample_rate_callback(jack_net_slave_t *net, JackNetSlaveSampleRateCallback samplerate_callback, void *arg)
902 {
903  JackNetExtSlave* slave = (JackNetExtSlave*)net;
904  return slave->SetSampleRateCallback(samplerate_callback, arg);
905 }
906 
907 SERVER_EXPORT int jack_set_net_slave_shutdown_callback(jack_net_slave_t *net, JackNetSlaveShutdownCallback shutdown_callback, void *arg)
908 {
909  JackNetExtSlave* slave = (JackNetExtSlave*)net;
910  return slave->SetShutdownCallback(shutdown_callback, arg);
911 }
912 
913 // Master API
914 
915 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)
916 {
917  JackNetExtMaster* master = new JackNetExtMaster(ip, port, name, request);
918  if (master->Open(result) == 0) {
919  return (jack_net_master_t*)master;
920  } else {
921  delete master;
922  return NULL;
923  }
924 }
925 
926 SERVER_EXPORT int jack_net_master_close(jack_net_master_t* net)
927 {
928  JackNetExtMaster* master = (JackNetExtMaster*)net;
929  master->Close();
930  delete master;
931  return 0;
932 }
933 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)
934 {
935  JackNetExtMaster* master = (JackNetExtMaster*)net;
936  return master->Read(audio_input, audio_input_buffer, midi_input, midi_input_buffer);
937 }
938 
939 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)
940 {
941  JackNetExtMaster* master = (JackNetExtMaster*)net;
942  return master->Write(audio_output, audio_output_buffer, midi_output, midi_output_buffer);
943 }
944 
945 // Adapter API
946 
947 SERVER_EXPORT jack_adapter_t* jack_create_adapter(int input, int output,
948  jack_nframes_t host_buffer_size,
949  jack_nframes_t host_sample_rate,
950  jack_nframes_t adapted_buffer_size,
951  jack_nframes_t adapted_sample_rate)
952 {
953  try {
954  return (jack_adapter_t*)new JackNetAdapter(input, output, host_buffer_size, host_sample_rate, adapted_buffer_size, adapted_sample_rate);
955  } catch (...) {
956  return NULL;
957  }
958 }
959 
960 SERVER_EXPORT int jack_destroy_adapter(jack_adapter_t* adapter)
961 {
962  delete((JackNetAdapter*)adapter);
963  return 0;
964 }
965 
966 SERVER_EXPORT void jack_flush_adapter(jack_adapter_t* adapter)
967 {
968  JackNetAdapter* slave = (JackNetAdapter*)adapter;
969  slave->Flush();
970 }
971 
972 SERVER_EXPORT int jack_adapter_push_and_pull(jack_adapter_t* adapter, float** input, float** output, unsigned int frames)
973 {
974  JackNetAdapter* slave = (JackNetAdapter*)adapter;
975  return slave->PushAndPull(input, output, frames);
976 }
977 
978 SERVER_EXPORT int jack_adapter_pull_and_push(jack_adapter_t* adapter, float** input, float** output, unsigned int frames)
979 {
980  JackNetAdapter* slave = (JackNetAdapter*)adapter;
981  return slave->PullAndPush(input, output, frames);
982 }
983 
984 
985 //#ifdef MY_TARGET_OS_IPHONE
986 #if 1
987 
988 static void jack_format_and_log(int level, const char *prefix, const char *fmt, va_list ap)
989 {
990  char buffer[300];
991  size_t len;
992 
993  if (prefix != NULL) {
994  len = strlen(prefix);
995  memcpy(buffer, prefix, len);
996  } else {
997  len = 0;
998  }
999 
1000  vsnprintf(buffer + len, sizeof(buffer) - len, fmt, ap);
1001  printf("%s", buffer);
1002  printf("\n");
1003 }
1004 
1005 SERVER_EXPORT void jack_error(const char *fmt, ...)
1006 {
1007  va_list ap;
1008  va_start(ap, fmt);
1009  jack_format_and_log(LOG_LEVEL_INFO, "Jack: ", fmt, ap);
1010  va_end(ap);
1011 }
1012 
1013 SERVER_EXPORT void jack_info(const char *fmt, ...)
1014 {
1015  va_list ap;
1016  va_start(ap, fmt);
1017  jack_format_and_log(LOG_LEVEL_INFO, "Jack: ", fmt, ap);
1018  va_end(ap);
1019 }
1020 
1021 SERVER_EXPORT void jack_log(const char *fmt, ...)
1022 {
1023  va_list ap;
1024  va_start(ap, fmt);
1025  jack_format_and_log(LOG_LEVEL_INFO, "Jack: ", fmt, ap);
1026  va_end(ap);
1027 }
1028 
1029 #else
1030 
1031 // Empty code for now..
1032 
1033 SERVER_EXPORT void jack_error(const char *fmt, ...)
1034 {}
1035 
1036 SERVER_EXPORT void jack_info(const char *fmt, ...)
1037 {}
1038 
1039 SERVER_EXPORT void jack_log(const char *fmt, ...)
1040 {}
1041 
1042 #endif
1043