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      * \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 
90 private:
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 
114 typedef 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  */
128 power_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  */
139 void 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 prefix            displayed at start of each line.
147  * \param lines             maximum number of lines to output (0 disables).
148  * \param limit_ns          limit dump to data more recent than limit_ns (0 disables).
149  * \return
150  *   NO_ERROR on success or a negative number (-errno) on failure of write().
151  *   if power_log is NULL, BAD_VALUE is returned.
152  */
153 int power_log_dump(
154         power_log_t *power_log, int fd, const char *prefix,  size_t lines, int64_t limit_ns);
155 
156 /**
157  * \brief Destroys the power log object.
158  *
159  * \param power_log         object returned by create, if NULL nothing happens.
160  */
161 void power_log_destroy(power_log_t *power_log);
162 
163 /** \cond */
164 __END_DECLS
165 /** \endcond */
166 
167 #endif // !ANDROID_AUDIO_POWER_LOG_H
168