jack2 codebase
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1046 lines
34KB

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