Jack2
1.9.8
|
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