1*aef9bcd9SKiyoung Kim /* 2*aef9bcd9SKiyoung Kim * Copyright (C) 2014 - 2017 Sony Corporation 3*aef9bcd9SKiyoung Kim * 4*aef9bcd9SKiyoung Kim * Licensed under the Apache License, Version 2.0 (the "License"); 5*aef9bcd9SKiyoung Kim * you may not use this file except in compliance with the License. 6*aef9bcd9SKiyoung Kim * You may obtain a copy of the License at 7*aef9bcd9SKiyoung Kim * 8*aef9bcd9SKiyoung Kim * http://www.apache.org/licenses/LICENSE-2.0 9*aef9bcd9SKiyoung Kim * 10*aef9bcd9SKiyoung Kim * Unless required by applicable law or agreed to in writing, software 11*aef9bcd9SKiyoung Kim * distributed under the License is distributed on an "AS IS" BASIS, 12*aef9bcd9SKiyoung Kim * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*aef9bcd9SKiyoung Kim * See the License for the specific language governing permissions and 14*aef9bcd9SKiyoung Kim * limitations under the License. 15*aef9bcd9SKiyoung Kim */ 16*aef9bcd9SKiyoung Kim 17*aef9bcd9SKiyoung Kim #ifndef _LDACBT_ABR_H_ 18*aef9bcd9SKiyoung Kim #define _LDACBT_ABR_H_ 19*aef9bcd9SKiyoung Kim 20*aef9bcd9SKiyoung Kim /* This file contains the definitions, declarations and macros for an implementation of 21*aef9bcd9SKiyoung Kim * LDAC Adaptive Bit Rate (hereinafter ABR) processing. 22*aef9bcd9SKiyoung Kim * 23*aef9bcd9SKiyoung Kim * The basic flow of the ABR processing is as follows: 24*aef9bcd9SKiyoung Kim * - The program creates a handle of LDAC ABR API using ldac_ABR_get_handle(). 25*aef9bcd9SKiyoung Kim * - The program initializes the handle by setting the ldac_ABR_Proc() call interval to 26*aef9bcd9SKiyoung Kim * ldac_ABR_Init(). 27*aef9bcd9SKiyoung Kim * The interval shall be as short as possible at the timing without accumulation 28*aef9bcd9SKiyoung Kim * of packet in the buffer if propagation environment is fine. 29*aef9bcd9SKiyoung Kim * - The program reinitializes the handle by calling ldac_ABR_Init() again when the 30*aef9bcd9SKiyoung Kim * state of the TX queue changes greatly, such as clearing the queue. 31*aef9bcd9SKiyoung Kim * - If the program demands to control the thresholds, then ldac_ABR_set_thresholds() 32*aef9bcd9SKiyoung Kim * should be called. 33*aef9bcd9SKiyoung Kim * - The program sets flagEnable to "1" when allowing LDAC encode bitrate to be 34*aef9bcd9SKiyoung Kim * adjusted by ABR, and sets it to "0" if it is not allowed. 35*aef9bcd9SKiyoung Kim * - The program calls ldac_ABR_Proc() at the interval set to ldac_ABR_Init() even if 36*aef9bcd9SKiyoung Kim * flagEnable is "0". 37*aef9bcd9SKiyoung Kim * The program passes TxQueueDepth and flagEnable to ldac_ABR_Proc() at this call, 38*aef9bcd9SKiyoung Kim * LDAC encode bitrate is adjusted only when flagEnable is "1". 39*aef9bcd9SKiyoung Kim * Otherwise, the internal parameters are updated and analyzed then returned. 40*aef9bcd9SKiyoung Kim * The ABR handle adjusts eqmid based on TxQueueDepth which is passed from the program. 41*aef9bcd9SKiyoung Kim * The ABR handle calls LDAC encode API ldacBT_alter_eqmid_priority() to adjust eqmid. 42*aef9bcd9SKiyoung Kim * The ABR handle calls LDAC encode API ldacBT_get_eqmid() to get current eqmid. 43*aef9bcd9SKiyoung Kim * - The handle may be released with ldac_ABR_free_handle(). 44*aef9bcd9SKiyoung Kim * 45*aef9bcd9SKiyoung Kim * Notes on debugging LDAC ABR: 46*aef9bcd9SKiyoung Kim * The meaning of "works fine" is that the bit rate will be low in case of bad radio situation 47*aef9bcd9SKiyoung Kim * and high in case of good radio situation. 48*aef9bcd9SKiyoung Kim * 49*aef9bcd9SKiyoung Kim * The bit rate transition can be debug by checking logcat messages from LDAC ABR library which 50*aef9bcd9SKiyoung Kim * built with the following changes in Android.bp: 51*aef9bcd9SKiyoung Kim * - Adding "liblog" to shared_libs. 52*aef9bcd9SKiyoung Kim * - Adding "-DLOCAL_DEBUG" to cflags. 53*aef9bcd9SKiyoung Kim * The messages are formated as follows: 54*aef9bcd9SKiyoung Kim * [LDAC ABR] - abrQualityModeID : 0 -- eqmid : 0 -- TxQue : 0 55*aef9bcd9SKiyoung Kim * where abrQualityModeID and eqmid related to the current bit rate and TxQue shows the depth 56*aef9bcd9SKiyoung Kim * of current Tx queue. 57*aef9bcd9SKiyoung Kim * The relationship between abrQualityModeID, eqmid and the bit rate is described in 58*aef9bcd9SKiyoung Kim * "ldacBT_abr.c". 59*aef9bcd9SKiyoung Kim * 60*aef9bcd9SKiyoung Kim * The bit rate transition can be estimated/debug by listening to the audio played on the SNK 61*aef9bcd9SKiyoung Kim * device. This method cannot use to confirm the details of the bit rate transition, but useful 62*aef9bcd9SKiyoung Kim * to know how LDAC ABR algorithm works in a field test without checking the log. 63*aef9bcd9SKiyoung Kim * To try this method, rebuilding of the "libldacBT_enc" library with the following change in 64*aef9bcd9SKiyoung Kim * Android.bp is required: 65*aef9bcd9SKiyoung Kim * - Adding "-DUSE_LDAC_ENC_SETTING_FOR_ABR_DEBUG" to cflags. 66*aef9bcd9SKiyoung Kim * By defining the above macro, the lower the bit rate, the greatly lower the bandwidth of the audio 67*aef9bcd9SKiyoung Kim * played on the SNK device. Therefore, the audio played on the SNK device will sounds like a 68*aef9bcd9SKiyoung Kim * low-pass filtered sound when the bit rate is low and will sounds as usual when the bit rate is 69*aef9bcd9SKiyoung Kim * enough high. It is recommend using sound such as white noise to hear those changes for the first 70*aef9bcd9SKiyoung Kim * time. 71*aef9bcd9SKiyoung Kim * 72*aef9bcd9SKiyoung Kim * IMPORTANT: 73*aef9bcd9SKiyoung Kim * These libraries modified as described above shall be used only to confirm the bit rate transition 74*aef9bcd9SKiyoung Kim * and SHALL NOT BE USED FOR FINAL PRODUCTS. 75*aef9bcd9SKiyoung Kim */ 76*aef9bcd9SKiyoung Kim 77*aef9bcd9SKiyoung Kim #ifdef __cplusplus 78*aef9bcd9SKiyoung Kim extern "C" { 79*aef9bcd9SKiyoung Kim #endif 80*aef9bcd9SKiyoung Kim 81*aef9bcd9SKiyoung Kim #ifndef LDAC_ABR_API 82*aef9bcd9SKiyoung Kim #define LDAC_ABR_API 83*aef9bcd9SKiyoung Kim #endif /* LDAC_ABR_API */ 84*aef9bcd9SKiyoung Kim 85*aef9bcd9SKiyoung Kim #include <ldacBT.h> /* HANDLE_LDAC_BT */ 86*aef9bcd9SKiyoung Kim 87*aef9bcd9SKiyoung Kim /* LDAC ABR handle type*/ 88*aef9bcd9SKiyoung Kim typedef struct _ldacbt_abr_param * HANDLE_LDAC_ABR; 89*aef9bcd9SKiyoung Kim 90*aef9bcd9SKiyoung Kim /* Allocation of LDAC ABR handle. 91*aef9bcd9SKiyoung Kim * Format 92*aef9bcd9SKiyoung Kim * HANDLE_LDAC_ABR ldacBT_get_handle( void ); 93*aef9bcd9SKiyoung Kim * Arguments 94*aef9bcd9SKiyoung Kim * None. 95*aef9bcd9SKiyoung Kim * Return value 96*aef9bcd9SKiyoung Kim * HANDLE_LDAC_ABR for success, NULL for failure. 97*aef9bcd9SKiyoung Kim */ 98*aef9bcd9SKiyoung Kim LDAC_ABR_API HANDLE_LDAC_ABR ldac_ABR_get_handle(void); 99*aef9bcd9SKiyoung Kim 100*aef9bcd9SKiyoung Kim /* Release of LDAC ABR handle. 101*aef9bcd9SKiyoung Kim * Format 102*aef9bcd9SKiyoung Kim * void ldac_ABR_free_handle( HANDLE_LDAC_ABR ); 103*aef9bcd9SKiyoung Kim * Arguments 104*aef9bcd9SKiyoung Kim * hLdacAbr HANDLE_LDAC_ABR LDAC ABR handle. 105*aef9bcd9SKiyoung Kim * Return value 106*aef9bcd9SKiyoung Kim * None. 107*aef9bcd9SKiyoung Kim */ 108*aef9bcd9SKiyoung Kim LDAC_ABR_API void ldac_ABR_free_handle(HANDLE_LDAC_ABR hLdacAbr); 109*aef9bcd9SKiyoung Kim 110*aef9bcd9SKiyoung Kim /* Initialize LDAC ABR. 111*aef9bcd9SKiyoung Kim * Format 112*aef9bcd9SKiyoung Kim * int ldac_ABR_Init( HANDLE_LDAC_ABR, unsigned int ); 113*aef9bcd9SKiyoung Kim * Arguments 114*aef9bcd9SKiyoung Kim * hLdacAbr HANDLE_LDAC_ABR LDAC ABR handle. 115*aef9bcd9SKiyoung Kim * interval_ms unsigned int interval in ms for calling ldac_ABR_Proc(). 116*aef9bcd9SKiyoung Kim * interval of 1ms to 500ms is valid. 117*aef9bcd9SKiyoung Kim * Return value 118*aef9bcd9SKiyoung Kim * int: 0 for success, -1 for failure. 119*aef9bcd9SKiyoung Kim */ 120*aef9bcd9SKiyoung Kim LDAC_ABR_API int ldac_ABR_Init(HANDLE_LDAC_ABR hLdacAbr, unsigned int interval_ms); 121*aef9bcd9SKiyoung Kim 122*aef9bcd9SKiyoung Kim /* Setup thresholds for LDAC ABR. 123*aef9bcd9SKiyoung Kim * Format 124*aef9bcd9SKiyoung Kim * int ldac_ABR_set_thresholds( HANDLE_LDAC_ABR, unsigned int, unsigned int, unsigned int ); 125*aef9bcd9SKiyoung Kim * Arguments 126*aef9bcd9SKiyoung Kim * hLdacAbr HANDLE_LDAC_ABR LDAC ABR handle. 127*aef9bcd9SKiyoung Kim * thCritical unsigned int threshold for critical TxQueueDepth status. 128*aef9bcd9SKiyoung Kim * thDangerousTrend unsigned int threshold for dangerous trend of TxQueueDepth. 129*aef9bcd9SKiyoung Kim * thSafety4HQSQ unsigned int safety threshold for LDACBT_EQMID_HQ and 130*aef9bcd9SKiyoung Kim * LDACBT_EQMID_SQ. 131*aef9bcd9SKiyoung Kim * Return value 132*aef9bcd9SKiyoung Kim * int: 0 for success, -1 for failure. 133*aef9bcd9SKiyoung Kim * Remarks 134*aef9bcd9SKiyoung Kim * Those thresholds should be the number of packets stored in the TX queue and should be 135*aef9bcd9SKiyoung Kim * greater than 0. 136*aef9bcd9SKiyoung Kim * The thCritical and thDangerousTrend are used for all eqmid and thSafety4HQSQ is used 137*aef9bcd9SKiyoung Kim * only for LDACBT_EQMID_HQ and LDACBT_EQMID_SQ. Therefore, those thresholds must satisfy 138*aef9bcd9SKiyoung Kim * the following releationship: 139*aef9bcd9SKiyoung Kim * thCritical >= thDangerousTrend >= thSafety4HQSQ 140*aef9bcd9SKiyoung Kim */ 141*aef9bcd9SKiyoung Kim LDAC_ABR_API int ldac_ABR_set_thresholds(HANDLE_LDAC_ABR hLdacAbr, unsigned int thCritical, 142*aef9bcd9SKiyoung Kim unsigned int thDangerousTrend, unsigned int thSafety4HQSQ); 143*aef9bcd9SKiyoung Kim 144*aef9bcd9SKiyoung Kim /* LDAC ABR main process. 145*aef9bcd9SKiyoung Kim * Format 146*aef9bcd9SKiyoung Kim * int ldac_ABR_Proc( HANDLE_LDAC_BT, HANDLE_LDAC_ABR, unsigned int, unsigned int ); 147*aef9bcd9SKiyoung Kim * Arguments 148*aef9bcd9SKiyoung Kim * hLdacBt HANDLE_LDAC_BT LDAC handle. 149*aef9bcd9SKiyoung Kim * hLdacAbr HANDLE_LDAC_ABR LDAC ABR handle. 150*aef9bcd9SKiyoung Kim * TxQueueDepth unsigned int depth of TX queue. 151*aef9bcd9SKiyoung Kim * flagEnable unsigned int flag indicating whether ABR is allowed to adjust LDAC 152*aef9bcd9SKiyoung Kim * encode bitrate 153*aef9bcd9SKiyoung Kim * Return value 154*aef9bcd9SKiyoung Kim * int: updated Encode Quality Mode Index for success, -1 for failure. 155*aef9bcd9SKiyoung Kim */ 156*aef9bcd9SKiyoung Kim LDAC_ABR_API int ldac_ABR_Proc(HANDLE_LDAC_BT hLdacBt, HANDLE_LDAC_ABR hLdacAbr, 157*aef9bcd9SKiyoung Kim unsigned int TxQueueDepth, unsigned int flagEnable); 158*aef9bcd9SKiyoung Kim #ifdef __cplusplus 159*aef9bcd9SKiyoung Kim } 160*aef9bcd9SKiyoung Kim #endif 161*aef9bcd9SKiyoung Kim 162*aef9bcd9SKiyoung Kim #endif /* _LDACBT_ABR_H_ */ 163*aef9bcd9SKiyoung Kim 164