blob: efbbfc59f5d5fc81de80bacacfa28f831b075f65 [file] [log] [blame]
Phil Burk5ed503c2017-02-01 09:38:15 -08001/*
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
Phil Burka4eb0d82017-04-12 15:44:06 -070025#include "aaudio/AAudio.h"
Phil Burk5ed503c2017-02-01 09:38:15 -080026#include "AAudioUtilities.h"
27
28using namespace android;
29
Phil Burk3316d5e2017-02-15 11:23:01 -080030int32_t AAudioConvert_formatToSizeInBytes(aaudio_audio_format_t format) {
31 int32_t size = AAUDIO_ERROR_ILLEGAL_ARGUMENT;
Phil Burk5ed503c2017-02-01 09:38:15 -080032 switch (format) {
33 case AAUDIO_FORMAT_PCM_I16:
34 size = sizeof(int16_t);
35 break;
Phil Burk5ed503c2017-02-01 09:38:15 -080036 case AAUDIO_FORMAT_PCM_FLOAT:
37 size = sizeof(float);
38 break;
39 default:
40 break;
41 }
42 return size;
43}
44
45// TODO This similar to a function in audio_utils. Consider using that instead.
46void AAudioConvert_floatToPcm16(const float *source, int32_t numSamples, int16_t *destination) {
47 for (int i = 0; i < numSamples; i++) {
48 float fval = source[i];
49 fval += 1.0; // to avoid discontinuity at 0.0 caused by truncation
50 fval *= 32768.0f;
51 int32_t sample = (int32_t) fval;
52 // clip to 16-bit range
53 if (sample < 0) sample = 0;
54 else if (sample > 0x0FFFF) sample = 0x0FFFF;
55 sample -= 32768; // center at zero
56 destination[i] = (int16_t) sample;
57 }
58}
59
Phil Burk71f35bb2017-04-13 16:05:07 -070060void AAudioConvert_pcm16ToFloat(const int16_t *source, int32_t numSamples, float *destination) {
Phil Burk5ed503c2017-02-01 09:38:15 -080061 for (int i = 0; i < numSamples; i++) {
62 destination[i] = source[i] * (1.0f / 32768.0f);
63 }
64}
65
66status_t AAudioConvert_aaudioToAndroidStatus(aaudio_result_t result) {
67 // This covers the case for AAUDIO_OK and for positive results.
68 if (result >= 0) {
69 return result;
70 }
71 status_t status;
72 switch (result) {
73 case AAUDIO_ERROR_DISCONNECTED:
74 case AAUDIO_ERROR_INVALID_HANDLE:
75 status = DEAD_OBJECT;
76 break;
77 case AAUDIO_ERROR_INVALID_STATE:
78 status = INVALID_OPERATION;
79 break;
80 case AAUDIO_ERROR_UNEXPECTED_VALUE: // TODO redundant?
Phil Burk71f35bb2017-04-13 16:05:07 -070081 case AAUDIO_ERROR_INVALID_RATE:
82 case AAUDIO_ERROR_INVALID_FORMAT:
Phil Burk5ed503c2017-02-01 09:38:15 -080083 case AAUDIO_ERROR_ILLEGAL_ARGUMENT:
84 status = BAD_VALUE;
85 break;
86 case AAUDIO_ERROR_WOULD_BLOCK:
87 status = WOULD_BLOCK;
88 break;
89 // TODO add more result codes
90 default:
91 status = UNKNOWN_ERROR;
92 break;
93 }
94 return status;
95}
96
97aaudio_result_t AAudioConvert_androidToAAudioResult(status_t status) {
98 // This covers the case for OK and for positive result.
99 if (status >= 0) {
100 return status;
101 }
102 aaudio_result_t result;
103 switch (status) {
104 case BAD_TYPE:
105 result = AAUDIO_ERROR_INVALID_HANDLE;
106 break;
107 case DEAD_OBJECT:
Phil Burk71f35bb2017-04-13 16:05:07 -0700108 result = AAUDIO_ERROR_NO_SERVICE;
Phil Burk5ed503c2017-02-01 09:38:15 -0800109 break;
110 case INVALID_OPERATION:
111 result = AAUDIO_ERROR_INVALID_STATE;
112 break;
113 case BAD_VALUE:
114 result = AAUDIO_ERROR_UNEXPECTED_VALUE;
115 break;
116 case WOULD_BLOCK:
117 result = AAUDIO_ERROR_WOULD_BLOCK;
118 break;
119 // TODO add more status codes
120 default:
121 result = AAUDIO_ERROR_INTERNAL;
122 break;
123 }
124 return result;
125}
126
127audio_format_t AAudioConvert_aaudioToAndroidDataFormat(aaudio_audio_format_t aaudioFormat) {
128 audio_format_t androidFormat;
129 switch (aaudioFormat) {
130 case AAUDIO_FORMAT_PCM_I16:
131 androidFormat = AUDIO_FORMAT_PCM_16_BIT;
132 break;
133 case AAUDIO_FORMAT_PCM_FLOAT:
134 androidFormat = AUDIO_FORMAT_PCM_FLOAT;
135 break;
Phil Burk5ed503c2017-02-01 09:38:15 -0800136 default:
137 androidFormat = AUDIO_FORMAT_DEFAULT;
138 ALOGE("AAudioConvert_aaudioToAndroidDataFormat 0x%08X unrecognized", aaudioFormat);
139 break;
140 }
141 return androidFormat;
142}
143
144aaudio_audio_format_t AAudioConvert_androidToAAudioDataFormat(audio_format_t androidFormat) {
145 aaudio_audio_format_t aaudioFormat = AAUDIO_FORMAT_INVALID;
146 switch (androidFormat) {
147 case AUDIO_FORMAT_PCM_16_BIT:
148 aaudioFormat = AAUDIO_FORMAT_PCM_I16;
149 break;
150 case AUDIO_FORMAT_PCM_FLOAT:
151 aaudioFormat = AAUDIO_FORMAT_PCM_FLOAT;
152 break;
Phil Burk5ed503c2017-02-01 09:38:15 -0800153 default:
154 aaudioFormat = AAUDIO_FORMAT_INVALID;
155 ALOGE("AAudioConvert_androidToAAudioDataFormat 0x%08X unrecognized", androidFormat);
156 break;
157 }
158 return aaudioFormat;
159}
160
Phil Burk3316d5e2017-02-15 11:23:01 -0800161int32_t AAudioConvert_framesToBytes(int32_t numFrames,
162 int32_t bytesPerFrame,
163 int32_t *sizeInBytes) {
Phil Burk5ed503c2017-02-01 09:38:15 -0800164 // TODO implement more elegantly
165 const int32_t maxChannels = 256; // ridiculously large
Phil Burk3316d5e2017-02-15 11:23:01 -0800166 const int32_t maxBytesPerFrame = maxChannels * sizeof(float);
Phil Burk5ed503c2017-02-01 09:38:15 -0800167 // Prevent overflow by limiting multiplicands.
168 if (bytesPerFrame > maxBytesPerFrame || numFrames > (0x3FFFFFFF / maxBytesPerFrame)) {
169 ALOGE("size overflow, numFrames = %d, frameSize = %zd", numFrames, bytesPerFrame);
170 return AAUDIO_ERROR_OUT_OF_RANGE;
171 }
172 *sizeInBytes = numFrames * bytesPerFrame;
173 return AAUDIO_OK;
174}