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.

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