1 use num_derive::FromPrimitive;
2 
3 use crate::AudioFormat;
4 
5 pub(crate) struct Context;
6 
7 impl Context {
8     pub const AUDIO_SERVICE: &'static str = "audio";
9 }
10 
11 pub(crate) struct PackageManager;
12 
13 impl PackageManager {
14     pub const FEATURE_AUDIO_LOW_LATENCY: &'static str = "android.hardware.audio.low_latency";
15     pub const FEATURE_AUDIO_OUTPUT: &'static str = "android.hardware.audio.output";
16     pub const FEATURE_AUDIO_PRO: &'static str = "android.hardware.audio.pro";
17     pub const FEATURE_MICROPHONE: &'static str = "android.hardware.microphone";
18     pub const FEATURE_MIDI: &'static str = "android.software.midi";
19 }
20 
21 pub(crate) struct AudioManager;
22 
23 impl AudioManager {
24     pub const PROPERTY_OUTPUT_SAMPLE_RATE: &'static str =
25         "android.media.property.OUTPUT_SAMPLE_RATE";
26     pub const PROPERTY_OUTPUT_FRAMES_PER_BUFFER: &'static str =
27         "android.media.property.OUTPUT_FRAMES_PER_BUFFER";
28 
29     pub const GET_DEVICES_INPUTS: i32 = 1 << 0;
30     pub const GET_DEVICES_OUTPUTS: i32 = 1 << 1;
31     pub const GET_DEVICES_ALL: i32 = Self::GET_DEVICES_INPUTS | Self::GET_DEVICES_OUTPUTS;
32 }
33 
34 /**
35  * The Android audio device info
36  */
37 #[cfg_attr(feature = "doc-cfg", doc(cfg(feature = "java-interface")))]
38 #[derive(Debug, Clone)]
39 pub struct AudioDeviceInfo {
40     /**
41      * Device identifier
42      */
43     pub id: i32,
44 
45     /**
46      * The type of device
47      */
48     pub device_type: AudioDeviceType,
49 
50     /**
51      * The device can be used for playback and/or capture
52      */
53     pub direction: AudioDeviceDirection,
54 
55     /**
56      * Device address
57      */
58     pub address: String,
59 
60     /**
61      * Device product name
62      */
63     pub product_name: String,
64 
65     /**
66      * Available channel configurations
67      */
68     pub channel_counts: Vec<i32>,
69 
70     /**
71      * Supported sample rates
72      */
73     pub sample_rates: Vec<i32>,
74 
75     /**
76      * Supported audio formats
77      */
78     pub formats: Vec<AudioFormat>,
79 }
80 
81 /**
82  * The type of audio device
83  */
84 #[cfg_attr(feature = "doc-cfg", doc(cfg(feature = "java-interface")))]
85 #[derive(Debug, Clone, Copy, FromPrimitive)]
86 #[non_exhaustive]
87 #[repr(i32)]
88 pub enum AudioDeviceType {
89     Unknown = 0,
90     AuxLine = 19,
91     BluetoothA2DP = 8,
92     BluetoothSCO = 7,
93     BuiltinEarpiece = 1,
94     BuiltinMic = 15,
95     BuiltinSpeaker = 2,
96     BuiltinSpeakerSafe = 24,
97     Bus = 21,
98     Dock = 13,
99     Fm = 14,
100     FmTuner = 16,
101     Hdmi = 9,
102     HdmiArc = 10,
103     HearingAid = 23,
104     Ip = 20,
105     LineAnalog = 5,
106     LineDigital = 6,
107     Telephony = 18,
108     TvTuner = 17,
109     UsbAccessory = 12,
110     UsbDevice = 11,
111     UsbHeadset = 22,
112     WiredHeadphones = 4,
113     WiredHeadset = 3,
114 }
115 
116 /**
117  * The direction of audio device
118  */
119 #[cfg_attr(feature = "doc-cfg", doc(cfg(feature = "java-interface")))]
120 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
121 #[repr(i32)]
122 pub enum AudioDeviceDirection {
123     Dumb = 0,
124     Input = AudioManager::GET_DEVICES_INPUTS,
125     Output = AudioManager::GET_DEVICES_OUTPUTS,
126     InputOutput = AudioManager::GET_DEVICES_ALL,
127 }
128 
wrap_status(result: i32) -> Status129 impl AudioDeviceDirection {
130     pub fn new(is_input: bool, is_output: bool) -> Self {
131         use self::AudioDeviceDirection::*;
132         match (is_input, is_output) {
133             (true, true) => InputOutput,
134             (false, true) => Output,
135             (true, false) => Input,
136             _ => Dumb,
137         }
138     }
139 
140     pub fn is_input(&self) -> bool {
141         0 < *self as i32 & AudioDeviceDirection::Input as i32
142     }
143 
144     pub fn is_output(&self) -> bool {
145         0 < *self as i32 & AudioDeviceDirection::Output as i32
146     }
147 }
148 
149 impl AudioFormat {
150     pub(crate) const ENCODING_PCM_16BIT: i32 = 2;
151     //pub(crate) const ENCODING_PCM_8BIT: i32 = 3;
152     pub(crate) const ENCODING_PCM_FLOAT: i32 = 4;
153 
154     pub(crate) fn from_encoding(encoding: i32) -> Option<AudioFormat> {
155         match encoding {
156             AudioFormat::ENCODING_PCM_16BIT => Some(AudioFormat::I16),
157             AudioFormat::ENCODING_PCM_FLOAT => Some(AudioFormat::F32),
158             _ => None,
159         }
160     }
161 }
162