jack1 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.

526 lines
14KB

  1. /* -*- mode: c; c-file-style: "linux"; -*- */
  2. /*
  3. Copyright (C) 2003 Robert Ham <rah@bash.sh>
  4. Copyright (C) 2001 Paul Davis
  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 <math.h>
  18. #include <stdio.h>
  19. #include <memory.h>
  20. #include <unistd.h>
  21. #include <stdlib.h>
  22. #include <errno.h>
  23. #include <stdarg.h>
  24. #include <sys/mman.h>
  25. #include <jack/types.h>
  26. #include "internal.h"
  27. #include "engine.h"
  28. #include <sysdeps/time.h>
  29. #include "dummy_driver.h"
  30. #undef DEBUG_WAKEUP
  31. /* this is used for calculate what counts as an xrun */
  32. #define PRETEND_BUFFER_SIZE 4096
  33. void
  34. FakeVideoSync( dummy_driver_t *driver )
  35. {
  36. #define VIDEO_SYNC_PERIOD (48000 / 30)
  37. static int vidCounter = VIDEO_SYNC_PERIOD;
  38. int period = driver->period_size;
  39. jack_position_t *position = &driver->engine->control->current_time;
  40. if ( period >= VIDEO_SYNC_PERIOD ) {
  41. jack_error("JACK driver period size too large for simple video sync emulation. Halting.");
  42. exit(0);
  43. }
  44. //enable video sync, whether it occurs in this period or not
  45. position->audio_frames_per_video_frame = VIDEO_SYNC_PERIOD;
  46. position->valid = (jack_position_bits_t) (position->valid | JackAudioVideoRatio);
  47. //no video pulse found in this period, just decrement the counter
  48. if ( vidCounter > period ) {
  49. vidCounter -= period;
  50. }
  51. //video pulse occurs in this period
  52. if ( vidCounter <= period ) {
  53. int remainder = period - vidCounter;
  54. vidCounter = VIDEO_SYNC_PERIOD - remainder;
  55. position->video_offset = vidCounter;
  56. position->valid = (jack_position_bits_t) (position->valid | JackVideoFrameOffset);
  57. }
  58. }
  59. #ifdef HAVE_CLOCK_GETTIME
  60. static inline unsigned long long ts_to_nsec(struct timespec ts)
  61. {
  62. return ts.tv_sec * 1000000000LL + ts.tv_nsec;
  63. }
  64. static inline struct timespec nsec_to_ts(unsigned long long nsecs)
  65. {
  66. struct timespec ts;
  67. ts.tv_sec = nsecs / (1000000000LL);
  68. ts.tv_nsec = nsecs % (1000000000LL);
  69. return ts;
  70. }
  71. static inline struct timespec add_ts(struct timespec ts, unsigned int usecs)
  72. {
  73. unsigned long long nsecs = ts_to_nsec(ts);
  74. nsecs += usecs * 1000LL;
  75. return nsec_to_ts(nsecs);
  76. }
  77. static inline int cmp_lt_ts(struct timespec ts1, struct timespec ts2)
  78. {
  79. if(ts1.tv_sec < ts2.tv_sec) {
  80. return 1;
  81. } else if (ts1.tv_sec == ts2.tv_sec && ts1.tv_nsec < ts2.tv_nsec) {
  82. return 1;
  83. } else return 0;
  84. }
  85. static jack_nframes_t
  86. dummy_driver_wait (dummy_driver_t *driver, int extra_fd, int *status,
  87. float *delayed_usecs)
  88. {
  89. jack_nframes_t nframes = driver->period_size;
  90. struct timespec now;
  91. *status = 0;
  92. /* this driver doesn't work so well if we report a delay */
  93. *delayed_usecs = 0; /* lie about it */
  94. clock_gettime(CLOCK_REALTIME, &now);
  95. if (cmp_lt_ts(driver->next_wakeup, now)) {
  96. if (driver->next_wakeup.tv_sec == 0) {
  97. /* first time through */
  98. clock_gettime(CLOCK_REALTIME, &driver->next_wakeup);
  99. } else if ((ts_to_nsec(now) - ts_to_nsec(driver->next_wakeup))/1000LL
  100. > (PRETEND_BUFFER_SIZE * 1000000LL
  101. / driver->sample_rate)) {
  102. /* xrun */
  103. jack_error("**** dummy: xrun of %ju usec",
  104. (uintmax_t)(ts_to_nsec(now) - ts_to_nsec(driver->next_wakeup))/1000LL);
  105. nframes = 0;
  106. driver->next_wakeup.tv_sec = 0;
  107. } else {
  108. /* late, but handled by our "buffer"; try to
  109. * get back on track */
  110. }
  111. driver->next_wakeup = add_ts(driver->next_wakeup, driver->wait_time);
  112. } else {
  113. if(clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, &driver->next_wakeup, NULL)) {
  114. jack_error("error while sleeping");
  115. *status = -1;
  116. } else {
  117. clock_gettime(CLOCK_REALTIME, &now);
  118. // guaranteed to sleep long enough for this to be correct
  119. *delayed_usecs = (ts_to_nsec(now) - ts_to_nsec(driver->next_wakeup));
  120. *delayed_usecs /= 1000.0;
  121. }
  122. driver->next_wakeup = add_ts(driver->next_wakeup, driver->wait_time);
  123. }
  124. driver->last_wait_ust = driver->engine->get_microseconds ();
  125. driver->engine->transport_cycle_start (driver->engine,
  126. driver->last_wait_ust);
  127. return nframes;
  128. }
  129. static int dummy_driver_nt_start (dummy_driver_t *drv)
  130. {
  131. drv->next_wakeup.tv_sec = 0;
  132. return 0;
  133. }
  134. #else
  135. static jack_nframes_t
  136. dummy_driver_wait (dummy_driver_t *driver, int extra_fd, int *status,
  137. float *delayed_usecs)
  138. {
  139. jack_time_t now = driver->engine->get_microseconds();
  140. if (driver->next_time < now) {
  141. if (driver->next_time == 0) {
  142. /* first time through */
  143. driver->next_time = now + driver->wait_time;
  144. } else if (now - driver->next_time
  145. > (PRETEND_BUFFER_SIZE * 1000000LL
  146. / driver->sample_rate)) {
  147. /* xrun */
  148. jack_error("**** dummy: xrun of %ju usec",
  149. (uintmax_t)now - driver->next_time);
  150. driver->next_time = now + driver->wait_time;
  151. } else {
  152. /* late, but handled by our "buffer"; try to
  153. * get back on track */
  154. driver->next_time += driver->wait_time;
  155. }
  156. } else {
  157. jack_time_t wait = driver->next_time - now;
  158. struct timespec ts = { .tv_sec = wait / 1000000,
  159. .tv_nsec = (wait % 1000000) * 1000 };
  160. nanosleep(&ts,NULL);
  161. driver->next_time += driver->wait_time;
  162. }
  163. driver->last_wait_ust = driver->engine->get_microseconds ();
  164. driver->engine->transport_cycle_start (driver->engine,
  165. driver->last_wait_ust);
  166. /* this driver doesn't work so well if we report a delay */
  167. *delayed_usecs = 0; /* lie about it */
  168. *status = 0;
  169. return driver->period_size;
  170. }
  171. static int dummy_driver_nt_start (dummy_driver_t *drv)
  172. {
  173. drv->next_time = 0;
  174. return 0;
  175. }
  176. #endif
  177. static inline int
  178. dummy_driver_run_cycle (dummy_driver_t *driver)
  179. {
  180. jack_engine_t *engine = driver->engine;
  181. int wait_status;
  182. float delayed_usecs;
  183. jack_nframes_t nframes = dummy_driver_wait (driver, -1, &wait_status,
  184. &delayed_usecs);
  185. if (nframes == 0) {
  186. /* we detected an xrun and restarted: notify
  187. * clients about the delay. */
  188. engine->delay (engine, delayed_usecs);
  189. return 0;
  190. }
  191. // FakeVideoSync (driver);
  192. if (wait_status == 0)
  193. return engine->run_cycle (engine, nframes, delayed_usecs);
  194. if (wait_status < 0)
  195. return -1;
  196. else
  197. return 0;
  198. }
  199. static int
  200. dummy_driver_null_cycle (dummy_driver_t* driver, jack_nframes_t nframes)
  201. {
  202. return 0;
  203. }
  204. static int
  205. dummy_driver_bufsize (dummy_driver_t* driver, jack_nframes_t nframes)
  206. {
  207. driver->period_size = nframes;
  208. driver->period_usecs = driver->wait_time =
  209. (jack_time_t) floor ((((float) nframes) / driver->sample_rate)
  210. * 1000000.0f);
  211. /* tell the engine to change its buffer size */
  212. if (driver->engine->set_buffer_size (driver->engine, nframes)) {
  213. jack_error ("dummy: cannot set engine buffer size to %d (check MIDI)", nframes);
  214. return -1;
  215. }
  216. return 0;
  217. }
  218. static int
  219. dummy_driver_write (dummy_driver_t* driver, jack_nframes_t nframes)
  220. {
  221. return 0;
  222. }
  223. static int
  224. dummy_driver_attach (dummy_driver_t *driver)
  225. {
  226. jack_port_t * port;
  227. char buf[32];
  228. unsigned int chn;
  229. int port_flags;
  230. if (driver->engine->set_buffer_size (driver->engine, driver->period_size)) {
  231. jack_error ("dummy: cannot set engine buffer size to %d (check MIDI)", driver->period_size);
  232. return -1;
  233. }
  234. driver->engine->set_sample_rate (driver->engine, driver->sample_rate);
  235. port_flags = JackPortIsOutput|JackPortIsPhysical|JackPortIsTerminal;
  236. for (chn = 0; chn < driver->capture_channels; chn++)
  237. {
  238. snprintf (buf, sizeof(buf) - 1, "capture_%u", chn+1);
  239. port = jack_port_register (driver->client, buf,
  240. JACK_DEFAULT_AUDIO_TYPE,
  241. port_flags, 0);
  242. if (!port)
  243. {
  244. jack_error ("DUMMY: cannot register port for %s", buf);
  245. break;
  246. }
  247. driver->capture_ports =
  248. jack_slist_append (driver->capture_ports, port);
  249. }
  250. port_flags = JackPortIsInput|JackPortIsPhysical|JackPortIsTerminal;
  251. for (chn = 0; chn < driver->playback_channels; chn++)
  252. {
  253. snprintf (buf, sizeof(buf) - 1, "playback_%u", chn+1);
  254. port = jack_port_register (driver->client, buf,
  255. JACK_DEFAULT_AUDIO_TYPE,
  256. port_flags, 0);
  257. if (!port)
  258. {
  259. jack_error ("DUMMY: cannot register port for %s", buf);
  260. break;
  261. }
  262. driver->playback_ports =
  263. jack_slist_append (driver->playback_ports, port);
  264. }
  265. jack_activate (driver->client);
  266. return 0;
  267. }
  268. static int
  269. dummy_driver_detach (dummy_driver_t *driver)
  270. {
  271. JSList * node;
  272. if (driver->engine == 0)
  273. return 0;
  274. for (node = driver->capture_ports; node; node = jack_slist_next (node))
  275. jack_port_unregister (driver->client,
  276. ((jack_port_t *) node->data));
  277. jack_slist_free (driver->capture_ports);
  278. driver->capture_ports = NULL;
  279. for (node = driver->playback_ports; node; node = jack_slist_next (node))
  280. jack_port_unregister (driver->client,
  281. ((jack_port_t *) node->data));
  282. jack_slist_free (driver->playback_ports);
  283. driver->playback_ports = NULL;
  284. return 0;
  285. }
  286. static void
  287. dummy_driver_delete (dummy_driver_t *driver)
  288. {
  289. jack_driver_nt_finish ((jack_driver_nt_t *) driver);
  290. free (driver);
  291. }
  292. static jack_driver_t *
  293. dummy_driver_new (jack_client_t * client,
  294. char *name,
  295. unsigned int capture_ports,
  296. unsigned int playback_ports,
  297. jack_nframes_t sample_rate,
  298. jack_nframes_t period_size,
  299. unsigned long wait_time)
  300. {
  301. dummy_driver_t * driver;
  302. jack_info ("creating dummy driver ... %s|%" PRIu32 "|%" PRIu32
  303. "|%lu|%u|%u", name, sample_rate, period_size, wait_time,
  304. capture_ports, playback_ports);
  305. driver = (dummy_driver_t *) calloc (1, sizeof (dummy_driver_t));
  306. jack_driver_nt_init ((jack_driver_nt_t *) driver);
  307. driver->write = (JackDriverReadFunction) dummy_driver_write;
  308. driver->null_cycle = (JackDriverNullCycleFunction) dummy_driver_null_cycle;
  309. driver->nt_attach = (JackDriverNTAttachFunction) dummy_driver_attach;
  310. driver->nt_start = (JackDriverNTStartFunction) dummy_driver_nt_start;
  311. driver->nt_detach = (JackDriverNTDetachFunction) dummy_driver_detach;
  312. driver->nt_bufsize = (JackDriverNTBufSizeFunction) dummy_driver_bufsize;
  313. driver->nt_run_cycle = (JackDriverNTRunCycleFunction) dummy_driver_run_cycle;
  314. driver->period_usecs =
  315. (jack_time_t) floor ((((float) period_size) / sample_rate)
  316. * 1000000.0f);
  317. driver->sample_rate = sample_rate;
  318. driver->period_size = period_size;
  319. driver->wait_time = wait_time;
  320. //driver->next_time = 0; // not needed since calloc clears the memory
  321. driver->last_wait_ust = 0;
  322. driver->capture_channels = capture_ports;
  323. driver->capture_ports = NULL;
  324. driver->playback_channels = playback_ports;
  325. driver->playback_ports = NULL;
  326. driver->client = client;
  327. driver->engine = NULL;
  328. return (jack_driver_t *) driver;
  329. }
  330. /* DRIVER "PLUGIN" INTERFACE */
  331. jack_driver_desc_t *
  332. driver_get_descriptor ()
  333. {
  334. jack_driver_desc_t * desc;
  335. jack_driver_param_desc_t * params;
  336. unsigned int i;
  337. desc = calloc (1, sizeof (jack_driver_desc_t));
  338. strcpy (desc->name, "dummy");
  339. desc->nparams = 5;
  340. params = calloc (desc->nparams, sizeof (jack_driver_param_desc_t));
  341. i = 0;
  342. strcpy (params[i].name, "capture");
  343. params[i].character = 'C';
  344. params[i].type = JackDriverParamUInt;
  345. params[i].value.ui = 2U;
  346. strcpy (params[i].short_desc, "Number of capture ports");
  347. strcpy (params[i].long_desc, params[i].short_desc);
  348. i++;
  349. strcpy (params[i].name, "playback");
  350. params[i].character = 'P';
  351. params[i].type = JackDriverParamUInt;
  352. params[1].value.ui = 2U;
  353. strcpy (params[i].short_desc, "Number of playback ports");
  354. strcpy (params[i].long_desc, params[i].short_desc);
  355. i++;
  356. strcpy (params[i].name, "rate");
  357. params[i].character = 'r';
  358. params[i].type = JackDriverParamUInt;
  359. params[i].value.ui = 48000U;
  360. strcpy (params[i].short_desc, "Sample rate");
  361. strcpy (params[i].long_desc, params[i].short_desc);
  362. i++;
  363. strcpy (params[i].name, "period");
  364. params[i].character = 'p';
  365. params[i].type = JackDriverParamUInt;
  366. params[i].value.ui = 1024U;
  367. strcpy (params[i].short_desc, "Frames per period");
  368. strcpy (params[i].long_desc, params[i].short_desc);
  369. i++;
  370. strcpy (params[i].name, "wait");
  371. params[i].character = 'w';
  372. params[i].type = JackDriverParamUInt;
  373. params[i].value.ui = 21333U;
  374. strcpy (params[i].short_desc,
  375. "Number of usecs to wait between engine processes");
  376. strcpy (params[i].long_desc, params[i].short_desc);
  377. desc->params = params;
  378. return desc;
  379. }
  380. const char driver_client_name[] = "dummy_pcm";
  381. jack_driver_t *
  382. driver_initialize (jack_client_t *client, const JSList * params)
  383. {
  384. jack_nframes_t sample_rate = 48000;
  385. jack_nframes_t period_size = 1024;
  386. unsigned int capture_ports = 2;
  387. unsigned int playback_ports = 2;
  388. int wait_time_set = 0;
  389. unsigned long wait_time = 0;
  390. const JSList * node;
  391. const jack_driver_param_t * param;
  392. for (node = params; node; node = jack_slist_next (node)) {
  393. param = (const jack_driver_param_t *) node->data;
  394. switch (param->character) {
  395. case 'C':
  396. capture_ports = param->value.ui;
  397. break;
  398. case 'P':
  399. playback_ports = param->value.ui;
  400. break;
  401. case 'r':
  402. sample_rate = param->value.ui;
  403. break;
  404. case 'p':
  405. period_size = param->value.ui;
  406. break;
  407. case 'w':
  408. wait_time = param->value.ui;
  409. wait_time_set = 1;
  410. break;
  411. }
  412. }
  413. if (!wait_time_set)
  414. wait_time = (((float)period_size) / ((float)sample_rate)) * 1000000.0;
  415. return dummy_driver_new (client, "dummy_pcm", capture_ports,
  416. playback_ports, sample_rate, period_size,
  417. wait_time);
  418. }
  419. void
  420. driver_finish (jack_driver_t *driver)
  421. {
  422. dummy_driver_delete ((dummy_driver_t *) driver);
  423. }