| /* |
| ** Copyright 2022, The Android Open-Source Project |
| ** |
| ** Licensed under the Apache License, Version 2.0 (the "License"); |
| ** you may not use this file except in compliance with the License. |
| ** You may obtain a copy of the License at |
| ** |
| ** http://www.apache.org/licenses/LICENSE-2.0 |
| ** |
| ** Unless required by applicable law or agreed to in writing, software |
| ** distributed under the License is distributed on an "AS IS" BASIS, |
| ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| ** See the License for the specific language governing permissions and |
| ** limitations under the License. |
| */ |
| |
| // This library is used to help collect audio smoothness metrics from an |
| // implementation of an Audio Hardware Abstraction Layer (HAL). This is |
| // primarily used to count xruns and number of frames written and lost for an |
| // audio stream. |
| // |
| // To use this library, create an instance of the struct "hal_smoothness" using |
| // the "initialize()" method. The "client_flush_cb" callback method needs to be |
| // defined, which will be called when the library thinks it is time to flush |
| // metrics data, which is when "num_writes_to_logs" == "total_writes". The |
| // callback's purpose is so that the client can flush these metrics wherever |
| // it wants (ie. flushing it to a metrics server or to logcat). A |
| // "hal_smoothness_metrics" will be passed into it. After the callback has |
| // finished, all values will be set back to 0. |
| |
| #pragma once |
| |
| #include <sys/cdefs.h> |
| |
| #define HAL_SMOOTHNESS_VERSION_1 1 |
| |
| __BEGIN_DECLS |
| |
| // Audio HAL smoothness metrics that can be read by the client. These metrics, |
| // get reset after every flush to the client's callback. |
| struct hal_smoothness_metrics { |
| // Count of underruns, right before a flush. |
| unsigned int underrun_count; |
| |
| // Count of overruns, right before a flush. |
| unsigned int overrun_count; |
| |
| // Count of times audio samples are written to the endpoint buffer, right |
| // before a flush. |
| unsigned int total_writes; |
| |
| // Total number of frames written, right before a flush. |
| unsigned int total_frames_written; |
| |
| // Total number of frames lost, right before a flush. |
| unsigned int total_frames_lost; |
| |
| // Smoothness value calculated by library right before calling the flush |
| // callback: |
| // -ln(total_frames_lost/(total_frames_written + total_frames_lost)) |
| // |
| // If "total_frames_lost" is 0, that would imply perfect audio quality in |
| // terms of no bytes were dropped. In this case, DBL_MAX will be returned. |
| double smoothness_value; |
| |
| // Timestamp of when these metrics were flushed. It is up to the client to |
| // decide which clock and what granularity to use. However, it is recommended |
| // to use the system clock CLOCK_REALTIME. |
| unsigned long timestamp; |
| }; |
| |
| // Used by the audio HAL implementor to help with collection of audio smoothness |
| // metrics. |
| struct hal_smoothness { |
| // Struct version. |
| unsigned int version; |
| |
| // Increments “underrun_count” and "total_frames_lost". |
| // |
| // returns 0 if successful and non-zero on failure. |
| int (*increment_underrun)(struct hal_smoothness *smoothness, |
| unsigned int frames_lost); |
| |
| // Increments “overrun_count” and "total_frames_lost". |
| // |
| // returns 0 if successful and non-zero on failure. |
| int (*increment_overrun)(struct hal_smoothness *smoothness, |
| unsigned int frames_lost); |
| |
| // Increments “total_writes” and "total_frames_written". Once “total_writes >= |
| // num_writes_to_logs”, “client_flush_cb” will be triggered and all the ints |
| // in "hal_smoothness_metrics" will be reset to 0. |
| // |
| // returns 0 if successful and non-zero on failure. |
| int (*increment_total_writes)(struct hal_smoothness *smoothness, |
| unsigned int frames_written, |
| unsigned long timestamp); |
| |
| // Manual flush. Will call "client_flush_cb" and reset "hal_smoothness_metrics". |
| int (*flush)(struct hal_smoothness *smoothness); |
| }; |
| |
| // version: hal_smoothness library version. |
| // |
| // num_writes_to_log: number of writes before we flushing |
| // |
| // client_flush_cb: Client defined flush method. The library will pass in |
| // "hal_smoothness_metrics", which will be generated by the library, and |
| // "private_data", which is provided by the client. |
| // |
| // private_data: Client defined data that is passed into “client_flush_cb” |
| // |
| // returns 0 if successful and non-zero on failure. |
| int hal_smoothness_initialize( |
| struct hal_smoothness **smoothness, unsigned int version, |
| unsigned int num_writes_to_log, |
| void (*client_flush_cb)(struct hal_smoothness_metrics *, void *), |
| void *private_data); |
| |
| void hal_smoothness_free(struct hal_smoothness **smoothness); |
| |
| __END_DECLS |