audio_device/alsa/
hardware_parameters.rs

1use crate::alsa::{Access, AccessMask, Direction, Error, Format, FormatMask, Result};
2use crate::libc as c;
3use alsa_sys as alsa;
4use std::mem;
5use std::ops;
6use std::ptr;
7
8/// Collection of current hardware parameters being configured for a
9/// [Pcm][super::Pcm] handle.
10///
11/// See [Pcm::hardware_parameters][super::Pcm::hardware_parameters].
12pub struct HardwareParameters {
13    handle: ptr::NonNull<alsa::snd_pcm_hw_params_t>,
14}
15
16impl HardwareParameters {
17    /// Open current hardware parameters for the current device for writing.
18    pub(super) unsafe fn current(pcm: &mut ptr::NonNull<alsa::snd_pcm_t>) -> Result<Self> {
19        let mut handle = mem::MaybeUninit::uninit();
20
21        errno!(alsa::snd_pcm_hw_params_malloc(handle.as_mut_ptr()))?;
22
23        let mut handle = ptr::NonNull::new_unchecked(handle.assume_init());
24
25        if let Err(e) = errno!(alsa::snd_pcm_hw_params_current(
26            pcm.as_ptr(),
27            handle.as_mut()
28        )) {
29            alsa::snd_pcm_hw_params_free(handle.as_mut());
30            return Err(e.into());
31        }
32
33        Ok(HardwareParameters { handle })
34    }
35
36    /// Open all available hardware parameters for the current device.
37    pub(super) unsafe fn any(pcm: &mut ptr::NonNull<alsa::snd_pcm_t>) -> Result<Self> {
38        let mut handle = mem::MaybeUninit::uninit();
39
40        errno!(alsa::snd_pcm_hw_params_malloc(handle.as_mut_ptr()))?;
41
42        let mut handle = ptr::NonNull::new_unchecked(handle.assume_init());
43
44        if let Err(e) = errno!(alsa::snd_pcm_hw_params_any(pcm.as_ptr(), handle.as_mut())) {
45            alsa::snd_pcm_hw_params_free(handle.as_mut());
46            return Err(e.into());
47        }
48
49        Ok(HardwareParameters { handle })
50    }
51
52    /// Restrict a configuration space to contain only one channels count.
53    ///
54    /// # Examples
55    ///
56    /// ```rust,no_run
57    /// use audio_device::alsa;
58    ///
59    /// # fn main() -> anyhow::Result<()> {
60    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
61    /// let hw = pcm.hardware_parameters()?;
62    ///
63    /// let result = hw.channels()?;
64    /// dbg!(result);
65    /// # Ok(()) }
66    /// ```
67    pub fn channels(&self) -> Result<c::c_uint> {
68        unsafe {
69            let mut channels = mem::MaybeUninit::uninit();
70
71            errno!(alsa::snd_pcm_hw_params_get_channels(
72                self.handle.as_ptr(),
73                channels.as_mut_ptr()
74            ))?;
75
76            Ok(channels.assume_init())
77        }
78    }
79
80    /// Extract maximum channels count from a configuration space.
81    ///
82    /// # Examples
83    ///
84    /// ```rust,no_run
85    /// use audio_device::alsa;
86    ///
87    /// # fn main() -> anyhow::Result<()> {
88    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
89    /// let hw = pcm.hardware_parameters()?;
90    ///
91    /// println!("{}", hw.channels_max()?);
92    /// # Ok(()) }
93    /// ```
94    pub fn channels_max(&self) -> Result<c::c_uint> {
95        unsafe {
96            let mut channels = mem::MaybeUninit::uninit();
97
98            errno!(alsa::snd_pcm_hw_params_get_channels_max(
99                self.handle.as_ptr(),
100                channels.as_mut_ptr()
101            ))?;
102
103            Ok(channels.assume_init())
104        }
105    }
106
107    /// Extract minimum channels count from a configuration space.
108    ///
109    /// # Examples
110    ///
111    /// ```rust,no_run
112    /// use audio_device::alsa;
113    ///
114    /// # fn main() -> anyhow::Result<()> {
115    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
116    /// let hw = pcm.hardware_parameters()?;
117    ///
118    /// println!("{}", hw.channels_min()?);
119    /// # Ok(()) }
120    /// ```
121    pub fn channels_min(&self) -> Result<c::c_uint> {
122        unsafe {
123            let mut channels = mem::MaybeUninit::uninit();
124
125            errno!(alsa::snd_pcm_hw_params_get_channels_min(
126                self.handle.as_ptr(),
127                channels.as_mut_ptr()
128            ))?;
129
130            Ok(channels.assume_init())
131        }
132    }
133
134    /// Extract rate from a configuration space.
135    ///
136    /// # Examples
137    ///
138    /// ```rust,no_run
139    /// use audio_device::alsa;
140    ///
141    /// # fn main() -> anyhow::Result<()> {
142    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
143    /// let mut hw = pcm.hardware_parameters_any()?;
144    ///
145    /// println!("{}", hw.rate()?);
146    /// # Ok(()) }
147    /// ```
148    pub fn rate(&self) -> Result<c::c_uint> {
149        unsafe {
150            let mut rate = 0;
151            let mut dir = 0;
152
153            errno!(alsa::snd_pcm_hw_params_get_rate(
154                self.handle.as_ptr(),
155                &mut rate,
156                &mut dir,
157            ))?;
158
159            Ok(rate)
160        }
161    }
162
163    /// Get rate exact info from a configuration space.
164    ///
165    /// # Examples
166    ///
167    /// ```rust,no_run
168    /// use audio_device::alsa;
169    ///
170    /// # fn main() -> anyhow::Result<()> {
171    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
172    /// let mut hw = pcm.hardware_parameters_any()?;
173    ///
174    /// dbg!(hw.rate_numden()?);
175    /// # Ok(()) }
176    /// ```
177    pub fn rate_numden(&self) -> Result<(c::c_uint, c::c_uint)> {
178        unsafe {
179            let mut num = mem::MaybeUninit::uninit();
180            let mut den = mem::MaybeUninit::uninit();
181            errno!(alsa::snd_pcm_hw_params_get_rate_numden(
182                self.handle.as_ptr(),
183                num.as_mut_ptr(),
184                den.as_mut_ptr(),
185            ))?;
186            let num = num.assume_init();
187            let den = den.assume_init();
188            Ok((num, den))
189        }
190    }
191
192    /// Extract max rate from a configuration space.
193    ///
194    /// # Examples
195    ///
196    /// ```rust,no_run
197    /// use audio_device::alsa;
198    ///
199    /// # fn main() -> anyhow::Result<()> {
200    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
201    /// let mut hw = pcm.hardware_parameters_any()?;
202    ///
203    /// println!("{}", hw.rate_max()?);
204    /// # Ok(()) }
205    /// ```
206    pub fn rate_max(&self) -> Result<c::c_uint> {
207        unsafe {
208            let mut rate = 0;
209            let mut dir = 0;
210
211            errno!(alsa::snd_pcm_hw_params_get_rate_max(
212                self.handle.as_ptr(),
213                &mut rate,
214                &mut dir,
215            ))?;
216
217            Ok(rate)
218        }
219    }
220
221    /// Extract min rate from a configuration space.
222    ///
223    /// # Examples
224    ///
225    /// ```rust,no_run
226    /// use audio_device::alsa;
227    ///
228    /// # fn main() -> anyhow::Result<()> {
229    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
230    /// let mut hw = pcm.hardware_parameters_any()?;
231    ///
232    /// println!("{}", hw.rate_min()?);
233    /// # Ok(()) }
234    /// ```
235    pub fn rate_min(&self) -> Result<c::c_uint> {
236        unsafe {
237            let mut rate = 0;
238            let mut dir = 0;
239
240            errno!(alsa::snd_pcm_hw_params_get_rate_min(
241                self.handle.as_ptr(),
242                &mut rate,
243                &mut dir,
244            ))?;
245
246            Ok(rate)
247        }
248    }
249
250    /// Extract format from a configuration space.
251    ///
252    /// # Examples
253    ///
254    /// ```rust,no_run
255    /// use audio_device::alsa;
256    ///
257    /// # fn main() -> anyhow::Result<()> {
258    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
259    /// let mut hw = pcm.hardware_parameters_any()?;
260    ///
261    /// println!("{}", hw.format()?);
262    /// # Ok(()) }
263    /// ```
264    pub fn format(&self) -> Result<Format> {
265        unsafe {
266            let mut format = mem::MaybeUninit::uninit();
267
268            errno!(alsa::snd_pcm_hw_params_get_format(
269                self.handle.as_ptr(),
270                format.as_mut_ptr(),
271            ))?;
272
273            let format = format.assume_init();
274            let format = Format::from_value(format).ok_or_else(|| Error::BadFormat(format))?;
275            Ok(format)
276        }
277    }
278
279    /// Get format mask from a configuration space.
280    ///
281    /// # Examples
282    ///
283    /// ```rust,no_run
284    /// use audio_device::alsa;
285    ///
286    /// # fn main() -> anyhow::Result<()> {
287    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
288    /// let hw = pcm.hardware_parameters()?;
289    ///
290    /// let _mask = hw.format_mask()?;
291    /// # Ok(()) }
292    /// ```
293    pub fn format_mask(&self) -> Result<FormatMask> {
294        unsafe {
295            let mut mask = FormatMask::allocate()?;
296            alsa::snd_pcm_hw_params_get_format_mask(self.handle.as_ptr(), mask.handle.as_mut());
297            Ok(mask)
298        }
299    }
300
301    /// Extract access type from a configuration space.
302    ///
303    /// # Examples
304    ///
305    /// ```rust,no_run
306    /// use audio_device::alsa;
307    ///
308    /// # fn main() -> anyhow::Result<()> {
309    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
310    /// let mut hw = pcm.hardware_parameters_any()?;
311    ///
312    /// println!("{}", hw.access()?);
313    /// # Ok(()) }
314    /// ```
315    pub fn access(&self) -> Result<Access> {
316        unsafe {
317            let mut access = mem::MaybeUninit::uninit();
318
319            errno!(alsa::snd_pcm_hw_params_get_access(
320                self.handle.as_ptr(),
321                access.as_mut_ptr(),
322            ))?;
323
324            let access = access.assume_init();
325            let access = Access::from_value(access).ok_or_else(|| Error::BadAccess(access))?;
326            Ok(access)
327        }
328    }
329
330    /// Get access mask from a configuration space.
331    ///
332    /// # Examples
333    ///
334    /// ```rust,no_run
335    /// use audio_device::alsa;
336    ///
337    /// # fn main() -> anyhow::Result<()> {
338    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
339    /// let hw = pcm.hardware_parameters()?;
340    ///
341    /// let _mask = hw.get_access_mask()?;
342    /// # Ok(()) }
343    /// ```
344    pub fn get_access_mask(&self) -> Result<AccessMask> {
345        unsafe {
346            let mut mask = AccessMask::allocate()?;
347
348            errno!(alsa::snd_pcm_hw_params_get_access_mask(
349                self.handle.as_ptr(),
350                mask.handle.as_mut(),
351            ))?;
352
353            Ok(mask)
354        }
355    }
356
357    /// Check if hardware supports pause.
358    ///
359    /// # Examples
360    ///
361    /// ```rust,no_run
362    /// use audio_device::alsa;
363    ///
364    /// # fn main() -> anyhow::Result<()> {
365    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
366    /// let mut hw = pcm.hardware_parameters_any()?;
367    ///
368    /// println!("{}", hw.can_pause());
369    /// # Ok(()) }
370    /// ```
371    pub fn can_pause(&self) -> bool {
372        unsafe { alsa::snd_pcm_hw_params_can_pause(self.handle.as_ptr()) != 0 }
373    }
374
375    /// Check if hardware supports resume.
376    ///
377    /// # Examples
378    ///
379    /// ```rust,no_run
380    /// use audio_device::alsa;
381    ///
382    /// # fn main() -> anyhow::Result<()> {
383    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
384    /// let mut hw = pcm.hardware_parameters_any()?;
385    ///
386    /// println!("{}", hw.can_resume());
387    /// # Ok(()) }
388    /// ```
389    pub fn can_resume(&self) -> bool {
390        unsafe { alsa::snd_pcm_hw_params_can_resume(self.handle.as_ptr()) != 0 }
391    }
392
393    /// Copy one hardware parameters to another.
394    ///
395    /// # Examples
396    ///
397    /// ```rust,no_run
398    /// use audio_device::alsa;
399    ///
400    /// # fn main() -> anyhow::Result<()> {
401    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
402    /// let a = pcm.hardware_parameters()?;
403    /// let mut hw = pcm.hardware_parameters()?;
404    ///
405    /// hw.copy(&a);
406    /// # Ok(()) }
407    /// ```
408    pub fn copy(&mut self, other: &HardwareParameters) {
409        unsafe { alsa::snd_pcm_hw_params_copy(self.handle.as_mut(), other.handle.as_ptr()) };
410    }
411
412    /// Check if hardware supports sample-resolution mmap for given configuration.
413    ///
414    /// # Examples
415    ///
416    /// ```rust,no_run
417    /// use audio_device::alsa;
418    ///
419    /// # fn main() -> anyhow::Result<()> {
420    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
421    /// let hw = pcm.hardware_parameters()?;
422    ///
423    /// println!("{}", hw.can_mmap_sample_resolution());
424    /// # Ok(()) }
425    /// ```
426    pub fn can_mmap_sample_resolution(&self) -> bool {
427        unsafe { alsa::snd_pcm_hw_params_can_mmap_sample_resolution(self.handle.as_ptr()) == 1 }
428    }
429
430    /// Check if hardware does double buffering for start/stop for given configuration.
431    ///
432    /// # Examples
433    ///
434    /// ```rust,no_run
435    /// use audio_device::alsa;
436    ///
437    /// # fn main() -> anyhow::Result<()> {
438    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
439    /// let hw = pcm.hardware_parameters()?;
440    ///
441    /// println!("{}", hw.is_double());
442    /// # Ok(()) }
443    /// ```
444    pub fn is_double(&self) -> bool {
445        unsafe { alsa::snd_pcm_hw_params_is_double(self.handle.as_ptr()) == 1 }
446    }
447
448    /// Check if hardware does double buffering for data transfers for given configuration.
449    ///
450    /// # Examples
451    ///
452    /// ```rust,no_run
453    /// use audio_device::alsa;
454    ///
455    /// # fn main() -> anyhow::Result<()> {
456    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
457    /// let hw = pcm.hardware_parameters()?;
458    ///
459    /// println!("{}", hw.is_batch());
460    /// # Ok(()) }
461    /// ```
462    pub fn is_batch(&self) -> bool {
463        unsafe { alsa::snd_pcm_hw_params_is_batch(self.handle.as_ptr()) == 1 }
464    }
465
466    /// Check if hardware does block transfers for samples for given configuration.
467    ///
468    /// # Examples
469    ///
470    /// ```rust,no_run
471    /// use audio_device::alsa;
472    ///
473    /// # fn main() -> anyhow::Result<()> {
474    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
475    /// let hw = pcm.hardware_parameters()?;
476    ///
477    /// println!("{}", hw.is_block_transfer());
478    /// # Ok(()) }
479    /// ```
480    pub fn is_block_transfer(&self) -> bool {
481        unsafe { alsa::snd_pcm_hw_params_is_block_transfer(self.handle.as_ptr()) == 1 }
482    }
483
484    /// Check if timestamps are monotonic for given configuration.
485    ///
486    /// # Examples
487    ///
488    /// ```rust,no_run
489    /// use audio_device::alsa;
490    ///
491    /// # fn main() -> anyhow::Result<()> {
492    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
493    /// let hw = pcm.hardware_parameters()?;
494    ///
495    /// println!("{}", hw.is_monotonic());
496    /// # Ok(()) }
497    /// ```
498    pub fn is_monotonic(&self) -> bool {
499        unsafe { alsa::snd_pcm_hw_params_is_monotonic(self.handle.as_ptr()) == 1 }
500    }
501
502    /// Check if hardware supports overrange detection.
503    ///
504    /// # Examples
505    ///
506    /// ```rust,no_run
507    /// use audio_device::alsa;
508    ///
509    /// # fn main() -> anyhow::Result<()> {
510    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
511    /// let hw = pcm.hardware_parameters()?;
512    ///
513    /// println!("{}", hw.can_overrange());
514    /// # Ok(()) }
515    /// ```
516    pub fn can_overrange(&self) -> bool {
517        unsafe { alsa::snd_pcm_hw_params_can_overrange(self.handle.as_ptr()) == 1 }
518    }
519
520    /// Check if hardware does half-duplex only.
521    ///
522    /// # Examples
523    ///
524    /// ```rust,no_run
525    /// use audio_device::alsa;
526    ///
527    /// # fn main() -> anyhow::Result<()> {
528    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
529    /// let hw = pcm.hardware_parameters()?;
530    ///
531    /// println!("{}", hw.is_half_duplex());
532    /// # Ok(()) }
533    /// ```
534    pub fn is_half_duplex(&self) -> bool {
535        unsafe { alsa::snd_pcm_hw_params_is_half_duplex(self.handle.as_ptr()) == 1 }
536    }
537
538    /// Check if hardware does joint-duplex (playback and capture are somewhat correlated)
539    ///
540    /// # Examples
541    ///
542    /// ```rust,no_run
543    /// use audio_device::alsa;
544    ///
545    /// # fn main() -> anyhow::Result<()> {
546    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
547    /// let hw = pcm.hardware_parameters()?;
548    ///
549    /// println!("{}", hw.is_joint_duplex());
550    /// # Ok(()) }
551    /// ```
552    pub fn is_joint_duplex(&self) -> bool {
553        unsafe { alsa::snd_pcm_hw_params_is_joint_duplex(self.handle.as_ptr()) == 1 }
554    }
555
556    /// Check if hardware supports synchronized start with sample resolution.
557    ///
558    /// # Examples
559    ///
560    /// ```rust,no_run
561    /// use audio_device::alsa;
562    ///
563    /// # fn main() -> anyhow::Result<()> {
564    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
565    /// let hw = pcm.hardware_parameters()?;
566    ///
567    /// println!("{}", hw.can_sync_start());
568    /// # Ok(()) }
569    /// ```
570    pub fn can_sync_start(&self) -> bool {
571        unsafe { alsa::snd_pcm_hw_params_can_sync_start(self.handle.as_ptr()) == 1 }
572    }
573
574    /// Check if hardware can disable period wakeups.
575    ///
576    /// # Examples
577    ///
578    /// ```rust,no_run
579    /// use audio_device::alsa;
580    ///
581    /// # fn main() -> anyhow::Result<()> {
582    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
583    /// let hw = pcm.hardware_parameters()?;
584    ///
585    /// println!("{}", hw.can_disable_period_wakeup());
586    /// # Ok(()) }
587    /// ```
588    pub fn can_disable_period_wakeup(&self) -> bool {
589        unsafe { alsa::snd_pcm_hw_params_can_disable_period_wakeup(self.handle.as_ptr()) == 1 }
590    }
591
592    /// Check if hardware supports audio wallclock timestamps.
593    ///
594    /// # Examples
595    ///
596    /// ```rust,no_run
597    /// use audio_device::alsa;
598    ///
599    /// # fn main() -> anyhow::Result<()> {
600    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
601    /// let hw = pcm.hardware_parameters()?;
602    ///
603    /// println!("{}", hw.supports_audio_wallclock_ts());
604    /// # Ok(()) }
605    /// ```
606    pub fn supports_audio_wallclock_ts(&self) -> bool {
607        unsafe { alsa::snd_pcm_hw_params_supports_audio_wallclock_ts(self.handle.as_ptr()) == 1 }
608    }
609
610    /// Check if hardware supports type of audio timestamps.
611    ///
612    /// # Examples
613    ///
614    /// ```rust,no_run
615    /// use audio_device::alsa;
616    ///
617    /// # fn main() -> anyhow::Result<()> {
618    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
619    /// let hw = pcm.hardware_parameters()?;
620    ///
621    /// println!("{}", hw.supports_audio_ts_type(2));
622    /// # Ok(()) }
623    /// ```
624    pub fn supports_audio_ts_type(&self, ty: c::c_int) -> bool {
625        unsafe { alsa::snd_pcm_hw_params_supports_audio_ts_type(self.handle.as_ptr(), ty) == 1 }
626    }
627
628    /// Get sample resolution info from a configuration space.
629    ///
630    /// # Examples
631    ///
632    /// ```rust,no_run
633    /// use audio_device::alsa;
634    ///
635    /// # fn main() -> anyhow::Result<()> {
636    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
637    /// let hw = pcm.hardware_parameters()?;
638    ///
639    /// println!("{}", hw.sbits()?);
640    /// # Ok(()) }
641    /// ```
642    pub fn sbits(&self) -> Result<c::c_int> {
643        unsafe {
644            Ok(errno!(alsa::snd_pcm_hw_params_get_sbits(
645                self.handle.as_ptr()
646            ))?)
647        }
648    }
649
650    /// Get hardware FIFO size info from a configuration space.
651    ///
652    /// # Examples
653    ///
654    /// ```rust,no_run
655    /// use audio_device::alsa;
656    ///
657    /// # fn main() -> anyhow::Result<()> {
658    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
659    /// let hw = pcm.hardware_parameters()?;
660    ///
661    /// println!("{}", hw.fifo_size()?);
662    /// # Ok(()) }
663    /// ```
664    pub fn fifo_size(&self) -> Result<c::c_int> {
665        unsafe {
666            Ok(errno!(alsa::snd_pcm_hw_params_get_fifo_size(
667                self.handle.as_ptr()
668            ))?)
669        }
670    }
671
672    /// Extract period time from a configuration space.
673    ///
674    /// # Examples
675    ///
676    /// ```rust,no_run
677    /// use audio_device::alsa;
678    ///
679    /// # fn main() -> anyhow::Result<()> {
680    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
681    /// let hw = pcm.hardware_parameters()?;
682    ///
683    /// dbg!(hw.period_time());
684    /// # Ok(()) }
685    /// ```
686    pub fn period_time(&self) -> Result<(c::c_uint, Direction)> {
687        unsafe {
688            let mut period_time = mem::MaybeUninit::uninit();
689            let mut dir = mem::MaybeUninit::uninit();
690            alsa::snd_pcm_hw_params_get_period_time(
691                self.handle.as_ptr(),
692                period_time.as_mut_ptr(),
693                dir.as_mut_ptr(),
694            );
695            let period_time = period_time.assume_init();
696            let dir = Direction::from_value(dir.assume_init());
697            Ok((period_time, dir))
698        }
699    }
700
701    /// Extract minimum period time from a configuration space.
702    ///
703    /// # Examples
704    ///
705    /// ```rust,no_run
706    /// use audio_device::alsa;
707    ///
708    /// # fn main() -> anyhow::Result<()> {
709    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
710    /// let hw = pcm.hardware_parameters()?;
711    ///
712    /// dbg!(hw.period_time_min());
713    /// # Ok(()) }
714    /// ```
715    pub fn period_time_min(&self) -> Result<(c::c_uint, Direction)> {
716        unsafe {
717            let mut period_time = mem::MaybeUninit::uninit();
718            let mut dir = mem::MaybeUninit::uninit();
719            alsa::snd_pcm_hw_params_get_period_time_min(
720                self.handle.as_ptr(),
721                period_time.as_mut_ptr(),
722                dir.as_mut_ptr(),
723            );
724            let period_time = period_time.assume_init();
725            let dir = Direction::from_value(dir.assume_init());
726            Ok((period_time, dir))
727        }
728    }
729
730    /// Extract maximum period time from a configuration space.
731    ///
732    /// # Examples
733    ///
734    /// ```rust,no_run
735    /// use audio_device::alsa;
736    ///
737    /// # fn main() -> anyhow::Result<()> {
738    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
739    /// let hw = pcm.hardware_parameters()?;
740    ///
741    /// dbg!(hw.period_time_max());
742    /// # Ok(()) }
743    /// ```
744    pub fn period_time_max(&self) -> Result<(c::c_uint, Direction)> {
745        unsafe {
746            let mut period_time = mem::MaybeUninit::uninit();
747            let mut dir = mem::MaybeUninit::uninit();
748            alsa::snd_pcm_hw_params_get_period_time_max(
749                self.handle.as_ptr(),
750                period_time.as_mut_ptr(),
751                dir.as_mut_ptr(),
752            );
753            let period_time = period_time.assume_init();
754            let dir = Direction::from_value(dir.assume_init());
755            Ok((period_time, dir))
756        }
757    }
758
759    /// Extract period size from a configuration space.
760    ///
761    /// # Examples
762    ///
763    /// ```rust,no_run
764    /// use audio_device::alsa;
765    ///
766    /// # fn main() -> anyhow::Result<()> {
767    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
768    /// let hw = pcm.hardware_parameters()?;
769    ///
770    /// dbg!(hw.period_size());
771    /// # Ok(()) }
772    /// ```
773    pub fn period_size(&self) -> Result<(c::c_ulong, Direction)> {
774        unsafe {
775            let mut frames = mem::MaybeUninit::uninit();
776            let mut dir = mem::MaybeUninit::uninit();
777            errno!(alsa::snd_pcm_hw_params_get_period_size(
778                self.handle.as_ptr(),
779                frames.as_mut_ptr(),
780                dir.as_mut_ptr()
781            ))?;
782            let frames = frames.assume_init();
783            let dir = dir.assume_init();
784            let dir = Direction::from_value(dir);
785            Ok((frames, dir))
786        }
787    }
788
789    /// Extract minimum period size from a configuration space.
790    ///
791    /// # Examples
792    ///
793    /// ```rust,no_run
794    /// use audio_device::alsa;
795    ///
796    /// # fn main() -> anyhow::Result<()> {
797    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
798    /// let hw = pcm.hardware_parameters()?;
799    ///
800    /// dbg!(hw.period_size_min());
801    /// # Ok(()) }
802    /// ```
803    pub fn period_size_min(&self) -> Result<(c::c_ulong, Direction)> {
804        unsafe {
805            let mut frames = mem::MaybeUninit::uninit();
806            let mut dir = mem::MaybeUninit::uninit();
807            errno!(alsa::snd_pcm_hw_params_get_period_size_min(
808                self.handle.as_ptr(),
809                frames.as_mut_ptr(),
810                dir.as_mut_ptr()
811            ))?;
812            let frames = frames.assume_init();
813            let dir = dir.assume_init();
814            let dir = Direction::from_value(dir);
815            Ok((frames, dir))
816        }
817    }
818
819    /// Extract maximum period size from a configuration space.
820    ///
821    /// # Examples
822    ///
823    /// ```rust,no_run
824    /// use audio_device::alsa;
825    ///
826    /// # fn main() -> anyhow::Result<()> {
827    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
828    /// let hw = pcm.hardware_parameters()?;
829    ///
830    /// dbg!(hw.period_size_max()?);
831    /// # Ok(()) }
832    /// ```
833    pub fn period_size_max(&self) -> Result<(c::c_ulong, Direction)> {
834        unsafe {
835            let mut frames = mem::MaybeUninit::uninit();
836            let mut dir = mem::MaybeUninit::uninit();
837            errno!(alsa::snd_pcm_hw_params_get_period_size_max(
838                self.handle.as_ptr(),
839                frames.as_mut_ptr(),
840                dir.as_mut_ptr()
841            ))?;
842            let frames = frames.assume_init();
843            let dir = dir.assume_init();
844            let dir = Direction::from_value(dir);
845            Ok((frames, dir))
846        }
847    }
848
849    /// Extract periods from a configuration space.
850    ///
851    /// # Examples
852    ///
853    /// ```rust,no_run
854    /// use audio_device::alsa;
855    ///
856    /// # fn main() -> anyhow::Result<()> {
857    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
858    /// let hw = pcm.hardware_parameters()?;
859    ///
860    /// dbg!(hw.periods()?);
861    /// # Ok(()) }
862    /// ```
863    pub fn periods(&self) -> Result<(c::c_uint, Direction)> {
864        unsafe {
865            let mut periods = mem::MaybeUninit::uninit();
866            let mut dir = mem::MaybeUninit::uninit();
867            errno!(alsa::snd_pcm_hw_params_get_periods(
868                self.handle.as_ptr(),
869                periods.as_mut_ptr(),
870                dir.as_mut_ptr(),
871            ))?;
872            let periods = periods.assume_init();
873            let dir = Direction::from_value(dir.assume_init());
874            Ok((periods, dir))
875        }
876    }
877
878    /// Extract minimum periods count from a configuration space.
879    ///
880    /// # Examples
881    ///
882    /// ```rust,no_run
883    /// use audio_device::alsa;
884    ///
885    /// # fn main() -> anyhow::Result<()> {
886    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
887    /// let hw = pcm.hardware_parameters()?;
888    ///
889    /// dbg!(hw.periods_min()?);
890    /// # Ok(()) }
891    /// ```
892    pub fn periods_min(&self) -> Result<(c::c_uint, Direction)> {
893        unsafe {
894            let mut periods = mem::MaybeUninit::uninit();
895            let mut dir = mem::MaybeUninit::uninit();
896            errno!(alsa::snd_pcm_hw_params_get_periods_min(
897                self.handle.as_ptr(),
898                periods.as_mut_ptr(),
899                dir.as_mut_ptr(),
900            ))?;
901            let periods = periods.assume_init();
902            let dir = Direction::from_value(dir.assume_init());
903            Ok((periods, dir))
904        }
905    }
906
907    /// Extract maximum periods count from a configuration space.
908    ///
909    /// # Examples
910    ///
911    /// ```rust,no_run
912    /// use audio_device::alsa;
913    ///
914    /// # fn main() -> anyhow::Result<()> {
915    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
916    /// let hw = pcm.hardware_parameters()?;
917    ///
918    /// dbg!(hw.periods_max()?);
919    /// # Ok(()) }
920    /// ```
921    pub fn periods_max(&self) -> Result<(c::c_uint, Direction)> {
922        unsafe {
923            let mut periods = mem::MaybeUninit::uninit();
924            let mut dir = mem::MaybeUninit::uninit();
925            errno!(alsa::snd_pcm_hw_params_get_periods_max(
926                self.handle.as_ptr(),
927                periods.as_mut_ptr(),
928                dir.as_mut_ptr(),
929            ))?;
930            let periods = periods.assume_init();
931            let dir = Direction::from_value(dir.assume_init());
932            Ok((periods, dir))
933        }
934    }
935
936    /// Extract buffer time from a configuration space.
937    ///
938    /// # Examples
939    ///
940    /// ```rust,no_run
941    /// use audio_device::alsa;
942    ///
943    /// # fn main() -> anyhow::Result<()> {
944    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
945    /// let hw = pcm.hardware_parameters()?;
946    ///
947    /// dbg!(hw.buffer_time()?);
948    /// # Ok(()) }
949    /// ```
950    pub fn buffer_time(&self) -> Result<(c::c_uint, Direction)> {
951        unsafe {
952            let mut periods = mem::MaybeUninit::uninit();
953            let mut dir = mem::MaybeUninit::uninit();
954            errno!(alsa::snd_pcm_hw_params_get_buffer_time(
955                self.handle.as_ptr(),
956                periods.as_mut_ptr(),
957                dir.as_mut_ptr(),
958            ))?;
959            let periods = periods.assume_init();
960            let dir = Direction::from_value(dir.assume_init());
961            Ok((periods, dir))
962        }
963    }
964
965    /// Extract minimum buffer time from a configuration space.
966    ///
967    /// # Examples
968    ///
969    /// ```rust,no_run
970    /// use audio_device::alsa;
971    ///
972    /// # fn main() -> anyhow::Result<()> {
973    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
974    /// let hw = pcm.hardware_parameters()?;
975    ///
976    /// dbg!(hw.buffer_time_min()?);
977    /// # Ok(()) }
978    /// ```
979    pub fn buffer_time_min(&self) -> Result<(c::c_uint, Direction)> {
980        unsafe {
981            let mut periods = mem::MaybeUninit::uninit();
982            let mut dir = mem::MaybeUninit::uninit();
983            errno!(alsa::snd_pcm_hw_params_get_buffer_time_min(
984                self.handle.as_ptr(),
985                periods.as_mut_ptr(),
986                dir.as_mut_ptr(),
987            ))?;
988            let periods = periods.assume_init();
989            let dir = Direction::from_value(dir.assume_init());
990            Ok((periods, dir))
991        }
992    }
993
994    /// Extract maximum buffer time from a configuration space.
995    ///
996    /// # Examples
997    ///
998    /// ```rust,no_run
999    /// use audio_device::alsa;
1000    ///
1001    /// # fn main() -> anyhow::Result<()> {
1002    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
1003    /// let hw = pcm.hardware_parameters()?;
1004    ///
1005    /// dbg!(hw.buffer_time_max()?);
1006    /// # Ok(()) }
1007    /// ```
1008    pub fn buffer_time_max(&self) -> Result<(c::c_uint, Direction)> {
1009        unsafe {
1010            let mut periods = mem::MaybeUninit::uninit();
1011            let mut dir = mem::MaybeUninit::uninit();
1012            errno!(alsa::snd_pcm_hw_params_get_buffer_time_max(
1013                self.handle.as_ptr(),
1014                periods.as_mut_ptr(),
1015                dir.as_mut_ptr(),
1016            ))?;
1017            let periods = periods.assume_init();
1018            let dir = Direction::from_value(dir.assume_init());
1019            Ok((periods, dir))
1020        }
1021    }
1022
1023    /// Extract buffer size from a configuration space.
1024    ///
1025    /// # Examples
1026    ///
1027    /// ```rust,no_run
1028    /// use audio_device::alsa;
1029    ///
1030    /// # fn main() -> anyhow::Result<()> {
1031    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
1032    /// let mut hw = pcm.hardware_parameters()?;
1033    ///
1034    /// dbg!(hw.buffer_size()?);
1035    /// # Ok(()) }
1036    /// ```
1037    pub fn buffer_size(&self) -> Result<c::c_ulong> {
1038        unsafe {
1039            let mut buffer_size = mem::MaybeUninit::uninit();
1040            errno!(alsa::snd_pcm_hw_params_get_buffer_size(
1041                self.handle.as_ptr(),
1042                buffer_size.as_mut_ptr()
1043            ))?;
1044            Ok(buffer_size.assume_init())
1045        }
1046    }
1047
1048    /// Extract minimum buffer size from a configuration space.
1049    ///
1050    /// # Examples
1051    ///
1052    /// ```rust,no_run
1053    /// use audio_device::alsa;
1054    ///
1055    /// # fn main() -> anyhow::Result<()> {
1056    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
1057    /// let mut hw = pcm.hardware_parameters()?;
1058    ///
1059    /// dbg!(hw.buffer_size_min()?);
1060    /// # Ok(()) }
1061    /// ```
1062    pub fn buffer_size_min(&self) -> Result<c::c_ulong> {
1063        unsafe {
1064            let mut buffer_size = mem::MaybeUninit::uninit();
1065            errno!(alsa::snd_pcm_hw_params_get_buffer_size_min(
1066                self.handle.as_ptr(),
1067                buffer_size.as_mut_ptr()
1068            ))?;
1069            Ok(buffer_size.assume_init())
1070        }
1071    }
1072
1073    /// Extract maximum buffer size from a configuration space.
1074    ///
1075    /// # Examples
1076    ///
1077    /// ```rust,no_run
1078    /// use audio_device::alsa;
1079    ///
1080    /// # fn main() -> anyhow::Result<()> {
1081    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
1082    /// let mut hw = pcm.hardware_parameters()?;
1083    ///
1084    /// dbg!(hw.buffer_size_max()?);
1085    /// # Ok(()) }
1086    /// ```
1087    pub fn buffer_size_max(&self) -> Result<c::c_ulong> {
1088        unsafe {
1089            let mut buffer_size = mem::MaybeUninit::uninit();
1090            errno!(alsa::snd_pcm_hw_params_get_buffer_size_max(
1091                self.handle.as_ptr(),
1092                buffer_size.as_mut_ptr()
1093            ))?;
1094            Ok(buffer_size.assume_init())
1095        }
1096    }
1097
1098    /// Get the minimum transfer align value in samples.
1099    ///
1100    /// # Examples
1101    ///
1102    /// ```rust,no_run
1103    /// use audio_device::alsa;
1104    ///
1105    /// # fn main() -> anyhow::Result<()> {
1106    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
1107    /// let mut hw = pcm.hardware_parameters()?;
1108    ///
1109    /// dbg!(hw.min_align()?);
1110    /// # Ok(()) }
1111    /// ```
1112    pub fn min_align(&self) -> Result<c::c_ulong> {
1113        unsafe {
1114            let mut min_align = mem::MaybeUninit::uninit();
1115            errno!(alsa::snd_pcm_hw_params_get_min_align(
1116                self.handle.as_ptr(),
1117                min_align.as_mut_ptr()
1118            ))?;
1119            Ok(min_align.assume_init())
1120        }
1121    }
1122}
1123
1124impl Drop for HardwareParameters {
1125    fn drop(&mut self) {
1126        unsafe {
1127            let _ = alsa::snd_pcm_hw_params_free(self.handle.as_mut());
1128        }
1129    }
1130}
1131
1132/// Collection of harward parameters being configured for a [Pcm][super::Pcm]
1133/// handle.
1134///
1135/// Must be refined before they are applied to a [Pcm][super::Pcm] device
1136/// through [HardwareParametersMut::install].
1137///
1138/// See [Pcm::hardware_parameters_any][super::Pcm::hardware_parameters_any].
1139pub struct HardwareParametersMut<'a> {
1140    pcm: &'a mut ptr::NonNull<alsa::snd_pcm_t>,
1141    base: HardwareParameters,
1142}
1143
1144impl<'a> HardwareParametersMut<'a> {
1145    /// Open current hardware parameters for the current device for writing.
1146    pub(super) unsafe fn current(pcm: &'a mut ptr::NonNull<alsa::snd_pcm_t>) -> Result<Self> {
1147        let base = HardwareParameters::current(pcm)?;
1148        Ok(HardwareParametersMut { pcm, base })
1149    }
1150
1151    /// Open all available hardware parameters for the current device.
1152    pub(super) unsafe fn any(pcm: &'a mut ptr::NonNull<alsa::snd_pcm_t>) -> Result<Self> {
1153        let base = HardwareParameters::any(pcm)?;
1154        Ok(HardwareParametersMut { pcm, base })
1155    }
1156
1157    /// Install one PCM hardware configuration chosen from a configuration space
1158    /// and prepare it.
1159    ///
1160    /// # Examples
1161    ///
1162    /// ```rust,no_run
1163    /// use audio_device::alsa;
1164    ///
1165    /// # fn main() -> anyhow::Result<()> {
1166    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
1167    /// let mut hw = pcm.hardware_parameters_any()?;
1168    ///
1169    /// hw.set_channels_near(2)?;
1170    /// hw.install()?;
1171    /// # Ok(()) }
1172    /// ```
1173    pub fn install(mut self) -> Result<()> {
1174        unsafe {
1175            errno!(alsa::snd_pcm_hw_params(
1176                self.pcm.as_mut(),
1177                self.base.handle.as_mut()
1178            ))?;
1179            Ok(())
1180        }
1181    }
1182
1183    /// Extract resample state from a configuration space.
1184    ///
1185    /// # Examples
1186    ///
1187    /// ```rust,no_run
1188    /// use audio_device::alsa;
1189    ///
1190    /// # fn main() -> anyhow::Result<()> {
1191    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
1192    /// let mut hw = pcm.hardware_parameters_any()?;
1193    ///
1194    /// let result = hw.rate_resample()?;
1195    /// dbg!(result);
1196    /// # Ok(()) }
1197    /// ```
1198    pub fn rate_resample(&mut self) -> Result<bool> {
1199        unsafe {
1200            let mut v = mem::MaybeUninit::uninit();
1201
1202            errno!(alsa::snd_pcm_hw_params_get_rate_resample(
1203                self.pcm.as_mut(),
1204                self.base.handle.as_mut(),
1205                v.as_mut_ptr()
1206            ))?;
1207
1208            Ok(v.assume_init() != 0)
1209        }
1210    }
1211
1212    /// Restrict a configuration space to contain only real hardware rates.
1213    ///
1214    /// # Examples
1215    ///
1216    /// ```rust,no_run
1217    /// use audio_device::alsa;
1218    ///
1219    /// # fn main() -> anyhow::Result<()> {
1220    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
1221    /// let mut hw = pcm.hardware_parameters_any()?;
1222    ///
1223    /// let actual = hw.set_rate_resample(true)?;
1224    /// dbg!(actual);
1225    /// # Ok(()) }
1226    /// ```
1227    pub fn set_rate_resample(&mut self, resample: bool) -> Result<()> {
1228        unsafe {
1229            errno!(alsa::snd_pcm_hw_params_set_rate_resample(
1230                self.pcm.as_mut(),
1231                self.base.handle.as_mut(),
1232                if resample { 1 } else { 0 }
1233            ))?;
1234
1235            Ok(())
1236        }
1237    }
1238
1239    /// Restrict a configuration space to have channels count nearest to a target.
1240    ///
1241    /// # Examples
1242    ///
1243    /// ```rust,no_run
1244    /// use audio_device::alsa;
1245    ///
1246    /// # fn main() -> anyhow::Result<()> {
1247    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
1248    /// let mut hw = pcm.hardware_parameters_any()?;
1249    ///
1250    /// let actual = hw.set_channels_near(2)?;
1251    /// dbg!(actual);
1252    /// # Ok(()) }
1253    /// ```
1254    pub fn set_channels_near(&mut self, mut channels: c::c_uint) -> Result<c::c_uint> {
1255        unsafe {
1256            errno!(alsa::snd_pcm_hw_params_set_channels_near(
1257                self.pcm.as_mut(),
1258                self.base.handle.as_mut(),
1259                &mut channels
1260            ))?;
1261
1262            Ok(channels)
1263        }
1264    }
1265
1266    /// Restrict a configuration space to contain only one channels count.
1267    ///
1268    /// # Examples
1269    ///
1270    /// ```rust,no_run
1271    /// use audio_device::alsa;
1272    ///
1273    /// # fn main() -> anyhow::Result<()> {
1274    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
1275    /// let mut hw = pcm.hardware_parameters_any()?;
1276    ///
1277    /// let actual = hw.set_channels(2)?;
1278    /// dbg!(actual);
1279    /// # Ok(()) }
1280    /// ```
1281    pub fn set_channels(&mut self, channels: c::c_uint) -> Result<()> {
1282        unsafe {
1283            errno!(alsa::snd_pcm_hw_params_set_channels(
1284                self.pcm.as_mut(),
1285                self.base.handle.as_mut(),
1286                channels
1287            ))?;
1288
1289            Ok(())
1290        }
1291    }
1292
1293    /// Extract minimum channels count from a configuration space.
1294    ///
1295    /// # Examples
1296    ///
1297    /// ```rust,no_run
1298    /// use audio_device::alsa;
1299    ///
1300    /// # fn main() -> anyhow::Result<()> {
1301    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
1302    /// let mut hw = pcm.hardware_parameters_any()?;
1303    ///
1304    /// let result = hw.test_channels(4)?;
1305    /// dbg!(result);
1306    /// # Ok(()) }
1307    /// ```
1308    pub fn test_channels(&mut self, channels: c::c_uint) -> Result<bool> {
1309        unsafe {
1310            let result = alsa::snd_pcm_hw_params_test_channels(
1311                self.pcm.as_mut(),
1312                self.base.handle.as_mut(),
1313                channels,
1314            );
1315
1316            Ok(result == 0)
1317        }
1318    }
1319
1320    /// Restrict a configuration space with a minimum channels count.
1321    ///
1322    /// # Examples
1323    ///
1324    /// ```rust,no_run
1325    /// use audio_device::alsa;
1326    ///
1327    /// # fn main() -> anyhow::Result<()> {
1328    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
1329    /// let mut hw = pcm.hardware_parameters_any()?;
1330    ///
1331    /// let actual = hw.set_channels_min(2)?;
1332    /// dbg!(actual);
1333    /// # Ok(()) }
1334    /// ```
1335    pub fn set_channels_min(&mut self, mut channels: c::c_uint) -> Result<c::c_uint> {
1336        unsafe {
1337            errno!(alsa::snd_pcm_hw_params_set_channels_min(
1338                self.pcm.as_mut(),
1339                self.base.handle.as_mut(),
1340                &mut channels
1341            ))?;
1342            Ok(channels)
1343        }
1344    }
1345
1346    /// Restrict a configuration space with a maximum channels count.
1347    ///
1348    /// # Examples
1349    ///
1350    /// ```rust,no_run
1351    /// use audio_device::alsa;
1352    ///
1353    /// # fn main() -> anyhow::Result<()> {
1354    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
1355    /// let mut hw = pcm.hardware_parameters_any()?;
1356    ///
1357    /// let actual = hw.set_channels_max(2)?;
1358    /// dbg!(actual);
1359    /// # Ok(()) }
1360    /// ```
1361    pub fn set_channels_max(&mut self, mut channels: c::c_uint) -> Result<c::c_uint> {
1362        unsafe {
1363            errno!(alsa::snd_pcm_hw_params_set_channels_max(
1364                self.pcm.as_mut(),
1365                self.base.handle.as_mut(),
1366                &mut channels
1367            ))?;
1368            Ok(channels)
1369        }
1370    }
1371
1372    /// Restrict a configuration space to have channels counts in a given range.
1373    ///
1374    /// # Examples
1375    ///
1376    /// ```rust,no_run
1377    /// use audio_device::alsa;
1378    ///
1379    /// # fn main() -> anyhow::Result<()> {
1380    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
1381    /// let mut hw = pcm.hardware_parameters_any()?;
1382    ///
1383    /// let actual = hw.set_channels_minmax(2, 4)?;
1384    /// dbg!(actual);
1385    /// # Ok(()) }
1386    /// ```
1387    pub fn set_channels_minmax(
1388        &mut self,
1389        mut channels_min: c::c_uint,
1390        mut channels_max: c::c_uint,
1391    ) -> Result<(c::c_uint, c::c_uint)> {
1392        unsafe {
1393            errno!(alsa::snd_pcm_hw_params_set_channels_minmax(
1394                self.pcm.as_mut(),
1395                self.base.handle.as_mut(),
1396                &mut channels_min,
1397                &mut channels_max
1398            ))?;
1399            Ok((channels_min, channels_max))
1400        }
1401    }
1402
1403    /// Restrict a configuration space to contain only its minimum channels count.
1404    ///
1405    /// # Examples
1406    ///
1407    /// ```rust,no_run
1408    /// use audio_device::alsa;
1409    ///
1410    /// # fn main() -> anyhow::Result<()> {
1411    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
1412    /// let mut hw = pcm.hardware_parameters_any()?;
1413    ///
1414    /// let actual = hw.set_channels_first()?;
1415    /// dbg!(actual);
1416    /// # Ok(()) }
1417    /// ```
1418    pub fn set_channels_first(&mut self) -> Result<c::c_uint> {
1419        unsafe {
1420            let mut channels = mem::MaybeUninit::uninit();
1421            errno!(alsa::snd_pcm_hw_params_set_channels_first(
1422                self.pcm.as_mut(),
1423                self.base.handle.as_mut(),
1424                channels.as_mut_ptr()
1425            ))?;
1426            Ok(channels.assume_init())
1427        }
1428    }
1429
1430    /// Restrict a configuration space to contain only its maximum channels count.
1431    ///
1432    /// # Examples
1433    ///
1434    /// ```rust,no_run
1435    /// use audio_device::alsa;
1436    ///
1437    /// # fn main() -> anyhow::Result<()> {
1438    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
1439    /// let mut hw = pcm.hardware_parameters_any()?;
1440    ///
1441    /// let actual = hw.set_channels_last()?;
1442    /// dbg!(actual);
1443    /// # Ok(()) }
1444    /// ```
1445    pub fn set_channels_last(&mut self) -> Result<c::c_uint> {
1446        unsafe {
1447            let mut channels = mem::MaybeUninit::uninit();
1448            errno!(alsa::snd_pcm_hw_params_set_channels_last(
1449                self.pcm.as_mut(),
1450                self.base.handle.as_mut(),
1451                channels.as_mut_ptr()
1452            ))?;
1453            Ok(channels.assume_init())
1454        }
1455    }
1456
1457    /// Restrict a configuration space to have rate nearest to a target.
1458    ///
1459    /// # Examples
1460    ///
1461    /// ```rust,no_run
1462    /// use audio_device::alsa;
1463    ///
1464    /// # fn main() -> anyhow::Result<()> {
1465    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
1466    /// let mut hw = pcm.hardware_parameters_any()?;
1467    ///
1468    /// let actual = hw.set_rate_near(44100, alsa::Direction::Nearest)?;
1469    /// dbg!(actual);
1470    /// dbg!(actual);
1471    /// # Ok(()) }
1472    /// ```
1473    pub fn set_rate_near(
1474        &mut self,
1475        mut rate: c::c_uint,
1476        dir: Direction,
1477    ) -> Result<(u32, Direction)> {
1478        unsafe {
1479            let mut dir = dir as c::c_int;
1480
1481            errno!(alsa::snd_pcm_hw_params_set_rate_near(
1482                self.pcm.as_mut(),
1483                self.base.handle.as_mut(),
1484                &mut rate,
1485                &mut dir,
1486            ))?;
1487            let dir = Direction::from_value(dir);
1488            Ok((rate, dir))
1489        }
1490    }
1491
1492    /// Restrict a configuration space to have rate nearest to a target.
1493    ///
1494    /// # Examples
1495    ///
1496    /// ```rust,no_run
1497    /// use audio_device::alsa;
1498    ///
1499    /// # fn main() -> anyhow::Result<()> {
1500    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
1501    /// let mut hw = pcm.hardware_parameters_any()?;
1502    ///
1503    /// let actual = hw.set_rate(44100, alsa::Direction::Nearest)?;
1504    /// dbg!(actual);
1505    /// # Ok(()) }
1506    /// ```
1507    pub fn set_rate(&mut self, rate: c::c_uint, dir: Direction) -> Result<()> {
1508        unsafe {
1509            errno!(alsa::snd_pcm_hw_params_set_rate(
1510                self.pcm.as_mut(),
1511                self.base.handle.as_mut(),
1512                rate,
1513                dir as c::c_int,
1514            ))?;
1515
1516            Ok(())
1517        }
1518    }
1519
1520    /// Restrict a configuration space with a minimum rate.
1521    ///
1522    /// # Examples
1523    ///
1524    /// ```rust,no_run
1525    /// use audio_device::alsa;
1526    ///
1527    /// # fn main() -> anyhow::Result<()> {
1528    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
1529    /// let mut hw = pcm.hardware_parameters_any()?;
1530    ///
1531    /// let actual = hw.set_rate_min(44100, alsa::Direction::Nearest)?;
1532    /// dbg!(actual);
1533    /// # Ok(()) }
1534    /// ```
1535    pub fn set_rate_min(
1536        &mut self,
1537        mut rate: c::c_uint,
1538        dir: Direction,
1539    ) -> Result<(c::c_uint, Direction)> {
1540        unsafe {
1541            let mut dir = dir as i32;
1542            errno!(alsa::snd_pcm_hw_params_set_rate_min(
1543                self.pcm.as_mut(),
1544                self.base.handle.as_mut(),
1545                &mut rate,
1546                &mut dir,
1547            ))?;
1548            let dir = Direction::from_value(dir);
1549            Ok((rate, dir))
1550        }
1551    }
1552
1553    /// Restrict a configuration space with a maximum rate.
1554    ///
1555    /// # Examples
1556    ///
1557    /// ```rust,no_run
1558    /// use audio_device::alsa;
1559    ///
1560    /// # fn main() -> anyhow::Result<()> {
1561    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
1562    /// let mut hw = pcm.hardware_parameters_any()?;
1563    ///
1564    /// let actual = hw.set_rate_max(44100, alsa::Direction::Nearest)?;
1565    /// dbg!(actual);
1566    /// # Ok(()) }
1567    /// ```
1568    pub fn set_rate_max(
1569        &mut self,
1570        mut rate: c::c_uint,
1571        dir: Direction,
1572    ) -> Result<(c::c_uint, Direction)> {
1573        unsafe {
1574            let mut dir = dir as i32;
1575            errno!(alsa::snd_pcm_hw_params_set_rate_max(
1576                self.pcm.as_mut(),
1577                self.base.handle.as_mut(),
1578                &mut rate,
1579                &mut dir,
1580            ))?;
1581            let dir = Direction::from_value(dir);
1582            Ok((rate, dir))
1583        }
1584    }
1585
1586    /// Restrict a configuration space to have rates in a given range.
1587    ///
1588    /// # Examples
1589    ///
1590    /// ```rust,no_run
1591    /// use audio_device::alsa;
1592    ///
1593    /// # fn main() -> anyhow::Result<()> {
1594    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
1595    /// let mut hw = pcm.hardware_parameters_any()?;
1596    ///
1597    /// let actual = hw.set_rate_minmax(128, alsa::Direction::Nearest, 256, alsa::Direction::Nearest)?;
1598    /// dbg!(actual);
1599    /// # Ok(()) }
1600    /// ```
1601    pub fn set_rate_minmax(
1602        &mut self,
1603        mut rate_min: c::c_uint,
1604        dir_min: Direction,
1605        mut rate_max: c::c_uint,
1606        dir_max: Direction,
1607    ) -> Result<(c::c_uint, Direction, c::c_uint, Direction)> {
1608        unsafe {
1609            let mut dir_min = dir_min as i32;
1610            let mut dir_max = dir_max as i32;
1611            errno!(alsa::snd_pcm_hw_params_set_rate_minmax(
1612                self.pcm.as_mut(),
1613                self.base.handle.as_mut(),
1614                &mut rate_min,
1615                &mut dir_min,
1616                &mut rate_max,
1617                &mut dir_max,
1618            ))?;
1619            let dir_min = Direction::from_value(dir_min);
1620            let dir_max = Direction::from_value(dir_max);
1621            Ok((rate_min, dir_min, rate_max, dir_max))
1622        }
1623    }
1624
1625    /// Restrict a configuration space to contain only its minimum rate.
1626    ///
1627    /// # Examples
1628    ///
1629    /// ```rust,no_run
1630    /// use audio_device::alsa;
1631    ///
1632    /// # fn main() -> anyhow::Result<()> {
1633    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
1634    /// let mut hw = pcm.hardware_parameters_any()?;
1635    ///
1636    /// let actual = hw.set_rate_first()?;
1637    /// dbg!(actual);
1638    /// # Ok(()) }
1639    /// ```
1640    pub fn set_rate_first(&mut self) -> Result<(c::c_uint, Direction)> {
1641        unsafe {
1642            let mut rate = mem::MaybeUninit::uninit();
1643            let mut dir = mem::MaybeUninit::uninit();
1644            errno!(alsa::snd_pcm_hw_params_set_rate_first(
1645                self.pcm.as_mut(),
1646                self.base.handle.as_mut(),
1647                rate.as_mut_ptr(),
1648                dir.as_mut_ptr(),
1649            ))?;
1650            let rate = rate.assume_init();
1651            let dir = Direction::from_value(dir.assume_init());
1652            Ok((rate, dir))
1653        }
1654    }
1655
1656    /// Restrict a configuration space to contain only its maximum rate.
1657    ///
1658    /// # Examples
1659    ///
1660    /// ```rust,no_run
1661    /// use audio_device::alsa;
1662    ///
1663    /// # fn main() -> anyhow::Result<()> {
1664    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
1665    /// let mut hw = pcm.hardware_parameters_any()?;
1666    ///
1667    /// let actual = hw.set_rate_last()?;
1668    /// dbg!(actual);
1669    /// # Ok(()) }
1670    /// ```
1671    pub fn set_rate_last(&mut self) -> Result<(c::c_uint, Direction)> {
1672        unsafe {
1673            let mut rate = mem::MaybeUninit::uninit();
1674            let mut dir = mem::MaybeUninit::uninit();
1675            errno!(alsa::snd_pcm_hw_params_set_rate_last(
1676                self.pcm.as_mut(),
1677                self.base.handle.as_mut(),
1678                rate.as_mut_ptr(),
1679                dir.as_mut_ptr(),
1680            ))?;
1681            let rate = rate.assume_init();
1682            let dir = Direction::from_value(dir.assume_init());
1683            Ok((rate, dir))
1684        }
1685    }
1686
1687    /// Extract min rate from a configuration space.
1688    ///
1689    /// # Examples
1690    ///
1691    /// ```rust,no_run
1692    /// use audio_device::alsa;
1693    ///
1694    /// # fn main() -> anyhow::Result<()> {
1695    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
1696    /// let mut hw = pcm.hardware_parameters_any()?;
1697    ///
1698    /// let result = hw.test_rate(44100)?;
1699    /// dbg!(result);
1700    /// # Ok(()) }
1701    /// ```
1702    pub fn test_rate(&mut self, rate: c::c_uint) -> Result<bool> {
1703        unsafe {
1704            let result = alsa::snd_pcm_hw_params_test_rate(
1705                self.pcm.as_mut(),
1706                self.base.handle.as_mut(),
1707                rate,
1708                0,
1709            );
1710
1711            Ok(result == 0)
1712        }
1713    }
1714
1715    /// Restrict a configuration space to contain only one format.
1716    ///
1717    /// # Examples
1718    ///
1719    /// ```rust,no_run
1720    /// use audio_device::alsa;
1721    ///
1722    /// # fn main() -> anyhow::Result<()> {
1723    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
1724    /// let mut hw = pcm.hardware_parameters_any()?;
1725    ///
1726    /// let actual = hw.set_format(alsa::Format::S16LE)?;
1727    /// dbg!(actual);
1728    /// # Ok(()) }
1729    /// ```
1730    pub fn set_format(&mut self, format: Format) -> Result<()> {
1731        unsafe {
1732            errno!(alsa::snd_pcm_hw_params_set_format(
1733                self.pcm.as_mut(),
1734                self.base.handle.as_mut(),
1735                format as c::c_int
1736            ))?;
1737
1738            Ok(())
1739        }
1740    }
1741
1742    /// Restrict a configuration space to contain only its first format.
1743    ///
1744    /// # Examples
1745    ///
1746    /// ```rust,no_run
1747    /// use audio_device::alsa;
1748    ///
1749    /// # fn main() -> anyhow::Result<()> {
1750    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
1751    /// let mut hw = pcm.hardware_parameters_any()?;
1752    ///
1753    /// let actual = hw.set_format_first()?;
1754    /// dbg!(actual);
1755    /// # Ok(()) }
1756    /// ```
1757    pub fn set_format_first(&mut self) -> Result<Format> {
1758        unsafe {
1759            let mut format = mem::MaybeUninit::uninit();
1760
1761            errno!(alsa::snd_pcm_hw_params_set_format_first(
1762                self.pcm.as_mut(),
1763                self.base.handle.as_mut(),
1764                format.as_mut_ptr(),
1765            ))?;
1766
1767            let format = format.assume_init();
1768            let format = Format::from_value(format).ok_or_else(|| Error::BadFormat(format))?;
1769            Ok(format)
1770        }
1771    }
1772
1773    /// Restrict a configuration space to contain only its last format.
1774    ///
1775    /// # Examples
1776    ///
1777    /// ```rust,no_run
1778    /// use audio_device::alsa;
1779    ///
1780    /// # fn main() -> anyhow::Result<()> {
1781    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
1782    /// let mut hw = pcm.hardware_parameters_any()?;
1783    ///
1784    /// let actual = hw.set_format_last()?;
1785    /// dbg!(actual);
1786    /// # Ok(()) }
1787    /// ```
1788    pub fn set_format_last(&mut self) -> Result<Format> {
1789        unsafe {
1790            let mut format = mem::MaybeUninit::uninit();
1791
1792            errno!(alsa::snd_pcm_hw_params_set_format_last(
1793                self.pcm.as_mut(),
1794                self.base.handle.as_mut(),
1795                format.as_mut_ptr(),
1796            ))?;
1797
1798            let format = format.assume_init();
1799            let format = Format::from_value(format).ok_or_else(|| Error::BadFormat(format))?;
1800            Ok(format)
1801        }
1802    }
1803
1804    /// Restrict a configuration space to contain only a set of formats.
1805    ///
1806    /// # Examples
1807    ///
1808    /// ```rust,no_run
1809    /// use audio_device::alsa;
1810    ///
1811    /// # fn main() -> anyhow::Result<()> {
1812    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
1813    /// let mut hw = pcm.hardware_parameters_any()?;
1814    ///
1815    /// let mut mask = alsa::FormatMask::new()?;
1816    /// mask.set(alsa::Format::S16LE);
1817    ///
1818    /// let actual = hw.set_format_mask(&mask)?;
1819    /// dbg!(actual);
1820    /// # Ok(()) }
1821    /// ```
1822    pub fn set_format_mask(&mut self, mask: &FormatMask) -> Result<()> {
1823        unsafe {
1824            errno!(alsa::snd_pcm_hw_params_set_format_mask(
1825                self.pcm.as_mut(),
1826                self.base.handle.as_mut(),
1827                mask.handle.as_ptr(),
1828            ))?;
1829
1830            Ok(())
1831        }
1832    }
1833
1834    /// Verify if a format is available inside a configuration space for a PCM.
1835    ///
1836    /// # Examples
1837    ///
1838    /// ```rust,no_run
1839    /// use audio_device::alsa;
1840    ///
1841    /// # fn main() -> anyhow::Result<()> {
1842    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
1843    /// let mut hw = pcm.hardware_parameters_any()?;
1844    ///
1845    /// let result = hw.test_format(alsa::Format::S16LE)?;
1846    /// dbg!(result);
1847    /// # Ok(()) }
1848    /// ```
1849    pub fn test_format(&mut self, format: Format) -> Result<bool> {
1850        unsafe {
1851            let result = alsa::snd_pcm_hw_params_test_format(
1852                self.pcm.as_mut(),
1853                self.base.handle.as_mut(),
1854                format as c::c_int,
1855            );
1856
1857            Ok(result == 0)
1858        }
1859    }
1860
1861    /// Restrict a configuration space to contain only one access type.
1862    ///
1863    /// # Examples
1864    ///
1865    /// ```rust,no_run
1866    /// use audio_device::alsa;
1867    ///
1868    /// # fn main() -> anyhow::Result<()> {
1869    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
1870    /// let mut hw = pcm.hardware_parameters_any()?;
1871    ///
1872    /// let actual = hw.set_access(alsa::Access::MmapInterleaved)?;
1873    /// dbg!(actual);
1874    /// # Ok(()) }
1875    /// ```
1876    pub fn set_access(&mut self, access: Access) -> Result<()> {
1877        unsafe {
1878            errno!(alsa::snd_pcm_hw_params_set_access(
1879                self.pcm.as_mut(),
1880                self.base.handle.as_mut(),
1881                access as c::c_uint
1882            ))?;
1883
1884            Ok(())
1885        }
1886    }
1887
1888    /// Verify if an access type is available inside a configuration space for a PCM.
1889    ///
1890    /// # Examples
1891    ///
1892    /// ```rust,no_run
1893    /// use audio_device::alsa;
1894    ///
1895    /// # fn main() -> anyhow::Result<()> {
1896    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
1897    /// let mut hw = pcm.hardware_parameters_any()?;
1898    ///
1899    /// let result = hw.test_access(alsa::Access::MmapInterleaved)?;
1900    /// dbg!(result);
1901    /// # Ok(()) }
1902    /// ```
1903    pub fn test_access(&mut self, access: Access) -> Result<bool> {
1904        unsafe {
1905            let result = alsa::snd_pcm_hw_params_test_access(
1906                self.pcm.as_mut(),
1907                self.base.handle.as_mut(),
1908                access as c::c_uint,
1909            );
1910
1911            Ok(result == 0)
1912        }
1913    }
1914
1915    /// Restrict a configuration space to contain only its first access type.
1916    ///
1917    /// # Examples
1918    ///
1919    /// ```rust,no_run
1920    /// use audio_device::alsa;
1921    ///
1922    /// # fn main() -> anyhow::Result<()> {
1923    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
1924    /// let mut hw = pcm.hardware_parameters_any()?;
1925    ///
1926    /// println!("{}", hw.set_access_first()?);
1927    /// # Ok(()) }
1928    /// ```
1929    pub fn set_access_first(&mut self) -> Result<Access> {
1930        unsafe {
1931            let mut access = mem::MaybeUninit::uninit();
1932
1933            errno!(alsa::snd_pcm_hw_params_set_access_first(
1934                self.pcm.as_mut(),
1935                self.base.handle.as_mut(),
1936                access.as_mut_ptr(),
1937            ))?;
1938
1939            let access = access.assume_init();
1940            let access = Access::from_value(access).ok_or_else(|| Error::BadAccess(access))?;
1941            Ok(access)
1942        }
1943    }
1944
1945    /// Restrict a configuration space to contain only its last access type.
1946    ///
1947    /// # Examples
1948    ///
1949    /// ```rust,no_run
1950    /// use audio_device::alsa;
1951    ///
1952    /// # fn main() -> anyhow::Result<()> {
1953    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
1954    /// let mut hw = pcm.hardware_parameters_any()?;
1955    ///
1956    /// println!("{}", hw.set_access_last()?);
1957    /// # Ok(()) }
1958    /// ```
1959    pub fn set_access_last(&mut self) -> Result<Access> {
1960        unsafe {
1961            let mut access = mem::MaybeUninit::uninit();
1962
1963            errno!(alsa::snd_pcm_hw_params_set_access_last(
1964                self.pcm.as_mut(),
1965                self.base.handle.as_mut(),
1966                access.as_mut_ptr(),
1967            ))?;
1968
1969            let access = access.assume_init();
1970            let access = Access::from_value(access).ok_or_else(|| Error::BadAccess(access))?;
1971            Ok(access)
1972        }
1973    }
1974
1975    /// Restrict a configuration space to contain only a set of access types.
1976    ///
1977    /// # Examples
1978    ///
1979    /// ```rust,no_run
1980    /// use audio_device::alsa;
1981    ///
1982    /// # fn main() -> anyhow::Result<()> {
1983    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
1984    /// let mut hw = pcm.hardware_parameters_any()?;
1985    ///
1986    /// let mut mask = alsa::AccessMask::new()?;
1987    /// mask.set(alsa::Access::MmapInterleaved);
1988    ///
1989    /// let actual = hw.set_access_mask(&mask)?;
1990    /// dbg!(actual);
1991    /// # Ok(()) }
1992    /// ```
1993    pub fn set_access_mask(&mut self, mask: &AccessMask) -> Result<()> {
1994        unsafe {
1995            errno!(alsa::snd_pcm_hw_params_set_access_mask(
1996                self.pcm.as_mut(),
1997                self.base.handle.as_mut(),
1998                mask.handle.as_ptr(),
1999            ))?;
2000
2001            Ok(())
2002        }
2003    }
2004
2005    /// Restrict a configuration space to allow the buffer to be accessible from outside.
2006    ///
2007    /// # Examples
2008    ///
2009    /// ```rust,no_run
2010    /// use audio_device::alsa;
2011    ///
2012    /// # fn main() -> anyhow::Result<()> {
2013    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
2014    /// let mut hw = pcm.hardware_parameters_any()?;
2015    ///
2016    /// let actual = hw.set_export_buffer(1024)?;
2017    /// dbg!(actual);
2018    /// # Ok(()) }
2019    /// ```
2020    pub fn set_export_buffer(&mut self, export_buffer: c::c_uint) -> Result<()> {
2021        unsafe {
2022            errno!(alsa::snd_pcm_hw_params_set_export_buffer(
2023                self.pcm.as_mut(),
2024                self.base.handle.as_mut(),
2025                export_buffer
2026            ))?;
2027            Ok(())
2028        }
2029    }
2030
2031    /// Extract buffer accessibility from a configuration space.
2032    ///
2033    /// # Examples
2034    ///
2035    /// ```rust,no_run
2036    /// use audio_device::alsa;
2037    ///
2038    /// # fn main() -> anyhow::Result<()> {
2039    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
2040    /// let mut hw = pcm.hardware_parameters_any()?;
2041    ///
2042    /// let result = hw.export_buffer()?;
2043    /// dbg!(result);
2044    /// # Ok(()) }
2045    /// ```
2046    pub fn export_buffer(&mut self) -> Result<c::c_uint> {
2047        unsafe {
2048            let mut export_buffer = mem::MaybeUninit::uninit();
2049            errno!(alsa::snd_pcm_hw_params_get_export_buffer(
2050                self.pcm.as_mut(),
2051                self.base.handle.as_mut(),
2052                export_buffer.as_mut_ptr()
2053            ))?;
2054            Ok(export_buffer.assume_init())
2055        }
2056    }
2057
2058    /// Restrict a configuration space to settings without period wakeups.
2059    ///
2060    /// # Examples
2061    ///
2062    /// ```rust,no_run
2063    /// use audio_device::alsa;
2064    ///
2065    /// # fn main() -> anyhow::Result<()> {
2066    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
2067    /// let mut hw = pcm.hardware_parameters_any()?;
2068    ///
2069    /// let actual = hw.set_period_wakeup(10000)?;
2070    /// dbg!(actual);
2071    /// # Ok(()) }
2072    /// ```
2073    pub fn set_period_wakeup(&mut self, period_wakeup: c::c_uint) -> Result<()> {
2074        unsafe {
2075            errno!(alsa::snd_pcm_hw_params_set_period_wakeup(
2076                self.pcm.as_mut(),
2077                self.base.handle.as_mut(),
2078                period_wakeup
2079            ))?;
2080            Ok(())
2081        }
2082    }
2083
2084    /// Extract period wakeup flag from a configuration space.
2085    ///
2086    /// # Examples
2087    ///
2088    /// ```rust,no_run
2089    /// use audio_device::alsa;
2090    ///
2091    /// # fn main() -> anyhow::Result<()> {
2092    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
2093    /// let mut hw = pcm.hardware_parameters_any()?;
2094    ///
2095    /// dbg!(hw.period_wakeup()?);
2096    /// # Ok(()) }
2097    /// ```
2098    pub fn period_wakeup(&mut self) -> Result<c::c_uint> {
2099        unsafe {
2100            let mut period_wakeup = mem::MaybeUninit::uninit();
2101            errno!(alsa::snd_pcm_hw_params_get_period_wakeup(
2102                self.pcm.as_mut(),
2103                self.base.handle.as_mut(),
2104                period_wakeup.as_mut_ptr()
2105            ))?;
2106            Ok(period_wakeup.assume_init())
2107        }
2108    }
2109
2110    /// Verify if a period time is available inside a configuration space for a PCM.
2111    ///
2112    /// # Examples
2113    ///
2114    /// ```rust,no_run
2115    /// use audio_device::alsa;
2116    ///
2117    /// # fn main() -> anyhow::Result<()> {
2118    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
2119    /// let mut hw = pcm.hardware_parameters_any()?;
2120    ///
2121    /// dbg!(hw.test_period_time(1000, alsa::Direction::Nearest)?);
2122    /// # Ok(()) }
2123    /// ```
2124    pub fn test_period_time(&mut self, period_time: c::c_uint, dir: Direction) -> Result<bool> {
2125        unsafe {
2126            let result = errno!(alsa::snd_pcm_hw_params_test_period_time(
2127                self.pcm.as_mut(),
2128                self.base.handle.as_mut(),
2129                period_time,
2130                dir as i32,
2131            ))?;
2132            Ok(result == 0)
2133        }
2134    }
2135
2136    /// Restrict a configuration space to contain only one period time.
2137    ///
2138    /// # Examples
2139    ///
2140    /// ```rust,no_run
2141    /// use audio_device::alsa;
2142    ///
2143    /// # fn main() -> anyhow::Result<()> {
2144    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
2145    /// let mut hw = pcm.hardware_parameters_any()?;
2146    ///
2147    /// let actual = hw.set_period_time(1000, alsa::Direction::Nearest)?;
2148    /// dbg!(actual);
2149    /// # Ok(()) }
2150    /// ```
2151    pub fn set_period_time(&mut self, period_time: c::c_uint, dir: Direction) -> Result<()> {
2152        unsafe {
2153            errno!(alsa::snd_pcm_hw_params_set_period_time(
2154                self.pcm.as_mut(),
2155                self.base.handle.as_mut(),
2156                period_time,
2157                dir as i32,
2158            ))?;
2159            Ok(())
2160        }
2161    }
2162
2163    /// Restrict a configuration space with a minimum period time.
2164    ///
2165    /// # Examples
2166    ///
2167    /// ```rust,no_run
2168    /// use audio_device::alsa;
2169    ///
2170    /// # fn main() -> anyhow::Result<()> {
2171    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
2172    /// let mut hw = pcm.hardware_parameters_any()?;
2173    ///
2174    /// let actual = hw.set_period_time_min(1000, alsa::Direction::Nearest)?;
2175    /// dbg!(actual);
2176    /// # Ok(()) }
2177    /// ```
2178    pub fn set_period_time_min(
2179        &mut self,
2180        mut period_time: c::c_uint,
2181        dir: Direction,
2182    ) -> Result<(c::c_uint, Direction)> {
2183        unsafe {
2184            let mut dir = dir as i32;
2185            errno!(alsa::snd_pcm_hw_params_set_period_time_min(
2186                self.pcm.as_mut(),
2187                self.base.handle.as_mut(),
2188                &mut period_time,
2189                &mut dir
2190            ))?;
2191            let dir = Direction::from_value(dir);
2192            Ok((period_time, dir))
2193        }
2194    }
2195
2196    /// Restrict a configuration space with a maximum period time.
2197    ///
2198    /// # Examples
2199    ///
2200    /// ```rust,no_run
2201    /// use audio_device::alsa;
2202    ///
2203    /// # fn main() -> anyhow::Result<()> {
2204    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
2205    /// let mut hw = pcm.hardware_parameters_any()?;
2206    ///
2207    /// let actual = hw.set_period_time_max(1000, alsa::Direction::Nearest)?;
2208    /// dbg!(actual);
2209    /// # Ok(()) }
2210    /// ```
2211    pub fn set_period_time_max(
2212        &mut self,
2213        mut period_time: c::c_uint,
2214        dir: Direction,
2215    ) -> Result<(c::c_uint, Direction)> {
2216        unsafe {
2217            let mut dir = dir as i32;
2218            errno!(alsa::snd_pcm_hw_params_set_period_time_max(
2219                self.pcm.as_mut(),
2220                self.base.handle.as_mut(),
2221                &mut period_time,
2222                &mut dir
2223            ))?;
2224            let dir = Direction::from_value(dir);
2225            Ok((period_time, dir))
2226        }
2227    }
2228
2229    /// Restrict a configuration space to have period times in a given range.
2230    ///
2231    /// # Examples
2232    ///
2233    /// ```rust,no_run
2234    /// use audio_device::alsa;
2235    ///
2236    /// # fn main() -> anyhow::Result<()> {
2237    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
2238    /// let mut hw = pcm.hardware_parameters_any()?;
2239    ///
2240    /// let actual = hw.set_period_time_minmax(1000, alsa::Direction::Nearest, 10000, alsa::Direction::Nearest)?;
2241    /// dbg!(actual);
2242    /// # Ok(()) }
2243    /// ```
2244    pub fn set_period_time_minmax(
2245        &mut self,
2246        mut period_time_max: c::c_uint,
2247        dir_max: Direction,
2248        mut period_time_min: c::c_uint,
2249        dir_min: Direction,
2250    ) -> Result<(c::c_uint, Direction, c::c_uint, Direction)> {
2251        unsafe {
2252            let mut dir_min = dir_min as i32;
2253            let mut dir_max = dir_max as i32;
2254            errno!(alsa::snd_pcm_hw_params_set_period_time_minmax(
2255                self.pcm.as_mut(),
2256                self.base.handle.as_mut(),
2257                &mut period_time_min,
2258                &mut dir_min,
2259                &mut period_time_max,
2260                &mut dir_max
2261            ))?;
2262            let dir_min = Direction::from_value(dir_min);
2263            let dir_max = Direction::from_value(dir_max);
2264            Ok((period_time_min, dir_min, period_time_max, dir_max))
2265        }
2266    }
2267
2268    /// Restrict a configuration space to have period time nearest to a target.
2269    ///
2270    /// # Examples
2271    ///
2272    /// ```rust,no_run
2273    /// use audio_device::alsa;
2274    ///
2275    /// # fn main() -> anyhow::Result<()> {
2276    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
2277    /// let mut hw = pcm.hardware_parameters_any()?;
2278    ///
2279    /// let actual = hw.set_period_time_near(1000, alsa::Direction::Nearest)?;
2280    /// dbg!(actual);
2281    /// # Ok(()) }
2282    /// ```
2283    pub fn set_period_time_near(
2284        &mut self,
2285        mut period_time: c::c_uint,
2286        dir: Direction,
2287    ) -> Result<(c::c_uint, Direction)> {
2288        unsafe {
2289            let mut dir = dir as i32;
2290            errno!(alsa::snd_pcm_hw_params_set_period_time_near(
2291                self.pcm.as_mut(),
2292                self.base.handle.as_mut(),
2293                &mut period_time,
2294                &mut dir
2295            ))?;
2296            let dir = Direction::from_value(dir);
2297            Ok((period_time, dir))
2298        }
2299    }
2300
2301    /// Restrict a configuration space to contain only its minimum period time.
2302    ///
2303    /// # Examples
2304    ///
2305    /// ```rust,no_run
2306    /// use audio_device::alsa;
2307    ///
2308    /// # fn main() -> anyhow::Result<()> {
2309    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
2310    /// let mut hw = pcm.hardware_parameters_any()?;
2311    ///
2312    /// let actual = hw.set_period_time_first()?;
2313    /// dbg!(actual);
2314    /// # Ok(()) }
2315    /// ```
2316    pub fn set_period_time_first(&mut self) -> Result<(c::c_uint, Direction)> {
2317        unsafe {
2318            let mut period_time = mem::MaybeUninit::uninit();
2319            let mut dir = mem::MaybeUninit::uninit();
2320            errno!(alsa::snd_pcm_hw_params_set_period_time_first(
2321                self.pcm.as_mut(),
2322                self.base.handle.as_mut(),
2323                period_time.as_mut_ptr(),
2324                dir.as_mut_ptr()
2325            ))?;
2326            let period_time = period_time.assume_init();
2327            let dir = Direction::from_value(dir.assume_init());
2328            Ok((period_time, dir))
2329        }
2330    }
2331
2332    /// Restrict a configuration space to contain only its maximum period time.
2333    ///
2334    /// # Examples
2335    ///
2336    /// ```rust,no_run
2337    /// use audio_device::alsa;
2338    ///
2339    /// # fn main() -> anyhow::Result<()> {
2340    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
2341    /// let mut hw = pcm.hardware_parameters_any()?;
2342    ///
2343    /// let actual = hw.set_period_time_last()?;
2344    /// dbg!(actual);
2345    /// # Ok(()) }
2346    /// ```
2347    pub fn set_period_time_last(&mut self) -> Result<(c::c_uint, Direction)> {
2348        unsafe {
2349            let mut period_time = mem::MaybeUninit::uninit();
2350            let mut dir = mem::MaybeUninit::uninit();
2351            errno!(alsa::snd_pcm_hw_params_set_period_time_last(
2352                self.pcm.as_mut(),
2353                self.base.handle.as_mut(),
2354                period_time.as_mut_ptr(),
2355                dir.as_mut_ptr()
2356            ))?;
2357            let period_time = period_time.assume_init();
2358            let dir = Direction::from_value(dir.assume_init());
2359            Ok((period_time, dir))
2360        }
2361    }
2362
2363    /// Verify if a period size is available inside a configuration space for a PCM.
2364    ///
2365    /// # Examples
2366    ///
2367    /// ```rust,no_run
2368    /// use audio_device::alsa;
2369    ///
2370    /// # fn main() -> anyhow::Result<()> {
2371    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
2372    /// let mut hw = pcm.hardware_parameters_any()?;
2373    ///
2374    /// if hw.test_period_size(128, alsa::Direction::Nearest)? {
2375    ///     println!("period size supported!");
2376    /// }
2377    /// # Ok(()) }
2378    /// ```
2379    pub fn test_period_size(&mut self, frames: c::c_ulong, dir: Direction) -> Result<bool> {
2380        unsafe {
2381            let result = alsa::snd_pcm_hw_params_test_period_size(
2382                self.pcm.as_mut(),
2383                self.base.handle.as_mut(),
2384                frames,
2385                dir as i32,
2386            );
2387            Ok(result == 1)
2388        }
2389    }
2390
2391    /// Restrict a configuration space to contain only one period size.
2392    ///
2393    /// # Examples
2394    ///
2395    /// ```rust,no_run
2396    /// use audio_device::alsa;
2397    ///
2398    /// # fn main() -> anyhow::Result<()> {
2399    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
2400    /// let mut hw = pcm.hardware_parameters_any()?;
2401    ///
2402    /// let actual = hw.set_period_size(128, alsa::Direction::Nearest)?;
2403    /// dbg!(actual);
2404    /// # Ok(()) }
2405    /// ```
2406    pub fn set_period_size(&mut self, frames: c::c_ulong, dir: Direction) -> Result<()> {
2407        unsafe {
2408            errno!(alsa::snd_pcm_hw_params_set_period_size(
2409                self.pcm.as_mut(),
2410                self.base.handle.as_mut(),
2411                frames,
2412                dir as i32,
2413            ))?;
2414            Ok(())
2415        }
2416    }
2417
2418    /// Restrict a configuration space with a minimum period size.
2419    ///
2420    /// # Examples
2421    ///
2422    /// ```rust,no_run
2423    /// use audio_device::alsa;
2424    ///
2425    /// # fn main() -> anyhow::Result<()> {
2426    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
2427    /// let mut hw = pcm.hardware_parameters_any()?;
2428    ///
2429    /// let actual = hw.set_period_size_min(128, alsa::Direction::Nearest)?;
2430    /// dbg!(actual);
2431    /// # Ok(()) }
2432    /// ```
2433    pub fn set_period_size_min(
2434        &mut self,
2435        mut frames: c::c_ulong,
2436        dir: Direction,
2437    ) -> Result<(c::c_ulong, Direction)> {
2438        unsafe {
2439            let mut dir = dir as i32;
2440            errno!(alsa::snd_pcm_hw_params_set_period_size_min(
2441                self.pcm.as_mut(),
2442                self.base.handle.as_mut(),
2443                &mut frames,
2444                &mut dir
2445            ))?;
2446            let dir = Direction::from_value(dir);
2447            Ok((frames, dir))
2448        }
2449    }
2450
2451    /// Restrict a configuration space with a maximum period size.
2452    ///
2453    /// # Examples
2454    ///
2455    /// ```rust,no_run
2456    /// use audio_device::alsa;
2457    ///
2458    /// # fn main() -> anyhow::Result<()> {
2459    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
2460    /// let mut hw = pcm.hardware_parameters_any()?;
2461    ///
2462    /// let actual = hw.set_period_size_max(128, alsa::Direction::Nearest)?;
2463    /// dbg!(actual);
2464    /// # Ok(()) }
2465    /// ```
2466    pub fn set_period_size_max(
2467        &mut self,
2468        mut frames: c::c_ulong,
2469        dir: Direction,
2470    ) -> Result<(c::c_ulong, Direction)> {
2471        unsafe {
2472            let mut dir = dir as i32;
2473            errno!(alsa::snd_pcm_hw_params_set_period_size_max(
2474                self.pcm.as_mut(),
2475                self.base.handle.as_mut(),
2476                &mut frames,
2477                &mut dir
2478            ))?;
2479            let dir = Direction::from_value(dir);
2480            Ok((frames, dir))
2481        }
2482    }
2483
2484    /// Restrict a configuration space to have period sizes in a given range.
2485    ///
2486    /// # Examples
2487    ///
2488    /// ```rust,no_run
2489    /// use audio_device::alsa;
2490    ///
2491    /// # fn main() -> anyhow::Result<()> {
2492    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
2493    /// let mut hw = pcm.hardware_parameters_any()?;
2494    ///
2495    /// let actual = hw.set_period_size_minmax(128, alsa::Direction::Nearest, 256, alsa::Direction::Nearest)?;
2496    /// dbg!(actual);
2497    /// # Ok(()) }
2498    /// ```
2499    pub fn set_period_size_minmax(
2500        &mut self,
2501        mut frames_min: c::c_ulong,
2502        dir_min: Direction,
2503        mut frames_max: c::c_ulong,
2504        dir_max: Direction,
2505    ) -> Result<(c::c_ulong, Direction, c::c_ulong, Direction)> {
2506        unsafe {
2507            let mut dir_min = dir_min as i32;
2508            let mut dir_max = dir_max as i32;
2509            errno!(alsa::snd_pcm_hw_params_set_period_size_minmax(
2510                self.pcm.as_mut(),
2511                self.base.handle.as_mut(),
2512                &mut frames_min,
2513                &mut dir_min,
2514                &mut frames_max,
2515                &mut dir_max,
2516            ))?;
2517            let dir_min = Direction::from_value(dir_min);
2518            let dir_max = Direction::from_value(dir_max);
2519            Ok((frames_min, dir_min, frames_max, dir_max))
2520        }
2521    }
2522
2523    /// Restrict a configuration space to have period size nearest to a target.
2524    ///
2525    /// # Examples
2526    ///
2527    /// ```rust,no_run
2528    /// use audio_device::alsa;
2529    ///
2530    /// # fn main() -> anyhow::Result<()> {
2531    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
2532    /// let mut hw = pcm.hardware_parameters_any()?;
2533    ///
2534    /// let actual = hw.set_period_size_near(1024, alsa::Direction::Nearest)?;
2535    /// dbg!(actual);
2536    /// # Ok(()) }
2537    /// ```
2538    pub fn set_period_size_near(
2539        &mut self,
2540        mut frames: c::c_ulong,
2541        dir: Direction,
2542    ) -> Result<(c::c_ulong, Direction)> {
2543        unsafe {
2544            let mut dir = dir as i32;
2545            errno!(alsa::snd_pcm_hw_params_set_period_size_near(
2546                self.pcm.as_mut(),
2547                self.base.handle.as_mut(),
2548                &mut frames,
2549                &mut dir,
2550            ))?;
2551            let dir = Direction::from_value(dir);
2552            Ok((frames, dir))
2553        }
2554    }
2555
2556    /// Restrict a configuration space to contain only its minimum period size.
2557    ///
2558    /// # Examples
2559    ///
2560    /// ```rust,no_run
2561    /// use audio_device::alsa;
2562    ///
2563    /// # fn main() -> anyhow::Result<()> {
2564    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
2565    /// let mut hw = pcm.hardware_parameters_any()?;
2566    ///
2567    /// let actual = hw.set_period_size_first()?;
2568    /// dbg!(actual);
2569    /// # Ok(()) }
2570    /// ```
2571    pub fn set_period_size_first(&mut self) -> Result<(c::c_ulong, Direction)> {
2572        unsafe {
2573            let mut frames = mem::MaybeUninit::uninit();
2574            let mut dir = mem::MaybeUninit::uninit();
2575            errno!(alsa::snd_pcm_hw_params_set_period_size_first(
2576                self.pcm.as_mut(),
2577                self.base.handle.as_mut(),
2578                frames.as_mut_ptr(),
2579                dir.as_mut_ptr()
2580            ))?;
2581            let frames = frames.assume_init();
2582            let dir = Direction::from_value(dir.assume_init());
2583            Ok((frames, dir))
2584        }
2585    }
2586
2587    /// Restrict a configuration space to contain only its maximum period size.
2588    ///
2589    /// # Examples
2590    ///
2591    /// ```rust,no_run
2592    /// use audio_device::alsa;
2593    ///
2594    /// # fn main() -> anyhow::Result<()> {
2595    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
2596    /// let mut hw = pcm.hardware_parameters_any()?;
2597    ///
2598    /// let actual = hw.set_period_size_last()?;
2599    /// dbg!(actual);
2600    /// # Ok(()) }
2601    /// ```
2602    pub fn set_period_size_last(&mut self) -> Result<(c::c_ulong, Direction)> {
2603        unsafe {
2604            let mut frames = mem::MaybeUninit::uninit();
2605            let mut dir = mem::MaybeUninit::uninit();
2606            errno!(alsa::snd_pcm_hw_params_set_period_size_last(
2607                self.pcm.as_mut(),
2608                self.base.handle.as_mut(),
2609                frames.as_mut_ptr(),
2610                dir.as_mut_ptr()
2611            ))?;
2612            let frames = frames.assume_init();
2613            let dir = Direction::from_value(dir.assume_init());
2614            Ok((frames, dir))
2615        }
2616    }
2617
2618    /// Restrict a configuration space to contain only integer period sizes.
2619    ///
2620    /// # Examples
2621    ///
2622    /// ```rust,no_run
2623    /// use audio_device::alsa;
2624    ///
2625    /// # fn main() -> anyhow::Result<()> {
2626    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
2627    /// let mut hw = pcm.hardware_parameters_any()?;
2628    ///
2629    /// let actual = hw.set_period_size_integer()?;
2630    /// dbg!(actual);
2631    /// # Ok(()) }
2632    /// ```
2633    pub fn set_period_size_integer(&mut self) -> Result<()> {
2634        unsafe {
2635            errno!(alsa::snd_pcm_hw_params_set_period_size_integer(
2636                self.pcm.as_mut(),
2637                self.base.handle.as_mut(),
2638            ))?;
2639            Ok(())
2640        }
2641    }
2642
2643    /// Verify if a periods count is available inside a configuration space for a PCM.
2644    ///
2645    /// # Examples
2646    ///
2647    /// ```rust,no_run
2648    /// use audio_device::alsa;
2649    ///
2650    /// # fn main() -> anyhow::Result<()> {
2651    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
2652    /// let mut hw = pcm.hardware_parameters_any()?;
2653    ///
2654    /// if hw.test_periods(128, alsa::Direction::Nearest)? {
2655    ///     println!("period size supported!");
2656    /// }
2657    /// # Ok(()) }
2658    /// ```
2659    pub fn test_periods(&mut self, periods: c::c_uint, dir: Direction) -> Result<bool> {
2660        unsafe {
2661            let result = alsa::snd_pcm_hw_params_test_periods(
2662                self.pcm.as_mut(),
2663                self.base.handle.as_mut(),
2664                periods,
2665                dir as i32,
2666            );
2667            Ok(result == 1)
2668        }
2669    }
2670
2671    /// Restrict a configuration space to contain only one periods count.
2672    ///
2673    /// # Examples
2674    ///
2675    /// ```rust,no_run
2676    /// use audio_device::alsa;
2677    ///
2678    /// # fn main() -> anyhow::Result<()> {
2679    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
2680    /// let mut hw = pcm.hardware_parameters_any()?;
2681    ///
2682    /// let actual = hw.set_periods(128, alsa::Direction::Nearest)?;
2683    /// dbg!(actual);
2684    /// # Ok(()) }
2685    /// ```
2686    pub fn set_periods(&mut self, periods: c::c_uint, dir: Direction) -> Result<()> {
2687        unsafe {
2688            errno!(alsa::snd_pcm_hw_params_set_periods(
2689                self.pcm.as_mut(),
2690                self.base.handle.as_mut(),
2691                periods,
2692                dir as i32,
2693            ))?;
2694            Ok(())
2695        }
2696    }
2697
2698    /// Restrict a configuration space with a minimum periods count.
2699    ///
2700    /// # Examples
2701    ///
2702    /// ```rust,no_run
2703    /// use audio_device::alsa;
2704    ///
2705    /// # fn main() -> anyhow::Result<()> {
2706    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
2707    /// let mut hw = pcm.hardware_parameters_any()?;
2708    ///
2709    /// let actual = hw.set_periods_min(128, alsa::Direction::Nearest)?;
2710    /// dbg!(actual);
2711    /// # Ok(()) }
2712    /// ```
2713    pub fn set_periods_min(
2714        &mut self,
2715        mut periods: c::c_uint,
2716        dir: Direction,
2717    ) -> Result<(c::c_uint, Direction)> {
2718        unsafe {
2719            let mut dir = dir as i32;
2720            errno!(alsa::snd_pcm_hw_params_set_periods_min(
2721                self.pcm.as_mut(),
2722                self.base.handle.as_mut(),
2723                &mut periods,
2724                &mut dir
2725            ))?;
2726            let dir = Direction::from_value(dir);
2727            Ok((periods, dir))
2728        }
2729    }
2730
2731    /// Restrict a configuration space with a maximum periods count.
2732    ///
2733    /// # Examples
2734    ///
2735    /// ```rust,no_run
2736    /// use audio_device::alsa;
2737    ///
2738    /// # fn main() -> anyhow::Result<()> {
2739    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
2740    /// let mut hw = pcm.hardware_parameters_any()?;
2741    ///
2742    /// let actual = hw.set_periods_max(128, alsa::Direction::Nearest)?;
2743    /// dbg!(actual);
2744    /// # Ok(()) }
2745    /// ```
2746    pub fn set_periods_max(
2747        &mut self,
2748        mut periods: c::c_uint,
2749        dir: Direction,
2750    ) -> Result<(c::c_uint, Direction)> {
2751        unsafe {
2752            let mut dir = dir as i32;
2753            errno!(alsa::snd_pcm_hw_params_set_periods_max(
2754                self.pcm.as_mut(),
2755                self.base.handle.as_mut(),
2756                &mut periods,
2757                &mut dir
2758            ))?;
2759            let dir = Direction::from_value(dir);
2760            Ok((periods, dir))
2761        }
2762    }
2763
2764    /// Restrict a configuration space to have periods counts in a given range.
2765    ///
2766    /// # Examples
2767    ///
2768    /// ```rust,no_run
2769    /// use audio_device::alsa;
2770    ///
2771    /// # fn main() -> anyhow::Result<()> {
2772    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
2773    /// let mut hw = pcm.hardware_parameters_any()?;
2774    ///
2775    /// let actual = hw.set_periods_minmax(128, alsa::Direction::Nearest, 256, alsa::Direction::Nearest)?;
2776    /// dbg!(actual);
2777    /// # Ok(()) }
2778    /// ```
2779    pub fn set_periods_minmax(
2780        &mut self,
2781        mut periods_min: c::c_uint,
2782        dir_min: Direction,
2783        mut periods_max: c::c_uint,
2784        dir_max: Direction,
2785    ) -> Result<(c::c_uint, Direction, c::c_uint, Direction)> {
2786        unsafe {
2787            let mut dir_min = dir_min as i32;
2788            let mut dir_max = dir_max as i32;
2789            errno!(alsa::snd_pcm_hw_params_set_periods_minmax(
2790                self.pcm.as_mut(),
2791                self.base.handle.as_mut(),
2792                &mut periods_min,
2793                &mut dir_min,
2794                &mut periods_max,
2795                &mut dir_max,
2796            ))?;
2797            let dir_min = Direction::from_value(dir_min);
2798            let dir_max = Direction::from_value(dir_max);
2799            Ok((periods_min, dir_min, periods_max, dir_max))
2800        }
2801    }
2802
2803    /// Restrict a configuration space to have periods count nearest to a target.
2804    ///
2805    /// # Examples
2806    ///
2807    /// ```rust,no_run
2808    /// use audio_device::alsa;
2809    ///
2810    /// # fn main() -> anyhow::Result<()> {
2811    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
2812    /// let mut hw = pcm.hardware_parameters_any()?;
2813    ///
2814    /// let actual = hw.set_periods_near(1024, alsa::Direction::Nearest)?;
2815    /// dbg!(actual);
2816    /// # Ok(()) }
2817    /// ```
2818    pub fn set_periods_near(
2819        &mut self,
2820        mut periods: c::c_uint,
2821        dir: Direction,
2822    ) -> Result<(c::c_uint, Direction)> {
2823        unsafe {
2824            let mut dir = dir as i32;
2825            errno!(alsa::snd_pcm_hw_params_set_periods_near(
2826                self.pcm.as_mut(),
2827                self.base.handle.as_mut(),
2828                &mut periods,
2829                &mut dir,
2830            ))?;
2831            let dir = Direction::from_value(dir);
2832            Ok((periods, dir))
2833        }
2834    }
2835
2836    /// Restrict a configuration space to contain only its minimum periods count.
2837    ///
2838    /// # Examples
2839    ///
2840    /// ```rust,no_run
2841    /// use audio_device::alsa;
2842    ///
2843    /// # fn main() -> anyhow::Result<()> {
2844    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
2845    /// let mut hw = pcm.hardware_parameters_any()?;
2846    ///
2847    /// let actual = hw.set_periods_first()?;
2848    /// dbg!(actual);
2849    /// # Ok(()) }
2850    /// ```
2851    pub fn set_periods_first(&mut self) -> Result<(c::c_uint, Direction)> {
2852        unsafe {
2853            let mut periods = mem::MaybeUninit::uninit();
2854            let mut dir = mem::MaybeUninit::uninit();
2855            errno!(alsa::snd_pcm_hw_params_set_periods_first(
2856                self.pcm.as_mut(),
2857                self.base.handle.as_mut(),
2858                periods.as_mut_ptr(),
2859                dir.as_mut_ptr()
2860            ))?;
2861            let periods = periods.assume_init();
2862            let dir = Direction::from_value(dir.assume_init());
2863            Ok((periods, dir))
2864        }
2865    }
2866
2867    /// Restrict a configuration space to contain only its maximum periods count.
2868    ///
2869    /// # Examples
2870    ///
2871    /// ```rust,no_run
2872    /// use audio_device::alsa;
2873    ///
2874    /// # fn main() -> anyhow::Result<()> {
2875    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
2876    /// let mut hw = pcm.hardware_parameters_any()?;
2877    ///
2878    /// let actual = hw.set_periods_last()?;
2879    /// dbg!(actual);
2880    /// # Ok(()) }
2881    /// ```
2882    pub fn set_periods_last(&mut self) -> Result<(c::c_uint, Direction)> {
2883        unsafe {
2884            let mut periods = mem::MaybeUninit::uninit();
2885            let mut dir = mem::MaybeUninit::uninit();
2886            errno!(alsa::snd_pcm_hw_params_set_periods_last(
2887                self.pcm.as_mut(),
2888                self.base.handle.as_mut(),
2889                periods.as_mut_ptr(),
2890                dir.as_mut_ptr()
2891            ))?;
2892            let periods = periods.assume_init();
2893            let dir = Direction::from_value(dir.assume_init());
2894            Ok((periods, dir))
2895        }
2896    }
2897
2898    /// Restrict a configuration space to contain only integer periods counts.
2899    ///
2900    /// # Examples
2901    ///
2902    /// ```rust,no_run
2903    /// use audio_device::alsa;
2904    ///
2905    /// # fn main() -> anyhow::Result<()> {
2906    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
2907    /// let mut hw = pcm.hardware_parameters_any()?;
2908    ///
2909    /// let actual = hw.set_periods_integer()?;
2910    /// dbg!(actual);
2911    /// # Ok(()) }
2912    /// ```
2913    pub fn set_periods_integer(&mut self) -> Result<()> {
2914        unsafe {
2915            errno!(alsa::snd_pcm_hw_params_set_periods_integer(
2916                self.pcm.as_mut(),
2917                self.base.handle.as_mut(),
2918            ))?;
2919            Ok(())
2920        }
2921    }
2922
2923    /// Verify if a buffer time is available inside a configuration space for a PCM.
2924    ///
2925    /// # Examples
2926    ///
2927    /// ```rust,no_run
2928    /// use audio_device::alsa;
2929    ///
2930    /// # fn main() -> anyhow::Result<()> {
2931    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
2932    /// let mut hw = pcm.hardware_parameters_any()?;
2933    ///
2934    /// dbg!(hw.test_buffer_time(10_000, alsa::Direction::Nearest)?);
2935    /// # Ok(()) }
2936    /// ```
2937    pub fn test_buffer_time(&mut self, buffer_time: c::c_uint, dir: Direction) -> Result<bool> {
2938        unsafe {
2939            let result = errno!(alsa::snd_pcm_hw_params_test_buffer_time(
2940                self.pcm.as_mut(),
2941                self.base.handle.as_mut(),
2942                buffer_time,
2943                dir as i32,
2944            ))?;
2945            Ok(result == 0)
2946        }
2947    }
2948
2949    /// Restrict a configuration space to contain only one buffer time.
2950    ///
2951    /// # Examples
2952    ///
2953    /// ```rust,no_run
2954    /// use audio_device::alsa;
2955    ///
2956    /// # fn main() -> anyhow::Result<()> {
2957    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
2958    /// let mut hw = pcm.hardware_parameters_any()?;
2959    ///
2960    /// let actual = hw.set_buffer_time(10_000, alsa::Direction::Nearest)?;
2961    /// dbg!(actual);
2962    /// # Ok(()) }
2963    /// ```
2964    pub fn set_buffer_time(&mut self, buffer_time: c::c_uint, dir: Direction) -> Result<()> {
2965        unsafe {
2966            errno!(alsa::snd_pcm_hw_params_set_buffer_time(
2967                self.pcm.as_mut(),
2968                self.base.handle.as_mut(),
2969                buffer_time,
2970                dir as i32,
2971            ))?;
2972            Ok(())
2973        }
2974    }
2975
2976    /// Restrict a configuration space with a minimum buffer time.
2977    ///
2978    /// # Examples
2979    ///
2980    /// ```rust,no_run
2981    /// use audio_device::alsa;
2982    ///
2983    /// # fn main() -> anyhow::Result<()> {
2984    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
2985    /// let mut hw = pcm.hardware_parameters_any()?;
2986    ///
2987    /// let actual = hw.set_buffer_time_min(10_000, alsa::Direction::Nearest)?;
2988    /// dbg!(actual);
2989    /// # Ok(()) }
2990    /// ```
2991    pub fn set_buffer_time_min(
2992        &mut self,
2993        mut buffer_time: c::c_uint,
2994        dir: Direction,
2995    ) -> Result<(c::c_uint, Direction)> {
2996        unsafe {
2997            let mut dir = dir as i32;
2998            errno!(alsa::snd_pcm_hw_params_set_buffer_time_min(
2999                self.pcm.as_mut(),
3000                self.base.handle.as_mut(),
3001                &mut buffer_time,
3002                &mut dir
3003            ))?;
3004            let dir = Direction::from_value(dir);
3005            Ok((buffer_time, dir))
3006        }
3007    }
3008
3009    /// Restrict a configuration space with a maximum buffer time.
3010    ///
3011    /// # Examples
3012    ///
3013    /// ```rust,no_run
3014    /// use audio_device::alsa;
3015    ///
3016    /// # fn main() -> anyhow::Result<()> {
3017    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
3018    /// let mut hw = pcm.hardware_parameters_any()?;
3019    ///
3020    /// let actual = hw.set_buffer_time_max(10_000, alsa::Direction::Nearest)?;
3021    /// dbg!(actual);
3022    /// # Ok(()) }
3023    /// ```
3024    pub fn set_buffer_time_max(
3025        &mut self,
3026        mut buffer_time: c::c_uint,
3027        dir: Direction,
3028    ) -> Result<(c::c_uint, Direction)> {
3029        unsafe {
3030            let mut dir = dir as i32;
3031            errno!(alsa::snd_pcm_hw_params_set_buffer_time_max(
3032                self.pcm.as_mut(),
3033                self.base.handle.as_mut(),
3034                &mut buffer_time,
3035                &mut dir
3036            ))?;
3037            let dir = Direction::from_value(dir);
3038            Ok((buffer_time, dir))
3039        }
3040    }
3041
3042    /// Restrict a configuration space to have buffer times in a given range.
3043    ///
3044    /// # Examples
3045    ///
3046    /// ```rust,no_run
3047    /// use audio_device::alsa;
3048    ///
3049    /// # fn main() -> anyhow::Result<()> {
3050    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
3051    /// let mut hw = pcm.hardware_parameters_any()?;
3052    ///
3053    /// let actual = hw.set_buffer_time_minmax(10_000, alsa::Direction::Nearest, 20_000, alsa::Direction::Nearest)?;
3054    /// dbg!(actual);
3055    /// # Ok(()) }
3056    /// ```
3057    pub fn set_buffer_time_minmax(
3058        &mut self,
3059        mut buffer_time_min: c::c_uint,
3060        dir_min: Direction,
3061        mut buffer_time_max: c::c_uint,
3062        dir_max: Direction,
3063    ) -> Result<(c::c_uint, Direction, c::c_uint, Direction)> {
3064        unsafe {
3065            let mut dir_min = dir_min as i32;
3066            let mut dir_max = dir_max as i32;
3067            errno!(alsa::snd_pcm_hw_params_set_buffer_time_minmax(
3068                self.pcm.as_mut(),
3069                self.base.handle.as_mut(),
3070                &mut buffer_time_min,
3071                &mut dir_min,
3072                &mut buffer_time_max,
3073                &mut dir_max
3074            ))?;
3075            let dir_min = Direction::from_value(dir_min);
3076            let dir_max = Direction::from_value(dir_max);
3077            Ok((buffer_time_min, dir_min, buffer_time_max, dir_max))
3078        }
3079    }
3080
3081    /// Restrict a configuration space to have buffer time nearest to a target.
3082    ///
3083    /// # Examples
3084    ///
3085    /// ```rust,no_run
3086    /// use audio_device::alsa;
3087    ///
3088    /// # fn main() -> anyhow::Result<()> {
3089    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
3090    /// let mut hw = pcm.hardware_parameters_any()?;
3091    ///
3092    /// let actual = hw.set_buffer_time_near(10_000, alsa::Direction::Nearest)?;
3093    /// dbg!(actual);
3094    /// # Ok(()) }
3095    /// ```
3096    pub fn set_buffer_time_near(
3097        &mut self,
3098        mut buffer_time: c::c_uint,
3099        dir: Direction,
3100    ) -> Result<(c::c_uint, Direction)> {
3101        unsafe {
3102            let mut dir = dir as i32;
3103            errno!(alsa::snd_pcm_hw_params_set_buffer_time_near(
3104                self.pcm.as_mut(),
3105                self.base.handle.as_mut(),
3106                &mut buffer_time,
3107                &mut dir
3108            ))?;
3109            let dir = Direction::from_value(dir);
3110            Ok((buffer_time, dir))
3111        }
3112    }
3113
3114    /// Restrict a configuration space to contain only its minimum buffer time.
3115    ///
3116    /// # Examples
3117    ///
3118    /// ```rust,no_run
3119    /// use audio_device::alsa;
3120    ///
3121    /// # fn main() -> anyhow::Result<()> {
3122    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
3123    /// let mut hw = pcm.hardware_parameters_any()?;
3124    ///
3125    /// let actual = hw.set_buffer_time_first()?;
3126    /// dbg!(actual);
3127    /// # Ok(()) }
3128    /// ```
3129    pub fn set_buffer_time_first(&mut self) -> Result<(c::c_uint, Direction)> {
3130        unsafe {
3131            let mut buffer_time = mem::MaybeUninit::uninit();
3132            let mut dir = mem::MaybeUninit::uninit();
3133            errno!(alsa::snd_pcm_hw_params_set_buffer_time_first(
3134                self.pcm.as_mut(),
3135                self.base.handle.as_mut(),
3136                buffer_time.as_mut_ptr(),
3137                dir.as_mut_ptr()
3138            ))?;
3139            let buffer_time = buffer_time.assume_init();
3140            let dir = Direction::from_value(dir.assume_init());
3141            Ok((buffer_time, dir))
3142        }
3143    }
3144
3145    /// Restrict a configuration space to contain only its maximum buffered time.
3146    ///
3147    /// # Examples
3148    ///
3149    /// ```rust,no_run
3150    /// use audio_device::alsa;
3151    ///
3152    /// # fn main() -> anyhow::Result<()> {
3153    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
3154    /// let mut hw = pcm.hardware_parameters_any()?;
3155    ///
3156    /// let actual = hw.set_buffer_time_last()?;
3157    /// dbg!(actual);
3158    /// # Ok(()) }
3159    /// ```
3160    pub fn set_buffer_time_last(&mut self) -> Result<(c::c_uint, Direction)> {
3161        unsafe {
3162            let mut buffer_time = mem::MaybeUninit::uninit();
3163            let mut dir = mem::MaybeUninit::uninit();
3164            errno!(alsa::snd_pcm_hw_params_set_buffer_time_last(
3165                self.pcm.as_mut(),
3166                self.base.handle.as_mut(),
3167                buffer_time.as_mut_ptr(),
3168                dir.as_mut_ptr()
3169            ))?;
3170            let buffer_time = buffer_time.assume_init();
3171            let dir = Direction::from_value(dir.assume_init());
3172            Ok((buffer_time, dir))
3173        }
3174    }
3175
3176    /// Verify if a buffer size is available inside a configuration space for a PCM.
3177    ///
3178    /// # Examples
3179    ///
3180    /// ```rust,no_run
3181    /// use audio_device::alsa;
3182    ///
3183    /// # fn main() -> anyhow::Result<()> {
3184    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
3185    /// let mut hw = pcm.hardware_parameters_any()?;
3186    ///
3187    /// dbg!(hw.test_buffer_size(1024)?);
3188    /// # Ok(()) }
3189    /// ```
3190    pub fn test_buffer_size(&mut self, buffer_size: c::c_ulong) -> Result<bool> {
3191        unsafe {
3192            let result = errno!(alsa::snd_pcm_hw_params_test_buffer_size(
3193                self.pcm.as_mut(),
3194                self.base.handle.as_mut(),
3195                buffer_size
3196            ))?;
3197            Ok(result == 0)
3198        }
3199    }
3200
3201    /// Restrict a configuration space to contain only one buffer size.
3202    ///
3203    /// # Examples
3204    ///
3205    /// ```rust,no_run
3206    /// use audio_device::alsa;
3207    ///
3208    /// # fn main() -> anyhow::Result<()> {
3209    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
3210    /// let mut hw = pcm.hardware_parameters_any()?;
3211    ///
3212    /// let actual = hw.set_buffer_size(1024)?;
3213    /// dbg!(actual);
3214    /// # Ok(()) }
3215    /// ```
3216    pub fn set_buffer_size(&mut self, buffer_size: c::c_ulong) -> Result<()> {
3217        unsafe {
3218            errno!(alsa::snd_pcm_hw_params_set_buffer_size(
3219                self.pcm.as_mut(),
3220                self.base.handle.as_mut(),
3221                buffer_size
3222            ))?;
3223            Ok(())
3224        }
3225    }
3226
3227    /// Restrict a configuration space with a minimum buffer size.
3228    ///
3229    /// # Examples
3230    ///
3231    /// ```rust,no_run
3232    /// use audio_device::alsa;
3233    ///
3234    /// # fn main() -> anyhow::Result<()> {
3235    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
3236    /// let mut hw = pcm.hardware_parameters_any()?;
3237    ///
3238    /// let actual = hw.set_buffer_size_min(1024)?;
3239    /// dbg!(actual);
3240    /// # Ok(()) }
3241    /// ```
3242    pub fn set_buffer_size_min(&mut self, mut buffer_size: c::c_ulong) -> Result<c::c_ulong> {
3243        unsafe {
3244            errno!(alsa::snd_pcm_hw_params_set_buffer_size_min(
3245                self.pcm.as_mut(),
3246                self.base.handle.as_mut(),
3247                &mut buffer_size
3248            ))?;
3249            Ok(buffer_size)
3250        }
3251    }
3252
3253    /// Restrict a configuration space with a maximum buffer size.
3254    ///
3255    /// # Examples
3256    ///
3257    /// ```rust,no_run
3258    /// use audio_device::alsa;
3259    ///
3260    /// # fn main() -> anyhow::Result<()> {
3261    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
3262    /// let mut hw = pcm.hardware_parameters_any()?;
3263    ///
3264    /// let actual = hw.set_buffer_size_max(1024)?;
3265    /// dbg!(actual);
3266    /// # Ok(()) }
3267    /// ```
3268    pub fn set_buffer_size_max(&mut self, mut buffer_size: c::c_ulong) -> Result<c::c_ulong> {
3269        unsafe {
3270            errno!(alsa::snd_pcm_hw_params_set_buffer_size_max(
3271                self.pcm.as_mut(),
3272                self.base.handle.as_mut(),
3273                &mut buffer_size
3274            ))?;
3275            Ok(buffer_size)
3276        }
3277    }
3278
3279    /// Restrict a configuration space to have buffer sizes in a given range.
3280    ///
3281    /// # Examples
3282    ///
3283    /// ```rust,no_run
3284    /// use audio_device::alsa;
3285    ///
3286    /// # fn main() -> anyhow::Result<()> {
3287    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
3288    /// let mut hw = pcm.hardware_parameters_any()?;
3289    ///
3290    /// let actual = hw.set_buffer_size_minmax(1024, 4096)?;
3291    /// dbg!(actual);
3292    /// # Ok(()) }
3293    /// ```
3294    pub fn set_buffer_size_minmax(
3295        &mut self,
3296        mut buffer_size_min: c::c_ulong,
3297        mut buffer_size_max: c::c_ulong,
3298    ) -> Result<(c::c_ulong, c::c_ulong)> {
3299        unsafe {
3300            errno!(alsa::snd_pcm_hw_params_set_buffer_size_minmax(
3301                self.pcm.as_mut(),
3302                self.base.handle.as_mut(),
3303                &mut buffer_size_min,
3304                &mut buffer_size_max,
3305            ))?;
3306            Ok((buffer_size_min, buffer_size_max))
3307        }
3308    }
3309
3310    /// Restrict a configuration space to have buffer size nearest to a target.
3311    ///
3312    /// # Examples
3313    ///
3314    /// ```rust,no_run
3315    /// use audio_device::alsa;
3316    ///
3317    /// # fn main() -> anyhow::Result<()> {
3318    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
3319    /// let mut hw = pcm.hardware_parameters_any()?;
3320    ///
3321    /// let actual = hw.set_buffer_size_near(1024)?;
3322    /// dbg!(actual);
3323    /// # Ok(()) }
3324    /// ```
3325    pub fn set_buffer_size_near(&mut self, mut buffer_size: c::c_ulong) -> Result<c::c_ulong> {
3326        unsafe {
3327            errno!(alsa::snd_pcm_hw_params_set_buffer_size_near(
3328                self.pcm.as_mut(),
3329                self.base.handle.as_mut(),
3330                &mut buffer_size
3331            ))?;
3332            Ok(buffer_size)
3333        }
3334    }
3335
3336    /// Restrict a configuration space to contain only its minimum buffer size.
3337    ///
3338    /// # Examples
3339    ///
3340    /// ```rust,no_run
3341    /// use audio_device::alsa;
3342    ///
3343    /// # fn main() -> anyhow::Result<()> {
3344    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
3345    /// let mut hw = pcm.hardware_parameters_any()?;
3346    ///
3347    /// let actual = hw.set_buffer_size_first()?;
3348    /// dbg!(actual);
3349    /// # Ok(()) }
3350    /// ```
3351    pub fn set_buffer_size_first(&mut self) -> Result<c::c_ulong> {
3352        unsafe {
3353            let mut buffer_size = mem::MaybeUninit::uninit();
3354            errno!(alsa::snd_pcm_hw_params_set_buffer_size_first(
3355                self.pcm.as_mut(),
3356                self.base.handle.as_mut(),
3357                buffer_size.as_mut_ptr()
3358            ))?;
3359            Ok(buffer_size.assume_init())
3360        }
3361    }
3362
3363    /// Restrict a configuration space to contain only its maximum buffer size.
3364    ///
3365    /// # Examples
3366    ///
3367    /// ```rust,no_run
3368    /// use audio_device::alsa;
3369    ///
3370    /// # fn main() -> anyhow::Result<()> {
3371    /// let mut pcm = alsa::Pcm::open_default(alsa::Stream::Playback)?;
3372    /// let mut hw = pcm.hardware_parameters_any()?;
3373    ///
3374    /// let actual = hw.set_buffer_size_last()?;
3375    /// dbg!(actual);
3376    /// # Ok(()) }
3377    /// ```
3378    pub fn set_buffer_size_last(&mut self) -> Result<c::c_ulong> {
3379        unsafe {
3380            let mut buffer_size = mem::MaybeUninit::uninit();
3381            errno!(alsa::snd_pcm_hw_params_set_buffer_size_last(
3382                self.pcm.as_mut(),
3383                self.base.handle.as_mut(),
3384                buffer_size.as_mut_ptr()
3385            ))?;
3386            Ok(buffer_size.assume_init())
3387        }
3388    }
3389
3390    // Note: subformat related things is not implemented.
3391
3392    // int snd_pcm_hw_params_get_subformat (const snd_pcm_hw_params_t *params, snd_pcm_subformat_t *subformat)
3393    // Extract subformat from a configuration space.
3394
3395    // int snd_pcm_hw_params_test_subformat (snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_subformat_t subformat)
3396    // Verify if a subformat is available inside a configuration space for a PCM.
3397
3398    // int snd_pcm_hw_params_set_subformat (snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_subformat_t subformat)
3399    // Restrict a configuration space to contain only one subformat.
3400
3401    // int snd_pcm_hw_params_set_subformat_first (snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_subformat_t *subformat)
3402    // Restrict a configuration space to contain only its first subformat.
3403
3404    // int snd_pcm_hw_params_set_subformat_last (snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_subformat_t *subformat)
3405    // Restrict a configuration space to contain only its last subformat.
3406
3407    // int snd_pcm_hw_params_set_subformat_mask (snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_subformat_mask_t *mask)
3408    // Restrict a configuration space to contain only a set of subformats.
3409
3410    // void snd_pcm_hw_params_get_subformat_mask (snd_pcm_hw_params_t *params, snd_pcm_subformat_mask_t *mask)
3411    // Get subformat mask from a configuration space.
3412}
3413
3414impl ops::Deref for HardwareParametersMut<'_> {
3415    type Target = HardwareParameters;
3416
3417    fn deref(&self) -> &Self::Target {
3418        &self.base
3419    }
3420}