1 /* 2 ** Copyright 2022, 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 // This library is used to help collect audio smoothness metrics from an 18 // implementation of an Audio Hardware Abstraction Layer (HAL). This is 19 // primarily used to count xruns and number of frames written and lost for an 20 // audio stream. 21 // 22 // To use this library, create an instance of the struct "hal_smoothness" using 23 // the "initialize()" method. The "client_flush_cb" callback method needs to be 24 // defined, which will be called when the library thinks it is time to flush 25 // metrics data, which is when "num_writes_to_logs" == "total_writes". The 26 // callback's purpose is so that the client can flush these metrics wherever 27 // it wants (ie. flushing it to a metrics server or to logcat). A 28 // "hal_smoothness_metrics" will be passed into it. After the callback has 29 // finished, all values will be set back to 0. 30 31 #pragma once 32 33 #include <sys/cdefs.h> 34 35 #define HAL_SMOOTHNESS_VERSION_1 1 36 37 __BEGIN_DECLS 38 39 // Audio HAL smoothness metrics that can be read by the client. These metrics, 40 // get reset after every flush to the client's callback. 41 struct hal_smoothness_metrics { 42 // Count of underruns, right before a flush. 43 unsigned int underrun_count; 44 45 // Count of overruns, right before a flush. 46 unsigned int overrun_count; 47 48 // Count of times audio samples are written to the endpoint buffer, right 49 // before a flush. 50 unsigned int total_writes; 51 52 // Total number of frames written, right before a flush. 53 unsigned int total_frames_written; 54 55 // Total number of frames lost, right before a flush. 56 unsigned int total_frames_lost; 57 58 // Smoothness value calculated by library right before calling the flush 59 // callback: 60 // -ln(total_frames_lost/(total_frames_written + total_frames_lost)) 61 // 62 // If "total_frames_lost" is 0, that would imply perfect audio quality in 63 // terms of no bytes were dropped. In this case, DBL_MAX will be returned. 64 double smoothness_value; 65 66 // Timestamp of when these metrics were flushed. It is up to the client to 67 // decide which clock and what granularity to use. However, it is recommended 68 // to use the system clock CLOCK_REALTIME. 69 unsigned long timestamp; 70 }; 71 72 // Used by the audio HAL implementor to help with collection of audio smoothness 73 // metrics. 74 struct hal_smoothness { 75 // Struct version. 76 unsigned int version; 77 78 // Increments “underrun_count” and "total_frames_lost". 79 // 80 // returns 0 if successful and non-zero on failure. 81 int (*increment_underrun)(struct hal_smoothness *smoothness, 82 unsigned int frames_lost); 83 84 // Increments “overrun_count” and "total_frames_lost". 85 // 86 // returns 0 if successful and non-zero on failure. 87 int (*increment_overrun)(struct hal_smoothness *smoothness, 88 unsigned int frames_lost); 89 90 // Increments “total_writes” and "total_frames_written". Once “total_writes >= 91 // num_writes_to_logs”, “client_flush_cb” will be triggered and all the ints 92 // in "hal_smoothness_metrics" will be reset to 0. 93 // 94 // returns 0 if successful and non-zero on failure. 95 int (*increment_total_writes)(struct hal_smoothness *smoothness, 96 unsigned int frames_written, 97 unsigned long timestamp); 98 99 // Manual flush. Will call "client_flush_cb" and reset "hal_smoothness_metrics". 100 int (*flush)(struct hal_smoothness *smoothness); 101 }; 102 103 // version: hal_smoothness library version. 104 // 105 // num_writes_to_log: number of writes before we flushing 106 // 107 // client_flush_cb: Client defined flush method. The library will pass in 108 // "hal_smoothness_metrics", which will be generated by the library, and 109 // "private_data", which is provided by the client. 110 // 111 // private_data: Client defined data that is passed into “client_flush_cb” 112 // 113 // returns 0 if successful and non-zero on failure. 114 int hal_smoothness_initialize( 115 struct hal_smoothness **smoothness, unsigned int version, 116 unsigned int num_writes_to_log, 117 void (*client_flush_cb)(struct hal_smoothness_metrics *, void *), 118 void *private_data); 119 120 void hal_smoothness_free(struct hal_smoothness **smoothness); 121 122 __END_DECLS 123