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.

1255 lines
40KB

  1. /*
  2. Copyright (C) 2001 Paul Davis
  3. Copyright (C) 2004 Grame
  4. Copyright (C) 2007 Pieter Palmers
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. */
  17. #include <iostream>
  18. #include <unistd.h>
  19. #include <math.h>
  20. #include <stdio.h>
  21. #include <memory.h>
  22. #include <unistd.h>
  23. #include <stdlib.h>
  24. #include <errno.h>
  25. #include <stdarg.h>
  26. #include <signal.h>
  27. #include <sys/types.h>
  28. #include <sys/time.h>
  29. #include <regex.h>
  30. #include <string.h>
  31. #include "JackFreebobDriver.h"
  32. #include "JackEngineControl.h"
  33. #include "JackClientControl.h"
  34. #include "JackPort.h"
  35. #include "JackGraphManager.h"
  36. namespace Jack
  37. {
  38. #define jack_get_microseconds GetMicroSeconds
  39. #define SAMPLE_MAX_24BIT 8388608.0f
  40. #define SAMPLE_MAX_16BIT 32768.0f
  41. int
  42. JackFreebobDriver::freebob_driver_read (freebob_driver_t * driver, jack_nframes_t nframes)
  43. {
  44. jack_default_audio_sample_t* buf = NULL;
  45. // channel_t chn;
  46. // JSList *node;
  47. // jack_port_t* port;
  48. freebob_sample_t nullbuffer[nframes];
  49. void *addr_of_nullbuffer = (void *)nullbuffer;
  50. freebob_streaming_stream_type stream_type;
  51. printEnter();
  52. // make sure all buffers have a valid buffer if not connected
  53. for (int i = 0; i < driver->capture_nchannels; i++) {
  54. stream_type = freebob_streaming_get_playback_stream_type(driver->dev, i);
  55. if (stream_type == freebob_stream_type_audio) {
  56. freebob_streaming_set_playback_stream_buffer(driver->dev, i,
  57. (char *)(nullbuffer), freebob_buffer_type_float);
  58. } else if (stream_type == freebob_stream_type_midi) {
  59. // these should be read/written with the per-stream functions
  60. } else { // empty other buffers without doing something with them
  61. freebob_streaming_set_playback_stream_buffer(driver->dev, i,
  62. (char *)(nullbuffer), freebob_buffer_type_uint24);
  63. }
  64. }
  65. for (int i = 0; i < fCaptureChannels; i++) {
  66. stream_type = freebob_streaming_get_capture_stream_type(driver->dev, i);
  67. if (stream_type == freebob_stream_type_audio) {
  68. if (fGraphManager->GetConnectionsNum(fCapturePortList[i]) > 0) {
  69. buf = (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fCapturePortList[i], nframes);
  70. if (!buf) {
  71. buf = (jack_default_audio_sample_t *)addr_of_nullbuffer;
  72. }
  73. freebob_streaming_set_capture_stream_buffer(driver->dev, i, (char *)(buf), freebob_buffer_type_float);
  74. }
  75. } else if (stream_type == freebob_stream_type_midi) {
  76. // these should be read/written with the per-stream functions
  77. } else { // empty other buffers without doing something with them
  78. freebob_streaming_set_capture_stream_buffer(driver->dev, i, (char *)(nullbuffer), freebob_buffer_type_uint24);
  79. }
  80. }
  81. // now transfer the buffers
  82. freebob_streaming_transfer_capture_buffers(driver->dev);
  83. printExit();
  84. return 0;
  85. }
  86. int
  87. JackFreebobDriver::freebob_driver_write (freebob_driver_t * driver, jack_nframes_t nframes)
  88. {
  89. channel_t chn;
  90. JSList *node;
  91. jack_default_audio_sample_t* buf = NULL;
  92. jack_port_t *port;
  93. freebob_streaming_stream_type stream_type;
  94. freebob_sample_t nullbuffer[nframes];
  95. void *addr_of_nullbuffer = (void*)nullbuffer;
  96. memset(&nullbuffer, 0, nframes*sizeof(freebob_sample_t));
  97. printEnter();
  98. driver->process_count++;
  99. assert(driver->dev);
  100. // make sure all buffers output silence if not connected
  101. for (int i = 0; i < driver->playback_nchannels; i++) {
  102. stream_type = freebob_streaming_get_playback_stream_type(driver->dev, i);
  103. if (stream_type == freebob_stream_type_audio) {
  104. freebob_streaming_set_playback_stream_buffer(driver->dev, i,
  105. (char *)(nullbuffer), freebob_buffer_type_float);
  106. } else if (stream_type == freebob_stream_type_midi) {
  107. // these should be read/written with the per-stream functions
  108. } else { // empty other buffers without doing something with them
  109. freebob_streaming_set_playback_stream_buffer(driver->dev, i,
  110. (char *)(nullbuffer), freebob_buffer_type_uint24);
  111. }
  112. }
  113. for (int i = 0; i < fPlaybackChannels; i++) {
  114. stream_type = freebob_streaming_get_playback_stream_type(driver->dev, i);
  115. if (stream_type == freebob_stream_type_audio) {
  116. // Ouput ports
  117. if (fGraphManager->GetConnectionsNum(fPlaybackPortList[i]) > 0) {
  118. buf = (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fPlaybackPortList[i], nframes);
  119. if (!buf) {
  120. buf = (jack_default_audio_sample_t *)addr_of_nullbuffer;
  121. }
  122. freebob_streaming_set_playback_stream_buffer(driver->dev, i, (char *)(buf), freebob_buffer_type_float);
  123. }
  124. }
  125. }
  126. freebob_streaming_transfer_playback_buffers(driver->dev);
  127. printExit();
  128. return 0;
  129. }
  130. jack_nframes_t
  131. JackFreebobDriver::freebob_driver_wait (freebob_driver_t *driver, int extra_fd, int *status,
  132. float *delayed_usecs)
  133. {
  134. int nframes;
  135. jack_time_t wait_enter;
  136. jack_time_t wait_ret;
  137. printEnter();
  138. wait_enter = jack_get_microseconds ();
  139. if (wait_enter > driver->wait_next) {
  140. /*
  141. * This processing cycle was delayed past the
  142. * next due interrupt! Do not account this as
  143. * a wakeup delay:
  144. */
  145. driver->wait_next = 0;
  146. driver->wait_late++;
  147. }
  148. // *status = -2; interrupt
  149. // *status = -3; timeout
  150. // *status = -4; extra FD
  151. nframes = freebob_streaming_wait(driver->dev);
  152. wait_ret = jack_get_microseconds ();
  153. if (driver->wait_next && wait_ret > driver->wait_next) {
  154. *delayed_usecs = wait_ret - driver->wait_next;
  155. }
  156. driver->wait_last = wait_ret;
  157. driver->wait_next = wait_ret + driver->period_usecs;
  158. // driver->engine->transport_cycle_start (driver->engine, wait_ret);
  159. if (nframes < 0) {
  160. *status = 0;
  161. return 0;
  162. }
  163. *status = 0;
  164. fLastWaitUst = wait_ret;
  165. // FIXME: this should do something more usefull
  166. *delayed_usecs = 0;
  167. printExit();
  168. return nframes - nframes % driver->period_size;
  169. }
  170. int
  171. JackFreebobDriver::freebob_driver_start (freebob_driver_t *driver)
  172. {
  173. int retval = 0;
  174. #ifdef FREEBOB_DRIVER_WITH_MIDI
  175. if (driver->midi_handle) {
  176. if ((retval = freebob_driver_midi_start(driver->midi_handle))) {
  177. printError("Could not start MIDI threads");
  178. return retval;
  179. }
  180. }
  181. #endif
  182. if ((retval = freebob_streaming_start(driver->dev))) {
  183. printError("Could not start streaming threads");
  184. #ifdef FREEBOB_DRIVER_WITH_MIDI
  185. if (driver->midi_handle) {
  186. freebob_driver_midi_stop(driver->midi_handle);
  187. }
  188. #endif
  189. return retval;
  190. }
  191. return 0;
  192. }
  193. int
  194. JackFreebobDriver::freebob_driver_stop (freebob_driver_t *driver)
  195. {
  196. int retval = 0;
  197. #ifdef FREEBOB_DRIVER_WITH_MIDI
  198. if (driver->midi_handle) {
  199. if ((retval = freebob_driver_midi_stop(driver->midi_handle))) {
  200. printError("Could not stop MIDI threads");
  201. return retval;
  202. }
  203. }
  204. #endif
  205. if ((retval = freebob_streaming_stop(driver->dev))) {
  206. printError("Could not stop streaming threads");
  207. return retval;
  208. }
  209. return 0;
  210. }
  211. int
  212. JackFreebobDriver::freebob_driver_restart (freebob_driver_t *driver)
  213. {
  214. if (Stop())
  215. return -1;
  216. return Start();
  217. }
  218. int
  219. JackFreebobDriver::SetBufferSize (jack_nframes_t nframes)
  220. {
  221. printError("Buffer size change requested but not supported!!!");
  222. /*
  223. driver->period_size = nframes;
  224. driver->period_usecs =
  225. (jack_time_t) floor ((((float) nframes) / driver->sample_rate)
  226. * 1000000.0f);
  227. */
  228. /* tell the engine to change its buffer size */
  229. //driver->engine->set_buffer_size (driver->engine, nframes);
  230. return -1; // unsupported
  231. }
  232. typedef void (*JackDriverFinishFunction) (jack_driver_t *);
  233. freebob_driver_t *
  234. JackFreebobDriver::freebob_driver_new (char *name,
  235. freebob_jack_settings_t *params)
  236. {
  237. freebob_driver_t *driver;
  238. assert(params);
  239. if (freebob_get_api_version() != 1) {
  240. printMessage("Incompatible libfreebob version! (%s)", freebob_get_version());
  241. return NULL;
  242. }
  243. printMessage("Starting Freebob backend (%s)", freebob_get_version());
  244. driver = (freebob_driver_t*)calloc (1, sizeof (freebob_driver_t));
  245. /* Setup the jack interfaces */
  246. jack_driver_nt_init ((jack_driver_nt_t *) driver);
  247. /* driver->nt_attach = (JackDriverNTAttachFunction) freebob_driver_attach;
  248. driver->nt_detach = (JackDriverNTDetachFunction) freebob_driver_detach;
  249. driver->nt_start = (JackDriverNTStartFunction) freebob_driver_start;
  250. driver->nt_stop = (JackDriverNTStopFunction) freebob_driver_stop;
  251. driver->nt_run_cycle = (JackDriverNTRunCycleFunction) freebob_driver_run_cycle;
  252. driver->null_cycle = (JackDriverNullCycleFunction) freebob_driver_null_cycle;
  253. driver->write = (JackDriverReadFunction) freebob_driver_write;
  254. driver->read = (JackDriverReadFunction) freebob_driver_read;
  255. driver->nt_bufsize = (JackDriverNTBufSizeFunction) freebob_driver_bufsize;
  256. */
  257. /* copy command line parameter contents to the driver structure */
  258. memcpy(&driver->settings, params, sizeof(freebob_jack_settings_t));
  259. /* prepare all parameters */
  260. driver->sample_rate = params->sample_rate;
  261. driver->period_size = params->period_size;
  262. fLastWaitUst = 0;
  263. driver->period_usecs =
  264. (jack_time_t) floor ((((float) driver->period_size) * 1000000.0f) / driver->sample_rate);
  265. // driver->client = client;
  266. driver->engine = NULL;
  267. memset(&driver->device_options, 0, sizeof(driver->device_options));
  268. driver->device_options.sample_rate = params->sample_rate;
  269. driver->device_options.period_size = params->period_size;
  270. driver->device_options.nb_buffers = params->buffer_size;
  271. driver->device_options.node_id = params->node_id;
  272. driver->device_options.port = params->port;
  273. driver->capture_frame_latency = params->capture_frame_latency;
  274. driver->playback_frame_latency = params->playback_frame_latency;
  275. if (!params->capture_ports) {
  276. driver->device_options.directions |= FREEBOB_IGNORE_CAPTURE;
  277. }
  278. if (!params->playback_ports) {
  279. driver->device_options.directions |= FREEBOB_IGNORE_PLAYBACK;
  280. }
  281. debugPrint(DEBUG_LEVEL_STARTUP, " Driver compiled on %s %s", __DATE__, __TIME__);
  282. debugPrint(DEBUG_LEVEL_STARTUP, " Created driver %s", name);
  283. debugPrint(DEBUG_LEVEL_STARTUP, " period_size: %d", driver->period_size);
  284. debugPrint(DEBUG_LEVEL_STARTUP, " period_usecs: %d", driver->period_usecs);
  285. debugPrint(DEBUG_LEVEL_STARTUP, " sample rate: %d", driver->sample_rate);
  286. return (freebob_driver_t *) driver;
  287. }
  288. void
  289. JackFreebobDriver::freebob_driver_delete (freebob_driver_t *driver)
  290. {
  291. if (driver->dev) {
  292. Detach();
  293. }
  294. jack_driver_nt_finish ((jack_driver_nt_t *) driver);
  295. free (driver);
  296. }
  297. #ifdef FREEBOB_DRIVER_WITH_MIDI
  298. /*
  299. * MIDI support
  300. */
  301. // the thread that will queue the midi events from the seq to the stream buffers
  302. void *
  303. JackFreebobDriver::freebob_driver_midi_queue_thread(void *arg)
  304. {
  305. freebob_driver_midi_handle_t *m = (freebob_driver_midi_handle_t *)arg;
  306. assert(m);
  307. snd_seq_event_t *ev;
  308. unsigned char work_buffer[MIDI_TRANSMIT_BUFFER_SIZE];
  309. int bytes_to_send;
  310. int b;
  311. int i;
  312. printMessage("MIDI queue thread started");
  313. while (1) {
  314. // get next event, if one is present
  315. while ((snd_seq_event_input(m->seq_handle, &ev) > 0)) {
  316. // get the port this event is originated from
  317. freebob_midi_port_t *port = NULL;
  318. for (i = 0;i < m->nb_output_ports;i++) {
  319. if (m->output_ports[i]->seq_port_nr == ev->dest.port) {
  320. port = m->output_ports[i];
  321. break;
  322. }
  323. }
  324. if (!port) {
  325. printError(" Could not find target port for event: dst=%d src=%d", ev->dest.port, ev->source.port);
  326. break;
  327. }
  328. // decode it to the work buffer
  329. if ((bytes_to_send = snd_midi_event_decode ( port->parser,
  330. work_buffer,
  331. MIDI_TRANSMIT_BUFFER_SIZE,
  332. ev)) < 0) { // failed
  333. printError(" Error decoding event for port %d (errcode=%d)", port->seq_port_nr, bytes_to_send);
  334. bytes_to_send = 0;
  335. //return -1;
  336. }
  337. for (b = 0;b < bytes_to_send;b++) {
  338. freebob_sample_t tmp_event = work_buffer[b];
  339. if (freebob_streaming_write(m->dev, port->stream_nr, &tmp_event, 1) < 1) {
  340. printError(" Midi send buffer overrun");
  341. }
  342. }
  343. }
  344. // sleep for some time
  345. usleep(MIDI_THREAD_SLEEP_TIME_USECS);
  346. }
  347. return NULL;
  348. }
  349. // the dequeue thread (maybe we need one thread per stream)
  350. void *
  351. JackFreebobDriver::freebob_driver_midi_dequeue_thread (void *arg)
  352. {
  353. freebob_driver_midi_handle_t *m = (freebob_driver_midi_handle_t *)arg;
  354. int i;
  355. int s;
  356. int samples_read;
  357. assert(m);
  358. while (1) {
  359. // read incoming events
  360. for (i = 0;i < m->nb_input_ports;i++) {
  361. unsigned int buff[64];
  362. freebob_midi_port_t *port = m->input_ports[i];
  363. if (!port) {
  364. printError(" something went wrong when setting up the midi input port map (%d)", i);
  365. }
  366. do {
  367. samples_read = freebob_streaming_read(m->dev, port->stream_nr, buff, 64);
  368. for (s = 0;s < samples_read;s++) {
  369. unsigned int *byte = (buff + s) ;
  370. snd_seq_event_t ev;
  371. if ((snd_midi_event_encode_byte(port->parser, (*byte) & 0xFF, &ev)) > 0) {
  372. // a midi message is complete, send it out to ALSA
  373. snd_seq_ev_set_subs(&ev);
  374. snd_seq_ev_set_direct(&ev);
  375. snd_seq_ev_set_source(&ev, port->seq_port_nr);
  376. snd_seq_event_output_direct(port->seq_handle, &ev);
  377. }
  378. }
  379. } while (samples_read > 0);
  380. }
  381. // sleep for some time
  382. usleep(MIDI_THREAD_SLEEP_TIME_USECS);
  383. }
  384. return NULL;
  385. }
  386. freebob_driver_midi_handle_t *
  387. JackFreebobDriver::freebob_driver_midi_init(freebob_driver_t *driver)
  388. {
  389. // int err;
  390. char buf[256];
  391. channel_t chn;
  392. int nchannels;
  393. int i = 0;
  394. freebob_device_t *dev = driver->dev;
  395. assert(dev);
  396. freebob_driver_midi_handle_t *m = calloc(1, sizeof(freebob_driver_midi_handle_t));
  397. if (!m) {
  398. printError("not enough memory to create midi structure");
  399. return NULL;
  400. }
  401. if (snd_seq_open(&m->seq_handle, "default", SND_SEQ_OPEN_DUPLEX, SND_SEQ_NONBLOCK) < 0) {
  402. printError("Error opening ALSA sequencer.");
  403. free(m);
  404. return NULL;
  405. }
  406. snd_seq_set_client_name(m->seq_handle, "FreeBoB Jack MIDI");
  407. // find out the number of midi in/out ports we need to setup
  408. nchannels = freebob_streaming_get_nb_capture_streams(dev);
  409. m->nb_input_ports = 0;
  410. for (chn = 0; chn < nchannels; chn++) {
  411. if (freebob_streaming_get_capture_stream_type(dev, chn) == freebob_stream_type_midi) {
  412. m->nb_input_ports++;
  413. }
  414. }
  415. m->input_ports = calloc(m->nb_input_ports, sizeof(freebob_midi_port_t *));
  416. if (!m->input_ports) {
  417. printError("not enough memory to create midi structure");
  418. free(m);
  419. return NULL;
  420. }
  421. i = 0;
  422. for (chn = 0; chn < nchannels; chn++) {
  423. if (freebob_streaming_get_capture_stream_type(dev, chn) == freebob_stream_type_midi) {
  424. m->input_ports[i] = calloc(1, sizeof(freebob_midi_port_t));
  425. if (!m->input_ports[i]) {
  426. // fixme
  427. printError("Could not allocate memory for seq port");
  428. continue;
  429. }
  430. freebob_streaming_get_capture_stream_name(dev, chn, buf, sizeof(buf) - 1);
  431. printMessage("Register MIDI IN port %s", buf);
  432. m->input_ports[i]->seq_port_nr = snd_seq_create_simple_port(m->seq_handle, buf,
  433. SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ,
  434. SND_SEQ_PORT_TYPE_MIDI_GENERIC);
  435. if (m->input_ports[i]->seq_port_nr < 0) {
  436. printError("Could not create seq port");
  437. m->input_ports[i]->stream_nr = -1;
  438. m->input_ports[i]->seq_port_nr = -1;
  439. } else {
  440. m->input_ports[i]->stream_nr = chn;
  441. m->input_ports[i]->seq_handle = m->seq_handle;
  442. if (snd_midi_event_new ( ALSA_SEQ_BUFF_SIZE, &(m->input_ports[i]->parser)) < 0) {
  443. printError("could not init parser for MIDI IN port %d", i);
  444. m->input_ports[i]->stream_nr = -1;
  445. m->input_ports[i]->seq_port_nr = -1;
  446. }
  447. }
  448. i++;
  449. }
  450. }
  451. // playback
  452. nchannels = freebob_streaming_get_nb_playback_streams(dev);
  453. m->nb_output_ports = 0;
  454. for (chn = 0; chn < nchannels; chn++) {
  455. if (freebob_streaming_get_playback_stream_type(dev, chn) == freebob_stream_type_midi) {
  456. m->nb_output_ports++;
  457. }
  458. }
  459. m->output_ports = calloc(m->nb_output_ports, sizeof(freebob_midi_port_t *));
  460. if (!m->output_ports) {
  461. printError("not enough memory to create midi structure");
  462. for (i = 0; i < m->nb_input_ports; i++) {
  463. free(m->input_ports[i]);
  464. }
  465. free(m->input_ports);
  466. free(m);
  467. return NULL;
  468. }
  469. i = 0;
  470. for (chn = 0; chn < nchannels; chn++) {
  471. if (freebob_streaming_get_playback_stream_type(dev, chn) == freebob_stream_type_midi) {
  472. m->output_ports[i] = calloc(1, sizeof(freebob_midi_port_t));
  473. if (!m->output_ports[i]) {
  474. // fixme
  475. printError("Could not allocate memory for seq port");
  476. continue;
  477. }
  478. freebob_streaming_get_playback_stream_name(dev, chn, buf, sizeof(buf) - 1);
  479. printMessage("Register MIDI OUT port %s", buf);
  480. m->output_ports[i]->seq_port_nr = snd_seq_create_simple_port(m->seq_handle, buf,
  481. SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE,
  482. SND_SEQ_PORT_TYPE_MIDI_GENERIC);
  483. if (m->output_ports[i]->seq_port_nr < 0) {
  484. printError("Could not create seq port");
  485. m->output_ports[i]->stream_nr = -1;
  486. m->output_ports[i]->seq_port_nr = -1;
  487. } else {
  488. m->output_ports[i]->stream_nr = chn;
  489. m->output_ports[i]->seq_handle = m->seq_handle;
  490. if (snd_midi_event_new ( ALSA_SEQ_BUFF_SIZE, &(m->output_ports[i]->parser)) < 0) {
  491. printError("could not init parser for MIDI OUT port %d", i);
  492. m->output_ports[i]->stream_nr = -1;
  493. m->output_ports[i]->seq_port_nr = -1;
  494. }
  495. }
  496. i++;
  497. }
  498. }
  499. m->dev = dev;
  500. m->driver = driver;
  501. return m;
  502. }
  503. int
  504. JackFreebobDriver::freebob_driver_midi_start (freebob_driver_midi_handle_t *m)
  505. {
  506. assert(m);
  507. // start threads
  508. m->queue_thread_realtime = (m->driver->engine->control->real_time ? 1 : 0);
  509. m->queue_thread_priority =
  510. m->driver->engine->control->client_priority +
  511. FREEBOB_RT_PRIORITY_MIDI_RELATIVE;
  512. if (m->queue_thread_priority > 98) {
  513. m->queue_thread_priority = 98;
  514. }
  515. if (m->queue_thread_realtime) {
  516. printMessage("MIDI threads running with Realtime scheduling, priority %d",
  517. m->queue_thread_priority);
  518. } else {
  519. printMessage("MIDI threads running without Realtime scheduling");
  520. }
  521. if (jack_client_create_thread(NULL, &m->queue_thread, m->queue_thread_priority, m->queue_thread_realtime, freebob_driver_midi_queue_thread, (void *)m)) {
  522. printError(" cannot create midi queueing thread");
  523. return -1;
  524. }
  525. if (jack_client_create_thread(NULL, &m->dequeue_thread, m->queue_thread_priority, m->queue_thread_realtime, freebob_driver_midi_dequeue_thread, (void *)m)) {
  526. printError(" cannot create midi dequeueing thread");
  527. return -1;
  528. }
  529. return 0;
  530. }
  531. int
  532. JackFreebobDriver::freebob_driver_midi_stop (freebob_driver_midi_handle_t *m)
  533. {
  534. assert(m);
  535. pthread_cancel (m->queue_thread);
  536. pthread_join (m->queue_thread, NULL);
  537. pthread_cancel (m->dequeue_thread);
  538. pthread_join (m->dequeue_thread, NULL);
  539. return 0;
  540. }
  541. void
  542. JackFreebobDriver::freebob_driver_midi_finish (freebob_driver_midi_handle_t *m)
  543. {
  544. assert(m);
  545. int i;
  546. // TODO: add state info here, if not stopped then stop
  547. for (i = 0;i < m->nb_input_ports;i++) {
  548. free(m->input_ports[i]);
  549. }
  550. free(m->input_ports);
  551. for (i = 0;i < m->nb_output_ports;i++) {
  552. free(m->output_ports[i]);
  553. }
  554. free(m->output_ports);
  555. free(m);
  556. }
  557. #endif
  558. int JackFreebobDriver::Attach()
  559. {
  560. JackPort* port;
  561. int port_index;
  562. unsigned long port_flags;
  563. char buf[JACK_PORT_NAME_SIZE];
  564. char portname[JACK_PORT_NAME_SIZE];
  565. freebob_driver_t* driver = (freebob_driver_t*)fDriver;
  566. JackLog("JackFreebobDriver::Attach fBufferSize %ld fSampleRate %ld\n", fEngineControl->fBufferSize, fEngineControl->fSampleRate);
  567. g_verbose = (fEngineControl->fVerbose ? 1 : 0);
  568. driver->device_options.verbose = (fEngineControl->fVerbose ? 1 : 0);
  569. /* packetizer thread options */
  570. driver->device_options.realtime = (fEngineControl->fRealTime ? 1 : 0);
  571. driver->device_options.packetizer_priority = fEngineControl->fPriority +
  572. FREEBOB_RT_PRIORITY_PACKETIZER_RELATIVE;
  573. if (driver->device_options.packetizer_priority > 98) {
  574. driver->device_options.packetizer_priority = 98;
  575. }
  576. // initialize the thread
  577. driver->dev = freebob_streaming_init(&driver->device_info, driver->device_options);
  578. if (!driver->dev) {
  579. printError("FREEBOB: Error creating virtual device");
  580. return -1;
  581. }
  582. #ifdef FREEBOB_DRIVER_WITH_MIDI
  583. driver->midi_handle = freebob_driver_midi_init(driver);
  584. if (!driver->midi_handle) {
  585. printError("-----------------------------------------------------------");
  586. printError("Error creating midi device!");
  587. printError("FreeBob will run without MIDI support.");
  588. printError("Consult the above error messages to solve the problem. ");
  589. printError("-----------------------------------------------------------\n\n");
  590. }
  591. #endif
  592. if (driver->device_options.realtime) {
  593. printMessage("Streaming thread running with Realtime scheduling, priority %d",
  594. driver->device_options.packetizer_priority);
  595. } else {
  596. printMessage("Streaming thread running without Realtime scheduling");
  597. }
  598. /* ports */
  599. // capture
  600. port_flags = JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal;
  601. driver->capture_nchannels = freebob_streaming_get_nb_capture_streams(driver->dev);
  602. driver->capture_nchannels_audio = 0;
  603. for (unsigned int i = 0; i < driver->capture_nchannels; i++) {
  604. freebob_streaming_get_capture_stream_name(driver->dev, i, portname, sizeof(portname) - 1);
  605. snprintf(buf, sizeof(buf) - 1, "%s:%s", fClientControl->fName, portname);
  606. if (freebob_streaming_get_capture_stream_type(driver->dev, i) != freebob_stream_type_audio) {
  607. printMessage ("Don't register capture port %s", buf);
  608. } else {
  609. printMessage ("Registering capture port %s", buf);
  610. if ((port_index = fGraphManager->AllocatePort(fClientControl->fRefNum, buf, (JackPortFlags)port_flags)) == NO_PORT) {
  611. jack_error("driver: cannot register port for %s", buf);
  612. return -1;
  613. }
  614. port = fGraphManager->GetPort(port_index);
  615. port->SetLatency(driver->period_size + driver->capture_frame_latency);
  616. fCapturePortList[i] = port_index;
  617. JackLog("JackAudioDriver::Attach fCapturePortList[i] %ld \n", port_index);
  618. driver->capture_nchannels_audio++;
  619. }
  620. }
  621. // playback
  622. port_flags = JackPortIsInput | JackPortIsPhysical | JackPortIsTerminal;
  623. driver->playback_nchannels = freebob_streaming_get_nb_playback_streams(driver->dev);
  624. driver->playback_nchannels_audio = 0;
  625. for (int i = 0; i < driver->playback_nchannels; i++) {
  626. freebob_streaming_get_playback_stream_name(driver->dev, i, portname, sizeof(portname) - 1);
  627. snprintf(buf, sizeof(buf) - 1, "%s:%s", fClientControl->fName, portname);
  628. if (freebob_streaming_get_playback_stream_type(driver->dev, i) != freebob_stream_type_audio) {
  629. printMessage ("Don't register playback port %s", buf);
  630. } else {
  631. printMessage ("Registering playback port %s", buf);
  632. if ((port_index = fGraphManager->AllocatePort(fClientControl->fRefNum, buf, (JackPortFlags)port_flags)) == NO_PORT) {
  633. jack_error("driver: cannot register port for %s", buf);
  634. return -1;
  635. }
  636. port = fGraphManager->GetPort(port_index);
  637. port->SetLatency((driver->period_size * (driver->device_options.nb_buffers - 1)) + driver->playback_frame_latency);
  638. fPlaybackPortList[i] = port_index;
  639. JackLog("JackAudioDriver::Attach fPlaybackPortList[i] %ld \n", port_index);
  640. driver->playback_nchannels_audio++;
  641. }
  642. }
  643. fCaptureChannels = driver->capture_nchannels_audio;
  644. fPlaybackChannels = driver->playback_nchannels_audio;
  645. assert(fCaptureChannels < PORT_NUM);
  646. assert(fPlaybackChannels < PORT_NUM);
  647. // this makes no sense...
  648. assert(fCaptureChannels + fPlaybackChannels > 0);
  649. return 0;
  650. }
  651. int JackFreebobDriver::Detach()
  652. {
  653. freebob_driver_t* driver = (freebob_driver_t*)fDriver;
  654. JackLog("JackFreebobDriver::Detach\n");
  655. // finish the libfreebob streaming
  656. freebob_streaming_finish(driver->dev);
  657. driver->dev = NULL;
  658. #ifdef FREEBOB_DRIVER_WITH_MIDI
  659. if (driver->midi_handle) {
  660. freebob_driver_midi_finish(driver->midi_handle);
  661. }
  662. driver->midi_handle = NULL;
  663. #endif
  664. // unregister the ports
  665. for (int i = 0; i < fCaptureChannels; i++) {
  666. fGraphManager->RemovePort(fClientControl->fRefNum, fCapturePortList[i]);
  667. }
  668. for (int i = 0; i < fPlaybackChannels; i++) {
  669. fGraphManager->RemovePort(fClientControl->fRefNum, fPlaybackPortList[i]);
  670. if (fWithMonitorPorts)
  671. fGraphManager->RemovePort(fClientControl->fRefNum, fMonitorPortList[i]);
  672. }
  673. return 0;
  674. }
  675. int JackFreebobDriver::Open(freebob_jack_settings_t *params)
  676. {
  677. // Generic JackAudioDriver Open
  678. if (JackAudioDriver::Open(
  679. params->period_size, params->sample_rate,
  680. params->playback_ports, params->playback_ports,
  681. 0, 0, 0, "", "",
  682. params->capture_frame_latency, params->playback_frame_latency) != 0) {
  683. return -1;
  684. }
  685. fDriver = (jack_driver_t *)freebob_driver_new ("freebob_pcm", params);
  686. if (fDriver) {
  687. // FreeBoB driver may have changed the in/out values
  688. fCaptureChannels = ((freebob_driver_t *)fDriver)->capture_nchannels_audio;
  689. fPlaybackChannels = ((freebob_driver_t *)fDriver)->playback_nchannels_audio;
  690. return 0;
  691. } else {
  692. return -1;
  693. }
  694. }
  695. int JackFreebobDriver::Close()
  696. {
  697. JackAudioDriver::Close();
  698. freebob_driver_delete((freebob_driver_t*)fDriver);
  699. return 0;
  700. }
  701. int JackFreebobDriver::Start()
  702. {
  703. return freebob_driver_start((freebob_driver_t *)fDriver);
  704. }
  705. int JackFreebobDriver::Stop()
  706. {
  707. return freebob_driver_stop((freebob_driver_t *)fDriver);
  708. }
  709. int JackFreebobDriver::Read()
  710. {
  711. printEnter();
  712. /* Taken from freebob_driver_run_cycle */
  713. freebob_driver_t* driver = (freebob_driver_t*)fDriver;
  714. int wait_status = 0;
  715. float delayed_usecs = 0.0;
  716. jack_nframes_t nframes = freebob_driver_wait (driver, -1, &wait_status,
  717. &delayed_usecs);
  718. if ((wait_status < 0)) {
  719. printError( "wait status < 0! (= %d)", wait_status);
  720. return -1;
  721. }
  722. if (nframes == 0) {
  723. /* we detected an xrun and restarted: notify
  724. * clients about the delay.
  725. */
  726. //engine->delay (engine, delayed_usecs);
  727. JackLog("FreeBoB XRun \n");
  728. //NotifyXRun(jack_get_microseconds());
  729. NotifyXRun(fLastWaitUst);
  730. //return 0;
  731. return -1;
  732. }
  733. //fLastWaitUst = GetMicroSeconds(); // Take callback date here
  734. if (nframes != fEngineControl->fBufferSize)
  735. JackLog("JackFreebobDriver::Read nframes = %ld\n", nframes);
  736. //return engine->run_cycle (engine, nframes, delayed_usecs);
  737. fDelayedUst = (jack_time_t)delayed_usecs;
  738. printExit();
  739. return freebob_driver_read((freebob_driver_t *)fDriver, fEngineControl->fBufferSize);
  740. }
  741. int JackFreebobDriver::Write()
  742. {
  743. printEnter();
  744. //JackLog("write\n");
  745. int res = freebob_driver_write((freebob_driver_t *)fDriver, fEngineControl->fBufferSize);
  746. jack_time_t write_time = GetMicroSeconds();
  747. /*
  748. if (write_time > (fLastWaitUst - fDelayedUst) + fEngineControl->fPeriodUsecs) {
  749. JackLog("FreeBoB write XRun \n");
  750. NotifyXRun(write_time);
  751. }
  752. */
  753. printExit();
  754. return res;
  755. }
  756. void
  757. JackFreebobDriver::jack_driver_init (jack_driver_t *driver)
  758. {
  759. memset (driver, 0, sizeof (*driver));
  760. driver->attach = 0;
  761. driver->detach = 0;
  762. driver->write = 0;
  763. driver->read = 0;
  764. driver->null_cycle = 0;
  765. driver->bufsize = 0;
  766. driver->start = 0;
  767. driver->stop = 0;
  768. }
  769. void
  770. JackFreebobDriver::jack_driver_nt_init (jack_driver_nt_t * driver)
  771. {
  772. memset (driver, 0, sizeof (*driver));
  773. jack_driver_init ((jack_driver_t *) driver);
  774. driver->attach = 0;
  775. driver->detach = 0;
  776. driver->bufsize = 0;
  777. driver->stop = 0;
  778. driver->start = 0;
  779. driver->nt_bufsize = 0;
  780. driver->nt_start = 0;
  781. driver->nt_stop = 0;
  782. driver->nt_attach = 0;
  783. driver->nt_detach = 0;
  784. driver->nt_run_cycle = 0;
  785. pthread_mutex_init (&driver->nt_run_lock, NULL);
  786. }
  787. void
  788. JackFreebobDriver::jack_driver_nt_finish(jack_driver_nt_t * driver)
  789. {
  790. pthread_mutex_destroy (&driver->nt_run_lock);
  791. }
  792. void JackFreebobDriver::PrintState()
  793. {
  794. std::cout << "JackFreebobDriver State" << std::endl;
  795. int port_index;
  796. std::cout << "Input ports" << std::endl;
  797. for (int i = 0; i < fPlaybackChannels; i++) {
  798. port_index = fCapturePortList[i];
  799. JackPort* port = fGraphManager->GetPort(port_index);
  800. std::cout << port->GetName() << std::endl;
  801. //if (fGraphManager->IsConnected(port_index)) {}
  802. if (fGraphManager->GetConnectionsNum(port_index)) {}
  803. }
  804. std::cout << "Output ports" << std::endl;
  805. for (int i = 0; i < fCaptureChannels; i++) {
  806. port_index = fPlaybackPortList[i];
  807. JackPort* port = fGraphManager->GetPort(port_index);
  808. std::cout << port->GetName() << std::endl;
  809. //if (fGraphManager->IsConnected(port_index)) {}
  810. if (fGraphManager->GetConnectionsNum(port_index)) {}
  811. }
  812. }
  813. /*
  814. JackDriver* DriverInit(JackGraphManager* manager)
  815. {
  816. return new JackFreebobDriver("ALSA", manager);
  817. }
  818. */
  819. } // end of namespace
  820. #ifdef __cplusplus
  821. extern "C"
  822. {
  823. #endif
  824. const jack_driver_desc_t *
  825. driver_get_descriptor () {
  826. jack_driver_desc_t * desc;
  827. jack_driver_param_desc_t * params;
  828. unsigned int i;
  829. desc = (jack_driver_desc_t *)calloc (1, sizeof (jack_driver_desc_t));
  830. strcpy (desc->name, "freebob");
  831. desc->nparams = 11;
  832. params = (jack_driver_param_desc_t *)calloc (desc->nparams, sizeof (jack_driver_param_desc_t));
  833. desc->params = params;
  834. i = 0;
  835. strcpy (params[i].name, "device");
  836. params[i].character = 'd';
  837. params[i].type = JackDriverParamString;
  838. strcpy (params[i].value.str, "hw:0");
  839. strcpy (params[i].short_desc, "The FireWire device to use. Format is: 'hw:port[,node]'.");
  840. strcpy (params[i].long_desc, params[i].short_desc);
  841. i++;
  842. strcpy (params[i].name, "period");
  843. params[i].character = 'p';
  844. params[i].type = JackDriverParamUInt;
  845. params[i].value.ui = 1024;
  846. strcpy (params[i].short_desc, "Frames per period");
  847. strcpy (params[i].long_desc, params[i].short_desc);
  848. i++;
  849. strcpy (params[i].name, "nperiods");
  850. params[i].character = 'n';
  851. params[i].type = JackDriverParamUInt;
  852. params[i].value.ui = 3;
  853. strcpy (params[i].short_desc, "Number of periods of playback latency");
  854. strcpy (params[i].long_desc, params[i].short_desc);
  855. i++;
  856. strcpy (params[i].name, "rate");
  857. params[i].character = 'r';
  858. params[i].type = JackDriverParamUInt;
  859. params[i].value.ui = 48000U;
  860. strcpy (params[i].short_desc, "Sample rate");
  861. strcpy (params[i].long_desc, params[i].short_desc);
  862. i++;
  863. strcpy (params[i].name, "capture");
  864. params[i].character = 'C';
  865. params[i].type = JackDriverParamBool;
  866. params[i].value.i = 0;
  867. strcpy (params[i].short_desc, "Provide capture ports.");
  868. strcpy (params[i].long_desc, params[i].short_desc);
  869. i++;
  870. strcpy (params[i].name, "playback");
  871. params[i].character = 'P';
  872. params[i].type = JackDriverParamBool;
  873. params[i].value.i = 0;
  874. strcpy (params[i].short_desc, "Provide playback ports.");
  875. strcpy (params[i].long_desc, params[i].short_desc);
  876. i++;
  877. strcpy (params[i].name, "duplex");
  878. params[i].character = 'D';
  879. params[i].type = JackDriverParamBool;
  880. params[i].value.i = 1;
  881. strcpy (params[i].short_desc, "Provide both capture and playback ports.");
  882. strcpy (params[i].long_desc, params[i].short_desc);
  883. i++;
  884. strcpy (params[i].name, "input-latency");
  885. params[i].character = 'I';
  886. params[i].type = JackDriverParamUInt;
  887. params[i].value.ui = 0;
  888. strcpy (params[i].short_desc, "Extra input latency (frames)");
  889. strcpy (params[i].long_desc, params[i].short_desc);
  890. i++;
  891. strcpy (params[i].name, "output-latency");
  892. params[i].character = 'O';
  893. params[i].type = JackDriverParamUInt;
  894. params[i].value.ui = 0;
  895. strcpy (params[i].short_desc, "Extra output latency (frames)");
  896. strcpy (params[i].long_desc, params[i].short_desc);
  897. i++;
  898. strcpy (params[i].name, "inchannels");
  899. params[i].character = 'i';
  900. params[i].type = JackDriverParamUInt;
  901. params[i].value.ui = 0;
  902. strcpy (params[i].short_desc, "Number of input channels to provide (note: currently ignored)");
  903. strcpy (params[i].long_desc, params[i].short_desc);
  904. i++;
  905. strcpy (params[i].name, "outchannels");
  906. params[i].character = 'o';
  907. params[i].type = JackDriverParamUInt;
  908. params[i].value.ui = 0;
  909. strcpy (params[i].short_desc, "Number of output channels to provide (note: currently ignored)");
  910. strcpy (params[i].long_desc, params[i].short_desc);
  911. return desc;
  912. }
  913. Jack::JackDriverClientInterface* driver_initialize(Jack::JackEngine* engine, Jack::JackSynchro** table, const JSList* params) {
  914. jack_driver_t *driver;
  915. unsigned int port = 0;
  916. unsigned int node_id = -1;
  917. int nbitems;
  918. const JSList * node;
  919. const jack_driver_param_t * param;
  920. freebob_jack_settings_t cmlparams;
  921. char *device_name = "hw:0";
  922. cmlparams.period_size_set = 0;
  923. cmlparams.sample_rate_set = 0;
  924. cmlparams.buffer_size_set = 0;
  925. cmlparams.port_set = 0;
  926. cmlparams.node_id_set = 0;
  927. /* default values */
  928. cmlparams.period_size = 1024;
  929. cmlparams.sample_rate = 48000;
  930. cmlparams.buffer_size = 3;
  931. cmlparams.port = 0;
  932. cmlparams.node_id = -1;
  933. cmlparams.playback_ports = 0;
  934. cmlparams.capture_ports = 0;
  935. cmlparams.playback_frame_latency = 0;
  936. cmlparams.capture_frame_latency = 0;
  937. for (node = params; node; node = jack_slist_next (node)) {
  938. param = (jack_driver_param_t *) node->data;
  939. switch (param->character) {
  940. case 'd':
  941. device_name = strdup (param->value.str);
  942. break;
  943. case 'p':
  944. cmlparams.period_size = param->value.ui;
  945. cmlparams.period_size_set = 1;
  946. break;
  947. case 'n':
  948. cmlparams.buffer_size = param->value.ui;
  949. cmlparams.buffer_size_set = 1;
  950. break;
  951. case 'r':
  952. cmlparams.sample_rate = param->value.ui;
  953. cmlparams.sample_rate_set = 1;
  954. break;
  955. case 'C':
  956. cmlparams.capture_ports = 1;
  957. break;
  958. case 'P':
  959. cmlparams.playback_ports = 1;
  960. break;
  961. case 'D':
  962. cmlparams.capture_ports = 1;
  963. cmlparams.playback_ports = 1;
  964. break;
  965. case 'I':
  966. cmlparams.capture_frame_latency = param->value.ui;
  967. break;
  968. case 'O':
  969. cmlparams.playback_frame_latency = param->value.ui;
  970. break;
  971. // ignore these for now
  972. case 'i':
  973. break;
  974. case 'o':
  975. break;
  976. }
  977. }
  978. /* duplex is the default */
  979. if (!cmlparams.playback_ports && !cmlparams.capture_ports) {
  980. cmlparams.playback_ports = TRUE;
  981. cmlparams.capture_ports = TRUE;
  982. }
  983. nbitems = sscanf(device_name, "hw:%u,%u", &port, &node_id);
  984. if (nbitems < 2) {
  985. nbitems = sscanf(device_name, "hw:%u", &port);
  986. if (nbitems < 1) {
  987. free(device_name);
  988. printError("device (-d) argument not valid\n");
  989. return NULL;
  990. } else {
  991. cmlparams.port = port;
  992. cmlparams.port_set = 1;
  993. cmlparams.node_id = -1;
  994. cmlparams.node_id_set = 0;
  995. }
  996. } else {
  997. cmlparams.port = port;
  998. cmlparams.port_set = 1;
  999. cmlparams.node_id = node_id;
  1000. cmlparams.node_id_set = 1;
  1001. }
  1002. jack_error("Freebob using Firewire port %d, node %d", cmlparams.port, cmlparams.node_id);
  1003. Jack::JackFreebobDriver* freebob_driver = new Jack::JackFreebobDriver("freebob_pcm", engine, table);
  1004. Jack::JackDriverClientInterface* threaded_driver = new Jack::JackThreadedDriver(freebob_driver);
  1005. // Special open for FreeBoB driver...
  1006. if (freebob_driver->Open(&cmlparams) == 0) {
  1007. return threaded_driver;
  1008. } else {
  1009. delete threaded_driver; // Delete the decorated driver
  1010. return NULL;
  1011. }
  1012. }
  1013. #ifdef __cplusplus
  1014. }
  1015. #endif