1 /* 2 * Copyright 2017 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 17 package com.mobileer.oboetester; 18 19 import android.content.res.Resources; 20 21 import java.util.HashMap; 22 23 /** 24 * Container for the properties of a Stream. 25 * 26 * This can be used to build a stream, or as a base class for a Stream, 27 * or as a way to report the properties of a Stream. 28 */ 29 30 public class StreamConfiguration { 31 public static final int UNSPECIFIED = 0; 32 33 // These must match order in Spinner and in native code and in AAudio.h 34 public static final int NATIVE_API_UNSPECIFIED = 0; 35 public static final int NATIVE_API_OPENSLES = 1; 36 public static final int NATIVE_API_AAUDIO = 2; 37 38 public static final int SHARING_MODE_EXCLUSIVE = 0; // must match AAUDIO 39 public static final int SHARING_MODE_SHARED = 1; // must match AAUDIO 40 41 public static final int AUDIO_FORMAT_PCM_16 = 1; // must match AAUDIO 42 public static final int AUDIO_FORMAT_PCM_FLOAT = 2; // must match AAUDIO 43 public static final int AUDIO_FORMAT_PCM_24 = 3; // must match AAUDIO 44 public static final int AUDIO_FORMAT_PCM_32 = 4; // must match AAUDIO 45 46 public static final int DIRECTION_OUTPUT = 0; // must match AAUDIO 47 public static final int DIRECTION_INPUT = 1; // must match AAUDIO 48 49 public static final int SESSION_ID_NONE = -1; // must match AAUDIO 50 public static final int SESSION_ID_ALLOCATE = 0; // must match AAUDIO 51 52 public static final int PERFORMANCE_MODE_NONE = 10; // must match AAUDIO 53 public static final int PERFORMANCE_MODE_POWER_SAVING = 11; // must match AAUDIO 54 public static final int PERFORMANCE_MODE_LOW_LATENCY = 12; // must match AAUDIO 55 56 public static final int RATE_CONVERSION_QUALITY_NONE = 0; // must match Oboe 57 public static final int RATE_CONVERSION_QUALITY_FASTEST = 1; // must match Oboe 58 public static final int RATE_CONVERSION_QUALITY_LOW = 2; // must match Oboe 59 public static final int RATE_CONVERSION_QUALITY_MEDIUM = 3; // must match Oboe 60 public static final int RATE_CONVERSION_QUALITY_HIGH = 4; // must match Oboe 61 public static final int RATE_CONVERSION_QUALITY_BEST = 5; // must match Oboe 62 63 public static final int STREAM_STATE_STARTING = 3; // must match Oboe 64 public static final int STREAM_STATE_STARTED = 4; // must match Oboe 65 66 public static final int INPUT_PRESET_GENERIC = 1; // must match Oboe 67 public static final int INPUT_PRESET_CAMCORDER = 5; // must match Oboe 68 public static final int INPUT_PRESET_VOICE_RECOGNITION = 6; // must match Oboe 69 public static final int INPUT_PRESET_VOICE_COMMUNICATION = 7; // must match Oboe 70 public static final int INPUT_PRESET_UNPROCESSED = 9; // must match Oboe 71 public static final int INPUT_PRESET_VOICE_PERFORMANCE = 10; // must match Oboe 72 73 public static final int ERROR_DISCONNECTED = -899; // must match Oboe 74 75 public static final int USAGE_MEDIA = 1; 76 public static final int USAGE_VOICE_COMMUNICATION = 2; 77 public static final int USAGE_VOICE_COMMUNICATION_SIGNALLING = 3; 78 public static final int USAGE_ALARM = 4; 79 public static final int USAGE_NOTIFICATION = 5; 80 public static final int USAGE_NOTIFICATION_RINGTONE = 6; 81 public static final int USAGE_NOTIFICATION_EVENT = 10; 82 public static final int USAGE_ASSISTANCE_ACCESSIBILITY = 11; 83 public static final int USAGE_ASSISTANCE_NAVIGATION_GUIDANCE = 12; 84 public static final int USAGE_ASSISTANCE_SONIFICATION = 13; 85 public static final int USAGE_GAME = 14; 86 public static final int USAGE_ASSISTANT = 16; 87 88 public static final int[] usages = { 89 USAGE_MEDIA, 90 USAGE_VOICE_COMMUNICATION, 91 USAGE_VOICE_COMMUNICATION_SIGNALLING, 92 USAGE_ALARM, 93 USAGE_NOTIFICATION, 94 USAGE_NOTIFICATION_RINGTONE, 95 USAGE_NOTIFICATION_EVENT, 96 USAGE_ASSISTANCE_ACCESSIBILITY, 97 USAGE_ASSISTANCE_NAVIGATION_GUIDANCE, 98 USAGE_ASSISTANCE_SONIFICATION, 99 USAGE_GAME, 100 USAGE_ASSISTANT}; 101 102 private int mNativeApi; 103 private int mBufferCapacityInFrames; 104 private int mChannelCount; 105 private int mDeviceId; 106 private int mSessionId; 107 private int mDirection; // does not get reset 108 private int mFormat; 109 private int mSampleRate; 110 private int mSharingMode; 111 private int mPerformanceMode; 112 private boolean mFormatConversionAllowed; 113 private boolean mChannelConversionAllowed; 114 private int mRateConversionQuality; 115 private int mInputPreset; 116 private int mUsage; 117 private static HashMap<String,Integer> mUsageStringToIntegerMap; 118 119 private int mFramesPerBurst = 0; 120 121 private boolean mMMap = false; 122 StreamConfiguration()123 public StreamConfiguration() { 124 reset(); 125 } 126 127 static { 128 // Build map for Usage string-to-int conversion. 129 mUsageStringToIntegerMap = new HashMap<String,Integer>(); 130 for (int usage : usages) { convertUsageToText(usage)131 mUsageStringToIntegerMap.put(convertUsageToText(usage), usage); 132 } 133 } 134 reset()135 public void reset() { 136 mNativeApi = NATIVE_API_UNSPECIFIED; 137 mBufferCapacityInFrames = UNSPECIFIED; 138 mChannelCount = UNSPECIFIED; 139 mDeviceId = UNSPECIFIED; 140 mSessionId = -1; 141 mFormat = AUDIO_FORMAT_PCM_FLOAT; 142 mSampleRate = UNSPECIFIED; 143 mSharingMode = SHARING_MODE_EXCLUSIVE; 144 mPerformanceMode = PERFORMANCE_MODE_LOW_LATENCY; 145 mInputPreset = INPUT_PRESET_VOICE_RECOGNITION; 146 mUsage = 0; // FIXME add USAGE_* 147 mFormatConversionAllowed = false; 148 mChannelConversionAllowed = false; 149 mRateConversionQuality = RATE_CONVERSION_QUALITY_NONE; 150 mMMap = NativeEngine.isMMapSupported(); 151 } 152 getFramesPerBurst()153 public int getFramesPerBurst() { 154 return mFramesPerBurst; 155 } 156 setFramesPerBurst(int framesPerBurst)157 public void setFramesPerBurst(int framesPerBurst) { 158 this.mFramesPerBurst = framesPerBurst; 159 } 160 getBufferCapacityInFrames()161 public int getBufferCapacityInFrames() { 162 return mBufferCapacityInFrames; 163 } 164 setBufferCapacityInFrames(int bufferCapacityInFrames)165 public void setBufferCapacityInFrames(int bufferCapacityInFrames) { 166 this.mBufferCapacityInFrames = bufferCapacityInFrames; 167 } 168 getFormat()169 public int getFormat() { 170 return mFormat; 171 } 172 setFormat(int format)173 public void setFormat(int format) { 174 this.mFormat = format; 175 } 176 getDirection()177 public int getDirection() { 178 return mDirection; 179 } 180 setDirection(int direction)181 public void setDirection(int direction) { 182 this.mDirection = direction; 183 } 184 getPerformanceMode()185 public int getPerformanceMode() { 186 return mPerformanceMode; 187 } 188 setPerformanceMode(int performanceMode)189 public void setPerformanceMode(int performanceMode) { 190 this.mPerformanceMode = performanceMode; 191 } 192 convertPerformanceModeToText(int performanceMode)193 static String convertPerformanceModeToText(int performanceMode) { 194 switch(performanceMode) { 195 case PERFORMANCE_MODE_NONE: 196 return "NO"; 197 case PERFORMANCE_MODE_POWER_SAVING: 198 return "PS"; 199 case PERFORMANCE_MODE_LOW_LATENCY: 200 return "LL"; 201 default: 202 return "??"; 203 } 204 } 205 getInputPreset()206 public int getInputPreset() { return mInputPreset; } setInputPreset(int inputPreset)207 public void setInputPreset(int inputPreset) { 208 this.mInputPreset = inputPreset; 209 } 210 getUsage()211 public int getUsage() { return mUsage; } setUsage(int Usage)212 public void setUsage(int Usage) { 213 this.mUsage = Usage; 214 } 215 convertUsageToText(int usage)216 static String convertUsageToText(int usage) { 217 switch(usage) { 218 case USAGE_MEDIA: 219 return "Media"; 220 case USAGE_VOICE_COMMUNICATION: 221 return "VoiceComm"; 222 case USAGE_VOICE_COMMUNICATION_SIGNALLING: 223 return "VoiceCommSig"; 224 case USAGE_ALARM: 225 return "Alarm"; 226 case USAGE_NOTIFICATION: 227 return "Notification"; 228 case USAGE_NOTIFICATION_RINGTONE: 229 return "Ringtone"; 230 case USAGE_NOTIFICATION_EVENT: 231 return "Event"; 232 case USAGE_ASSISTANCE_ACCESSIBILITY: 233 return "Accessability"; 234 case USAGE_ASSISTANCE_NAVIGATION_GUIDANCE: 235 return "Navigation"; 236 case USAGE_ASSISTANCE_SONIFICATION: 237 return "Sonification"; 238 case USAGE_GAME: 239 return "Game"; 240 case USAGE_ASSISTANT: 241 return "Assistant"; 242 default: 243 return "?=" + usage; 244 } 245 } 246 convertTextToUsage(String text)247 public static int convertTextToUsage(String text) { 248 return mUsageStringToIntegerMap.get(text); 249 } 250 getSharingMode()251 public int getSharingMode() { 252 return mSharingMode; 253 } 254 setSharingMode(int sharingMode)255 public void setSharingMode(int sharingMode) { 256 this.mSharingMode = sharingMode; 257 } 258 convertSharingModeToText(int sharingMode)259 static String convertSharingModeToText(int sharingMode) { 260 switch(sharingMode) { 261 case SHARING_MODE_SHARED: 262 return "SH"; 263 case SHARING_MODE_EXCLUSIVE: 264 return "EX"; 265 default: 266 return "??"; 267 } 268 } 269 convertFormatToText(int format)270 public static String convertFormatToText(int format) { 271 switch(format) { 272 case UNSPECIFIED: 273 return "Unspecified"; 274 case AUDIO_FORMAT_PCM_16: 275 return "I16"; 276 case AUDIO_FORMAT_PCM_24: 277 return "I24"; 278 case AUDIO_FORMAT_PCM_32: 279 return "I32"; 280 case AUDIO_FORMAT_PCM_FLOAT: 281 return "Float"; 282 default: 283 return "Invalid"; 284 } 285 } 286 convertNativeApiToText(int api)287 public static String convertNativeApiToText(int api) { 288 switch(api) { 289 case NATIVE_API_UNSPECIFIED: 290 return "Unspec"; 291 case NATIVE_API_AAUDIO: 292 return "AAudio"; 293 case NATIVE_API_OPENSLES: 294 return "OpenSL"; 295 default: 296 return "Invalid"; 297 } 298 } 299 300 dump()301 public String dump() { 302 String prefix = (getDirection() == DIRECTION_INPUT) ? "in" : "out"; 303 StringBuffer message = new StringBuffer(); 304 message.append(String.format("%s.channels = %d\n", prefix, mChannelCount)); 305 message.append(String.format("%s.perf = %s\n", prefix, 306 convertPerformanceModeToText(mPerformanceMode).toLowerCase())); 307 if (getDirection() == DIRECTION_INPUT) { 308 message.append(String.format("%s.preset = %s\n", prefix, 309 convertInputPresetToText(mInputPreset).toLowerCase())); 310 } else { 311 message.append(String.format("%s.preset = %s\n", prefix, 312 convertUsageToText(mUsage).toLowerCase())); 313 } 314 message.append(String.format("%s.sharing = %s\n", prefix, 315 convertSharingModeToText(mSharingMode).toLowerCase())); 316 message.append(String.format("%s.api = %s\n", prefix, 317 convertNativeApiToText(getNativeApi()).toLowerCase())); 318 message.append(String.format("%s.rate = %d\n", prefix, mSampleRate)); 319 message.append(String.format("%s.device = %d\n", prefix, mDeviceId)); 320 message.append(String.format("%s.mmap = %s\n", prefix, isMMap() ? "yes" : "no")); 321 message.append(String.format("%s.rate.conversion.quality = %d\n", prefix, mRateConversionQuality)); 322 return message.toString(); 323 } 324 325 // text must match menu values 326 public static final String NAME_INPUT_PRESET_GENERIC = "Generic"; 327 public static final String NAME_INPUT_PRESET_CAMCORDER = "Camcorder"; 328 public static final String NAME_INPUT_PRESET_VOICE_RECOGNITION = "VoiceRec"; 329 public static final String NAME_INPUT_PRESET_VOICE_COMMUNICATION = "VoiceComm"; 330 public static final String NAME_INPUT_PRESET_UNPROCESSED = "Unprocessed"; 331 public static final String NAME_INPUT_PRESET_VOICE_PERFORMANCE = "Performance"; 332 convertInputPresetToText(int inputPreset)333 public static String convertInputPresetToText(int inputPreset) { 334 switch(inputPreset) { 335 case INPUT_PRESET_GENERIC: 336 return NAME_INPUT_PRESET_GENERIC; 337 case INPUT_PRESET_CAMCORDER: 338 return NAME_INPUT_PRESET_CAMCORDER; 339 case INPUT_PRESET_VOICE_RECOGNITION: 340 return NAME_INPUT_PRESET_VOICE_RECOGNITION; 341 case INPUT_PRESET_VOICE_COMMUNICATION: 342 return NAME_INPUT_PRESET_VOICE_COMMUNICATION; 343 case INPUT_PRESET_UNPROCESSED: 344 return NAME_INPUT_PRESET_UNPROCESSED; 345 case INPUT_PRESET_VOICE_PERFORMANCE: 346 return NAME_INPUT_PRESET_VOICE_PERFORMANCE; 347 default: 348 return "Invalid"; 349 } 350 } 351 matchInputPreset(String text, int preset)352 private static boolean matchInputPreset(String text, int preset) { 353 return convertInputPresetToText(preset).toLowerCase().equals(text); 354 } 355 356 /** 357 * Case insensitive. 358 * @param text 359 * @return inputPreset, eg. INPUT_PRESET_CAMCORDER 360 */ convertTextToInputPreset(String text)361 public static int convertTextToInputPreset(String text) { 362 text = text.toLowerCase(); 363 if (matchInputPreset(text, INPUT_PRESET_GENERIC)) { 364 return INPUT_PRESET_GENERIC; 365 } else if (matchInputPreset(text, INPUT_PRESET_CAMCORDER)) { 366 return INPUT_PRESET_CAMCORDER; 367 } else if (matchInputPreset(text, INPUT_PRESET_VOICE_RECOGNITION)) { 368 return INPUT_PRESET_VOICE_RECOGNITION; 369 } else if (matchInputPreset(text, INPUT_PRESET_VOICE_COMMUNICATION)) { 370 return INPUT_PRESET_VOICE_COMMUNICATION; 371 } else if (matchInputPreset(text, INPUT_PRESET_UNPROCESSED)) { 372 return INPUT_PRESET_UNPROCESSED; 373 } else if (matchInputPreset(text, INPUT_PRESET_VOICE_PERFORMANCE)) { 374 return INPUT_PRESET_VOICE_PERFORMANCE; 375 } 376 return -1; 377 } 378 getChannelCount()379 public int getChannelCount() { 380 return mChannelCount; 381 } 382 setChannelCount(int channelCount)383 public void setChannelCount(int channelCount) { 384 this.mChannelCount = channelCount; 385 } 386 getSampleRate()387 public int getSampleRate() { 388 return mSampleRate; 389 } 390 setSampleRate(int sampleRate)391 public void setSampleRate(int sampleRate) { 392 this.mSampleRate = sampleRate; 393 } 394 getDeviceId()395 public int getDeviceId() { 396 return mDeviceId; 397 } 398 setDeviceId(int deviceId)399 public void setDeviceId(int deviceId) { 400 this.mDeviceId = deviceId; 401 } 402 getSessionId()403 public int getSessionId() { 404 return mSessionId; 405 } 406 setSessionId(int sessionId)407 public void setSessionId(int sessionId) { 408 mSessionId = sessionId; 409 } 410 isMMap()411 public boolean isMMap() { 412 return mMMap; 413 } 414 setMMap(boolean b)415 public void setMMap(boolean b) { mMMap = b; } 416 getNativeApi()417 public int getNativeApi() { 418 return mNativeApi; 419 } 420 setNativeApi(int nativeApi)421 public void setNativeApi(int nativeApi) { 422 mNativeApi = nativeApi; 423 } 424 setChannelConversionAllowed(boolean b)425 public void setChannelConversionAllowed(boolean b) { mChannelConversionAllowed = b; } 426 getChannelConversionAllowed()427 public boolean getChannelConversionAllowed() { 428 return mChannelConversionAllowed; 429 } 430 setFormatConversionAllowed(boolean b)431 public void setFormatConversionAllowed(boolean b) { 432 mFormatConversionAllowed = b; 433 } 434 getFormatConversionAllowed()435 public boolean getFormatConversionAllowed() { 436 return mFormatConversionAllowed; 437 } 438 setRateConversionQuality(int quality)439 public void setRateConversionQuality(int quality) { mRateConversionQuality = quality; } 440 getRateConversionQuality()441 public int getRateConversionQuality() { 442 return mRateConversionQuality; 443 } 444 445 } 446