1use fmod_sys::*;
2
3#[cfg(doc)]
4use crate::{OutputType, Sound, System, SystemBuilder, studio};
5
6#[derive(Clone, Copy, PartialEq, Eq, Debug)]
8pub enum Error {
9 BadCommand,
11 ChannelAlloc,
13 ChannelStolen,
15 DMA,
17 DspConnection,
19 DspDontProcess,
21 DspFormat,
23 DspInuse,
25 DspNotFound,
27 DspReserved,
29 DspSilence,
31 DspType,
33 FileBad,
35 FileCouldNotSeek,
37 FileDiskEjected,
39 FileEof,
41 FileEndOfData,
43 FileNotFound,
45 Format,
47 HeaderMismatch,
49 Http,
51 HttpAccess,
53 HttpProxyAuth,
55 HttpServerError,
57 HttpTimeout,
59 Initialization,
61 Initialized,
63 Internal,
65 InvalidFloat,
67 InvalidHandle,
69 InvalidParam,
71 InvalidPosition,
73 InvalidSpeaker,
75 InvalidSyncPoint,
77 InvalidThread,
79 InvalidVector,
81 MaxAudible,
83 Memory,
85 MemoryCantPoint,
87 Needs3D,
89 NeedsHardWare,
91 NetConnect,
93 NetSocketError,
95 NetUrl,
97 NetWouldBlock,
99 NotReady,
101 OutputAllocated,
103 OutputCreateBuffer,
105 OuputDriverCall,
107 OutputFormat,
109 OutputInit,
111 OutputNoDrivers,
113 Plugin,
115 PluginMissing,
117 PluginResource,
119 PluginVersion,
121 Record,
123 ReverbChannelGroup,
125 ReverbInstance,
127 Subsounds,
129 SubsoundAllocated,
131 SubsoundCantMove,
133 TagNotFound,
135 TooManyChannels,
138 Truncated,
140 Unimplemented,
142 Uninitialized,
144 Unsupported,
146 Version,
148 EventAlreadyLoaded,
150 EventLiveUpdateBusy,
152 EventLiveUpdateMismatch,
154 EventLiveUpdateTimeout,
156 EventNotFound,
158 StudioUninitialized,
160 StudioNotLoaded,
162 InvalidString,
164 AlreadyLocked,
166 NotLocked,
168 RecordDisconnected,
170 TooManySamples,
172
173 EnumFromPrivitive {
178 name: &'static str,
180 primitive: i64,
182 },
183}
184
185impl std::fmt::Display for Error {
186 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
187 match self {
188 Error::EnumFromPrivitive { name, primitive } => f.write_fmt(format_args!(
189 "No discriminant in enum `{name}` matches the value `{primitive:?}. If you got this error from an FMOD function, please file an issue!"
190 )),
191 error => {
192 let fmod_result = (*error).into();
193 f.write_str(fmod_sys::error_code_to_str(fmod_result))
194 }
195 }
196 }
197}
198
199impl std::error::Error for Error {}
200
201pub type Result<T> = std::result::Result<T, Error>;
203
204impl From<FMOD_RESULT> for Error {
205 fn from(value: FMOD_RESULT) -> Self {
206 match value {
207 FMOD_RESULT::FMOD_ERR_BADCOMMAND => Error::BadCommand,
208 FMOD_RESULT::FMOD_ERR_CHANNEL_ALLOC => Error::ChannelAlloc,
209 FMOD_RESULT::FMOD_ERR_CHANNEL_STOLEN => Error::ChannelStolen,
210 FMOD_RESULT::FMOD_ERR_DMA => Error::DMA,
211 FMOD_RESULT::FMOD_ERR_DSP_CONNECTION => Error::DspConnection,
212 FMOD_RESULT::FMOD_ERR_DSP_DONTPROCESS => Error::DspDontProcess,
213 FMOD_RESULT::FMOD_ERR_DSP_FORMAT => Error::DspFormat,
214 FMOD_RESULT::FMOD_ERR_DSP_INUSE => Error::DspInuse,
215 FMOD_RESULT::FMOD_ERR_DSP_NOTFOUND => Error::DspNotFound,
216 FMOD_RESULT::FMOD_ERR_DSP_RESERVED => Error::DspReserved,
217 FMOD_RESULT::FMOD_ERR_DSP_SILENCE => Error::DspSilence,
218 FMOD_RESULT::FMOD_ERR_DSP_TYPE => Error::DspType,
219 FMOD_RESULT::FMOD_ERR_FILE_BAD => Error::FileBad,
220 FMOD_RESULT::FMOD_ERR_FILE_COULDNOTSEEK => Error::FileCouldNotSeek,
221 FMOD_RESULT::FMOD_ERR_FILE_DISKEJECTED => Error::FileDiskEjected,
222 FMOD_RESULT::FMOD_ERR_FILE_EOF => Error::FileEof,
223 FMOD_RESULT::FMOD_ERR_FILE_ENDOFDATA => Error::FileEndOfData,
224 FMOD_RESULT::FMOD_ERR_FILE_NOTFOUND => Error::FileNotFound,
225 FMOD_RESULT::FMOD_ERR_FORMAT => Error::Format,
226 FMOD_RESULT::FMOD_ERR_HEADER_MISMATCH => Error::HeaderMismatch,
227 FMOD_RESULT::FMOD_ERR_HTTP => Error::Http,
228 FMOD_RESULT::FMOD_ERR_HTTP_ACCESS => Error::HttpAccess,
229 FMOD_RESULT::FMOD_ERR_HTTP_PROXY_AUTH => Error::HttpProxyAuth,
230 FMOD_RESULT::FMOD_ERR_HTTP_SERVER_ERROR => Error::HttpServerError,
231 FMOD_RESULT::FMOD_ERR_HTTP_TIMEOUT => Error::HttpTimeout,
232 FMOD_RESULT::FMOD_ERR_INITIALIZATION => Error::Initialization,
233 FMOD_RESULT::FMOD_ERR_INITIALIZED => Error::Initialized,
234 FMOD_RESULT::FMOD_ERR_INTERNAL => Error::Internal,
235 FMOD_RESULT::FMOD_ERR_INVALID_FLOAT => Error::InvalidFloat,
236 FMOD_RESULT::FMOD_ERR_INVALID_HANDLE => Error::InvalidHandle,
237 FMOD_RESULT::FMOD_ERR_INVALID_PARAM => Error::InvalidParam,
238 FMOD_RESULT::FMOD_ERR_INVALID_POSITION => Error::InvalidPosition,
239 FMOD_RESULT::FMOD_ERR_INVALID_SPEAKER => Error::InvalidSpeaker,
240 FMOD_RESULT::FMOD_ERR_INVALID_SYNCPOINT => Error::InvalidSyncPoint,
241 FMOD_RESULT::FMOD_ERR_INVALID_THREAD => Error::InvalidThread,
242 FMOD_RESULT::FMOD_ERR_INVALID_VECTOR => Error::InvalidVector,
243 FMOD_RESULT::FMOD_ERR_MAXAUDIBLE => Error::MaxAudible,
244 FMOD_RESULT::FMOD_ERR_MEMORY => Error::Memory,
245 FMOD_RESULT::FMOD_ERR_MEMORY_CANTPOINT => Error::MemoryCantPoint,
246 FMOD_RESULT::FMOD_ERR_NEEDS3D => Error::Needs3D,
247 FMOD_RESULT::FMOD_ERR_NEEDSHARDWARE => Error::NeedsHardWare,
248 FMOD_RESULT::FMOD_ERR_NET_CONNECT => Error::NetConnect,
249 FMOD_RESULT::FMOD_ERR_NET_SOCKET_ERROR => Error::NetSocketError,
250 FMOD_RESULT::FMOD_ERR_NET_URL => Error::NetUrl,
251 FMOD_RESULT::FMOD_ERR_NET_WOULD_BLOCK => Error::NetWouldBlock,
252 FMOD_RESULT::FMOD_ERR_NOTREADY => Error::NotReady,
253 FMOD_RESULT::FMOD_ERR_OUTPUT_ALLOCATED => Error::OutputAllocated,
254 FMOD_RESULT::FMOD_ERR_OUTPUT_CREATEBUFFER => Error::OutputCreateBuffer,
255 FMOD_RESULT::FMOD_ERR_OUTPUT_DRIVERCALL => Error::OuputDriverCall,
256 FMOD_RESULT::FMOD_ERR_OUTPUT_FORMAT => Error::OutputFormat,
257 FMOD_RESULT::FMOD_ERR_OUTPUT_INIT => Error::OutputInit,
258 FMOD_RESULT::FMOD_ERR_OUTPUT_NODRIVERS => Error::OutputNoDrivers,
259 FMOD_RESULT::FMOD_ERR_PLUGIN => Error::Plugin,
260 FMOD_RESULT::FMOD_ERR_PLUGIN_MISSING => Error::PluginMissing,
261 FMOD_RESULT::FMOD_ERR_PLUGIN_RESOURCE => Error::PluginResource,
262 FMOD_RESULT::FMOD_ERR_PLUGIN_VERSION => Error::PluginVersion,
263 FMOD_RESULT::FMOD_ERR_RECORD => Error::Record,
264 FMOD_RESULT::FMOD_ERR_REVERB_CHANNELGROUP => Error::ReverbChannelGroup,
265 FMOD_RESULT::FMOD_ERR_REVERB_INSTANCE => Error::ReverbInstance,
266 FMOD_RESULT::FMOD_ERR_SUBSOUNDS => Error::Subsounds,
267 FMOD_RESULT::FMOD_ERR_SUBSOUND_ALLOCATED => Error::SubsoundAllocated,
268 FMOD_RESULT::FMOD_ERR_SUBSOUND_CANTMOVE => Error::SubsoundCantMove,
269 FMOD_RESULT::FMOD_ERR_TAGNOTFOUND => Error::TagNotFound,
270 FMOD_RESULT::FMOD_ERR_TOOMANYCHANNELS => Error::TooManyChannels,
271 FMOD_RESULT::FMOD_ERR_TRUNCATED => Error::Truncated,
272 FMOD_RESULT::FMOD_ERR_UNIMPLEMENTED => Error::Unimplemented,
273 FMOD_RESULT::FMOD_ERR_UNINITIALIZED => Error::Uninitialized,
274 FMOD_RESULT::FMOD_ERR_UNSUPPORTED => Error::Unsupported,
275 FMOD_RESULT::FMOD_ERR_VERSION => Error::Version,
276 FMOD_RESULT::FMOD_ERR_EVENT_ALREADY_LOADED => Error::EventAlreadyLoaded,
277 FMOD_RESULT::FMOD_ERR_EVENT_LIVEUPDATE_BUSY => Error::EventLiveUpdateBusy,
278 FMOD_RESULT::FMOD_ERR_EVENT_LIVEUPDATE_MISMATCH => Error::EventLiveUpdateMismatch,
279 FMOD_RESULT::FMOD_ERR_EVENT_LIVEUPDATE_TIMEOUT => Error::EventLiveUpdateTimeout,
280 FMOD_RESULT::FMOD_ERR_EVENT_NOTFOUND => Error::EventNotFound,
281 FMOD_RESULT::FMOD_ERR_STUDIO_UNINITIALIZED => Error::StudioUninitialized,
282 FMOD_RESULT::FMOD_ERR_STUDIO_NOT_LOADED => Error::StudioNotLoaded,
283 FMOD_RESULT::FMOD_ERR_INVALID_STRING => Error::InvalidString,
284 FMOD_RESULT::FMOD_ERR_ALREADY_LOCKED => Error::AlreadyLocked,
285 FMOD_RESULT::FMOD_ERR_NOT_LOCKED => Error::NotLocked,
286 FMOD_RESULT::FMOD_ERR_RECORD_DISCONNECTED => Error::RecordDisconnected,
287 FMOD_RESULT::FMOD_ERR_TOOMANYSAMPLES => Error::TooManySamples,
288 _ => panic!("invalid value"),
289 }
290 }
291}
292
293impl<T> From<num_enum::TryFromPrimitiveError<T>> for Error
294where
295 T: num_enum::TryFromPrimitive,
296 T::Primitive: Into<i64>,
297{
298 fn from(value: num_enum::TryFromPrimitiveError<T>) -> Self {
299 Self::EnumFromPrivitive {
300 name: T::NAME,
301 primitive: value.number.into(),
302 }
303 }
304}
305
306#[allow(clippy::match_same_arms)]
307impl From<Error> for FMOD_RESULT {
308 fn from(val: Error) -> Self {
309 match val {
310 Error::BadCommand => FMOD_RESULT::FMOD_ERR_BADCOMMAND,
311 Error::ChannelAlloc => FMOD_RESULT::FMOD_ERR_CHANNEL_ALLOC,
312 Error::ChannelStolen => FMOD_RESULT::FMOD_ERR_CHANNEL_STOLEN,
313 Error::DMA => FMOD_RESULT::FMOD_ERR_DMA,
314 Error::DspConnection => FMOD_RESULT::FMOD_ERR_DSP_CONNECTION,
315 Error::DspDontProcess => FMOD_RESULT::FMOD_ERR_DSP_DONTPROCESS,
316 Error::DspFormat => FMOD_RESULT::FMOD_ERR_DSP_FORMAT,
317 Error::DspInuse => FMOD_RESULT::FMOD_ERR_DSP_INUSE,
318 Error::DspNotFound => FMOD_RESULT::FMOD_ERR_DSP_NOTFOUND,
319 Error::DspReserved => FMOD_RESULT::FMOD_ERR_DSP_RESERVED,
320 Error::DspSilence => FMOD_RESULT::FMOD_ERR_DSP_SILENCE,
321 Error::DspType => FMOD_RESULT::FMOD_ERR_DSP_TYPE,
322 Error::FileBad => FMOD_RESULT::FMOD_ERR_FILE_BAD,
323 Error::FileCouldNotSeek => FMOD_RESULT::FMOD_ERR_FILE_COULDNOTSEEK,
324 Error::FileDiskEjected => FMOD_RESULT::FMOD_ERR_FILE_DISKEJECTED,
325 Error::FileEof => FMOD_RESULT::FMOD_ERR_FILE_EOF,
326 Error::FileEndOfData => FMOD_RESULT::FMOD_ERR_FILE_ENDOFDATA,
327 Error::FileNotFound => FMOD_RESULT::FMOD_ERR_FILE_NOTFOUND,
328 Error::Format => FMOD_RESULT::FMOD_ERR_FORMAT,
329 Error::HeaderMismatch => FMOD_RESULT::FMOD_ERR_HEADER_MISMATCH,
330 Error::Http => FMOD_RESULT::FMOD_ERR_HTTP,
331 Error::HttpAccess => FMOD_RESULT::FMOD_ERR_HTTP_ACCESS,
332 Error::HttpProxyAuth => FMOD_RESULT::FMOD_ERR_HTTP_PROXY_AUTH,
333 Error::HttpServerError => FMOD_RESULT::FMOD_ERR_HTTP_SERVER_ERROR,
334 Error::HttpTimeout => FMOD_RESULT::FMOD_ERR_HTTP_TIMEOUT,
335 Error::Initialization => FMOD_RESULT::FMOD_ERR_INITIALIZATION,
336 Error::Initialized => FMOD_RESULT::FMOD_ERR_INITIALIZED,
337 Error::Internal => FMOD_RESULT::FMOD_ERR_INTERNAL,
338 Error::InvalidFloat => FMOD_RESULT::FMOD_ERR_INVALID_FLOAT,
339 Error::InvalidHandle => FMOD_RESULT::FMOD_ERR_INVALID_HANDLE,
340 Error::InvalidParam => FMOD_RESULT::FMOD_ERR_INVALID_PARAM,
341 Error::InvalidPosition => FMOD_RESULT::FMOD_ERR_INVALID_POSITION,
342 Error::InvalidSpeaker => FMOD_RESULT::FMOD_ERR_INVALID_SPEAKER,
343 Error::InvalidSyncPoint => FMOD_RESULT::FMOD_ERR_INVALID_SYNCPOINT,
344 Error::InvalidThread => FMOD_RESULT::FMOD_ERR_INVALID_THREAD,
345 Error::InvalidVector => FMOD_RESULT::FMOD_ERR_INVALID_VECTOR,
346 Error::MaxAudible => FMOD_RESULT::FMOD_ERR_MAXAUDIBLE,
347 Error::Memory => FMOD_RESULT::FMOD_ERR_MEMORY,
348 Error::MemoryCantPoint => FMOD_RESULT::FMOD_ERR_MEMORY_CANTPOINT,
349 Error::Needs3D => FMOD_RESULT::FMOD_ERR_NEEDS3D,
350 Error::NeedsHardWare => FMOD_RESULT::FMOD_ERR_NEEDSHARDWARE,
351 Error::NetConnect => FMOD_RESULT::FMOD_ERR_NET_CONNECT,
352 Error::NetSocketError => FMOD_RESULT::FMOD_ERR_NET_SOCKET_ERROR,
353 Error::NetUrl => FMOD_RESULT::FMOD_ERR_NET_URL,
354 Error::NetWouldBlock => FMOD_RESULT::FMOD_ERR_NET_WOULD_BLOCK,
355 Error::NotReady => FMOD_RESULT::FMOD_ERR_NOTREADY,
356 Error::OutputAllocated => FMOD_RESULT::FMOD_ERR_OUTPUT_ALLOCATED,
357 Error::OutputCreateBuffer => FMOD_RESULT::FMOD_ERR_OUTPUT_CREATEBUFFER,
358 Error::OuputDriverCall => FMOD_RESULT::FMOD_ERR_OUTPUT_DRIVERCALL,
359 Error::OutputFormat => FMOD_RESULT::FMOD_ERR_OUTPUT_FORMAT,
360 Error::OutputInit => FMOD_RESULT::FMOD_ERR_OUTPUT_INIT,
361 Error::OutputNoDrivers => FMOD_RESULT::FMOD_ERR_OUTPUT_NODRIVERS,
362 Error::Plugin => FMOD_RESULT::FMOD_ERR_PLUGIN,
363 Error::PluginMissing => FMOD_RESULT::FMOD_ERR_PLUGIN_MISSING,
364 Error::PluginResource => FMOD_RESULT::FMOD_ERR_PLUGIN_RESOURCE,
365 Error::PluginVersion => FMOD_RESULT::FMOD_ERR_PLUGIN_VERSION,
366 Error::Record => FMOD_RESULT::FMOD_ERR_RECORD,
367 Error::ReverbChannelGroup => FMOD_RESULT::FMOD_ERR_REVERB_CHANNELGROUP,
368 Error::ReverbInstance => FMOD_RESULT::FMOD_ERR_REVERB_INSTANCE,
369 Error::Subsounds => FMOD_RESULT::FMOD_ERR_SUBSOUNDS,
370 Error::SubsoundAllocated => FMOD_RESULT::FMOD_ERR_SUBSOUND_ALLOCATED,
371 Error::SubsoundCantMove => FMOD_RESULT::FMOD_ERR_SUBSOUND_CANTMOVE,
372 Error::TagNotFound => FMOD_RESULT::FMOD_ERR_TAGNOTFOUND,
373 Error::TooManyChannels => FMOD_RESULT::FMOD_ERR_TOOMANYCHANNELS,
374 Error::Truncated => FMOD_RESULT::FMOD_ERR_TRUNCATED,
375 Error::Unimplemented => FMOD_RESULT::FMOD_ERR_UNIMPLEMENTED,
376 Error::Uninitialized => FMOD_RESULT::FMOD_ERR_UNINITIALIZED,
377 Error::Unsupported => FMOD_RESULT::FMOD_ERR_UNSUPPORTED,
378 Error::Version => FMOD_RESULT::FMOD_ERR_VERSION,
379 Error::EventAlreadyLoaded => FMOD_RESULT::FMOD_ERR_EVENT_ALREADY_LOADED,
380 Error::EventLiveUpdateBusy => FMOD_RESULT::FMOD_ERR_EVENT_LIVEUPDATE_BUSY,
381 Error::EventLiveUpdateMismatch => FMOD_RESULT::FMOD_ERR_EVENT_LIVEUPDATE_MISMATCH,
382 Error::EventLiveUpdateTimeout => FMOD_RESULT::FMOD_ERR_EVENT_LIVEUPDATE_TIMEOUT,
383 Error::EventNotFound => FMOD_RESULT::FMOD_ERR_EVENT_NOTFOUND,
384 Error::StudioUninitialized => FMOD_RESULT::FMOD_ERR_STUDIO_UNINITIALIZED,
385 Error::StudioNotLoaded => FMOD_RESULT::FMOD_ERR_STUDIO_NOT_LOADED,
386 Error::InvalidString => FMOD_RESULT::FMOD_ERR_INVALID_STRING,
387 Error::AlreadyLocked => FMOD_RESULT::FMOD_ERR_ALREADY_LOCKED,
388 Error::NotLocked => FMOD_RESULT::FMOD_ERR_NOT_LOCKED,
389 Error::RecordDisconnected => FMOD_RESULT::FMOD_ERR_RECORD_DISCONNECTED,
390 Error::TooManySamples => FMOD_RESULT::FMOD_ERR_TOOMANYSAMPLES,
391 Error::EnumFromPrivitive { .. } => FMOD_RESULT::FMOD_ERR_INVALID_PARAM,
393 }
394 }
395}
396
397pub(crate) trait FmodResultExt {
398 fn to_result(self) -> Result<()>;
399
400 fn to_error(self) -> Option<Error>;
401
402 fn from_result<T>(result: Result<T>) -> Self;
403}
404
405impl FmodResultExt for FMOD_RESULT {
406 fn to_result(self) -> Result<()> {
407 if matches!(self, FMOD_RESULT::FMOD_OK) {
408 Ok(())
409 } else {
410 Err(self.into())
411 }
412 }
413
414 fn to_error(self) -> Option<Error> {
415 self.to_result().err()
416 }
417
418 fn from_result<T>(result: Result<T>) -> Self {
419 match result {
420 Ok(_) => FMOD_RESULT::FMOD_OK,
421 Err(e) => e.into(),
422 }
423 }
424}