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.

506 lines
13KB

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