libaudioverse/
lib.rs

1//!
2//! Rust bindings for [Libaudioverse](https://github.com/libaudioverse/libaudioverse), a highly flexible realtime audio synthesis library.
3//!
4
5extern crate libaudioverse_sys;
6
7pub mod buffer;
8pub mod nodes;
9pub mod server;
10
11use std::error;
12use std::fmt;
13use std::ptr;
14use std::result;
15
16use std::os::raw::{c_int, c_char};
17use std::ffi::CStr;
18
19use self::libaudioverse_sys::*;
20
21pub use self::buffer::Buffer;
22pub use self::nodes::Node;
23pub use self::server::Server;
24
25pub use self::nodes::buffer_node::BufferNode;
26pub use self::nodes::environment_node::EnvironmentNode;
27pub use self::nodes::file_streamer_node::FileStreamerNode;
28pub use self::nodes::gain_node::GainNode;
29pub use self::nodes::hrtf_node::HrtfNode;
30pub use self::nodes::source_node::SourceNode;
31
32pub use self::nodes::properties::bool_property::BoolProperty;
33pub use self::nodes::properties::buffer_property::BufferProperty;
34pub use self::nodes::properties::distance_model_property::{DistanceModel, DistanceModelProperty};
35pub use self::nodes::properties::double_property::DoubleProperty;
36pub use self::nodes::properties::float_property::FloatProperty;
37pub use self::nodes::properties::float3_property::Float3Property;
38pub use self::nodes::properties::float6_property::Float6Property;
39pub use self::nodes::properties::node_state_property::{NodeState, NodeStateProperty};
40pub use self::nodes::properties::panning_strategy_property::{PanningStrategy, PanningStrategyProperty};
41
42#[derive(Debug)]
43pub struct Error {
44    pub code: i32,
45    pub message: String
46}
47
48impl fmt::Display for Error {
49    fn fmt(&self, f: &mut fmt::Formatter) -> result::Result<(), fmt::Error> {
50        // Displaying an `Error` simply displays the message from libaudioverse
51        self.message.fmt(f)
52    }
53}
54
55impl error::Error for Error {
56    fn description(&self) -> &str { &self.message }
57}
58
59pub type Result<T> = result::Result<T, Error>;
60
61fn check(code: LavError) -> Result<()> {
62    if code == Lav_ERRORS_Lav_ERROR_NONE {
63        return Ok(());
64    }
65    
66    let mut msg: *const c_char = ptr::null_mut();
67    unsafe {
68        // Get the message corresponding to the last error that happened on this thread. 
69        // The returned pointer is valid until another error occurs.
70        let _error = Lav_errorGetMessage(&mut msg);
71        let message = CStr::from_ptr(msg)
72            .to_string_lossy()
73            .into_owned();
74        
75        Err(Error {
76            code: code as i32,
77            message
78        })
79    }
80}
81
82/// Initializes Libaudioverse. Failure to do so will result in crashes. You may initialize the library more than once: subsequent initializations do nothing.
83pub fn initialize() -> Result<()> {
84    check(unsafe { Lav_initialize() })
85}
86
87pub fn is_initialized() -> Result<bool> {
88    let mut res : c_int = 0;
89    
90    check(unsafe { Lav_isInitialized(&mut res) })?;
91    Ok(res != 0)
92}
93
94/// Deinitializes Libaudioverse. Failure to do so may lead to crashes, depending on what is or is not created. It is not safe to assume that Libaudioverse will properly clean itself up at process exit unless this function is called. You must deinitialize the library exactly as many times as it has been initialized.
95pub fn shutdown() -> Result<()> {
96    check(unsafe { Lav_shutdown() })
97}
98
99#[test]
100fn initializes_and_shuts_down() {
101    initialize().unwrap();
102    assert!(is_initialized().unwrap());
103    shutdown().unwrap();
104}
105