1use libc::{c_uint, c_int, c_short, c_uchar, c_void, c_long, size_t, pollfd};
4use super::error::*;
5use crate::alsa;
6use super::{Direction, poll};
7use core::{ptr, fmt, mem, slice, time, cell};
8use core::str::{FromStr, Split};
9use core::ffi::CStr;
10use ::alloc::borrow::Cow;
11use ::alloc::boxed::Box;
12
13#[repr(packed)]
15struct EvExtPacked {
16 len: c_uint,
17 ptr: *mut c_void,
18}
19
20#[derive(Debug)]
26pub struct Seq(*mut alsa::snd_seq_t, cell::Cell<bool>);
27
28unsafe impl Send for Seq {}
29
30impl Drop for Seq {
31 fn drop(&mut self) { unsafe { alsa::snd_seq_close(self.0) }; }
32}
33
34impl Seq {
35 fn check_has_input(&self) {
36 if self.1.get() { panic!("No additional Input object allowed")}
37 }
38
39 pub fn open(name: Option<&CStr>, dir: Option<Direction>, nonblock: bool) -> Result<Seq> {
43 let n2 = name.unwrap_or(unsafe { CStr::from_bytes_with_nul_unchecked(b"default\0") });
44 let mut h = ptr::null_mut();
45 let mode = if nonblock { alsa::SND_SEQ_NONBLOCK } else { 0 };
46 let streams = match dir {
47 None => alsa::SND_SEQ_OPEN_DUPLEX,
48 Some(Direction::Playback) => alsa::SND_SEQ_OPEN_OUTPUT,
49 Some(Direction::Capture) => alsa::SND_SEQ_OPEN_INPUT,
50 };
51 acheck!(snd_seq_open(&mut h, n2.as_ptr(), streams, mode))
52 .map(|_| Seq(h, cell::Cell::new(false)))
53 }
54
55 pub fn set_client_name(&self, name: &CStr) -> Result<()> {
56 acheck!(snd_seq_set_client_name(self.0, name.as_ptr())).map(|_| ())
57 }
58
59 pub fn set_client_event_filter(&self, event_type: i32) -> Result<()> {
60 acheck!(snd_seq_set_client_event_filter(self.0, event_type as c_int)).map(|_| ())
61 }
62
63 pub fn set_client_pool_output(&self, size: u32) -> Result<()> {
64 acheck!(snd_seq_set_client_pool_output(self.0, size as size_t)).map(|_| ())
65 }
66
67 pub fn set_client_pool_input(&self, size: u32) -> Result<()> {
68 acheck!(snd_seq_set_client_pool_input(self.0, size as size_t)).map(|_| ())
69 }
70
71 pub fn set_client_pool_output_room(&self, size: u32) -> Result<()> {
72 acheck!(snd_seq_set_client_pool_output_room(self.0, size as size_t)).map(|_| ())
73 }
74
75 pub fn client_id(&self) -> Result<i32> {
76 acheck!(snd_seq_client_id(self.0)).map(|q| q as i32)
77 }
78
79 pub fn drain_output(&self) -> Result<i32> {
80 acheck!(snd_seq_drain_output(self.0)).map(|q| q as i32)
81 }
82
83 pub fn get_any_client_info(&self, client: i32) -> Result<ClientInfo> {
84 let c = ClientInfo::new()?;
85 acheck!(snd_seq_get_any_client_info(self.0, client, c.0)).map(|_| c)
86 }
87
88 pub fn get_any_port_info(&self, a: Addr) -> Result<PortInfo> {
89 let c = PortInfo::new()?;
90 acheck!(snd_seq_get_any_port_info(self.0, a.client as c_int, a.port as c_int, c.0)).map(|_| c)
91 }
92
93 pub fn create_port(&self, port: &PortInfo) -> Result<()> {
94 acheck!(snd_seq_create_port(self.0, port.0)).map(|_| ())
95 }
96
97 pub fn create_simple_port(&self, name: &CStr, caps: PortCap, t: PortType) -> Result<i32> {
98 acheck!(snd_seq_create_simple_port(self.0, name.as_ptr(), caps.bits() as c_uint, t.bits() as c_uint)).map(|q| q as i32)
99 }
100
101 pub fn set_port_info(&self, port: i32, info: &mut PortInfo) -> Result<()> {
102 acheck!(snd_seq_set_port_info(self.0, port, info.0)).map(|_| ())
103 }
104
105 pub fn delete_port(&self, port: i32) -> Result<()> {
106 acheck!(snd_seq_delete_port(self.0, port as c_int)).map(|_| ())
107 }
108
109 pub fn subscribe_port(&self, info: &PortSubscribe) -> Result<()> {
110 acheck!(snd_seq_subscribe_port(self.0, info.0)).map(|_| ())
111 }
112
113 pub fn unsubscribe_port(&self, sender: Addr, dest: Addr) -> Result<()> {
114 let z = PortSubscribe::new()?;
115 z.set_sender(sender);
116 z.set_dest(dest);
117 acheck!(snd_seq_unsubscribe_port(self.0, z.0)).map(|_| ())
118 }
119
120 pub fn control_queue(&self, q: i32, t: EventType, value: i32, e: Option<&mut Event>) -> Result<()> {
121 assert!(EvQueueControl::<()>::has_data(t) || EvQueueControl::<i32>::has_data(t) || EvQueueControl::<u32>::has_data(t));
122 let p = e.map(|e| &mut e.0 as *mut _).unwrap_or(ptr::null_mut());
123 acheck!(snd_seq_control_queue(self.0, q as c_int, t as c_int, value as c_int, p)).map(|_| ())
124 }
125
126 pub fn event_output(&self, e: &mut Event) -> Result<u32> {
127 e.ensure_buf();
128 acheck!(snd_seq_event_output(self.0, &mut e.0)).map(|q| q as u32)
129 }
130
131 pub fn event_output_buffer(&self, e: &mut Event) -> Result<u32> {
132 e.ensure_buf();
133 acheck!(snd_seq_event_output_buffer(self.0, &mut e.0)).map(|q| q as u32)
134 }
135
136 pub fn event_output_direct(&self, e: &mut Event) -> Result<u32> {
137 e.ensure_buf();
138 acheck!(snd_seq_event_output_direct(self.0, &mut e.0)).map(|q| q as u32)
139 }
140
141 pub fn get_queue_tempo(&self, q: i32) -> Result<QueueTempo> {
142 let value = QueueTempo::new()?;
143 acheck!(snd_seq_get_queue_tempo(self.0, q as c_int, value.0)).map(|_| value)
144 }
145
146 pub fn set_queue_tempo(&self, q: i32, value: &QueueTempo) -> Result<()> {
147 acheck!(snd_seq_set_queue_tempo(self.0, q as c_int, value.0)).map(|_| ())
148 }
149
150 pub fn get_queue_status(&self, q: i32) -> Result<QueueStatus> {
151 let value = QueueStatus::new()?;
152 acheck!(snd_seq_get_queue_status(self.0, q as c_int, value.0)).map(|_| value)
153 }
154
155 pub fn free_queue(&self, q: i32) -> Result<()> { acheck!(snd_seq_free_queue(self.0, q)).map(|_| ()) }
156 pub fn alloc_queue(&self) -> Result<i32> { acheck!(snd_seq_alloc_queue(self.0)).map(|q| q as i32) }
157 pub fn alloc_named_queue(&self, n: &CStr) -> Result<i32> {
158 acheck!(snd_seq_alloc_named_queue(self.0, n.as_ptr())).map(|q| q as i32)
159 }
160
161 pub fn sync_output_queue(&self) -> Result<()> {
162 acheck!(snd_seq_sync_output_queue(self.0)).map(|_| ())
163 }
164
165 pub fn drop_output(&self) -> Result<()> {
166 acheck!(snd_seq_drop_output(self.0)).map(|_| ())
167 }
168
169 pub fn input(&self) -> Input<'_> {
172 Input::new(self)
173 }
174
175 pub fn remove_events(&self, condition: RemoveEvents) -> Result<()> {
176 acheck!(snd_seq_remove_events(self.0, condition.0)).map(|_| ())
177 }
178}
179
180#[derive(Debug)]
188pub struct Input<'a>(&'a Seq);
189
190impl<'a> Drop for Input<'a> {
191 fn drop(&mut self) { (self.0).1.set(false) }
192}
193
194impl<'a> Input<'a> {
195 fn new(s: &'a Seq) -> Input<'a> {
196 s.check_has_input();
197 s.1.set(true);
198 Input(s)
199 }
200
201 pub fn event_input(&mut self) -> Result<Event<'_>> {
202 let mut z = ptr::null_mut();
207 acheck!(snd_seq_event_input((self.0).0, &mut z))?;
208 unsafe { Event::extract (&mut *z, "snd_seq_event_input") }
209 }
210
211 pub fn event_input_pending(&self, fetch_sequencer: bool) -> Result<u32> {
212 acheck!(snd_seq_event_input_pending((self.0).0, if fetch_sequencer {1} else {0})).map(|q| q as u32)
213 }
214
215 pub fn set_input_buffer_size(&self, size: u32) -> Result<()> {
216 acheck!(snd_seq_set_input_buffer_size((self.0).0, size as size_t)).map(|_| ())
217 }
218
219 pub fn drop_input(&self) -> Result<()> {
220 acheck!(snd_seq_drop_input((self.0).0)).map(|_| ())
221 }
222}
223
224fn polldir(o: Option<Direction>) -> c_short {
225 match o {
226 None => poll::Flags::IN | poll::Flags::OUT,
227 Some(Direction::Playback) => poll::Flags::OUT,
228 Some(Direction::Capture) => poll::Flags::IN,
229 }.bits()
230}
231
232impl<'a> poll::Descriptors for (&'a Seq, Option<Direction>) {
233
234 fn count(&self) -> usize {
235 unsafe { alsa::snd_seq_poll_descriptors_count((self.0).0, polldir(self.1)) as usize }
236 }
237
238 fn fill(&self, p: &mut [pollfd]) -> Result<usize> {
239 let z = unsafe { alsa::snd_seq_poll_descriptors((self.0).0, p.as_mut_ptr(), p.len() as c_uint, polldir(self.1)) };
240 from_code("snd_seq_poll_descriptors", z).map(|_| z as usize)
241 }
242
243 fn revents(&self, p: &[pollfd]) -> Result<poll::Flags> {
244 let mut r = 0;
245 let z = unsafe { alsa::snd_seq_poll_descriptors_revents((self.0).0, p.as_ptr() as *mut pollfd, p.len() as c_uint, &mut r) };
246 from_code("snd_seq_poll_descriptors_revents", z).map(|_| poll::Flags::from_bits_truncate(r as c_short))
247 }
248}
249
250pub struct ClientInfo(*mut alsa::snd_seq_client_info_t);
252
253unsafe impl Send for ClientInfo {}
254
255impl Drop for ClientInfo {
256 fn drop(&mut self) {
257 unsafe { alsa::snd_seq_client_info_free(self.0) };
258 }
259}
260
261impl ClientInfo {
262 fn new() -> Result<Self> {
263 let mut p = ptr::null_mut();
264 acheck!(snd_seq_client_info_malloc(&mut p)).map(|_| ClientInfo(p))
265 }
266
267 fn set_client(&self, client: i32) {
269 unsafe { alsa::snd_seq_client_info_set_client(self.0, client as c_int) };
270 }
271
272 pub fn get_client(&self) -> i32 {
273 unsafe { alsa::snd_seq_client_info_get_client(self.0) as i32 }
274 }
275
276 pub fn get_name(&self) -> Result<&str> {
277 let c = unsafe { alsa::snd_seq_client_info_get_name(self.0) };
278 from_const("snd_seq_client_info_get_name", c)
279 }
280
281 pub fn get_card(&self) -> Result<i32> {
282 acheck!(snd_seq_client_info_get_card(self.0))
283 }
284}
285
286impl fmt::Debug for ClientInfo {
287 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
288 write!(f, "ClientInfo({},{:?})", self.get_client(), self.get_name())
289 }
290}
291
292#[derive(Copy, Clone, Debug)]
293pub struct ClientIter<'a>(&'a Seq, i32);
295
296impl<'a> ClientIter<'a> {
297 pub fn new(seq: &'a Seq) -> Self { ClientIter(seq, -1) }
298}
299
300impl<'a> Iterator for ClientIter<'a> {
301 type Item = ClientInfo;
302 fn next(&mut self) -> Option<Self::Item> {
303 let z = ClientInfo::new().unwrap();
304 z.set_client(self.1);
305 let r = unsafe { alsa::snd_seq_query_next_client((self.0).0, z.0) };
306 if r < 0 { self.1 = -1; return None };
307 self.1 = z.get_client();
308 Some(z)
309 }
310}
311
312pub struct PortInfo(*mut alsa::snd_seq_port_info_t);
314
315unsafe impl Send for PortInfo {}
316
317impl Drop for PortInfo {
318 fn drop(&mut self) {
319 unsafe { alsa::snd_seq_port_info_free(self.0) };
320 }
321}
322
323impl PortInfo {
324 fn new() -> Result<Self> {
325 let mut p = ptr::null_mut();
326 acheck!(snd_seq_port_info_malloc(&mut p)).map(|_| PortInfo(p))
327 }
328
329 pub fn empty() -> Result<Self> {
331 let z = Self::new()?;
332 unsafe { ptr::write_bytes(z.0 as *mut u8, 0, alsa::snd_seq_port_info_sizeof()) };
333 Ok(z)
334 }
335
336 pub fn get_client(&self) -> i32 {
337 unsafe { alsa::snd_seq_port_info_get_client(self.0) as i32 }
338 }
339
340 pub fn get_port(&self) -> i32 {
341 unsafe { alsa::snd_seq_port_info_get_port(self.0) as i32 }
342 }
343
344 fn set_client(&self, client: i32) {
346 unsafe { alsa::snd_seq_port_info_set_client(self.0, client as c_int) };
347 }
348
349 fn set_port(&self, port: i32) {
351 unsafe { alsa::snd_seq_port_info_set_port(self.0, port as c_int) };
352 }
353
354 pub fn get_name(&self) -> Result<&str> {
355 let c = unsafe { alsa::snd_seq_port_info_get_name(self.0) };
356 from_const("snd_seq_port_info_get_name", c)
357 }
358
359 pub fn set_name(&mut self, name: &CStr) {
360 unsafe { alsa::snd_seq_port_info_set_name(self.0, name.as_ptr()) };
362 }
363
364 pub fn get_capability(&self) -> PortCap {
365 PortCap::from_bits_truncate(unsafe { alsa::snd_seq_port_info_get_capability(self.0) as u32 })
366 }
367
368 pub fn get_type(&self) -> PortType {
369 PortType::from_bits_truncate(unsafe { alsa::snd_seq_port_info_get_type(self.0) as u32 })
370 }
371
372 pub fn set_capability(&self, c: PortCap) {
373 unsafe { alsa::snd_seq_port_info_set_capability(self.0, c.bits() as c_uint) }
374 }
375
376 pub fn set_type(&self, c: PortType) {
377 unsafe { alsa::snd_seq_port_info_set_type(self.0, c.bits() as c_uint) }
378 }
379
380 pub fn addr(&self) -> Addr {
382 Addr {
383 client: self.get_client(),
384 port: self.get_port(),
385 }
386 }
387
388 pub fn get_midi_channels(&self) -> i32 { unsafe { alsa::snd_seq_port_info_get_midi_channels(self.0) as i32 } }
389 pub fn get_midi_voices(&self) -> i32 { unsafe { alsa::snd_seq_port_info_get_midi_voices(self.0) as i32 } }
390 pub fn get_synth_voices(&self) -> i32 { unsafe { alsa::snd_seq_port_info_get_synth_voices(self.0) as i32 } }
391 pub fn get_read_use(&self) -> i32 { unsafe { alsa::snd_seq_port_info_get_read_use(self.0) as i32 } }
392 pub fn get_write_use(&self) -> i32 { unsafe { alsa::snd_seq_port_info_get_write_use(self.0) as i32 } }
393 pub fn get_port_specified(&self) -> bool { unsafe { alsa::snd_seq_port_info_get_port_specified(self.0) == 1 } }
394 pub fn get_timestamping(&self) -> bool { unsafe { alsa::snd_seq_port_info_get_timestamping(self.0) == 1 } }
395 pub fn get_timestamp_real(&self) -> bool { unsafe { alsa::snd_seq_port_info_get_timestamp_real(self.0) == 1 } }
396 pub fn get_timestamp_queue(&self) -> i32 { unsafe { alsa::snd_seq_port_info_get_timestamp_queue(self.0) as i32 } }
397
398 pub fn set_midi_channels(&self, value: i32) { unsafe { alsa::snd_seq_port_info_set_midi_channels(self.0, value as c_int) } }
399 pub fn set_midi_voices(&self, value: i32) { unsafe { alsa::snd_seq_port_info_set_midi_voices(self.0, value as c_int) } }
400 pub fn set_synth_voices(&self, value: i32) { unsafe { alsa::snd_seq_port_info_set_synth_voices(self.0, value as c_int) } }
401 pub fn set_port_specified(&self, value: bool) { unsafe { alsa::snd_seq_port_info_set_port_specified(self.0, if value { 1 } else { 0 } ) } }
402 pub fn set_timestamping(&self, value: bool) { unsafe { alsa::snd_seq_port_info_set_timestamping(self.0, if value { 1 } else { 0 } ) } }
403 pub fn set_timestamp_real(&self, value: bool) { unsafe { alsa::snd_seq_port_info_set_timestamp_real(self.0, if value { 1 } else { 0 } ) } }
404 pub fn set_timestamp_queue(&self, value: i32) { unsafe { alsa::snd_seq_port_info_set_timestamp_queue(self.0, value as c_int) } }
405}
406
407impl fmt::Debug for PortInfo {
408 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
409 write!(f, "PortInfo({}:{},{:?})", self.get_client(), self.get_port(), self.get_name())
410 }
411}
412
413#[derive(Copy, Clone, Debug)]
414pub struct PortIter<'a>(&'a Seq, i32, i32);
416
417impl<'a> PortIter<'a> {
418 pub fn new(seq: &'a Seq, client: i32) -> Self { PortIter(seq, client, -1) }
419}
420
421impl<'a> Iterator for PortIter<'a> {
422 type Item = PortInfo;
423 fn next(&mut self) -> Option<Self::Item> {
424 let z = PortInfo::new().unwrap();
425 z.set_client(self.1);
426 z.set_port(self.2);
427 let r = unsafe { alsa::snd_seq_query_next_port((self.0).0, z.0) };
428 if r < 0 { self.2 = -1; return None };
429 self.2 = z.get_port();
430 Some(z)
431 }
432}
433
434bitflags! {
435 #[repr(transparent)]
436 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
437 pub struct PortCap: u32 {
439 const READ = 1<<0;
440 const WRITE = 1<<1;
441 const SYNC_READ = 1<<2;
442 const SYNC_WRITE = 1<<3;
443 const DUPLEX = 1<<4;
444 const SUBS_READ = 1<<5;
445 const SUBS_WRITE = 1<<6;
446 const NO_EXPORT = 1<<7;
447 }
448}
449
450bitflags! {
451 #[repr(transparent)]
452 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
453 pub struct PortType: u32 {
455 const SPECIFIC = (1<<0);
456 const MIDI_GENERIC = (1<<1);
457 const MIDI_GM = (1<<2);
458 const MIDI_GS = (1<<3);
459 const MIDI_XG = (1<<4);
460 const MIDI_MT32 = (1<<5);
461 const MIDI_GM2 = (1<<6);
462 const SYNTH = (1<<10);
463 const DIRECT_SAMPLE = (1<<11);
464 const SAMPLE = (1<<12);
465 const HARDWARE = (1<<16);
466 const SOFTWARE = (1<<17);
467 const SYNTHESIZER = (1<<18);
468 const PORT = (1<<19);
469 const APPLICATION = (1<<20);
470 }
471}
472
473bitflags! {
474 #[repr(transparent)]
475 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
476 pub struct Remove: u32 {
478 const INPUT = (1<<0);
479 const OUTPUT = (1<<1);
480 const DEST = (1<<2);
481 const DEST_CHANNEL = (1<<3);
482 const TIME_BEFORE = (1<<4);
483 const TIME_AFTER = (1<<5);
484 const TIME_TICK = (1<<6);
485 const EVENT_TYPE = (1<<7);
486 const IGNORE_OFF = (1<<8);
487 const TAG_MATCH = (1<<9);
488 }
489}
490
491
492#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash, Default)]
494pub struct Addr {
495 pub client: i32,
496 pub port: i32,
497}
498
499impl FromStr for Addr {
500 type Err = Box<dyn core::error::Error>;
501
502 fn from_str(s: &str) -> core::result::Result<Self, Self::Err> {
503 let mut split: Split<'_, char> = s.trim().split(':');
504 let client = split.next()
505 .ok_or("no client provided")?
506 .parse::<i32>()?;
507 let port = split.next()
508 .ok_or("no port provided")?
509 .parse::<i32>()?;
510 match split.next() {
511 Some(_) => {
512 Err("too many arguments".into())
513 },
514 None => {
515 Ok(Addr { client, port })
516 }
517 }
518 }
519}
520
521impl Addr {
522 pub fn system_timer() -> Addr { Addr { client: alsa::SND_SEQ_CLIENT_SYSTEM as i32, port: alsa::SND_SEQ_PORT_SYSTEM_TIMER as i32 } }
523 pub fn system_announce() -> Addr { Addr { client: alsa::SND_SEQ_CLIENT_SYSTEM as i32, port: alsa::SND_SEQ_PORT_SYSTEM_ANNOUNCE as i32 } }
524 pub fn broadcast() -> Addr { Addr { client: alsa::SND_SEQ_ADDRESS_BROADCAST as i32, port: alsa::SND_SEQ_ADDRESS_BROADCAST as i32 } }
525}
526
527#[derive(Debug)]
529pub struct PortSubscribe(*mut alsa::snd_seq_port_subscribe_t);
530
531unsafe impl Send for PortSubscribe {}
532
533impl Drop for PortSubscribe {
534 fn drop(&mut self) { unsafe { alsa::snd_seq_port_subscribe_free(self.0) }; }
535}
536
537impl PortSubscribe {
538 fn new() -> Result<Self> {
539 let mut p = ptr::null_mut();
540 acheck!(snd_seq_port_subscribe_malloc(&mut p)).map(|_| PortSubscribe(p))
541 }
542
543 pub fn empty() -> Result<Self> {
545 let z = Self::new()?;
546 unsafe { ptr::write_bytes(z.0 as *mut u8, 0, alsa::snd_seq_port_subscribe_sizeof()) };
547 Ok(z)
548 }
549
550 pub fn get_sender(&self) -> Addr { unsafe {
551 let z = alsa::snd_seq_port_subscribe_get_sender(self.0);
552 Addr { client: (*z).client as i32, port: (*z).port as i32 }
553 } }
554
555 pub fn get_dest(&self) -> Addr { unsafe {
556 let z = alsa::snd_seq_port_subscribe_get_dest(self.0);
557 Addr { client: (*z).client as i32, port: (*z).port as i32 }
558 } }
559
560 pub fn get_queue(&self) -> i32 { unsafe { alsa::snd_seq_port_subscribe_get_queue(self.0) as i32 } }
561 pub fn get_exclusive(&self) -> bool { unsafe { alsa::snd_seq_port_subscribe_get_exclusive(self.0) == 1 } }
562 pub fn get_time_update(&self) -> bool { unsafe { alsa::snd_seq_port_subscribe_get_time_update(self.0) == 1 } }
563 pub fn get_time_real(&self) -> bool { unsafe { alsa::snd_seq_port_subscribe_get_time_real(self.0) == 1 } }
564
565 pub fn set_sender(&self, value: Addr) {
566 let z = alsa::snd_seq_addr_t { client: value.client as c_uchar, port: value.port as c_uchar };
567 unsafe { alsa::snd_seq_port_subscribe_set_sender(self.0, &z) };
568 }
569
570 pub fn set_dest(&self, value: Addr) {
571 let z = alsa::snd_seq_addr_t { client: value.client as c_uchar, port: value.port as c_uchar };
572 unsafe { alsa::snd_seq_port_subscribe_set_dest(self.0, &z) };
573 }
574
575 pub fn set_queue(&self, value: i32) { unsafe { alsa::snd_seq_port_subscribe_set_queue(self.0, value as c_int) } }
576 pub fn set_exclusive(&self, value: bool) { unsafe { alsa::snd_seq_port_subscribe_set_exclusive(self.0, if value { 1 } else { 0 } ) } }
577 pub fn set_time_update(&self, value: bool) { unsafe { alsa::snd_seq_port_subscribe_set_time_update(self.0, if value { 1 } else { 0 } ) } }
578 pub fn set_time_real(&self, value: bool) { unsafe { alsa::snd_seq_port_subscribe_set_time_real(self.0, if value { 1 } else { 0 } ) } }
579
580}
581
582#[derive(Copy, Clone, Debug)]
584pub enum QuerySubsType {
585 READ = alsa::SND_SEQ_QUERY_SUBS_READ as isize,
586 WRITE = alsa::SND_SEQ_QUERY_SUBS_WRITE as isize,
587}
588
589struct QuerySubscribe(*mut alsa::snd_seq_query_subscribe_t);
592
593unsafe impl Send for QuerySubscribe {}
594
595impl Drop for QuerySubscribe {
596 fn drop(&mut self) { unsafe { alsa::snd_seq_query_subscribe_free(self.0) } }
597}
598
599impl QuerySubscribe {
600 pub fn new() -> Result<Self> {
601 let mut q = ptr::null_mut();
602 acheck!(snd_seq_query_subscribe_malloc(&mut q)).map(|_| QuerySubscribe(q))
603 }
604
605 pub fn get_index(&self) -> i32 { unsafe { alsa::snd_seq_query_subscribe_get_index(self.0) as i32 } }
606 pub fn get_addr(&self) -> Addr { unsafe {
607 let a = &(*alsa::snd_seq_query_subscribe_get_addr(self.0));
608 Addr { client: a.client as i32, port: a.port as i32 }
609 } }
610 pub fn get_queue(&self) -> i32 { unsafe { alsa::snd_seq_query_subscribe_get_queue(self.0) as i32 } }
611 pub fn get_exclusive(&self) -> bool { unsafe { alsa::snd_seq_query_subscribe_get_exclusive(self.0) == 1 } }
612 pub fn get_time_update(&self) -> bool { unsafe { alsa::snd_seq_query_subscribe_get_time_update(self.0) == 1 } }
613 pub fn get_time_real(&self) -> bool { unsafe { alsa::snd_seq_query_subscribe_get_time_real(self.0) == 1 } }
614
615 pub fn set_root(&self, value: Addr) { unsafe {
616 let a = alsa::snd_seq_addr_t { client: value.client as c_uchar, port: value.port as c_uchar};
617 alsa::snd_seq_query_subscribe_set_root(self.0, &a);
618 } }
619 pub fn set_type(&self, value: QuerySubsType) { unsafe {
620 alsa::snd_seq_query_subscribe_set_type(self.0, value as alsa::snd_seq_query_subs_type_t)
621 } }
622 pub fn set_index(&self, value: i32) { unsafe { alsa::snd_seq_query_subscribe_set_index(self.0, value as c_int) } }
623}
624
625#[derive(Copy, Clone, Debug)]
626pub struct PortSubscribeIter<'a> {
628 seq: &'a Seq,
629 addr: Addr,
630 query_subs_type: QuerySubsType,
631 index: i32
632}
633
634impl<'a> PortSubscribeIter<'a> {
635 pub fn new(seq: &'a Seq, addr: Addr, query_subs_type: QuerySubsType) -> Self {
636 PortSubscribeIter {seq, addr, query_subs_type, index: 0 }
637 }
638}
639
640impl<'a> Iterator for PortSubscribeIter<'a> {
641 type Item = PortSubscribe;
642
643 fn next(&mut self) -> Option<Self::Item> {
644 let query = QuerySubscribe::new().unwrap();
645
646 query.set_root(self.addr);
647 query.set_type(self.query_subs_type);
648 query.set_index(self.index);
649
650 let r = unsafe { alsa::snd_seq_query_port_subscribers((self.seq).0, query.0) };
651 if r < 0 {
652 self.index = 0;
653 return None;
654 }
655
656 self.index = query.get_index() + 1;
657 let vtr = PortSubscribe::new().unwrap();
658 match self.query_subs_type {
659 QuerySubsType::READ => {
660 vtr.set_sender(self.addr);
661 vtr.set_dest(query.get_addr());
662 },
663 QuerySubsType:: WRITE => {
664 vtr.set_sender(query.get_addr());
665 vtr.set_dest(self.addr);
666 }
667 };
668 vtr.set_queue(query.get_queue());
669 vtr.set_exclusive(query.get_exclusive());
670 vtr.set_time_update(query.get_time_update());
671 vtr.set_time_real(query.get_time_real());
672
673 Some(vtr)
674 }
675}
676
677pub struct Event<'a>(alsa::snd_seq_event_t, EventType, Option<Cow<'a, [u8]>>);
685
686unsafe impl<'a> Send for Event<'a> {}
687
688impl<'a> Event<'a> {
689 pub fn new<D: EventData>(t: EventType, data: &D) -> Event<'static> {
691 assert!(!Event::has_ext_data(t), "event type must not carry variable-length data");
692 let mut z = Event(unsafe { mem::zeroed() }, t, None);
693 (z.0).type_ = t as c_uchar;
694 (z.0).flags |= Event::get_length_flag(t);
695 debug_assert!(D::has_data(t));
696 data.set_data(&mut z);
697 z
698 }
699
700 pub fn new_ext<D: Into<Cow<'a, [u8]>>>(t: EventType, data: D) -> Event<'a> {
702 assert!(Event::has_ext_data(t), "event type must carry variable-length data");
703 let mut z = Event(unsafe { mem::zeroed() }, t, Some(data.into()));
704 (z.0).type_ = t as c_uchar;
705 (z.0).flags |= Event::get_length_flag(t);
706 z
707 }
708
709 pub fn into_owned(self) -> Event<'static> {
713 Event(self.0, self.1, self.2.map(|cow| Cow::Owned(cow.into_owned())))
714 }
715
716 fn get_length_flag(t: EventType) -> u8 {
717 match t {
718 EventType::Sysex => alsa::SND_SEQ_EVENT_LENGTH_VARIABLE,
719 EventType::Bounce => alsa::SND_SEQ_EVENT_LENGTH_VARIABLE, EventType::UsrVar0 => alsa::SND_SEQ_EVENT_LENGTH_VARUSR,
721 EventType::UsrVar1 => alsa::SND_SEQ_EVENT_LENGTH_VARUSR,
722 EventType::UsrVar2 => alsa::SND_SEQ_EVENT_LENGTH_VARUSR,
723 EventType::UsrVar3 => alsa::SND_SEQ_EVENT_LENGTH_VARUSR,
724 EventType::UsrVar4 => alsa::SND_SEQ_EVENT_LENGTH_VARUSR,
725 _ => alsa::SND_SEQ_EVENT_LENGTH_FIXED
726 }
727 }
728
729 fn has_ext_data(t: EventType) -> bool {
730 Event::get_length_flag(t) != alsa::SND_SEQ_EVENT_LENGTH_FIXED
731 }
732
733 unsafe fn extract<'any>(z: &mut alsa::snd_seq_event_t, func: &'static str) -> Result<Event<'any>> {
735 let t = EventType::from_c_int((*z).type_ as c_int, func)?;
736 let ext_data = if Event::has_ext_data(t) {
737 assert_ne!((*z).flags & alsa::SND_SEQ_EVENT_LENGTH_MASK, alsa::SND_SEQ_EVENT_LENGTH_FIXED);
738 Some(Cow::Borrowed({
739 let zz: &EvExtPacked = &*(&(*z).data as *const alsa::snd_seq_event_data as *const _);
740 slice::from_raw_parts((*zz).ptr as *mut u8, (*zz).len as usize)
741 }))
742 } else {
743 None
744 };
745 Ok(Event(ptr::read(z), t, ext_data))
746 }
747
748 fn ensure_buf(&mut self) {
751 if !Event::has_ext_data(self.1) { return; }
752 let slice: &[u8] = match self.2 {
753 Some(Cow::Owned(ref mut vec)) => &vec[..],
754 Some(Cow::Borrowed(buf)) => buf,
755 None => panic!("event type requires variable-length data, but none was provided")
757 };
758 let z: &mut EvExtPacked = unsafe { &mut *(&mut self.0.data as *mut alsa::snd_seq_event_data as *mut _) };
759 z.len = slice.len() as c_uint;
760 z.ptr = slice.as_ptr() as *mut c_void;
761 }
762
763 #[inline]
764 pub fn get_type(&self) -> EventType { self.1 }
765
766 pub fn get_data<D: EventData>(&self) -> Option<D> { if D::has_data(self.1) { Some(D::get_data(self)) } else { None } }
769
770 pub fn get_ext(&self) -> Option<&[u8]> {
772 if Event::has_ext_data(self.1) {
773 match self.2 {
774 Some(Cow::Owned(ref vec)) => Some(&vec[..]),
775 Some(Cow::Borrowed(buf)) => Some(buf),
776 None => panic!("event type requires variable-length data, but none was found")
778 }
779 } else {
780 None
781 }
782 }
783
784 pub fn set_subs(&mut self) {
785 self.0.dest.client = alsa::SND_SEQ_ADDRESS_SUBSCRIBERS;
786 self.0.dest.port = alsa::SND_SEQ_ADDRESS_UNKNOWN;
787 }
788
789 pub fn set_source(&mut self, p: i32) { self.0.source.port = p as u8 }
790 pub fn set_dest(&mut self, d: Addr) { self.0.dest.client = d.client as c_uchar; self.0.dest.port = d.port as c_uchar; }
791 pub fn set_tag(&mut self, t: u8) { self.0.tag = t as c_uchar; }
792 pub fn set_queue(&mut self, q: i32) { self.0.queue = q as c_uchar; }
793
794 pub fn get_source(&self) -> Addr { Addr { client: self.0.source.client as i32, port: self.0.source.port as i32 } }
795 pub fn get_dest(&self) -> Addr { Addr { client: self.0.dest.client as i32, port: self.0.dest.port as i32 } }
796 pub fn get_tag(&self) -> u8 { self.0.tag as u8 }
797 pub fn get_queue(&self) -> i32 { self.0.queue as i32 }
798
799 pub fn schedule_real(&mut self, queue: i32, relative: bool, rtime: time::Duration) {
800 self.0.flags &= !(alsa::SND_SEQ_TIME_STAMP_MASK | alsa::SND_SEQ_TIME_MODE_MASK);
801 self.0.flags |= alsa::SND_SEQ_TIME_STAMP_REAL | (if relative { alsa::SND_SEQ_TIME_MODE_REL } else { alsa::SND_SEQ_TIME_MODE_ABS });
802 self.0.queue = queue as u8;
803 let t = unsafe { &mut self.0.time.time };
804 t.tv_sec = rtime.as_secs() as c_uint;
805 t.tv_nsec = rtime.subsec_nanos() as c_uint;
806 }
807
808 pub fn schedule_tick(&mut self, queue: i32, relative: bool, ttime: u32) {
809 self.0.flags &= !(alsa::SND_SEQ_TIME_STAMP_MASK | alsa::SND_SEQ_TIME_MODE_MASK);
810 self.0.flags |= alsa::SND_SEQ_TIME_STAMP_TICK | (if relative { alsa::SND_SEQ_TIME_MODE_REL } else { alsa::SND_SEQ_TIME_MODE_ABS });
811 self.0.queue = queue as u8;
812 let t = unsafe { &mut self.0.time.tick };
813 *t = ttime as c_uint;
814 }
815
816 pub fn set_direct(&mut self) { self.0.queue = alsa::SND_SEQ_QUEUE_DIRECT }
817
818 pub fn get_relative(&self) -> bool { (self.0.flags & alsa::SND_SEQ_TIME_MODE_REL) != 0 }
819
820 pub fn get_time(&self) -> Option<time::Duration> {
821 if (self.0.flags & alsa::SND_SEQ_TIME_STAMP_REAL) != 0 {
822 let d = self.0.time;
823 let t = unsafe { &d.time };
824 Some(time::Duration::new(t.tv_sec as u64, t.tv_nsec as u32))
825 } else { None }
826 }
827
828 pub fn get_tick(&self) -> Option<u32> {
829 if (self.0.flags & alsa::SND_SEQ_TIME_STAMP_REAL) == 0 {
830 let d = self.0.time;
831 let t = unsafe { &d.tick };
832 Some(*t)
833 } else { None }
834 }
835
836 pub fn get_priority(&self) -> bool { (self.0.flags & alsa::SND_SEQ_PRIORITY_HIGH) != 0 }
838
839 pub fn set_priority(&mut self, is_high_prio: bool) {
840 if is_high_prio { self.0.flags |= alsa::SND_SEQ_PRIORITY_HIGH; }
841 else { self.0.flags &= !alsa::SND_SEQ_PRIORITY_HIGH; }
842 }
843}
844
845impl<'a> Clone for Event<'a> {
846 fn clone(&self) -> Self { Event(unsafe { ptr::read(&self.0) }, self.1, self.2.clone()) }
847}
848
849impl<'a> fmt::Debug for Event<'a> {
850 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
851 let mut x = f.debug_tuple("Event");
852 x.field(&self.1);
853 if let Some(z) = self.get_data::<EvNote>() { x.field(&z); }
854 if let Some(z) = self.get_data::<EvCtrl>() { x.field(&z); }
855 if let Some(z) = self.get_data::<Addr>() { x.field(&z); }
856 if let Some(z) = self.get_data::<Connect>() { x.field(&z); }
857 if let Some(z) = self.get_data::<EvQueueControl<()>>() { x.field(&z); }
858 if let Some(z) = self.get_data::<EvQueueControl<i32>>() { x.field(&z); }
859 if let Some(z) = self.get_data::<EvQueueControl<u32>>() { x.field(&z); }
860 if let Some(z) = self.get_data::<EvQueueControl<time::Duration>>() { x.field(&z); }
861 if let Some(z) = self.get_data::<EvResult>() { x.field(&z); }
862 if let Some(z) = self.get_data::<[u8; 12]>() { x.field(&z); }
863 if let Some(z) = self.get_ext() { x.field(&z); }
864 x.finish()
865 }
866}
867
868pub trait EventData {
872 #[doc(hidden)]
873 fn get_data(ev: &Event) -> Self;
874 #[doc(hidden)]
875 fn has_data(e: EventType) -> bool;
876 #[doc(hidden)]
877 fn set_data(&self, ev: &mut Event);
878}
879
880impl EventData for () {
881 fn get_data(_: &Event) -> Self {}
882 fn has_data(e: EventType) -> bool {
883 matches!(e,
884 EventType::TuneRequest |
885 EventType::Reset |
886 EventType::Sensing |
887 EventType::None)
888 }
889 fn set_data(&self, _: &mut Event) {}
890}
891
892impl EventData for [u8; 12] {
893 fn get_data(ev: &Event) -> Self {
894 let d = unsafe { ptr::read(&ev.0.data) };
895 let z = unsafe { &d.raw8 };
896 z.d
897 }
898 fn has_data(e: EventType) -> bool {
899 matches!(e,
900 EventType::Echo |
901 EventType::Oss |
902 EventType::Usr0 |
903 EventType::Usr1 |
904 EventType::Usr2 |
905 EventType::Usr3 |
906 EventType::Usr4 |
907 EventType::Usr5 |
908 EventType::Usr6 |
909 EventType::Usr7 |
910 EventType::Usr8 |
911 EventType::Usr9)
912 }
913 fn set_data(&self, ev: &mut Event) {
914 let z = unsafe { &mut ev.0.data.raw8 };
915 z.d = *self;
916 }
917}
918
919
920#[derive(Copy, Clone, Debug, PartialEq, Eq, Ord, PartialOrd, Hash, Default)]
921pub struct EvNote {
922 pub channel: u8,
923 pub note: u8,
924 pub velocity: u8,
925 pub off_velocity: u8,
926 pub duration: u32,
927}
928
929impl EventData for EvNote {
930 fn get_data(ev: &Event) -> Self {
931 let z: &alsa::snd_seq_ev_note_t = unsafe { &*(&ev.0.data as *const alsa::snd_seq_event_data as *const _) };
932 EvNote { channel: z.channel as u8, note: z.note as u8, velocity: z.velocity as u8, off_velocity: z.off_velocity as u8, duration: z.duration as u32 }
933 }
934 fn has_data(e: EventType) -> bool {
935 matches!(e,
936 EventType::Note |
937 EventType::Noteon |
938 EventType::Noteoff |
939 EventType::Keypress)
940 }
941 fn set_data(&self, ev: &mut Event) {
942 let z: &mut alsa::snd_seq_ev_note_t = unsafe { &mut *(&mut ev.0.data as *mut alsa::snd_seq_event_data as *mut _) };
943 z.channel = self.channel as c_uchar;
944 z.note = self.note as c_uchar;
945 z.velocity = self.velocity as c_uchar;
946 z.off_velocity = self.off_velocity as c_uchar;
947 z.duration = self.duration as c_uint;
948 }
949}
950
951#[derive(Copy, Clone, Debug, PartialEq, Eq, Ord, PartialOrd, Hash, Default)]
952pub struct EvCtrl {
953 pub channel: u8,
954 pub param: u32,
955 pub value: i32,
956}
957
958impl EventData for EvCtrl {
959 fn get_data(ev: &Event) -> Self {
960 let z: &alsa::snd_seq_ev_ctrl_t = unsafe { &*(&ev.0.data as *const alsa::snd_seq_event_data as *const _) };
961 EvCtrl { channel: z.channel as u8, param: z.param as u32, value: z.value as i32 }
962 }
963 fn has_data(e: EventType) -> bool {
964 matches!(e,
965 EventType::Controller |
966 EventType::Pgmchange |
967 EventType::Chanpress |
968 EventType::Pitchbend |
969 EventType::Control14 |
970 EventType::Nonregparam |
971 EventType::Regparam |
972 EventType::Songpos |
973 EventType::Songsel |
974 EventType::Qframe |
975 EventType::Timesign |
976 EventType::Keysign)
977 }
978 fn set_data(&self, ev: &mut Event) {
979 let z: &mut alsa::snd_seq_ev_ctrl_t = unsafe { &mut *(&mut ev.0.data as *mut alsa::snd_seq_event_data as *mut _) };
980 z.channel = self.channel as c_uchar;
981 z.param = self.param as c_uint;
982 z.value = self.value as c_int;
983 }
984}
985
986impl EventData for Addr {
987 fn get_data(ev: &Event) -> Self {
988 let z: &alsa::snd_seq_addr_t = unsafe { &*(&ev.0.data as *const alsa::snd_seq_event_data as *const _) };
989 Addr { client: z.client as i32, port: z.port as i32 }
990 }
991 fn has_data(e: EventType) -> bool {
992 matches!(e,
993 EventType::ClientStart |
994 EventType::ClientExit |
995 EventType::ClientChange |
996 EventType::PortStart |
997 EventType::PortExit |
998 EventType::PortChange)
999 }
1000 fn set_data(&self, ev: &mut Event) {
1001 let z: &mut alsa::snd_seq_addr_t = unsafe { &mut *(&mut ev.0.data as *mut alsa::snd_seq_event_data as *mut _) };
1002 z.client = self.client as c_uchar;
1003 z.port = self.port as c_uchar;
1004 }
1005}
1006
1007#[derive(Copy, Clone, Debug, PartialEq, Eq, Ord, PartialOrd, Hash, Default)]
1008pub struct Connect {
1010 pub sender: Addr,
1011 pub dest: Addr,
1012}
1013
1014impl EventData for Connect {
1015 fn get_data(ev: &Event) -> Self {
1016 let d = unsafe { ptr::read(&ev.0.data) };
1017 let z = unsafe { &d.connect };
1018 Connect {
1019 sender: Addr { client: z.sender.client as i32, port: z.sender.port as i32 },
1020 dest: Addr { client: z.dest.client as i32, port: z.dest.port as i32 }
1021 }
1022 }
1023 fn has_data(e: EventType) -> bool {
1024 matches!(e,
1025 EventType::PortSubscribed |
1026 EventType::PortUnsubscribed)
1027 }
1028 fn set_data(&self, ev: &mut Event) {
1029 let z = unsafe { &mut ev.0.data.connect };
1030 z.sender.client = self.sender.client as c_uchar;
1031 z.sender.port = self.sender.port as c_uchar;
1032 z.dest.client = self.dest.client as c_uchar;
1033 z.dest.port = self.dest.port as c_uchar;
1034 }
1035}
1036
1037#[derive(Copy, Clone, Debug, PartialEq, Eq, Ord, PartialOrd, Hash, Default)]
1038pub struct EvQueueControl<T> {
1044 pub queue: i32,
1045 pub value: T,
1046}
1047
1048impl EventData for EvQueueControl<()> {
1049 fn get_data(ev: &Event) -> Self {
1050 let d = unsafe { ptr::read(&ev.0.data) };
1051 let z = unsafe { &d.queue };
1052 EvQueueControl { queue: z.queue as i32, value: () }
1053 }
1054 fn has_data(e: EventType) -> bool {
1055 matches!(e,
1056 EventType::Start |
1057 EventType::Continue |
1058 EventType::Stop |
1059 EventType::Clock |
1060 EventType::QueueSkew)
1061 }
1062 fn set_data(&self, ev: &mut Event) {
1063 let z = unsafe { &mut ev.0.data.queue };
1064 z.queue = self.queue as c_uchar;
1065 }
1066}
1067
1068impl EventData for EvQueueControl<i32> {
1069 fn get_data(ev: &Event) -> Self { unsafe {
1070 let mut d = ptr::read(&ev.0.data);
1071 let z = &mut d.queue;
1072 EvQueueControl { queue: z.queue as i32, value: z.param.value as i32 }
1073 } }
1074 fn has_data(e: EventType) -> bool {
1075 matches!(e,
1076 EventType::Tempo)
1077 }
1078 fn set_data(&self, ev: &mut Event) { unsafe {
1079 let z = &mut ev.0.data.queue;
1080 z.queue = self.queue as c_uchar;
1081 z.param.value = self.value as c_int;
1082 } }
1083}
1084
1085impl EventData for EvQueueControl<u32> {
1086 fn get_data(ev: &Event) -> Self { unsafe {
1087 let mut d = ptr::read(&ev.0.data);
1088 let z = &mut d.queue;
1089 EvQueueControl { queue: z.queue as i32, value: z.param.position as u32 }
1090 } }
1091 fn has_data(e: EventType) -> bool {
1092 matches!(e,
1093 EventType::SyncPos |
1094 EventType::Tick |
1095 EventType::SetposTick)
1096 }
1097 fn set_data(&self, ev: &mut Event) { unsafe {
1098 let z = &mut ev.0.data.queue;
1099 z.queue = self.queue as c_uchar;
1100 z.param.position = self.value as c_uint;
1101 } }
1102}
1103
1104impl EventData for EvQueueControl<time::Duration> {
1105 fn get_data(ev: &Event) -> Self { unsafe {
1106 let mut d = ptr::read(&ev.0.data);
1107 let z = &mut d.queue;
1108 let t = &mut z.param.time.time;
1109 EvQueueControl { queue: z.queue as i32, value: time::Duration::new(t.tv_sec as u64, t.tv_nsec as u32) }
1110 } }
1111 fn has_data(e: EventType) -> bool {
1112 matches!(e,
1113 EventType::SetposTime)
1114 }
1115 fn set_data(&self, ev: &mut Event) { unsafe {
1116 let z = &mut ev.0.data.queue;
1117 z.queue = self.queue as c_uchar;
1118 let t = &mut z.param.time.time;
1119 t.tv_sec = self.value.as_secs() as c_uint;
1120 t.tv_nsec = self.value.subsec_nanos() as c_uint;
1121 } }
1122}
1123
1124#[derive(Copy, Clone, Debug, PartialEq, Eq, Ord, PartialOrd, Hash, Default)]
1125pub struct EvResult {
1129 pub event: i32,
1130 pub result: i32,
1131}
1132
1133impl EventData for EvResult {
1134 fn get_data(ev: &Event) -> Self {
1135 let d = unsafe { ptr::read(&ev.0.data) };
1136 let z = unsafe { &d.result };
1137 EvResult { event: z.event as i32, result: z.result as i32 }
1138 }
1139 fn has_data(e: EventType) -> bool {
1140 matches!(e,
1141 EventType::System |
1142 EventType::Result)
1143 }
1144 fn set_data(&self, ev: &mut Event) {
1145 let z = unsafe { &mut ev.0.data.result };
1146 z.event = self.event as c_int;
1147 z.result = self.result as c_int;
1148 }
1149}
1150
1151
1152
1153alsa_enum!(
1154 EventType, ALL_EVENT_TYPES[59],
1157
1158 Bounce = SND_SEQ_EVENT_BOUNCE,
1159 Chanpress = SND_SEQ_EVENT_CHANPRESS,
1160 ClientChange = SND_SEQ_EVENT_CLIENT_CHANGE,
1161 ClientExit = SND_SEQ_EVENT_CLIENT_EXIT,
1162 ClientStart = SND_SEQ_EVENT_CLIENT_START,
1163 Clock = SND_SEQ_EVENT_CLOCK,
1164 Continue = SND_SEQ_EVENT_CONTINUE,
1165 Control14 = SND_SEQ_EVENT_CONTROL14,
1166 Controller = SND_SEQ_EVENT_CONTROLLER,
1167 Echo = SND_SEQ_EVENT_ECHO,
1168 Keypress = SND_SEQ_EVENT_KEYPRESS,
1169 Keysign = SND_SEQ_EVENT_KEYSIGN,
1170 None = SND_SEQ_EVENT_NONE,
1171 Nonregparam = SND_SEQ_EVENT_NONREGPARAM,
1172 Note = SND_SEQ_EVENT_NOTE,
1173 Noteoff = SND_SEQ_EVENT_NOTEOFF,
1174 Noteon = SND_SEQ_EVENT_NOTEON,
1175 Oss = SND_SEQ_EVENT_OSS,
1176 Pgmchange = SND_SEQ_EVENT_PGMCHANGE,
1177 Pitchbend = SND_SEQ_EVENT_PITCHBEND,
1178 PortChange = SND_SEQ_EVENT_PORT_CHANGE,
1179 PortExit = SND_SEQ_EVENT_PORT_EXIT,
1180 PortStart = SND_SEQ_EVENT_PORT_START,
1181 PortSubscribed = SND_SEQ_EVENT_PORT_SUBSCRIBED,
1182 PortUnsubscribed = SND_SEQ_EVENT_PORT_UNSUBSCRIBED,
1183 Qframe = SND_SEQ_EVENT_QFRAME,
1184 QueueSkew = SND_SEQ_EVENT_QUEUE_SKEW,
1185 Regparam = SND_SEQ_EVENT_REGPARAM,
1186 Reset = SND_SEQ_EVENT_RESET,
1187 Result = SND_SEQ_EVENT_RESULT,
1188 Sensing = SND_SEQ_EVENT_SENSING,
1189 SetposTick = SND_SEQ_EVENT_SETPOS_TICK,
1190 SetposTime = SND_SEQ_EVENT_SETPOS_TIME,
1191 Songpos = SND_SEQ_EVENT_SONGPOS,
1192 Songsel = SND_SEQ_EVENT_SONGSEL,
1193 Start = SND_SEQ_EVENT_START,
1194 Stop = SND_SEQ_EVENT_STOP,
1195 SyncPos = SND_SEQ_EVENT_SYNC_POS,
1196 Sysex = SND_SEQ_EVENT_SYSEX,
1197 System = SND_SEQ_EVENT_SYSTEM,
1198 Tempo = SND_SEQ_EVENT_TEMPO,
1199 Tick = SND_SEQ_EVENT_TICK,
1200 Timesign = SND_SEQ_EVENT_TIMESIGN,
1201 TuneRequest = SND_SEQ_EVENT_TUNE_REQUEST,
1202 Usr0 = SND_SEQ_EVENT_USR0,
1203 Usr1 = SND_SEQ_EVENT_USR1,
1204 Usr2 = SND_SEQ_EVENT_USR2,
1205 Usr3 = SND_SEQ_EVENT_USR3,
1206 Usr4 = SND_SEQ_EVENT_USR4,
1207 Usr5 = SND_SEQ_EVENT_USR5,
1208 Usr6 = SND_SEQ_EVENT_USR6,
1209 Usr7 = SND_SEQ_EVENT_USR7,
1210 Usr8 = SND_SEQ_EVENT_USR8,
1211 Usr9 = SND_SEQ_EVENT_USR9,
1212 UsrVar0 = SND_SEQ_EVENT_USR_VAR0,
1213 UsrVar1 = SND_SEQ_EVENT_USR_VAR1,
1214 UsrVar2 = SND_SEQ_EVENT_USR_VAR2,
1215 UsrVar3 = SND_SEQ_EVENT_USR_VAR3,
1216 UsrVar4 = SND_SEQ_EVENT_USR_VAR4,
1217);
1218
1219#[derive(Debug)]
1221pub struct QueueTempo(*mut alsa::snd_seq_queue_tempo_t);
1222
1223unsafe impl Send for QueueTempo {}
1224
1225impl Drop for QueueTempo {
1226 fn drop(&mut self) { unsafe { alsa::snd_seq_queue_tempo_free(self.0) } }
1227}
1228
1229impl QueueTempo {
1230 fn new() -> Result<Self> {
1231 let mut q = ptr::null_mut();
1232 acheck!(snd_seq_queue_tempo_malloc(&mut q)).map(|_| QueueTempo(q))
1233 }
1234
1235 pub fn empty() -> Result<Self> {
1237 let q = QueueTempo::new()?;
1238 unsafe { ptr::write_bytes(q.0 as *mut u8, 0, alsa::snd_seq_queue_tempo_sizeof()) };
1239 Ok(q)
1240 }
1241
1242 pub fn get_queue(&self) -> i32 { unsafe { alsa::snd_seq_queue_tempo_get_queue(self.0) as i32 } }
1243 pub fn get_tempo(&self) -> u32 { unsafe { alsa::snd_seq_queue_tempo_get_tempo(self.0) as u32 } }
1244 pub fn get_ppq(&self) -> i32 { unsafe { alsa::snd_seq_queue_tempo_get_ppq(self.0) as i32 } }
1245 pub fn get_skew(&self) -> u32 { unsafe { alsa::snd_seq_queue_tempo_get_skew(self.0) as u32 } }
1246 pub fn get_skew_base(&self) -> u32 { unsafe { alsa::snd_seq_queue_tempo_get_skew_base(self.0) as u32 } }
1247
1248pub fn set_tempo(&self, value: u32) { unsafe { alsa::snd_seq_queue_tempo_set_tempo(self.0, value as c_uint) } }
1250 pub fn set_ppq(&self, value: i32) { unsafe { alsa::snd_seq_queue_tempo_set_ppq(self.0, value as c_int) } }
1251 pub fn set_skew(&self, value: u32) { unsafe { alsa::snd_seq_queue_tempo_set_skew(self.0, value as c_uint) } }
1252 pub fn set_skew_base(&self, value: u32) { unsafe { alsa::snd_seq_queue_tempo_set_skew_base(self.0, value as c_uint) } }
1253}
1254
1255#[derive(Debug)]
1257pub struct QueueStatus(*mut alsa::snd_seq_queue_status_t);
1258
1259unsafe impl Send for QueueStatus {}
1260
1261impl Drop for QueueStatus {
1262 fn drop(&mut self) { unsafe { alsa::snd_seq_queue_status_free(self.0) } }
1263}
1264
1265impl QueueStatus {
1266 fn new() -> Result<Self> {
1267 let mut q = ptr::null_mut();
1268 acheck!(snd_seq_queue_status_malloc(&mut q)).map(|_| QueueStatus(q))
1269 }
1270
1271 pub fn empty() -> Result<Self> {
1273 let q = QueueStatus::new()?;
1274 unsafe { ptr::write_bytes(q.0 as *mut u8, 0, alsa::snd_seq_queue_status_sizeof()) };
1275 Ok(q)
1276 }
1277
1278 pub fn get_queue(&self) -> i32 { unsafe { alsa::snd_seq_queue_status_get_queue(self.0) as i32 } }
1279 pub fn get_events(&self) -> i32 { unsafe { alsa::snd_seq_queue_status_get_events(self.0) as i32 } }
1280 pub fn get_tick_time(&self) -> u32 { unsafe {alsa::snd_seq_queue_status_get_tick_time(self.0) as u32 } }
1281 pub fn get_real_time(&self) -> time::Duration { unsafe {
1282 let t = &(*alsa::snd_seq_queue_status_get_real_time(self.0));
1283 time::Duration::new(t.tv_sec as u64, t.tv_nsec as u32)
1284 } }
1285 pub fn get_status(&self) -> u32 { unsafe { alsa::snd_seq_queue_status_get_status(self.0) as u32 } }
1286}
1287
1288#[derive(Debug)]
1290pub struct RemoveEvents(*mut alsa::snd_seq_remove_events_t);
1291
1292unsafe impl Send for RemoveEvents {}
1293
1294impl Drop for RemoveEvents {
1295 fn drop(&mut self) { unsafe { alsa::snd_seq_remove_events_free(self.0) } }
1296}
1297
1298impl RemoveEvents {
1299 pub fn new() -> Result<Self> {
1300 let mut q = ptr::null_mut();
1301 acheck!(snd_seq_remove_events_malloc(&mut q)).map(|_| RemoveEvents(q))
1302 }
1303
1304 pub fn get_condition(&self) -> Remove { unsafe {
1305 Remove::from_bits_truncate(alsa::snd_seq_remove_events_get_condition(self.0) as u32)
1306 } }
1307 pub fn get_queue(&self) -> i32 { unsafe { alsa::snd_seq_remove_events_get_queue(self.0) as i32 } }
1308 pub fn get_time(&self) -> time::Duration { unsafe {
1309 let d = ptr::read(alsa::snd_seq_remove_events_get_time(self.0));
1310 let t = &d.time;
1311
1312 time::Duration::new(t.tv_sec as u64, t.tv_nsec as u32)
1313 } }
1314 pub fn get_dest(&self) -> Addr { unsafe {
1315 let a = &(*alsa::snd_seq_remove_events_get_dest(self.0));
1316
1317 Addr { client: a.client as i32, port: a.port as i32 }
1318 } }
1319 pub fn get_channel(&self) -> i32 { unsafe { alsa::snd_seq_remove_events_get_channel(self.0) as i32 } }
1320 pub fn get_event_type(&self) -> Result<EventType> { unsafe {
1321 EventType::from_c_int(alsa::snd_seq_remove_events_get_event_type(self.0), "snd_seq_remove_events_get_event_type")
1322 } }
1323 pub fn get_tag(&self) -> u8 { unsafe { alsa::snd_seq_remove_events_get_tag(self.0) as u8 } }
1324
1325
1326 pub fn set_condition(&self, value: Remove) { unsafe {
1327 alsa::snd_seq_remove_events_set_condition(self.0, value.bits() as c_uint);
1328 } }
1329 pub fn set_queue(&self, value: i32) { unsafe { alsa::snd_seq_remove_events_set_queue(self.0, value as c_int) } }
1330 pub fn set_time(&self, value: time::Duration) { unsafe {
1331 let mut d: alsa::snd_seq_timestamp_t = mem::zeroed();
1332 let t = &mut d.time;
1333
1334 t.tv_sec = value.as_secs() as c_uint;
1335 t.tv_nsec = value.subsec_nanos() as c_uint;
1336
1337 alsa::snd_seq_remove_events_set_time(self.0, &d);
1338 } }
1339 pub fn set_dest(&self, value: Addr) { unsafe {
1340 let a = alsa::snd_seq_addr_t { client: value.client as c_uchar, port: value.port as c_uchar};
1341
1342 alsa::snd_seq_remove_events_set_dest(self.0, &a);
1343 } }
1344 pub fn set_channel(&self, value: i32) { unsafe { alsa::snd_seq_remove_events_set_channel(self.0, value as c_int) } }
1345 pub fn set_event_type(&self, value: EventType) { unsafe { alsa::snd_seq_remove_events_set_event_type(self.0, value as i32); } }
1346 pub fn set_tag(&self, value: u8) { unsafe { alsa::snd_seq_remove_events_set_tag(self.0, value as c_int) } }
1347}
1348
1349#[derive(Debug)]
1353pub struct MidiEvent(*mut alsa::snd_midi_event_t);
1354
1355impl Drop for MidiEvent {
1356 fn drop(&mut self) { unsafe { alsa::snd_midi_event_free(self.0) } }
1357}
1358
1359impl MidiEvent {
1360 pub fn new(bufsize: u32) -> Result<MidiEvent> {
1361 let mut q = ptr::null_mut();
1362 acheck!(snd_midi_event_new(bufsize as size_t, &mut q)).map(|_| MidiEvent(q))
1363 }
1364
1365 pub fn resize_buffer(&self, bufsize: u32) -> Result<()> { acheck!(snd_midi_event_resize_buffer(self.0, bufsize as size_t)).map(|_| ()) }
1366
1367 pub fn enable_running_status(&self, enable: bool) { unsafe { alsa::snd_midi_event_no_status(self.0, if enable {0} else {1}) } }
1371
1372 pub fn init(&self) { unsafe { alsa::snd_midi_event_init(self.0) } }
1374
1375 pub fn reset_encode(&self) { unsafe { alsa::snd_midi_event_reset_encode(self.0) } }
1376
1377 pub fn reset_decode(&self) { unsafe { alsa::snd_midi_event_reset_decode(self.0) } }
1378
1379 pub fn decode(&self, buf: &mut [u8], ev: &mut Event) -> Result<usize> {
1380 ev.ensure_buf();
1381 acheck!(snd_midi_event_decode(self.0, buf.as_mut_ptr() as *mut c_uchar, buf.len() as c_long, &ev.0)).map(|r| r as usize)
1382 }
1383
1384 pub fn encode<'a>(&'a mut self, buf: &[u8]) -> Result<(usize, Option<Event<'a>>)> {
1386 let mut ev = unsafe { mem::zeroed() };
1391 let r = acheck!(snd_midi_event_encode(self.0, buf.as_ptr() as *const c_uchar, buf.len() as c_long, &mut ev))?;
1392 let e = if ev.type_ == alsa::SND_SEQ_EVENT_NONE as u8 {
1393 None
1394 } else {
1395 Some(unsafe { Event::extract(&mut ev, "snd_midi_event_encode") }?)
1396 };
1397 Ok((r as usize, e))
1398 }
1399}
1400
1401#[test]
1402fn print_seqs() {
1403 extern crate std;
1404 use ::alloc::ffi::CString;
1405 use ::alloc::vec::Vec;
1406 let s = super::Seq::open(None, None, false).unwrap();
1407 s.set_client_name(&CString::new("rust_test_print_seqs").unwrap()).unwrap();
1408 let clients: Vec<_> = ClientIter::new(&s).collect();
1409 for a in &clients {
1410 let ports: Vec<_> = PortIter::new(&s, a.get_client()).collect();
1411 std::println!("{:?}: {:?}", a, ports);
1412 }
1413}
1414
1415#[test]
1416fn seq_subscribe() {
1417 use ::alloc::ffi::CString;
1418 let s = super::Seq::open(None, None, false).unwrap();
1419 s.set_client_name(&CString::new("rust_test_seq_subscribe").unwrap()).unwrap();
1420 let timer_info = s.get_any_port_info(Addr { client: 0, port: 0 }).unwrap();
1421 assert_eq!(timer_info.get_name().unwrap(), "Timer");
1422 let info = PortInfo::empty().unwrap();
1423 let _port = s.create_port(&info);
1424 let subs = PortSubscribe::empty().unwrap();
1425 subs.set_sender(Addr { client: 0, port: 0 });
1426 subs.set_dest(Addr { client: s.client_id().unwrap(), port: info.get_port() });
1427 s.subscribe_port(&subs).unwrap();
1428}
1429
1430#[test]
1431fn seq_loopback() {
1432 extern crate std;
1433 use ::alloc::ffi::CString;
1434 let s = super::Seq::open(Some(&CString::new("default").unwrap()), None, false).unwrap();
1435 s.set_client_name(&CString::new("rust_test_seq_loopback").unwrap()).unwrap();
1436
1437 let sinfo = PortInfo::empty().unwrap();
1439 sinfo.set_capability(PortCap::READ | PortCap::SUBS_READ);
1440 sinfo.set_type(PortType::MIDI_GENERIC | PortType::APPLICATION);
1441 s.create_port(&sinfo).unwrap();
1442 let sport = sinfo.get_port();
1443 let dinfo = PortInfo::empty().unwrap();
1444 dinfo.set_capability(PortCap::WRITE | PortCap::SUBS_WRITE);
1445 dinfo.set_type(PortType::MIDI_GENERIC | PortType::APPLICATION);
1446 s.create_port(&dinfo).unwrap();
1447 let dport = dinfo.get_port();
1448
1449 let subs = PortSubscribe::empty().unwrap();
1451 subs.set_sender(Addr { client: s.client_id().unwrap(), port: sport });
1452 subs.set_dest(Addr { client: s.client_id().unwrap(), port: dport });
1453 s.subscribe_port(&subs).unwrap();
1454 std::println!("Connected {:?} to {:?}", subs.get_sender(), subs.get_dest());
1455
1456 let note = EvNote { channel: 0, note: 64, duration: 100, velocity: 100, off_velocity: 64 };
1458 let mut e = Event::new(EventType::Noteon, ¬e);
1459 e.set_subs();
1460 e.set_direct();
1461 e.set_source(sport);
1462 std::println!("Sending {:?}", e);
1463 s.event_output(&mut e).unwrap();
1464 s.drain_output().unwrap();
1465
1466 let mut input = s.input();
1468 let e2 = input.event_input().unwrap();
1469 std::println!("Receiving {:?}", e2);
1470 assert_eq!(e2.get_type(), EventType::Noteon);
1471 assert_eq!(e2.get_data(), Some(note));
1472}
1473
1474#[test]
1475fn seq_encode_sysex() {
1476 let mut me = MidiEvent::new(16).unwrap();
1477 let sysex = &[0xf0, 1, 2, 3, 4, 5, 6, 7, 0xf7];
1478 let (s, ev) = me.encode(sysex).unwrap();
1479 assert_eq!(s, 9);
1480 let ev = ev.unwrap();
1481 let v = ev.get_ext().unwrap();
1482 assert_eq!(&*v, sysex);
1483}
1484
1485#[test]
1486fn seq_decode_sysex() {
1487 let sysex = [0xf0, 1, 2, 3, 4, 5, 6, 7, 0xf7];
1488 let mut ev = Event::new_ext(EventType::Sysex, &sysex[..]);
1489 let me = MidiEvent::new(0).unwrap();
1490 let mut buffer = ::alloc::vec![0; sysex.len()];
1491 assert_eq!(me.decode(&mut buffer[..], &mut ev).unwrap(), sysex.len());
1492 assert_eq!(buffer, sysex);
1493}
1494
1495#[test]
1496#[should_panic]
1497fn seq_get_input_twice() {
1498 use ::alloc::ffi::CString;
1499 let s = super::Seq::open(None, None, false).unwrap();
1500 s.set_client_name(&CString::new("rust_test_seq_get_input_twice").unwrap()).unwrap();
1501 let input1 = s.input();
1502 let input2 = s.input(); let _ = (input1, input2);
1504}
1505
1506#[test]
1507fn seq_has_data() {
1508 for v in EventType::all() {
1509 let v = *v;
1510 let mut i = 0;
1511 if <() as EventData>::has_data(v) { i += 1; }
1512 if <[u8; 12] as EventData>::has_data(v) { i += 1; }
1513 if Event::has_ext_data(v) { i += 1; }
1514 if EvNote::has_data(v) { i += 1; }
1515 if EvCtrl::has_data(v) { i += 1; }
1516 if Addr::has_data(v) { i += 1; }
1517 if Connect::has_data(v) { i += 1; }
1518 if EvResult::has_data(v) { i += 1; }
1519 if EvQueueControl::<()>::has_data(v) { i += 1; }
1520 if EvQueueControl::<u32>::has_data(v) { i += 1; }
1521 if EvQueueControl::<i32>::has_data(v) { i += 1; }
1522 if EvQueueControl::<time::Duration>::has_data(v) { i += 1; }
1523 if i != 1 { panic!("{:?}: {} has_data", v, i) }
1524 }
1525}
1526
1527#[test]
1528fn seq_remove_events() -> core::result::Result<(), Box<dyn core::error::Error>> {
1529 let info = RemoveEvents::new()?;
1530
1531
1532 info.set_condition(Remove::INPUT | Remove::DEST | Remove::TIME_BEFORE | Remove::TAG_MATCH);
1533 info.set_queue(123);
1534 info.set_time(time::Duration::new(456, 789));
1535 info.set_dest(Addr { client: 212, port: 121 });
1536 info.set_channel(15);
1537 info.set_event_type(EventType::Noteon);
1538 info.set_tag(213);
1539
1540 assert_eq!(info.get_condition(), Remove::INPUT | Remove::DEST | Remove::TIME_BEFORE | Remove::TAG_MATCH);
1541 assert_eq!(info.get_queue(), 123);
1542 assert_eq!(info.get_time(), time::Duration::new(456, 789));
1543 assert_eq!(info.get_dest(), Addr { client: 212, port: 121 });
1544 assert_eq!(info.get_channel(), 15);
1545 assert_eq!(info.get_event_type()?, EventType::Noteon);
1546 assert_eq!(info.get_tag(), 213);
1547
1548 Ok(())
1549}
1550
1551#[test]
1552fn seq_portsubscribeiter() {
1553 use ::alloc::vec::Vec;
1554
1555 let s = super::Seq::open(None, None, false).unwrap();
1556
1557 let sinfo = PortInfo::empty().unwrap();
1559 sinfo.set_capability(PortCap::READ | PortCap::SUBS_READ);
1560 sinfo.set_type(PortType::MIDI_GENERIC | PortType::APPLICATION);
1561 s.create_port(&sinfo).unwrap();
1562 let sport = sinfo.get_port();
1563 let dinfo = PortInfo::empty().unwrap();
1564 dinfo.set_capability(PortCap::WRITE | PortCap::SUBS_WRITE);
1565 dinfo.set_type(PortType::MIDI_GENERIC | PortType::APPLICATION);
1566 s.create_port(&dinfo).unwrap();
1567 let dport = dinfo.get_port();
1568
1569 let subs = PortSubscribe::empty().unwrap();
1571 subs.set_sender(Addr { client: s.client_id().unwrap(), port: sport });
1572 subs.set_dest(Addr { client: s.client_id().unwrap(), port: dport });
1573 s.subscribe_port(&subs).unwrap();
1574
1575 let read_subs: Vec<PortSubscribe> = PortSubscribeIter::new(&s,
1577 Addr {client: s.client_id().unwrap(), port: sport },
1578 QuerySubsType::READ).collect();
1579 assert_eq!(read_subs.len(), 1);
1580 assert_eq!(read_subs[0].get_sender(), subs.get_sender());
1581 assert_eq!(read_subs[0].get_dest(), subs.get_dest());
1582
1583 let write_subs: Vec<PortSubscribe> = PortSubscribeIter::new(&s,
1584 Addr {client: s.client_id().unwrap(), port: sport },
1585 QuerySubsType::WRITE).collect();
1586 assert_eq!(write_subs.len(), 0);
1587
1588 let write_subs: Vec<PortSubscribe> = PortSubscribeIter::new(&s,
1590 Addr {client: s.client_id().unwrap(), port: dport },
1591 QuerySubsType::WRITE).collect();
1592 assert_eq!(write_subs.len(), 1);
1593 assert_eq!(write_subs[0].get_sender(), subs.get_sender());
1594 assert_eq!(write_subs[0].get_dest(), subs.get_dest());
1595}