1 //! Info about connected audio devices
2
3 use ll;
4 use util::{to_pa_result, pa_time_to_duration};
5 use hostapi::HostApiIndex;
6 use pa::PaError;
7 use std::time::Duration;
8 use std::ffi::CStr;
9
10 /// Index of a Device
11 pub type DeviceIndex = u32;
12
13 /// Information for a specific device
14 pub struct DeviceInfo
15 {
16 /// Human readable name
17 pub name: String,
18
19 /// Index of the host API this device belongs to
20 pub host_api: HostApiIndex,
21
22 /// Maximal number of input channels that can be used
23 pub max_input_channels: u32,
24
25 /// Maximal number of ouput channels that can be used
26 pub max_output_channels: u32,
27
28 /// Default input latency for interactive performance
29 pub default_low_input_latency: Duration,
30
31 /// Default output latency for interactive performance
32 pub default_low_output_latency: Duration,
33
34 /// Default input latency for robust non-interactive applications
35 pub default_high_input_latency: Duration,
36
37 /// Default output latency for robust non-interactive applications
38 pub default_high_output_latency: Duration,
39
40 /// Default sample rate
41 pub default_sample_rate: f64,
42 }
43
44 impl DeviceInfo
45 {
from_ll(input: &ll::PaDeviceInfo) -> DeviceInfo46 fn from_ll(input: &ll::PaDeviceInfo) -> DeviceInfo
47 {
48 DeviceInfo
49 {
50 name: String::from_utf8_lossy(unsafe { CStr::from_ptr(input.name).to_bytes() }).into_owned(),
51 host_api: input.hostApi as HostApiIndex,
52 max_input_channels: input.maxInputChannels as u32,
53 max_output_channels: input.maxOutputChannels as u32,
54 default_low_input_latency: pa_time_to_duration(input.defaultLowInputLatency),
55 default_low_output_latency: pa_time_to_duration(input.defaultLowOutputLatency),
56 default_high_input_latency: pa_time_to_duration(input.defaultHighInputLatency),
57 default_high_output_latency: pa_time_to_duration(input.defaultHighOutputLatency),
58 default_sample_rate: input.defaultSampleRate,
59 }
60 }
61 }
62
63 /// Retrieve the number of available devices.
get_count() -> Result<u32, PaError>64 pub fn get_count() -> Result<u32, PaError>
65 {
66 match unsafe { ll::Pa_GetDeviceCount() }
67 {
68 n if n >= 0 => Ok(n as u32),
69 m => to_pa_result(m).map(|_| 0),
70 }
71 }
72
73 /// Retrieve the index of the default input device
74 ///
75 /// Will return None when none are available.
get_default_input_index() -> Option<DeviceIndex>76 pub fn get_default_input_index() -> Option<DeviceIndex>
77 {
78 match unsafe { ll::Pa_GetDefaultInputDevice() }
79 {
80 n if n >= 0 => Some(n as u32),
81 _ => None,
82 }
83 }
84
85 /// Retrieve the index of the default output device
86 ///
87 /// Will return None when none are available.
get_default_output_index() -> Option<DeviceIndex>88 pub fn get_default_output_index() -> Option<DeviceIndex>
89 {
90 match unsafe { ll::Pa_GetDefaultOutputDevice() }
91 {
92 n if n >= 0 => Some(n as u32),
93 _ => None,
94 }
95 }
96
97 /// Get info about a particular device
98 ///
99 /// Returns None when the index is out of range.
get_info(index: DeviceIndex) -> Option<DeviceInfo>100 pub fn get_info(index: DeviceIndex) -> Option<DeviceInfo>
101 {
102 unsafe
103 {
104 match ll::Pa_GetDeviceInfo(index as i32) {
105 p if p.is_null() => None,
106 p => Some(DeviceInfo::from_ll(&*p)),
107 }
108 }
109 }
110
111 /// Converts a device index from a specific host API to a global device index
112 ///
113 /// Returns Err(InvalidHostApi) when the host_api is out of range, and Err(InvalidDevice) when
114 /// host_api_device_index is out of range.
115 ///
116 /// ```
117 /// // We retrieve the index of device 3 of api 1
118 /// let device_index = match portaudio_rs::device::get_from_host_api_device_index(1, 3)
119 /// {
120 /// Ok(n) => n,
121 /// Err(e) => { println!("Error: {:?}", e); return },
122 /// };
123 /// ```
get_from_host_api_device_index(host_api: HostApiIndex, host_api_device_index: u32) -> Result<DeviceIndex, PaError>124 pub fn get_from_host_api_device_index(host_api: HostApiIndex, host_api_device_index: u32) -> Result<DeviceIndex, PaError>
125 {
126 match unsafe { ll::Pa_HostApiDeviceIndexToDeviceIndex(host_api as i32, host_api_device_index as i32) }
127 {
128 n if n >= 0 => Ok(n as DeviceIndex),
129 m => to_pa_result(m).map(|_| 0),
130 }
131 }
132