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.

1166 lines
38KB

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