no more dither when converting from float to 24 bit values - i am not sure how this...
[jack.git] / libjack / driver.c
blob34db14a6f41a968167cdd56c81d12b6389a19a60
1 /* -*- mode: c; c-file-style: "linux"; -*- */
2 /*
3 Copyright (C) 2001-2003 Paul Davis
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 #include <config.h>
22 #include <stdio.h>
23 #include <string.h>
24 #include <stdarg.h>
25 #include <stdlib.h>
26 #include <stdio.h>
27 #include <errno.h>
29 #include <jack/internal.h>
30 #include <jack/driver.h>
31 #include <jack/engine.h>
32 #include <jack/thread.h>
34 #ifdef USE_MLOCK
35 #include <sys/mman.h>
36 #endif /* USE_MLOCK */
38 static int dummy_attach (jack_driver_t *drv, jack_engine_t *eng) { return 0; }
39 static int dummy_detach (jack_driver_t *drv, jack_engine_t *eng) { return 0; }
40 static int dummy_write (jack_driver_t *drv,
41 jack_nframes_t nframes) { return 0; }
42 static int dummy_read (jack_driver_t *drv, jack_nframes_t nframes) { return 0; }
43 static int dummy_null_cycle (jack_driver_t *drv,
44 jack_nframes_t nframes) { return 0; }
45 static int dummy_bufsize (jack_driver_t *drv,
46 jack_nframes_t nframes) {return 0;}
47 static int dummy_stop (jack_driver_t *drv) { return 0; }
48 static int dummy_start (jack_driver_t *drv) { return 0; }
50 void
51 jack_driver_init (jack_driver_t *driver)
53 memset (driver, 0, sizeof (*driver));
55 driver->attach = dummy_attach;
56 driver->detach = dummy_detach;
57 driver->write = dummy_write;
58 driver->read = dummy_read;
59 driver->null_cycle = dummy_null_cycle;
60 driver->bufsize = dummy_bufsize;
61 driver->start = dummy_start;
62 driver->stop = dummy_stop;
67 /****************************
68 *** Non-Threaded Drivers ***
69 ****************************/
71 static int dummy_nt_run_cycle (jack_driver_nt_t *drv) { return 0; }
72 static int dummy_nt_attach (jack_driver_nt_t *drv) { return 0; }
73 static int dummy_nt_detach (jack_driver_nt_t *drv) { return 0; }
77 * These are used in driver->nt_run for controlling whether or not
78 * driver->engine->driver_exit() gets called (EXIT = call it, PAUSE = don't)
80 #define DRIVER_NT_RUN 0
81 #define DRIVER_NT_EXIT 1
82 #define DRIVER_NT_PAUSE 2
83 #define DRIVER_NT_DYING 3
85 static int
86 jack_driver_nt_attach (jack_driver_nt_t * driver, jack_engine_t * engine)
88 driver->engine = engine;
89 return driver->nt_attach (driver);
92 static int
93 jack_driver_nt_detach (jack_driver_nt_t * driver, jack_engine_t * engine)
95 int ret;
97 ret = driver->nt_detach (driver);
98 driver->engine = NULL;
100 return ret;
103 static void *
104 jack_driver_nt_thread (void * arg)
106 jack_driver_nt_t * driver = (jack_driver_nt_t *) arg;
107 int rc = 0;
108 int run;
110 /* This thread may start running before pthread_create()
111 * actually stores the driver->nt_thread value. It's safer to
112 * store it here as well.
115 driver->nt_thread = pthread_self();
117 pthread_mutex_lock (&driver->nt_run_lock);
119 while ((run = driver->nt_run) == DRIVER_NT_RUN) {
120 pthread_mutex_unlock (&driver->nt_run_lock);
122 if ((rc = driver->nt_run_cycle (driver)) != 0) {
123 jack_error ("DRIVER NT: could not run driver cycle");
124 goto out;
127 pthread_mutex_lock (&driver->nt_run_lock);
130 pthread_mutex_unlock (&driver->nt_run_lock);
132 out:
133 if (rc) {
134 driver->nt_run = DRIVER_NT_DYING;
135 driver->engine->driver_exit (driver->engine);
137 pthread_exit (NULL);
140 static int
141 jack_driver_nt_start (jack_driver_nt_t * driver)
143 int err;
145 /* stop the new thread from really starting until the driver has
146 been started.
149 pthread_mutex_lock (&driver->nt_run_lock);
150 driver->nt_run = DRIVER_NT_RUN;
152 if ((err = jack_client_create_thread (NULL,
153 &driver->nt_thread,
154 driver->engine->rtpriority,
155 driver->engine->control->real_time,
156 jack_driver_nt_thread, driver)) != 0) {
157 jack_error ("DRIVER NT: could not start driver thread!");
158 return err;
161 if ((err = driver->nt_start (driver)) != 0) {
162 /* make the thread run and exit immediately */
163 driver->nt_run = DRIVER_NT_EXIT;
164 pthread_mutex_unlock (&driver->nt_run_lock);
165 jack_error ("DRIVER NT: could not start driver");
166 return err;
169 /* let the thread run, since the underlying "device" has now been started */
171 pthread_mutex_unlock (&driver->nt_run_lock);
173 return 0;
176 static int
177 jack_driver_nt_do_stop (jack_driver_nt_t * driver, int run)
179 int err;
181 pthread_mutex_lock (&driver->nt_run_lock);
182 if(driver->nt_run != DRIVER_NT_DYING) {
183 driver->nt_run = run;
185 pthread_mutex_unlock (&driver->nt_run_lock);
187 /* detect when called while the thread is shutting itself down */
188 if (driver->nt_thread && driver->nt_run != DRIVER_NT_DYING
189 && (err = pthread_join (driver->nt_thread, NULL)) != 0) {
190 jack_error ("DRIVER NT: error waiting for driver thread: %s",
191 strerror (err));
192 return err;
195 if ((err = driver->nt_stop (driver)) != 0) {
196 jack_error ("DRIVER NT: error stopping driver");
197 return err;
200 return 0;
203 static int
204 jack_driver_nt_stop (jack_driver_nt_t * driver)
206 return jack_driver_nt_do_stop (driver, DRIVER_NT_EXIT);
209 static int
210 jack_driver_nt_bufsize (jack_driver_nt_t * driver, jack_nframes_t nframes)
212 int err;
213 int ret;
215 err = jack_driver_nt_do_stop (driver, DRIVER_NT_PAUSE);
216 if (err) {
217 jack_error ("DRIVER NT: could not stop driver to change buffer size");
218 driver->engine->driver_exit (driver->engine);
219 return err;
222 ret = driver->nt_bufsize (driver, nframes);
224 err = jack_driver_nt_start (driver);
225 if (err) {
226 jack_error ("DRIVER NT: could not restart driver during buffer size change");
227 driver->engine->driver_exit (driver->engine);
228 return err;
231 return ret;
234 void
235 jack_driver_nt_init (jack_driver_nt_t * driver)
237 memset (driver, 0, sizeof (*driver));
239 jack_driver_init ((jack_driver_t *) driver);
241 driver->attach = (JackDriverAttachFunction) jack_driver_nt_attach;
242 driver->detach = (JackDriverDetachFunction) jack_driver_nt_detach;
243 driver->bufsize = (JackDriverBufSizeFunction) jack_driver_nt_bufsize;
244 driver->stop = (JackDriverStopFunction) jack_driver_nt_stop;
245 driver->start = (JackDriverStartFunction) jack_driver_nt_start;
247 driver->nt_bufsize = (JackDriverNTBufSizeFunction) dummy_bufsize;
248 driver->nt_start = (JackDriverNTStartFunction) dummy_start;
249 driver->nt_stop = (JackDriverNTStopFunction) dummy_stop;
250 driver->nt_attach = dummy_nt_attach;
251 driver->nt_detach = dummy_nt_detach;
252 driver->nt_run_cycle = dummy_nt_run_cycle;
255 pthread_mutex_init (&driver->nt_run_lock, NULL);
258 void
259 jack_driver_nt_finish (jack_driver_nt_t * driver)
261 pthread_mutex_destroy (&driver->nt_run_lock);