Skip to main content

alto/
lib.rs

1//! # Overview
2//! Alto is an idiomatic wrapper for the OpenAL 3D audio API and associated extensions (including EFX).
3//! This documentation does not describe how to use the OpenAL API itself, but rather explains how
4//! it has been adapted for rust and provides the native symbols associated with each function
5//! so they can be cross-referenced with the official OpenAL documentation for full details.
6//!
7//! The core of the API is the [`Alto`](struct.Alto.html) struct. It has no analog in raw OpenAL and
8//! represents an implementation of the API itself. From there, instances of familiar OpenAL objects
9//! can be instantiated.
10//!
11//! # WARNING
12//! Because Alto interacts with global C state via dynamic linking, having multiple versions of Alto in one project could lead to unsafety.
13//! Please make sure only one version of Alto is in your dependency tree at any given time.
14
15
16#[macro_use]
17extern crate lazy_static;
18extern crate parking_lot;
19extern crate al_sys;
20
21use std::error::Error as StdError;
22use std::fmt;
23use std::io;
24
25
26mod alc;
27pub use alc::*;
28
29
30mod al;
31pub use al::*;
32
33
34pub mod ext;
35
36
37pub mod efx;
38
39
40pub mod sys {
41	pub use al_sys::*;
42}
43
44
45/// An error as reported by `alcGetError` or `alGetError`, plus some Alto specific variants.
46#[derive(Debug)]
47pub enum AltoError {
48	/// `ALC_INVALID_DEVICE`
49	InvalidDevice,
50	/// `ALC_INVALID_CONTEXT`
51	InvalidContext,
52	/// `AL_INVALID_NAME`
53	InvalidName,
54	/// `ALC/AL_INVALID_ENUM`
55	InvalidEnum,
56	/// `ALC/AL_INVALID_VALUE`
57	InvalidValue,
58	/// `AL_INVALID_OPERATION`
59	InvalidOperation,
60	/// `ALC/AL_OUT_OF_MEMORY`
61	OutOfMemory,
62	UnknownAlcError(sys::ALCint),
63	UnknownAlError(sys::ALint),
64
65	/// The underlying implementation is not compatible with the 1.1 spec. Alto specific.
66	UnsupportedVersion{major: sys::ALCint, minor: sys::ALCint},
67	/// The requested action can't be performed because the required extension is unavaiable. Alto specific.
68	ExtensionNotPresent,
69	/// Resource creation failed without setting an error code.
70	NullError,
71	/// A resource belongs to another device and is not eligible.
72	WrongDevice,
73	/// A resource belongs to another context and is not eligible.
74	WrongContext,
75	/// There was an underlying IO error, usually from a failure when loading the OpenAL dylib. Alto specific.
76	Io(io::Error),
77}
78
79
80pub type AltoResult<T> = ::std::result::Result<T, AltoError>;
81
82
83impl AltoError {
84	fn from_alc(alc: sys::ALCenum) -> AltoError {
85		match alc {
86			sys::ALC_INVALID_DEVICE => AltoError::InvalidDevice,
87			sys::ALC_INVALID_CONTEXT => AltoError::InvalidContext,
88			sys::ALC_INVALID_ENUM => AltoError::InvalidEnum,
89			sys::ALC_INVALID_VALUE => AltoError::InvalidValue,
90			sys::ALC_OUT_OF_MEMORY => AltoError::OutOfMemory,
91			e => AltoError::UnknownAlcError(e),
92		}
93	}
94
95
96	fn from_al(al: sys::ALenum) -> AltoError {
97		match al {
98			sys::AL_INVALID_NAME => AltoError::InvalidName,
99			sys::AL_INVALID_ENUM => AltoError::InvalidEnum,
100			sys::AL_INVALID_VALUE => AltoError::InvalidValue,
101			sys::AL_INVALID_OPERATION => AltoError::InvalidOperation,
102			sys::AL_OUT_OF_MEMORY => AltoError::OutOfMemory,
103			e => AltoError::UnknownAlError(e),
104		}
105	}
106}
107
108
109impl fmt::Display for AltoError {
110	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
111		write!(f, "{}", self.description())
112	}
113}
114
115
116impl StdError for AltoError {
117	fn description(&self) -> &str {
118		match *self {
119			AltoError::InvalidDevice => "ALTO ERROR: ALC Invalid Device",
120			AltoError::InvalidContext => "ALTO ERROR: ALC Invalid Context",
121			AltoError::InvalidName => "ALTO ERROR: AL Invalid Name",
122			AltoError::InvalidEnum => "ALTO ERROR: ALC Invalid Enum",
123			AltoError::InvalidValue => "ALTO ERROR: ALC Invalid Value",
124			AltoError::InvalidOperation => "ALTO ERROR: AL Invalid Operation",
125			AltoError::OutOfMemory => "ALTO ERROR: ALC Out of Memory",
126			AltoError::UnknownAlcError(..) => "ALTO ERROR: Unknown ALC error",
127			AltoError::UnknownAlError(..) => "ALTO ERROR: Unknown AL error",
128
129			AltoError::UnsupportedVersion{..} => "ALTO ERROR: Unsupported Version",
130			AltoError::ExtensionNotPresent => "ALTO ERROR: Extension Not Present",
131			AltoError::NullError => "ALTO ERROR: Return value is NULL with no error code",
132			AltoError::WrongDevice => "ALTO ERROR: Resource used on wrong device",
133			AltoError::WrongContext => "ALTO ERROR: Resource used on wrong device",
134			AltoError::Io(ref io) => io.description(),
135		}
136	}
137}
138
139
140impl From<io::Error> for AltoError {
141	fn from(io: io::Error) -> AltoError {
142		AltoError::Io(io)
143	}
144}
145
146
147impl From<ext::ExtensionError> for AltoError {
148	fn from(_: ext::ExtensionError) -> AltoError {
149		AltoError::ExtensionNotPresent
150	}
151}