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.

532 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. #if HAVE_CLOCK_GETTIME && HAVE_CLOCK_NANOSLEEP
  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. struct timespec ts;
  92. *status = 0;
  93. /* this driver doesn't work so well if we report a delay */
  94. *delayed_usecs = 0; /* lie about it */
  95. clock_gettime (CLOCK_REALTIME, &now);
  96. if (cmp_lt_ts (driver->next_wakeup, now)) {
  97. if (driver->next_wakeup.tv_sec == 0) {
  98. /* first time through */
  99. clock_gettime (CLOCK_REALTIME, &driver->next_wakeup);
  100. } else if ((ts_to_nsec (now) - ts_to_nsec (driver->next_wakeup)) / 1000LL
  101. > (PRETEND_BUFFER_SIZE * 1000000LL
  102. / driver->sample_rate)) {
  103. /* xrun */
  104. jack_error ("**** dummy: xrun of %ju usec",
  105. (uintmax_t)(ts_to_nsec (now) - ts_to_nsec (driver->next_wakeup)) / 1000LL);
  106. nframes = 0;
  107. driver->next_wakeup.tv_sec = 0;
  108. } else {
  109. /* late, but handled by our "buffer"; try to
  110. * get back on track */
  111. }
  112. driver->next_wakeup = add_ts (driver->next_wakeup, driver->wait_time);
  113. } else {
  114. ts.tv_sec = 0;
  115. ts.tv_nsec = ts_to_nsec(driver->next_wakeup) - ts_to_nsec(now);
  116. if (nanosleep (&ts, NULL)) {
  117. jack_error ("error while sleeping");
  118. *status = -1;
  119. } else {
  120. clock_gettime (CLOCK_REALTIME, &now);
  121. // guaranteed to sleep long enough for this to be correct
  122. *delayed_usecs = (ts_to_nsec (now) - ts_to_nsec (driver->next_wakeup));
  123. *delayed_usecs /= 1000.0;
  124. }
  125. driver->next_wakeup = add_ts (driver->next_wakeup, driver->wait_time);
  126. }
  127. driver->last_wait_ust = driver->engine->get_microseconds ();
  128. driver->engine->transport_cycle_start (driver->engine,
  129. driver->last_wait_ust);
  130. return nframes;
  131. }
  132. static int dummy_driver_nt_start (dummy_driver_t *drv)
  133. {
  134. drv->next_wakeup.tv_sec = 0;
  135. return 0;
  136. }
  137. #else
  138. static jack_nframes_t
  139. dummy_driver_wait (dummy_driver_t *driver, int extra_fd, int *status,
  140. float *delayed_usecs)
  141. {
  142. jack_time_t now = driver->engine->get_microseconds ();
  143. if (driver->next_time < now) {
  144. if (driver->next_time == 0) {
  145. /* first time through */
  146. driver->next_time = now + driver->wait_time;
  147. } else if (now - driver->next_time
  148. > (PRETEND_BUFFER_SIZE * 1000000LL
  149. / driver->sample_rate)) {
  150. /* xrun */
  151. jack_error ("**** dummy: xrun of %ju usec",
  152. (uintmax_t)now - driver->next_time);
  153. driver->next_time = now + driver->wait_time;
  154. } else {
  155. /* late, but handled by our "buffer"; try to
  156. * get back on track */
  157. driver->next_time += driver->wait_time;
  158. }
  159. } else {
  160. jack_time_t wait = driver->next_time - now;
  161. struct timespec ts = { .tv_sec = wait / 1000000,
  162. .tv_nsec = (wait % 1000000) * 1000 };
  163. nanosleep (&ts, NULL);
  164. driver->next_time += driver->wait_time;
  165. }
  166. driver->last_wait_ust = driver->engine->get_microseconds ();
  167. driver->engine->transport_cycle_start (driver->engine,
  168. driver->last_wait_ust);
  169. /* this driver doesn't work so well if we report a delay */
  170. *delayed_usecs = 0; /* lie about it */
  171. *status = 0;
  172. return driver->period_size;
  173. }
  174. static int dummy_driver_nt_start (dummy_driver_t *drv)
  175. {
  176. drv->next_time = 0;
  177. return 0;
  178. }
  179. #endif
  180. static inline int
  181. dummy_driver_run_cycle (dummy_driver_t *driver)
  182. {
  183. jack_engine_t *engine = driver->engine;
  184. int wait_status;
  185. float delayed_usecs;
  186. jack_nframes_t nframes = dummy_driver_wait (driver, -1, &wait_status,
  187. &delayed_usecs);
  188. if (nframes == 0) {
  189. /* we detected an xrun and restarted: notify
  190. * clients about the delay. */
  191. engine->delay (engine, delayed_usecs);
  192. return 0;
  193. }
  194. // FakeVideoSync (driver);
  195. if (wait_status == 0) {
  196. return engine->run_cycle (engine, nframes, delayed_usecs);
  197. }
  198. if (wait_status < 0) {
  199. return -1;
  200. } else {
  201. return 0;
  202. }
  203. }
  204. static int
  205. dummy_driver_null_cycle (dummy_driver_t* driver, jack_nframes_t nframes)
  206. {
  207. return 0;
  208. }
  209. static int
  210. dummy_driver_bufsize (dummy_driver_t* driver, jack_nframes_t nframes)
  211. {
  212. driver->period_size = nframes;
  213. driver->period_usecs = driver->wait_time =
  214. (jack_time_t)floor ((((float)nframes) / driver->sample_rate)
  215. * 1000000.0f);
  216. /* tell the engine to change its buffer size */
  217. if (driver->engine->set_buffer_size (driver->engine, nframes)) {
  218. jack_error ("dummy: cannot set engine buffer size to %d (check MIDI)", nframes);
  219. return -1;
  220. }
  221. return 0;
  222. }
  223. static int
  224. dummy_driver_write (dummy_driver_t* driver, jack_nframes_t nframes)
  225. {
  226. return 0;
  227. }
  228. static int
  229. dummy_driver_attach (dummy_driver_t *driver)
  230. {
  231. jack_port_t * port;
  232. char buf[32];
  233. unsigned int chn;
  234. int port_flags;
  235. if (driver->engine->set_buffer_size (driver->engine, driver->period_size)) {
  236. jack_error ("dummy: cannot set engine buffer size to %d (check MIDI)", driver->period_size);
  237. return -1;
  238. }
  239. driver->engine->set_sample_rate (driver->engine, driver->sample_rate);
  240. port_flags = JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal;
  241. for (chn = 0; chn < driver->capture_channels; chn++) {
  242. snprintf (buf, sizeof(buf) - 1, "capture_%u", chn + 1);
  243. port = jack_port_register (driver->client, buf,
  244. JACK_DEFAULT_AUDIO_TYPE,
  245. port_flags, 0);
  246. if (!port) {
  247. jack_error ("DUMMY: cannot register port for %s", buf);
  248. break;
  249. }
  250. driver->capture_ports =
  251. jack_slist_append (driver->capture_ports, port);
  252. }
  253. port_flags = JackPortIsInput | JackPortIsPhysical | JackPortIsTerminal;
  254. for (chn = 0; chn < driver->playback_channels; chn++) {
  255. snprintf (buf, sizeof(buf) - 1, "playback_%u", chn + 1);
  256. port = jack_port_register (driver->client, buf,
  257. JACK_DEFAULT_AUDIO_TYPE,
  258. port_flags, 0);
  259. if (!port) {
  260. jack_error ("DUMMY: cannot register port for %s", buf);
  261. break;
  262. }
  263. driver->playback_ports =
  264. jack_slist_append (driver->playback_ports, port);
  265. }
  266. jack_activate (driver->client);
  267. return 0;
  268. }
  269. static int
  270. dummy_driver_detach (dummy_driver_t *driver)
  271. {
  272. JSList * node;
  273. if (driver->engine == 0) {
  274. return 0;
  275. }
  276. for (node = driver->capture_ports; node; node = jack_slist_next (node))
  277. jack_port_unregister (driver->client,
  278. ((jack_port_t*)node->data));
  279. jack_slist_free (driver->capture_ports);
  280. driver->capture_ports = NULL;
  281. for (node = driver->playback_ports; node; node = jack_slist_next (node))
  282. jack_port_unregister (driver->client,
  283. ((jack_port_t*)node->data));
  284. jack_slist_free (driver->playback_ports);
  285. driver->playback_ports = NULL;
  286. return 0;
  287. }
  288. static void
  289. dummy_driver_delete (dummy_driver_t *driver)
  290. {
  291. jack_driver_nt_finish ((jack_driver_nt_t*)driver);
  292. free (driver);
  293. }
  294. static jack_driver_t *
  295. dummy_driver_new (jack_client_t * client,
  296. char *name,
  297. unsigned int capture_ports,
  298. unsigned int playback_ports,
  299. jack_nframes_t sample_rate,
  300. jack_nframes_t period_size,
  301. unsigned long wait_time)
  302. {
  303. dummy_driver_t * driver;
  304. jack_info ("creating dummy driver ... %s|%" PRIu32 "|%" PRIu32
  305. "|%lu|%u|%u", name, sample_rate, period_size, wait_time,
  306. capture_ports, playback_ports);
  307. driver = (dummy_driver_t*)calloc (1, sizeof(dummy_driver_t));
  308. jack_driver_nt_init ((jack_driver_nt_t*)driver);
  309. driver->write = (JackDriverReadFunction)dummy_driver_write;
  310. driver->null_cycle = (JackDriverNullCycleFunction)dummy_driver_null_cycle;
  311. driver->nt_attach = (JackDriverNTAttachFunction)dummy_driver_attach;
  312. driver->nt_start = (JackDriverNTStartFunction)dummy_driver_nt_start;
  313. driver->nt_detach = (JackDriverNTDetachFunction)dummy_driver_detach;
  314. driver->nt_bufsize = (JackDriverNTBufSizeFunction)dummy_driver_bufsize;
  315. driver->nt_run_cycle = (JackDriverNTRunCycleFunction)dummy_driver_run_cycle;
  316. driver->period_usecs =
  317. (jack_time_t)floor ((((float)period_size) / sample_rate)
  318. * 1000000.0f);
  319. driver->sample_rate = sample_rate;
  320. driver->period_size = period_size;
  321. driver->wait_time = wait_time;
  322. //driver->next_time = 0; // not needed since calloc clears the memory
  323. driver->last_wait_ust = 0;
  324. driver->capture_channels = capture_ports;
  325. driver->capture_ports = NULL;
  326. driver->playback_channels = playback_ports;
  327. driver->playback_ports = NULL;
  328. driver->client = client;
  329. driver->engine = NULL;
  330. return (jack_driver_t*)driver;
  331. }
  332. /* DRIVER "PLUGIN" INTERFACE */
  333. jack_driver_desc_t *
  334. driver_get_descriptor ()
  335. {
  336. jack_driver_desc_t * desc;
  337. jack_driver_param_desc_t * params;
  338. unsigned int i;
  339. desc = calloc (1, sizeof(jack_driver_desc_t));
  340. strcpy (desc->name, "dummy");
  341. desc->nparams = 5;
  342. params = calloc (desc->nparams, sizeof(jack_driver_param_desc_t));
  343. i = 0;
  344. strcpy (params[i].name, "capture");
  345. params[i].character = 'C';
  346. params[i].type = JackDriverParamUInt;
  347. params[i].value.ui = 2U;
  348. strcpy (params[i].short_desc, "Number of capture ports");
  349. strcpy (params[i].long_desc, params[i].short_desc);
  350. i++;
  351. strcpy (params[i].name, "playback");
  352. params[i].character = 'P';
  353. params[i].type = JackDriverParamUInt;
  354. params[1].value.ui = 2U;
  355. strcpy (params[i].short_desc, "Number of playback ports");
  356. strcpy (params[i].long_desc, params[i].short_desc);
  357. i++;
  358. strcpy (params[i].name, "rate");
  359. params[i].character = 'r';
  360. params[i].type = JackDriverParamUInt;
  361. params[i].value.ui = 48000U;
  362. strcpy (params[i].short_desc, "Sample rate");
  363. strcpy (params[i].long_desc, params[i].short_desc);
  364. i++;
  365. strcpy (params[i].name, "period");
  366. params[i].character = 'p';
  367. params[i].type = JackDriverParamUInt;
  368. params[i].value.ui = 1024U;
  369. strcpy (params[i].short_desc, "Frames per period");
  370. strcpy (params[i].long_desc, params[i].short_desc);
  371. i++;
  372. strcpy (params[i].name, "wait");
  373. params[i].character = 'w';
  374. params[i].type = JackDriverParamUInt;
  375. params[i].value.ui = 21333U;
  376. strcpy (params[i].short_desc,
  377. "Number of usecs to wait between engine processes");
  378. strcpy (params[i].long_desc, params[i].short_desc);
  379. desc->params = params;
  380. return desc;
  381. }
  382. const char driver_client_name[] = "dummy_pcm";
  383. jack_driver_t *
  384. driver_initialize (jack_client_t *client, const JSList * params)
  385. {
  386. jack_nframes_t sample_rate = 48000;
  387. jack_nframes_t period_size = 1024;
  388. unsigned int capture_ports = 2;
  389. unsigned int playback_ports = 2;
  390. int wait_time_set = 0;
  391. unsigned long wait_time = 0;
  392. const JSList * node;
  393. const jack_driver_param_t * param;
  394. for (node = params; node; node = jack_slist_next (node)) {
  395. param = (const jack_driver_param_t*)node->data;
  396. switch (param->character) {
  397. case 'C':
  398. capture_ports = param->value.ui;
  399. break;
  400. case 'P':
  401. playback_ports = param->value.ui;
  402. break;
  403. case 'r':
  404. sample_rate = param->value.ui;
  405. break;
  406. case 'p':
  407. period_size = param->value.ui;
  408. break;
  409. case 'w':
  410. wait_time = param->value.ui;
  411. wait_time_set = 1;
  412. break;
  413. }
  414. }
  415. if (!wait_time_set) {
  416. wait_time = (((float)period_size) / ((float)sample_rate)) * 1000000.0;
  417. }
  418. return dummy_driver_new (client, "dummy_pcm", capture_ports,
  419. playback_ports, sample_rate, period_size,
  420. wait_time);
  421. }
  422. void
  423. driver_finish (jack_driver_t *driver)
  424. {
  425. dummy_driver_delete ((dummy_driver_t*)driver);
  426. }