1/*
2 * Copyright 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef ANDROID_AUDIO_POWER_LOG_H
18#define ANDROID_AUDIO_POWER_LOG_H
19
20#ifdef __cplusplus
21
22#include <mutex>
23#include <vector>
24#include <system/audio.h>
25#include <utils/Errors.h>
26
27namespace android {
28
29/**
30 * PowerLog captures the audio data power (measured in dBFS) over time.
31 *
32 * For the purposes of power evaluation, the audio data is divided into "bins",
33 * and grouped by signals consisting of consecutive non-zero energy bins.
34 * The sum energy in dB of each signal is computed for comparison purposes.
35 *
36 * No distinction is made between channels in an audio frame; they are all
37 * summed together for energy purposes.
38 *
39 * The public methods are internally protected by a mutex to be thread-safe.
40 */
41class PowerLog {
42public:
43    /**
44     * \brief Creates a PowerLog object.
45     *
46     * \param sampleRate        sample rate of the audio data.
47     * \param channelCount      channel count of the audio data.
48     * \param format            format of the audio data. It must be allowed by
49     *                          audio_utils_is_compute_power_format_supported()
50     *                          else the constructor will abort.
51     * \param entries           total number of energy entries "bins" to use.
52     * \param framesPerEntry    total number of audio frames used in each entry.
53     */
54    PowerLog(uint32_t sampleRate,
55            uint32_t channelCount,
56            audio_format_t format,
57            size_t entries,
58            size_t framesPerEntry);
59
60    /**
61     * \brief Adds new audio data to the power log.
62     *
63     * \param buffer            pointer to the audio data buffer.
64     * \param frames            buffer size in audio frames.
65     * \param nowNs             current time in nanoseconds.
66     */
67    void log(const void *buffer, size_t frames, int64_t nowNs);
68
69    /**
70     * \brief Dumps the log to a std::string.
71     *
72     * \param lines             maximum number of lines to output (0 disables).
73     * \param limitNs           limit dump to data more recent than limitNs (0 disables).
74     * \return the std::string for the log.
75     */
76    std::string dumpToString(
77            const char *prefix = "", size_t lines = 0, int64_t limitNs = 0) const;
78
79    /**
80     * \brief Dumps the log to a raw file descriptor.
81     *
82     * \param fd                file descriptor to use.
83     * \param lines             maximum number of lines to output (0 disables).
84     * \param limitNs           limit dump to data more recent than limitNs (0 disables).
85     * \return
86     *   NO_ERROR on success or a negative number (-errno) on failure of write().
87     */
88    status_t dump(int fd, const char *prefix = "", size_t lines = 0, int64_t limitNs = 0) const;
89
90private:
91    mutable std::mutex mLock;     // monitor mutex
92    int64_t mCurrentTime;         // time of first frame in buffer
93    float mCurrentEnergy;         // local energy accumulation
94    size_t mCurrentFrames;        // number of frames in the energy
95    size_t mIdx;                  // next usable index in mEntries
96    size_t mConsecutiveZeroes;    // current run of consecutive zero entries
97    const uint32_t mSampleRate;   // audio data sample rate
98    const uint32_t mChannelCount; // audio data channel count
99    const audio_format_t mFormat; // audio data format
100    const size_t mFramesPerEntry; // number of audio frames per entry
101    std::vector<std::pair<int64_t /* real time ns */, float /* energy */>> mEntries;
102};
103
104} // namespace android
105
106#endif // __cplusplus
107
108/** \cond */
109__BEGIN_DECLS
110/** \endcond */
111
112// C API (see C++ api above for details)
113
114typedef struct power_log_t power_log_t;
115
116/**
117 * \brief Creates a power log object.
118 *
119 * \param sample_rate       sample rate of the audio data.
120 * \param channel_count     channel count of the audio data.
121 * \param format            format of the audio data. It must be allowed by
122 *                          audio_utils_is_compute_power_format_supported().
123 * \param entries           total number of energy entries "bins" to use.
124 * \param frames_per_entry  total number of audio frames used in each entry.
125 *
126 * \return power log object or NULL on failure.
127 */
128power_log_t *power_log_create(uint32_t sample_rate,
129        uint32_t channel_count, audio_format_t format, size_t entries, size_t frames_per_entry);
130
131/**
132 * \brief Adds new audio data to the power log.
133 *
134 * \param power_log         object returned by create, if NULL nothing happens.
135 * \param buffer            pointer to the audio data buffer.
136 * \param frames            buffer size in audio frames.
137 * \param now_ns            current time in nanoseconds.
138 */
139void power_log_log(power_log_t *power_log, const void *buffer, size_t frames, int64_t now_ns);
140
141/**
142 * \brief Dumps the log to a raw file descriptor.
143 *
144 * \param power_log         object returned by create, if NULL nothing happens.
145 * \param fd                file descriptor to use.
146 * \param lines             maximum number of lines to output (0 disables).
147 * \param limit_ns          limit dump to data more recent than limit_ns (0 disables).
148 * \return
149 *   NO_ERROR on success or a negative number (-errno) on failure of write().
150 *   if power_log is NULL, BAD_VALUE is returned.
151 */
152int power_log_dump(
153        power_log_t *power_log, int fd, const char *prefix,  size_t lines, int64_t limit_ns);
154
155/**
156 * \brief Destroys the power log object.
157 *
158 * \param power_log         object returned by create, if NULL nothing happens.
159 */
160void power_log_destroy(power_log_t *power_log);
161
162/** \cond */
163__END_DECLS
164/** \endcond */
165
166#endif // !ANDROID_AUDIO_POWER_LOG_H
167