1 | /** |
2 | * \file include/seqmid.h |
3 | * \brief Application interface library for the ALSA driver |
4 | * \author Jaroslav Kysela <perex@perex.cz> |
5 | * \author Abramo Bagnara <abramo@alsa-project.org> |
6 | * \author Takashi Iwai <tiwai@suse.de> |
7 | * \date 1998-2001 |
8 | * |
9 | * Application interface library for the ALSA driver |
10 | */ |
11 | /* |
12 | * This library is free software; you can redistribute it and/or modify |
13 | * it under the terms of the GNU Lesser General Public License as |
14 | * published by the Free Software Foundation; either version 2.1 of |
15 | * the License, or (at your option) any later version. |
16 | * |
17 | * This program is distributed in the hope that it will be useful, |
18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
20 | * GNU Lesser General Public License for more details. |
21 | * |
22 | * You should have received a copy of the GNU Lesser General Public |
23 | * License along with this library; if not, write to the Free Software |
24 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
25 | * |
26 | */ |
27 | |
28 | #ifndef __ALSA_SEQMID_H |
29 | #define __ALSA_SEQMID_H |
30 | |
31 | #ifdef __cplusplus |
32 | extern "C" { |
33 | #endif |
34 | |
35 | /** |
36 | * \defgroup SeqMiddle Sequencer Middle Level Interface |
37 | * Sequencer Middle Level Interface |
38 | * \ingroup Sequencer |
39 | * \{ |
40 | */ |
41 | |
42 | /** |
43 | * \brief initialize event record |
44 | * \param ev event record pointer |
45 | * |
46 | * This macro clears the given event record pointer to the default status. |
47 | */ |
48 | #define snd_seq_ev_clear(ev) \ |
49 | memset(ev, 0, sizeof(snd_seq_event_t)) |
50 | |
51 | /** |
52 | * \brief set the tag for given event |
53 | * \param ev event record |
54 | * \param t event tag |
55 | * |
56 | * This macro sets the tag to the given event record. |
57 | */ |
58 | #define snd_seq_ev_set_tag(ev,t) \ |
59 | ((ev)->tag = (t)) |
60 | |
61 | /** |
62 | * \brief set the explicit destination |
63 | * \param ev event record |
64 | * \param c destination client id |
65 | * \param p destination port id |
66 | * |
67 | * This macro sets the client and port id numbers to the given event record. |
68 | * |
69 | * \sa snd_seq_ev_set_subs() |
70 | */ |
71 | #define snd_seq_ev_set_dest(ev,c,p) \ |
72 | ((ev)->dest.client = (c), (ev)->dest.port = (p)) |
73 | |
74 | /** |
75 | * \brief set broadcasting to subscribers |
76 | * \param ev event record |
77 | * |
78 | * This macro sets the destination as the subscribers. |
79 | * |
80 | * \sa snd_seq_ev_set_dest() |
81 | */ |
82 | #define snd_seq_ev_set_subs(ev) \ |
83 | ((ev)->dest.client = SND_SEQ_ADDRESS_SUBSCRIBERS,\ |
84 | (ev)->dest.port = SND_SEQ_ADDRESS_UNKNOWN) |
85 | |
86 | /** |
87 | * \brief set broadcasting to all clients/ports |
88 | * \param ev event record |
89 | * |
90 | * This macro sets the destination as the broadcasting. |
91 | * |
92 | * \sa snd_seq_ev_set_dest() |
93 | */ |
94 | #define snd_seq_ev_set_broadcast(ev) \ |
95 | ((ev)->dest.client = SND_SEQ_ADDRESS_BROADCAST,\ |
96 | (ev)->dest.port = SND_SEQ_ADDRESS_BROADCAST) |
97 | |
98 | /** |
99 | * \brief set the source port |
100 | * \param ev event record |
101 | * \param p source port id |
102 | * |
103 | * This macro sets the source port id number. |
104 | */ |
105 | #define snd_seq_ev_set_source(ev,p) \ |
106 | ((ev)->source.port = (p)) |
107 | |
108 | /** |
109 | * \brief set direct passing mode (without queued) |
110 | * \param ev event instance |
111 | * |
112 | * This macro sets the event to the direct passing mode |
113 | * to be delivered immediately without queueing. |
114 | * |
115 | * \sa snd_seq_ev_schedule_tick(), snd_seq_ev_schedule_real() |
116 | */ |
117 | #define snd_seq_ev_set_direct(ev) \ |
118 | ((ev)->queue = SND_SEQ_QUEUE_DIRECT) |
119 | |
120 | /** |
121 | * \brief set tick-scheduling mode on queue |
122 | * \param ev event instance |
123 | * \param q queue id to schedule |
124 | * \param relative relative time-stamp if non-zero |
125 | * \param ttick tick time-stamp to be delivered |
126 | * |
127 | * This macro sets the scheduling of the event in the |
128 | * MIDI tick mode. |
129 | * |
130 | * \sa snd_seq_ev_schedule_real(), snd_seq_ev_set_direct() |
131 | */ |
132 | #define snd_seq_ev_schedule_tick(ev, q, relative, ttick) \ |
133 | ((ev)->flags &= ~(SND_SEQ_TIME_STAMP_MASK | SND_SEQ_TIME_MODE_MASK),\ |
134 | (ev)->flags |= SND_SEQ_TIME_STAMP_TICK,\ |
135 | (ev)->flags |= (relative) ? SND_SEQ_TIME_MODE_REL : SND_SEQ_TIME_MODE_ABS,\ |
136 | (ev)->time.tick = (ttick),\ |
137 | (ev)->queue = (q)) |
138 | |
139 | /** |
140 | * \brief set real-time-scheduling mode on queue |
141 | * \param ev event instance |
142 | * \param q queue id to schedule |
143 | * \param relative relative time-stamp if non-zero |
144 | * \param rtime time-stamp to be delivered |
145 | * |
146 | * This macro sets the scheduling of the event in the |
147 | * realtime mode. |
148 | * |
149 | * \sa snd_seq_ev_schedule_tick(), snd_seq_ev_set_direct() |
150 | */ |
151 | #define snd_seq_ev_schedule_real(ev, q, relative, rtime) \ |
152 | ((ev)->flags &= ~(SND_SEQ_TIME_STAMP_MASK | SND_SEQ_TIME_MODE_MASK),\ |
153 | (ev)->flags |= SND_SEQ_TIME_STAMP_REAL,\ |
154 | (ev)->flags |= (relative) ? SND_SEQ_TIME_MODE_REL : SND_SEQ_TIME_MODE_ABS,\ |
155 | (ev)->time.time = *(rtime),\ |
156 | (ev)->queue = (q)) |
157 | |
158 | /** |
159 | * \brief set event priority |
160 | * \param ev event instance |
161 | * \param high_prior 1 for high priority mode |
162 | */ |
163 | #define snd_seq_ev_set_priority(ev, high_prior) \ |
164 | ((ev)->flags &= ~SND_SEQ_PRIORITY_MASK,\ |
165 | (ev)->flags |= (high_prior) ? SND_SEQ_PRIORITY_HIGH : SND_SEQ_PRIORITY_NORMAL) |
166 | |
167 | /** |
168 | * \brief set fixed data |
169 | * \param ev event instance |
170 | * |
171 | * Sets the event length mode as fixed size. |
172 | * |
173 | * \sa snd_seq_ev_set_variable(), snd_seq_ev_set_varusr() |
174 | */ |
175 | #define snd_seq_ev_set_fixed(ev) \ |
176 | ((ev)->flags &= ~SND_SEQ_EVENT_LENGTH_MASK,\ |
177 | (ev)->flags |= SND_SEQ_EVENT_LENGTH_FIXED) |
178 | |
179 | /** |
180 | * \brief set variable data |
181 | * \param ev event instance |
182 | * \param datalen length of the external data |
183 | * \param dataptr pointer of the external data |
184 | * |
185 | * Sets the event length mode as variable length and stores the data. |
186 | * |
187 | * \sa snd_seq_ev_set_fixed(), snd_seq_ev_set_varusr() |
188 | */ |
189 | #define snd_seq_ev_set_variable(ev, datalen, dataptr) \ |
190 | ((ev)->flags &= ~SND_SEQ_EVENT_LENGTH_MASK,\ |
191 | (ev)->flags |= SND_SEQ_EVENT_LENGTH_VARIABLE,\ |
192 | (ev)->data.ext.len = (datalen),\ |
193 | (ev)->data.ext.ptr = (dataptr)) |
194 | |
195 | /** |
196 | * \brief set varusr data |
197 | * \param ev event instance |
198 | * \param datalen length of the external data |
199 | * \param dataptr pointer of the external data |
200 | * |
201 | * Sets the event length mode as variable user-space data and stores the data. |
202 | * |
203 | * \sa snd_seq_ev_set_fixed(), snd_seq_ev_set_variable() |
204 | */ |
205 | #define snd_seq_ev_set_varusr(ev, datalen, dataptr) \ |
206 | ((ev)->flags &= ~SND_SEQ_EVENT_LENGTH_MASK,\ |
207 | (ev)->flags |= SND_SEQ_EVENT_LENGTH_VARUSR,\ |
208 | (ev)->data.ext.len = (datalen),\ |
209 | (ev)->data.ext.ptr = (dataptr)) |
210 | |
211 | /** |
212 | * \brief set queue controls |
213 | * \param ev event record |
214 | * \param typ event type |
215 | * \param q queue id |
216 | * \param val control value |
217 | */ |
218 | #define snd_seq_ev_set_queue_control(ev, typ, q, val) \ |
219 | ((ev)->type = (typ),\ |
220 | snd_seq_ev_set_dest(ev, SND_SEQ_CLIENT_SYSTEM, SND_SEQ_PORT_SYSTEM_TIMER),\ |
221 | (ev)->data.queue.queue = (q),\ |
222 | (ev)->data.queue.param.value = (val)) |
223 | |
224 | /** |
225 | * \brief set the start queue event |
226 | * \param ev event record |
227 | * \param q queue id to start |
228 | * |
229 | * \sa snd_seq_ev_set_queue_stop(), snd_seq_ev_set_queue_continue() |
230 | */ |
231 | #define snd_seq_ev_set_queue_start(ev, q) \ |
232 | snd_seq_ev_set_queue_control(ev, SND_SEQ_EVENT_START, q, 0) |
233 | |
234 | /** |
235 | * \brief set the stop queue event |
236 | * \param ev event record |
237 | * \param q queue id to stop |
238 | * |
239 | * \sa snd_seq_ev_set_queue_start(), snd_seq_ev_set_queue_continue() |
240 | */ |
241 | #define snd_seq_ev_set_queue_stop(ev, q) \ |
242 | snd_seq_ev_set_queue_control(ev, SND_SEQ_EVENT_STOP, q, 0) |
243 | |
244 | /** |
245 | * \brief set the stop queue event |
246 | * \param ev event record |
247 | * \param q queue id to continue |
248 | * |
249 | * \sa snd_seq_ev_set_queue_start(), snd_seq_ev_set_queue_stop() |
250 | */ |
251 | #define snd_seq_ev_set_queue_continue(ev, q) \ |
252 | snd_seq_ev_set_queue_control(ev, SND_SEQ_EVENT_CONTINUE, q, 0) |
253 | |
254 | /** |
255 | * \brief set the stop queue event |
256 | * \param ev event record |
257 | * \param q queue id to change tempo |
258 | * \param val the new tempo value |
259 | */ |
260 | #define snd_seq_ev_set_queue_tempo(ev, q, val) \ |
261 | snd_seq_ev_set_queue_control(ev, SND_SEQ_EVENT_TEMPO, q, val) |
262 | |
263 | /** |
264 | * \brief set the real-time position of a queue |
265 | * \param ev event record |
266 | * \param q queue id to change tempo |
267 | * \param rtime the new real-time pointer |
268 | */ |
269 | #define snd_seq_ev_set_queue_pos_real(ev, q, rtime) \ |
270 | ((ev)->type = SND_SEQ_EVENT_SETPOS_TIME,\ |
271 | snd_seq_ev_set_dest(ev, SND_SEQ_CLIENT_SYSTEM, SND_SEQ_PORT_SYSTEM_TIMER),\ |
272 | (ev)->data.queue.queue = (q),\ |
273 | (ev)->data.queue.param.time.time = *(rtime)) |
274 | |
275 | /** |
276 | * \brief set the tick-time position of a queue |
277 | * \param ev event record |
278 | * \param q queue id to change tempo |
279 | * \param ttime the new tick-time |
280 | */ |
281 | #define snd_seq_ev_set_queue_pos_tick(ev, q, ttime) \ |
282 | ((ev)->type = SND_SEQ_EVENT_SETPOS_TICK,\ |
283 | snd_seq_ev_set_dest(ev, SND_SEQ_CLIENT_SYSTEM, SND_SEQ_PORT_SYSTEM_TIMER),\ |
284 | (ev)->data.queue.queue = (q),\ |
285 | (ev)->data.queue.param.time.tick = (ttime)) |
286 | |
287 | /* set and send a queue control event */ |
288 | int snd_seq_control_queue(snd_seq_t *seq, int q, int type, int value, snd_seq_event_t *ev); |
289 | |
290 | /** |
291 | * \brief start the specified queue |
292 | * \param seq sequencer handle |
293 | * \param q queue id to start |
294 | * \param ev optional event record (see #snd_seq_control_queue) |
295 | */ |
296 | #define snd_seq_start_queue(seq, q, ev) \ |
297 | snd_seq_control_queue(seq, q, SND_SEQ_EVENT_START, 0, ev) |
298 | |
299 | /** |
300 | * \brief stop the specified queue |
301 | * \param seq sequencer handle |
302 | * \param q queue id to stop |
303 | * \param ev optional event record (see #snd_seq_control_queue) |
304 | */ |
305 | #define snd_seq_stop_queue(seq, q, ev) \ |
306 | snd_seq_control_queue(seq, q, SND_SEQ_EVENT_STOP, 0, ev) |
307 | |
308 | /** |
309 | * \brief continue the specified queue |
310 | * \param seq sequencer handle |
311 | * \param q queue id to continue |
312 | * \param ev optional event record (see #snd_seq_control_queue) |
313 | */ |
314 | #define snd_seq_continue_queue(seq, q, ev) \ |
315 | snd_seq_control_queue(seq, q, SND_SEQ_EVENT_CONTINUE, 0, ev) |
316 | |
317 | /** |
318 | * \brief change the tempo of the specified queue |
319 | * \param seq sequencer handle |
320 | * \param q queue id |
321 | * \param tempo the new tempo value |
322 | * \param ev optional event record (see #snd_seq_control_queue) |
323 | */ |
324 | #define snd_seq_change_queue_tempo(seq, q, tempo, ev) \ |
325 | snd_seq_control_queue(seq, q, SND_SEQ_EVENT_TEMPO, tempo, ev) |
326 | |
327 | /* create a port - simple version - return the port number */ |
328 | int snd_seq_create_simple_port(snd_seq_t *seq, const char *name, |
329 | unsigned int caps, unsigned int type); |
330 | /* delete the port */ |
331 | int snd_seq_delete_simple_port(snd_seq_t *seq, int port); |
332 | |
333 | /* simple subscription between this port and another port |
334 | (w/o exclusive & time conversion) |
335 | */ |
336 | int snd_seq_connect_from(snd_seq_t *seq, int my_port, int src_client, int src_port); |
337 | int snd_seq_connect_to(snd_seq_t *seq, int my_port, int dest_client, int dest_port); |
338 | int snd_seq_disconnect_from(snd_seq_t *seq, int my_port, int src_client, int src_port); |
339 | int snd_seq_disconnect_to(snd_seq_t *seq, int my_port, int dest_client, int dest_port); |
340 | |
341 | /* |
342 | * set client information |
343 | */ |
344 | int snd_seq_set_client_name(snd_seq_t *seq, const char *name); |
345 | int snd_seq_set_client_event_filter(snd_seq_t *seq, int event_type); |
346 | int snd_seq_set_client_pool_output(snd_seq_t *seq, size_t size); |
347 | int snd_seq_set_client_pool_output_room(snd_seq_t *seq, size_t size); |
348 | int snd_seq_set_client_pool_input(snd_seq_t *seq, size_t size); |
349 | /* sync output queue */ |
350 | int snd_seq_sync_output_queue(snd_seq_t *seq); |
351 | |
352 | /* |
353 | * parse the given string and get the sequencer address |
354 | */ |
355 | int snd_seq_parse_address(snd_seq_t *seq, snd_seq_addr_t *addr, const char *str); |
356 | |
357 | /* |
358 | * reset client input/output pool |
359 | */ |
360 | int snd_seq_reset_pool_output(snd_seq_t *seq); |
361 | int snd_seq_reset_pool_input(snd_seq_t *seq); |
362 | |
363 | /** |
364 | * \brief set note event |
365 | * \param ev event record |
366 | * \param ch channel number |
367 | * \param key note key |
368 | * \param vel velocity |
369 | * \param dur duration (in tick or msec) |
370 | */ |
371 | #define snd_seq_ev_set_note(ev, ch, key, vel, dur) \ |
372 | ((ev)->type = SND_SEQ_EVENT_NOTE,\ |
373 | snd_seq_ev_set_fixed(ev),\ |
374 | (ev)->data.note.channel = (ch),\ |
375 | (ev)->data.note.note = (key),\ |
376 | (ev)->data.note.velocity = (vel),\ |
377 | (ev)->data.note.duration = (dur)) |
378 | |
379 | /** |
380 | * \brief set note-on event |
381 | * \param ev event record |
382 | * \param ch channel number |
383 | * \param key note key |
384 | * \param vel velocity |
385 | */ |
386 | #define snd_seq_ev_set_noteon(ev, ch, key, vel) \ |
387 | ((ev)->type = SND_SEQ_EVENT_NOTEON,\ |
388 | snd_seq_ev_set_fixed(ev),\ |
389 | (ev)->data.note.channel = (ch),\ |
390 | (ev)->data.note.note = (key),\ |
391 | (ev)->data.note.velocity = (vel)) |
392 | |
393 | /** |
394 | * \brief set note-off event |
395 | * \param ev event record |
396 | * \param ch channel number |
397 | * \param key note key |
398 | * \param vel velocity |
399 | */ |
400 | #define snd_seq_ev_set_noteoff(ev, ch, key, vel) \ |
401 | ((ev)->type = SND_SEQ_EVENT_NOTEOFF,\ |
402 | snd_seq_ev_set_fixed(ev),\ |
403 | (ev)->data.note.channel = (ch),\ |
404 | (ev)->data.note.note = (key),\ |
405 | (ev)->data.note.velocity = (vel)) |
406 | |
407 | /** |
408 | * \brief set key-pressure event |
409 | * \param ev event record |
410 | * \param ch channel number |
411 | * \param key note key |
412 | * \param vel velocity |
413 | */ |
414 | #define snd_seq_ev_set_keypress(ev,ch,key,vel) \ |
415 | ((ev)->type = SND_SEQ_EVENT_KEYPRESS,\ |
416 | snd_seq_ev_set_fixed(ev),\ |
417 | (ev)->data.note.channel = (ch),\ |
418 | (ev)->data.note.note = (key),\ |
419 | (ev)->data.note.velocity = (vel)) |
420 | |
421 | /** |
422 | * \brief set MIDI controller event |
423 | * \param ev event record |
424 | * \param ch channel number |
425 | * \param cc controller number |
426 | * \param val control value |
427 | */ |
428 | #define snd_seq_ev_set_controller(ev,ch,cc,val) \ |
429 | ((ev)->type = SND_SEQ_EVENT_CONTROLLER,\ |
430 | snd_seq_ev_set_fixed(ev),\ |
431 | (ev)->data.control.channel = (ch),\ |
432 | (ev)->data.control.param = (cc),\ |
433 | (ev)->data.control.value = (val)) |
434 | |
435 | /** |
436 | * \brief set program change event |
437 | * \param ev event record |
438 | * \param ch channel number |
439 | * \param val program number |
440 | */ |
441 | #define snd_seq_ev_set_pgmchange(ev,ch,val) \ |
442 | ((ev)->type = SND_SEQ_EVENT_PGMCHANGE,\ |
443 | snd_seq_ev_set_fixed(ev),\ |
444 | (ev)->data.control.channel = (ch),\ |
445 | (ev)->data.control.value = (val)) |
446 | |
447 | /** |
448 | * \brief set pitch-bend event |
449 | * \param ev event record |
450 | * \param ch channel number |
451 | * \param val pitch bend; zero centered from -8192 to 8191 |
452 | */ |
453 | #define snd_seq_ev_set_pitchbend(ev,ch,val) \ |
454 | ((ev)->type = SND_SEQ_EVENT_PITCHBEND,\ |
455 | snd_seq_ev_set_fixed(ev),\ |
456 | (ev)->data.control.channel = (ch),\ |
457 | (ev)->data.control.value = (val)) |
458 | |
459 | /** |
460 | * \brief set channel pressure event |
461 | * \param ev event record |
462 | * \param ch channel number |
463 | * \param val channel pressure value |
464 | */ |
465 | #define snd_seq_ev_set_chanpress(ev,ch,val) \ |
466 | ((ev)->type = SND_SEQ_EVENT_CHANPRESS,\ |
467 | snd_seq_ev_set_fixed(ev),\ |
468 | (ev)->data.control.channel = (ch),\ |
469 | (ev)->data.control.value = (val)) |
470 | |
471 | /** |
472 | * \brief set sysex event |
473 | * \param ev event record |
474 | * \param datalen length of sysex data |
475 | * \param dataptr sysex data pointer |
476 | * |
477 | * the sysex data must contain the start byte 0xf0 and the end byte 0xf7. |
478 | */ |
479 | #define snd_seq_ev_set_sysex(ev,datalen,dataptr) \ |
480 | ((ev)->type = SND_SEQ_EVENT_SYSEX,\ |
481 | snd_seq_ev_set_variable(ev, datalen, dataptr)) |
482 | |
483 | /** \} */ |
484 | |
485 | #ifdef __cplusplus |
486 | } |
487 | #endif |
488 | |
489 | #endif /* __ALSA_SEQMID_H */ |
490 | |
491 | |