diff options
author | Chisato Kenmochi <Chisato.Kenmochi@sony.com> | 2017-03-28 05:10:23 +0000 |
---|---|---|
committer | android-build-merger <android-build-merger@google.com> | 2017-03-28 05:10:23 +0000 |
commit | 147d610ad346a9895c0e5776fd5169780c98ab9f (patch) | |
tree | 8c841292dbdb5f6b5e611b971cff0808cd062a9d | |
parent | 9e776a0f9f9524932a6e15a16c7de72920a17c56 (diff) | |
parent | b4f70c5b723ddd3e7b4785e81cb0120d5d8fd861 (diff) | |
download | libldac-147d610ad346a9895c0e5776fd5169780c98ab9f.tar.gz |
Contribution of LDAC Adaptive Bit Rate am: 878aad2a83
am: b4f70c5b72
Change-Id: Ia9a0cbf958274082652dd0f2e60accb91b8f964c
-rw-r--r-- | Android.bp | 13 | ||||
-rw-r--r-- | abr/inc/ldacBT_abr.h | 163 | ||||
-rw-r--r-- | abr/src/ldacBT_abr.c | 355 | ||||
-rw-r--r-- | src/ldaclib_api.c | 15 |
4 files changed, 546 insertions, 0 deletions
@@ -14,3 +14,16 @@ cc_library_shared { // unit such as ARM Cortex-R series or external 32-bit DSPs. cflags: ["-O2", "-Werror", "-Wall", "-Wextra"], } + +cc_library_shared { + name: "libldacBT_abr", + arch: { + arm: { + instruction_set: "arm", + }, + }, + export_include_dirs: ["abr/inc"], + srcs: ["abr/src/ldacBT_abr.c"], + shared_libs: ["libldacBT_enc"], + cflags: ["-O2", "-Werror", "-Wall", "-Wextra"] +} diff --git a/abr/inc/ldacBT_abr.h b/abr/inc/ldacBT_abr.h new file mode 100644 index 0000000..135238f --- /dev/null +++ b/abr/inc/ldacBT_abr.h @@ -0,0 +1,163 @@ +/* + * Copyright (C) 2014 - 2017 Sony Corporation + * + * 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. + */ + +#ifndef _LDACBT_ABR_H_ +#define _LDACBT_ABR_H_ + +/* This file contains the definitions, declarations and macros for an implementation of + * LDAC Adaptive Bit Rate (hereinafter ABR) processing. + * + * The basic flow of the ABR processing is as follows: + * - The program creates a handle of LDAC ABR API using ldac_ABR_get_handle(). + * - The program initializes the handle by setting the ldac_ABR_Proc() call interval to + * ldac_ABR_Init(). + * The interval shall be as short as possible at the timing without accumulation + * of packet in the buffer if propagation environment is fine. + * - The program reinitializes the handle by calling ldac_ABR_Init() again when the + * state of the TX queue changes greatly, such as clearing the queue. + * - If the program demands to control the thresholds, then ldac_ABR_set_thresholds() + * should be called. + * - The program sets flagEnable to "1" when allowing LDAC encode bitrate to be + * adjusted by ABR, and sets it to "0" if it is not allowed. + * - The program calls ldac_ABR_Proc() at the interval set to ldac_ABR_Init() even if + * flagEnable is "0". + * The program passes TxQueueDepth and flagEnable to ldac_ABR_Proc() at this call, + * LDAC encode bitrate is adjusted only when flagEnable is "1". + * Otherwise, the internal parameters are updated and analyzed then returned. + * The ABR handle adjusts eqmid based on TxQueueDepth which is passed from the program. + * The ABR handle calls LDAC encode API ldacBT_alter_eqmid_priority() to adjust eqmid. + * The ABR handle calls LDAC encode API ldacBT_get_eqmid() to get current eqmid. + * - The handle may be released with ldac_ABR_free_handle(). + * + * Notes on debugging LDAC ABR: + * The meaning of "works fine" is that the bit rate will be low in case of bad radio situation + * and high in case of good radio situation. + * + * The bit rate transition can be debug by checking logcat messages from LDAC ABR library which + * built with the following changes in Android.bp: + * - Adding "liblog" to shared_libs. + * - Adding "-DLOCAL_DEBUG" to cflags. + * The messages are formated as follows: + * [LDAC ABR] - abrQualityModeID : 0 -- eqmid : 0 -- TxQue : 0 + * where abrQualityModeID and eqmid related to the current bit rate and TxQue shows the depth + * of current Tx queue. + * The relationship between abrQualityModeID, eqmid and the bit rate is described in + * "ldacBT_abr.c". + * + * The bit rate transition can be estimated/debug by listening to the audio played on the SNK + * device. This method cannot use to confirm the details of the bit rate transition, but useful + * to know how LDAC ABR algorithm works in a field test without checking the log. + * To try this method, rebuilding of the "libldacBT_enc" library with the following change in + * Android.bp is required: + * - Adding "-DUSE_LDAC_ENC_SETTING_FOR_ABR_DEBUG" to cflags. + * By defining the above macro, the lower the bit rate, the greatly lower the bandwidth of the audio + * played on the SNK device. Therefore, the audio played on the SNK device will sounds like a + * low-pass filtered sound when the bit rate is low and will sounds as usual when the bit rate is + * enough high. It is recommend using sound such as white noise to hear those changes for the first + * time. + * + * IMPORTANT: + * These libraries modified as described above shall be used only to confirm the bit rate transition + * and SHALL NOT BE USED FOR FINAL PRODUCTS. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef LDAC_ABR_API +#define LDAC_ABR_API +#endif /* LDAC_ABR_API */ + +#include <ldacBT.h> /* HANDLE_LDAC_BT */ + +/* LDAC ABR handle type*/ +typedef struct _ldacbt_abr_param * HANDLE_LDAC_ABR; + +/* Allocation of LDAC ABR handle. + * Format + * HANDLE_LDAC_ABR ldacBT_get_handle( void ); + * Arguments + * None. + * Return value + * HANDLE_LDAC_ABR for success, NULL for failure. + */ +LDAC_ABR_API HANDLE_LDAC_ABR ldac_ABR_get_handle(void); + +/* Release of LDAC ABR handle. + * Format + * void ldac_ABR_free_handle( HANDLE_LDAC_ABR ); + * Arguments + * hLdacAbr HANDLE_LDAC_ABR LDAC ABR handle. + * Return value + * None. + */ +LDAC_ABR_API void ldac_ABR_free_handle(HANDLE_LDAC_ABR hLdacAbr); + +/* Initialize LDAC ABR. + * Format + * int ldac_ABR_Init( HANDLE_LDAC_ABR, unsigned int ); + * Arguments + * hLdacAbr HANDLE_LDAC_ABR LDAC ABR handle. + * interval_ms unsigned int interval in ms for calling ldac_ABR_Proc(). + * interval of 1ms to 500ms is valid. + * Return value + * int: 0 for success, -1 for failure. + */ +LDAC_ABR_API int ldac_ABR_Init(HANDLE_LDAC_ABR hLdacAbr, unsigned int interval_ms); + +/* Setup thresholds for LDAC ABR. + * Format + * int ldac_ABR_set_thresholds( HANDLE_LDAC_ABR, unsigned int, unsigned int, unsigned int ); + * Arguments + * hLdacAbr HANDLE_LDAC_ABR LDAC ABR handle. + * thCritical unsigned int threshold for critical TxQueueDepth status. + * thDangerousTrend unsigned int threshold for dangerous trend of TxQueueDepth. + * thSafety4HQSQ unsigned int safety threshold for LDACBT_EQMID_HQ and + * LDACBT_EQMID_SQ. + * Return value + * int: 0 for success, -1 for failure. + * Remarks + * Those thresholds should be the number of packets stored in the TX queue and should be + * greater than 0. + * The thCritical and thDangerousTrend are used for all eqmid and thSafety4HQSQ is used + * only for LDACBT_EQMID_HQ and LDACBT_EQMID_SQ. Therefore, those thresholds must satisfy + * the following releationship: + * thCritical >= thDangerousTrend >= thSafety4HQSQ + */ +LDAC_ABR_API int ldac_ABR_set_thresholds(HANDLE_LDAC_ABR hLdacAbr, unsigned int thCritical, + unsigned int thDangerousTrend, unsigned int thSafety4HQSQ); + +/* LDAC ABR main process. + * Format + * int ldac_ABR_Proc( HANDLE_LDAC_BT, HANDLE_LDAC_ABR, unsigned int, unsigned int ); + * Arguments + * hLdacBt HANDLE_LDAC_BT LDAC handle. + * hLdacAbr HANDLE_LDAC_ABR LDAC ABR handle. + * TxQueueDepth unsigned int depth of TX queue. + * flagEnable unsigned int flag indicating whether ABR is allowed to adjust LDAC + * encode bitrate + * Return value + * int: updated Encode Quality Mode Index for success, -1 for failure. + */ +LDAC_ABR_API int ldac_ABR_Proc(HANDLE_LDAC_BT hLdacBt, HANDLE_LDAC_ABR hLdacAbr, + unsigned int TxQueueDepth, unsigned int flagEnable); +#ifdef __cplusplus +} +#endif + +#endif /* _LDACBT_ABR_H_ */ + diff --git a/abr/src/ldacBT_abr.c b/abr/src/ldacBT_abr.c new file mode 100644 index 0000000..b9bf4be --- /dev/null +++ b/abr/src/ldacBT_abr.c @@ -0,0 +1,355 @@ +/* + * Copyright (C) 2014 - 2017 Sony Corporation + * + * 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. + */ + +#include "ldacBT_abr.h" + +#include <stdlib.h> +#include <string.h> + +#define LDAC_ABR_OBSERVING_TIME_MS 500 /* [ms] the time length for storing Tx Queue Depth */ +#define LDAC_ABR_PENALTY_MAX 4 + +/* Number of observing count to judge whether EQMID may be increase. + * Those count can convert in time by following formula: + * Time [ms] = (Count - abrQualityModeID) * LDAC_ABR_OBSERVING_TIME_MS + * where abrQualityModeID is the value which converted EQMID by aEqmidToAbrQualityModeID[]. + * Therefore, using the default value of 12, the observation time in each abrQualityModeID is + * as follows: + * ---------------------------------------------------- + * | abrQualityModeID | 0 | 1 | 2 | 3 | 4 | + * | observation time [s] | 6 | 5 | 4 | 3 | 2 | + * ---------------------------------------------------- + */ +#define LDAC_ABR_OBSERVING_COUNT_TO_JUDGE_INC_QUALITY 12 +#define LDAC_ABR_OBSERVING_COUNT_FOR_INIT 6 /* = 3sec. keep same EQMID in first 3sec */ +/* Default value for thresholds */ +#define LDAC_ABR_THRESHOLD_CRITICAL_DEFAULT 6 +#define LDAC_ABR_THRESHOLD_DANGEROUSTREND_DEFAULT 4 +#define LDAC_ABR_THRESHOLD_SAFETY_FOR_HQSQ_DEFAULT 2 +/* Number of steady state count to judge */ +#define LDAC_ABR_NUM_STEADY_STATE_TO_JUDGE_STEADY 3 +/* Number of steady state count to reset for LDACBT_EQMID_HQ */ +#define LDAC_ABR_NUM_STEADY_STATE_TO_RESET_PENALTY_FOR_HQ 60 + + +typedef struct _tx_queue_param +{ + unsigned char *pHist; + unsigned int szHist; + int sum; + unsigned int cnt; + unsigned int idx; +} TxQ_INFO; + +typedef struct _ldacbt_abr_param +{ + TxQ_INFO TxQD_Info; + int cntToIncQuality; + int nSteadyState; + int nPenalty; + int abrQualityModeIdSteady; + unsigned int numToEvaluate; + /* thresholds */ + unsigned int thCritical; + unsigned int thDangerousTrend; + unsigned int thSafety4HQSQ; +} LDAC_ABR_PARAMS; + +#define clear_data(ptr, n) memset(ptr, 0, n) + +#ifdef LOCAL_DEBUG +#include <android/log.h> +#define ABRDBG(fmt, ... ) \ + __android_log_print( ANDROID_LOG_INFO, "******** LDAC ABR ********",\ + "%s@%s:%d::"fmt, __func__, __FILE__, __LINE__, ## __VA_ARGS__ ) +#else +#define ABRDBG(fmt, ...) +#endif /* LOCAL_DEBUG */ + +/* A table for converting EQMID to abrQualityModeID which is sorted in descending order by bit rate. + * The relationship between EQMID, bit rate and abrQualityModeID when the sampling frequency is + * 96 kHz is as follows: + * ---------------------------------------------------- + * | EQMID | 0 | 1 | 2 | 3 | 4 | + * | bit rate [kbps] | 990 | 660 | 330 | 492 | 396 | + * | abrQualityModeID | 0 | 1 | 4 | 2 | 3 | + * ---------------------------------------------------- + */ +static const int aEqmidToAbrQualityModeID[]={ 0, 1, 4, 2, 3}; +static const int sizeOfEqmidToBitrateSortedIdTable = (int)(sizeof(aEqmidToAbrQualityModeID) + / sizeof(aEqmidToAbrQualityModeID[0])); + +/* Get LDAC ABR handle */ +HANDLE_LDAC_ABR ldac_ABR_get_handle(void) +{ + HANDLE_LDAC_ABR hLdacAbr; + ABRDBG( "" ); + if ((hLdacAbr = (HANDLE_LDAC_ABR)malloc(sizeof(LDAC_ABR_PARAMS))) == NULL) { + ABRDBG( "[ERR] Failed to allocate memory for handle." ); + return NULL; + } + hLdacAbr->TxQD_Info.pHist = NULL; + return hLdacAbr; +} + +/* Free LDAC ABR handle */ +void ldac_ABR_free_handle(HANDLE_LDAC_ABR hLdacAbr) +{ + ABRDBG( "" ); + if (hLdacAbr != NULL) { + if (hLdacAbr->TxQD_Info.pHist) { + free(hLdacAbr->TxQD_Info.pHist); + } + free(hLdacAbr); + } +} + +/* Initialize LDAC ABR */ +int ldac_ABR_Init( HANDLE_LDAC_ABR hLdacAbr, unsigned int interval_ms ) +{ + ABRDBG( "hLdacAbr:0x%x, interval_ms:%u", (unsigned int)hLdacAbr, interval_ms ); + if (hLdacAbr == NULL) return -1; + if (interval_ms == 0) return -1; + if (interval_ms > LDAC_ABR_OBSERVING_TIME_MS) return -1; + + hLdacAbr->numToEvaluate = LDAC_ABR_OBSERVING_TIME_MS / interval_ms; + hLdacAbr->TxQD_Info.sum = 0; + hLdacAbr->TxQD_Info.cnt = 0; + hLdacAbr->TxQD_Info.idx = 0; + hLdacAbr->TxQD_Info.szHist = hLdacAbr->numToEvaluate + 1; + if (hLdacAbr->TxQD_Info.pHist) free(hLdacAbr->TxQD_Info.pHist); + if ((hLdacAbr->TxQD_Info.pHist = + (unsigned char*)malloc(hLdacAbr->TxQD_Info.szHist * sizeof(unsigned char))) == NULL){ + return -1; + } + clear_data(hLdacAbr->TxQD_Info.pHist, hLdacAbr->TxQD_Info.szHist * sizeof(unsigned char)); + + hLdacAbr->nSteadyState = 0; + hLdacAbr->nPenalty = 1; + hLdacAbr->abrQualityModeIdSteady = aEqmidToAbrQualityModeID[LDACBT_EQMID_HQ]; + hLdacAbr->cntToIncQuality = LDAC_ABR_OBSERVING_COUNT_FOR_INIT; + /* thresholds */ + hLdacAbr->thCritical = LDAC_ABR_THRESHOLD_CRITICAL_DEFAULT; + hLdacAbr->thDangerousTrend = LDAC_ABR_THRESHOLD_DANGEROUSTREND_DEFAULT; + hLdacAbr->thSafety4HQSQ = LDAC_ABR_THRESHOLD_SAFETY_FOR_HQSQ_DEFAULT; + + return 0; +} + +/* Setup thresholds for LDAC ABR */ +int ldac_ABR_set_thresholds( HANDLE_LDAC_ABR hLdacAbr, unsigned int thCritical, + unsigned int thDangerousTrend, unsigned int thSafety4HQSQ ) +{ + ABRDBG( "thCritical=%u, thDangerousTrend=%u, thSafety4HQSQ=%u", + thCritical, thDangerousTrend, thSafety4HQSQ); + if (hLdacAbr == NULL) return -1; + if (thCritical < thDangerousTrend) return -1; + if (thDangerousTrend < thSafety4HQSQ) return -1; + hLdacAbr->thCritical = thCritical; + hLdacAbr->thDangerousTrend = thDangerousTrend; + hLdacAbr->thSafety4HQSQ = thSafety4HQSQ; + return 0; +} + +/* LDAC ABR main process */ +int ldac_ABR_Proc( HANDLE_LDAC_BT hLDAC, HANDLE_LDAC_ABR hLdacAbr, + unsigned int TxQueueDepth, unsigned int flagEnable) +{ + int nStepsToChangeEQMID, abrQualityModeID, eqmid, i; + unsigned int TxQD_curr, TxQD_prev; +#ifdef LOCAL_DEBUG + int qd, TxQ; // for debug +#endif + + if (hLDAC == NULL) return -1; + if (hLdacAbr == NULL) return -1; + + eqmid = ldacBT_get_eqmid(hLDAC); + abrQualityModeID = -1; + if ((LDACBT_EQMID_HQ <= eqmid) && (eqmid < sizeOfEqmidToBitrateSortedIdTable)) { + abrQualityModeID = aEqmidToAbrQualityModeID[eqmid]; + } +#ifdef LOCAL_DEBUG + ABRDBG( "[LDAC ABR] - abrQualityModeID : %d -- eqmid : %d -- TxQue : %d --------------", + abrQualityModeID, eqmid, TxQueueDepth); +#endif + /* check for the situation when unsupported eqmid was return from ldacBT_get_eqmid(). */ + if (abrQualityModeID < 0) return eqmid; /* return current eqmid. */ + + /* update */ + TxQD_curr = TxQueueDepth; + if ((i = hLdacAbr->TxQD_Info.idx - 1) < 0 ) i = hLdacAbr->TxQD_Info.szHist - 1; + TxQD_prev = hLdacAbr->TxQD_Info.pHist[i]; + + hLdacAbr->TxQD_Info.sum -= hLdacAbr->TxQD_Info.pHist[hLdacAbr->TxQD_Info.idx]; + hLdacAbr->TxQD_Info.pHist[hLdacAbr->TxQD_Info.idx] = (unsigned char)TxQD_curr; + if (++hLdacAbr->TxQD_Info.idx >= hLdacAbr->TxQD_Info.szHist) hLdacAbr->TxQD_Info.idx = 0; + + hLdacAbr->TxQD_Info.sum += TxQD_curr; + ++hLdacAbr->TxQD_Info.cnt; + +#ifdef LOCAL_DEBUG + qd = (abrQualityModeID * 100000000); + qd += (hLdacAbr->nPenalty * 1000000); + qd += (hLdacAbr->cntToIncQuality *1000); + qd += (hLdacAbr->nSteadyState); + TxQ = TxQD_prev * 100 + TxQD_curr; +#endif + + /* judge */ + nStepsToChangeEQMID = 0; + if (TxQD_curr >= hLdacAbr->thCritical) { + /* for Critical situation */ + ABRDBG("Critical: %d, %d", TxQ, qd); + nStepsToChangeEQMID = -1; + if ((eqmid == LDACBT_EQMID_HQ) || (eqmid == LDACBT_EQMID_SQ)) { + nStepsToChangeEQMID = -2; + } + } + else if ((TxQD_curr > hLdacAbr->thDangerousTrend) && (TxQD_curr > TxQD_prev)) { + ABRDBG("Dangerous: %d, %d", TxQ, qd); + nStepsToChangeEQMID = -1; + } + else if ((TxQD_curr > hLdacAbr->thSafety4HQSQ) && + ((eqmid == LDACBT_EQMID_HQ) || (eqmid == LDACBT_EQMID_SQ))) { + ABRDBG("Safety4HQSQ: %d, %d", TxQ, qd); + nStepsToChangeEQMID = -1; + } + else if (hLdacAbr->TxQD_Info.cnt >= hLdacAbr->numToEvaluate) { + int ave10; + hLdacAbr->TxQD_Info.cnt = hLdacAbr->numToEvaluate; + /* eanble average process */ + ave10 = (hLdacAbr->TxQD_Info.sum * 10) / hLdacAbr->TxQD_Info.cnt; + + if (ave10 > 15) { /* if average of TxQue_Count in 0.5[s] was larger than 1.5 */ + ABRDBG("ave: %d, %d, %d", TxQ, qd, ave10); + nStepsToChangeEQMID = -1; + } + else { + ++hLdacAbr->nSteadyState; +#ifdef LOCAL_DEBUG + qd = (abrQualityModeID * 100000000); + qd += (hLdacAbr->nPenalty * 1000000); + qd += (hLdacAbr->cntToIncQuality *1000); + qd += (hLdacAbr->nSteadyState); +#endif + + if (hLdacAbr->TxQD_Info.sum == 0) { + if (--hLdacAbr->cntToIncQuality <= 0) { + ABRDBG("inc1: %d, %d, %d", TxQ, qd, ave10); + nStepsToChangeEQMID = 1; + } + else { + ABRDBG("reset: %d, %d, %d", TxQ, qd, ave10); + hLdacAbr->TxQD_Info.cnt = 0; // reset the number of sample for average proc. + } + } + else { + ABRDBG( "reset cntToIncQuality, %d,%d, %d", TxQ,qd, ave10); + hLdacAbr->cntToIncQuality = LDAC_ABR_OBSERVING_COUNT_TO_JUDGE_INC_QUALITY + - 2 * abrQualityModeID; + if (abrQualityModeID >= hLdacAbr->abrQualityModeIdSteady) { + hLdacAbr->cntToIncQuality *= hLdacAbr->nPenalty; + } + } + } + } +#ifdef LOCAL_DEBUG + else { + ABRDBG("Nothing %d, hLdacAbr->TxQD_Info.cnt %u", TxQ, hLdacAbr->TxQD_Info.cnt); + } +#endif + if (flagEnable) { + if (nStepsToChangeEQMID) { + int abrQualityModeIDNew; + if (nStepsToChangeEQMID < 0) { + for (i = 0; i > nStepsToChangeEQMID; --i) { + if (ldacBT_alter_eqmid_priority(hLDAC, LDACBT_EQMID_INC_CONNECTION)) { +#ifdef LOCAL_DEBUG + int err; + err = ldacBT_get_error_code(hLDAC); + ABRDBG("Info@%d : %d ,%d, %d", __LINE__, + LDACBT_API_ERR(err), LDACBT_HANDLE_ERR(err), LDACBT_BLOCK_ERR(err)); +#endif + break;// EQMID was already the ID of the highest connectivity. + } + } + + eqmid = ldacBT_get_eqmid(hLDAC); + abrQualityModeIDNew = abrQualityModeID; + if (eqmid >= 0) { + if (eqmid < sizeOfEqmidToBitrateSortedIdTable) { + abrQualityModeIDNew = aEqmidToAbrQualityModeID[eqmid]; + } + } + + if (hLdacAbr->nSteadyState < LDAC_ABR_NUM_STEADY_STATE_TO_JUDGE_STEADY) { + hLdacAbr->abrQualityModeIdSteady = abrQualityModeIDNew - 1; + if (hLdacAbr->abrQualityModeIdSteady < 0) hLdacAbr->abrQualityModeIdSteady = 0; + hLdacAbr->nPenalty *= 2; + if(hLdacAbr->nPenalty > LDAC_ABR_PENALTY_MAX) { + hLdacAbr->nPenalty = LDAC_ABR_PENALTY_MAX; // MAX PENALTY + } + } + } + else { + if (ldacBT_alter_eqmid_priority( hLDAC, LDACBT_EQMID_INC_QUALITY )) { +#ifdef LOCAL_DEBUG + int err; + err = ldacBT_get_error_code(hLDAC); + ABRDBG("Info@%d : %d ,%d, %d", __LINE__, + LDACBT_API_ERR(err), LDACBT_HANDLE_ERR(err), LDACBT_BLOCK_ERR(err)); +#endif + ;// EQMID was already the ID of the highest sound quality. + } + eqmid = ldacBT_get_eqmid(hLDAC); + abrQualityModeIDNew = abrQualityModeID; + if (eqmid >= 0) { + if (eqmid < sizeOfEqmidToBitrateSortedIdTable) { + abrQualityModeIDNew = aEqmidToAbrQualityModeID[eqmid]; + } + } + if (abrQualityModeIDNew < hLdacAbr->abrQualityModeIdSteady) { + hLdacAbr->nPenalty = 1; + } + if (abrQualityModeIDNew == aEqmidToAbrQualityModeID[0]) { /* for HQ */ + if (hLdacAbr->nSteadyState > LDAC_ABR_NUM_STEADY_STATE_TO_RESET_PENALTY_FOR_HQ) { + hLdacAbr->nPenalty = 1; + } + } + } + + hLdacAbr->nSteadyState = 0; + // reset the number of sample for average proc. + hLdacAbr->TxQD_Info.cnt = 0; + hLdacAbr->cntToIncQuality = LDAC_ABR_OBSERVING_COUNT_TO_JUDGE_INC_QUALITY + - 2 * abrQualityModeIDNew; + if (hLdacAbr->cntToIncQuality <= 0) { + // set minimum value. e1 f == 0.5[s] + hLdacAbr->cntToIncQuality = 1; + } + hLdacAbr->cntToIncQuality *= hLdacAbr->nPenalty; + ABRDBG("EQMID NOW %d", eqmid); + } + } +#ifdef LOCAL_DEBUG + else if (TxQueueDepth) { + ABRDBG("flagEnable false: %d ,%d", TxQ, qd); + } +#endif + + return eqmid; +} diff --git a/src/ldaclib_api.c b/src/ldaclib_api.c index d15cae2..4c54407 100644 --- a/src/ldaclib_api.c +++ b/src/ldaclib_api.c @@ -456,6 +456,20 @@ int frame_status) static const int saa_encode_setting_ldac[LDAC_ENC_NSETTING][LDAC_ENC_NPROPERTY] = { {0, 512, 17, 0, 28, 44, 8, 24, 0}, {0, 256, 17, 0, 28, 44, 6, 22, 0}, +#ifdef MODIFY_LDAC_ENC_SETTING_FOR_ABR_DEBUG // See file "ldacBT_abr.h" for description + {0, 164, 16, 0, 18, 32, 7, 23, 0}, + {0, 110, 8, 0, 16, 32, 10, 31, 0}, + {0, 82, 6, 0, 16, 32, 12, 31, 0}, + {0, 66, 4, 0, 14, 26, 12, 31, 0}, + {0, 54, 2, 0, 14, 26, 12, 31, 0}, + {0, 46, 2, 1, 10, 26, 12, 31, 0}, + {0, 40, 2, 2, 10, 26, 12, 31, 0}, + {0, 36, 2, 2, 8, 26, 12, 31, 0}, + {0, 32, 2, 2, 8, 26, 16, 31, 0}, + {0, 30, 2, 2, 4, 26, 16, 31, 0}, + {0, 26, 2, 3, 4, 26, 16, 31, 0}, + {0, 24, 2, 3, 4, 26, 16, 31, 0}, +#else {0, 164, 16, 0, 18, 32, 7, 23, 0}, {0, 110, 13, 0, 16, 32, 10, 31, 0}, {0, 82, 12, 0, 16, 32, 12, 31, 0}, @@ -468,6 +482,7 @@ static const int saa_encode_setting_ldac[LDAC_ENC_NSETTING][LDAC_ENC_NPROPERTY] {0, 30, 5, 2, 4, 26, 16, 31, 0}, {0, 26, 4, 3, 4, 26, 16, 31, 0}, {0, 24, 3, 3, 4, 26, 16, 31, 0}, +#endif {0, 22, 2, 3, 4, 26, 16, 31, 0}, }; |