1459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung/*
2459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung * Copyright 2017 The Android Open Source Project
3459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung *
4459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung * Licensed under the Apache License, Version 2.0 (the "License");
5459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung * you may not use this file except in compliance with the License.
6459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung * You may obtain a copy of the License at
7459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung *
8459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung *      http://www.apache.org/licenses/LICENSE-2.0
9459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung *
10459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung * Unless required by applicable law or agreed to in writing, software
11459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung * distributed under the License is distributed on an "AS IS" BASIS,
12459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung * See the License for the specific language governing permissions and
14459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung * limitations under the License.
15459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung */
16459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung
17459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung#ifndef ANDROID_AUDIO_POWER_LOG_H
18459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung#define ANDROID_AUDIO_POWER_LOG_H
19459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung
20459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung#ifdef __cplusplus
21459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung
22459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung#include <mutex>
23459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung#include <vector>
243213c5e868e93241ac6af84c10f32d1f9e251392Andy Hung#include <system/audio.h>
25459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung#include <utils/Errors.h>
26459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung
27459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hungnamespace android {
28459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung
29459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung/**
30459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung * PowerLog captures the audio data power (measured in dBFS) over time.
31459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung *
32459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung * For the purposes of power evaluation, the audio data is divided into "bins",
33459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung * and grouped by signals consisting of consecutive non-zero energy bins.
34459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung * The sum energy in dB of each signal is computed for comparison purposes.
35459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung *
36459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung * No distinction is made between channels in an audio frame; they are all
37459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung * summed together for energy purposes.
38459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung *
39459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung * The public methods are internally protected by a mutex to be thread-safe.
40459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung */
41459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hungclass PowerLog {
42459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hungpublic:
43459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung    /**
44459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung     * \brief Creates a PowerLog object.
45459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung     *
46459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung     * \param sampleRate        sample rate of the audio data.
47459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung     * \param channelCount      channel count of the audio data.
48459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung     * \param format            format of the audio data. It must be allowed by
49459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung     *                          audio_utils_is_compute_power_format_supported()
50459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung     *                          else the constructor will abort.
51459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung     * \param entries           total number of energy entries "bins" to use.
52459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung     * \param framesPerEntry    total number of audio frames used in each entry.
53459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung     */
543213c5e868e93241ac6af84c10f32d1f9e251392Andy Hung    PowerLog(uint32_t sampleRate,
55459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung            uint32_t channelCount,
56459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung            audio_format_t format,
57459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung            size_t entries,
58459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung            size_t framesPerEntry);
59459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung
60459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung    /**
61459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung     * \brief Adds new audio data to the power log.
62459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung     *
63459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung     * \param buffer            pointer to the audio data buffer.
64459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung     * \param frames            buffer size in audio frames.
65459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung     * \param nowNs             current time in nanoseconds.
66459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung     */
67459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung    void log(const void *buffer, size_t frames, int64_t nowNs);
68459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung
69459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung    /**
70459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung     * \brief Dumps the log to a std::string.
71459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung     *
72459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung     * \param lines             maximum number of lines to output (0 disables).
73459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung     * \param limitNs           limit dump to data more recent than limitNs (0 disables).
74459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung     * \return the std::string for the log.
75459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung     */
763213c5e868e93241ac6af84c10f32d1f9e251392Andy Hung    std::string dumpToString(
773213c5e868e93241ac6af84c10f32d1f9e251392Andy Hung            const char *prefix = "", size_t lines = 0, int64_t limitNs = 0) const;
78459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung
79459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung    /**
80459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung     * \brief Dumps the log to a raw file descriptor.
81459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung     *
82459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung     * \param fd                file descriptor to use.
83459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung     * \param lines             maximum number of lines to output (0 disables).
84459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung     * \param limitNs           limit dump to data more recent than limitNs (0 disables).
85459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung     * \return
86459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung     *   NO_ERROR on success or a negative number (-errno) on failure of write().
87459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung     */
883213c5e868e93241ac6af84c10f32d1f9e251392Andy Hung    status_t dump(int fd, const char *prefix = "", size_t lines = 0, int64_t limitNs = 0) const;
89459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung
90459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hungprivate:
91459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung    mutable std::mutex mLock;     // monitor mutex
92459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung    int64_t mCurrentTime;         // time of first frame in buffer
93459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung    float mCurrentEnergy;         // local energy accumulation
94459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung    size_t mCurrentFrames;        // number of frames in the energy
95459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung    size_t mIdx;                  // next usable index in mEntries
96459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung    size_t mConsecutiveZeroes;    // current run of consecutive zero entries
97459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung    const uint32_t mSampleRate;   // audio data sample rate
98459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung    const uint32_t mChannelCount; // audio data channel count
99459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung    const audio_format_t mFormat; // audio data format
100459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung    const size_t mFramesPerEntry; // number of audio frames per entry
101459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung    std::vector<std::pair<int64_t /* real time ns */, float /* energy */>> mEntries;
102459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung};
103459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung
104459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung} // namespace android
105459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung
106459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung#endif // __cplusplus
107459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung
108459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung/** \cond */
109459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung__BEGIN_DECLS
110459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung/** \endcond */
111459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung
112459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung// C API (see C++ api above for details)
113459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung
114459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hungtypedef struct power_log_t power_log_t;
115459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung
116459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung/**
117459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung * \brief Creates a power log object.
118459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung *
119459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung * \param sample_rate       sample rate of the audio data.
120459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung * \param channel_count     channel count of the audio data.
121459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung * \param format            format of the audio data. It must be allowed by
122459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung *                          audio_utils_is_compute_power_format_supported().
123459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung * \param entries           total number of energy entries "bins" to use.
124459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung * \param frames_per_entry  total number of audio frames used in each entry.
125459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung *
126459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung * \return power log object or NULL on failure.
127459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung */
128459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hungpower_log_t *power_log_create(uint32_t sample_rate,
129459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung        uint32_t channel_count, audio_format_t format, size_t entries, size_t frames_per_entry);
130459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung
131459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung/**
132459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung * \brief Adds new audio data to the power log.
133459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung *
134459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung * \param power_log         object returned by create, if NULL nothing happens.
135459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung * \param buffer            pointer to the audio data buffer.
136459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung * \param frames            buffer size in audio frames.
137459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung * \param now_ns            current time in nanoseconds.
138459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung */
139459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hungvoid power_log_log(power_log_t *power_log, const void *buffer, size_t frames, int64_t now_ns);
140459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung
141459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung/**
142459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung * \brief Dumps the log to a raw file descriptor.
143459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung *
144459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung * \param power_log         object returned by create, if NULL nothing happens.
145459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung * \param fd                file descriptor to use.
146459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung * \param lines             maximum number of lines to output (0 disables).
147459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung * \param limit_ns          limit dump to data more recent than limit_ns (0 disables).
148459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung * \return
149459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung *   NO_ERROR on success or a negative number (-errno) on failure of write().
150459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung *   if power_log is NULL, BAD_VALUE is returned.
151459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung */
1523213c5e868e93241ac6af84c10f32d1f9e251392Andy Hungint power_log_dump(
1533213c5e868e93241ac6af84c10f32d1f9e251392Andy Hung        power_log_t *power_log, int fd, const char *prefix,  size_t lines, int64_t limit_ns);
154459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung
155459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung/**
156459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung * \brief Destroys the power log object.
157459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung *
158459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung * \param power_log         object returned by create, if NULL nothing happens.
159459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung */
160459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hungvoid power_log_destroy(power_log_t *power_log);
161459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung
162459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung/** \cond */
163459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung__END_DECLS
164459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung/** \endcond */
165459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung
166459a2a3cc5aced24c8d5fe5fb500af1194dca06eAndy Hung#endif // !ANDROID_AUDIO_POWER_LOG_H
167