1*b9df5ad1SAndroid Build Coastguard Worker /*
2*b9df5ad1SAndroid Build Coastguard Worker * Copyright 2017 The Android Open Source Project
3*b9df5ad1SAndroid Build Coastguard Worker *
4*b9df5ad1SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*b9df5ad1SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*b9df5ad1SAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*b9df5ad1SAndroid Build Coastguard Worker *
8*b9df5ad1SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*b9df5ad1SAndroid Build Coastguard Worker *
10*b9df5ad1SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*b9df5ad1SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*b9df5ad1SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*b9df5ad1SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*b9df5ad1SAndroid Build Coastguard Worker * limitations under the License.
15*b9df5ad1SAndroid Build Coastguard Worker */
16*b9df5ad1SAndroid Build Coastguard Worker
17*b9df5ad1SAndroid Build Coastguard Worker // #define LOG_NDEBUG 0
18*b9df5ad1SAndroid Build Coastguard Worker #define LOG_TAG "audio_utils_power"
19*b9df5ad1SAndroid Build Coastguard Worker #include <log/log.h>
20*b9df5ad1SAndroid Build Coastguard Worker
21*b9df5ad1SAndroid Build Coastguard Worker #include <audio_utils/power.h>
22*b9df5ad1SAndroid Build Coastguard Worker
23*b9df5ad1SAndroid Build Coastguard Worker #include <audio_utils/intrinsic_utils.h>
24*b9df5ad1SAndroid Build Coastguard Worker #include <audio_utils/primitives.h>
25*b9df5ad1SAndroid Build Coastguard Worker
26*b9df5ad1SAndroid Build Coastguard Worker #if defined(__aarch64__) || defined(__ARM_NEON__)
27*b9df5ad1SAndroid Build Coastguard Worker #define USE_NEON
28*b9df5ad1SAndroid Build Coastguard Worker #endif
29*b9df5ad1SAndroid Build Coastguard Worker
30*b9df5ad1SAndroid Build Coastguard Worker namespace {
31*b9df5ad1SAndroid Build Coastguard Worker
isFormatSupported(audio_format_t format)32*b9df5ad1SAndroid Build Coastguard Worker constexpr inline bool isFormatSupported(audio_format_t format) {
33*b9df5ad1SAndroid Build Coastguard Worker switch (format) {
34*b9df5ad1SAndroid Build Coastguard Worker case AUDIO_FORMAT_PCM_8_BIT:
35*b9df5ad1SAndroid Build Coastguard Worker case AUDIO_FORMAT_PCM_16_BIT:
36*b9df5ad1SAndroid Build Coastguard Worker case AUDIO_FORMAT_PCM_24_BIT_PACKED:
37*b9df5ad1SAndroid Build Coastguard Worker case AUDIO_FORMAT_PCM_8_24_BIT:
38*b9df5ad1SAndroid Build Coastguard Worker case AUDIO_FORMAT_PCM_32_BIT:
39*b9df5ad1SAndroid Build Coastguard Worker case AUDIO_FORMAT_PCM_FLOAT:
40*b9df5ad1SAndroid Build Coastguard Worker return true;
41*b9df5ad1SAndroid Build Coastguard Worker default:
42*b9df5ad1SAndroid Build Coastguard Worker return false;
43*b9df5ad1SAndroid Build Coastguard Worker }
44*b9df5ad1SAndroid Build Coastguard Worker }
45*b9df5ad1SAndroid Build Coastguard Worker
46*b9df5ad1SAndroid Build Coastguard Worker template <typename T>
getPtrPtrValueAndIncrement(const void ** data)47*b9df5ad1SAndroid Build Coastguard Worker inline T getPtrPtrValueAndIncrement(const void **data)
48*b9df5ad1SAndroid Build Coastguard Worker {
49*b9df5ad1SAndroid Build Coastguard Worker return *(*reinterpret_cast<const T **>(data))++;
50*b9df5ad1SAndroid Build Coastguard Worker }
51*b9df5ad1SAndroid Build Coastguard Worker
52*b9df5ad1SAndroid Build Coastguard Worker template <audio_format_t FORMAT>
convertToFloatAndIncrement(const void ** data)53*b9df5ad1SAndroid Build Coastguard Worker inline float convertToFloatAndIncrement(const void **data)
54*b9df5ad1SAndroid Build Coastguard Worker {
55*b9df5ad1SAndroid Build Coastguard Worker switch (FORMAT) {
56*b9df5ad1SAndroid Build Coastguard Worker case AUDIO_FORMAT_PCM_8_BIT:
57*b9df5ad1SAndroid Build Coastguard Worker return float_from_u8(getPtrPtrValueAndIncrement<uint8_t>(data));
58*b9df5ad1SAndroid Build Coastguard Worker
59*b9df5ad1SAndroid Build Coastguard Worker case AUDIO_FORMAT_PCM_16_BIT:
60*b9df5ad1SAndroid Build Coastguard Worker return float_from_i16(getPtrPtrValueAndIncrement<int16_t>(data));
61*b9df5ad1SAndroid Build Coastguard Worker
62*b9df5ad1SAndroid Build Coastguard Worker case AUDIO_FORMAT_PCM_24_BIT_PACKED: {
63*b9df5ad1SAndroid Build Coastguard Worker const uint8_t *uptr = reinterpret_cast<const uint8_t *>(*data);
64*b9df5ad1SAndroid Build Coastguard Worker *data = uptr + 3;
65*b9df5ad1SAndroid Build Coastguard Worker return float_from_p24(uptr);
66*b9df5ad1SAndroid Build Coastguard Worker }
67*b9df5ad1SAndroid Build Coastguard Worker
68*b9df5ad1SAndroid Build Coastguard Worker case AUDIO_FORMAT_PCM_8_24_BIT:
69*b9df5ad1SAndroid Build Coastguard Worker return float_from_q8_23(getPtrPtrValueAndIncrement<int32_t>(data));
70*b9df5ad1SAndroid Build Coastguard Worker
71*b9df5ad1SAndroid Build Coastguard Worker case AUDIO_FORMAT_PCM_32_BIT:
72*b9df5ad1SAndroid Build Coastguard Worker return float_from_i32(getPtrPtrValueAndIncrement<int32_t>(data));
73*b9df5ad1SAndroid Build Coastguard Worker
74*b9df5ad1SAndroid Build Coastguard Worker case AUDIO_FORMAT_PCM_FLOAT:
75*b9df5ad1SAndroid Build Coastguard Worker return getPtrPtrValueAndIncrement<float>(data);
76*b9df5ad1SAndroid Build Coastguard Worker
77*b9df5ad1SAndroid Build Coastguard Worker default:
78*b9df5ad1SAndroid Build Coastguard Worker // static_assert cannot use false because the compiler may interpret it
79*b9df5ad1SAndroid Build Coastguard Worker // even though this code path may never be taken.
80*b9df5ad1SAndroid Build Coastguard Worker static_assert(isFormatSupported(FORMAT), "unsupported format");
81*b9df5ad1SAndroid Build Coastguard Worker }
82*b9df5ad1SAndroid Build Coastguard Worker }
83*b9df5ad1SAndroid Build Coastguard Worker
84*b9df5ad1SAndroid Build Coastguard Worker // used to normalize integer fixed point value to the floating point equivalent.
85*b9df5ad1SAndroid Build Coastguard Worker template <audio_format_t FORMAT>
normalizeAmplitude()86*b9df5ad1SAndroid Build Coastguard Worker constexpr inline float normalizeAmplitude()
87*b9df5ad1SAndroid Build Coastguard Worker {
88*b9df5ad1SAndroid Build Coastguard Worker switch (FORMAT) {
89*b9df5ad1SAndroid Build Coastguard Worker case AUDIO_FORMAT_PCM_8_BIT:
90*b9df5ad1SAndroid Build Coastguard Worker return 1.f / (1 << 7);
91*b9df5ad1SAndroid Build Coastguard Worker
92*b9df5ad1SAndroid Build Coastguard Worker case AUDIO_FORMAT_PCM_16_BIT:
93*b9df5ad1SAndroid Build Coastguard Worker return 1.f / (1 << 15);
94*b9df5ad1SAndroid Build Coastguard Worker
95*b9df5ad1SAndroid Build Coastguard Worker case AUDIO_FORMAT_PCM_24_BIT_PACKED: // fall through
96*b9df5ad1SAndroid Build Coastguard Worker case AUDIO_FORMAT_PCM_8_24_BIT:
97*b9df5ad1SAndroid Build Coastguard Worker return 1.f / (1 << 23);
98*b9df5ad1SAndroid Build Coastguard Worker
99*b9df5ad1SAndroid Build Coastguard Worker case AUDIO_FORMAT_PCM_32_BIT:
100*b9df5ad1SAndroid Build Coastguard Worker return 1.f / (1U << 31);
101*b9df5ad1SAndroid Build Coastguard Worker
102*b9df5ad1SAndroid Build Coastguard Worker case AUDIO_FORMAT_PCM_FLOAT:
103*b9df5ad1SAndroid Build Coastguard Worker return 1.f;
104*b9df5ad1SAndroid Build Coastguard Worker
105*b9df5ad1SAndroid Build Coastguard Worker default:
106*b9df5ad1SAndroid Build Coastguard Worker // static_assert cannot use false because the compiler may interpret it
107*b9df5ad1SAndroid Build Coastguard Worker // even though this code path may never be taken.
108*b9df5ad1SAndroid Build Coastguard Worker static_assert(isFormatSupported(FORMAT), "unsupported format");
109*b9df5ad1SAndroid Build Coastguard Worker }
110*b9df5ad1SAndroid Build Coastguard Worker }
111*b9df5ad1SAndroid Build Coastguard Worker
112*b9df5ad1SAndroid Build Coastguard Worker template <audio_format_t FORMAT>
normalizeEnergy()113*b9df5ad1SAndroid Build Coastguard Worker constexpr inline float normalizeEnergy()
114*b9df5ad1SAndroid Build Coastguard Worker {
115*b9df5ad1SAndroid Build Coastguard Worker const float val = normalizeAmplitude<FORMAT>();
116*b9df5ad1SAndroid Build Coastguard Worker return val * val;
117*b9df5ad1SAndroid Build Coastguard Worker }
118*b9df5ad1SAndroid Build Coastguard Worker
119*b9df5ad1SAndroid Build Coastguard Worker template <audio_format_t FORMAT>
energyMonoRef(const void * amplitudes,size_t size)120*b9df5ad1SAndroid Build Coastguard Worker inline float energyMonoRef(const void *amplitudes, size_t size)
121*b9df5ad1SAndroid Build Coastguard Worker {
122*b9df5ad1SAndroid Build Coastguard Worker float accum(0.f);
123*b9df5ad1SAndroid Build Coastguard Worker for (size_t i = 0; i < size; ++i) {
124*b9df5ad1SAndroid Build Coastguard Worker const float amplitude = convertToFloatAndIncrement<FORMAT>(&litudes);
125*b9df5ad1SAndroid Build Coastguard Worker accum += amplitude * amplitude;
126*b9df5ad1SAndroid Build Coastguard Worker }
127*b9df5ad1SAndroid Build Coastguard Worker return accum;
128*b9df5ad1SAndroid Build Coastguard Worker }
129*b9df5ad1SAndroid Build Coastguard Worker
130*b9df5ad1SAndroid Build Coastguard Worker template <audio_format_t FORMAT>
energyRef(const void * amplitudes,size_t size,size_t numChannels,float * out)131*b9df5ad1SAndroid Build Coastguard Worker inline void energyRef(const void *amplitudes, size_t size, size_t numChannels, float* out)
132*b9df5ad1SAndroid Build Coastguard Worker {
133*b9df5ad1SAndroid Build Coastguard Worker const size_t framesSize = size / numChannels;
134*b9df5ad1SAndroid Build Coastguard Worker for (size_t i = 0; i < framesSize; ++i) {
135*b9df5ad1SAndroid Build Coastguard Worker for (size_t c = 0; c < numChannels; ++c) {
136*b9df5ad1SAndroid Build Coastguard Worker const float amplitude = convertToFloatAndIncrement<FORMAT>(&litudes);
137*b9df5ad1SAndroid Build Coastguard Worker out[c] += amplitude * amplitude;
138*b9df5ad1SAndroid Build Coastguard Worker }
139*b9df5ad1SAndroid Build Coastguard Worker }
140*b9df5ad1SAndroid Build Coastguard Worker }
141*b9df5ad1SAndroid Build Coastguard Worker
142*b9df5ad1SAndroid Build Coastguard Worker template <audio_format_t FORMAT>
energyMono(const void * amplitudes,size_t size)143*b9df5ad1SAndroid Build Coastguard Worker inline float energyMono(const void *amplitudes, size_t size)
144*b9df5ad1SAndroid Build Coastguard Worker {
145*b9df5ad1SAndroid Build Coastguard Worker return energyMonoRef<FORMAT>(amplitudes, size);
146*b9df5ad1SAndroid Build Coastguard Worker }
147*b9df5ad1SAndroid Build Coastguard Worker
148*b9df5ad1SAndroid Build Coastguard Worker // TODO: optimize with NEON
149*b9df5ad1SAndroid Build Coastguard Worker template <audio_format_t FORMAT>
energy(const void * amplitudes,size_t size,size_t numChannels,float * out)150*b9df5ad1SAndroid Build Coastguard Worker inline void energy(const void *amplitudes, size_t size, size_t numChannels, float* out)
151*b9df5ad1SAndroid Build Coastguard Worker {
152*b9df5ad1SAndroid Build Coastguard Worker energyRef<FORMAT>(amplitudes, size, numChannels, out);
153*b9df5ad1SAndroid Build Coastguard Worker }
154*b9df5ad1SAndroid Build Coastguard Worker
155*b9df5ad1SAndroid Build Coastguard Worker // TODO(b/323611666) in some cases having a large kVectorWidth generic internal array is
156*b9df5ad1SAndroid Build Coastguard Worker // faster than the NEON intrinsic version. Optimize this.
157*b9df5ad1SAndroid Build Coastguard Worker #ifdef USE_NEON
158*b9df5ad1SAndroid Build Coastguard Worker // The type conversion appears faster if we use a neon accumulator type.
159*b9df5ad1SAndroid Build Coastguard Worker // Using a vector length of 4 triggers the code below to use the neon type float32x4_t.
160*b9df5ad1SAndroid Build Coastguard Worker constexpr size_t kVectorWidth16 = 4; // neon float32x4_t
161*b9df5ad1SAndroid Build Coastguard Worker constexpr size_t kVectorWidth32 = 4; // neon float32x4_t
162*b9df5ad1SAndroid Build Coastguard Worker constexpr size_t kVectorWidthFloat = 8; // use generic intrinsics for float.
163*b9df5ad1SAndroid Build Coastguard Worker #else
164*b9df5ad1SAndroid Build Coastguard Worker constexpr size_t kVectorWidth16 = 8;
165*b9df5ad1SAndroid Build Coastguard Worker constexpr size_t kVectorWidth32 = 8;
166*b9df5ad1SAndroid Build Coastguard Worker constexpr size_t kVectorWidthFloat = 8;
167*b9df5ad1SAndroid Build Coastguard Worker #endif
168*b9df5ad1SAndroid Build Coastguard Worker
169*b9df5ad1SAndroid Build Coastguard Worker template <typename Scalar, size_t N>
energyMonoVector(const void * amplitudes,size_t size)170*b9df5ad1SAndroid Build Coastguard Worker inline float energyMonoVector(const void *amplitudes, size_t size)
171*b9df5ad1SAndroid Build Coastguard Worker { // check pointer validity, must be aligned with scalar type.
172*b9df5ad1SAndroid Build Coastguard Worker const Scalar *samplitudes = reinterpret_cast<const Scalar *>(amplitudes);
173*b9df5ad1SAndroid Build Coastguard Worker LOG_ALWAYS_FATAL_IF((uintptr_t)samplitudes % alignof(Scalar) != 0,
174*b9df5ad1SAndroid Build Coastguard Worker "Non-element aligned address: %p %zu", samplitudes, alignof(Scalar));
175*b9df5ad1SAndroid Build Coastguard Worker
176*b9df5ad1SAndroid Build Coastguard Worker float accumulator = 0;
177*b9df5ad1SAndroid Build Coastguard Worker
178*b9df5ad1SAndroid Build Coastguard Worker #ifdef USE_NEON
179*b9df5ad1SAndroid Build Coastguard Worker using AccumulatorType = std::conditional_t<N == 4, float32x4_t,
180*b9df5ad1SAndroid Build Coastguard Worker android::audio_utils::intrinsics::internal_array_t<float, N>>;
181*b9df5ad1SAndroid Build Coastguard Worker #else
182*b9df5ad1SAndroid Build Coastguard Worker using AccumulatorType = android::audio_utils::intrinsics::internal_array_t<float, N>;
183*b9df5ad1SAndroid Build Coastguard Worker #endif
184*b9df5ad1SAndroid Build Coastguard Worker
185*b9df5ad1SAndroid Build Coastguard Worker // seems that loading input data is fine using our generic intrinsic.
186*b9df5ad1SAndroid Build Coastguard Worker using Vector = android::audio_utils::intrinsics::internal_array_t<Scalar, N>;
187*b9df5ad1SAndroid Build Coastguard Worker
188*b9df5ad1SAndroid Build Coastguard Worker // handle pointer unaligned to vector type.
189*b9df5ad1SAndroid Build Coastguard Worker while ((uintptr_t)samplitudes % sizeof(Vector) != 0 /* compiler optimized */ && size > 0) {
190*b9df5ad1SAndroid Build Coastguard Worker const float amp = (float)*samplitudes++;
191*b9df5ad1SAndroid Build Coastguard Worker accumulator += amp * amp;
192*b9df5ad1SAndroid Build Coastguard Worker --size;
193*b9df5ad1SAndroid Build Coastguard Worker }
194*b9df5ad1SAndroid Build Coastguard Worker
195*b9df5ad1SAndroid Build Coastguard Worker // samplitudes is now adjusted for proper vector alignment, cast to Vector *
196*b9df5ad1SAndroid Build Coastguard Worker const Vector *vamplitudes = reinterpret_cast<const Vector *>(samplitudes);
197*b9df5ad1SAndroid Build Coastguard Worker
198*b9df5ad1SAndroid Build Coastguard Worker // clear vector accumulator
199*b9df5ad1SAndroid Build Coastguard Worker AccumulatorType accum{};
200*b9df5ad1SAndroid Build Coastguard Worker
201*b9df5ad1SAndroid Build Coastguard Worker // iterate over array getting sum of squares in vectorLength lanes.
202*b9df5ad1SAndroid Build Coastguard Worker size_t i;
203*b9df5ad1SAndroid Build Coastguard Worker const size_t limit = size - size % N;
204*b9df5ad1SAndroid Build Coastguard Worker for (i = 0; i < limit; i += N) {
205*b9df5ad1SAndroid Build Coastguard Worker const auto famplitude = vconvert<AccumulatorType>(*vamplitudes++);
206*b9df5ad1SAndroid Build Coastguard Worker accum = android::audio_utils::intrinsics::vmla(accum, famplitude, famplitude);
207*b9df5ad1SAndroid Build Coastguard Worker }
208*b9df5ad1SAndroid Build Coastguard Worker
209*b9df5ad1SAndroid Build Coastguard Worker // add all components of the vector.
210*b9df5ad1SAndroid Build Coastguard Worker accumulator += android::audio_utils::intrinsics::vaddv(accum);
211*b9df5ad1SAndroid Build Coastguard Worker
212*b9df5ad1SAndroid Build Coastguard Worker // accumulate any trailing elements too small for vector size
213*b9df5ad1SAndroid Build Coastguard Worker for (; i < size; ++i) {
214*b9df5ad1SAndroid Build Coastguard Worker const float amp = (float)samplitudes[i];
215*b9df5ad1SAndroid Build Coastguard Worker accumulator += amp * amp;
216*b9df5ad1SAndroid Build Coastguard Worker }
217*b9df5ad1SAndroid Build Coastguard Worker return accumulator;
218*b9df5ad1SAndroid Build Coastguard Worker }
219*b9df5ad1SAndroid Build Coastguard Worker
220*b9df5ad1SAndroid Build Coastguard Worker template <>
energyMono(const void * amplitudes,size_t size)221*b9df5ad1SAndroid Build Coastguard Worker inline float energyMono<AUDIO_FORMAT_PCM_FLOAT>(const void *amplitudes, size_t size)
222*b9df5ad1SAndroid Build Coastguard Worker {
223*b9df5ad1SAndroid Build Coastguard Worker return energyMonoVector<float, kVectorWidthFloat>(amplitudes, size);
224*b9df5ad1SAndroid Build Coastguard Worker }
225*b9df5ad1SAndroid Build Coastguard Worker
226*b9df5ad1SAndroid Build Coastguard Worker template <>
energyMono(const void * amplitudes,size_t size)227*b9df5ad1SAndroid Build Coastguard Worker inline float energyMono<AUDIO_FORMAT_PCM_16_BIT>(const void *amplitudes, size_t size)
228*b9df5ad1SAndroid Build Coastguard Worker {
229*b9df5ad1SAndroid Build Coastguard Worker return energyMonoVector<int16_t, kVectorWidth16>(amplitudes, size)
230*b9df5ad1SAndroid Build Coastguard Worker * normalizeEnergy<AUDIO_FORMAT_PCM_16_BIT>();
231*b9df5ad1SAndroid Build Coastguard Worker }
232*b9df5ad1SAndroid Build Coastguard Worker
233*b9df5ad1SAndroid Build Coastguard Worker // fast int32_t power computation for PCM_32
234*b9df5ad1SAndroid Build Coastguard Worker template <>
energyMono(const void * amplitudes,size_t size)235*b9df5ad1SAndroid Build Coastguard Worker inline float energyMono<AUDIO_FORMAT_PCM_32_BIT>(const void *amplitudes, size_t size)
236*b9df5ad1SAndroid Build Coastguard Worker {
237*b9df5ad1SAndroid Build Coastguard Worker return energyMonoVector<int32_t, kVectorWidth32>(amplitudes, size)
238*b9df5ad1SAndroid Build Coastguard Worker * normalizeEnergy<AUDIO_FORMAT_PCM_32_BIT>();
239*b9df5ad1SAndroid Build Coastguard Worker }
240*b9df5ad1SAndroid Build Coastguard Worker
241*b9df5ad1SAndroid Build Coastguard Worker // fast int32_t power computation for PCM_8_24 (essentially identical to PCM_32 above)
242*b9df5ad1SAndroid Build Coastguard Worker template <>
energyMono(const void * amplitudes,size_t size)243*b9df5ad1SAndroid Build Coastguard Worker inline float energyMono<AUDIO_FORMAT_PCM_8_24_BIT>(const void *amplitudes, size_t size)
244*b9df5ad1SAndroid Build Coastguard Worker {
245*b9df5ad1SAndroid Build Coastguard Worker return energyMonoVector<int32_t, kVectorWidth32>(amplitudes, size)
246*b9df5ad1SAndroid Build Coastguard Worker * normalizeEnergy<AUDIO_FORMAT_PCM_8_24_BIT>();
247*b9df5ad1SAndroid Build Coastguard Worker }
248*b9df5ad1SAndroid Build Coastguard Worker
249*b9df5ad1SAndroid Build Coastguard Worker } // namespace
250*b9df5ad1SAndroid Build Coastguard Worker
audio_utils_compute_energy_mono(const void * buffer,audio_format_t format,size_t samples)251*b9df5ad1SAndroid Build Coastguard Worker float audio_utils_compute_energy_mono(const void *buffer, audio_format_t format, size_t samples)
252*b9df5ad1SAndroid Build Coastguard Worker {
253*b9df5ad1SAndroid Build Coastguard Worker switch (format) {
254*b9df5ad1SAndroid Build Coastguard Worker case AUDIO_FORMAT_PCM_8_BIT:
255*b9df5ad1SAndroid Build Coastguard Worker return energyMono<AUDIO_FORMAT_PCM_8_BIT>(buffer, samples);
256*b9df5ad1SAndroid Build Coastguard Worker
257*b9df5ad1SAndroid Build Coastguard Worker case AUDIO_FORMAT_PCM_16_BIT:
258*b9df5ad1SAndroid Build Coastguard Worker return energyMono<AUDIO_FORMAT_PCM_16_BIT>(buffer, samples);
259*b9df5ad1SAndroid Build Coastguard Worker
260*b9df5ad1SAndroid Build Coastguard Worker case AUDIO_FORMAT_PCM_24_BIT_PACKED:
261*b9df5ad1SAndroid Build Coastguard Worker return energyMono<AUDIO_FORMAT_PCM_24_BIT_PACKED>(buffer, samples);
262*b9df5ad1SAndroid Build Coastguard Worker
263*b9df5ad1SAndroid Build Coastguard Worker case AUDIO_FORMAT_PCM_8_24_BIT:
264*b9df5ad1SAndroid Build Coastguard Worker return energyMono<AUDIO_FORMAT_PCM_8_24_BIT>(buffer, samples);
265*b9df5ad1SAndroid Build Coastguard Worker
266*b9df5ad1SAndroid Build Coastguard Worker case AUDIO_FORMAT_PCM_32_BIT:
267*b9df5ad1SAndroid Build Coastguard Worker return energyMono<AUDIO_FORMAT_PCM_32_BIT>(buffer, samples);
268*b9df5ad1SAndroid Build Coastguard Worker
269*b9df5ad1SAndroid Build Coastguard Worker case AUDIO_FORMAT_PCM_FLOAT:
270*b9df5ad1SAndroid Build Coastguard Worker return energyMono<AUDIO_FORMAT_PCM_FLOAT>(buffer, samples);
271*b9df5ad1SAndroid Build Coastguard Worker
272*b9df5ad1SAndroid Build Coastguard Worker default:
273*b9df5ad1SAndroid Build Coastguard Worker LOG_ALWAYS_FATAL("invalid format: %#x", format);
274*b9df5ad1SAndroid Build Coastguard Worker }
275*b9df5ad1SAndroid Build Coastguard Worker }
276*b9df5ad1SAndroid Build Coastguard Worker
audio_utils_accumulate_energy(const void * buffer,audio_format_t format,size_t samples,size_t numChannels,float * out)277*b9df5ad1SAndroid Build Coastguard Worker void audio_utils_accumulate_energy(const void* buffer,
278*b9df5ad1SAndroid Build Coastguard Worker audio_format_t format,
279*b9df5ad1SAndroid Build Coastguard Worker size_t samples,
280*b9df5ad1SAndroid Build Coastguard Worker size_t numChannels,
281*b9df5ad1SAndroid Build Coastguard Worker float* out)
282*b9df5ad1SAndroid Build Coastguard Worker {
283*b9df5ad1SAndroid Build Coastguard Worker switch (format) {
284*b9df5ad1SAndroid Build Coastguard Worker case AUDIO_FORMAT_PCM_8_BIT:
285*b9df5ad1SAndroid Build Coastguard Worker energy<AUDIO_FORMAT_PCM_8_BIT>(buffer, samples, numChannels, out);
286*b9df5ad1SAndroid Build Coastguard Worker break;
287*b9df5ad1SAndroid Build Coastguard Worker
288*b9df5ad1SAndroid Build Coastguard Worker case AUDIO_FORMAT_PCM_16_BIT:
289*b9df5ad1SAndroid Build Coastguard Worker energy<AUDIO_FORMAT_PCM_16_BIT>(buffer, samples, numChannels, out);
290*b9df5ad1SAndroid Build Coastguard Worker break;
291*b9df5ad1SAndroid Build Coastguard Worker
292*b9df5ad1SAndroid Build Coastguard Worker case AUDIO_FORMAT_PCM_24_BIT_PACKED:
293*b9df5ad1SAndroid Build Coastguard Worker energy<AUDIO_FORMAT_PCM_24_BIT_PACKED>(buffer, samples, numChannels, out);
294*b9df5ad1SAndroid Build Coastguard Worker break;
295*b9df5ad1SAndroid Build Coastguard Worker
296*b9df5ad1SAndroid Build Coastguard Worker case AUDIO_FORMAT_PCM_8_24_BIT:
297*b9df5ad1SAndroid Build Coastguard Worker energy<AUDIO_FORMAT_PCM_8_24_BIT>(buffer, samples, numChannels, out);
298*b9df5ad1SAndroid Build Coastguard Worker break;
299*b9df5ad1SAndroid Build Coastguard Worker
300*b9df5ad1SAndroid Build Coastguard Worker case AUDIO_FORMAT_PCM_32_BIT:
301*b9df5ad1SAndroid Build Coastguard Worker energy<AUDIO_FORMAT_PCM_32_BIT>(buffer, samples, numChannels, out);
302*b9df5ad1SAndroid Build Coastguard Worker break;
303*b9df5ad1SAndroid Build Coastguard Worker
304*b9df5ad1SAndroid Build Coastguard Worker case AUDIO_FORMAT_PCM_FLOAT:
305*b9df5ad1SAndroid Build Coastguard Worker energy<AUDIO_FORMAT_PCM_FLOAT>(buffer, samples, numChannels, out);
306*b9df5ad1SAndroid Build Coastguard Worker break;
307*b9df5ad1SAndroid Build Coastguard Worker
308*b9df5ad1SAndroid Build Coastguard Worker default:
309*b9df5ad1SAndroid Build Coastguard Worker LOG_ALWAYS_FATAL("invalid format: %#x", format);
310*b9df5ad1SAndroid Build Coastguard Worker }
311*b9df5ad1SAndroid Build Coastguard Worker }
312*b9df5ad1SAndroid Build Coastguard Worker
audio_utils_compute_power_mono(const void * buffer,audio_format_t format,size_t samples)313*b9df5ad1SAndroid Build Coastguard Worker float audio_utils_compute_power_mono(const void *buffer, audio_format_t format, size_t samples)
314*b9df5ad1SAndroid Build Coastguard Worker {
315*b9df5ad1SAndroid Build Coastguard Worker return audio_utils_power_from_energy(
316*b9df5ad1SAndroid Build Coastguard Worker audio_utils_compute_energy_mono(buffer, format, samples) / samples);
317*b9df5ad1SAndroid Build Coastguard Worker }
318*b9df5ad1SAndroid Build Coastguard Worker
audio_utils_is_compute_power_format_supported(audio_format_t format)319*b9df5ad1SAndroid Build Coastguard Worker bool audio_utils_is_compute_power_format_supported(audio_format_t format)
320*b9df5ad1SAndroid Build Coastguard Worker {
321*b9df5ad1SAndroid Build Coastguard Worker return isFormatSupported(format);
322*b9df5ad1SAndroid Build Coastguard Worker }
323