Revert "Add power logging"
This reverts commit 13082f80dcee5f119cdb68a4dbc972cd2b939668.
Change-Id: I6bd03874fd219ef5b82e23d6e0dc97decbb87198
diff --git a/audio_utils/Android.bp b/audio_utils/Android.bp
index b6d01ea..11ed72c 100644
--- a/audio_utils/Android.bp
+++ b/audio_utils/Android.bp
@@ -24,8 +24,6 @@
"format.c",
"limiter.c",
"minifloat.c",
- "power.cpp",
- "PowerLog.cpp",
"primitives.c",
"roundup.c",
],
diff --git a/audio_utils/PowerLog.cpp b/audio_utils/PowerLog.cpp
deleted file mode 100644
index 64e3c65..0000000
--- a/audio_utils/PowerLog.cpp
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
- * Copyright 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-// #define LOG_NDEBUG 0
-#define LOG_TAG "audio_utils_PowerLog"
-#include <log/log.h>
-
-#include <algorithm>
-#include <iomanip>
-#include <math.h>
-#include <sstream>
-#include <stdint.h>
-
-#include <audio_utils/clock.h>
-#include <audio_utils/power.h>
-#include <audio_utils/PowerLog.h>
-
-namespace android {
-
-// TODO move to separate file
-template <typename T, size_t N>
-constexpr size_t array_size(const T(&)[N])
-{
- return N;
-}
-
-PowerLog::PowerLog(uint32_t sampleRate,
- uint32_t channelCount,
- audio_format_t format,
- size_t entries,
- size_t framesPerEntry)
- : mCurrentTime(0)
- , mCurrentEnergy(0)
- , mCurrentFrames(0)
- , mIdx(0)
- , mConsecutiveZeroes(0)
- , mSampleRate(sampleRate)
- , mChannelCount(channelCount)
- , mFormat(format)
- , mFramesPerEntry(framesPerEntry)
- , mEntries(entries)
-{
- (void)mSampleRate; // currently unused, for future use
- LOG_ALWAYS_FATAL_IF(!audio_utils_is_compute_power_format_supported(format),
- "unsupported format: %#x", format);
-}
-
-void PowerLog::log(const void *buffer, size_t frames, int64_t nowNs)
-{
- std::lock_guard<std::mutex> guard(mLock);
-
- const size_t bytes_per_sample = audio_bytes_per_sample(mFormat);
- while (frames > 0) {
- // check partial computation
- size_t required = mFramesPerEntry - mCurrentFrames;
- size_t process = std::min(required, frames);
-
- if (mCurrentTime == 0) {
- mCurrentTime = nowNs;
- }
- mCurrentEnergy +=
- audio_utils_compute_energy_mono(buffer, mFormat, process * mChannelCount);
- mCurrentFrames += process;
-
- ALOGV("nowNs:%lld, required:%zu, process:%zu, mCurrentEnergy:%f, mCurrentFrames:%zu",
- (long long)nowNs, required, process, mCurrentEnergy, mCurrentFrames);
- if (process < required) {
- return;
- }
-
- // We store the data as normalized energy per sample. The energy sequence is
- // zero terminated. Consecutive zeroes are ignored.
- if (mCurrentEnergy == 0.f) {
- if (mConsecutiveZeroes++ == 0) {
- mEntries[mIdx++] = std::make_pair(nowNs, 0.f);
- // zero terminate the signal sequence.
- }
- } else {
- mConsecutiveZeroes = 0;
- mEntries[mIdx++] = std::make_pair(mCurrentTime, mCurrentEnergy);
- ALOGV("writing %lld %f", (long long)mCurrentTime, mCurrentEnergy);
- }
- if (mIdx >= mEntries.size()) {
- mIdx -= mEntries.size();
- }
- mCurrentTime = 0;
- mCurrentEnergy = 0;
- mCurrentFrames = 0;
- frames -= process;
- buffer = (const uint8_t *)buffer + mCurrentFrames * mChannelCount * bytes_per_sample;
- }
-}
-
-std::string PowerLog::dumpToString(size_t lines, int64_t limitNs) const
-{
- std::lock_guard<std::mutex> guard(mLock);
-
- const size_t maxColumns = 10;
- const size_t numberOfEntries = mEntries.size();
- if (lines == 0) lines = SIZE_MAX;
-
- // compute where to start logging
- enum {
- AT_END,
- IN_SIGNAL,
- } state = IN_SIGNAL;
- size_t count = 1;
- size_t column = 0;
- size_t nonzeros = 0;
- ssize_t offset; // TODO doesn't dump if # entries exceeds SSIZE_MAX
- for (offset = 0; offset < (ssize_t)numberOfEntries && count < lines; ++offset) {
- const size_t idx = (mIdx + numberOfEntries - offset - 1) % numberOfEntries; // reverse direction
- const int64_t time = mEntries[idx].first;
- const float energy = mEntries[idx].second;
-
- if (state == AT_END) {
- if (energy == 0.f) {
- ALOGV("two zeroes detected");
- break; // normally single zero terminated - two zeroes means no more data.
- }
- state = IN_SIGNAL;
- } else { // IN_SIGNAL
- if (energy == 0.f) {
- if (column != 0) {
- column = 0;
- ++count;
- }
- state = AT_END;
- continue;
- }
- }
- if (column == 0 && time <= limitNs) {
- break;
- }
- ++nonzeros;
- if (++column == maxColumns) {
- column = 0;
- // TODO ideally we would peek the previous entry to see if it is 0
- // to ensure we properly put in a starting signal bracket.
- // We don't do that because it would complicate the logic here.
- ++count;
- }
- }
- if (offset > 0) {
- --offset;
- }
- // We accumulate the log info into a string, and write to the fd once.
- std::stringstream ss;
- ss << std::fixed << std::setprecision(1);
- // ss << std::scientific;
- if (nonzeros == 0) {
- ss << " Signal power history: (none)\n";
- } else {
- ss << " Signal power history:\n";
-
- size_t column = 0;
- bool first = true;
- bool start = false;
- float cumulative = 0.f;
- for (; offset >= 0; --offset) {
- const size_t idx = (mIdx + numberOfEntries - offset - 1) % numberOfEntries;
- const int64_t time = mEntries[idx].first;
- const float energy = mEntries[idx].second;
-
- if (energy == 0.f) {
- if (!first) {
- ss << " ] sum(" << audio_utils_power_from_energy(cumulative) << ")";
- }
- cumulative = 0.f;
- column = 0;
- start = true;
- continue;
- }
- if (column == 0) {
- // print time if at start of column
- char timeinfo[32];
- audio_utils_ns_to_string(time, timeinfo, array_size(timeinfo));
- if (!first) {
- ss << "\n";
- }
- ss << timeinfo << (start ? ": [ ": ": ");
- first = false;
- start = false;
- } else {
- ss << " ";
- }
- if (++column >= maxColumns) {
- column = 0;
- }
-
- cumulative += energy;
- // convert energy to power and print
- const float power =
- audio_utils_power_from_energy(energy / (mChannelCount * mFramesPerEntry));
- ss << std::setw(6) << power;
- ALOGV("state: %d %lld %f", state, (long long)time, power);
- }
- ss << "\n";
- }
- return ss.str();
-}
-
-status_t PowerLog::dump(int fd, size_t lines, int64_t limitNs) const
-{
- // Since dumpToString and write are thread safe, this function
- // is conceptually thread-safe but simultaneous calls to dump
- // by different threads to the same file descriptor may not write
- // the two logs in time order.
- const std::string s = dumpToString(lines, limitNs);
- if (s.size() > 0 && write(fd, s.c_str(), s.size()) < 0) {
- return -errno;
- }
- return NO_ERROR;
-}
-
-} // namespace android
-
-using namespace android;
-
-power_log_t *power_log_create(uint32_t sample_rate,
- uint32_t channel_count, audio_format_t format, size_t entries, size_t frames_per_entry)
-{
- if (!audio_utils_is_compute_power_format_supported(format)) {
- return nullptr;
- }
- return reinterpret_cast<power_log_t *>
- (new PowerLog(sample_rate, channel_count, format, entries, frames_per_entry));
-}
-
-void power_log_log(power_log_t *power_log,
- const void *buffer, size_t frames, int64_t now_ns)
-{
- if (power_log == nullptr) {
- return;
- }
- reinterpret_cast<PowerLog *>(power_log)->log(buffer, frames, now_ns);
-}
-
-int power_log_dump(power_log_t *power_log, int fd, size_t lines, int64_t limit_ns)
-{
- if (power_log == nullptr) {
- return BAD_VALUE;
- }
- return reinterpret_cast<PowerLog *>(power_log)->dump(fd, lines, limit_ns);
-}
-
-void power_log_destroy(power_log_t *power_log)
-{
- delete reinterpret_cast<PowerLog *>(power_log);
-}
diff --git a/audio_utils/include/audio_utils/PowerLog.h b/audio_utils/include/audio_utils/PowerLog.h
deleted file mode 100644
index 497bb3c..0000000
--- a/audio_utils/include/audio_utils/PowerLog.h
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_AUDIO_POWER_LOG_H
-#define ANDROID_AUDIO_POWER_LOG_H
-
-#ifdef __cplusplus
-
-#include <mutex>
-#include <vector>
-
-#include <utils/Errors.h>
-
-namespace android {
-
-/**
- * PowerLog captures the audio data power (measured in dBFS) over time.
- *
- * For the purposes of power evaluation, the audio data is divided into "bins",
- * and grouped by signals consisting of consecutive non-zero energy bins.
- * The sum energy in dB of each signal is computed for comparison purposes.
- *
- * No distinction is made between channels in an audio frame; they are all
- * summed together for energy purposes.
- *
- * The public methods are internally protected by a mutex to be thread-safe.
- */
-class PowerLog {
-public:
- /**
- * \brief Creates a PowerLog object.
- *
- * \param sampleRate sample rate of the audio data.
- * \param channelCount channel count of the audio data.
- * \param format format of the audio data. It must be allowed by
- * audio_utils_is_compute_power_format_supported()
- * else the constructor will abort.
- * \param entries total number of energy entries "bins" to use.
- * \param framesPerEntry total number of audio frames used in each entry.
- */
- explicit PowerLog(uint32_t sampleRate,
- uint32_t channelCount,
- audio_format_t format,
- size_t entries,
- size_t framesPerEntry);
-
- /**
- * \brief Adds new audio data to the power log.
- *
- * \param buffer pointer to the audio data buffer.
- * \param frames buffer size in audio frames.
- * \param nowNs current time in nanoseconds.
- */
- void log(const void *buffer, size_t frames, int64_t nowNs);
-
- /**
- * \brief Dumps the log to a std::string.
- *
- * \param lines maximum number of lines to output (0 disables).
- * \param limitNs limit dump to data more recent than limitNs (0 disables).
- * \return the std::string for the log.
- */
- std::string dumpToString(size_t lines = 0, int64_t limitNs = 0) const;
-
- /**
- * \brief Dumps the log to a raw file descriptor.
- *
- * \param fd file descriptor to use.
- * \param lines maximum number of lines to output (0 disables).
- * \param limitNs limit dump to data more recent than limitNs (0 disables).
- * \return
- * NO_ERROR on success or a negative number (-errno) on failure of write().
- */
- status_t dump(int fd, size_t lines = 0, int64_t limitNs = 0) const;
-
-private:
- mutable std::mutex mLock; // monitor mutex
- int64_t mCurrentTime; // time of first frame in buffer
- float mCurrentEnergy; // local energy accumulation
- size_t mCurrentFrames; // number of frames in the energy
- size_t mIdx; // next usable index in mEntries
- size_t mConsecutiveZeroes; // current run of consecutive zero entries
- const uint32_t mSampleRate; // audio data sample rate
- const uint32_t mChannelCount; // audio data channel count
- const audio_format_t mFormat; // audio data format
- const size_t mFramesPerEntry; // number of audio frames per entry
- std::vector<std::pair<int64_t /* real time ns */, float /* energy */>> mEntries;
-};
-
-} // namespace android
-
-#endif // __cplusplus
-
-/** \cond */
-__BEGIN_DECLS
-/** \endcond */
-
-// C API (see C++ api above for details)
-
-typedef struct power_log_t power_log_t;
-
-/**
- * \brief Creates a power log object.
- *
- * \param sample_rate sample rate of the audio data.
- * \param channel_count channel count of the audio data.
- * \param format format of the audio data. It must be allowed by
- * audio_utils_is_compute_power_format_supported().
- * \param entries total number of energy entries "bins" to use.
- * \param frames_per_entry total number of audio frames used in each entry.
- *
- * \return power log object or NULL on failure.
- */
-power_log_t *power_log_create(uint32_t sample_rate,
- uint32_t channel_count, audio_format_t format, size_t entries, size_t frames_per_entry);
-
-/**
- * \brief Adds new audio data to the power log.
- *
- * \param power_log object returned by create, if NULL nothing happens.
- * \param buffer pointer to the audio data buffer.
- * \param frames buffer size in audio frames.
- * \param now_ns current time in nanoseconds.
- */
-void power_log_log(power_log_t *power_log, const void *buffer, size_t frames, int64_t now_ns);
-
-/**
- * \brief Dumps the log to a raw file descriptor.
- *
- * \param power_log object returned by create, if NULL nothing happens.
- * \param fd file descriptor to use.
- * \param lines maximum number of lines to output (0 disables).
- * \param limit_ns limit dump to data more recent than limit_ns (0 disables).
- * \return
- * NO_ERROR on success or a negative number (-errno) on failure of write().
- * if power_log is NULL, BAD_VALUE is returned.
- */
-int power_log_dump(power_log_t *power_log, int fd, size_t lines, int64_t limit_ns);
-
-/**
- * \brief Destroys the power log object.
- *
- * \param power_log object returned by create, if NULL nothing happens.
- */
-void power_log_destroy(power_log_t *power_log);
-
-/** \cond */
-__END_DECLS
-/** \endcond */
-
-#endif // !ANDROID_AUDIO_POWER_LOG_H
diff --git a/audio_utils/include/audio_utils/clock.h b/audio_utils/include/audio_utils/clock.h
deleted file mode 100644
index 149ac8c..0000000
--- a/audio_utils/include/audio_utils/clock.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_AUDIO_CLOCK_H
-#define ANDROID_AUDIO_CLOCK_H
-
-#include <time.h>
-
-/**
- * \brief Converts time in ns to a time string, with format similar to logcat.
- * \param ns input time in nanoseconds to convert.
- * \param buffer caller allocated string buffer, buffer_length must be >= 19 chars
- * in order to fully fit in time. The string is always returned
- * null terminated if buffer_size is greater than zero.
- * \param buffer_size size of buffer.
- */
-static inline void audio_utils_ns_to_string(int64_t ns, char *buffer, int buffer_size)
-{
- const int one_second = 1000000000;
- const time_t sec = ns / one_second;
- struct tm tm;
- localtime_r(&sec, &tm);
- if (snprintf(buffer, buffer_size, "%02d-%02d %02d:%02d:%02d.%03d",
- tm.tm_mon + 1, // localtime_r uses months in 0 - 11 range
- tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec,
- (int)(ns % one_second / 1000000)) < 0) {
- buffer[0] = '\0'; // null terminate on format error, which should not happen
- }
-}
-
-/**
- * \brief Converts a timespec to nanoseconds.
- * \param ts input timespec to convert.
- * \return timespec converted to nanoseconds.
- */
-static inline int64_t audio_utils_ns_from_timespec(const struct timespec *ts)
-{
- return ts->tv_sec * 1000000000LL + ts->tv_nsec;
-}
-
-/**
- * \brief Gets the real time clock in nanoseconds.
- * \return the real time clock in nanoseconds, or 0 on error.
- */
-static inline int64_t audio_utils_get_real_time_ns() {
- struct timespec now_ts;
- if (clock_gettime(CLOCK_REALTIME, &now_ts) == 0) {
- return audio_utils_ns_from_timespec(&now_ts);
- }
- return 0; // should not happen.
-}
-
-#endif // !ANDROID_AUDIO_CLOCK_H
diff --git a/audio_utils/include/audio_utils/power.h b/audio_utils/include/audio_utils/power.h
deleted file mode 100644
index 385b6a7..0000000
--- a/audio_utils/include/audio_utils/power.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_AUDIO_POWER_H
-#define ANDROID_AUDIO_POWER_H
-
-#include <math.h>
-#include <stdint.h>
-#include <sys/cdefs.h>
-#include <system/audio.h>
-
-/** \cond */
-__BEGIN_DECLS
-/** \endcond */
-
-/**
- * \brief Compute signal power on a scale of 0 dBFS.
- *
- * \param buffer buffer of samples.
- * \param format one of AUDIO_FORMAT_PCM_8_BIT, AUDIO_FORMAT_PCM_16_BIT,
- * AUDIO_FORMAT_PCM_24_BIT_PACKED, AUDIO_FORMAT_PCM_8_24_BIT,
- * AUDIO_FORMAT_PCM_32_BIT, AUDIO_FORMAT_PCM_FLOAT.
- * \param samples number of samples in buffer. This is not audio frames;
- * usually the number of samples is the number of audio frames
- * multiplied by channel count.
- *
- * \return
- * signal power of the samples in the buffer. It is possible to return negative infinity
- * if the power is zero.
- */
-
-float audio_utils_compute_power_mono(const void *buffer, audio_format_t format, size_t samples);
-
-/**
- * \brief Compute signal energy (sum of squared amplitudes).
- *
- * \param buffer buffer of samples.
- * \param format one of AUDIO_FORMAT_PCM_8_BIT, AUDIO_FORMAT_PCM_16_BIT,
- * AUDIO_FORMAT_PCM_24_BIT_PACKED, AUDIO_FORMAT_PCM_8_24_BIT,
- * AUDIO_FORMAT_PCM_32_BIT, AUDIO_FORMAT_PCM_FLOAT.
- * \param samples number of samples in buffer. This is not audio frames;
- * usually the number of samples is the number of audio frames
- * multiplied by channel count.
- *
- * \return
- * signal energy of the samples in the buffer (sum of squares) where each sample is
- * normalized to peak to peak range of 1.f.
- */
-
-float audio_utils_compute_energy_mono(const void *buffer, audio_format_t format, size_t samples);
-
-/**
- * \brief Returns true if the format is supported for compute_energy_for_mono()
- * and compute_power_for_mono().
- * \param format format under consideration.
- * \return true if supported.
- */
-bool audio_utils_is_compute_power_format_supported(audio_format_t format);
-
-/**
- * \brief Returns the signal power from amplitude.
- * \param amplitude the signal amplitude. A negative amplitude is treated
- * the same as a positive amplitude.
- * \return signal power in dB. It is possible to return negative infinity
- * if the input is zero.
- */
-static inline float audio_utils_power_from_amplitude(float amplitude)
-{
- return 20.f * log10f(fabsf(amplitude));
-}
-
-/**
- * \brief Returns the signal power from energy.
- * \param energy the signal energy. This should be non-negative.
- * \return signal power in dB. It is possible to return NaN if the input is
- * negative, or negative infinity if the input is zero.
- */
-static inline float audio_utils_power_from_energy(float energy)
-{
- return 10.f * log10f(energy);
-}
-
-/** \cond */
-__END_DECLS
-/** \endcond */
-
-#endif // !ANDROID_AUDIO_POWER_H
diff --git a/audio_utils/power.cpp b/audio_utils/power.cpp
deleted file mode 100644
index e801da0..0000000
--- a/audio_utils/power.cpp
+++ /dev/null
@@ -1,306 +0,0 @@
-/*
- * Copyright 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-// #define LOG_NDEBUG 0
-#define LOG_TAG "audio_utils_power"
-#include <log/log.h>
-
-#include <math.h>
-
-#include <audio_utils/power.h>
-#include <audio_utils/primitives.h>
-
-#if defined(__aarch64__) || defined(__ARM_NEON__)
-#include <arm_neon.h>
-#define USE_NEON
-#endif
-
-namespace {
-
-constexpr inline bool isFormatSupported(audio_format_t format) {
- switch (format) {
- case AUDIO_FORMAT_PCM_8_BIT:
- case AUDIO_FORMAT_PCM_16_BIT:
- case AUDIO_FORMAT_PCM_24_BIT_PACKED:
- case AUDIO_FORMAT_PCM_8_24_BIT:
- case AUDIO_FORMAT_PCM_32_BIT:
- case AUDIO_FORMAT_PCM_FLOAT:
- return true;
- default:
- return false;
- }
-}
-
-template <typename T>
-inline T getPtrPtrValueAndIncrement(const void **data)
-{
- return *(*reinterpret_cast<const T **>(data))++;
-}
-
-template <audio_format_t FORMAT>
-inline float convertToFloatAndIncrement(const void **data)
-{
- switch (FORMAT) {
- case AUDIO_FORMAT_PCM_8_BIT:
- return float_from_u8(getPtrPtrValueAndIncrement<uint8_t>(data));
-
- case AUDIO_FORMAT_PCM_16_BIT:
- return float_from_i16(getPtrPtrValueAndIncrement<int16_t>(data));
-
- case AUDIO_FORMAT_PCM_24_BIT_PACKED: {
- const uint8_t *uptr = reinterpret_cast<const uint8_t *>(*data);
- *data = uptr + 3;
- return float_from_p24(uptr);
- }
-
- case AUDIO_FORMAT_PCM_8_24_BIT:
- return float_from_q8_23(getPtrPtrValueAndIncrement<int32_t>(data));
-
- case AUDIO_FORMAT_PCM_32_BIT:
- return float_from_i32(getPtrPtrValueAndIncrement<int32_t>(data));
-
- case AUDIO_FORMAT_PCM_FLOAT:
- return getPtrPtrValueAndIncrement<float>(data);
-
- default:
- // static_assert cannot use false because the compiler may interpret it
- // even though this code path may never be taken.
- static_assert(isFormatSupported(FORMAT), "unsupported format");
- }
-}
-
-// used to normalize integer fixed point value to the floating point equivalent.
-template <audio_format_t FORMAT>
-constexpr inline float normalizeAmplitude()
-{
- switch (FORMAT) {
- case AUDIO_FORMAT_PCM_8_BIT:
- return 1.f / (1 << 7);
-
- case AUDIO_FORMAT_PCM_16_BIT:
- return 1.f / (1 << 15);
-
- case AUDIO_FORMAT_PCM_24_BIT_PACKED: // fall through
- case AUDIO_FORMAT_PCM_8_24_BIT:
- return 1.f / (1 << 23);
-
- case AUDIO_FORMAT_PCM_32_BIT:
- return 1.f / (1U << 31);
-
- case AUDIO_FORMAT_PCM_FLOAT:
- return 1.f;
-
- default:
- // static_assert cannot use false because the compiler may interpret it
- // even though this code path may never be taken.
- static_assert(isFormatSupported(FORMAT), "unsupported format");
- }
-}
-
-template <audio_format_t FORMAT>
-constexpr inline float normalizeEnergy()
-{
- const float val = normalizeAmplitude<FORMAT>();
- return val * val;
-}
-
-template <audio_format_t FORMAT>
-inline float energyMonoRef(const void *amplitudes, size_t size)
-{
- float accum(0.f);
- for (size_t i = 0; i < size; ++i) {
- const float amplitude = convertToFloatAndIncrement<FORMAT>(&litudes);
- accum += amplitude * amplitude;
- }
- return accum;
-}
-
-template <audio_format_t FORMAT>
-inline float energyMono(const void *amplitudes, size_t size)
-{
- return energyMonoRef<FORMAT>(amplitudes, size);
-}
-
-// fast float power computation for ARM processors that support NEON.
-#ifdef USE_NEON
-
-template <>
-inline float energyMono<AUDIO_FORMAT_PCM_FLOAT>(const void *amplitudes, size_t size)
-{
- float32x4_t *famplitudes = (float32x4_t *)amplitudes;
-
- // clear accumulator
- float32x4_t accum = vdupq_n_f32(0);
-
- // iterate over array getting sum of squares in 4 lanes.
- size_t i;
- for (i = 0; i < (size & ~3); i += 4) {
- accum = vmlaq_f32(accum, *famplitudes, *famplitudes);
- ++famplitudes;
- }
-
- // narrow 4 lanes of floats
- float32x2_t accum2 = vadd_f32(vget_low_f32(accum), vget_high_f32(accum)); // get stereo volume
- accum2 = vpadd_f32(accum2, accum2); // combine to mono
-
- // accumulate remainder
- float value = vget_lane_f32(accum2, 0);
- for (; i < size; ++i) {
- const float amplitude = ((float *)amplitudes)[i];
- value += amplitude * amplitude;
- }
-
- return value;
-}
-
-template <>
-inline float energyMono<AUDIO_FORMAT_PCM_16_BIT>(const void *amplitudes, size_t size)
-{
- int16x4_t *samplitudes = (int16x4_t *)amplitudes;
-
- // clear accumulator
- float32x4_t accum = vdupq_n_f32(0);
-
- // iterate over array getting sum of squares in 4 lanes.
- size_t i;
- for (i = 0; i < (size & ~3); i += 4) {
- // expand s16 to s32
- int32x4_t amplitude = vmovl_s16(*samplitudes);
- ++samplitudes;
- // convert s32 to f32
- float32x4_t famplitude = vcvtq_f32_s32(amplitude);
- accum = vmlaq_f32(accum, famplitude, famplitude);
- }
-
- // narrow 4 lanes of floats
- float32x2_t accum2 = vadd_f32(vget_low_f32(accum), vget_high_f32(accum)); // get stereo volume
- accum2 = vpadd_f32(accum2, accum2); // combine to mono
-
- // accumulate remainder
- float value = vget_lane_f32(accum2, 0);
- for (; i < size; ++i) {
- const float amplitude = (float)((int16_t *)amplitudes)[i];
- value += amplitude * amplitude;
- }
-
- return value * normalizeEnergy<AUDIO_FORMAT_PCM_16_BIT>();
-}
-
-// fast int32_t power computation for PCM_32
-template <>
-inline float energyMono<AUDIO_FORMAT_PCM_32_BIT>(const void *amplitudes, size_t size)
-{
- int32x4_t *samplitudes = (int32x4_t *)amplitudes;
-
- // clear accumulator
- float32x4_t accum = vdupq_n_f32(0);
-
- // iterate over array getting sum of squares in 4 lanes.
- size_t i;
- for (i = 0; i < (size & ~3); i += 4) {
- // convert s32 to f32
- float32x4_t famplitude = vcvtq_f32_s32(*samplitudes);
- ++samplitudes;
- accum = vmlaq_f32(accum, famplitude, famplitude);
- }
-
- // narrow 4 lanes of floats
- float32x2_t accum2 = vadd_f32(vget_low_f32(accum), vget_high_f32(accum)); // get stereo volume
- accum2 = vpadd_f32(accum2, accum2); // combine to mono
-
- // accumulate remainder
- float value = vget_lane_f32(accum2, 0);
- for (; i < size; ++i) {
- const float amplitude = (float)((int32_t *)amplitudes)[i];
- value += amplitude * amplitude;
- }
-
- return value * normalizeEnergy<AUDIO_FORMAT_PCM_32_BIT>();
-}
-
-// fast int32_t power computation for PCM_8_24 (essentially identical to PCM_32 above)
-template <>
-inline float energyMono<AUDIO_FORMAT_PCM_8_24_BIT>(const void *amplitudes, size_t size)
-{
- int32x4_t *samplitudes = (int32x4_t *)amplitudes;
-
- // clear accumulator
- float32x4_t accum = vdupq_n_f32(0);
-
- // iterate over array getting sum of squares in 4 lanes.
- size_t i;
- for (i = 0; i < (size & ~3); i += 4) {
- // convert s32 to f32
- float32x4_t famplitude = vcvtq_f32_s32(*samplitudes);
- ++samplitudes;
- accum = vmlaq_f32(accum, famplitude, famplitude);
- }
-
- // narrow 4 lanes of floats
- float32x2_t accum2 = vadd_f32(vget_low_f32(accum), vget_high_f32(accum)); // get stereo volume
- accum2 = vpadd_f32(accum2, accum2); // combine to mono
-
- // accumulate remainder
- float value = vget_lane_f32(accum2, 0);
- for (; i < size; ++i) {
- const float amplitude = (float)((int32_t *)amplitudes)[i];
- value += amplitude * amplitude;
- }
-
- return value * normalizeEnergy<AUDIO_FORMAT_PCM_8_24_BIT>();
-}
-
-#endif // USE_NEON
-
-} // namespace
-
-float audio_utils_compute_energy_mono(const void *buffer, audio_format_t format, size_t samples)
-{
- switch (format) {
- case AUDIO_FORMAT_PCM_8_BIT:
- return energyMono<AUDIO_FORMAT_PCM_8_BIT>(buffer, samples);
-
- case AUDIO_FORMAT_PCM_16_BIT:
- return energyMono<AUDIO_FORMAT_PCM_16_BIT>(buffer, samples);
-
- case AUDIO_FORMAT_PCM_24_BIT_PACKED:
- return energyMono<AUDIO_FORMAT_PCM_24_BIT_PACKED>(buffer, samples);
-
- case AUDIO_FORMAT_PCM_8_24_BIT:
- return energyMono<AUDIO_FORMAT_PCM_8_24_BIT>(buffer, samples);
-
- case AUDIO_FORMAT_PCM_32_BIT:
- return energyMono<AUDIO_FORMAT_PCM_32_BIT>(buffer, samples);
-
- case AUDIO_FORMAT_PCM_FLOAT:
- return energyMono<AUDIO_FORMAT_PCM_FLOAT>(buffer, samples);
-
- default:
- LOG_ALWAYS_FATAL("invalid format: %#x", format);
- }
-}
-
-float audio_utils_compute_power_mono(const void *buffer, audio_format_t format, size_t samples)
-{
- return audio_utils_power_from_energy(
- audio_utils_compute_energy_mono(buffer, format, samples) / samples);
-}
-
-bool audio_utils_is_compute_power_format_supported(audio_format_t format)
-{
- return isFormatSupported(format);
-}
-
diff --git a/audio_utils/tests/Android.bp b/audio_utils/tests/Android.bp
index 91eef0f..6fa3f82 100644
--- a/audio_utils/tests/Android.bp
+++ b/audio_utils/tests/Android.bp
@@ -74,27 +74,3 @@
"-UNDEBUG",
],
}
-
-cc_test {
- name: "power_tests",
- host_supported: true,
-
- shared_libs: [
- "libcutils",
- "liblog",
- ],
- srcs: ["power_tests.cpp"],
- cflags: [
- "-Wall",
- "-Werror",
- "-Wextra",
- ],
- target: {
- android: {
- shared_libs: ["libaudioutils"],
- },
- host: {
- static_libs: ["libaudioutils"],
- },
- }
-}
diff --git a/audio_utils/tests/power_tests.cpp b/audio_utils/tests/power_tests.cpp
deleted file mode 100644
index b86dac3..0000000
--- a/audio_utils/tests/power_tests.cpp
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "audio_utils_power_tests"
-
-#include <cmath>
-#include <math.h>
-
-#include <audio_utils/power.h>
-#include <gtest/gtest.h>
-#include <log/log.h>
-
-typedef struct { uint8_t c[3]; } __attribute__((__packed__)) uint8x3_t;
-
-void testFloatValue(float f_value, size_t length) {
- const float power = audio_utils_power_from_amplitude(f_value);
- float f_ary[length];
- uint8_t u8_ary[length];
- int16_t i16_ary[length];
- int32_t i32_ary[length];
- int32_t q8_23_ary[length];
- uint8x3_t p24_ary[length];
-
- // magic formulas to convert floating point to fixed point representations.
- // we negate the floating point value to ensure full integer range for 1.f.
- const uint8_t u8_value((1.f - f_value) * 128);
- const int16_t i16_value(f_value * INT16_MIN);
- const int32_t i32_value (f_value * INT32_MIN);
- const int32_t q8_23_value(f_value * -(1 << 23));
-
- // PCM_24_BIT_PACKED is native endian.
-#if HAVE_BIG_ENDIAN
- const uint8x3_t p24_value{{
- uint8_t(q8_23_value >> 16),
- uint8_t(q8_23_value >> 8),
- uint8_t(q8_23_value),
- }};
-#else
- const uint8x3_t p24_value{{
- uint8_t(q8_23_value),
- uint8_t(q8_23_value >> 8),
- uint8_t(q8_23_value >> 16),
- }};
-#endif
-
- for (size_t i = 0; i < length; ++i) {
- f_ary[i] = f_value;
- u8_ary[i] = u8_value;
- i16_ary[i] = i16_value;
- i32_ary[i] = i32_value;
- q8_23_ary[i] = q8_23_value;
- p24_ary[i] = p24_value;
- }
-
- EXPECT_EQ(power,
- audio_utils_compute_power_mono(f_ary, AUDIO_FORMAT_PCM_FLOAT, length));
- EXPECT_EQ(power,
- audio_utils_compute_power_mono(u8_ary, AUDIO_FORMAT_PCM_8_BIT, length));
- EXPECT_EQ(power,
- audio_utils_compute_power_mono(i16_ary, AUDIO_FORMAT_PCM_16_BIT, length));
- EXPECT_EQ(power,
- audio_utils_compute_power_mono(i32_ary, AUDIO_FORMAT_PCM_32_BIT, length));
- EXPECT_EQ(power,
- audio_utils_compute_power_mono(q8_23_ary, AUDIO_FORMAT_PCM_8_24_BIT, length));
- EXPECT_EQ(power,
- audio_utils_compute_power_mono(p24_ary, AUDIO_FORMAT_PCM_24_BIT_PACKED, length));
-}
-
-void testFloatRamp(size_t length) {
- float f_ary[length];
- uint8_t u8_ary[length];
- int16_t i16_ary[length];
- int32_t i32_ary[length];
- int32_t q8_23_ary[length];
- uint8x3_t p24_ary[length];
-
- for (size_t i = 0; i < length; ++i) {
- // must be expressed cleanly in uint8_t
- const float f_value = (int(length & 0xff) - 128) / 128.f;
-
- // magic formulas to convert floating point to fixed point representations.
- // we negate the floating point value to ensure full integer range for 1.f.
- const uint8_t u8_value((1.f - f_value) * 128);
- const int16_t i16_value(f_value * INT16_MIN);
- const int32_t i32_value (f_value * INT32_MIN);
- const int32_t q8_23_value(f_value * -(1 << 23));
-
- // PCM_24_BIT_PACKED is native endian.
- #if HAVE_BIG_ENDIAN
- const uint8x3_t p24_value{{
- uint8_t(q8_23_value >> 16),
- uint8_t(q8_23_value >> 8),
- uint8_t(q8_23_value),
- }};
- #else
- const uint8x3_t p24_value{{
- uint8_t(q8_23_value),
- uint8_t(q8_23_value >> 8),
- uint8_t(q8_23_value >> 16),
- }};
- #endif
-
- f_ary[i] = f_value;
- u8_ary[i] = u8_value;
- i16_ary[i] = i16_value;
- i32_ary[i] = i32_value;
- q8_23_ary[i] = q8_23_value;
- p24_ary[i] = p24_value;
- }
-
- const float power8 = audio_utils_compute_power_mono(u8_ary, AUDIO_FORMAT_PCM_8_BIT, length);
-
- EXPECT_EQ(power8,
- audio_utils_compute_power_mono(f_ary, AUDIO_FORMAT_PCM_FLOAT, length));
- EXPECT_EQ(power8,
- audio_utils_compute_power_mono(i16_ary, AUDIO_FORMAT_PCM_16_BIT, length));
- EXPECT_EQ(power8,
- audio_utils_compute_power_mono(i32_ary, AUDIO_FORMAT_PCM_32_BIT, length));
- EXPECT_EQ(power8,
- audio_utils_compute_power_mono(q8_23_ary, AUDIO_FORMAT_PCM_8_24_BIT, length));
- EXPECT_EQ(power8,
- audio_utils_compute_power_mono(p24_ary, AUDIO_FORMAT_PCM_24_BIT_PACKED, length));
-}
-
-// power_mono implicitly tests energy_mono
-TEST(audio_utils_power, power_mono) {
- // f_values should have limited mantissa
- for (float f_value : { 0.f, 0.25f, 0.5f, 0.75f, 1.f }) {
- const float power = audio_utils_power_from_amplitude(f_value);
- printf("power_mono: amplitude: %f power: %f\n", f_value, power);
-
- for (size_t length : { 1, 3, 5, 7, 16, 21, 32, 37 }) {
- testFloatValue(f_value, length);
- }
- }
-}
-
-// power_mono implicitly tests energy_mono
-TEST(audio_utils_power, power_mono_ramp) {
- for (size_t length : { 1, 3, 5, 7, 16, 21, 32, 37, 297 }) {
- testFloatRamp(length);
- }
-}
-
-TEST(audio_utils_power, power_from) {
- EXPECT_EQ(0.f, audio_utils_power_from_amplitude(1.f));
- EXPECT_EQ(-INFINITY, audio_utils_power_from_amplitude(0.f));
- EXPECT_EQ(0.f, audio_utils_power_from_amplitude(-1.f));
-
- EXPECT_EQ(0.f, audio_utils_power_from_energy(1.f));
- EXPECT_EQ(-INFINITY, audio_utils_power_from_energy(0.f));
- EXPECT_TRUE(std::isnan(audio_utils_power_from_energy(-1.f)));
-}