stop & detach driver when exiting due to -T/--temporary flag
[jack.git] / jack / driver.h
blobec1eea9ae26b8c4db8daf00fd53888b954e63c33
1 /*
2 Copyright (C) 2001 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (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.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #ifndef __jack_driver_h__
21 #define __jack_driver_h__
23 #include <pthread.h>
24 #include <jack/types.h>
25 #include <jack/port.h>
26 #include <jack/driver_interface.h>
28 typedef float gain_t;
29 typedef unsigned long channel_t;
31 typedef enum {
32 Lock = 0x1,
33 NoLock = 0x2,
34 Sync = 0x4,
35 NoSync = 0x8
36 } ClockSyncStatus;
38 typedef void (*ClockSyncListenerFunction)(channel_t,ClockSyncStatus,void*);
40 typedef struct {
41 unsigned long id;
42 ClockSyncListenerFunction function;
43 void *arg;
44 } ClockSyncListener;
46 struct _jack_engine;
47 struct _jack_driver;
49 typedef int (*JackDriverAttachFunction)(struct _jack_driver *,
50 struct _jack_engine *);
51 typedef int (*JackDriverDetachFunction)(struct _jack_driver *,
52 struct _jack_engine *);
53 typedef int (*JackDriverReadFunction)(struct _jack_driver *,
54 jack_nframes_t nframes);
55 typedef int (*JackDriverWriteFunction)(struct _jack_driver *,
56 jack_nframes_t nframes);
57 typedef int (*JackDriverNullCycleFunction)(struct _jack_driver *,
58 jack_nframes_t nframes);
59 typedef int (*JackDriverStopFunction)(struct _jack_driver *);
60 typedef int (*JackDriverStartFunction)(struct _jack_driver *);
61 typedef int (*JackDriverBufSizeFunction)(struct _jack_driver *,
62 jack_nframes_t nframes);
63 /*
64 Call sequence summary:
66 1) engine loads driver via runtime dynamic linking
67 - calls jack_driver_load
68 - we call dlsym for "driver_initialize" and execute it
69 2) engine attaches to driver
70 3) engine starts driver
71 4) driver runs its own thread, calling
72 while () {
73 driver->wait ();
74 driver->engine->run_cycle ()
76 5) engine stops driver
77 6) engine detaches from driver
78 7) engine calls driver `finish' routine
80 Note that stop/start may be called multiple times in the event of an
81 error return from the `wait' function.
84 typedef struct _jack_driver {
86 /* The _jack_driver structure fields are included at the beginning of
87 each driver-specific structure using the JACK_DRIVER_DECL macro,
88 which is defined below. The comments that follow describe each
89 common field.
91 The driver should set this to be the interval it expects to elapse
92 between returning from the `wait' function. if set to zero, it
93 implies that the driver does not expect regular periodic wakeups.
95 jack_time_t period_usecs;
98 The driver should set this within its "wait" function to indicate
99 the UST of the most recent determination that the engine cycle
100 should run. it should not be set if the "extra_fd" argument of
101 the wait function is set to a non-zero value.
103 jack_time_t last_wait_ust;
106 These are not used by the driver. They should not be written to or
107 modified in any way
109 void *handle;
110 struct _jack_internal_client *internal_client;
112 This should perform any cleanup associated with the driver. it will
113 be called when jack server process decides to get rid of the
114 driver. in some systems, it may not be called at all, so the driver
115 should never rely on a call to this. it can set it to NULL if
116 it has nothing do do.
118 void (*finish)(struct _jack_driver *);
121 The JACK engine will call this when it wishes to attach itself to
122 the driver. the engine will pass a pointer to itself, which the driver
123 may use in anyway it wishes to. the driver may assume that this
124 is the same engine object that will make `wait' calls until a
125 `detach' call is made.
127 JackDriverAttachFunction attach;
130 The JACK engine will call this when it is finished using a driver.
132 JackDriverDetachFunction detach;
135 The JACK engine will call this when it wants to wait until the
136 driver decides that its time to process some data. the driver returns
137 a count of the number of audioframes that can be processed.
139 it should set the variable pointed to by `status' as follows:
141 zero: the wait completed normally, processing may begin
142 negative: the wait failed, and recovery is not possible
143 positive: the wait failed, and the driver stopped itself.
144 a call to `start' will return the driver to
145 a correct and known state.
147 the driver should also fill out the `delayed_usecs' variable to
148 indicate any delay in its expected periodic execution. for example,
149 if it discovers that its return from poll(2) is later than it
150 expects it to be, it would place an estimate of the delay
151 in this variable. the engine will use this to decide if it
152 plans to continue execution.
154 JackDriverWaitFunction wait;
157 The JACK engine will call this to ask the driver to move
158 data from its inputs to its output port buffers. it should
159 return 0 to indicate successful completion, negative otherwise.
161 This function will always be called after the wait function (above).
163 JackDriverReadFunction read;
166 The JACK engine will call this to ask the driver to move
167 data from its input port buffers to its outputs. it should
168 return 0 to indicate successful completion, negative otherwise.
170 this function will always be called after the read function (above).
172 JackDriverWriteFunction write;
175 The JACK engine will call this after the wait function (above) has
176 been called, but for some reason the engine is unable to execute
177 a full "cycle". the driver should do whatever is necessary to
178 keep itself running correctly, but cannot reference ports
179 or other JACK data structures in any way.
181 JackDriverNullCycleFunction null_cycle;
184 The engine will call this when it plans to stop calling the `wait'
185 function for some period of time. the driver should take
186 appropriate steps to handle this (possibly no steps at all).
187 NOTE: the driver must silence its capture buffers (if any)
188 from within this function or the function that actually
189 implements the change in state.
191 JackDriverStopFunction stop;
194 The engine will call this to let the driver know that it plans
195 to start calling the `wait' function on a regular basis. the driver
196 should take any appropriate steps to handle this (possibly no steps
197 at all). NOTE: The driver may wish to silence its playback buffers
198 (if any) from within this function or the function that actually
199 implements the change in state.
201 JackDriverStartFunction start;
203 The engine will call this to let the driver know that some client
204 has requested a new buffer size. The stop function will be called
205 prior to this, and the start function after this one has returned.
207 JackDriverBufSizeFunction bufsize;
210 /* define the fields here... */
211 #define JACK_DRIVER_DECL \
212 jack_time_t period_usecs; \
213 jack_time_t last_wait_ust; \
214 void *handle; \
215 struct _jack_client_internal * internal_client; \
216 void (*finish)(struct _jack_driver *);\
217 JackDriverAttachFunction attach; \
218 JackDriverDetachFunction detach; \
219 JackDriverReadFunction read; \
220 JackDriverWriteFunction write; \
221 JackDriverNullCycleFunction null_cycle; \
222 JackDriverStopFunction stop; \
223 JackDriverStartFunction start; \
224 JackDriverBufSizeFunction bufsize;
226 JACK_DRIVER_DECL /* expand the macro */
228 } jack_driver_t;
231 typedef jack_driver_desc_t * (*JackDriverDescFunction) ();
233 void jack_driver_init (jack_driver_t *);
234 void jack_driver_release (jack_driver_t *);
236 jack_driver_t *jack_driver_load (int argc, char **argv);
237 void jack_driver_unload (jack_driver_t *);
240 /****************************
241 *** Non-Threaded Drivers ***
242 ****************************/
245 Call sequence summary:
247 1) engine loads driver via runtime dynamic linking
248 - calls jack_driver_load
249 - we call dlsym for "driver_initialize" and execute it
250 - driver_initialize calls jack_driver_nt_init
251 2) nt layer attaches to driver
252 3) nt layer starts driver
253 4) nt layer runs a thread, calling
254 while () {
255 driver->nt_run_ctcle();
257 5) nt layer stops driver
258 6) nt layer detaches driver
259 7) engine calls driver `finish' routine which calls jack_driver_nt_finish
261 Note that stop/start may be called multiple times in the event of an
262 error return from the `wait' function.
267 struct _jack_driver_nt;
269 typedef int (*JackDriverNTAttachFunction)(struct _jack_driver_nt *);
270 typedef int (*JackDriverNTDetachFunction)(struct _jack_driver_nt *);
271 typedef int (*JackDriverNTStopFunction)(struct _jack_driver_nt *);
272 typedef int (*JackDriverNTStartFunction)(struct _jack_driver_nt *);
273 typedef int (*JackDriverNTBufSizeFunction)(struct _jack_driver_nt *,
274 jack_nframes_t nframes);
275 typedef int (*JackDriverNTRunCycleFunction)(struct _jack_driver_nt *);
277 typedef struct _jack_driver_nt {
279 #define JACK_DRIVER_NT_DECL \
280 JACK_DRIVER_DECL \
281 struct _jack_engine * engine; \
282 volatile int nt_run; \
283 pthread_t nt_thread; \
284 pthread_mutex_t nt_run_lock; \
285 JackDriverNTAttachFunction nt_attach; \
286 JackDriverNTDetachFunction nt_detach; \
287 JackDriverNTStopFunction nt_stop; \
288 JackDriverNTStartFunction nt_start; \
289 JackDriverNTBufSizeFunction nt_bufsize; \
290 JackDriverNTRunCycleFunction nt_run_cycle;
291 #define nt_read read
292 #define nt_write write
293 #define nt_null_cycle null_cycle
295 JACK_DRIVER_NT_DECL
298 } jack_driver_nt_t;
300 void jack_driver_nt_init (jack_driver_nt_t * driver);
301 void jack_driver_nt_finish (jack_driver_nt_t * driver);
304 #endif /* __jack_driver_h__ */