Jack2
1.9.10
|
00001 /* 00002 Copyright (C) 2009-2013 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 00023 #include "JackNetInterface.h" 00024 #include "JackAudioAdapterInterface.h" 00025 00026 #ifdef __cplusplus 00027 extern "C" 00028 { 00029 #endif 00030 00031 // NetJack common API 00032 00033 #define MASTER_NAME_SIZE 256 00034 00035 enum JackNetEncoder { 00036 00037 JackFloatEncoder = 0, 00038 JackIntEncoder = 1, 00039 JackCeltEncoder = 2, 00040 JackOpusEncoder = 3 00041 }; 00042 00043 typedef struct { 00044 00045 int audio_input; 00046 int audio_output; 00047 int midi_input; 00048 int midi_output; 00049 int mtu; 00050 int time_out; // in millisecond, -1 means in infinite 00051 int encoder; // one of JackNetEncoder 00052 int kbps; // KB per second for CELT encoder 00053 int latency; // network cycles 00054 00055 } jack_slave_t; 00056 00057 typedef struct { 00058 00059 int audio_input; 00060 int audio_output; 00061 int midi_input; 00062 int midi_output; 00063 jack_nframes_t buffer_size; 00064 jack_nframes_t sample_rate; 00065 char master_name[MASTER_NAME_SIZE]; 00066 int time_out; 00067 int partial_cycle; 00068 00069 } jack_master_t; 00070 00071 // NetJack slave API 00072 00073 typedef struct _jack_net_slave jack_net_slave_t; 00074 00075 typedef int (* JackNetSlaveProcessCallback) (jack_nframes_t buffer_size, 00076 int audio_input, 00077 float** audio_input_buffer, 00078 int midi_input, 00079 void** midi_input_buffer, 00080 int audio_output, 00081 float** audio_output_buffer, 00082 int midi_output, 00083 void** midi_output_buffer, 00084 void* data); 00085 00086 typedef int (*JackNetSlaveBufferSizeCallback) (jack_nframes_t nframes, void *arg); 00087 typedef int (*JackNetSlaveSampleRateCallback) (jack_nframes_t nframes, void *arg); 00088 typedef void (*JackNetSlaveShutdownCallback) (void* arg); 00089 typedef int (*JackNetSlaveRestartCallback) (void* arg); 00090 typedef void (*JackNetSlaveErrorCallback) (int error_code, void* arg); 00091 00092 LIB_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); 00093 LIB_EXPORT int jack_net_slave_close(jack_net_slave_t* net); 00094 00095 LIB_EXPORT int jack_net_slave_activate(jack_net_slave_t* net); 00096 LIB_EXPORT int jack_net_slave_deactivate(jack_net_slave_t* net); 00097 LIB_EXPORT int jack_net_slave_is_active(jack_net_slave_t* net); 00098 00099 LIB_EXPORT int jack_set_net_slave_process_callback(jack_net_slave_t* net, JackNetSlaveProcessCallback net_callback, void *arg); 00100 LIB_EXPORT int jack_set_net_slave_buffer_size_callback(jack_net_slave_t* net, JackNetSlaveBufferSizeCallback bufsize_callback, void *arg); 00101 LIB_EXPORT int jack_set_net_slave_sample_rate_callback(jack_net_slave_t* net, JackNetSlaveSampleRateCallback samplerate_callback, void *arg); 00102 LIB_EXPORT int jack_set_net_slave_shutdown_callback(jack_net_slave_t* net, JackNetSlaveShutdownCallback shutdown_callback, void *arg); 00103 LIB_EXPORT int jack_set_net_slave_restart_callback(jack_net_slave_t* net, JackNetSlaveRestartCallback restart_callback, void *arg); 00104 LIB_EXPORT int jack_set_net_slave_error_callback(jack_net_slave_t* net, JackNetSlaveErrorCallback error_callback, void *arg); 00105 00106 // NetJack master API 00107 00108 typedef struct _jack_net_master jack_net_master_t; 00109 00110 LIB_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); 00111 LIB_EXPORT int jack_net_master_close(jack_net_master_t* net); 00112 00113 LIB_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); 00114 LIB_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); 00115 00116 LIB_EXPORT int jack_net_master_recv_slice(jack_net_master_t* net, int audio_input, float** audio_input_buffer, int midi_input, void** midi_input_buffer, int frames); 00117 LIB_EXPORT int jack_net_master_send_slice(jack_net_master_t* net, int audio_output, float** audio_output_buffer, int midi_output, void** midi_output_buffer, int frames); 00118 00119 // NetJack adapter API 00120 00121 typedef struct _jack_adapter jack_adapter_t; 00122 00123 LIB_EXPORT jack_adapter_t* jack_create_adapter(int input, int output, 00124 jack_nframes_t host_buffer_size, 00125 jack_nframes_t host_sample_rate, 00126 jack_nframes_t adapted_buffer_size, 00127 jack_nframes_t adapted_sample_rate); 00128 LIB_EXPORT int jack_destroy_adapter(jack_adapter_t* adapter); 00129 LIB_EXPORT void jack_flush_adapter(jack_adapter_t* adapter); 00130 00131 LIB_EXPORT int jack_adapter_push_and_pull(jack_adapter_t* adapter, float** input, float** output, unsigned int frames); 00132 LIB_EXPORT int jack_adapter_pull_and_push(jack_adapter_t* adapter, float** input, float** output, unsigned int frames); 00133 00134 #define LOG_LEVEL_INFO 1 00135 #define LOG_LEVEL_ERROR 2 00136 00137 LIB_EXPORT void jack_error(const char *fmt, ...); 00138 LIB_EXPORT void jack_info(const char *fmt, ...); 00139 LIB_EXPORT void jack_log(const char *fmt, ...); 00140 00141 #ifdef __cplusplus 00142 } 00143 #endif 00144 00145 namespace Jack 00146 { 00147 00148 struct JackNetExtMaster : public JackNetMasterInterface { 00149 00150 jack_master_t fRequest; 00151 00152 JackRingBuffer** fRingBuffer; 00153 00154 JackNetExtMaster(const char* ip, 00155 int port, 00156 const char* name, 00157 jack_master_t* request) 00158 { 00159 fRunning = true; 00160 assert(strlen(ip) < 32); 00161 strcpy(fMulticastIP, ip); 00162 fSocket.SetPort(port); 00163 fRequest.buffer_size = request->buffer_size; 00164 fRequest.sample_rate = request->sample_rate; 00165 fRequest.audio_input = request->audio_input; 00166 fRequest.audio_output = request->audio_output; 00167 fRequest.time_out = request->time_out; 00168 fRequest.partial_cycle = request->partial_cycle; 00169 fRingBuffer = NULL; 00170 } 00171 00172 virtual ~JackNetExtMaster() 00173 { 00174 if (fRingBuffer) { 00175 for (int i = 0; i < fParams.fReturnAudioChannels; i++) { 00176 delete fRingBuffer[i]; 00177 } 00178 delete [] fRingBuffer; 00179 } 00180 } 00181 00182 int Open(jack_slave_t* result) 00183 { 00184 // Check buffer_size 00185 if (fRequest.buffer_size == 0) { 00186 jack_error("Incorrect buffer_size..."); 00187 return -1; 00188 } 00189 // Check sample_rate 00190 if (fRequest.sample_rate == 0) { 00191 jack_error("Incorrect sample_rate..."); 00192 return -1; 00193 } 00194 00195 // Init socket API (win32) 00196 if (SocketAPIInit() < 0) { 00197 jack_error("Can't init Socket API, exiting..."); 00198 return -1; 00199 } 00200 00201 // Request socket 00202 if (fSocket.NewSocket() == SOCKET_ERROR) { 00203 jack_error("Can't create the network management input socket : %s", StrError(NET_ERROR_CODE)); 00204 return -1; 00205 } 00206 00207 // Bind the socket to the local port 00208 if (fSocket.Bind() == SOCKET_ERROR) { 00209 jack_error("Can't bind the network manager socket : %s", StrError(NET_ERROR_CODE)); 00210 fSocket.Close(); 00211 return -1; 00212 } 00213 00214 // Join multicast group 00215 if (fSocket.JoinMCastGroup(fMulticastIP) == SOCKET_ERROR) { 00216 jack_error("Can't join multicast group : %s", StrError(NET_ERROR_CODE)); 00217 } 00218 00219 // Local loop 00220 if (fSocket.SetLocalLoop() == SOCKET_ERROR) { 00221 jack_error("Can't set local loop : %s", StrError(NET_ERROR_CODE)); 00222 } 00223 00224 // Set a timeout on the multicast receive (the thread can now be cancelled) 00225 if (fSocket.SetTimeOut(MANAGER_INIT_TIMEOUT) == SOCKET_ERROR) { 00226 jack_error("Can't set timeout : %s", StrError(NET_ERROR_CODE)); 00227 } 00228 00229 // Main loop, wait for data, deal with it and wait again 00230 int attempt = 0; 00231 int rx_bytes = 0; 00232 int try_count = (fRequest.time_out > 0) ? int((1000000.f * float(fRequest.time_out)) / float(MANAGER_INIT_TIMEOUT)) : INT_MAX; 00233 00234 do 00235 { 00236 session_params_t net_params; 00237 rx_bytes = fSocket.CatchHost(&net_params, sizeof(session_params_t), 0); 00238 SessionParamsNToH(&net_params, &fParams); 00239 00240 if ((rx_bytes == SOCKET_ERROR) && (fSocket.GetError() != NET_NO_DATA)) { 00241 jack_error("Error in receive : %s", StrError(NET_ERROR_CODE)); 00242 if (++attempt == 10) { 00243 jack_error("Can't receive on the socket, exiting net manager" ); 00244 goto error; 00245 } 00246 } 00247 00248 if (rx_bytes == sizeof(session_params_t)) { 00249 switch (GetPacketType(&fParams)) { 00250 00251 case SLAVE_AVAILABLE: 00252 if (InitMaster(result) == 0) { 00253 SessionParamsDisplay(&fParams); 00254 fRunning = false; 00255 } else { 00256 jack_error("Can't init new net master..."); 00257 goto error; 00258 } 00259 jack_info("Waiting for a slave..."); 00260 break; 00261 00262 case KILL_MASTER: 00263 break; 00264 00265 default: 00266 break; 00267 } 00268 } 00269 } 00270 while (fRunning && (--try_count > 0)); 00271 00272 if (try_count == 0) { 00273 jack_error("Time out error in connect"); 00274 return -1; 00275 } 00276 00277 // Set result parameters 00278 result->audio_input = fParams.fSendAudioChannels; 00279 result->audio_output = fParams.fReturnAudioChannels; 00280 result->midi_input = fParams.fSendMidiChannels; 00281 result->midi_output = fParams.fReturnMidiChannels; 00282 result->mtu = fParams.fMtu; 00283 result->latency = fParams.fNetworkLatency; 00284 00285 // Use ringbuffer in case of partial cycle and latency > 0 00286 if (fRequest.partial_cycle && result->latency > 0) { 00287 fRingBuffer = new JackRingBuffer*[fParams.fReturnAudioChannels]; 00288 for (int i = 0; i < fParams.fReturnAudioChannels; i++) { 00289 fRingBuffer[i] = new JackRingBuffer(fRequest.buffer_size * result->latency * 2); 00290 } 00291 } 00292 return 0; 00293 00294 error: 00295 fSocket.Close(); 00296 return -1; 00297 } 00298 00299 int InitMaster(jack_slave_t* result) 00300 { 00301 // Check MASTER <==> SLAVE network protocol coherency 00302 if (fParams.fProtocolVersion != NETWORK_PROTOCOL) { 00303 jack_error("Error : slave '%s' is running with a different protocol %d != %d", fParams.fName, fParams.fProtocolVersion, NETWORK_PROTOCOL); 00304 return -1; 00305 } 00306 00307 // Settings 00308 fSocket.GetName(fParams.fMasterNetName); 00309 fParams.fID = 1; 00310 fParams.fPeriodSize = fRequest.buffer_size; 00311 fParams.fSampleRate = fRequest.sample_rate; 00312 00313 if (fRequest.audio_input == -1) { 00314 if (fParams.fSendAudioChannels == -1) { 00315 jack_error("Error : master and slave use -1 for wanted inputs..."); 00316 return -1; 00317 } else { 00318 result->audio_input = fParams.fSendAudioChannels; 00319 jack_info("Takes slave %d inputs", fParams.fSendAudioChannels); 00320 } 00321 } else if (fParams.fSendAudioChannels == -1) { 00322 fParams.fSendAudioChannels = fRequest.audio_input; 00323 jack_info("Takes master %d inputs", fRequest.audio_input); 00324 } else if (fParams.fSendAudioChannels != fRequest.audio_input) { 00325 jack_error("Error : master wants %d inputs and slave wants %d inputs...", fRequest.audio_input, fParams.fSendAudioChannels); 00326 return -1; 00327 } 00328 00329 if (fRequest.audio_output == -1) { 00330 if (fParams.fReturnAudioChannels == -1) { 00331 jack_error("Error : master and slave use -1 for wanted outputs..."); 00332 return -1; 00333 } else { 00334 result->audio_output = fParams.fReturnAudioChannels; 00335 jack_info("Takes slave %d outputs", fParams.fReturnAudioChannels); 00336 } 00337 } else if (fParams.fReturnAudioChannels == -1) { 00338 fParams.fReturnAudioChannels = fRequest.audio_output; 00339 jack_info("Takes master %d outputs", fRequest.audio_output); 00340 } else if (fParams.fReturnAudioChannels != fRequest.audio_output) { 00341 jack_error("Error : master wants %d outputs and slave wants %d outputs...", fRequest.audio_output, fParams.fReturnAudioChannels); 00342 return -1; 00343 } 00344 00345 // Close request socket 00346 fSocket.Close(); 00347 00349 if (!JackNetMasterInterface::Init()) { 00350 return -1; 00351 } 00352 00353 // Set global parameters 00354 if (!SetParams()) { 00355 return -1; 00356 } 00357 00358 return 0; 00359 } 00360 00361 int Close() 00362 { 00363 fSocket.Close(); 00364 return 0; 00365 } 00366 00367 void UseRingBuffer(int audio_input, float** audio_input_buffer, int write, int read) 00368 { 00369 // Possibly use ringbuffer... 00370 if (fRingBuffer) { 00371 for (int i = 0; i < audio_input; i++) { 00372 fRingBuffer[i]->Write(audio_input_buffer[i], write); 00373 fRingBuffer[i]->Read(audio_input_buffer[i], read); 00374 } 00375 } 00376 } 00377 00378 int Read(int audio_input, float** audio_input_buffer, int midi_input, void** midi_input_buffer, int frames) 00379 { 00380 try { 00381 00382 // frames = -1 means : entire buffer 00383 if (frames < 0) frames = fParams.fPeriodSize; 00384 00385 int read_frames = 0; 00386 assert(audio_input == fParams.fReturnAudioChannels); 00387 00388 for (int audio_port_index = 0; audio_port_index < audio_input; audio_port_index++) { 00389 fNetAudioPlaybackBuffer->SetBuffer(audio_port_index, audio_input_buffer[audio_port_index]); 00390 } 00391 00392 for (int midi_port_index = 0; midi_port_index < midi_input; midi_port_index++) { 00393 fNetMidiPlaybackBuffer->SetBuffer(midi_port_index, ((JackMidiBuffer**)midi_input_buffer)[midi_port_index]); 00394 } 00395 00396 int res1 = SyncRecv(); 00397 switch (res1) { 00398 00399 case NET_SYNCHING: 00400 // Data will not be received, so cleanup buffers... 00401 for (int audio_port_index = 0; audio_port_index < audio_input; audio_port_index++) { 00402 memset(audio_input_buffer[audio_port_index], 0, sizeof(float) * fParams.fPeriodSize); 00403 } 00404 UseRingBuffer(audio_input, audio_input_buffer, fParams.fPeriodSize, frames); 00405 return res1; 00406 00407 case SOCKET_ERROR: 00408 return res1; 00409 00410 case SYNC_PACKET_ERROR: 00411 // since sync packet is incorrect, don't decode it and continue with data 00412 break; 00413 00414 default: 00415 // decode sync 00416 DecodeSyncPacket(read_frames); 00417 break; 00418 } 00419 00420 int res2 = DataRecv(); 00421 UseRingBuffer(audio_input, audio_input_buffer, read_frames, frames); 00422 return res2; 00423 00424 } catch (JackNetException& e) { 00425 jack_error(e.what()); 00426 return -1; 00427 } 00428 } 00429 00430 int Write(int audio_output, float** audio_output_buffer, int midi_output, void** midi_output_buffer, int frames) 00431 { 00432 try { 00433 00434 // frames = -1 means : entire buffer 00435 if (frames < 0) frames = fParams.fPeriodSize; 00436 00437 assert(audio_output == fParams.fSendAudioChannels); 00438 00439 for (int audio_port_index = 0; audio_port_index < audio_output; audio_port_index++) { 00440 fNetAudioCaptureBuffer->SetBuffer(audio_port_index, audio_output_buffer[audio_port_index]); 00441 } 00442 00443 for (int midi_port_index = 0; midi_port_index < midi_output; midi_port_index++) { 00444 fNetMidiCaptureBuffer->SetBuffer(midi_port_index, ((JackMidiBuffer**)midi_output_buffer)[midi_port_index]); 00445 } 00446 00447 EncodeSyncPacket(frames); 00448 00449 // send sync 00450 if (SyncSend() == SOCKET_ERROR) { 00451 return SOCKET_ERROR; 00452 } 00453 00454 // send data 00455 if (DataSend() == SOCKET_ERROR) { 00456 return SOCKET_ERROR; 00457 } 00458 return 0; 00459 00460 } catch (JackNetException& e) { 00461 jack_error(e.what()); 00462 return -1; 00463 } 00464 } 00465 00466 // Transport 00467 void EncodeTransportData() 00468 {} 00469 00470 void DecodeTransportData() 00471 {} 00472 00473 }; 00474 00475 struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterface { 00476 00477 // Data buffers 00478 float** fAudioCaptureBuffer; 00479 float** fAudioPlaybackBuffer; 00480 00481 JackMidiBuffer** fMidiCaptureBuffer; 00482 JackMidiBuffer** fMidiPlaybackBuffer; 00483 00484 JackThread fThread; 00485 00486 JackNetSlaveProcessCallback fProcessCallback; 00487 void* fProcessArg; 00488 00489 JackNetSlaveShutdownCallback fShutdownCallback; 00490 void* fShutdownArg; 00491 00492 JackNetSlaveRestartCallback fRestartCallback; 00493 void* fRestartArg; 00494 00495 JackNetSlaveErrorCallback fErrorCallback; 00496 void* fErrorArg; 00497 00498 JackNetSlaveBufferSizeCallback fBufferSizeCallback; 00499 void* fBufferSizeArg; 00500 00501 JackNetSlaveSampleRateCallback fSampleRateCallback; 00502 void* fSampleRateArg; 00503 00504 int fConnectTimeOut; 00505 int fFrames; 00506 00507 JackNetExtSlave(const char* ip, 00508 int port, 00509 const char* name, 00510 jack_slave_t* request) 00511 :fThread(this), 00512 fProcessCallback(NULL),fProcessArg(NULL), 00513 fShutdownCallback(NULL), fShutdownArg(NULL), 00514 fRestartCallback(NULL), fRestartArg(NULL), 00515 fErrorCallback(NULL), fErrorArg(NULL), 00516 fBufferSizeCallback(NULL), fBufferSizeArg(NULL), 00517 fSampleRateCallback(NULL), fSampleRateArg(NULL) 00518 { 00519 char host_name[JACK_CLIENT_NAME_SIZE]; 00520 00521 // Request parameters 00522 assert(strlen(ip) < 32); 00523 strcpy(fMulticastIP, ip); 00524 fParams.fMtu = request->mtu; 00525 fParams.fTransportSync = 0; 00526 fParams.fSendAudioChannels = request->audio_input; 00527 fParams.fReturnAudioChannels = request->audio_output; 00528 fParams.fSendMidiChannels = request->midi_input; 00529 fParams.fReturnMidiChannels = request->midi_output; 00530 fParams.fNetworkLatency = request->latency; 00531 fParams.fSampleEncoder = request->encoder; 00532 fParams.fKBps = request->kbps; 00533 fParams.fSlaveSyncMode = 1; 00534 fConnectTimeOut = request->time_out; 00535 00536 // Create name with hostname and client name 00537 GetHostName(host_name, JACK_CLIENT_NAME_SIZE); 00538 snprintf(fParams.fName, JACK_CLIENT_NAME_SIZE, "%s_%s", host_name, name); 00539 fSocket.GetName(fParams.fSlaveNetName); 00540 00541 // Set the socket parameters 00542 fSocket.SetPort(port); 00543 fSocket.SetAddress(fMulticastIP, port); 00544 00545 fAudioCaptureBuffer = NULL; 00546 fAudioPlaybackBuffer = NULL; 00547 fMidiCaptureBuffer = NULL; 00548 fMidiPlaybackBuffer = NULL; 00549 } 00550 00551 virtual ~JackNetExtSlave() 00552 {} 00553 00554 void AllocPorts() 00555 { 00556 // Set buffers 00557 if (fParams.fSendAudioChannels > 0) { 00558 fAudioCaptureBuffer = new float*[fParams.fSendAudioChannels]; 00559 for (int audio_port_index = 0; audio_port_index < fParams.fSendAudioChannels; audio_port_index++) { 00560 fAudioCaptureBuffer[audio_port_index] = new float[fParams.fPeriodSize]; 00561 memset(fAudioCaptureBuffer[audio_port_index], 0, sizeof(float) * fParams.fPeriodSize); 00562 fNetAudioCaptureBuffer->SetBuffer(audio_port_index, fAudioCaptureBuffer[audio_port_index]); 00563 } 00564 } 00565 00566 if (fParams.fSendMidiChannels > 0) { 00567 fMidiCaptureBuffer = new JackMidiBuffer*[fParams.fSendMidiChannels]; 00568 for (int midi_port_index = 0; midi_port_index < fParams.fSendMidiChannels; midi_port_index++) { 00569 fMidiCaptureBuffer[midi_port_index] = (JackMidiBuffer*)new float[fParams.fPeriodSize]; 00570 memset(fMidiCaptureBuffer[midi_port_index], 0, sizeof(float) * fParams.fPeriodSize); 00571 fNetMidiCaptureBuffer->SetBuffer(midi_port_index, fMidiCaptureBuffer[midi_port_index]); 00572 } 00573 } 00574 00575 if (fParams.fReturnAudioChannels > 0) { 00576 fAudioPlaybackBuffer = new float*[fParams.fReturnAudioChannels]; 00577 for (int audio_port_index = 0; audio_port_index < fParams.fReturnAudioChannels; audio_port_index++) { 00578 fAudioPlaybackBuffer[audio_port_index] = new float[fParams.fPeriodSize]; 00579 memset(fAudioPlaybackBuffer[audio_port_index], 0, sizeof(float) * fParams.fPeriodSize); 00580 fNetAudioPlaybackBuffer->SetBuffer(audio_port_index, fAudioPlaybackBuffer[audio_port_index]); 00581 } 00582 } 00583 00584 if (fParams.fReturnMidiChannels > 0) { 00585 fMidiPlaybackBuffer = new JackMidiBuffer*[fParams.fReturnMidiChannels]; 00586 for (int midi_port_index = 0; midi_port_index < fParams.fReturnMidiChannels; midi_port_index++) { 00587 fMidiPlaybackBuffer[midi_port_index] = (JackMidiBuffer*)new float[fParams.fPeriodSize]; 00588 memset(fMidiPlaybackBuffer[midi_port_index], 0, sizeof(float) * fParams.fPeriodSize); 00589 fNetMidiPlaybackBuffer->SetBuffer(midi_port_index, fMidiPlaybackBuffer[midi_port_index]); 00590 } 00591 } 00592 } 00593 00594 void FreePorts() 00595 { 00596 if (fAudioCaptureBuffer) { 00597 for (int audio_port_index = 0; audio_port_index < fParams.fSendAudioChannels; audio_port_index++) { 00598 delete[] fAudioCaptureBuffer[audio_port_index]; 00599 } 00600 delete[] fAudioCaptureBuffer; 00601 fAudioCaptureBuffer = NULL; 00602 } 00603 00604 if (fMidiCaptureBuffer) { 00605 for (int midi_port_index = 0; midi_port_index < fParams.fSendMidiChannels; midi_port_index++) { 00606 delete[] fMidiCaptureBuffer[midi_port_index]; 00607 } 00608 delete[] fMidiCaptureBuffer; 00609 fMidiCaptureBuffer = NULL; 00610 } 00611 00612 if (fAudioPlaybackBuffer) { 00613 for (int audio_port_index = 0; audio_port_index < fParams.fReturnAudioChannels; audio_port_index++) { 00614 delete[] fAudioPlaybackBuffer[audio_port_index]; 00615 } 00616 delete[] fAudioPlaybackBuffer; 00617 fAudioPlaybackBuffer = NULL; 00618 } 00619 00620 if (fMidiPlaybackBuffer) { 00621 for (int midi_port_index = 0; midi_port_index < fParams.fReturnMidiChannels; midi_port_index++) { 00622 delete[] (fMidiPlaybackBuffer[midi_port_index]); 00623 } 00624 delete[] fMidiPlaybackBuffer; 00625 fMidiPlaybackBuffer = NULL; 00626 } 00627 } 00628 00629 int Open(jack_master_t* result) 00630 { 00631 // Check audio/midi parameters 00632 if (fParams.fSendAudioChannels == 0 00633 && fParams.fReturnAudioChannels == 0 00634 && fParams.fSendMidiChannels == 0 00635 && fParams.fReturnMidiChannels == 0) { 00636 jack_error("Incorrect audio/midi channels number..."); 00637 return -1; 00638 } 00639 00640 // Check MTU parameters 00641 if ((fParams.fMtu < DEFAULT_MTU) && (fParams.fMtu > MAX_MTU)) { 00642 jack_error("MTU is not in the expected range [%d ... %d]", DEFAULT_MTU, MAX_MTU); 00643 return -1; 00644 } 00645 00646 // Check CELT encoder parameters 00647 if ((fParams.fSampleEncoder == JackCeltEncoder) && (fParams.fKBps == 0)) { 00648 jack_error("CELT encoder with 0 for kps..."); 00649 return -1; 00650 } 00651 00652 if ((fParams.fSampleEncoder == JackOpusEncoder) && (fParams.fKBps == 0)) { 00653 jack_error("Opus encoder with 0 for kps..."); 00654 return -1; 00655 } 00656 00657 // Check latency 00658 if (fParams.fNetworkLatency > NETWORK_MAX_LATENCY) { 00659 jack_error("Network latency is limited to %d", NETWORK_MAX_LATENCY); 00660 return -1; 00661 } 00662 00663 // Init network connection 00664 if (!JackNetSlaveInterface::InitConnection(fConnectTimeOut)) { 00665 jack_error("Initing network fails..."); 00666 return -1; 00667 } 00668 00669 // Finish connection... 00670 if (!JackNetSlaveInterface::InitRendering()) { 00671 jack_error("Starting network fails..."); 00672 return -1; 00673 } 00674 00675 // Then set global parameters 00676 if (!SetParams()) { 00677 jack_error("SetParams error..."); 00678 return -1; 00679 } 00680 00681 // Set result 00682 if (result != NULL) { 00683 result->buffer_size = fParams.fPeriodSize; 00684 result->sample_rate = fParams.fSampleRate; 00685 result->audio_input = fParams.fSendAudioChannels; 00686 result->audio_output = fParams.fReturnAudioChannels; 00687 result->midi_input = fParams.fSendMidiChannels; 00688 result->midi_output = fParams.fReturnMidiChannels; 00689 strcpy(result->master_name, fParams.fMasterNetName); 00690 } 00691 00692 // By default fFrames is fPeriodSize 00693 fFrames = fParams.fPeriodSize; 00694 00695 SessionParamsDisplay(&fParams); 00696 00697 AllocPorts(); 00698 return 0; 00699 } 00700 00701 int Restart() 00702 { 00703 // Do it until client possibly decides to stop trying to connect... 00704 while (true) { 00705 00706 // If restart cb is set, then call it 00707 if (fRestartCallback) { 00708 if (fRestartCallback(fRestartArg) != 0) { 00709 return -1; 00710 } 00711 // Otherwise if shutdown cb is set, then call it 00712 } else if (fShutdownCallback) { 00713 fShutdownCallback(fShutdownArg); 00714 } 00715 00716 // Init network connection 00717 if (!JackNetSlaveInterface::InitConnection(fConnectTimeOut)) { 00718 jack_error("Initing network fails after time_out, retry..."); 00719 } else { 00720 break; 00721 } 00722 } 00723 00724 // Finish connection 00725 if (!JackNetSlaveInterface::InitRendering()) { 00726 jack_error("Starting network fails..."); 00727 return -1; 00728 } 00729 00730 // Then set global parameters 00731 if (!SetParams()) { 00732 jack_error("SetParams error..."); 00733 return -1; 00734 } 00735 00736 // We need to notify possibly new buffer size and sample rate (see Execute) 00737 if (fBufferSizeCallback) { 00738 if (fBufferSizeCallback(fParams.fPeriodSize, fBufferSizeArg) != 0) { 00739 jack_error("New buffer size = %d cannot be used...", fParams.fPeriodSize); 00740 return -1; 00741 } 00742 } 00743 00744 if (fSampleRateCallback) { 00745 if (fSampleRateCallback(fParams.fSampleRate, fSampleRateArg) != 0) { 00746 jack_error("New sample rate = %d cannot be used...", fParams.fSampleRate); 00747 return -1; 00748 } 00749 } 00750 00751 AllocPorts(); 00752 return 0; 00753 } 00754 00755 int Close() 00756 { 00757 fSocket.Close(); 00758 FreePorts(); 00759 return 0; 00760 } 00761 00762 // Transport 00763 void EncodeTransportData() 00764 {} 00765 00766 void DecodeTransportData() 00767 {} 00768 00769 bool Init() 00770 { 00771 // Will do "something" on OSX only... 00772 UInt64 period, constraint; 00773 period = constraint = UInt64(1000000000.f * (float(fParams.fPeriodSize) / float(fParams.fSampleRate))); 00774 UInt64 computation = JackTools::ComputationMicroSec(fParams.fPeriodSize) * 1000; 00775 fThread.SetParams(period, computation, constraint); 00776 00777 return (fThread.AcquireSelfRealTime(80) == 0); // TODO: get a value from the server 00778 } 00779 00780 bool IsRunning() 00781 { 00782 return (fThread.GetStatus() == JackThread::kRunning); 00783 } 00784 00785 bool Execute() 00786 { 00787 try { 00788 /* 00789 Fist cycle use an INT_MAX time out, so that connection 00790 is considered established (with PACKET_TIMEOUT later on) 00791 when the first cycle has been done. 00792 */ 00793 DummyProcess(); 00794 // keep running even in case of error 00795 while (fThread.GetStatus() == JackThread::kRunning) { 00796 if (Process() == SOCKET_ERROR) { 00797 return false; 00798 } 00799 } 00800 return false; 00801 } catch (JackNetException& e) { 00802 // otherwise just restart... 00803 e.PrintMessage(); 00804 jack_info("NetSlave is restarted"); 00805 fThread.DropRealTime(); 00806 fThread.SetStatus(JackThread::kIniting); 00807 FreePorts(); 00808 if (Restart() == 0 && Init()) { 00809 fThread.SetStatus(JackThread::kRunning); 00810 return true; 00811 } else { 00812 return false; 00813 } 00814 } 00815 } 00816 00817 int Read() 00818 { 00819 // receive sync (launch the cycle) 00820 switch (SyncRecv()) { 00821 00822 case SOCKET_ERROR: 00823 return SOCKET_ERROR; 00824 00825 case SYNC_PACKET_ERROR: 00826 // since sync packet is incorrect, don't decode it and continue with data 00827 if (fErrorCallback) { 00828 fErrorCallback(SYNC_PACKET_ERROR, fErrorArg); 00829 } 00830 break; 00831 00832 default: 00833 // decode sync 00834 DecodeSyncPacket(fFrames); 00835 break; 00836 } 00837 00838 int res = DataRecv(); 00839 if (res == DATA_PACKET_ERROR && fErrorCallback) { 00840 fErrorCallback(DATA_PACKET_ERROR, fErrorArg); 00841 } 00842 return res; 00843 } 00844 00845 int Write() 00846 { 00847 EncodeSyncPacket(fFrames); 00848 00849 if (SyncSend() == SOCKET_ERROR) { 00850 return SOCKET_ERROR; 00851 } 00852 00853 return DataSend(); 00854 } 00855 00856 void DummyProcess() 00857 { 00858 // First cycle with INT_MAX time out 00859 SetPacketTimeOut(INT_MAX); 00860 00861 // One cycle 00862 Process(); 00863 00864 // Then use PACKET_TIMEOUT * fParams.fNetworkLatency for next cycles 00865 SetPacketTimeOut(PACKET_TIMEOUT * fParams.fNetworkLatency); 00866 } 00867 00868 int Process() 00869 { 00870 // Read data from the network, throw JackNetException in case of network error... 00871 if (Read() == SOCKET_ERROR) { 00872 return SOCKET_ERROR; 00873 } 00874 00875 if (fFrames < 0) fFrames = fParams.fPeriodSize; 00876 00877 fProcessCallback(fFrames, 00878 fParams.fSendAudioChannels, 00879 fAudioCaptureBuffer, 00880 fParams.fSendMidiChannels, 00881 (void**)fMidiCaptureBuffer, 00882 fParams.fReturnAudioChannels, 00883 fAudioPlaybackBuffer, 00884 fParams.fReturnMidiChannels, 00885 (void**)fMidiPlaybackBuffer, 00886 fProcessArg); 00887 00888 // Then write data to network, throw JackNetException in case of network error... 00889 if (Write() == SOCKET_ERROR) { 00890 return SOCKET_ERROR; 00891 } 00892 00893 return 0; 00894 } 00895 00896 int Start() 00897 { 00898 return (fProcessCallback == 0) ? -1 : fThread.StartSync(); 00899 } 00900 00901 int Stop() 00902 { 00903 return (fProcessCallback == 0) ? -1 : fThread.Kill(); 00904 } 00905 00906 // Callback 00907 int SetProcessCallback(JackNetSlaveProcessCallback net_callback, void *arg) 00908 { 00909 if (fThread.GetStatus() == JackThread::kRunning) { 00910 return -1; 00911 } else { 00912 fProcessCallback = net_callback; 00913 fProcessArg = arg; 00914 return 0; 00915 } 00916 } 00917 00918 int SetShutdownCallback(JackNetSlaveShutdownCallback shutdown_callback, void *arg) 00919 { 00920 if (fThread.GetStatus() == JackThread::kRunning) { 00921 return -1; 00922 } else { 00923 fShutdownCallback = shutdown_callback; 00924 fShutdownArg = arg; 00925 return 0; 00926 } 00927 } 00928 00929 int SetRestartCallback(JackNetSlaveRestartCallback restart_callback, void *arg) 00930 { 00931 if (fThread.GetStatus() == JackThread::kRunning) { 00932 return -1; 00933 } else { 00934 fRestartCallback = restart_callback; 00935 fRestartArg = arg; 00936 return 0; 00937 } 00938 } 00939 00940 int SetErrorCallback(JackNetSlaveErrorCallback error_callback, void *arg) 00941 { 00942 if (fThread.GetStatus() == JackThread::kRunning) { 00943 return -1; 00944 } else { 00945 fErrorCallback = error_callback; 00946 fErrorArg = arg; 00947 return 0; 00948 } 00949 } 00950 00951 int SetBufferSizeCallback(JackNetSlaveBufferSizeCallback bufsize_callback, void *arg) 00952 { 00953 if (fThread.GetStatus() == JackThread::kRunning) { 00954 return -1; 00955 } else { 00956 fBufferSizeCallback = bufsize_callback; 00957 fBufferSizeArg = arg; 00958 return 0; 00959 } 00960 } 00961 00962 int SetSampleRateCallback(JackNetSlaveSampleRateCallback samplerate_callback, void *arg) 00963 { 00964 if (fThread.GetStatus() == JackThread::kRunning) { 00965 return -1; 00966 } else { 00967 fSampleRateCallback = samplerate_callback; 00968 fSampleRateArg = arg; 00969 return 0; 00970 } 00971 } 00972 00973 }; 00974 00975 struct JackNetAdapter : public JackAudioAdapterInterface { 00976 00977 JackNetAdapter(int input, int output, 00978 jack_nframes_t host_buffer_size, 00979 jack_nframes_t host_sample_rate, 00980 jack_nframes_t adapted_buffer_size, 00981 jack_nframes_t adapted_sample_rate) 00982 :JackAudioAdapterInterface(host_buffer_size, host_sample_rate, adapted_buffer_size, adapted_sample_rate) 00983 { 00984 fCaptureChannels = input; 00985 fPlaybackChannels = output; 00986 Create(); 00987 } 00988 00989 void Create() 00990 { 00991 //ringbuffers 00992 00993 if (fCaptureChannels > 0) { 00994 fCaptureRingBuffer = new JackResampler*[fCaptureChannels]; 00995 } 00996 if (fPlaybackChannels > 0) { 00997 fPlaybackRingBuffer = new JackResampler*[fPlaybackChannels]; 00998 } 00999 01000 if (fAdaptative) { 01001 AdaptRingBufferSize(); 01002 jack_info("Ringbuffer automatic adaptative mode size = %d frames", fRingbufferCurSize); 01003 } else { 01004 if (fRingbufferCurSize > DEFAULT_RB_SIZE) { 01005 fRingbufferCurSize = DEFAULT_RB_SIZE; 01006 } 01007 jack_info("Fixed ringbuffer size = %d frames", fRingbufferCurSize); 01008 } 01009 01010 for (int i = 0; i < fCaptureChannels; i++ ) { 01011 fCaptureRingBuffer[i] = new JackResampler(); 01012 fCaptureRingBuffer[i]->Reset(fRingbufferCurSize); 01013 } 01014 for (int i = 0; i < fPlaybackChannels; i++ ) { 01015 fPlaybackRingBuffer[i] = new JackResampler(); 01016 fPlaybackRingBuffer[i]->Reset(fRingbufferCurSize); 01017 } 01018 01019 if (fCaptureChannels > 0) { 01020 jack_log("ReadSpace = %ld", fCaptureRingBuffer[0]->ReadSpace()); 01021 } 01022 if (fPlaybackChannels > 0) { 01023 jack_log("WriteSpace = %ld", fPlaybackRingBuffer[0]->WriteSpace()); 01024 } 01025 } 01026 01027 virtual ~JackNetAdapter() 01028 { 01029 Destroy(); 01030 } 01031 01032 void Flush() 01033 { 01034 for (int i = 0; i < fCaptureChannels; i++ ) { 01035 fCaptureRingBuffer[i]->Reset(fRingbufferCurSize); 01036 } 01037 for (int i = 0; i < fPlaybackChannels; i++ ) { 01038 fPlaybackRingBuffer[i]->Reset(fRingbufferCurSize); 01039 } 01040 } 01041 01042 }; 01043 01044 01045 } // end of namespace 01046 01047 using namespace Jack; 01048 01049 LIB_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) 01050 { 01051 JackNetExtSlave* slave = new JackNetExtSlave(ip, port, name, request); 01052 if (slave->Open(result) == 0) { 01053 return (jack_net_slave_t*)slave; 01054 } else { 01055 delete slave; 01056 return NULL; 01057 } 01058 } 01059 01060 LIB_EXPORT int jack_net_slave_close(jack_net_slave_t* net) 01061 { 01062 JackNetExtSlave* slave = (JackNetExtSlave*)net; 01063 slave->Close(); 01064 delete slave; 01065 return 0; 01066 } 01067 01068 LIB_EXPORT int jack_set_net_slave_process_callback(jack_net_slave_t* net, JackNetSlaveProcessCallback net_callback, void *arg) 01069 { 01070 JackNetExtSlave* slave = (JackNetExtSlave*)net; 01071 return slave->SetProcessCallback(net_callback, arg); 01072 } 01073 01074 LIB_EXPORT int jack_net_slave_activate(jack_net_slave_t* net) 01075 { 01076 JackNetExtSlave* slave = (JackNetExtSlave*)net; 01077 return slave->Start(); 01078 } 01079 01080 LIB_EXPORT int jack_net_slave_deactivate(jack_net_slave_t* net) 01081 { 01082 JackNetExtSlave* slave = (JackNetExtSlave*)net; 01083 return slave->Stop(); 01084 } 01085 01086 LIB_EXPORT int jack_net_slave_is_active(jack_net_slave_t* net) 01087 { 01088 JackNetExtSlave* slave = (JackNetExtSlave*)net; 01089 return slave->IsRunning(); 01090 } 01091 01092 LIB_EXPORT int jack_set_net_slave_buffer_size_callback(jack_net_slave_t *net, JackNetSlaveBufferSizeCallback bufsize_callback, void *arg) 01093 { 01094 JackNetExtSlave* slave = (JackNetExtSlave*)net; 01095 return slave->SetBufferSizeCallback(bufsize_callback, arg); 01096 } 01097 01098 LIB_EXPORT int jack_set_net_slave_sample_rate_callback(jack_net_slave_t *net, JackNetSlaveSampleRateCallback samplerate_callback, void *arg) 01099 { 01100 JackNetExtSlave* slave = (JackNetExtSlave*)net; 01101 return slave->SetSampleRateCallback(samplerate_callback, arg); 01102 } 01103 01104 LIB_EXPORT int jack_set_net_slave_shutdown_callback(jack_net_slave_t *net, JackNetSlaveShutdownCallback shutdown_callback, void *arg) 01105 { 01106 JackNetExtSlave* slave = (JackNetExtSlave*)net; 01107 return slave->SetShutdownCallback(shutdown_callback, arg); 01108 } 01109 01110 LIB_EXPORT int jack_set_net_slave_restart_callback(jack_net_slave_t *net, JackNetSlaveRestartCallback restart_callback, void *arg) 01111 { 01112 JackNetExtSlave* slave = (JackNetExtSlave*)net; 01113 return slave->SetRestartCallback(restart_callback, arg); 01114 } 01115 01116 LIB_EXPORT int jack_set_net_slave_error_callback(jack_net_slave_t *net, JackNetSlaveErrorCallback error_callback, void *arg) 01117 { 01118 JackNetExtSlave* slave = (JackNetExtSlave*)net; 01119 return slave->SetErrorCallback(error_callback, arg); 01120 } 01121 01122 // Master API 01123 01124 LIB_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) 01125 { 01126 JackNetExtMaster* master = new JackNetExtMaster(ip, port, name, request); 01127 if (master->Open(result) == 0) { 01128 return (jack_net_master_t*)master; 01129 } else { 01130 delete master; 01131 return NULL; 01132 } 01133 } 01134 01135 LIB_EXPORT int jack_net_master_close(jack_net_master_t* net) 01136 { 01137 JackNetExtMaster* master = (JackNetExtMaster*)net; 01138 master->Close(); 01139 delete master; 01140 return 0; 01141 } 01142 01143 LIB_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) 01144 { 01145 JackNetExtMaster* master = (JackNetExtMaster*)net; 01146 return master->Read(audio_input, audio_input_buffer, midi_input, midi_input_buffer, -1); 01147 } 01148 01149 LIB_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) 01150 { 01151 JackNetExtMaster* master = (JackNetExtMaster*)net; 01152 return master->Write(audio_output, audio_output_buffer, midi_output, midi_output_buffer, -1); 01153 } 01154 01155 LIB_EXPORT int jack_net_master_recv_slice(jack_net_master_t* net, int audio_input, float** audio_input_buffer, int midi_input, void** midi_input_buffer, int frames) 01156 { 01157 JackNetExtMaster* master = (JackNetExtMaster*)net; 01158 return master->Read(audio_input, audio_input_buffer, midi_input, midi_input_buffer, frames); 01159 } 01160 01161 LIB_EXPORT int jack_net_master_send_slice(jack_net_master_t* net, int audio_output, float** audio_output_buffer, int midi_output, void** midi_output_buffer, int frames) 01162 { 01163 JackNetExtMaster* master = (JackNetExtMaster*)net; 01164 return master->Write(audio_output, audio_output_buffer, midi_output, midi_output_buffer, frames); 01165 } 01166 01167 // Adapter API 01168 01169 LIB_EXPORT jack_adapter_t* jack_create_adapter(int input, int output, 01170 jack_nframes_t host_buffer_size, 01171 jack_nframes_t host_sample_rate, 01172 jack_nframes_t adapted_buffer_size, 01173 jack_nframes_t adapted_sample_rate) 01174 { 01175 try { 01176 return (jack_adapter_t*)new JackNetAdapter(input, output, host_buffer_size, host_sample_rate, adapted_buffer_size, adapted_sample_rate); 01177 } catch (...) { 01178 return NULL; 01179 } 01180 } 01181 01182 LIB_EXPORT int jack_destroy_adapter(jack_adapter_t* adapter) 01183 { 01184 delete((JackNetAdapter*)adapter); 01185 return 0; 01186 } 01187 01188 LIB_EXPORT void jack_flush_adapter(jack_adapter_t* adapter) 01189 { 01190 JackNetAdapter* slave = (JackNetAdapter*)adapter; 01191 slave->Flush(); 01192 } 01193 01194 LIB_EXPORT int jack_adapter_push_and_pull(jack_adapter_t* adapter, float** input, float** output, unsigned int frames) 01195 { 01196 JackNetAdapter* slave = (JackNetAdapter*)adapter; 01197 return slave->PushAndPull(input, output, frames); 01198 } 01199 01200 LIB_EXPORT int jack_adapter_pull_and_push(jack_adapter_t* adapter, float** input, float** output, unsigned int frames) 01201 { 01202 JackNetAdapter* slave = (JackNetAdapter*)adapter; 01203 return slave->PullAndPush(input, output, frames); 01204 } 01205 01206 static void jack_format_and_log(int level, const char *prefix, const char *fmt, va_list ap) 01207 { 01208 static const char* netjack_log = getenv("JACK_NETJACK_LOG"); 01209 static bool is_netjack_log = (netjack_log) ? atoi(netjack_log) : 0; 01210 01211 if (is_netjack_log) { 01212 char buffer[300]; 01213 size_t len; 01214 01215 if (prefix != NULL) { 01216 len = strlen(prefix); 01217 memcpy(buffer, prefix, len); 01218 } else { 01219 len = 0; 01220 } 01221 01222 vsnprintf(buffer + len, sizeof(buffer) - len, fmt, ap); 01223 printf("%s", buffer); 01224 printf("\n"); 01225 } 01226 } 01227 01228 LIB_EXPORT void jack_error(const char *fmt, ...) 01229 { 01230 va_list ap; 01231 va_start(ap, fmt); 01232 jack_format_and_log(LOG_LEVEL_INFO, "Jack: ", fmt, ap); 01233 va_end(ap); 01234 } 01235 01236 LIB_EXPORT void jack_info(const char *fmt, ...) 01237 { 01238 va_list ap; 01239 va_start(ap, fmt); 01240 jack_format_and_log(LOG_LEVEL_INFO, "Jack: ", fmt, ap); 01241 va_end(ap); 01242 } 01243 01244 LIB_EXPORT void jack_log(const char *fmt, ...) 01245 { 01246 va_list ap; 01247 va_start(ap, fmt); 01248 jack_format_and_log(LOG_LEVEL_INFO, "Jack: ", fmt, ap); 01249 va_end(ap); 01250 }