#![allow(dead_code)]
pub mod audio;
mod context; pub mod data_source;
mod device; pub mod engine;
pub mod pcm_frames;
pub mod sound;
pub mod util;
#[doc(hidden)]
pub extern crate maudio_sys;
use maudio_sys::ffi as sys;
pub(crate) trait Binding: Sized {
type Raw;
fn from_ptr(raw: Self::Raw) -> Self;
fn to_raw(&self) -> Self::Raw;
}
pub(crate) trait AsRawRef {
type Raw;
fn as_raw(&self) -> &Self::Raw;
#[inline]
fn as_raw_ptr(&self) -> *const Self::Raw {
self.as_raw() as *const _
}
}
#[derive(Clone, Copy, PartialEq, Eq)]
struct MaError(pub sys::ma_result);
impl MaudioError {
fn check(res: i32) -> MaResult<()> {
if res == sys::ma_result_MA_SUCCESS {
Ok(())
} else {
Err(MaudioError {
native: None,
ma_result: MaError(res as sys::ma_result),
})
}
}
pub fn is_kind(&self) -> bool {
self.native.is_some()
}
pub fn kind(&self) -> Option<&ErrorKinds> {
self.native.as_ref()
}
pub fn ma_result(&self) -> sys::ma_result {
self.ma_result.0
}
fn from_ma_result(error: sys::ma_result) -> Self {
Self {
native: None,
ma_result: MaError(error),
}
}
fn new_ma_error(native: ErrorKinds) -> Self {
Self {
native: Some(native),
ma_result: MaError(sys::ma_result_MA_ERROR),
}
}
}
impl PartialEq<MaError> for MaudioError {
fn eq(&self, other: &MaError) -> bool {
self.ma_result.0.eq(&other.0)
}
}
impl std::fmt::Display for MaudioError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match &self.native {
None => {
write!(f, "{}", self.ma_result)
}
Some(kind) => {
write!(f, "{kind}.")?;
write!(f, " MA: ({})", self.ma_result)?;
Ok(())
}
}
}
}
impl std::fmt::Display for ErrorKinds {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
ErrorKinds::UnknownEnumValue { type_name, value } => {
write!(f, "unknown {type_name} value: {value}")
}
ErrorKinds::BufferSizeMismatch {
context,
expected,
actual,
} => {
if context.is_empty() {
write!(
f,
"buffer size mismatch (expected {expected}, got {actual})"
)
} else {
write!(
f,
"{context}: buffer size mismatch (expected {expected}, got {actual})"
)
}
}
ErrorKinds::IntegerOverflow { op, lhs, rhs } => {
write!(f, "integer overflow while computing {op} ({lhs} * {rhs})")
}
ErrorKinds::S24OverFlow => {
write!(f, "Overflow when converting S24 to miniaudio storage")
}
ErrorKinds::S24UnderFlow => {
write!(f, "Underflow when converting S24 to miniaudio storage")
}
ErrorKinds::InvalidPackedSampleSize {
bytes_per_sample,
actual_len,
} => {
write!(f, "SampleBuffer<S24Packed> with invalid length {actual_len} % {bytes_per_sample} != 0")
}
ErrorKinds::WriteExceedsCapacity { capacity, written } => {
write!(
f,
"Amount written exceds the capacity: {capacity}, written: {written}"
)
}
ErrorKinds::ReadExceedsAvailability { available, read } => {
write!(
f,
"Amount read exceds availability: {available}, read: {read}"
)
}
ErrorKinds::InvalidGraphState => write!(f, "invalid graph state"),
ErrorKinds::ChannelRecieveError => write!(f, "channel receive error"),
ErrorKinds::ChannelSendError => write!(f, "channel send error"),
ErrorKinds::InvalidFormat => write!(f, "invalid format"),
ErrorKinds::InvalidCString => write!(f, "invalid C string"),
}
}
}
impl std::fmt::Display for MaError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{} ({})", self.name(), self.0)
}
}
impl std::fmt::Debug for MaError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}, ({})", self.name(), self.0)
}
}
impl MaError {
pub fn name(self) -> &'static str {
match self.0 {
sys::ma_result_MA_ERROR => "MA_ERROR",
sys::ma_result_MA_INVALID_ARGS => "MA_INVALID_ARGS",
sys::ma_result_MA_INVALID_OPERATION => "MA_INVALID_OPERATION",
sys::ma_result_MA_OUT_OF_MEMORY => "MA_OUT_OF_MEMORY",
sys::ma_result_MA_OUT_OF_RANGE => "MA_OUT_OF_RANGE",
sys::ma_result_MA_ACCESS_DENIED => "MA_ACCESS_DENIED",
sys::ma_result_MA_DOES_NOT_EXIST => "MA_DOES_NOT_EXIST",
sys::ma_result_MA_ALREADY_EXISTS => "MA_ALREADY_EXISTS",
sys::ma_result_MA_TOO_MANY_OPEN_FILES => "MA_TOO_MANY_OPEN_FILES",
sys::ma_result_MA_INVALID_FILE => "MA_INVALID_FILE",
sys::ma_result_MA_TOO_BIG => "MA_TOO_BIG",
sys::ma_result_MA_PATH_TOO_LONG => "MA_PATH_TOO_LONG",
sys::ma_result_MA_NAME_TOO_LONG => "MA_NAME_TOO_LONG",
sys::ma_result_MA_NOT_DIRECTORY => "MA_NOT_DIRECTORY",
sys::ma_result_MA_IS_DIRECTORY => "MA_IS_DIRECTORY",
sys::ma_result_MA_DIRECTORY_NOT_EMPTY => "MA_DIRECTORY_NOT_EMPTY",
sys::ma_result_MA_AT_END => "MA_AT_END",
sys::ma_result_MA_NO_SPACE => "MA_NO_SPACE",
sys::ma_result_MA_BUSY => "MA_BUSY",
sys::ma_result_MA_IO_ERROR => "MA_IO_ERROR",
sys::ma_result_MA_INTERRUPT => "MA_INTERRUPT",
sys::ma_result_MA_UNAVAILABLE => "MA_UNAVAILABLE",
sys::ma_result_MA_ALREADY_IN_USE => "MA_ALREADY_IN_USE",
sys::ma_result_MA_BAD_ADDRESS => "MA_BAD_ADDRESS",
sys::ma_result_MA_BAD_SEEK => "MA_BAD_SEEK",
sys::ma_result_MA_BAD_PIPE => "MA_BAD_PIPE",
sys::ma_result_MA_DEADLOCK => "MA_DEADLOCK",
sys::ma_result_MA_TOO_MANY_LINKS => "MA_TOO_MANY_LINKS",
sys::ma_result_MA_NOT_IMPLEMENTED => "MA_NOT_IMPLEMENTED",
sys::ma_result_MA_NO_MESSAGE => "MA_NO_MESSAGE",
sys::ma_result_MA_BAD_MESSAGE => "MA_BAD_MESSAGE",
sys::ma_result_MA_NO_DATA_AVAILABLE => "MA_NO_DATA_AVAILABLE",
sys::ma_result_MA_INVALID_DATA => "MA_INVALID_DATA",
sys::ma_result_MA_TIMEOUT => "MA_TIMEOUT",
sys::ma_result_MA_NO_NETWORK => "MA_NO_NETWORK",
sys::ma_result_MA_NOT_UNIQUE => "MA_NOT_UNIQUE",
sys::ma_result_MA_NOT_SOCKET => "MA_NOT_SOCKET",
sys::ma_result_MA_NO_ADDRESS => "MA_NO_ADDRESS",
sys::ma_result_MA_BAD_PROTOCOL => "MA_BAD_PROTOCOL",
sys::ma_result_MA_PROTOCOL_UNAVAILABLE => "MA_PROTOCOL_UNAVAILABLE",
sys::ma_result_MA_PROTOCOL_NOT_SUPPORTED => "MA_PROTOCOL_NOT_SUPPORTED",
sys::ma_result_MA_PROTOCOL_FAMILY_NOT_SUPPORTED => "MA_PROTOCOL_FAMILY_NOT_SUPPORTED",
sys::ma_result_MA_ADDRESS_FAMILY_NOT_SUPPORTED => "MA_ADDRESS_FAMILY_NOT_SUPPORTED",
sys::ma_result_MA_SOCKET_NOT_SUPPORTED => "MA_SOCKET_NOT_SUPPORTED",
sys::ma_result_MA_CONNECTION_RESET => "MA_CONNECTION_RESET",
sys::ma_result_MA_ALREADY_CONNECTED => "MA_ALREADY_CONNECTED",
sys::ma_result_MA_NOT_CONNECTED => "MA_NOT_CONNECTED",
sys::ma_result_MA_CONNECTION_REFUSED => "MA_CONNECTION_REFUSED",
sys::ma_result_MA_NO_HOST => "MA_NO_HOST",
sys::ma_result_MA_IN_PROGRESS => "MA_IN_PROGRESS",
sys::ma_result_MA_CANCELLED => "MA_CANCELLED",
sys::ma_result_MA_MEMORY_ALREADY_MAPPED => "MemoryAlreadyMapped",
sys::ma_result_MA_CRC_MISMATCH => "MA_CRC_MISMATCH",
sys::ma_result_MA_FORMAT_NOT_SUPPORTED => "MA_FORMAT_NOT_SUPPORTED",
sys::ma_result_MA_DEVICE_TYPE_NOT_SUPPORTED => "MA_DEVICE_TYPE_NOT_SUPPORTED",
sys::ma_result_MA_SHARE_MODE_NOT_SUPPORTED => "MA_SHARE_MODE_NOT_SUPPORTED",
sys::ma_result_MA_NO_BACKEND => "MA_NO_BACKEND",
sys::ma_result_MA_NO_DEVICE => "MA_NO_DEVICE",
sys::ma_result_MA_API_NOT_FOUND => "MA_API_NOT_FOUND",
sys::ma_result_MA_INVALID_DEVICE_CONFIG => "MA_INVALID_DEVICE_CONFIG",
sys::ma_result_MA_LOOP => "MA_LOOP",
sys::ma_result_MA_BACKEND_NOT_ENABLED => "MA_BACKEND_NOT_ENABLED",
sys::ma_result_MA_DEVICE_NOT_INITIALIZED => "MA_DEVICE_NOT_INITIALIZED",
sys::ma_result_MA_DEVICE_ALREADY_INITIALIZED => "MA_DEVICE_ALREADY_INITIALIZED",
sys::ma_result_MA_DEVICE_NOT_STARTED => "MA_DEVICE_NOT_STARTED",
sys::ma_result_MA_DEVICE_NOT_STOPPED => "MA_DEVICE_NOT_STOPPED",
sys::ma_result_MA_FAILED_TO_INIT_BACKEND => "MA_FAILED_TO_INIT_BACKEND",
sys::ma_result_MA_FAILED_TO_OPEN_BACKEND_DEVICE => "MA_FAILED_TO_OPEN_BACKEND_DEVICE",
sys::ma_result_MA_FAILED_TO_START_BACKEND_DEVICE => "MA_FAILED_TO_START_BACKEND_DEVICE",
sys::ma_result_MA_FAILED_TO_STOP_BACKEND_DEVICE => "MA_FAILED_TO_STOP_BACKEND_DEVICE",
_ => "UNKNOWN_MA_ERROR",
}
}
}
impl ErrorKinds {
#[inline]
pub fn unknown_enum<T>(raw: i64) -> Self {
Self::UnknownEnumValue {
type_name: core::any::type_name::<T>(),
value: raw,
}
}
}
#[derive(Debug)]
#[non_exhaustive]
pub enum ErrorKinds {
UnknownEnumValue {
type_name: &'static str,
value: i64,
},
BufferSizeMismatch {
context: &'static str,
expected: usize,
actual: usize,
},
IntegerOverflow {
op: &'static str, lhs: u64,
rhs: u64,
},
InvalidPackedSampleSize {
bytes_per_sample: usize, actual_len: usize,
},
WriteExceedsCapacity {
capacity: usize,
written: usize,
},
ReadExceedsAvailability {
available: usize,
read: usize,
},
S24OverFlow,
S24UnderFlow,
InvalidGraphState,
ChannelRecieveError,
ChannelSendError,
InvalidFormat,
InvalidCString,
}
#[derive(Debug)]
pub struct MaudioError {
native: Option<ErrorKinds>,
ma_result: MaError,
}
pub type MaResult<T> = std::result::Result<T, MaudioError>;