allen/
lib.rs

1mod buffer;
2mod context;
3mod device;
4#[macro_use]
5mod properties;
6mod listener;
7mod source;
8pub(crate) mod sys;
9
10pub use buffer::*;
11pub use context::*;
12pub use device::*;
13pub use listener::*;
14pub(crate) use properties::*;
15pub use source::*;
16
17use crate::sys::*;
18#[cfg(feature = "serde")]
19use serde::{Deserialize, Serialize};
20use std::{
21    ffi::{CStr, CString},
22    ptr,
23};
24use thiserror::Error;
25
26/// For whatever reason, macros which take type parameters can't accept "[f32; 3]"
27pub(crate) type Float3 = [f32; 3];
28
29/// Used to define the orientation of a listener.
30#[derive(Debug, Default, Copy, Clone)]
31#[repr(C, packed)]
32#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
33pub struct Orientation {
34    pub up: Float3,
35    pub at: Float3,
36}
37
38/// An OpenAL error.
39#[derive(Error, Debug)]
40pub enum AllenError {
41    #[error("an invalid name was passed")]
42    InvalidName,
43    #[error("a bad device was passed")]
44    InvalidDevice,
45    #[error("a bad context was passed")]
46    InvalidContext,
47    #[error("an invalid enum value was passed")]
48    InvalidEnum,
49    #[error("an invalid value was passed")]
50    InvalidValue,
51    #[error("the requested operation is not valid")]
52    InvalidOperation,
53    #[error("out of memory")]
54    OutOfMemory,
55    #[error("unknown OpenAL error: `{0}`")]
56    Unknown(i32),
57}
58
59pub(crate) type AllenResult<T> = Result<T, AllenError>;
60
61pub(crate) fn check_al_error() -> AllenResult<()> {
62    let error = unsafe { alGetError() };
63
64    if error == AL_NO_ERROR {
65        Ok(())
66    } else {
67        Err(match error {
68            AL_INVALID_NAME => AllenError::InvalidName,
69            AL_INVALID_ENUM => AllenError::InvalidEnum,
70            AL_INVALID_VALUE => AllenError::InvalidValue,
71            AL_INVALID_OPERATION => AllenError::InvalidOperation,
72            AL_OUT_OF_MEMORY => AllenError::OutOfMemory,
73            e => AllenError::Unknown(e),
74        })
75    }
76}
77
78pub(crate) fn check_alc_error(device: *mut ALCdevice) -> AllenResult<()> {
79    let error = unsafe { alcGetError(device) };
80
81    if error == ALC_NO_ERROR {
82        Ok(())
83    } else {
84        Err(match error {
85            ALC_INVALID_DEVICE => AllenError::InvalidDevice,
86            ALC_INVALID_CONTEXT => AllenError::InvalidContext,
87            ALC_INVALID_ENUM => AllenError::InvalidEnum,
88            ALC_INVALID_VALUE => AllenError::InvalidValue,
89            ALC_OUT_OF_MEMORY => AllenError::OutOfMemory,
90            e => AllenError::Unknown(e),
91        })
92    }
93}
94
95pub(crate) fn get_string(param: ALenum) -> &'static str {
96    unsafe { CStr::from_ptr(alGetString(param)) }
97        .to_str()
98        .unwrap() // Unwrap is justified because from what I understand, this SHOULD be a valid string.
99}