blob: b28f7c7d9db596186dcaccef8b0468b8399e7d93 [file] [log] [blame]
Phil Burke1ce4912016-11-21 10:40:25 -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 "OboeAudio"
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 "oboe/OboeDefinitions.h"
26#include "OboeUtilities.h"
27
28using namespace android;
29
30oboe_size_bytes_t OboeConvert_formatToSizeInBytes(oboe_audio_format_t format) {
31 oboe_datatype_t dataType = OBOE_AUDIO_FORMAT_DATA_TYPE(format);
32 oboe_size_bytes_t size;
33 switch (dataType) {
34 case OBOE_AUDIO_DATATYPE_UINT8:
35 size = sizeof(uint8_t);
36 break;
37 case OBOE_AUDIO_DATATYPE_INT16:
38 size = sizeof(int16_t);
39 break;
40 case OBOE_AUDIO_DATATYPE_INT32:
41 case OBOE_AUDIO_DATATYPE_INT824:
42 size = sizeof(int32_t);
43 break;
44 case OBOE_AUDIO_DATATYPE_FLOAT32:
45 size = sizeof(float);
46 break;
47 default:
48 size = OBOE_ERROR_ILLEGAL_ARGUMENT;
49 break;
50 }
51 return size;
52}
53
54// TODO This similar to a function in audio_utils. Consider using that instead.
55void OboeConvert_floatToPcm16(const float *source, int32_t numSamples, int16_t *destination) {
56 for (int i = 0; i < numSamples; i++) {
57 float fval = source[i];
58 fval += 1.0; // to avoid discontinuity at 0.0 caused by truncation
59 fval *= 32768.0f;
60 int32_t sample = (int32_t) fval;
61 // clip to 16-bit range
62 if (sample < 0) sample = 0;
63 else if (sample > 0x0FFFF) sample = 0x0FFFF;
64 sample -= 32768; // center at zero
65 destination[i] = (int16_t) sample;
66 }
67}
68
69void OboeConvert_pcm16ToFloat(const float *source, int32_t numSamples, int16_t *destination) {
70 for (int i = 0; i < numSamples; i++) {
71 destination[i] = source[i] * (1.0f / 32768.0f);
72 }
73}
74
75oboe_result_t OboeConvert_androidToOboeError(status_t error) {
76 if (error >= 0) {
77 return error;
78 }
79 oboe_result_t result;
80 switch (error) {
81 case OK:
82 result = OBOE_OK;
83 break;
84 case INVALID_OPERATION:
85 result = OBOE_ERROR_INVALID_STATE;
86 break;
87 case BAD_VALUE:
88 result = OBOE_ERROR_UNEXPECTED_VALUE;
89 break;
90 case WOULD_BLOCK:
91 result = OBOE_ERROR_WOULD_BLOCK;
92 break;
93 // TODO add more error codes
94 default:
95 result = OBOE_ERROR_INTERNAL;
96 break;
97 }
98 return result;
99}
100
101audio_format_t OboeConvert_oboeToAndroidDataFormat(oboe_audio_format_t oboeFormat) {
102 audio_format_t androidFormat;
103 switch (oboeFormat) {
104 case OBOE_AUDIO_FORMAT_PCM16:
105 androidFormat = AUDIO_FORMAT_PCM_16_BIT;
106 break;
107 case OBOE_AUDIO_FORMAT_PCM_FLOAT:
108 androidFormat = AUDIO_FORMAT_PCM_FLOAT;
109 break;
110 case OBOE_AUDIO_FORMAT_PCM824:
111 androidFormat = AUDIO_FORMAT_PCM_8_24_BIT;
112 break;
113 case OBOE_AUDIO_FORMAT_PCM32:
114 androidFormat = AUDIO_FORMAT_PCM_32_BIT;
115 break;
116 default:
117 androidFormat = AUDIO_FORMAT_DEFAULT;
118 ALOGE("OboeConvert_oboeToAndroidDataFormat 0x%08X unrecognized", oboeFormat);
119 break;
120 }
121 return androidFormat;
122}
123
124oboe_audio_format_t OboeConvert_androidToOboeDataFormat(audio_format_t androidFormat) {
125 oboe_audio_format_t oboeFormat = OBOE_AUDIO_FORMAT_INVALID;
126 switch (androidFormat) {
127 case AUDIO_FORMAT_PCM_16_BIT:
128 oboeFormat = OBOE_AUDIO_FORMAT_PCM16;
129 break;
130 case AUDIO_FORMAT_PCM_FLOAT:
131 oboeFormat = OBOE_AUDIO_FORMAT_PCM_FLOAT;
132 break;
133 case AUDIO_FORMAT_PCM_32_BIT:
134 oboeFormat = OBOE_AUDIO_FORMAT_PCM32;
135 break;
136 case AUDIO_FORMAT_PCM_8_24_BIT:
137 oboeFormat = OBOE_AUDIO_FORMAT_PCM824;
138 break;
139 default:
140 oboeFormat = OBOE_AUDIO_FORMAT_INVALID;
141 ALOGE("OboeConvert_androidToOboeDataFormat 0x%08X unrecognized", androidFormat);
142 break;
143 }
144 return oboeFormat;
145}
146
147oboe_size_bytes_t OboeConvert_framesToBytes(oboe_size_frames_t numFrames,
148 oboe_size_bytes_t bytesPerFrame,
149 oboe_size_bytes_t *sizeInBytes) {
150 // TODO implement more elegantly
151 const int32_t maxChannels = 256; // ridiculously large
152 const oboe_size_frames_t maxBytesPerFrame = maxChannels * sizeof(float);
153 // Prevent overflow by limiting multiplicands.
154 if (bytesPerFrame > maxBytesPerFrame || numFrames > (0x3FFFFFFF / maxBytesPerFrame)) {
155 ALOGE("size overflow, numFrames = %d, frameSize = %zd", numFrames, bytesPerFrame);
156 return OBOE_ERROR_OUT_OF_RANGE;
157 }
158 *sizeInBytes = numFrames * bytesPerFrame;
159 return OBOE_OK;
160}