use crate::prelude::*;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
#[cfg(not(target_arch = "wasm32"))]
pub use crate::renderer::sdl::{AudioDevice, AudioFormatNum};
#[cfg(target_arch = "wasm32")]
pub use crate::renderer::wasm::{AudioDevice, AudioFormatNum};
pub trait AudioCallback: Send
where
Self::Channel: AudioFormatNum + 'static,
{
type Channel;
fn callback(&mut self, buffer: &mut [Self::Channel]);
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[must_use]
pub enum AudioFormat {
U8,
S8,
U16LSB,
U16MSB,
S16LSB,
S16MSB,
S32LSB,
S32MSB,
F32LSB,
F32MSB,
}
#[cfg(target_endian = "little")]
impl AudioFormat {
#[inline]
pub const fn u16_sys() -> AudioFormat {
AudioFormat::U16LSB
}
#[inline]
pub const fn s16_sys() -> AudioFormat {
AudioFormat::S16LSB
}
#[inline]
pub const fn s32_sys() -> AudioFormat {
AudioFormat::S32LSB
}
#[inline]
pub const fn f32_sys() -> AudioFormat {
AudioFormat::F32LSB
}
}
#[cfg(target_endian = "big")]
impl AudioFormat {
#[inline]
pub const fn u16_sys() -> AudioFormat {
AudioFormat::U16MSB
}
#[inline]
pub const fn s16_sys() -> AudioFormat {
AudioFormat::S16MSB
}
#[inline]
pub const fn s32_sys() -> AudioFormat {
AudioFormat::S32MSB
}
#[inline]
pub const fn f32_sys() -> AudioFormat {
AudioFormat::F32MSB
}
}
impl Default for AudioFormat {
fn default() -> Self {
Self::f32_sys()
}
}
#[derive(Default, Debug, Copy, Clone, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[must_use]
pub enum AudioStatus {
#[default]
Stopped,
Playing,
Paused,
}
#[derive(Default, Debug, Copy, Clone, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[must_use]
pub struct AudioSpecDesired {
pub freq: Option<i32>,
pub channels: Option<u8>,
pub samples: Option<u16>,
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[must_use]
pub struct AudioSpec {
pub freq: i32,
pub format: AudioFormat,
pub channels: u8,
pub samples: u16,
pub size: u32,
}
impl Default for AudioSpec {
fn default() -> Self {
Self {
freq: 44_100,
format: AudioFormat::default(),
channels: 1,
samples: 512,
size: 2048,
}
}
}
pub trait AudioDeviceDriver {
fn status(&self) -> AudioStatus;
fn driver(&self) -> &'static str;
fn spec(&self) -> AudioSpec;
fn resume(&self);
fn pause(&self);
}
impl PixState {
#[inline]
pub fn enqueue_audio<S: AsRef<[f32]>>(&mut self, samples: S) -> PixResult<()> {
self.renderer.enqueue_audio(samples.as_ref())
}
#[inline]
pub fn clear_audio(&mut self) {
self.renderer.clear_audio();
}
#[inline]
pub fn audio_status(&self) -> AudioStatus {
self.renderer.audio_status()
}
#[inline]
#[must_use]
pub fn audio_driver(&self) -> &'static str {
self.renderer.audio_driver()
}
#[inline]
#[must_use]
pub fn audio_sample_rate(&self) -> i32 {
self.renderer.audio_sample_rate()
}
#[inline]
#[must_use]
pub fn audio_queued_size(&self) -> u32 {
self.renderer.audio_queued_size()
}
#[inline]
#[must_use]
pub fn audio_size(&self) -> u32 {
self.renderer.audio_size()
}
#[inline]
pub fn resume_audio(&mut self) {
self.renderer.resume_audio();
}
#[inline]
pub fn pause_audio(&mut self) {
self.renderer.pause_audio();
}
#[allow(single_use_lifetimes)]
#[inline]
pub fn open_playback<'a, CB, F, D>(
&self,
device: D,
desired_spec: &AudioSpecDesired,
get_callback: F,
) -> PixResult<AudioDevice<CB>>
where
CB: AudioCallback,
F: FnOnce(AudioSpec) -> CB,
D: Into<Option<&'a str>>,
{
self.renderer
.open_playback(device, desired_spec, get_callback)
}
#[allow(single_use_lifetimes)]
#[inline]
pub fn open_capture<'a, CB, F, D>(
&self,
device: D,
desired_spec: &AudioSpecDesired,
get_callback: F,
) -> PixResult<AudioDevice<CB>>
where
CB: AudioCallback,
F: FnOnce(AudioSpec) -> CB,
D: Into<Option<&'a str>>,
{
self.renderer
.open_capture(device, desired_spec, get_callback)
}
}
pub(crate) trait AudioDriver {
fn enqueue_audio(&mut self, samples: &[f32]) -> PixResult<()>;
fn clear_audio(&mut self);
fn audio_status(&self) -> AudioStatus;
fn audio_driver(&self) -> &'static str;
fn audio_sample_rate(&self) -> i32;
fn audio_queued_size(&self) -> u32;
fn audio_size(&self) -> u32;
fn resume_audio(&mut self);
fn pause_audio(&mut self);
#[allow(single_use_lifetimes)]
fn open_playback<'a, CB, F, D>(
&self,
device: D,
desired_spec: &AudioSpecDesired,
get_callback: F,
) -> PixResult<AudioDevice<CB>>
where
CB: AudioCallback,
F: FnOnce(AudioSpec) -> CB,
D: Into<Option<&'a str>>;
#[allow(single_use_lifetimes)]
fn open_capture<'a, CB, F, D>(
&self,
device: D,
desired_spec: &AudioSpecDesired,
get_callback: F,
) -> PixResult<AudioDevice<CB>>
where
CB: AudioCallback,
F: FnOnce(AudioSpec) -> CB,
D: Into<Option<&'a str>>;
}