pix_engine/
audio.rs

1//! Trait and types for allowing [`Engine`] to play and capture audio.
2//!
3//! There are several methods for playing audio in your application:
4//!
5//! - Queuing pre-recorded or generated audio samples by calling [`PixState::enqueue_audio`].
6//! - Having [`Engine`] request pre-recorded or generated audio samples by implementing the
7//!   [`AudioCallback`] trait on a type and calling [`PixState::open_playback`].
8//! - Loading and playing a `.wav` or `.mp3` file. (Coming soon!).
9//!
10//! You can also record audio from a capture device using [`PixState::open_capture`].
11//!
12//! [`Engine`]: crate::engine::Engine
13//!
14//! # Examples
15//!
16//! ## Audio Queue
17//!
18//! ```no_run
19//! use pix_engine::{prelude::*, math::PI};
20//!
21//! struct MyApp;
22//!
23//! impl PixEngine for MyApp {
24//!     fn on_start(&mut self, s: &mut PixState) -> PixResult<()> {
25//!         s.resume_audio();
26//!         Ok(())
27//!     }
28//!
29//!     fn on_update(&mut self, s: &mut PixState) -> PixResult<()> {
30//!         // Some square wave samples of audio
31//!         let volume = 0.2;
32//!         let sample_rate = s.audio_sample_rate() as f32;
33//!         let sample_count = 4 * sample_rate as usize;
34//!         let frequency = 440.0; // A4 note
35//!         let mut samples = Vec::with_capacity(sample_count);
36//!         for x in 0..sample_count {
37//!             let s = (2.0 * PI as f32 * frequency * x as f32 / sample_rate).sin();
38//!             samples.push(if s <= 0.0 { -volume } else { volume });
39//!         }
40//!         // Add samples to audio queue for playback
41//!         s.enqueue_audio(&samples)?;
42//!         Ok(())
43//!     }
44//! }
45//! ```
46//!
47//! ## Audio Callback
48//!
49//! ```no_run
50//! use pix_engine::prelude::*;
51//! use std::time::Duration;
52//!
53//! struct SquareWave {
54//!     phase_inc: f32,
55//!     phase: f32,
56//!     volume: f32,
57//! }
58//!
59//! impl AudioCallback for SquareWave {
60//!     type Channel = f32;
61//!
62//!     fn callback(&mut self, out: &mut [Self::Channel]) {
63//!         // Generate a square wave
64//!         for x in out.iter_mut() {
65//!             *x = if self.phase <= 0.5 {
66//!                 self.volume
67//!             } else {
68//!                 -self.volume
69//!             };
70//!             self.phase = (self.phase + self.phase_inc) % 1.0;
71//!         }
72//!     }
73//! }
74//!
75//! struct MyApp;
76//!
77//! impl PixEngine for MyApp {
78//!     fn on_update(&mut self, s: &mut PixState) -> PixResult<()> {
79//!         let desired_spec = AudioSpecDesired {
80//!             freq: Some(44_100), // 44,100 HZ
81//!             channels: Some(1),  // mono audio
82//!             samples: None,      // default sample size
83//!         };
84//!         let mut device = s.open_playback(None, &desired_spec, |spec| {
85//!             SquareWave {
86//!                 phase_inc: 440.0 / spec.freq as f32,
87//!                 phase: 0.0,
88//!                 volume: 0.25,
89//!             }
90//!         })?;
91//!
92//!         // Start playback
93//!         device.resume();
94//!
95//!         // Play for 2 seconds then quit.
96//!         std::thread::sleep(Duration::from_millis(2000));
97//!         s.quit();
98//!
99//!         // Device stops playback when dropped.
100//!         Ok(())
101//!     }
102//! }
103//! ```
104//!
105//! ## Audio Capture
106//!
107//! For a more complete example, see `audio_capture_and_replay` in the `examples/` directory.
108//!
109//! ```no_run
110//! use pix_engine::prelude::*;
111//! use std::{sync::mpsc, time::Duration};
112//!
113//! struct Recording {
114//!     record_buffer: Vec<f32>,
115//!     pos: usize,
116//!     tx: mpsc::Sender<Vec<f32>>,
117//!     done: bool,
118//! }
119//!
120//! impl AudioCallback for Recording {
121//!     type Channel = f32;
122//!
123//!     fn callback(&mut self, input: &mut [Self::Channel]) {
124//!         if self.done {
125//!             return;
126//!         }
127//!         for x in input {
128//!            self.record_buffer[self.pos] = *x;
129//!            self.pos += 1;
130//!            if self.pos >= self.record_buffer.len() {
131//!                self.done = true;
132//!                self.tx
133//!                    .send(self.record_buffer.clone())
134//!                    .expect("could not send record buffer");
135//!                break;
136//!            }
137//!         }
138//!     }
139//! }
140//!
141//! struct MyApp;
142//!
143//! const RECORDING_LENGTH_SECONDS: usize = 3;
144//!
145//! impl PixEngine for MyApp {
146//!     fn on_update(&mut self, s: &mut PixState) -> PixResult<()> {
147//!         let desired_spec = AudioSpecDesired {
148//!             freq: None,     // default device frequency
149//!             channels: None, // default device channels
150//!             samples: None,  // default sample size
151//!         };
152//!
153//!         let (tx, rx) = mpsc::channel();
154//!         let capture_device = s.open_capture(None, &desired_spec, |spec| {
155//!             Recording {
156//!                 record_buffer: vec![
157//!                     0.0;
158//!                     spec.freq as usize
159//!                         * RECORDING_LENGTH_SECONDS
160//!                         * spec.channels as usize
161//!                 ],
162//!                 pos: 0,
163//!                 tx,
164//!                 done: false,
165//!             }
166//!         })?;
167//!
168//!         // Start playback
169//!         capture_device.resume();
170//!
171//!         // Wait for recording to finish
172//!         let recorded_samples = rx.recv()?;
173//!         capture_device.pause();
174//!
175//!         // Handle recorded_samples
176//!
177//!         // Device stops playback when dropped.
178//!         Ok(())
179//!     }
180//! }
181//! ```
182//!
183//! [`PixEngine`]: crate::prelude::PixEngine
184
185use crate::prelude::*;
186#[cfg(feature = "serde")]
187use serde::{Deserialize, Serialize};
188
189#[cfg(not(target_arch = "wasm32"))]
190pub use crate::renderer::sdl::{AudioDevice, AudioFormatNum};
191
192#[cfg(target_arch = "wasm32")]
193pub use crate::renderer::wasm::{AudioDevice, AudioFormatNum};
194
195/// Trait for allowing [`Engine`] to request audio samples from your application.
196///
197/// Please see the [module-level documentation] for more examples.
198///
199/// [`Engine`]: crate::engine::Engine
200/// [module-level documentation]: crate::audio
201pub trait AudioCallback: Send
202where
203    Self::Channel: AudioFormatNum + 'static,
204{
205    /// The audio type format for channel samples.
206    type Channel;
207
208    /// Called when the audio playback device needs samples to play or the capture device has
209    /// samples available. `buffer` is a pre-allocated buffer you can iterate over and update to
210    /// provide audio samples, or consume to record audio samples.
211    ///
212    /// # Example
213    ///
214    /// ```
215    /// use pix_engine::prelude::*;
216    ///
217    /// struct SquareWave {
218    ///     phase_inc: f32,
219    ///     phase: f32,
220    ///     volume: f32,
221    /// }
222    ///
223    /// impl AudioCallback for SquareWave {
224    ///     type Channel = f32;
225    ///
226    ///     fn callback(&mut self, out: &mut [Self::Channel]) {
227    ///         // Generate a square wave
228    ///         for x in out.iter_mut() {
229    ///             *x = if self.phase <= 0.5 {
230    ///                 self.volume
231    ///             } else {
232    ///                 -self.volume
233    ///             };
234    ///             self.phase = (self.phase + self.phase_inc) % 1.0;
235    ///         }
236    ///     }
237    /// }
238    /// ```
239    fn callback(&mut self, buffer: &mut [Self::Channel]);
240}
241
242/// Audio number and endianness format for the given audio device.
243#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
244#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
245#[must_use]
246pub enum AudioFormat {
247    /// Unsigned 8-bit samples
248    U8,
249    /// Signed 8-bit samples
250    S8,
251    /// Unsigned 16-bit samples, little-endian
252    U16LSB,
253    /// Unsigned 16-bit samples, big-endian
254    U16MSB,
255    /// Signed 16-bit samples, little-endian
256    S16LSB,
257    /// Signed 16-bit samples, big-endian
258    S16MSB,
259    /// Signed 32-bit samples, little-endian
260    S32LSB,
261    /// Signed 32-bit samples, big-endian
262    S32MSB,
263    /// 32-bit floating point samples, little-endian
264    F32LSB,
265    /// 32-bit floating point samples, big-endian
266    F32MSB,
267}
268
269#[cfg(target_endian = "little")]
270impl AudioFormat {
271    /// Unsigned 16-bit samples, native endian
272    #[inline]
273    pub const fn u16_sys() -> AudioFormat {
274        AudioFormat::U16LSB
275    }
276    /// Signed 16-bit samples, native endian
277    #[inline]
278    pub const fn s16_sys() -> AudioFormat {
279        AudioFormat::S16LSB
280    }
281    /// Signed 32-bit samples, native endian
282    #[inline]
283    pub const fn s32_sys() -> AudioFormat {
284        AudioFormat::S32LSB
285    }
286    /// 32-bit floating point samples, native endian
287    #[inline]
288    pub const fn f32_sys() -> AudioFormat {
289        AudioFormat::F32LSB
290    }
291}
292
293#[cfg(target_endian = "big")]
294impl AudioFormat {
295    /// Unsigned 16-bit samples, native endian
296    #[inline]
297    pub const fn u16_sys() -> AudioFormat {
298        AudioFormat::U16MSB
299    }
300    /// Signed 16-bit samples, native endian
301    #[inline]
302    pub const fn s16_sys() -> AudioFormat {
303        AudioFormat::S16MSB
304    }
305    /// Signed 32-bit samples, native endian
306    #[inline]
307    pub const fn s32_sys() -> AudioFormat {
308        AudioFormat::S32MSB
309    }
310    /// 32-bit floating point samples, native endian
311    #[inline]
312    pub const fn f32_sys() -> AudioFormat {
313        AudioFormat::F32MSB
314    }
315}
316
317impl Default for AudioFormat {
318    fn default() -> Self {
319        Self::f32_sys()
320    }
321}
322
323/// Playback status of an audio device.
324#[derive(Default, Debug, Copy, Clone, PartialEq, Eq, Hash)]
325#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
326#[must_use]
327pub enum AudioStatus {
328    /// Audio device is stopped.
329    #[default]
330    Stopped,
331    /// Audio device is playing.
332    Playing,
333    /// Audio device is paused.
334    Paused,
335}
336
337/// Desired audio device specification.
338#[derive(Default, Debug, Copy, Clone, PartialEq, Eq, Hash)]
339#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
340#[must_use]
341pub struct AudioSpecDesired {
342    /// DSP frequency (samples per second) in Hz. Set to None for the device’s fallback frequency.
343    pub freq: Option<i32>,
344    /// Number of separate sound channels. Set to None for the device’s fallback number of channels.
345    pub channels: Option<u8>,
346    /// The audio buffer size in samples (power of 2). Set to None for the device’s fallback sample size.
347    pub samples: Option<u16>,
348}
349
350/// Audio device specification.
351#[derive(Debug, Copy, Clone, PartialEq, Eq)]
352#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
353#[must_use]
354pub struct AudioSpec {
355    /// DSP frequency (samples per second) in Hz.
356    pub freq: i32,
357    /// `AudioFormat` for the generic sample type.
358    pub format: AudioFormat,
359    /// Number of separate sound channels.
360    pub channels: u8,
361    /// The audio buffer size in samples (power of 2).
362    pub samples: u16,
363    /// The audio buffer size in bytes.
364    pub size: u32,
365}
366
367impl Default for AudioSpec {
368    fn default() -> Self {
369        Self {
370            freq: 44_100,
371            format: AudioFormat::default(),
372            channels: 1,
373            samples: 512,
374            size: 2048,
375        }
376    }
377}
378
379/// Provides access to audio device driver properties and controlling playback.
380pub trait AudioDeviceDriver {
381    /// Return the status of this audio callback device.
382    fn status(&self) -> AudioStatus;
383
384    /// Return the current driver of this audio callback device.
385    fn driver(&self) -> &'static str;
386
387    /// Returns the [`AudioSpec`] for this audio callback device.
388    fn spec(&self) -> AudioSpec;
389
390    /// Resumes playback of this audio callback device.
391    fn resume(&self);
392
393    /// Pause playback of this audio callback device.
394    fn pause(&self);
395}
396
397impl PixState {
398    /// Add samples to the current audio buffer queue.
399    ///
400    /// # Errors
401    ///
402    /// If the audio device fails to queue samples, or if the audio buffer max size is reached,
403    /// then an error is returned.
404    ///
405    /// # Example
406    ///
407    /// ```
408    /// # use pix_engine::{math::PI, prelude::*};
409    /// # struct App;
410    /// # impl PixEngine for App {
411    /// fn on_update(&mut self, s: &mut PixState) -> PixResult<()> {
412    ///     // Some square wave samples of audio
413    ///     let volume = 0.2;
414    ///     let sample_rate = s.audio_sample_rate() as f32;
415    ///     let sample_count = 4 * sample_rate as usize;
416    ///     let frequency = 440.0; // A4 note
417    ///     let mut samples = Vec::with_capacity(sample_count);
418    ///     for x in 0..sample_count {
419    ///         let s = (2.0 * PI as f32 * frequency * x as f32 / sample_rate).sin();
420    ///         samples.push(if s <= 0.0 { -volume } else { volume });
421    ///     }
422    ///     // Add samples to audio queue for playback
423    ///     s.enqueue_audio(&samples)?;
424    ///     Ok(())
425    /// }
426    /// # }
427    /// ```
428    #[inline]
429    pub fn enqueue_audio<S: AsRef<[f32]>>(&mut self, samples: S) -> PixResult<()> {
430        self.renderer.enqueue_audio(samples.as_ref())
431    }
432
433    /// Clear audio samples from the current audio buffer queue.
434    #[inline]
435    pub fn clear_audio(&mut self) {
436        self.renderer.clear_audio();
437    }
438
439    /// Return the status of the current audio queue device.
440    ///
441    /// # Example
442    ///
443    /// ```
444    /// # use pix_engine::prelude::*;
445    /// # struct App;
446    /// # impl PixEngine for App {
447    /// # fn on_update(&mut self, s: &mut PixState) -> PixResult<()> { Ok(()) }
448    /// fn on_key_pressed(&mut self, s: &mut PixState, event: KeyEvent) -> PixResult<bool> {
449    ///     match event.key {
450    ///         Key::Return => {
451    ///             if s.audio_status() == AudioStatus::Paused {
452    ///                 s.resume_audio();
453    ///             }
454    ///             Ok(true)
455    ///         }
456    ///         _ => Ok(false),
457    ///     }
458    /// }
459    /// # }
460    /// ```
461    #[inline]
462    pub fn audio_status(&self) -> AudioStatus {
463        self.renderer.audio_status()
464    }
465
466    /// Return the current driver of this audio callback device.
467    #[inline]
468    #[must_use]
469    pub fn audio_driver(&self) -> &'static str {
470        self.renderer.audio_driver()
471    }
472
473    /// Returns the sample rate for the current audio queue device.
474    #[inline]
475    #[must_use]
476    pub fn audio_sample_rate(&self) -> i32 {
477        self.renderer.audio_sample_rate()
478    }
479
480    /// Returns the queued buffer size of the current audio queue device.
481    #[inline]
482    #[must_use]
483    pub fn audio_queued_size(&self) -> u32 {
484        self.renderer.audio_queued_size()
485    }
486
487    /// Returns the buffer size of the current audio queue device.
488    #[inline]
489    #[must_use]
490    pub fn audio_size(&self) -> u32 {
491        self.renderer.audio_size()
492    }
493
494    /// Resumes playback of the current audio queue device.
495    ///
496    /// # Example
497    ///
498    /// ```
499    /// # use pix_engine::prelude::*;
500    /// # struct App;
501    /// # impl PixEngine for App {
502    /// # fn on_update(&mut self, s: &mut PixState) -> PixResult<()> { Ok(()) }
503    /// fn on_key_pressed(&mut self, s: &mut PixState, event: KeyEvent) -> PixResult<bool> {
504    ///     match event.key {
505    ///         Key::Return => {
506    ///             s.resume_audio();
507    ///             Ok(true)
508    ///         }
509    ///         _ => Ok(false),
510    ///     }
511    /// }
512    /// # }
513    /// ```
514    #[inline]
515    pub fn resume_audio(&mut self) {
516        self.renderer.resume_audio();
517    }
518
519    /// Pause playback of the current audio queue device.
520    ///
521    /// # Example
522    ///
523    /// ```
524    /// # use pix_engine::prelude::*;
525    /// # struct App;
526    /// # impl PixEngine for App {
527    /// # fn on_update(&mut self, s: &mut PixState) -> PixResult<()> { Ok(()) }
528    /// fn on_key_pressed(&mut self, s: &mut PixState, event: KeyEvent) -> PixResult<bool> {
529    ///     match event.key {
530    ///         Key::Return => {
531    ///             s.pause_audio();
532    ///             Ok(true)
533    ///         }
534    ///         _ => Ok(false),
535    ///     }
536    /// }
537    /// # }
538    /// ```
539    #[inline]
540    pub fn pause_audio(&mut self) {
541        self.renderer.pause_audio();
542    }
543
544    /// Opens and returns an audio callback device for playback.
545    ///
546    /// The audio device starts out `paused`. Call [resume](`AudioDevice::resume`) to start
547    /// playback and [pause](`AudioDevice::pause`) to stop playback.
548    ///
549    /// # Errors
550    ///
551    /// If the renderer fails to open an audio device, then an error is returned.
552    ///
553    /// # Example
554    ///
555    /// ```no_run
556    /// use pix_engine::prelude::*;
557    /// use std::time::Duration;
558    ///
559    /// struct SquareWave {
560    ///     phase_inc: f32,
561    ///     phase: f32,
562    ///     volume: f32,
563    /// }
564    ///
565    /// impl AudioCallback for SquareWave {
566    ///     type Channel = f32;
567    ///
568    ///     fn callback(&mut self, out: &mut [Self::Channel]) {
569    ///         // Generate a square wave
570    ///         for x in out.iter_mut() {
571    ///             *x = if self.phase <= 0.5 {
572    ///                 self.volume
573    ///             } else {
574    ///                 -self.volume
575    ///             };
576    ///             self.phase = (self.phase + self.phase_inc) % 1.0;
577    ///         }
578    ///     }
579    /// }
580    ///
581    /// struct MyApp;
582    ///
583    /// impl PixEngine for MyApp {
584    ///     fn on_update(&mut self, s: &mut PixState) -> PixResult<()> {
585    ///         let desired_spec = AudioSpecDesired {
586    ///             freq: Some(44_100), // 44,100 HZ
587    ///             channels: Some(1),  // mono audio
588    ///             samples: None,      // default sample size
589    ///         };
590    ///         let mut device = s.open_playback(None, &desired_spec, |spec| {
591    ///             SquareWave {
592    ///                 phase_inc: 440.0 / spec.freq as f32,
593    ///                 phase: 0.0,
594    ///                 volume: 0.25,
595    ///             }
596    ///         })?;
597    ///
598    ///         // Start playback
599    ///         device.resume();
600    ///
601    ///         // Play for 2 seconds then quit.
602    ///         std::thread::sleep(Duration::from_millis(2000));
603    ///         s.quit();
604    ///
605    ///         // Device stops playback when dropped.
606    ///         Ok(())
607    ///     }
608    /// }
609    /// ```
610    #[allow(single_use_lifetimes)]
611    #[inline]
612    pub fn open_playback<'a, CB, F, D>(
613        &self,
614        device: D,
615        desired_spec: &AudioSpecDesired,
616        get_callback: F,
617    ) -> PixResult<AudioDevice<CB>>
618    where
619        CB: AudioCallback,
620        F: FnOnce(AudioSpec) -> CB,
621        D: Into<Option<&'a str>>,
622    {
623        self.renderer
624            .open_playback(device, desired_spec, get_callback)
625    }
626
627    /// Opens and returns an audio capture device for recording.
628    ///
629    /// The audio device starts out `paused`. Call [resume](`AudioDevice::resume`) to start
630    /// recording and [pause](`AudioDevice::pause`) to stop recording.
631    ///
632    /// # Errors
633    ///
634    /// If the renderer fails to open an audio device, then an error is returned.
635    ///
636    /// # Example
637    ///
638    /// ```no_run
639    /// use pix_engine::prelude::*;
640    /// use std::{sync::mpsc, time::Duration};
641    ///
642    /// struct Recording {
643    ///     record_buffer: Vec<f32>,
644    ///     pos: usize,
645    ///     tx: mpsc::Sender<Vec<f32>>,
646    ///     done: bool,
647    /// }
648    ///
649    /// impl AudioCallback for Recording {
650    ///     type Channel = f32;
651    ///
652    ///     fn callback(&mut self, input: &mut [Self::Channel]) {
653    ///         if self.done {
654    ///             return;
655    ///         }
656    ///         for x in input {
657    ///            self.record_buffer[self.pos] = *x;
658    ///            self.pos += 1;
659    ///            if self.pos >= self.record_buffer.len() {
660    ///                self.done = true;
661    ///                self.tx
662    ///                    .send(self.record_buffer.clone())
663    ///                    .expect("could not send record buffer");
664    ///                break;
665    ///            }
666    ///         }
667    ///     }
668    /// }
669    ///
670    /// struct MyApp;
671    ///
672    /// const RECORDING_LENGTH_SECONDS: usize = 3;
673    ///
674    /// impl PixEngine for MyApp {
675    ///     fn on_update(&mut self, s: &mut PixState) -> PixResult<()> {
676    ///         let desired_spec = AudioSpecDesired {
677    ///             freq: None,     // default device frequency
678    ///             channels: None, // default device channels
679    ///             samples: None,  // default sample size
680    ///         };
681    ///
682    ///         let (tx, rx) = mpsc::channel();
683    ///         let capture_device = s.open_capture(None, &desired_spec, |spec| {
684    ///             Recording {
685    ///                 record_buffer: vec![
686    ///                     0.0;
687    ///                     spec.freq as usize
688    ///                         * RECORDING_LENGTH_SECONDS
689    ///                         * spec.channels as usize
690    ///                 ],
691    ///                 pos: 0,
692    ///                 tx,
693    ///                 done: false,
694    ///             }
695    ///         })?;
696    ///
697    ///         // Start playback
698    ///         capture_device.resume();
699    ///
700    ///         // Wait for recording to finish
701    ///         let recorded_samples = rx.recv()?;
702    ///         capture_device.pause();
703    ///
704    ///         // Handle recorded_samples
705    ///
706    ///         // Device stops playback when dropped.
707    ///         Ok(())
708    ///     }
709    /// }
710    /// ```
711    #[allow(single_use_lifetimes)]
712    #[inline]
713    pub fn open_capture<'a, CB, F, D>(
714        &self,
715        device: D,
716        desired_spec: &AudioSpecDesired,
717        get_callback: F,
718    ) -> PixResult<AudioDevice<CB>>
719    where
720        CB: AudioCallback,
721        F: FnOnce(AudioSpec) -> CB,
722        D: Into<Option<&'a str>>,
723    {
724        self.renderer
725            .open_capture(device, desired_spec, get_callback)
726    }
727}
728
729/// Trait representing audio support.
730pub(crate) trait AudioDriver {
731    /// Add audio samples to the current audio buffer queue.
732    fn enqueue_audio(&mut self, samples: &[f32]) -> PixResult<()>;
733
734    /// Clear audio samples from the current audio buffer queue.
735    fn clear_audio(&mut self);
736
737    /// Return the status of the current audio queue device.
738    fn audio_status(&self) -> AudioStatus;
739
740    /// Return the driver of current audio queue device.
741    fn audio_driver(&self) -> &'static str;
742
743    /// Return the sample rate of the current audio queue device.
744    fn audio_sample_rate(&self) -> i32;
745
746    /// Returns the queued buffer size (in bytes) of the current audio queue device.
747    fn audio_queued_size(&self) -> u32;
748
749    /// Returns the buffer size (in bytes) of the current audio queue device.
750    fn audio_size(&self) -> u32;
751
752    /// Resume playback of the current audio queue device.
753    fn resume_audio(&mut self);
754
755    /// Pause playback of the current audio queue device.
756    fn pause_audio(&mut self);
757
758    /// Opens and returns an audio callback device for playback.
759    #[allow(single_use_lifetimes)]
760    fn open_playback<'a, CB, F, D>(
761        &self,
762        device: D,
763        desired_spec: &AudioSpecDesired,
764        get_callback: F,
765    ) -> PixResult<AudioDevice<CB>>
766    where
767        CB: AudioCallback,
768        F: FnOnce(AudioSpec) -> CB,
769        D: Into<Option<&'a str>>;
770
771    /// Opens and returns an audio capture device for recording.
772    #[allow(single_use_lifetimes)]
773    fn open_capture<'a, CB, F, D>(
774        &self,
775        device: D,
776        desired_spec: &AudioSpecDesired,
777        get_callback: F,
778    ) -> PixResult<AudioDevice<CB>>
779    where
780        CB: AudioCallback,
781        F: FnOnce(AudioSpec) -> CB,
782        D: Into<Option<&'a str>>;
783}