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 
27 namespace 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  */
41 class PowerLog {
42 public:
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      * \param logPlot           true if a log plot is generated. This will result in
75      *                          additional 18 lines to be output.
76      * \return the std::string for the log.
77      */
78     std::string dumpToString(const char *prefix = "", size_t lines = 0, int64_t limitNs = 0,
79             bool logPlot = true) const;
80 
81     /**
82      * \brief Dumps the log to a raw file descriptor.
83      *
84      * \param fd                file descriptor to use.
85      * \param lines             maximum number of lines to output (0 disables).
86      * \param limitNs           limit dump to data more recent than limitNs (0 disables).
87      * \param logPlot           true if a log plot is generated. This will result in
88      *                          additional 18 lines to be output.
89      * \return
90      *   NO_ERROR on success or a negative number (-errno) on failure of write().
91      */
92     status_t dump(int fd, const char *prefix = "", size_t lines = 0, int64_t limitNs = 0,
93             bool logPlot = true) const;
94 
95 private:
96     mutable std::mutex mLock;     // monitor mutex
97     int64_t mCurrentTime;         // time of first frame in buffer
98     float mCurrentEnergy;         // local energy accumulation
99     size_t mCurrentFrames;        // number of frames in the energy
100     size_t mIdx;                  // next usable index in mEntries
101     size_t mConsecutiveZeroes;    // current run of consecutive zero entries
102     const uint32_t mSampleRate;   // audio data sample rate
103     const uint32_t mChannelCount; // audio data channel count
104     const audio_format_t mFormat; // audio data format
105     const size_t mFramesPerEntry; // number of audio frames per entry
106     std::vector<std::pair<int64_t /* real time ns */, float /* energy */>> mEntries;
107 };
108 
109 } // namespace android
110 
111 #endif // __cplusplus
112 
113 /** \cond */
114 __BEGIN_DECLS
115 /** \endcond */
116 
117 // C API (see C++ api above for details)
118 
119 typedef struct power_log_t power_log_t;
120 
121 /**
122  * \brief Creates a power log object.
123  *
124  * \param sample_rate       sample rate of the audio data.
125  * \param channel_count     channel count of the audio data.
126  * \param format            format of the audio data. It must be allowed by
127  *                          audio_utils_is_compute_power_format_supported().
128  * \param entries           total number of energy entries "bins" to use.
129  * \param frames_per_entry  total number of audio frames used in each entry.
130  *
131  * \return power log object or NULL on failure.
132  */
133 power_log_t *power_log_create(uint32_t sample_rate,
134         uint32_t channel_count, audio_format_t format, size_t entries, size_t frames_per_entry);
135 
136 /**
137  * \brief Adds new audio data to the power log.
138  *
139  * \param power_log         object returned by create, if NULL nothing happens.
140  * \param buffer            pointer to the audio data buffer.
141  * \param frames            buffer size in audio frames.
142  * \param now_ns            current time in nanoseconds.
143  */
144 void power_log_log(power_log_t *power_log, const void *buffer, size_t frames, int64_t now_ns);
145 
146 /**
147  * \brief Dumps the log to a raw file descriptor.
148  *
149  * A log plot is always generated, adding 18 more lines to the dump.
150  *
151  * \param power_log         object returned by create, if NULL nothing happens.
152  * \param fd                file descriptor to use.
153  * \param prefix            displayed at start of each line.
154  * \param lines             maximum number of lines to output (0 disables).
155  * \param limit_ns          limit dump to data more recent than limit_ns (0 disables).
156  * \return
157  *   NO_ERROR on success or a negative number (-errno) on failure of write().
158  *   if power_log is NULL, BAD_VALUE is returned.
159  */
160 int power_log_dump(
161         power_log_t *power_log, int fd, const char *prefix,  size_t lines, int64_t limit_ns);
162 
163 /**
164  * \brief Destroys the power log object.
165  *
166  * \param power_log         object returned by create, if NULL nothing happens.
167  */
168 void power_log_destroy(power_log_t *power_log);
169 
170 /** \cond */
171 __END_DECLS
172 /** \endcond */
173 
174 #endif // !ANDROID_AUDIO_POWER_LOG_H
175