1 //! Info module for available audio host API's
2 
3 use ll;
4 use pa::PaError;
5 use std::ffi::CStr;
6 use util::to_pa_result;
7 
8 /// Index number of a Host API
9 pub type HostApiIndex = u32;
10 
11 /// Possible Host API types
12 #[repr(u32)]
13 #[derive(Copy, Clone)]
14 #[allow(missing_docs)]
15 pub enum HostApiType
16 {
17     InDevelopment = ll::paInDevelopment,
18     DirectSound = ll::paDirectSound,
19     MME = ll::paMME,
20     ASIO = ll::paASIO,
21     SoundManager = ll::paSoundManager,
22     CoreAudio = ll::paCoreAudio,
23     OSS = ll::paOSS,
24     ALSA = ll::paALSA,
25     AL = ll::paAL,
26     BeOS = ll::paBeOS,
27     WDMKS = ll::paWDMKS,
28     JACK = ll::paJACK,
29     WASAPI = ll::paWASAPI,
30     AudioScienceHPI = ll::paAudioScienceHPI,
31 
32     /// Added for when FromPrimitive returns None
33     Unknown,
34 }
35 
36 impl HostApiType
37 {
38     /// Convert a static host API unique identifier, into a runtime host API index.
to_api_index(self) -> Result<HostApiIndex, PaError>39     pub fn to_api_index(self) -> Result<HostApiIndex, PaError>
40     {
41         match unsafe { ll::Pa_HostApiTypeIdToHostApiIndex(self as u32) }
42         {
43             n if n >= 0 => Ok(n as HostApiIndex),
44             m => to_pa_result(m).map(|_| 0),
45         }
46     }
47 
48     /// Get the enum value corresponding to the u32
from_u32(num: u32) -> HostApiType49     pub fn from_u32(num: u32) -> HostApiType
50     {
51         match num {
52             ll::paInDevelopment => HostApiType::InDevelopment,
53             ll::paDirectSound => HostApiType::DirectSound,
54             ll::paMME => HostApiType::MME,
55             ll::paASIO => HostApiType::ASIO,
56             ll::paSoundManager => HostApiType::SoundManager,
57             ll::paCoreAudio => HostApiType::CoreAudio,
58             ll::paOSS => HostApiType::OSS,
59             ll::paALSA => HostApiType::ALSA,
60             ll::paAL => HostApiType::AL,
61             ll::paBeOS => HostApiType::BeOS,
62             ll::paWDMKS => HostApiType::WDMKS,
63             ll::paJACK => HostApiType::JACK,
64             ll::paWASAPI => HostApiType::WASAPI,
65             ll::paAudioScienceHPI => HostApiType::AudioScienceHPI,
66             _ => HostApiType::Unknown,
67         }
68     }
69 }
70 
71 /// Information about a specific host API
72 pub struct HostApiInfo
73 {
74     /// The type of the API
75     pub api_type: HostApiType,
76 
77     /// Human-readable name of the API
78     pub name: String,
79 
80     /// Number of devices this API has
81     pub device_count: u32,
82 
83     /// Default input device of the API. Is None if there is no input device available.
84     pub default_input: Option<u32>,
85 
86     /// Default output device of the API. Is None if there is no output device available.
87     pub default_output: Option<u32>,
88 }
89 
90 impl HostApiInfo
91 {
from_ll(input: &ll::PaHostApiInfo) -> HostApiInfo92     fn from_ll(input: &ll::PaHostApiInfo) -> HostApiInfo
93     {
94         HostApiInfo
95         {
96             api_type: HostApiType::from_u32(input._type),
97             name: String::from_utf8_lossy(unsafe { CStr::from_ptr(input.name).to_bytes() }).into_owned(),
98             device_count: input.deviceCount as u32,
99             default_input: match input.defaultInputDevice { n if n >= 0 => Some(n as u32), _ => None },
100             default_output: match input.defaultOutputDevice { n if n >= 0 => Some(n as u32), _ => None },
101         }
102     }
103 }
104 
105 /// Error info obtained by get_last_error
106 pub struct HostErrorInfo
107 {
108     /// The error code given
109     pub code: i32,
110 
111     /// A human readable error message
112     pub text: String,
113 
114     /// The type of the API that produced the error
115     pub api_type: HostApiType,
116 }
117 
118 impl HostErrorInfo
119 {
from_ll(input: &ll::PaHostErrorInfo) -> HostErrorInfo120     fn from_ll(input: &ll::PaHostErrorInfo) -> HostErrorInfo
121     {
122         HostErrorInfo
123         {
124             code: input.errorCode as i32,
125             text: String::from_utf8_lossy(unsafe { CStr::from_ptr(input.errorText).to_bytes() }).into_owned(),
126             api_type: HostApiType::from_u32(input.hostApiType),
127         }
128     }
129 }
130 
131 /// Return information about the last host error encountered.
132 ///
133 /// The values in this structure will only be valid if a PortAudio function has previously returned
134 /// the UnanticipatedHostError error code.
get_last_error() -> Option<HostErrorInfo>135 pub fn get_last_error() -> Option<HostErrorInfo>
136 {
137     unsafe
138     {
139         match ll::Pa_GetLastHostErrorInfo() {
140             p if p.is_null() => None,
141             p => Some(HostErrorInfo::from_ll(&*p)),
142         }
143     }
144 }
145 
146 /// Get the number of host API's available
get_count() -> Result<u32, PaError>147 pub fn get_count() -> Result<u32, PaError>
148 {
149     match unsafe { ll::Pa_GetHostApiCount() }
150     {
151         n if n >= 0 => Ok(n as HostApiIndex),
152         m => to_pa_result(m).map(|_| 0),
153     }
154 }
155 
156 /// Get the default Host API
get_default_index() -> Result<HostApiIndex, PaError>157 pub fn get_default_index() -> Result<HostApiIndex, PaError>
158 {
159     match unsafe { ll::Pa_GetDefaultHostApi() }
160     {
161         n if n >= 0 => Ok(n as HostApiIndex),
162         m => to_pa_result(m).map(|_| 0),
163     }
164 }
165 
166 /// Get information about a specific Host API
167 ///
168 /// Returns None when an invalid index is given
get_info(index: HostApiIndex) -> Option<HostApiInfo>169 pub fn get_info(index: HostApiIndex) -> Option<HostApiInfo>
170 {
171     unsafe
172     {
173         match ll::Pa_GetHostApiInfo(index as i32) {
174             p if p.is_null() => None,
175             p => Some(HostApiInfo::from_ll(&*p)),
176         }
177     }
178 }
179