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.

259 lines
7.6KB

  1. /*
  2. Copyright (C) 2001 Paul Davis
  3. This program is free software; you can redistribute it and/or modify
  4. it under the terms of the GNU Lesser General Public License as published by
  5. the Free Software Foundation; either version 2.1 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU Lesser General Public License for more details.
  11. You should have received a copy of the GNU Lesser General Public License
  12. along with this program; if not, write to the Free Software
  13. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  14. $Id$
  15. */
  16. #include <string.h>
  17. #include <stdarg.h>
  18. #include <stdlib.h>
  19. #include <jack/driver.h>
  20. #include <jack/internal.h>
  21. #include <jack/error.h>
  22. static int dummy_attach (jack_driver_t *drv, jack_engine_t *eng) { return 0; }
  23. static int dummy_detach (jack_driver_t *drv, jack_engine_t *eng) { return 0; }
  24. static int dummy_wait (jack_driver_t *drv) { return 0; }
  25. static nframes_t dummy_frames_since_cycle_start (jack_driver_t *drv) { return 0; }
  26. static ClockSyncStatus dummy_clock_sync_status (jack_driver_t *drv, channel_t chn) { return ClockMaster; }
  27. static int dummy_audio_stop (jack_driver_t *drv) { return 0; }
  28. static int dummy_audio_start (jack_driver_t *drv) { return 0;; }
  29. static void dummy_set_hw_monitoring (jack_driver_t *drv, int yn) { return; }
  30. static int dummy_change_sample_clock (jack_driver_t *drv, SampleClockMode mode) { return 0; }
  31. static int dummy_reset_parameters (jack_driver_t *drv, nframes_t frames_per_cycle, nframes_t rate) { return 0; }
  32. static void dummy_mark_channel_silent (jack_driver_t *drv, unsigned long chn) { return; }
  33. static void dummy_request_monitor_input (jack_driver_t *drv, unsigned long chn, int yn) { return ; }
  34. static void dummy_request_all_monitor_input (jack_driver_t *drv, int yn) { return; }
  35. int
  36. jack_driver_monitoring_input (jack_driver_t *driver, channel_t chn)
  37. {
  38. return chn != NoChannel && (driver->all_monitor_in || (driver->input_monitor_mask & (1<<chn)));
  39. }
  40. void
  41. jack_driver_init (jack_driver_t *driver)
  42. {
  43. memset (driver, 0, sizeof (*driver));
  44. driver->input_monitor_mask = 0;
  45. driver->attach = dummy_attach;
  46. driver->detach = dummy_detach;
  47. driver->wait = dummy_wait;
  48. driver->frames_since_cycle_start = dummy_frames_since_cycle_start;
  49. driver->clock_sync_status = dummy_clock_sync_status;
  50. driver->audio_stop = dummy_audio_stop;
  51. driver->audio_start = dummy_audio_start;
  52. driver->set_hw_monitoring = dummy_set_hw_monitoring ;
  53. driver->change_sample_clock = dummy_change_sample_clock;
  54. driver->reset_parameters = dummy_reset_parameters;
  55. driver->mark_channel_silent = dummy_mark_channel_silent;
  56. driver->request_monitor_input = dummy_request_monitor_input;
  57. driver->request_all_monitor_input = dummy_request_all_monitor_input;
  58. driver->monitoring_input = jack_driver_monitoring_input;
  59. driver->engine = 0;
  60. pthread_mutex_init (&driver->clock_sync_lock, 0);
  61. driver->clock_sync_listeners = 0;
  62. pthread_mutex_init (&driver->input_monitor_lock, 0);
  63. driver->input_monitor_listeners = 0;
  64. }
  65. void
  66. jack_driver_release (jack_driver_t *driver)
  67. {
  68. GSList *node;
  69. for (node = driver->clock_sync_listeners; node; node = g_slist_next (node)) {
  70. free (node->data);
  71. }
  72. g_slist_free (driver->clock_sync_listeners);
  73. for (node = driver->input_monitor_listeners; node; node = g_slist_next (node)) {
  74. free (node->data);
  75. }
  76. g_slist_free (driver->input_monitor_listeners);
  77. }
  78. int
  79. jack_driver_listen_for_clock_sync_status (jack_driver_t *driver,
  80. ClockSyncListenerFunction func,
  81. void *arg)
  82. {
  83. ClockSyncListener *csl;
  84. csl = (ClockSyncListener *) malloc (sizeof (ClockSyncListener));
  85. csl->function = func;
  86. csl->arg = arg;
  87. csl->id = driver->next_clock_sync_listener_id++;
  88. pthread_mutex_lock (&driver->clock_sync_lock);
  89. driver->clock_sync_listeners = g_slist_prepend (driver->clock_sync_listeners, csl);
  90. pthread_mutex_unlock (&driver->clock_sync_lock);
  91. return csl->id;
  92. }
  93. int
  94. jack_driver_stop_listening_to_clock_sync_status (jack_driver_t *driver, int which)
  95. {
  96. GSList *node;
  97. int ret = -1;
  98. pthread_mutex_lock (&driver->clock_sync_lock);
  99. for (node = driver->clock_sync_listeners; node; node = g_slist_next (node)) {
  100. if (((ClockSyncListener *) node->data)->id == which) {
  101. driver->clock_sync_listeners = g_slist_remove_link (driver->clock_sync_listeners, node);
  102. free (node->data);
  103. g_slist_free_1 (node);
  104. ret = 0;
  105. break;
  106. }
  107. }
  108. pthread_mutex_unlock (&driver->clock_sync_lock);
  109. return ret;
  110. }
  111. int
  112. jack_driver_listen_for_input_monitor_status (jack_driver_t *driver,
  113. InputMonitorListenerFunction func,
  114. void *arg)
  115. {
  116. InputMonitorListener *iml;
  117. iml = (InputMonitorListener *) malloc (sizeof (InputMonitorListener));
  118. iml->function = func;
  119. iml->arg = arg;
  120. iml->id = driver->next_input_monitor_listener_id++;
  121. pthread_mutex_lock (&driver->input_monitor_lock);
  122. driver->input_monitor_listeners = g_slist_prepend (driver->input_monitor_listeners, iml);
  123. pthread_mutex_unlock (&driver->input_monitor_lock);
  124. return iml->id;
  125. }
  126. int
  127. jack_driver_stop_listening_to_input_monitor_status (jack_driver_t *driver, int which)
  128. {
  129. GSList *node;
  130. int ret = -1;
  131. pthread_mutex_lock (&driver->input_monitor_lock);
  132. for (node = driver->input_monitor_listeners; node; node = g_slist_next (node)) {
  133. if (((InputMonitorListener *) node->data)->id == which) {
  134. driver->input_monitor_listeners = g_slist_remove_link (driver->input_monitor_listeners, node);
  135. free (node->data);
  136. g_slist_free_1 (node);
  137. ret = 0;
  138. break;
  139. }
  140. }
  141. pthread_mutex_unlock (&driver->input_monitor_lock);
  142. return ret;
  143. }
  144. void jack_driver_clock_sync_notify (jack_driver_t *driver, channel_t chn, ClockSyncStatus status)
  145. {
  146. GSList *node;
  147. pthread_mutex_lock (&driver->input_monitor_lock);
  148. for (node = driver->input_monitor_listeners; node; node = g_slist_next (node)) {
  149. ClockSyncListener *csl = (ClockSyncListener *) node->data;
  150. csl->function (chn, status, csl->arg);
  151. }
  152. pthread_mutex_unlock (&driver->input_monitor_lock);
  153. }
  154. void jack_driver_input_monitor_notify (jack_driver_t *driver, channel_t chn, int status)
  155. {
  156. GSList *node;
  157. pthread_mutex_lock (&driver->input_monitor_lock);
  158. for (node = driver->input_monitor_listeners; node; node = g_slist_next (node)) {
  159. InputMonitorListener *iml = (InputMonitorListener *) node->data;
  160. iml->function (chn, status, iml->arg);
  161. }
  162. pthread_mutex_unlock (&driver->input_monitor_lock);
  163. }
  164. jack_driver_t *
  165. jack_driver_load (const char *path_to_so, ...)
  166. {
  167. va_list ap;
  168. const char *errstr;
  169. dlhandle handle;
  170. jack_driver_t *driver;
  171. jack_driver_t *(*initialize)(va_list);
  172. void (*finish)(jack_driver_t *);
  173. va_start (ap, path_to_so);
  174. handle = dlopen (path_to_so, RTLD_NOW|RTLD_GLOBAL);
  175. if (handle == 0) {
  176. if ((errstr = dlerror ()) != 0) {
  177. jack_error ("can't load \"%s\": %s", path_to_so, errstr);
  178. } else {
  179. jack_error ("bizarre error loading driver shared object %s", path_to_so);
  180. }
  181. va_end (ap);
  182. return 0;
  183. }
  184. initialize = dlsym (handle, "driver_initialize");
  185. if ((errstr = dlerror ()) != 0) {
  186. jack_error ("no initialize function in shared object %s\n", path_to_so);
  187. dlclose (handle);
  188. va_end (ap);
  189. return 0;
  190. }
  191. finish = dlsym (handle, "driver_finish");
  192. if ((errstr = dlerror ()) != 0) {
  193. jack_error ("no finish function in in shared driver object %s", path_to_so);
  194. dlclose (handle);
  195. va_end (ap);
  196. return 0;
  197. }
  198. if ((driver = initialize (ap)) != 0) {
  199. driver->handle = handle;
  200. driver->finish = finish;
  201. }
  202. va_end (ap);
  203. return driver;
  204. }
  205. void
  206. jack_driver_unload (jack_driver_t *driver)
  207. {
  208. driver->finish (driver);
  209. dlclose (driver->handle);
  210. }