use fmod_sys::*;
#[cfg(doc)]
use crate::{OutputType, Sound, System, SystemBuilder, studio};
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub enum Error {
BadCommand,
ChannelAlloc,
ChannelStolen,
DMA,
DspConnection,
DspDontProcess,
DspFormat,
DspInuse,
DspNotFound,
DspReserved,
DspSilence,
DspType,
FileBad,
FileCouldNotSeek,
FileDiskEjected,
FileEof,
FileEndOfData,
FileNotFound,
Format,
HeaderMismatch,
Http,
HttpAccess,
HttpProxyAuth,
HttpServerError,
HttpTimeout,
Initialization,
Initialized,
Internal,
InvalidFloat,
InvalidHandle,
InvalidParam,
InvalidPosition,
InvalidSpeaker,
InvalidSyncPoint,
InvalidThread,
InvalidVector,
MaxAudible,
Memory,
MemoryCantPoint,
Needs3D,
NeedsHardWare,
NetConnect,
NetSocketError,
NetUrl,
NetWouldBlock,
NotReady,
OutputAllocated,
OutputCreateBuffer,
OuputDriverCall,
OutputFormat,
OutputInit,
OutputNoDrivers,
Plugin,
PluginMissing,
PluginResource,
PluginVersion,
Record,
ReverbChannelGroup,
ReverbInstance,
Subsounds,
SubsoundAllocated,
SubsoundCantMove,
TagNotFound,
TooManyChannels,
Truncated,
Unimplemented,
Uninitialized,
Unsupported,
Version,
EventAlreadyLoaded,
EventLiveUpdateBusy,
EventLiveUpdateMismatch,
EventLiveUpdateTimeout,
EventNotFound,
StudioUninitialized,
StudioNotLoaded,
InvalidString,
AlreadyLocked,
NotLocked,
RecordDisconnected,
TooManySamples,
EnumFromPrivitive {
name: &'static str,
primitive: i64,
},
}
impl std::fmt::Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Error::EnumFromPrivitive { name, primitive } => f.write_fmt(format_args!(
"No discriminant in enum `{name}` matches the value `{primitive:?}. If you got this error from an FMOD function, please file an issue!"
)),
error => {
let fmod_result = (*error).into();
f.write_str(fmod_sys::error_code_to_str(fmod_result))
}
}
}
}
impl std::error::Error for Error {}
pub type Result<T> = std::result::Result<T, Error>;
impl From<FMOD_RESULT> for Error {
fn from(value: FMOD_RESULT) -> Self {
match value {
FMOD_RESULT::FMOD_ERR_BADCOMMAND => Error::BadCommand,
FMOD_RESULT::FMOD_ERR_CHANNEL_ALLOC => Error::ChannelAlloc,
FMOD_RESULT::FMOD_ERR_CHANNEL_STOLEN => Error::ChannelStolen,
FMOD_RESULT::FMOD_ERR_DMA => Error::DMA,
FMOD_RESULT::FMOD_ERR_DSP_CONNECTION => Error::DspConnection,
FMOD_RESULT::FMOD_ERR_DSP_DONTPROCESS => Error::DspDontProcess,
FMOD_RESULT::FMOD_ERR_DSP_FORMAT => Error::DspFormat,
FMOD_RESULT::FMOD_ERR_DSP_INUSE => Error::DspInuse,
FMOD_RESULT::FMOD_ERR_DSP_NOTFOUND => Error::DspNotFound,
FMOD_RESULT::FMOD_ERR_DSP_RESERVED => Error::DspReserved,
FMOD_RESULT::FMOD_ERR_DSP_SILENCE => Error::DspSilence,
FMOD_RESULT::FMOD_ERR_DSP_TYPE => Error::DspType,
FMOD_RESULT::FMOD_ERR_FILE_BAD => Error::FileBad,
FMOD_RESULT::FMOD_ERR_FILE_COULDNOTSEEK => Error::FileCouldNotSeek,
FMOD_RESULT::FMOD_ERR_FILE_DISKEJECTED => Error::FileDiskEjected,
FMOD_RESULT::FMOD_ERR_FILE_EOF => Error::FileEof,
FMOD_RESULT::FMOD_ERR_FILE_ENDOFDATA => Error::FileEndOfData,
FMOD_RESULT::FMOD_ERR_FILE_NOTFOUND => Error::FileNotFound,
FMOD_RESULT::FMOD_ERR_FORMAT => Error::Format,
FMOD_RESULT::FMOD_ERR_HEADER_MISMATCH => Error::HeaderMismatch,
FMOD_RESULT::FMOD_ERR_HTTP => Error::Http,
FMOD_RESULT::FMOD_ERR_HTTP_ACCESS => Error::HttpAccess,
FMOD_RESULT::FMOD_ERR_HTTP_PROXY_AUTH => Error::HttpProxyAuth,
FMOD_RESULT::FMOD_ERR_HTTP_SERVER_ERROR => Error::HttpServerError,
FMOD_RESULT::FMOD_ERR_HTTP_TIMEOUT => Error::HttpTimeout,
FMOD_RESULT::FMOD_ERR_INITIALIZATION => Error::Initialization,
FMOD_RESULT::FMOD_ERR_INITIALIZED => Error::Initialized,
FMOD_RESULT::FMOD_ERR_INTERNAL => Error::Internal,
FMOD_RESULT::FMOD_ERR_INVALID_FLOAT => Error::InvalidFloat,
FMOD_RESULT::FMOD_ERR_INVALID_HANDLE => Error::InvalidHandle,
FMOD_RESULT::FMOD_ERR_INVALID_PARAM => Error::InvalidParam,
FMOD_RESULT::FMOD_ERR_INVALID_POSITION => Error::InvalidPosition,
FMOD_RESULT::FMOD_ERR_INVALID_SPEAKER => Error::InvalidSpeaker,
FMOD_RESULT::FMOD_ERR_INVALID_SYNCPOINT => Error::InvalidSyncPoint,
FMOD_RESULT::FMOD_ERR_INVALID_THREAD => Error::InvalidThread,
FMOD_RESULT::FMOD_ERR_INVALID_VECTOR => Error::InvalidVector,
FMOD_RESULT::FMOD_ERR_MAXAUDIBLE => Error::MaxAudible,
FMOD_RESULT::FMOD_ERR_MEMORY => Error::Memory,
FMOD_RESULT::FMOD_ERR_MEMORY_CANTPOINT => Error::MemoryCantPoint,
FMOD_RESULT::FMOD_ERR_NEEDS3D => Error::Needs3D,
FMOD_RESULT::FMOD_ERR_NEEDSHARDWARE => Error::NeedsHardWare,
FMOD_RESULT::FMOD_ERR_NET_CONNECT => Error::NetConnect,
FMOD_RESULT::FMOD_ERR_NET_SOCKET_ERROR => Error::NetSocketError,
FMOD_RESULT::FMOD_ERR_NET_URL => Error::NetUrl,
FMOD_RESULT::FMOD_ERR_NET_WOULD_BLOCK => Error::NetWouldBlock,
FMOD_RESULT::FMOD_ERR_NOTREADY => Error::NotReady,
FMOD_RESULT::FMOD_ERR_OUTPUT_ALLOCATED => Error::OutputAllocated,
FMOD_RESULT::FMOD_ERR_OUTPUT_CREATEBUFFER => Error::OutputCreateBuffer,
FMOD_RESULT::FMOD_ERR_OUTPUT_DRIVERCALL => Error::OuputDriverCall,
FMOD_RESULT::FMOD_ERR_OUTPUT_FORMAT => Error::OutputFormat,
FMOD_RESULT::FMOD_ERR_OUTPUT_INIT => Error::OutputInit,
FMOD_RESULT::FMOD_ERR_OUTPUT_NODRIVERS => Error::OutputNoDrivers,
FMOD_RESULT::FMOD_ERR_PLUGIN => Error::Plugin,
FMOD_RESULT::FMOD_ERR_PLUGIN_MISSING => Error::PluginMissing,
FMOD_RESULT::FMOD_ERR_PLUGIN_RESOURCE => Error::PluginResource,
FMOD_RESULT::FMOD_ERR_PLUGIN_VERSION => Error::PluginVersion,
FMOD_RESULT::FMOD_ERR_RECORD => Error::Record,
FMOD_RESULT::FMOD_ERR_REVERB_CHANNELGROUP => Error::ReverbChannelGroup,
FMOD_RESULT::FMOD_ERR_REVERB_INSTANCE => Error::ReverbInstance,
FMOD_RESULT::FMOD_ERR_SUBSOUNDS => Error::Subsounds,
FMOD_RESULT::FMOD_ERR_SUBSOUND_ALLOCATED => Error::SubsoundAllocated,
FMOD_RESULT::FMOD_ERR_SUBSOUND_CANTMOVE => Error::SubsoundCantMove,
FMOD_RESULT::FMOD_ERR_TAGNOTFOUND => Error::TagNotFound,
FMOD_RESULT::FMOD_ERR_TOOMANYCHANNELS => Error::TooManyChannels,
FMOD_RESULT::FMOD_ERR_TRUNCATED => Error::Truncated,
FMOD_RESULT::FMOD_ERR_UNIMPLEMENTED => Error::Unimplemented,
FMOD_RESULT::FMOD_ERR_UNINITIALIZED => Error::Uninitialized,
FMOD_RESULT::FMOD_ERR_UNSUPPORTED => Error::Unsupported,
FMOD_RESULT::FMOD_ERR_VERSION => Error::Version,
FMOD_RESULT::FMOD_ERR_EVENT_ALREADY_LOADED => Error::EventAlreadyLoaded,
FMOD_RESULT::FMOD_ERR_EVENT_LIVEUPDATE_BUSY => Error::EventLiveUpdateBusy,
FMOD_RESULT::FMOD_ERR_EVENT_LIVEUPDATE_MISMATCH => Error::EventLiveUpdateMismatch,
FMOD_RESULT::FMOD_ERR_EVENT_LIVEUPDATE_TIMEOUT => Error::EventLiveUpdateTimeout,
FMOD_RESULT::FMOD_ERR_EVENT_NOTFOUND => Error::EventNotFound,
FMOD_RESULT::FMOD_ERR_STUDIO_UNINITIALIZED => Error::StudioUninitialized,
FMOD_RESULT::FMOD_ERR_STUDIO_NOT_LOADED => Error::StudioNotLoaded,
FMOD_RESULT::FMOD_ERR_INVALID_STRING => Error::InvalidString,
FMOD_RESULT::FMOD_ERR_ALREADY_LOCKED => Error::AlreadyLocked,
FMOD_RESULT::FMOD_ERR_NOT_LOCKED => Error::NotLocked,
FMOD_RESULT::FMOD_ERR_RECORD_DISCONNECTED => Error::RecordDisconnected,
FMOD_RESULT::FMOD_ERR_TOOMANYSAMPLES => Error::TooManySamples,
_ => panic!("invalid value"),
}
}
}
impl<T> From<num_enum::TryFromPrimitiveError<T>> for Error
where
T: num_enum::TryFromPrimitive,
T::Primitive: Into<i64>,
{
fn from(value: num_enum::TryFromPrimitiveError<T>) -> Self {
Self::EnumFromPrivitive {
name: T::NAME,
primitive: value.number.into(),
}
}
}
#[allow(clippy::match_same_arms)]
impl From<Error> for FMOD_RESULT {
fn from(val: Error) -> Self {
match val {
Error::BadCommand => FMOD_RESULT::FMOD_ERR_BADCOMMAND,
Error::ChannelAlloc => FMOD_RESULT::FMOD_ERR_CHANNEL_ALLOC,
Error::ChannelStolen => FMOD_RESULT::FMOD_ERR_CHANNEL_STOLEN,
Error::DMA => FMOD_RESULT::FMOD_ERR_DMA,
Error::DspConnection => FMOD_RESULT::FMOD_ERR_DSP_CONNECTION,
Error::DspDontProcess => FMOD_RESULT::FMOD_ERR_DSP_DONTPROCESS,
Error::DspFormat => FMOD_RESULT::FMOD_ERR_DSP_FORMAT,
Error::DspInuse => FMOD_RESULT::FMOD_ERR_DSP_INUSE,
Error::DspNotFound => FMOD_RESULT::FMOD_ERR_DSP_NOTFOUND,
Error::DspReserved => FMOD_RESULT::FMOD_ERR_DSP_RESERVED,
Error::DspSilence => FMOD_RESULT::FMOD_ERR_DSP_SILENCE,
Error::DspType => FMOD_RESULT::FMOD_ERR_DSP_TYPE,
Error::FileBad => FMOD_RESULT::FMOD_ERR_FILE_BAD,
Error::FileCouldNotSeek => FMOD_RESULT::FMOD_ERR_FILE_COULDNOTSEEK,
Error::FileDiskEjected => FMOD_RESULT::FMOD_ERR_FILE_DISKEJECTED,
Error::FileEof => FMOD_RESULT::FMOD_ERR_FILE_EOF,
Error::FileEndOfData => FMOD_RESULT::FMOD_ERR_FILE_ENDOFDATA,
Error::FileNotFound => FMOD_RESULT::FMOD_ERR_FILE_NOTFOUND,
Error::Format => FMOD_RESULT::FMOD_ERR_FORMAT,
Error::HeaderMismatch => FMOD_RESULT::FMOD_ERR_HEADER_MISMATCH,
Error::Http => FMOD_RESULT::FMOD_ERR_HTTP,
Error::HttpAccess => FMOD_RESULT::FMOD_ERR_HTTP_ACCESS,
Error::HttpProxyAuth => FMOD_RESULT::FMOD_ERR_HTTP_PROXY_AUTH,
Error::HttpServerError => FMOD_RESULT::FMOD_ERR_HTTP_SERVER_ERROR,
Error::HttpTimeout => FMOD_RESULT::FMOD_ERR_HTTP_TIMEOUT,
Error::Initialization => FMOD_RESULT::FMOD_ERR_INITIALIZATION,
Error::Initialized => FMOD_RESULT::FMOD_ERR_INITIALIZED,
Error::Internal => FMOD_RESULT::FMOD_ERR_INTERNAL,
Error::InvalidFloat => FMOD_RESULT::FMOD_ERR_INVALID_FLOAT,
Error::InvalidHandle => FMOD_RESULT::FMOD_ERR_INVALID_HANDLE,
Error::InvalidParam => FMOD_RESULT::FMOD_ERR_INVALID_PARAM,
Error::InvalidPosition => FMOD_RESULT::FMOD_ERR_INVALID_POSITION,
Error::InvalidSpeaker => FMOD_RESULT::FMOD_ERR_INVALID_SPEAKER,
Error::InvalidSyncPoint => FMOD_RESULT::FMOD_ERR_INVALID_SYNCPOINT,
Error::InvalidThread => FMOD_RESULT::FMOD_ERR_INVALID_THREAD,
Error::InvalidVector => FMOD_RESULT::FMOD_ERR_INVALID_VECTOR,
Error::MaxAudible => FMOD_RESULT::FMOD_ERR_MAXAUDIBLE,
Error::Memory => FMOD_RESULT::FMOD_ERR_MEMORY,
Error::MemoryCantPoint => FMOD_RESULT::FMOD_ERR_MEMORY_CANTPOINT,
Error::Needs3D => FMOD_RESULT::FMOD_ERR_NEEDS3D,
Error::NeedsHardWare => FMOD_RESULT::FMOD_ERR_NEEDSHARDWARE,
Error::NetConnect => FMOD_RESULT::FMOD_ERR_NET_CONNECT,
Error::NetSocketError => FMOD_RESULT::FMOD_ERR_NET_SOCKET_ERROR,
Error::NetUrl => FMOD_RESULT::FMOD_ERR_NET_URL,
Error::NetWouldBlock => FMOD_RESULT::FMOD_ERR_NET_WOULD_BLOCK,
Error::NotReady => FMOD_RESULT::FMOD_ERR_NOTREADY,
Error::OutputAllocated => FMOD_RESULT::FMOD_ERR_OUTPUT_ALLOCATED,
Error::OutputCreateBuffer => FMOD_RESULT::FMOD_ERR_OUTPUT_CREATEBUFFER,
Error::OuputDriverCall => FMOD_RESULT::FMOD_ERR_OUTPUT_DRIVERCALL,
Error::OutputFormat => FMOD_RESULT::FMOD_ERR_OUTPUT_FORMAT,
Error::OutputInit => FMOD_RESULT::FMOD_ERR_OUTPUT_INIT,
Error::OutputNoDrivers => FMOD_RESULT::FMOD_ERR_OUTPUT_NODRIVERS,
Error::Plugin => FMOD_RESULT::FMOD_ERR_PLUGIN,
Error::PluginMissing => FMOD_RESULT::FMOD_ERR_PLUGIN_MISSING,
Error::PluginResource => FMOD_RESULT::FMOD_ERR_PLUGIN_RESOURCE,
Error::PluginVersion => FMOD_RESULT::FMOD_ERR_PLUGIN_VERSION,
Error::Record => FMOD_RESULT::FMOD_ERR_RECORD,
Error::ReverbChannelGroup => FMOD_RESULT::FMOD_ERR_REVERB_CHANNELGROUP,
Error::ReverbInstance => FMOD_RESULT::FMOD_ERR_REVERB_INSTANCE,
Error::Subsounds => FMOD_RESULT::FMOD_ERR_SUBSOUNDS,
Error::SubsoundAllocated => FMOD_RESULT::FMOD_ERR_SUBSOUND_ALLOCATED,
Error::SubsoundCantMove => FMOD_RESULT::FMOD_ERR_SUBSOUND_CANTMOVE,
Error::TagNotFound => FMOD_RESULT::FMOD_ERR_TAGNOTFOUND,
Error::TooManyChannels => FMOD_RESULT::FMOD_ERR_TOOMANYCHANNELS,
Error::Truncated => FMOD_RESULT::FMOD_ERR_TRUNCATED,
Error::Unimplemented => FMOD_RESULT::FMOD_ERR_UNIMPLEMENTED,
Error::Uninitialized => FMOD_RESULT::FMOD_ERR_UNINITIALIZED,
Error::Unsupported => FMOD_RESULT::FMOD_ERR_UNSUPPORTED,
Error::Version => FMOD_RESULT::FMOD_ERR_VERSION,
Error::EventAlreadyLoaded => FMOD_RESULT::FMOD_ERR_EVENT_ALREADY_LOADED,
Error::EventLiveUpdateBusy => FMOD_RESULT::FMOD_ERR_EVENT_LIVEUPDATE_BUSY,
Error::EventLiveUpdateMismatch => FMOD_RESULT::FMOD_ERR_EVENT_LIVEUPDATE_MISMATCH,
Error::EventLiveUpdateTimeout => FMOD_RESULT::FMOD_ERR_EVENT_LIVEUPDATE_TIMEOUT,
Error::EventNotFound => FMOD_RESULT::FMOD_ERR_EVENT_NOTFOUND,
Error::StudioUninitialized => FMOD_RESULT::FMOD_ERR_STUDIO_UNINITIALIZED,
Error::StudioNotLoaded => FMOD_RESULT::FMOD_ERR_STUDIO_NOT_LOADED,
Error::InvalidString => FMOD_RESULT::FMOD_ERR_INVALID_STRING,
Error::AlreadyLocked => FMOD_RESULT::FMOD_ERR_ALREADY_LOCKED,
Error::NotLocked => FMOD_RESULT::FMOD_ERR_NOT_LOCKED,
Error::RecordDisconnected => FMOD_RESULT::FMOD_ERR_RECORD_DISCONNECTED,
Error::TooManySamples => FMOD_RESULT::FMOD_ERR_TOOMANYSAMPLES,
Error::EnumFromPrivitive { .. } => FMOD_RESULT::FMOD_ERR_INVALID_PARAM,
}
}
}
pub(crate) trait FmodResultExt {
fn to_result(self) -> Result<()>;
fn to_error(self) -> Option<Error>;
fn from_result<T>(result: Result<T>) -> Self;
}
impl FmodResultExt for FMOD_RESULT {
fn to_result(self) -> Result<()> {
if matches!(self, FMOD_RESULT::FMOD_OK) {
Ok(())
} else {
Err(self.into())
}
}
fn to_error(self) -> Option<Error> {
self.to_result().err()
}
fn from_result<T>(result: Result<T>) -> Self {
match result {
Ok(_) => FMOD_RESULT::FMOD_OK,
Err(e) => e.into(),
}
}
}