xref: /aosp_15_r20/system/media/audio_utils/power.cpp (revision b9df5ad1c9ac98a7fefaac271a55f7ae3db05414)
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>(&amplitudes);
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>(&amplitudes);
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