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.

239 lines
6.9KB

  1. #include <string.h>
  2. #include <stdarg.h>
  3. #include <stdlib.h>
  4. #include <jack/driver.h>
  5. #include <jack/internal.h>
  6. #include <jack/error.h>
  7. static int dummy_attach (jack_driver_t *drv, jack_engine_t *eng) { return 0; }
  8. static int dummy_detach (jack_driver_t *drv, jack_engine_t *eng) { return 0; }
  9. static int dummy_wait (jack_driver_t *drv) { return 0; }
  10. static nframes_t dummy_frames_since_cycle_start (jack_driver_t *drv) { return 0; }
  11. static ClockSyncStatus dummy_clock_sync_status (jack_driver_t *drv, channel_t chn) { return ClockMaster; }
  12. static int dummy_audio_stop (jack_driver_t *drv) { return 0; }
  13. static int dummy_audio_start (jack_driver_t *drv) { return 0;; }
  14. static void dummy_set_hw_monitoring (jack_driver_t *drv, int yn) { return; }
  15. static int dummy_change_sample_clock (jack_driver_t *drv, SampleClockMode mode) { return 0; }
  16. static int dummy_reset_parameters (jack_driver_t *drv, nframes_t frames_per_cycle, nframes_t rate) { return 0; }
  17. static void dummy_mark_channel_silent (jack_driver_t *drv, unsigned long chn) { return; }
  18. static void dummy_request_monitor_input (jack_driver_t *drv, unsigned long chn, int yn) { return ; }
  19. static void dummy_request_all_monitor_input (jack_driver_t *drv, int yn) { return; }
  20. int
  21. jack_driver_monitoring_input (jack_driver_t *driver, channel_t chn)
  22. {
  23. return chn != NoChannel && (driver->all_monitor_in || (driver->input_monitor_mask & (1<<chn)));
  24. }
  25. void
  26. jack_driver_init (jack_driver_t *driver)
  27. {
  28. memset (driver, 0, sizeof (*driver));
  29. driver->input_monitor_mask = 0;
  30. driver->attach = dummy_attach;
  31. driver->detach = dummy_detach;
  32. driver->wait = dummy_wait;
  33. driver->frames_since_cycle_start = dummy_frames_since_cycle_start;
  34. driver->clock_sync_status = dummy_clock_sync_status;
  35. driver->audio_stop = dummy_audio_stop;
  36. driver->audio_start = dummy_audio_start;
  37. driver->set_hw_monitoring = dummy_set_hw_monitoring ;
  38. driver->change_sample_clock = dummy_change_sample_clock;
  39. driver->reset_parameters = dummy_reset_parameters;
  40. driver->mark_channel_silent = dummy_mark_channel_silent;
  41. driver->request_monitor_input = dummy_request_monitor_input;
  42. driver->request_all_monitor_input = dummy_request_all_monitor_input;
  43. driver->monitoring_input = jack_driver_monitoring_input;
  44. driver->engine = 0;
  45. pthread_mutex_init (&driver->clock_sync_lock, 0);
  46. driver->clock_sync_listeners = 0;
  47. pthread_mutex_init (&driver->input_monitor_lock, 0);
  48. driver->input_monitor_listeners = 0;
  49. }
  50. void
  51. jack_driver_release (jack_driver_t *driver)
  52. {
  53. GSList *node;
  54. for (node = driver->clock_sync_listeners; node; node = g_slist_next (node)) {
  55. free (node->data);
  56. }
  57. g_slist_free (driver->clock_sync_listeners);
  58. for (node = driver->input_monitor_listeners; node; node = g_slist_next (node)) {
  59. free (node->data);
  60. }
  61. g_slist_free (driver->input_monitor_listeners);
  62. }
  63. int
  64. jack_driver_listen_for_clock_sync_status (jack_driver_t *driver,
  65. ClockSyncListenerFunction func,
  66. void *arg)
  67. {
  68. ClockSyncListener *csl;
  69. csl = (ClockSyncListener *) malloc (sizeof (ClockSyncListener));
  70. csl->function = func;
  71. csl->arg = arg;
  72. csl->id = driver->next_clock_sync_listener_id++;
  73. pthread_mutex_lock (&driver->clock_sync_lock);
  74. driver->clock_sync_listeners = g_slist_prepend (driver->clock_sync_listeners, csl);
  75. pthread_mutex_unlock (&driver->clock_sync_lock);
  76. return csl->id;
  77. }
  78. int
  79. jack_driver_stop_listening_to_clock_sync_status (jack_driver_t *driver, int which)
  80. {
  81. GSList *node;
  82. int ret = -1;
  83. pthread_mutex_lock (&driver->clock_sync_lock);
  84. for (node = driver->clock_sync_listeners; node; node = g_slist_next (node)) {
  85. if (((ClockSyncListener *) node->data)->id == which) {
  86. driver->clock_sync_listeners = g_slist_remove_link (driver->clock_sync_listeners, node);
  87. free (node->data);
  88. g_slist_free_1 (node);
  89. ret = 0;
  90. break;
  91. }
  92. }
  93. pthread_mutex_unlock (&driver->clock_sync_lock);
  94. return ret;
  95. }
  96. int
  97. jack_driver_listen_for_input_monitor_status (jack_driver_t *driver,
  98. InputMonitorListenerFunction func,
  99. void *arg)
  100. {
  101. InputMonitorListener *iml;
  102. iml = (InputMonitorListener *) malloc (sizeof (InputMonitorListener));
  103. iml->function = func;
  104. iml->arg = arg;
  105. iml->id = driver->next_input_monitor_listener_id++;
  106. pthread_mutex_lock (&driver->input_monitor_lock);
  107. driver->input_monitor_listeners = g_slist_prepend (driver->input_monitor_listeners, iml);
  108. pthread_mutex_unlock (&driver->input_monitor_lock);
  109. return iml->id;
  110. }
  111. int
  112. jack_driver_stop_listening_to_input_monitor_status (jack_driver_t *driver, int which)
  113. {
  114. GSList *node;
  115. int ret = -1;
  116. pthread_mutex_lock (&driver->input_monitor_lock);
  117. for (node = driver->input_monitor_listeners; node; node = g_slist_next (node)) {
  118. if (((InputMonitorListener *) node->data)->id == which) {
  119. driver->input_monitor_listeners = g_slist_remove_link (driver->input_monitor_listeners, node);
  120. free (node->data);
  121. g_slist_free_1 (node);
  122. ret = 0;
  123. break;
  124. }
  125. }
  126. pthread_mutex_unlock (&driver->input_monitor_lock);
  127. return ret;
  128. }
  129. void jack_driver_clock_sync_notify (jack_driver_t *driver, channel_t chn, ClockSyncStatus status)
  130. {
  131. GSList *node;
  132. pthread_mutex_lock (&driver->input_monitor_lock);
  133. for (node = driver->input_monitor_listeners; node; node = g_slist_next (node)) {
  134. ClockSyncListener *csl = (ClockSyncListener *) node->data;
  135. csl->function (chn, status, csl->arg);
  136. }
  137. pthread_mutex_unlock (&driver->input_monitor_lock);
  138. }
  139. void jack_driver_input_monitor_notify (jack_driver_t *driver, channel_t chn, int status)
  140. {
  141. GSList *node;
  142. pthread_mutex_lock (&driver->input_monitor_lock);
  143. for (node = driver->input_monitor_listeners; node; node = g_slist_next (node)) {
  144. InputMonitorListener *iml = (InputMonitorListener *) node->data;
  145. iml->function (chn, status, iml->arg);
  146. }
  147. pthread_mutex_unlock (&driver->input_monitor_lock);
  148. }
  149. jack_driver_t *
  150. jack_driver_load (const char *path_to_so, ...)
  151. {
  152. va_list ap;
  153. const char *errstr;
  154. dlhandle handle;
  155. jack_driver_t *driver;
  156. jack_driver_t *(*initialize)(va_list);
  157. void (*finish)(jack_driver_t *);
  158. va_start (ap, path_to_so);
  159. handle = dlopen (path_to_so, RTLD_NOW|RTLD_GLOBAL);
  160. if (handle == 0) {
  161. if ((errstr = dlerror ()) != 0) {
  162. jack_error ("can't load \"%s\": %s", path_to_so, errstr);
  163. } else {
  164. jack_error ("bizarre error loading driver shared object %s", path_to_so);
  165. }
  166. va_end (ap);
  167. return 0;
  168. }
  169. initialize = dlsym (handle, "driver_initialize");
  170. if ((errstr = dlerror ()) != 0) {
  171. jack_error ("no initialize function in shared object %s\n", path_to_so);
  172. dlclose (handle);
  173. va_end (ap);
  174. return 0;
  175. }
  176. finish = dlsym (handle, "driver_finish");
  177. if ((errstr = dlerror ()) != 0) {
  178. jack_error ("no finish function in in shared driver object %s", path_to_so);
  179. dlclose (handle);
  180. va_end (ap);
  181. return 0;
  182. }
  183. if ((driver = initialize (ap)) != 0) {
  184. driver->handle = handle;
  185. driver->finish = finish;
  186. }
  187. va_end (ap);
  188. return driver;
  189. }
  190. void
  191. jack_driver_unload (jack_driver_t *driver)
  192. {
  193. driver->finish (driver);
  194. dlclose (driver->handle);
  195. }