1 /*
2  * Copyright 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package org.hyphonate.megaaudio.common;
17 
18 import android.media.AudioDeviceInfo;
19 import android.media.AudioTrack;
20 
21 /**
22  * Base class for Stream Builders.
23  *
24  * Contains common stream attributes that will be used when building a contcrete stream object.
25  */
26 public abstract class BuilderBase {
27     @SuppressWarnings("unused")
28     private static final String TAG = BuilderBase.class.getSimpleName();
29     @SuppressWarnings("unused")
30     private static final boolean LOG = false;
31 
32     // API Types - enumerated in high nibble
33     public static final int TYPE_MASK = 0xF000;
34     public static final int TYPE_UNDEFINED = 0xF000;
35     public static final int TYPE_NONE = 0x0000;
36     public static final int TYPE_JAVA = 0x1000;
37     public static final int TYPE_OBOE = 0x2000;
38 
39     // API subtypes - enumerated in low nibble
40     public static final int SUB_TYPE_MASK = 0x0000F;
41     public static final int SUB_TYPE_OBOE_DEFAULT = 0x0000;
42     public static final int SUB_TYPE_OBOE_AAUDIO = 0x0001;
43     public static final int SUB_TYPE_OBOE_OPENSL_ES = 0x0002;
44 
45     /**
46      * The type id of the stream to create. Composed of the above constants.
47      */
48     protected int mType = TYPE_UNDEFINED;
49 
50     /**
51      * The number of frames per exchange of audio data to/from the AudioSink/AudioSource
52      * associated with this stream.
53      * Note: this is not the same as the size of record/playback buffers used by the
54      * underlying Native/Java player/recorder objects. That size is determined by the
55      * underlying Native/Java player/recorder objects.
56      */
57     protected int mNumExchangeFrames = 128;
58 
59     /**
60      * The sample rate for the created stream.
61      */
62     protected int mSampleRate = 48000;
63 
64     /**
65      * The number of channels for the created stream.
66      */
67     protected int mChannelCount = 2;
68     protected int mChannelMask = 0;
69 
70     // Performance Mode Constants
71     public static final int PERFORMANCE_MODE_NONE = 10; // AAUDIO_PERFORMANCE_MODE_NONE
72     public static final int
73             PERFORMANCE_MODE_POWERSAVING = 11;  // AAUDIO_PERFORMANCE_MODE_POWER_SAVING,
74     public static final int
75             PERFORMANCE_MODE_LOWLATENCY = 12;   // AAUDIO_PERFORMANCE_MODE_LOW_LATENCY
76     /**
77      * The performance mode for the created stream. It can be any one of the constants above.
78      */
79     protected int mPerformanceMode = PERFORMANCE_MODE_LOWLATENCY;
80 
81     // Sharing Mode Constants
82     public static final int SHARING_MODE_EXCLUSIVE = 0; // AAUDIO_SHARING_MODE_EXCLUSIVE
83     public static final int SHARING_MODE_SHARED = 1;    // AAUDIO_SHARING_MODE_SHARED
84     public static final int SHARING_MODE_NOTSUPPORTED = -1;    // A return value only
85 
86     /**
87      * The sharing mode for the created stream. It can be any one of the constants above.
88      */
89     protected int mSharingMode = SHARING_MODE_EXCLUSIVE;
90 
91     /**
92      * If non-null, the device to route the stream to/from upon creation.
93      */
94     protected AudioDeviceInfo mRouteDevice;
95 
96     /**
97      * Sets the number of frames exchanged between Players/Recorder and
98      * the corresponding AudioSource/AudioSink objects.
99      * @param numFrames the number of frames to exchange.
100      * @return this BuilderBase (for cascaded calls)
101      */
setNumExchangeFrames(int numFrames)102     public BuilderBase setNumExchangeFrames(int numFrames) {
103         mNumExchangeFrames = numFrames;
104         return this;
105     }
106 
107     /**
108      * @return The number of frames of audio exchanged between Players/Recorder and
109      * the corresponding AudioSource/AudioSink objects,
110      * specified in the setNumExchangeFrames() method.
111      */
getNumExchangeFrames()112     public int getNumExchangeFrames() {
113         return mNumExchangeFrames;
114     }
115 
116     /**
117      * Specifies the sample rate for the created stream
118      * @param sampleRate The sample rate for the created stream.
119      * @return this BuilderBase (for cascaded calls)
120      */
setSampleRate(int sampleRate)121     public BuilderBase setSampleRate(int sampleRate) {
122         mSampleRate = sampleRate;
123         return this;
124     }
125 
126     /**
127      * @return the sample rate for the created stream, specified in the
128      * setSampleRate() method.
129      */
getSampleRate()130     public int getSampleRate() {
131         return mSampleRate;
132     }
133 
134     /**
135      * Specifies the COUNT of channels for audio I/O. Note that this overrides
136      * any previously specified POSITIONAL channel mask.
137      *
138      * @param channelCount The number of channels for the created stream.
139      * @return this BuilderBase (for cascaded calls)
140      */
setChannelCount(int channelCount)141     public BuilderBase setChannelCount(int channelCount) {
142         mChannelCount = channelCount;
143         mChannelMask = 0;
144         return this;
145     }
146 
147     /**
148      * @return the number of channels for the created stream, specified in the
149      * setChannelCount() method. 0 if using positional channel-masks.
150      */
getChannelCount()151     public int getChannelCount() {
152         return mChannelCount;
153     }
154 
155     /**
156      * Specifies a POSITIONAL mask defining channel placement for audio I/O. Note that this
157      * overrides any previously specified channel COUNT.
158      *
159      * @param mask The desired AudioFormat channel mask
160      * @return this BuilderBase (for cascaded calls)
161      */
setChannelMask(int mask)162     public BuilderBase setChannelMask(int mask) {
163         mChannelMask = mask;
164         mChannelCount = 0;
165         return this;
166     }
167 
168     /**
169      * @return The current positional mask for audio I/O. 0 if using a channel-index mask.
170      */
getChannelMask()171     public int getChannelMask() {
172         return mChannelMask;
173     }
174 
175     /**
176      * Sets the sharing mode for the created stream.
177      * @param mode See "Sharing Mode Constants" Above
178      * @return this BuilderBase (for cascaded calls)
179      */
setSharingMode(int mode)180     public BuilderBase setSharingMode(int mode) {
181         mSharingMode = mode;
182         return this;
183     }
184 
185     /**
186      * @return The sharing mode for the created stream, set in the setSharingMode() method.
187      */
getSharingMode()188     public int getSharingMode() {
189         return mSharingMode;
190     }
191 
192     /**
193      * Sets the performance mode for the created stream.
194      * @param mode See "Performance Mode Constants" above
195      * @return this BuilderBase (for cascaded calls)
196      */
setPerformanceMode(int mode)197     public BuilderBase setPerformanceMode(int mode) {
198         mPerformanceMode = mode;
199         return this;
200     }
201 
202     /**
203      * @return The performance mode for the created stream, set in the setPerformanceMode() method.
204      */
getPerformanceMode()205     public int getPerformanceMode() {
206         return mPerformanceMode;
207     }
208 
209     // This is needed because the performance mode constants for the Java API
210     // are different than those for the AAudio/Oboe API
211     // These are the JAVA AudioTrack constants
212     // public static final int PERFORMANCE_MODE_NONE = 0;
213     // public static final int PERFORMANCE_MODE_LOW_LATENCY = 1;
214     // public static final int PERFORMANCE_MODE_POWER_SAVING = 2;
215     /**
216      * Maps from MegaAudio (and AAudio/Oboe) performance mode constants the equivalent
217      * Java AudioTrack constants.
218      * @return The Java AudioTrack constant corresponding the current performance mode
219      * for the created stream.
220      */
getJavaPerformanceMode()221     public int getJavaPerformanceMode() {
222         switch (mPerformanceMode) {
223             case PERFORMANCE_MODE_NONE:
224                 return AudioTrack.PERFORMANCE_MODE_NONE;
225 
226             case PERFORMANCE_MODE_POWERSAVING:
227                 return AudioTrack.PERFORMANCE_MODE_POWER_SAVING;
228 
229             case PERFORMANCE_MODE_LOWLATENCY:
230             default:
231                 return AudioTrack.PERFORMANCE_MODE_LOW_LATENCY;
232         }
233     }
234 
235     /**
236      * Specifies the device to route the stream to/from upon creation. If null, the default
237      * route is selected.
238      * @param routeDevice The device to route to, or null for the default device.
239      * @return This Builderbase (for cascaded calls)
240      */
setRouteDevice(AudioDeviceInfo routeDevice)241     public BuilderBase setRouteDevice(AudioDeviceInfo routeDevice) {
242         mRouteDevice = routeDevice;
243         return this;
244     }
245 
246     /**
247      * @return The AudioDevice to route the stream to/from. If null, specifies the default device.
248      */
getRouteDevice()249     public AudioDeviceInfo getRouteDevice() {
250         return mRouteDevice;
251     }
252 
253     // Indicates no specific routing (default routing).
254     public static final int ROUTED_DEVICE_ID_DEFAULT = -1;
255 
256     /**
257      * For convenience in converting the AudioDeviceInfo to an integer device ID.
258      * @return The integer device ID of the device to route to/from. -1 if no device is specified.
259      */
getRouteDeviceId()260     public int getRouteDeviceId() {
261         return mRouteDevice == null ? ROUTED_DEVICE_ID_DEFAULT : mRouteDevice.getId();
262     }
263 }
264