AAudioUtilities.cpp revision a4eb0d86a29be2763be5fac51727858d5095794b
1/* 2 * Copyright 2016 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#define LOG_TAG "AAudio" 18//#define LOG_NDEBUG 0 19#include <utils/Log.h> 20 21#include <stdint.h> 22#include <sys/types.h> 23#include <utils/Errors.h> 24 25#include "aaudio/AAudio.h" 26#include "AAudioUtilities.h" 27 28using namespace android; 29 30int32_t AAudioConvert_formatToSizeInBytes(aaudio_audio_format_t format) { 31 int32_t size = AAUDIO_ERROR_ILLEGAL_ARGUMENT; 32 switch (format) { 33 case AAUDIO_FORMAT_PCM_I16: 34 size = sizeof(int16_t); 35 break; 36 case AAUDIO_FORMAT_PCM_I32: 37 case AAUDIO_FORMAT_PCM_I8_24: 38 size = sizeof(int32_t); 39 break; 40 case AAUDIO_FORMAT_PCM_FLOAT: 41 size = sizeof(float); 42 break; 43 default: 44 break; 45 } 46 return size; 47} 48 49// TODO This similar to a function in audio_utils. Consider using that instead. 50void AAudioConvert_floatToPcm16(const float *source, int32_t numSamples, int16_t *destination) { 51 for (int i = 0; i < numSamples; i++) { 52 float fval = source[i]; 53 fval += 1.0; // to avoid discontinuity at 0.0 caused by truncation 54 fval *= 32768.0f; 55 int32_t sample = (int32_t) fval; 56 // clip to 16-bit range 57 if (sample < 0) sample = 0; 58 else if (sample > 0x0FFFF) sample = 0x0FFFF; 59 sample -= 32768; // center at zero 60 destination[i] = (int16_t) sample; 61 } 62} 63 64void AAudioConvert_pcm16ToFloat(const float *source, int32_t numSamples, int16_t *destination) { 65 for (int i = 0; i < numSamples; i++) { 66 destination[i] = source[i] * (1.0f / 32768.0f); 67 } 68} 69 70status_t AAudioConvert_aaudioToAndroidStatus(aaudio_result_t result) { 71 // This covers the case for AAUDIO_OK and for positive results. 72 if (result >= 0) { 73 return result; 74 } 75 status_t status; 76 switch (result) { 77 case AAUDIO_ERROR_DISCONNECTED: 78 case AAUDIO_ERROR_INVALID_HANDLE: 79 status = DEAD_OBJECT; 80 break; 81 case AAUDIO_ERROR_INVALID_STATE: 82 status = INVALID_OPERATION; 83 break; 84 case AAUDIO_ERROR_UNEXPECTED_VALUE: // TODO redundant? 85 case AAUDIO_ERROR_ILLEGAL_ARGUMENT: 86 status = BAD_VALUE; 87 break; 88 case AAUDIO_ERROR_WOULD_BLOCK: 89 status = WOULD_BLOCK; 90 break; 91 // TODO add more result codes 92 default: 93 status = UNKNOWN_ERROR; 94 break; 95 } 96 return status; 97} 98 99aaudio_result_t AAudioConvert_androidToAAudioResult(status_t status) { 100 // This covers the case for OK and for positive result. 101 if (status >= 0) { 102 return status; 103 } 104 aaudio_result_t result; 105 switch (status) { 106 case BAD_TYPE: 107 result = AAUDIO_ERROR_INVALID_HANDLE; 108 break; 109 case DEAD_OBJECT: 110 result = AAUDIO_ERROR_DISCONNECTED; 111 break; 112 case INVALID_OPERATION: 113 result = AAUDIO_ERROR_INVALID_STATE; 114 break; 115 case BAD_VALUE: 116 result = AAUDIO_ERROR_UNEXPECTED_VALUE; 117 break; 118 case WOULD_BLOCK: 119 result = AAUDIO_ERROR_WOULD_BLOCK; 120 break; 121 // TODO add more status codes 122 default: 123 result = AAUDIO_ERROR_INTERNAL; 124 break; 125 } 126 return result; 127} 128 129audio_format_t AAudioConvert_aaudioToAndroidDataFormat(aaudio_audio_format_t aaudioFormat) { 130 audio_format_t androidFormat; 131 switch (aaudioFormat) { 132 case AAUDIO_FORMAT_PCM_I16: 133 androidFormat = AUDIO_FORMAT_PCM_16_BIT; 134 break; 135 case AAUDIO_FORMAT_PCM_FLOAT: 136 androidFormat = AUDIO_FORMAT_PCM_FLOAT; 137 break; 138 case AAUDIO_FORMAT_PCM_I8_24: 139 androidFormat = AUDIO_FORMAT_PCM_8_24_BIT; 140 break; 141 case AAUDIO_FORMAT_PCM_I32: 142 androidFormat = AUDIO_FORMAT_PCM_32_BIT; 143 break; 144 default: 145 androidFormat = AUDIO_FORMAT_DEFAULT; 146 ALOGE("AAudioConvert_aaudioToAndroidDataFormat 0x%08X unrecognized", aaudioFormat); 147 break; 148 } 149 return androidFormat; 150} 151 152aaudio_audio_format_t AAudioConvert_androidToAAudioDataFormat(audio_format_t androidFormat) { 153 aaudio_audio_format_t aaudioFormat = AAUDIO_FORMAT_INVALID; 154 switch (androidFormat) { 155 case AUDIO_FORMAT_PCM_16_BIT: 156 aaudioFormat = AAUDIO_FORMAT_PCM_I16; 157 break; 158 case AUDIO_FORMAT_PCM_FLOAT: 159 aaudioFormat = AAUDIO_FORMAT_PCM_FLOAT; 160 break; 161 case AUDIO_FORMAT_PCM_32_BIT: 162 aaudioFormat = AAUDIO_FORMAT_PCM_I32; 163 break; 164 case AUDIO_FORMAT_PCM_8_24_BIT: 165 aaudioFormat = AAUDIO_FORMAT_PCM_I8_24; 166 break; 167 default: 168 aaudioFormat = AAUDIO_FORMAT_INVALID; 169 ALOGE("AAudioConvert_androidToAAudioDataFormat 0x%08X unrecognized", androidFormat); 170 break; 171 } 172 return aaudioFormat; 173} 174 175int32_t AAudioConvert_framesToBytes(int32_t numFrames, 176 int32_t bytesPerFrame, 177 int32_t *sizeInBytes) { 178 // TODO implement more elegantly 179 const int32_t maxChannels = 256; // ridiculously large 180 const int32_t maxBytesPerFrame = maxChannels * sizeof(float); 181 // Prevent overflow by limiting multiplicands. 182 if (bytesPerFrame > maxBytesPerFrame || numFrames > (0x3FFFFFFF / maxBytesPerFrame)) { 183 ALOGE("size overflow, numFrames = %d, frameSize = %zd", numFrames, bytesPerFrame); 184 return AAUDIO_ERROR_OUT_OF_RANGE; 185 } 186 *sizeInBytes = numFrames * bytesPerFrame; 187 return AAUDIO_OK; 188} 189