alsa/direct/
ffi.rs
1#![allow(non_camel_case_types)]
4
5use cfg_if::cfg_if;
6
7pub const SNDRV_PCM_MMAP_OFFSET_STATUS: libc::c_uint = 0x80000000;
9pub const SNDRV_PCM_MMAP_OFFSET_CONTROL: libc::c_uint = 0x81000000;
10
11pub const SNDRV_PCM_SYNC_PTR_HWSYNC: libc::c_uint = 1;
12pub const SNDRV_PCM_SYNC_PTR_APPL: libc::c_uint = 2;
13pub const SNDRV_PCM_SYNC_PTR_AVAIL_MIN: libc::c_uint = 4;
14
15#[allow(non_camel_case_types)]
17pub type snd_pcm_state_t = libc::c_int;
18
19#[allow(non_camel_case_types)]
21pub type snd_pcm_uframes_t = libc::c_ulong;
22
23#[allow(non_camel_case_types)]
25pub type __kernel_off_t = libc::c_long;
26
27#[repr(C)]
28#[derive(Copy, Clone)]
29pub struct snd_pcm_mmap_status {
30 pub state: snd_pcm_state_t, pub pad1: libc::c_int, pub hw_ptr: snd_pcm_uframes_t, pub tstamp: libc::timespec, pub suspended_state: snd_pcm_state_t, pub audio_tstamp: libc::timespec, }
37
38#[repr(C)]
39#[derive(Debug, Copy, Clone)]
40pub struct snd_pcm_mmap_control {
41 pub appl_ptr: snd_pcm_uframes_t, pub avail_min: snd_pcm_uframes_t, }
44
45#[repr(C)]
46#[derive(Debug)]
47pub struct snd_pcm_channel_info {
48 pub channel: libc::c_uint,
49 pub offset: __kernel_off_t, pub first: libc::c_uint, pub step: libc::c_uint, }
53
54#[repr(C)]
55#[derive(Copy, Clone)]
56pub union snd_pcm_mmap_status_r {
57 pub status: snd_pcm_mmap_status,
58 pub reserved: [libc::c_uchar; 64],
59}
60
61#[repr(C)]
62#[derive(Copy, Clone)]
63pub union snd_pcm_mmap_control_r {
64 pub control: snd_pcm_mmap_control,
65 pub reserved: [libc::c_uchar; 64],
66}
67
68#[repr(C)]
69#[derive(Copy, Clone)]
70pub struct snd_pcm_sync_ptr {
71 pub flags: libc::c_uint,
72 pub s: snd_pcm_mmap_status_r,
73 pub c: snd_pcm_mmap_control_r,
74}
75
76cfg_if! {
77 if #[cfg(any(target_os = "linux", target_os = "android"))] {
78 cfg_if! {
81 if #[cfg(any(target_os = "android", target_env = "musl"))] {
82 pub(super) type ioctl_num_type = libc::c_int;
83 } else {
84 pub(super) type ioctl_num_type = libc::c_ulong;
85 }
86 }
87
88 pub(super) const READ: ioctl_num_type = 2;
90
91 cfg_if!{
93 if #[cfg(any(
94 target_arch = "mips",
95 target_arch = "mips32r6",
96 target_arch = "mips64",
97 target_arch = "mips64r6",
98 target_arch = "powerpc",
99 target_arch = "powerpc64",
100 target_arch = "sparc64"
101 ))] {
102 pub(super) const WRITE: ioctl_num_type = 4;
103 const SIZEBITS: ioctl_num_type = 13;
104 } else {
105 pub(super) const WRITE: ioctl_num_type = 1;
106 const SIZEBITS: ioctl_num_type = 14;
107 }
108 }
109
110 const NRSHIFT: ioctl_num_type = 0;
111 const NRBITS: ioctl_num_type = 8;
112 const TYPEBITS: ioctl_num_type = 8;
113 const TYPESHIFT: ioctl_num_type = NRSHIFT + NRBITS;
114 const SIZESHIFT: ioctl_num_type = TYPESHIFT + TYPEBITS;
115 const DIRSHIFT: ioctl_num_type = SIZESHIFT + SIZEBITS;
116
117 pub(super) const fn make_request(
119 dir: ioctl_num_type,
120 typ: u8,
121 nr: u8,
122 size: usize,
123 ) -> ioctl_num_type {
124 dir << DIRSHIFT
125 | (typ as ioctl_num_type) << TYPESHIFT
126 | (nr as ioctl_num_type) << NRSHIFT
127 | (size as ioctl_num_type) << SIZESHIFT
128 }
129 } else if #[cfg(any(
130 target_os = "dragonfly",
131 target_os = "freebsd",
132 target_os = "netbsd",
133 target_os = "openbsd",
134 target_os = "solaris",
135 target_os = "illumos"
136 ))] {
137 cfg_if! {
140 if #[cfg(not(any(target_os = "illumos", target_os = "solaris")))] {
141 pub(super) type ioctl_num_type = libc::c_ulong;
142 } else {
143 pub(super) type ioctl_num_type = libc::c_int;
144 }
145 }
146
147 #[allow(overflowing_literals)]
148 pub(super) const READ: ioctl_num_type = 0x4000_0000;
149 #[allow(overflowing_literals)]
150 pub(super) const WRITE: ioctl_num_type = 0x8000_0000;
151
152 const IOCPARM_MASK: ioctl_num_type = 0x1fff;
153
154 pub(super) const fn make_request(
156 dir: ioctl_num_type,
157 typ: u8,
158 nr: u8,
159 size: usize,
160 ) -> ioctl_num_type {
161 dir | ((size as ioctl_num_type) & IOCPARM_MASK) << 16
162 | (typ as ioctl_num_type) << 8
163 | nr as ioctl_num_type
164 }
165 } else {
166 compile_error!("unknown target platform");
167 }
168}
169
170pub(crate) unsafe fn sndrv_pcm_ioctl_channel_info(
171 fd: libc::c_int,
172 data: *mut snd_pcm_channel_info,
173) -> Result<(), crate::Error> {
174 const REQUEST: ioctl_num_type = make_request(
175 READ,
176 b'A',
177 0x32,
178 std::mem::size_of::<snd_pcm_channel_info>(),
179 );
180
181 unsafe {
182 if libc::ioctl(fd, REQUEST, data) == -1 {
183 Err(crate::Error::last("SNDRV_PCM_IOCTL_CHANNEL_INFO"))
184 } else {
185 Ok(())
186 }
187 }
188}
189
190pub(crate) unsafe fn sndrv_pcm_ioctl_sync_ptr(
191 fd: libc::c_int,
192 data: *mut snd_pcm_sync_ptr,
193) -> Result<(), crate::Error> {
194 const REQUEST: ioctl_num_type = make_request(
195 READ | WRITE,
196 b'A',
197 0x23,
198 std::mem::size_of::<snd_pcm_sync_ptr>(),
199 );
200
201 unsafe {
202 if libc::ioctl(fd, REQUEST, data) == -1 {
203 Err(crate::Error::last("SNDRV_PCM_IOCTL_SYNC_PTR"))
204 } else {
205 Ok(())
206 }
207 }
208}
209
210pub fn pagesize() -> usize {
211 unsafe { libc::sysconf(libc::_SC_PAGESIZE) as usize }
212}