/* SPDX-License-Identifier: LGPL-2.1-only OR BSD-3-Clause */
/******************************************************************************
 *
 * This file is provided under a dual license.  When you use or
 * distribute this software, you may choose to be licensed under
 * version 2.1 of the GNU Lesser General Public License
 * ("LGPLv2.1 License") or BSD License.
 *
 * LGPLv2.1 License
 *
 * Copyright(C) 2019 MediaTek Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of version 2.1 of the GNU Lesser General Public
 * License as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html for more
 * details.
 *
 * BSD LICENSE
 *
 * Copyright(C) 2019 MediaTek Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *  * Neither the name of the copyright holder nor the names of its
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *****************************************************************************/

#include "drv_MapleAudApi.h"

extern BOOL AUD_IsAudHWInit(void);
extern void AUD_set4kBeMuteDone( BOOL isMute);
extern BOOL AUD_get4kBeMuteDone(void);
#ifdef CC_COMBINE_4K_2K	
extern UINT32 DRVCUST_Get_2K_Model(void);
#endif
extern UINT32 DRVCUST_Get_BE_Type(void);
#ifdef CC_AUD_SAKURA_RENDER
extern void _AUD_UpdateDspConfig(BOOL forceUpdateFlag);
extern void UpdateMainDelay(BOOL forceUpdateFlag, BOOL fgIsSpkOnly);
BOOL _fgBEBoot;
static SAPostStreamInfo gLastSAPostStreamInfo;
#endif // CC_AUD_SAKURA_RENDER
#ifdef CC_SUPPORT_96K_AOUT
extern SAMPLE_FREQ_T _MT5398_PWM_Out_Fs_Query(void);
#endif
extern void _AUD_GetCurrentDec(UINT8 *u1DspId, UINT8 *u1DecId, AUD_DECODER_T *pAudDecoder);

SONY_BE_AUD_FUNC_T* pBeAudFunc = NULL;
//-----------------------------------------------------------------------------
// Imported variables
//-----------------------------------------------------------------------------
extern E_CUST_AUD_DOUT_TYPE geDoutType;

void DRVCUST_RegisterBeAudFunc(SONY_BE_AUD_FUNC_T *be_func)
{
    if (be_func)
    {
        pBeAudFunc = be_func;
        LOG(2, "BE Aud function registered \n");
    }
    else
    {
        LOG(2, "BE Aud function NULL \n");
    }
}

void DRVCUST_DeregisterBeAudFunc(void)
{
    pBeAudFunc = NULL;    
    LOG(2, "BE Aud function unregistered \n");
}

#ifndef CC_MAPLE_CUST_DRV
void DRVCUST_GetAudioInputType (UINT8 bPath, CUST_AUD_INPUT_T* pAudioInput)
{
}

void DRVCUST_GetAudioSignalFormat(UINT8 bPath, CUST_AUD_FMT_T* pSignalFormat)
{
}

UINT32 DRVCUST_GetAudioDelay(void)
{
    return 0;
}

void DRVCUST_GetAudioOutputFormat (CUST_AUD_OUT_FORMAT_T* pOutFormat)
{
}

void DRVCUST_GetVolume(CUST_AUD_VOLUME_T* pVolume)
{
}
void DRVCUST_GetSoundSetting(CUST_AUD_SOUND_SETTING_T* pSoundSetting)
{
}

void DRVCUST_GetAudioChannelMuteState(UINT8 bPath, CUST_AUD_CH_MUTE_STATE_T* pMuteState)
{
}

void DRVCUST_GetAudioPlayState(UINT8 bPath, CUST_AUD_PLAY_STATE_T* pPlayState)
{
}

void DRVCUST_GetAudioMixState(CUST_AUD_MIX_STATE_T* pState)
{
}

void DRVCUST_GetServiceModeState(CUST_AUD_SERVICE_MODE_STATE_T* pState)
{
}

void DRVCUST_GetSubwooferState(CUST_AUD_SUBWOOFER_STATE_T* pState )
{
}

UINT8 DRVCUST_GetMCKState(void)
{
    return 1;
}


void DRVCUST_SetBeMuteState(UINT8 bState)
{
}

void DRVCUST_SetBeDelay(UINT32 u4Delay)
{
}

#else //CC_MAPLE_CUST_DRV

extern void _vAUD_Aproc_Get (UINT32 u4Type, UINT32 u4Item, UINT32 *pu4Addr, UINT32 u4Num);
extern BOOL ADAC_AmpEnableFlag(void);
extern BOOL _GetVolMuteStatus(UINT8 bPath);
#ifdef CC_AUD_SAKURA_RENDER
extern BOOL _AUD_DspGetChannelMute(UINT8 u1DecId, AUD_CH_T eChannel);
#endif // CC_AUD_SAKURA_RENDER



//**************************************************************
// Static APIs
//**************************************************************

static E_CUST_AUD_INPUT_TYPE eInputTypeConv(AUD_DEC_STREAM_FROM_T eStreamFrom)
{
    UNUSED(eInputTypeConv);

    switch(eStreamFrom)
    {
    case AUD_STREAM_FROM_OTHERS:
        return E_CUST_AUD_INPUT_TYPE_OTHERS;    
    case AUD_STREAM_FROM_DIGITAL_TUNER:
        return E_CUST_AUD_INPUT_TYPE_DIGITAL_TUNER;
    case AUD_STREAM_FROM_ANALOG_TUNER:
        return E_CUST_AUD_INPUT_TYPE_ANALOG_TUNER;
    case AUD_STREAM_FROM_SPDIF:
        return E_CUST_AUD_INPUT_TYPE_SPDIF;
    case AUD_STREAM_FROM_LINE_IN:        
        return E_CUST_AUD_INPUT_TYPE_LINE_IN;
    case AUD_STREAM_FROM_HDMI:        
        return E_CUST_AUD_INPUT_TYPE_HDMI;
    case AUD_STREAM_FROM_MEMORY:
        return E_CUST_AUD_INPUT_TYPE_MEMORY;
    case AUD_STREAM_FROM_BUF_AGT:
        return E_CUST_AUD_INPUT_TYPE_BUF_AGT;
    case AUD_STREAM_FROM_FEEDER:
        return E_CUST_AUD_INPUT_TYPE_FEEDER;
    case AUD_STREAM_FROM_MULTI_MEDIA:
        return E_CUST_AUD_INPUT_TYPE_MULTI_MEDIA;
    case AUD_STREAM_FROM_LINE_IN_2:
        return E_CUST_AUD_INPUT_TYPE_LINE_IN_2;
    case AUD_STREAM_FROM_LINE_IN_3:
        return E_CUST_AUD_INPUT_TYPE_LINE_IN_3;
#ifdef CC_ENABLE_AOMX
    case AUD_STREAM_FROM_GST:
        return E_CUST_AUD_INPUT_TYPE_GST;
#endif
#ifdef CC_AUD_I2S_IN
    case AUD_STREAM_FROM_I2S:
        return E_CUST_AUD_INPUT_TYPE_I2S;
#endif
    case AUD_STREAM_FROM_NUM:
        return E_CUST_AUD_INPUT_TYPE_NUM;
default:    
        return E_CUST_AUD_INPUT_TYPE_OTHERS;        
    }
}

static SAPostInput eInputTypeConvSAPost(AUD_DEC_STREAM_FROM_T eStreamFrom)
{
    UNUSED(eInputTypeConvSAPost);
    switch(eStreamFrom)
    {
    case AUD_STREAM_FROM_DIGITAL_TUNER:
        return SAPOST_INPUT_DIGITAL_TUNER;
    case AUD_STREAM_FROM_ANALOG_TUNER:
        return SAPOST_INPUT_ANALOG_TUNER;
    case AUD_STREAM_FROM_LINE_IN_3:
    case AUD_STREAM_FROM_LINE_IN_2:
    case AUD_STREAM_FROM_LINE_IN:        
        //SAPOST_INPUT_COMPONENT
        //SAPOST_INPUT_SCART
        //SAPOST_INPUT_HDMI_ANALOG
        //SAPOST_INPUT_ANALOG_PC
        return SAPOST_INPUT_COMPOSITE;
    case AUD_STREAM_FROM_HDMI:        
        return SAPOST_INPUT_HDMI;
    case AUD_STREAM_FROM_MEMORY:
    case AUD_STREAM_FROM_BUF_AGT:
    case AUD_STREAM_FROM_FEEDER:
        //SAPOST_INPUT_NETWORK_STREAM        
        return SAPOST_INPUT_TONE_GENERATOR;
    case AUD_STREAM_FROM_MULTI_MEDIA:
        return SAPOST_INPUT_STORAGE_STREAM;
    default:    
        return SAPOST_INPUT_NONE;        
    }
}

#ifdef CC_AUD_SAKURA_RENDER
static SAPostInput eInputTypeAQConvSAPost(AQ_INPUT eStreamFrom)
{
    UNUSED(eInputTypeAQConvSAPost);
    switch(eStreamFrom)
    {
    case AQ_INPUT_DIGITAL_RF:
        return SAPOST_INPUT_DIGITAL_TUNER;
    case AQ_INPUT_ANALOG_RF:
        return SAPOST_INPUT_ANALOG_TUNER;
    case AQ_INPUT_COMPOSITE:
        return SAPOST_INPUT_COMPOSITE;
    case AQ_INPUT_HDMI:        
        return SAPOST_INPUT_HDMI;
    default:    
        return SAPOST_INPUT_DIGITAL_TUNER;
    }
}

static E_CUST_AUD_INPUT_TYPE eInputTypeAQConv(AQ_INPUT eStreamFrom)
{
    UNUSED(eInputTypeAQConv);
    switch(eStreamFrom)
    {
    case AQ_INPUT_DIGITAL_RF:
        return E_CUST_AUD_INPUT_TYPE_DIGITAL_TUNER;
    case AQ_INPUT_ANALOG_RF:
        return E_CUST_AUD_INPUT_TYPE_ANALOG_TUNER;
    case AQ_INPUT_COMPOSITE:
        return E_CUST_AUD_INPUT_TYPE_LINE_IN;
    case AQ_INPUT_HDMI:        
        return E_CUST_AUD_INPUT_TYPE_HDMI;
    default:    
        return E_CUST_AUD_INPUT_TYPE_DIGITAL_TUNER;
    }
}
#endif //CC_AUD_SAKURA_RENDER

#ifdef CC_AUD_SAKURA_RENDER
static AQ_INPUT eInputTypeConvAQInput(AUD_DEC_STREAM_FROM_T eStreamFrom)
{
    UNUSED(eInputTypeConvSAPost);
    switch(eStreamFrom)
    {
    case AUD_STREAM_FROM_DIGITAL_TUNER:
        return AQ_INPUT_DIGITAL_RF;
    case AUD_STREAM_FROM_ANALOG_TUNER:
        return AQ_INPUT_ANALOG_RF;
    case AUD_STREAM_FROM_LINE_IN_3:
    case AUD_STREAM_FROM_LINE_IN_2:
        case AUD_STREAM_FROM_LINE_IN:        
        //AQ_INPUT_COMPONENT=5,
        //AQ_INPUT_PC=6,
        return AQ_INPUT_COMPOSITE;
    case AUD_STREAM_FROM_HDMI:        
        return AQ_INPUT_HDMI;
    case AUD_STREAM_FROM_MEMORY:
    case AUD_STREAM_FROM_BUF_AGT:
    case AUD_STREAM_FROM_FEEDER:
    case AUD_STREAM_FROM_MULTI_MEDIA:
        //AQ_INPUT_VIDEO_APP=7,
        //AQ_INPUT_PHOTO=8,
        //AQ_INPUT_JELLYFISH=9,
        //AQ_INPUT_SKYPE=10,
        //AQ_INPUT_MIRACAST=11,
        //AQ_INPUT_GENERAL_APP=12,
        //AQ_INPUT_RESERVED1=13,
        //AQ_INPUT_RESERVED2=14,
        //AQ_INPUT_RESERVED3=15,
    default:    
        return AQ_INPUT_DIGITAL_RF;        
    }
}
#endif // CC_AUD_SAKURA_RENDER

static E_CUST_AUD_CH_CONF eChConfConv(AUD_TYPE_T eChConf)
{
    UNUSED(eChConfConv);
    //E_CUST_AUD_CH_CONF_2_2_0_0,  // for 4ch/4K FRC model
    switch(eChConf)
    {
    case AUD_TYPE_MONO: 
    case AUD_TYPE_FM_MONO_NICAM_MONO:
    case AUD_TYPE_FMRDO_MONO:        
        return E_CUST_AUD_CH_CONF_MONO;    
    case AUD_TYPE_MONO_LFE:
        return E_CUST_AUD_CH_CONF_MONO_1;
    case AUD_TYPE_MONO_SUB:
    case AUD_TYPE_DUAL_MONO:
    case AUD_TYPE_FM_MONO_NICAM_DUAL:
        return E_CUST_AUD_CH_CONF_DUAL_MONO;
    case AUD_TYPE_STEREO:           
    case AUD_TYPE_FM_MONO_NICAM_STEREO:
    case AUD_TYPE_JOINT_STEREO:
    case AUD_TYPE_LEFT_SIDE_STEREO: 
    case AUD_TYPE_RIGHT_SIDE_STEREO:
    case AUD_TYPE_MID_SIDE_STEREO:
    case AUD_TYPE_FMRDO_STEREO:                
    case AUD_TYPE_STEREO_SUB:
    case AUD_TYPE_STEREO_DOLBY_SURROUND:
        return E_CUST_AUD_CH_CONF_STEREO;            
    case AUD_TYPE_SURROUND_2CH:
        return E_CUST_AUD_CH_CONF_2_0_1_0;    
    case AUD_TYPE_SURROUND:
        return E_CUST_AUD_CH_CONF_3_0_1_0;    
    case AUD_TYPE_3_0:
        return E_CUST_AUD_CH_CONF_3_0_0_0;
    case AUD_TYPE_4_0:
        return E_CUST_AUD_CH_CONF_2_0_2_0;        
    case AUD_TYPE_5_1:
        return E_CUST_AUD_CH_CONF_3_0_2_1;    
    case AUD_TYPE_5_0:
        return E_CUST_AUD_CH_CONF_3_0_2_0;
    case AUD_TYPE_7_1:
        return E_CUST_AUD_CH_CONF_3_2_2_1;
    case AUD_TYPE_DUAL_MONO_LFE:
        return E_CUST_AUD_CH_CONF_DUAL_MONO_1;
    case AUD_TYPE_3_1:                  
        return E_CUST_AUD_CH_CONF_3_0_0_1;
    case AUD_TYPE_4_1:                  
        return E_CUST_AUD_CH_CONF_2_0_2_1;
    case AUD_TYPE_STEREO_LFE:
        return E_CUST_AUD_CH_CONF_2_0_0_1;
    case AUD_TYPE_SURROUND_2CH_LFE:
        return E_CUST_AUD_CH_CONF_2_0_1_1;
    case AUD_TYPE_SURROUND_LFE:
        return E_CUST_AUD_CH_CONF_3_0_1_1;
    default:    
        return E_CUST_AUD_CH_CONF_UNKNOWN;
    }
}

static E_CUST_AUD_CODEC eDecTypeConv(AUD_DECODE_TYPE_T eFmt)
{
    UNUSED(eDecTypeConv);

    switch(eFmt)
    {
    case AUD_DECODE_TYPE_AC3:
        return E_CUST_AUD_CODEC_AC3;
    case AUD_DECODE_TYPE_EAC3:
        return E_CUST_AUD_CODEC_E_AC3;    
    case AUD_DECODE_TYPE_AAC:
        return E_CUST_AUD_CODEC_AAC;
    case AUD_DECODE_TYPE_HEAAC:
        return E_CUST_AUD_CODEC_HE_AAC;
    case AUD_DECODE_TYPE_HEAAC_V2:
        return E_CUST_AUD_CODEC_HE_AAC_V2;
    case AUD_DECODE_TYPE_MPEG1_LAYER3:
        return E_CUST_AUD_CODEC_MP3;
    case AUD_DECODE_TYPE_MPEG1_LAYER2:
        return E_CUST_AUD_CODEC_MPEG;
    case AUD_DECODE_TYPE_MPEG1_LAYER1:
        return E_CUST_AUD_CODEC_MPEG;
    case AUD_DECODE_TYPE_MPEG2_LAYER3:
        return E_CUST_AUD_CODEC_MP3;
    case AUD_DECODE_TYPE_MPEG2_LAYER2:
    case AUD_DECODE_TYPE_MPEG2_LAYER1:
        return E_CUST_AUD_CODEC_MPEG;
    case AUD_DECODE_TYPE_AC4:
        return E_CUST_AUD_CODEC_AC4;
    case AUD_DECODE_TYPE_UNKNOWN:
    case AUD_DECODE_TYPE_FLAC:
    case AUD_DECODE_TYPE_LPCM_ALAW:
    case AUD_DECODE_TYPE_LPCM_ULAW:
    default:
        return E_CUST_AUD_CODEC_UNKNOWN;        

    }
}

static E_CUST_AUD_CODEC eCodecFmtConv(AUD_FMT_T eFmt)
{
    UNUSED(eCodecFmtConv);

    switch(eFmt)
    {
    case AUD_FMT_MPEG:
        return E_CUST_AUD_CODEC_MPEG;
    case AUD_FMT_AC3:        
        return E_CUST_AUD_CODEC_AC3;
    case AUD_FMT_PCM:
    case AUD_FMT_LPCM:
        return E_CUST_AUD_CODEC_PCM;
    case AUD_FMT_MP3:
        return E_CUST_AUD_CODEC_MP3;
    case AUD_FMT_AAC:
        return E_CUST_AUD_CODEC_AAC;
    case AUD_FMT_DTS:
        return E_CUST_AUD_CODEC_DTS;       
    case AUD_FMT_WMA:
    case AUD_FMT_WMAPRO:
        return E_CUST_AUD_CODEC_WMA;
    case AUD_FMT_RA:
        return E_CUST_AUD_CODEC_RA;
    case AUD_FMT_HDCD:
        return E_CUST_AUD_CODEC_HDCD;
    case AUD_FMT_MLP:
        return E_CUST_AUD_CODEC_MLP;
    case AUD_FMT_MTS:
        return E_CUST_AUD_CODEC_MTS;
    case AUD_FMT_PAL:
        return E_CUST_AUD_CODEC_PAL;
    case AUD_FMT_A2:
        return E_CUST_AUD_CODEC_A2;
    case AUD_FMT_FMFM:
        return E_CUST_AUD_CODEC_FMFM;
    case AUD_FMT_NICAM:
        return E_CUST_AUD_CODEC_NICAM;
    case AUD_FMT_TTXAAC:
        return E_CUST_AUD_CODEC_TTXAAC;
    case AUD_FMT_DETECTOR:
        return E_CUST_AUD_CODEC_DETECTOR;
    case AUD_FMT_MINER:
        return E_CUST_AUD_CODEC_MINER;
    case AUD_FMT_HE_AAC: 
        return E_CUST_AUD_CODEC_HE_AAC;
    case AUD_FMT_HE_AAC_V2:
        return E_CUST_AUD_CODEC_HE_AAC_V2;
    case AUD_FMT_AC4:
        return E_CUST_AUD_CODEC_AC4;
    //E_CUST_AUD_CODEC_E_AC3           
    #if 0
    case AUD_FMT_DRA:
        return E_CUST_AUD_CODEC_DRA;
    case AUD_FMT_COOK:
        return E_CUST_AUD_CODEC_COOK;
    case AUD_FMT_VORBISDEC:
        return E_CUST_AUD_CODEC_VORBIS;
    case AUD_FMT_FLAC:
            return E_CUST_AUD_CODEC_FLAC;
    #endif
    default:
        return E_CUST_AUD_CODEC_UNKNOWN;   
    }
}

#ifdef CC_AUD_SAKURA_RENDER
static E_CUST_AUD_CH_CONF eAqChannelConfConvChConf(AQ_CHANNEL_CONF eAqChConf)
{
    UNUSED(eAqChannelConfConvChConf);
    
    switch(eAqChConf)
    {
    case AQ_CHANNEL_CONF_MONO: 
        return E_CUST_AUD_CH_CONF_MONO;
    case AQ_CHANNEL_CONF_DUAL_MONO:
        return E_CUST_AUD_CH_CONF_DUAL_MONO;
    case AQ_CHANNEL_CONF_STEREO:
        return E_CUST_AUD_CH_CONF_STEREO;
    case AQ_CHANNEL_CONF_2_1_0:
        return E_CUST_AUD_CH_CONF_2_0_1_0;
    case AQ_CHANNEL_CONF_3_1_0:
        return E_CUST_AUD_CH_CONF_3_0_1_0;
    case AQ_CHANNEL_CONF_3_0_0:
        return E_CUST_AUD_CH_CONF_3_0_0_0;
    case AQ_CHANNEL_CONF_2_2_0:
        return E_CUST_AUD_CH_CONF_2_0_2_0;
    case AQ_CHANNEL_CONF_3_2_1:
        return E_CUST_AUD_CH_CONF_3_0_2_1;
    case AQ_CHANNEL_CONF_3_2_0:
        return E_CUST_AUD_CH_CONF_3_0_2_0;
    case AQ_CHANNEL_CONF_3_0_1:
        return E_CUST_AUD_CH_CONF_3_0_0_1;
    case AQ_CHANNEL_CONF_2_2_1:
        return E_CUST_AUD_CH_CONF_2_0_2_1;
    case AQ_CHANNEL_CONF_2_0_1:
        return E_CUST_AUD_CH_CONF_2_0_0_1;
    case AQ_CHANNEL_CONF_2_1_1:
        return E_CUST_AUD_CH_CONF_2_0_1_1;
    case AQ_CHANNEL_CONF_3_1_1:
        return E_CUST_AUD_CH_CONF_3_0_1_1;
    default:    
        return E_CUST_AUD_CH_CONF_UNKNOWN;
    }
}

static E_CUST_AUD_FS eAqSampRateConvSampRate(AQ_FS eAqFs)
{
    UNUSED(eAqSampRateConvSampRate);

    switch(eAqFs)
    {
    case AQ_FS_48KHZ:
        return E_CUST_AUD_FS_48K;
    case AQ_FS_96KHZ:
        return E_CUST_AUD_FS_96K;
    default:
        return E_CUST_AUD_FS_UNKNOWN;
    }
}

static E_CUST_AUD_CH_CONF eAqChannelConfConvSAPost(AQ_CHANNEL_CONF eAqChConf)
{
    UNUSED(eAqChannelConfConvSAPost);
    
    switch(eAqChConf)
    {
    case AQ_CHANNEL_CONF_MONO: 
        return SAPOST_CHANNELS_MONO;
    case AQ_CHANNEL_CONF_DUAL_MONO:
        return SAPOST_CHANNELS_DUAL_MONO;
    case AQ_CHANNEL_CONF_STEREO:
        return SAPOST_CHANNELS_STEREO;
    case AQ_CHANNEL_CONF_2_1_0:
        return  SAPOST_CHANNELS_2_0_1_0;
    case AQ_CHANNEL_CONF_3_1_0:
        return SAPOST_CHANNELS_3_0_1_0;
    case AQ_CHANNEL_CONF_3_0_0:
        return SAPOST_CHANNELS_3_0_0_0;
    case AQ_CHANNEL_CONF_2_2_0:
        return SAPOST_CHANNELS_2_0_2_0;
    case AQ_CHANNEL_CONF_3_2_1:
        return SAPOST_CHANNELS_3_0_2_1;
    case AQ_CHANNEL_CONF_3_2_0:
        return SAPOST_CHANNELS_3_0_2_0;
    case AQ_CHANNEL_CONF_3_0_1:
        return SAPOST_CHANNELS_3_0_0_1;
    case AQ_CHANNEL_CONF_2_2_1:
        return SAPOST_CHANNELS_2_0_2_1;
    case AQ_CHANNEL_CONF_2_0_1:
        return SAPOST_CHANNELS_2_0_0_1;
    case AQ_CHANNEL_CONF_2_1_1:
        return SAPOST_CHANNELS_2_0_1_1;
    case AQ_CHANNEL_CONF_3_1_1:
        return SAPOST_CHANNELS_3_0_1_1;
    default:    
        return SAPOST_CHANNELS_UNKNOWN;
    }
}

static SAPostSamplingRate eAqSampRateConvSAPost(AQ_FS eAqFs)
{
    UNUSED(eAqSampRateConvSAPost);

    switch(eAqFs)
    {
    case AQ_FS_48KHZ:
        return SAPOST_SAMPLING_RATE_48K;
    case AQ_FS_96KHZ:
        return SAPOST_SAMPLING_RATE_96K;
    default:
        return SAPOST_SAMPLING_RATE_48K;
    }
}

#endif /* CC_AUD_SAKURA_RENDER */

static SAPostCodec eDecTypeConvSAPost(AUD_DECODE_TYPE_T eFmt)
{
    UNUSED(eDecTypeConvSAPost);

    switch(eFmt)
    {
    case AUD_DECODE_TYPE_AC3:
        return SAPOST_CODEC_AC3;
    case AUD_DECODE_TYPE_EAC3:
        return SAPOST_CODEC_AC3_PLUS;
    case AUD_DECODE_TYPE_FLAC:
        return SAPOST_CODEC_FLAC;
    case AUD_DECODE_TYPE_AAC:
        return SAPOST_CODEC_MPEG2_AAC;
    case AUD_DECODE_TYPE_HEAAC:
        return SAPOST_CODEC_MPEG4_HE_AAC;
    case AUD_DECODE_TYPE_HEAAC_V2:
        return SAPOST_CODEC_MPEG4_HE_AAC;
    case AUD_DECODE_TYPE_LPCM_ALAW:
        return SAPOST_CODEC_G711;
    case AUD_DECODE_TYPE_LPCM_ULAW:
        return SAPOST_CODEC_MU_LAW;
    case AUD_DECODE_TYPE_MPEG1_LAYER3:
        return SAPOST_CODEC_MPEG1_L3;
    case AUD_DECODE_TYPE_MPEG1_LAYER2:
        return SAPOST_CODEC_MPEG1_L2;
    case AUD_DECODE_TYPE_MPEG1_LAYER1:
        return SAPOST_CODEC_MPEG1_L1;
    case AUD_DECODE_TYPE_MPEG2_LAYER3:
    case AUD_DECODE_TYPE_MPEG2_LAYER2:
    case AUD_DECODE_TYPE_MPEG2_LAYER1:
        return SAPOST_CODEC_MPEG2_BC;
    case AUD_DECODE_TYPE_UNKNOWN:
    default:
        return SAPOST_CODEC_UNKNOWN;        
    }    
}

static SAPostCodec eCodecFmtConvSAPost(AUD_FMT_T eFmt)
{
    UNUSED(eCodecFmtConvSAPost);

    switch(eFmt)
    {
    case AUD_FMT_MPEG:
        //SAPOST_CODEC_MPEG1_L1
        return SAPOST_CODEC_MPEG1_L2;
    case AUD_FMT_AC3:        
        return SAPOST_CODEC_AC3;
    case AUD_FMT_PCM:
    case AUD_FMT_LPCM:
        return SAPOST_CODEC_LPCM;
    case AUD_FMT_MP3:
        return SAPOST_CODEC_MPEG1_L3;
    case AUD_FMT_AAC:
        return SAPOST_CODEC_MPEG2_AAC;
    case AUD_FMT_DTS:
        return SAPOST_CODEC_DTS;       
    case AUD_FMT_WMA:
        return SAPOST_CODEC_WMA;
    case AUD_FMT_WMAPRO:
        return SAPOST_CODEC_WMA_PRO;
    case AUD_FMT_HE_AAC: 
    case AUD_FMT_HE_AAC_V2:
        return SAPOST_CODEC_MPEG4_HE_AAC;
    case AUD_FMT_DRA:
        return SAPOST_CODEC_DRA;
    case AUD_FMT_COOK:
        return SAPOST_CODEC_COOK;
    case AUD_FMT_VORBISDEC:
        return SAPOST_CODEC_VORBIS;
    case AUD_FMT_FLAC:
            return SAPOST_CODEC_FLAC;
    case AUD_FMT_G711DEC:
        return SAPOST_CODEC_G711;
    case AUD_FMT_OMX_ULAW:
        return SAPOST_CODEC_MU_LAW;       
    case AUD_FMT_SBCDEC:
        return SAPOST_CODEC_SBC;
    default:
        return SAPOST_CODEC_UNKNOWN;   
    //SAPOST_CODEC_ATRAC3,
    //SAPOST_CODEC_ATRACX,
    //SAPOST_CODEC_WAV,
    //SAPOST_CODEC_AIFF,
    //SAPOST_CODEC_MPEG2_BC,
    //SAPOST_CODEC_MPEG2_BC_MC,
    //SAPOST_CODEC_AC3_PLUS,
    //SAPOST_CODEC_SIPRO,
    //SAPOST_CODEC_ALAC,
    //SAPOST_CODEC_DSD,
    //SAPOST_CODEC_OPUS,        
    }
}

static E_CUST_AUD_PLAY_STATE eGetPlayState(UINT8 u1DspId, UINT8 u1DecId)
{
    AUD_DECODER_T arAudDecoder={0};

    AUD_GetDecoderStatus(u1DspId, u1DecId, &arAudDecoder);
    switch (arAudDecoder.eDecState)
    {
    case AUD_DEC_PLAYING:
        return E_CUST_AUD_PLAY_STATE_PLAY;
    case AUD_DEC_PAUSE:
        return E_CUST_AUD_PLAY_STATE_PAUSE;
    default:
        return E_CUST_AUD_PLAY_STATE_STOP;
    }
}  

static E_CUST_AUD_FS eSampRateConv(SAMPLE_FREQ_T eSampRat)
{
    UNUSED(eSampRateConv);

    switch(eSampRat)
    {
    case FS_16K:
        return E_CUST_AUD_FS_16K;
    case FS_22K:        
        return E_CUST_AUD_FS_22K;
    case FS_24K:
        return E_CUST_AUD_FS_24K;
    case FS_32K:
        return E_CUST_AUD_FS_32K;
    case FS_44K:
        return E_CUST_AUD_FS_44K;
    case FS_48K:
        return E_CUST_AUD_FS_48K;
    case FS_64K:
    case FS_64K_SRC: 
        return E_CUST_AUD_FS_64K;
    case FS_88K:
        return E_CUST_AUD_FS_88K;
    case FS_96K:
        return E_CUST_AUD_FS_96K;
    case FS_176K:
        return E_CUST_AUD_FS_176K;
    case FS_192K:
        return E_CUST_AUD_FS_192K;
    case FS_8K:
        return E_CUST_AUD_FS_8K;
    case FS_11K: 
        return E_CUST_AUD_FS_11K;
    case FS_12K:
        return E_CUST_AUD_FS_12K;
    case FS_52K:
    case FS_56K: 
    case FS_62K: 
    case FS_6K: 
    case FS_10K: 
    case FS_5K: 
    default:
        return E_CUST_AUD_FS_UNKNOWN;
    }
}


static SAPostSamplingRate eSampRateConvSAPost(SAMPLE_FREQ_T eSampRat)
{
    UNUSED(eSampRateConvSAPost);

    switch(eSampRat)
    {
    case FS_16K:
        return SAPOST_SAMPLING_RATE_16K;
    case FS_22K:        
        return SAPOST_SAMPLING_RATE_22_05K;
    case FS_24K:
        return SAPOST_SAMPLING_RATE_24K;
    case FS_32K:
        return SAPOST_SAMPLING_RATE_32K;
    case FS_44K:
        return SAPOST_SAMPLING_RATE_44_1K;
    case FS_48K:
        return SAPOST_SAMPLING_RATE_48K;
    case FS_64K:
    case FS_64K_SRC: 
        return SAPOST_SAMPLING_RATE_64K;
    case FS_88K:
        return SAPOST_SAMPLING_RATE_88_2K;
    case FS_96K:
        return SAPOST_SAMPLING_RATE_96K;
    case FS_176K:
        return SAPOST_SAMPLING_RATE_176_4K;
    case FS_192K:
        return SAPOST_SAMPLING_RATE_192K;
    case FS_8K:
        return SAPOST_SAMPLING_RATE_8K;
    case FS_11K: 
        return SAPOST_SAMPLING_RATE_11_025K;
    case FS_12K:
        return SAPOST_SAMPLING_RATE_12K;
    case FS_52K:
    case FS_56K: 
    case FS_62K: 
    case FS_6K: 
    case FS_10K: 
    case FS_5K: 
    default:
        return SAPOST_SAMPLING_RATE_UNKNOWN;
    //SAPOST_SAMPLING_RATE_128K    
    }
}

static E_CUST_AUD_FS eSampRateConvFromUINT32(UINT32 eSampRat)
{
    UNUSED(eSampRateConvFromUINT32);

    switch(eSampRat)
    {
    case 8000:
        return E_CUST_AUD_FS_8K;
    case 11025: 
        return E_CUST_AUD_FS_11K;
    case 12000:
        return E_CUST_AUD_FS_12K;
    case 16000:
        return E_CUST_AUD_FS_16K;
    case 22050:        
        return E_CUST_AUD_FS_22K;
    case 24000:
        return E_CUST_AUD_FS_24K;
    case 32000:
        return E_CUST_AUD_FS_32K;
    case 44100:
        return E_CUST_AUD_FS_44K;
    case 48000:
        return E_CUST_AUD_FS_48K;
    case 64000:
        return E_CUST_AUD_FS_64K;
    case 88200:
        return E_CUST_AUD_FS_88K;
    case 96000:
        return E_CUST_AUD_FS_96K;
    case 128000:
        return E_CUST_AUD_FS_128K;        
    case 176400:
        return E_CUST_AUD_FS_176K;
    case 192000:
        return E_CUST_AUD_FS_192K;   
    default:
        return E_CUST_AUD_FS_UNKNOWN;        
    }
}

static SAPostSamplingRate eSampRateConvFromUINT32SAPost(UINT32 eSampRat)
{
    UNUSED(eSampRateConvFromUINT32SAPost);

    switch(eSampRat)
    {
    case 8000:
        return SAPOST_SAMPLING_RATE_8K;
    case 11025: 
        return SAPOST_SAMPLING_RATE_11_025K;
    case 12000:
        return SAPOST_SAMPLING_RATE_12K;
    case 16000:
        return SAPOST_SAMPLING_RATE_16K;
    case 22050:        
        return SAPOST_SAMPLING_RATE_22_05K;
    case 24000:
        return SAPOST_SAMPLING_RATE_24K;
    case 32000:
        return SAPOST_SAMPLING_RATE_32K;
    case 44100:
        return SAPOST_SAMPLING_RATE_44_1K;
    case 48000:
        return SAPOST_SAMPLING_RATE_48K;
    case 64000:
        return SAPOST_SAMPLING_RATE_64K;
    case 88200:
        return SAPOST_SAMPLING_RATE_88_2K;
    case 96000:
        return SAPOST_SAMPLING_RATE_96K;
    case 128000:
        return SAPOST_SAMPLING_RATE_128K;        
    case 176400:
        return SAPOST_SAMPLING_RATE_176_4K;
    case 192000:
        return SAPOST_SAMPLING_RATE_192K;   
    default:
        return SAPOST_SAMPLING_RATE_UNKNOWN;        
    }
}

#if 0
static void _GetAudInfo(UINT8 u1DecId, AUD_DEC_INFO_T * prAudInfo)  
{
    AUD_DEC_STREAM_FROM_T  rAudDecStreamFrom;
    AUD_FMT_T              eAudDecFormat;
    UINT8  u1Acmode;
    UINT8 u1Ac3DecType;
    UINT8  u1SmpRate;
    UINT32 u4DataRate;
    BOOL u1DecTypRet;

    if (prAudInfo != NULL)
    {
        // Get decoding format
        u1DecTypRet = AUD_DRVGetDecodeType(AUD_DSP0, u1DecId, &rAudDecStreamFrom, &eAudDecFormat);
        UNUSED(u1DecTypRet);
        prAudInfo->e_aud_fmt = eAudDecFormat;
        UNUSED(rAudDecStreamFrom);

        // Get audio information
        if (prAudInfo->e_aud_fmt == AUD_FMT_AC3)
        {
            AUD_GetStreamInfo_AC3(u1DecId, &u1Acmode, &u1Ac3DecType, &u1SmpRate, &u4DataRate);
            switch(u1Ac3DecType & 0x01)
            {
            case 0x00:
                prAudInfo->e_dec_type = AUD_DECODE_TYPE_AC3;
                break;
            case 0x01:
                prAudInfo->e_dec_type = AUD_DECODE_TYPE_EAC3;
                break;
            default:
                prAudInfo->e_dec_type = AUD_DECODE_TYPE_UNKNOWN;
                break;
            }
        }
        else if(prAudInfo->e_aud_fmt == AUD_FMT_AAC)
        {
            // Get audio information
            AUD_GetDtvAudInfo(u1DecId,&rAudInfo);
            //prAudInfo->e_aud_fmt = (AUD_DEC_FMT_T)rAudInfo.e_aud_fmt;
            prAudInfo->ui4_sample_rate = rAudInfo.ui4_sample_rate;
            prAudInfo->e_aud_type = (AUD_DEC_AUD_TYPE_T) rAudInfo.e_aud_type;
            prAudInfo->e_dec_type = (AUD_DEC_DECODE_TYPE_T) rAudInfo.e_dec_type;



        }
        else
        {
            AUD_GetStreamInfo(AUD_DSP0, u1DecId, &u1Acmode, &u1SmpRate, &u4DataRate);
        }
    }
}
#endif

//**************************************************************
// BE Audio Get APIs
//**************************************************************

void DRVCUST_GetAudioInputType (UINT8 bPath, CUST_AUD_INPUT_T* pAudioInput)
{
    AUD_DECODER_T arAudDecoder={0};
    UINT8 u1DecId, u1DspId;
    UNUSED(bPath);//BE_FIXME
    UINT32 isUpload = 0;

    u1DecId = AUD_DEC_MAIN; 
    u1DspId = AUD_DSP0;

    _AUD_GetCurrentDec(&u1DspId, &u1DecId, NULL);
    AUD_GetDecoderStatus(u1DspId, u1DecId, &arAudDecoder);
    isUpload = u4AprocReg_Read (APROC_ASM_ADDR(APROC_ASM_ID_CPU_0, APROC_REG_IOBUF_UPLOAD3_ENABLE));
    if ((arAudDecoder.eDecState != AUD_DEC_PLAYING && arAudDecoder.eDecState != AUD_DEC_PAUSE) ||
        (arAudDecoder.eStreamFrom == AUD_STREAM_FROM_MEMORY && isUpload == 1))
    {
        // E-mixsnd only case (Not decode or OMX decode)
        pAudioInput->eAudioInputType = eInputTypeConv(AUD_STREAM_FROM_MULTI_MEDIA);
    }
    else
    {
        pAudioInput->eAudioInputType = eInputTypeConv(arAudDecoder.eStreamFrom);
    }
}

void DRVCUST_GetAudioSignalFormat(UINT8 bPath, CUST_AUD_FMT_T* pSignalFormat)
{
    AUD_DECODER_T arAudDecoder={0};
    AUD_DEC_INFO_T rAudInfo={AUD_FMT_UNKNOWN,AUD_TYPE_UNKNOWN,0,0,0,AUD_DECODE_TYPE_UNKNOWN};
    UINT8 u1DecId, u1DspId;
    AUD_DEC_STREAM_FROM_T  rAudDecStreamFrom;
    AUD_FMT_T              eAudDecFormat;
    UINT8 u1Ca = 0;
    UINT32 isUpload = 0;
    UNUSED(eAudDecFormat);
    UNUSED(bPath); //BE_FIXME
#ifdef CC_AUD_SAKURA_RENDER
    static UINT32 lastDecId = AUD_DSP0 , lastDspId = AUD_DEC_MAIN;
#endif //CC_AUD_SAKURA_RENDER
    //UNUSED(rAudInfo);

#ifdef CC_AUD_DOLBY_SUPPORT_MS12v2
        extern CPUDEC_COMMON_DEC_INFO arCPUDECCommonDecInfo[ AUD_CPU_DEC_MAX ];
        pSignalFormat->eChConfHeight = 0;// height = 0 ( off )
        LOG( 0, "\n\neChConf = %d, eChConfHeight = %d @ GetAudioSignalFormat() init \n\n", pSignalFormat->eChConf, pSignalFormat->eChConfHeight );
#endif // CC_AUD_DOLBY_SUPPORT_MS12v2

    pSignalFormat->eSamplingRate = E_CUST_AUD_FS_48K; //BE_FIXME        
    pSignalFormat->eSigSta = E_CUST_AUD_SIG_STA_NO_SIG;
    pSignalFormat->eBitRateFlag = E_CUST_AUD_BIT_FLAG_UNKNOWN; //BE_FIXME    
    pSignalFormat->eCopyControl = E_CUST_AUD_COPY_CTRL_UNKNOWN; //BE_FIXME
#ifdef CC_AUD_SAKURA_RENDER
    pSignalFormat->u4BitLength = gSAPostInpStrInfo.m_bitLength;
#endif //CC_AUD_SAKURA_RENDER

    u1DspId = AUD_DSP0;
    u1DecId = AUD_DEC_MAIN; 
    _AUD_GetCurrentDec(&u1DspId, &u1DecId, NULL);
    AUD_DRVGetDecodeType(u1DspId, u1DecId, &rAudDecStreamFrom, &eAudDecFormat);
    AUD_GetDecoderStatus(u1DspId, u1DecId, &arAudDecoder);
    isUpload = u4AprocReg_Read (APROC_ASM_ADDR(APROC_ASM_ID_CPU_0, APROC_REG_IOBUF_UPLOAD3_ENABLE));
    if ((arAudDecoder.eDecState != AUD_DEC_PLAYING && arAudDecoder.eDecState != AUD_DEC_PAUSE) ||
        (arAudDecoder.eStreamFrom == AUD_STREAM_FROM_MEMORY && isUpload == 1))
    {
        // E-mixsnd only case (Not decode or OMX decode)
        pSignalFormat->eChConf       = E_CUST_AUD_CH_CONF_STEREO;
        pSignalFormat->eCodec        = E_CUST_AUD_CODEC_PCM;
        pSignalFormat->eSamplingRate = E_CUST_AUD_FS_48K;
        pSignalFormat->u4BitLength   = 24;
        return;
    }

    rAudInfo.e_dec_type=AUD_DECODE_TYPE_UNKNOWN;
    AUD_GetDtvAudInfo(u1DecId,&rAudInfo);

    if(rAudInfo.ui4_sample_rate != 0)
    {
        pSignalFormat->eSamplingRate =eSampRateConvFromUINT32(rAudInfo.ui4_sample_rate);    
    }
    else
    {
        pSignalFormat->eSamplingRate =eSampRateConv(AUD_GetSampleFreq(u1DecId));    
    }
    if(rAudInfo.ui4_data_rate != 0)
    {
        pSignalFormat->u4BitRate = rAudInfo.ui4_data_rate;
    }
    else
    {
        pSignalFormat->u4BitRate = DSP_GetDataRate(u1DecId);
    }  
#ifdef CC_AUD_SAKURA_RENDER
    if (rAudDecStreamFrom == AUD_STREAM_FROM_HDMI && eAudDecFormat == AUD_FMT_PCM)
    {
        u1Ca = AUD_HDMI_Get_Aud_CA();
        switch(AUD_HDMI_Get_Aud_ChannelNum())
        {
        case 0:
            pSignalFormat->eChConf = E_CUST_AUD_CH_CONF_STEREO;
            break;
        case 1: //u1Ca == 0x0
            pSignalFormat->eChConf = E_CUST_AUD_CH_CONF_STEREO;
            break;
        case 2:
            if (u1Ca == 0x1)
            {
                pSignalFormat->eChConf = E_CUST_AUD_CH_CONF_2_0_0_1;
            }
            else if (u1Ca == 0x4)
            {
                pSignalFormat->eChConf = E_CUST_AUD_CH_CONF_2_0_1_0;
            }
            else //u1Ca = 0x2 or others
            {
                pSignalFormat->eChConf = E_CUST_AUD_CH_CONF_3_0_0_0;
            }
            break;
        case 3:
            if (u1Ca == 0x3)
            {
                pSignalFormat->eChConf = E_CUST_AUD_CH_CONF_3_0_0_1;
            }
            else if (u1Ca == 0x5)
            {
                pSignalFormat->eChConf = E_CUST_AUD_CH_CONF_2_0_1_1;
            }
            else if (u1Ca == 0x8)
            {
                pSignalFormat->eChConf = E_CUST_AUD_CH_CONF_2_0_2_0;
            }
            else //u1Ca = 0x6 or others
            {
                pSignalFormat->eChConf = E_CUST_AUD_CH_CONF_3_0_1_0;
            }
            break;
        case 4:
            if (u1Ca == 0x7)
            {
                pSignalFormat->eChConf = E_CUST_AUD_CH_CONF_3_0_1_1;
            }
            else if (u1Ca == 0x9)
            {
                pSignalFormat->eChConf = E_CUST_AUD_CH_CONF_2_0_2_1;
            }
            else //u1Ca = 0xA or others
            {
                pSignalFormat->eChConf = E_CUST_AUD_CH_CONF_3_0_2_0;
            }
            break;
        case 5: //u1Ca == 0xB
            pSignalFormat->eChConf = E_CUST_AUD_CH_CONF_3_0_2_1;
            break;

        default:
            pSignalFormat->eChConf = E_CUST_AUD_CH_CONF_3_0_2_1;
            break;
        }
    }
    else if(rAudInfo.e_aud_type != AUD_TYPE_UNKNOWN)
#else // CC_AUD_SAKURA_RENDER
    if(rAudInfo.e_aud_type != AUD_TYPE_UNKNOWN)
#endif // CC_AUD_SAKURA_RENDER
    {
        pSignalFormat->eChConf = eChConfConv(rAudInfo.e_aud_type);
#ifdef CC_AUD_DOLBY_SUPPORT_MS12v2// if ATMOS contents, set height = on
        if ( 1 == arCPUDECCommonDecInfo[ u1DecId ].u4atmos_present ) 
        {
            pSignalFormat->eChConfHeight = 1;
            LOG( 1, "\n\neChConf = %d, eChConfHeight = %d @ GetAudioSignalFormat()\n\n", pSignalFormat->eChConf, pSignalFormat->eChConfHeight );
        }
#endif // CC_AUD_DOLBY_SUPPORT_MS12v2
    }
    else
    {
        pSignalFormat->eChConf = eChConfConv(DSP_GetAudChlInfo(u1DecId));
    }
    if(rAudInfo.e_dec_type!=AUD_DECODE_TYPE_UNKNOWN)
    {
        pSignalFormat->eCodec = eDecTypeConv(rAudInfo.e_dec_type);
    }    
    else
    {
        pSignalFormat->eCodec = eCodecFmtConv(arAudDecoder.eDecFormat);
    }
#ifdef CC_AUD_DOLBY_SUPPORT_MS12v2
    // if Signal is AAC && Dualmono, it need to check the HeaacDualMode.
    if ((pSignalFormat->eChConf == E_CUST_AUD_CH_CONF_DUAL_MONO) &&
            ((pSignalFormat->eCodec == E_CUST_AUD_CODEC_AAC) ||
            (pSignalFormat->eCodec == E_CUST_AUD_CODEC_HE_AAC) ||
            (pSignalFormat->eCodec == E_CUST_AUD_CODEC_HE_AAC_V2)))
    {
        if(AUD_GetHeaacDualMode(u1DecId) != 2) // 0: MAIN, 1: SUB, 2: MAIN & SUB
        {
            pSignalFormat->eChConf = E_CUST_AUD_CH_CONF_MONO;
        }
    }
#endif // CC_AUD_DOLBY_SUPPORT_MS12v2

    pSignalFormat->eSigSta = E_CUST_AUD_SIG_STA_STABLE;        
#ifdef CC_AUD_SAKURA_RENDER
    lastDspId=u1DspId;
    lastDecId=u1DecId;
#endif // CC_AUD_SAKURA_RENDER
}

UINT32 DRVCUST_GetAudioDelay(void)
{
    return AUD_DspQueryChannelDelay(AUD_CH_FRONT_RIGHT);
}

void DRVCUST_GetAudioOutputFormat (CUST_AUD_OUT_FORMAT_T* pOutFormat)
{
//BE_FIXME
#if 0
    SAMPLE_FREQ_T eSmpRate;
    AUD_DECODER_T arAudDecoder;

    UINT8 u1DecId;
    AUD_DEC_STREAM_FROM_T  rAudDecStreamFrom;
    AUD_FMT_T              eAudDecFormat;
    UNUSED(eAudDecFormat);

    u1DecId = AUD_DEC_MAIN; 
    AUD_DRVGetDecodeType(u1DecId, &rAudDecStreamFrom, &eAudDecFormat);
    AUD_GetDecoderStatus(u1DecId, &arAudDecoder);
    if((arAudDecoder.eDecState != AUD_DEC_PLAYING) || 
       (rAudDecStreamFrom==AUD_STREAM_FROM_DIGITAL_TUNER) ||
       (rAudDecStreamFrom==AUD_STREAM_FROM_ANALOG_TUNER))
    {
        u1DecId = AUD_DEC_AUX; 
        AUD_GetDecoderStatus(u1DecId, &arAudDecoder);               
        if(arAudDecoder.eDecState != AUD_DEC_PLAYING)
        {
            pOutFormat->eSamplingRate=E_CUST_AUD_FS_UNKNOWN;
            return;
        }        
    }    
    eSmpRate = AUD_GetSampleFreq(u1DecId); //BE_FIXME
    pOutFormat->eSamplingRate = eSampRateConv(eSmpRate);
#else
    UNUSED(eSampRateConv);
    UINT32 u4Reg0;
#ifdef CC_SUPPORT_96K_AOUT
    if (_MT5398_PWM_Out_Fs_Query()==FS_96K)
    {
        pOutFormat->eSamplingRate = E_CUST_AUD_FS_96K;
    }
    else
#endif
    {
        pOutFormat->eSamplingRate = E_CUST_AUD_FS_48K;
    }

    _vAUD_Aproc_Get (APROC_CONTROL_TYPE_IEC, APROC_IOCTRL_IEC_RAWAUDFMT, (UINT32 *)&u4Reg0, 1);
    if (AUD_GetHDMIRxBypassAout3()!= AUD_AOUT3_BYPASS_OFF)
    {
        pOutFormat->eDoutPath = E_CUST_AUD_DOUT_TYPE_I2S_BYPASS;
    }
    else
    {
        pOutFormat->eDoutPath = geDoutType;
    }
#endif
}

void DRVCUST_GetVolume(CUST_AUD_VOLUME_T* pVolume)
{
#ifdef CC_AUD_SAKURA_RENDER
    BOOL bChMute = _AUD_DspGetChannelMute(AUD_DEC_MAIN, AUD_CH_FRONT_LEFT);
    if(bChMute) {
        pVolume->u4SpeakerVolume = 0;
    }
    else {
    pVolume->u4SpeakerVolume = (UINT32)AUD_DspGetChannelVolume(AUD_DEC_MAIN, AUD_CH_FRONT_LEFT); //BE_FIXME
    }
#else
    pVolume->u4SpeakerVolume = (UINT32)AUD_DspGetMasterVolume(AUD_DEC_MAIN); //BE_FIXME    
#endif // CC_AUD_SAKURA_RENDER
}

void DRVCUST_GetSoundSetting(CUST_AUD_SOUND_SETTING_T* pSoundSetting)
{
    x_memcpy((VOID*)VIRTUAL((UPTR)pSoundSetting), (VOID*)&gSoundSetting, sizeof(CUST_AUD_SOUND_SETTING_T));
#ifdef CC_AUD_SAKURA_RENDER
     if(gSoundSetting.eDynamicRange != E_CUST_AUD_DYNAMIC_RANGE_COMPRESSED){
        pSoundSetting->i1HeAacAudioLevel = 0;
    }
#endif //CC_AUD_SAKURA_RENDER
}

void DRVCUST_GetAudioChannelMuteState(UINT8 bPath, CUST_AUD_CH_MUTE_STATE_T* pMuteState)
{
    BOOL bAmpEnableFlag, bVolMute;
    UNUSED(bPath); //BE_FIXME

    bAmpEnableFlag = ADAC_AmpEnableFlag();
    bVolMute = _GetVolMuteStatus(bPath);
    pMuteState->eMuteState = E_CUST_AUD_MUTE_STATE_UNMUTE;
    if (!bAmpEnableFlag || bVolMute)
    {
        pMuteState->eMuteState = E_CUST_AUD_MUTE_STATE_MUTE;
    }
}
    
void DRVCUST_GetAudioPlayState(UINT8 bPath, CUST_AUD_PLAY_STATE_T* pPlayState)
{
   UINT8 u1DecId, u1DspId;
   UNUSED(bPath);//BE_FIXME

   u1DecId = AUD_DEC_MAIN;
   u1DspId = AUD_DSP0;
   _AUD_GetCurrentDec(&u1DspId, &u1DecId, NULL);
   pPlayState->eAudioState = eGetPlayState(AUD_DSP0, u1DecId);
}

void DRVCUST_GetAudioMixState(CUST_AUD_MIX_STATE_T* pState)
{
    UNUSED(DRVCUST_GetAudioMixState); 
    pState->eSkypeMixState = E_CUST_AUD_STATE_OFF;
    pState->eAudioDescriptionMixState = E_CUST_AUD_STATE_OFF;
}


void DRVCUST_GetServiceModeState(CUST_AUD_SERVICE_MODE_STATE_T* pState)
{
    UNUSED(DRVCUST_GetServiceModeState);
    pState->eServiceModeState = E_CUST_AUD_STATE_OFF;
}

void DRVCUST_GetSubwooferState(CUST_AUD_SUBWOOFER_STATE_T* pState )
{
    UNUSED(DRVCUST_GetSubwooferState);
#ifndef CC_AUD_SAKURA_RENDER
    pState->eSubwooferState = E_CUST_AUD_SUBWOOFER_STATE_NONE;
#else // CC_AUD_SAKURA_RENDER
    if(gSoundSetting.u1SubwooferEnable && gSoundSetting.eHpAudioOut == E_CUST_AUD_HP_AUD_OUT_SUBWOOFER)
    {
        pState->eSubwooferState = E_CUST_AUD_SUBWOOFER_STATE_WIRELESS;
    }
    else
    {
        pState->eSubwooferState = E_CUST_AUD_SUBWOOFER_STATE_WIRED;
    }
#endif //CC_AUD_SAKURA_RENDER
}

UINT8 DRVCUST_GetMCKState(void)
{
    UNUSED(DRVCUST_GetMCKState);   
#ifdef CC_AUD_SAKURA_RENDER
    if(AUD_IsAudHWInit() == 1){
        _fgBEBoot = TRUE;
    }
#endif
    return (UINT8)AUD_IsAudHWInit();
}

int DRVCUST_SendAudEvent(E_CUST_AUD_EVENT eCustEvent, UINT8 u1Option)
{
    u1Option = 0; //BE_FIXME //bPath set to 0 temp
    if((eCustEvent == E_CUST_AUD_SPEAKER_MUTE_REQUEST) && (AUD_get4kBeMuteDone()==TRUE))
    {
        return -1;
    }
    else if((eCustEvent == E_CUST_AUD_SPEAKER_UNMUTE_REQUEST) && (AUD_get4kBeMuteDone()==FALSE))
    {
        return -1;
    }
    //Printf("\n\n\t\tDRVCUST_SendAudEvent, %d\n\n\n",eCustEvent);
    if (pBeAudFunc)
    {    
        pBeAudFunc->aDrvCustSendAudEvent(eCustEvent, u1Option);
    } else {
        return -1;
    }    

    if(eCustEvent == E_CUST_AUD_SPEAKER_MUTE_REQUEST)
    {
        LOG(0, "DRVCUST_SendAudEvent notified E_CUST_AUD_SPEAKER_MUTE_REQUEST\n");
    }
    else if(eCustEvent == E_CUST_AUD_SPEAKER_UNMUTE_REQUEST)
    {
        LOG(0, "DRVCUST_SendAudEvent notified E_CUST_AUD_SPEAKER_UNMUTE_REQUEST\n");
    }

    return 0;
}

void DRVCUST_SendSAPostEvent(E_CUST_AUD_SAPOST_EVENT eCustEvent, UINT8 u1Option)
{
    AUD_DECODER_T arAudDecoder={0};
    AUD_DEC_INFO_T rAudInfo={AUD_FMT_UNKNOWN,AUD_TYPE_UNKNOWN,0,0,0,AUD_DECODE_TYPE_UNKNOWN};
    UINT8 u1DecId, u1DspId;
    AUD_DEC_STREAM_FROM_T  rAudDecStreamFrom;
    AUD_FMT_T              eAudDecFormat;
#ifdef CC_AUD_SAKURA_RENDER    
    UINT32 u4AdReg[2];
#endif // CC_AUD_SAKURA_RENDER
    UINT32 SPK_Out_Sel;
    UINT8 u1Ca = 0;
    UINT32 isUpload = 0;

    UNUSED(u1Option);

    //Currently there are 6 cases to this function.
    // 1. E_CUST_AUD_SAPOST_GEN_CONFIG:  (Wall, Table....)
    // 2. E_CUST_AUD_SAPOST_POST_CONFIG: (Post Proc Config)
    // 3. E_CUST_AUD_SAPOST_STR_INFO:    (Stream Info)
    // 4. E_CUST_AUD_SAPOST_SP_MODE:     (Picture Reset Mode)
    // 5. E_CUST_AUD_SAPOST_BT_INFO:     (Bluetooth info)
    // 6. E_CUST_AUD_SAPOST_AUD_ITEM_CMD: (General Info)
    // These 6 information should be set to "speaker source"
    // e.x. Play MM on Dec0, Speaker sel to 0
    //      Play TV on Dec1, Speaker sel to 1
    //      Play HDMI on Dec0 and TV on Dec1(SCART), Speaker sel to 0   	
    SPK_Out_Sel= u4AprocReg_Read (APROC_ASM_ADDR(APROC_ASM_ID_SEL_0, APROC_REG_SEL_DSP_SP_IN));
    if (SPK_Out_Sel >= (UINT32)AUD_DEC_THIRD)
    {
        SPK_Out_Sel = (UINT32)AUD_DEC_MAIN; //Sometime if ASM is not set ready (e.x. just power up), set to default.
    }
    if((u4AprocReg_Read (APROC_ASM_ADDR(APROC_ASM_ID_COMM_2, APROC_REG_AMIXER2_ADMIX_FLAG)) != 0) &&
        (SPK_Out_Sel == (UINT32)AUD_DEC_MAIN))
    {
        SPK_Out_Sel = (UINT32)AUD_DEC_AUX; //AD_TO_SRC0
    }
    
    //LOG(0,"\n\n\tDRVCUST_SendSAPostEvent %d %d\n\n",eCustEvent,u1Option );
    switch(eCustEvent)
    {
    case E_CUST_AUD_SAPOST_GEN_CONFIG: //Wall, Table
#ifdef CC_COMBINE_4K_2K
        if((DRVCUST_Get_2K_Model()&0x03)==0x00)
        {
			gSAPostGenConfig.m_modelChassisType = SAPOST_MODEL_CHASSIS_TYPE_2K;
        }
		else
		{
#ifdef CC_MT5891
        if (CustomGetFY()<2017)
        {
            if(DRVCUST_Get_BE_Type() != 0) //4K / M2 + BE
                gSAPostGenConfig.m_modelChassisType = SAPOST_MODEL_CHASSIS_TYPE_M2_TYPE1;
            else
                gSAPostGenConfig.m_modelChassisType = SAPOST_MODEL_CHASSIS_TYPE_M2_TYPE0;
        }
        else
        {
            if(GetBackEndType()==0)
                gSAPostGenConfig.m_modelChassisType = SAPOST_MODEL_CHASSIS_TYPE_M2_TYPE2;
            else
                gSAPostGenConfig.m_modelChassisType = SAPOST_MODEL_CHASSIS_TYPE_M2_TYPE3;
        }
#else
			gSAPostGenConfig.m_modelChassisType = SAPOST_MODEL_CHASSIS_TYPE_4K;
#endif

		}        
#endif        
        gSAPostGenConfig.m_usage = SAPOST_USAGE_NORMAL_MODE;
        gSAPostGenConfig.m_modelType = SAPOST_MODEL_TYPE_2_0ch;
        gSAPostGenConfig.m_modelDataAq =SAPOST_MODEL_DATA_AQ_STANDARD;
        vAprocDataPort_WriteByte(APROC_DATAPORT_SAPOST_GEN_CONFIG_BASE, (UINT8 *)&gSAPostGenConfig, sizeof(gSAPostGenConfig));  
        vAprocReg_Write (APROC_ASM_ADDR (APROC_ASM_ID_SAP_MISC_23, APROC_REG_SPOST_GEN_CONFIG), 1); 
     #ifdef CC_AUD_SAKURA_RENDER_AQ //for Sony Downmix	
        //LOG(0, "Downmix - E_CUST_AUD_SAPOST_GEN_CONFIG -%d, %d\n", u1Option, SPK_Out_Sel);
        Aud_Updata_DSP_Downmix(SPK_Out_Sel, gSAPostInpStrInfo.m_codec, gSAPostInpStrInfo.m_channels, gSAPostGenConfig.m_speakers, gSAPostConfig.m_soundMode, gSAPostConfig.m_surround, gSAPostConfig.m_nightMode);		
     #endif	   		
        break;
    case E_CUST_AUD_SAPOST_POST_CONFIG: //Post Proc Config
        gSAPostConfig.m_soundBooster = (unsigned char)SAPOST_SOUND_BOOSTER_UNKNOWN; // requested, due to not included in this version
        gSAPostConfig.m_volumeOffset = (char)0; //requested
        vAprocDataPort_WriteByte(APROC_DATAPORT_SAPOST_POST_CONFIG_BASE, (UINT8 *)&gSAPostConfig, sizeof(gSAPostConfig));  
        vAprocReg_Write (APROC_ASM_ADDR (APROC_ASM_ID_SAP_MISC_23, APROC_REG_SPOST_POST_CONFIG), 1); 
     #ifdef CC_AUD_SAKURA_RENDER_AQ //for Sony Downmix	
        //LOG(0, "Downmix - E_CUST_AUD_SAPOST_POST_CONFIG -%d, %d\n", u1Option, SPK_Out_Sel);     
        Aud_Updata_DSP_Downmix(SPK_Out_Sel, gSAPostInpStrInfo.m_codec, gSAPostInpStrInfo.m_channels, gSAPostGenConfig.m_speakers, gSAPostConfig.m_soundMode, gSAPostConfig.m_surround, gSAPostConfig.m_nightMode);		
     #endif	   		
        break;
    case E_CUST_AUD_SAPOST_STR_INFO: //Stream Info 
        u1DspId = AUD_DSP0;
        u1DecId = AUD_DEC_MAIN; 
        AUD_GetDecoderStatus(u1DspId, u1DecId, &arAudDecoder);
        gSAPostInpStrInfo.m_input = (unsigned char)eInputTypeConvSAPost(arAudDecoder.eStreamFrom);                
                
#ifdef CC_AUD_SAKURA_RENDER
        gAqKey.u1Input = eInputTypeConvAQInput(arAudDecoder.eStreamFrom);
        DrvCust_AQ_SetGet(AUD_DrvCust_AQ_Gen_Key, (VOID*)&gAqKey, (VOID*)&_gu4CurrentAqKey, 0, 0);
#endif // CC_AUD_SAKURA_RENDER
                
        _AUD_GetCurrentDec(&u1DspId, &u1DecId, NULL);
        AUD_DRVGetDecodeType(u1DspId, u1DecId, &rAudDecStreamFrom, &eAudDecFormat);
        AUD_GetDecoderStatus(u1DspId, u1DecId, &arAudDecoder);
        isUpload = u4AprocReg_Read (APROC_ASM_ADDR(APROC_ASM_ID_CPU_0, APROC_REG_IOBUF_UPLOAD3_ENABLE));
        if ((arAudDecoder.eDecState != AUD_DEC_PLAYING && arAudDecoder.eDecState != AUD_DEC_PAUSE) ||
            (arAudDecoder.eStreamFrom == AUD_STREAM_FROM_MEMORY && isUpload == 1))
        {
            // E-mixsnd only case (Not decode or OMX decode)
            gSAPostInpStrInfo.m_input =
                    (unsigned char)eInputTypeConvSAPost(AUD_STREAM_FROM_MULTI_MEDIA);
            gSAPostInpStrInfo.m_codec = (unsigned char)eCodecFmtConvSAPost(AUD_FMT_LPCM);
            gSAPostInpStrInfo.m_samplingRate = SAPOST_SAMPLING_RATE_48K;
            gSAPostInpStrInfo.m_bitRateType = SAPOST_BIT_RATE_TYPE_UNKNOWN;
            gSAPostInpStrInfo.m_bitRate = 0;
            gSAPostInpStrInfo.m_channels = SAPOST_CHANNELS_STEREO;
            gSAPostInpStrInfo.m_bitLength = 24;
            gSAPostInpStrInfo.m_srcEn = 0;
            vAprocDataPort_WriteByte(APROC_DATAPORT_SAPOST_STR_INFO_BASE,
                    (UINT8 *)&gSAPostInpStrInfo, sizeof(gSAPostInpStrInfo));
            _AUD_UpdateDspConfig(false);
            break;
        }

        gSAPostInpStrInfo.m_input = (unsigned char)eInputTypeConvSAPost(arAudDecoder.eStreamFrom);                
        rAudInfo.e_dec_type=AUD_DECODE_TYPE_UNKNOWN;
        AUD_GetDtvAudInfo(u1DecId,&rAudInfo);
        if(rAudInfo.e_dec_type!=AUD_DECODE_TYPE_UNKNOWN)
                {
            gSAPostInpStrInfo.m_codec = (unsigned char)eDecTypeConvSAPost(rAudInfo.e_dec_type);      
                }
        else
        {
            gSAPostInpStrInfo.m_codec = (unsigned char)eCodecFmtConvSAPost(arAudDecoder.eDecFormat);
        }
        if(rAudInfo.ui4_sample_rate != 0)
        {
            gSAPostInpStrInfo.m_samplingRate = (unsigned char)eSampRateConvFromUINT32SAPost(rAudInfo.ui4_sample_rate);    
        }
        else
        {
            gSAPostInpStrInfo.m_samplingRate = (unsigned char)eSampRateConvSAPost(AUD_GetSampleFreq(u1DecId));    
        }
        gSAPostInpStrInfo.m_bitRateType = SAPOST_BIT_RATE_TYPE_UNKNOWN;
        if(rAudInfo.ui4_data_rate != 0)
        {
            gSAPostInpStrInfo.m_bitRate = rAudInfo.ui4_data_rate;
        }
        else
        {
            gSAPostInpStrInfo.m_bitRate = DSP_GetDataRate(u1DecId);
        }  

        if(gSAPostInpStrInfo.m_input == SAPOST_INPUT_HDMI && eAudDecFormat == AUD_FMT_PCM)
        {
            u1Ca = AUD_HDMI_Get_Aud_CA();
            switch(AUD_HDMI_Get_Aud_ChannelNum())
            {
            case 0:
                //gSAPostInpStrInfo.m_channels = (unsigned char)E_CUST_AUD_CH_CONF_MONO;
                gSAPostInpStrInfo.m_channels = (unsigned char)E_CUST_AUD_CH_CONF_STEREO;
                break;
            case 1: //u1Ca == 0x0
                gSAPostInpStrInfo.m_channels = (unsigned char)E_CUST_AUD_CH_CONF_STEREO;
                break;
            case 2:
                if (u1Ca == 0x1)
                {
                    gSAPostInpStrInfo.m_channels = (unsigned char)E_CUST_AUD_CH_CONF_2_0_0_1;
                }
                else if (u1Ca == 0x4)
                {
                    gSAPostInpStrInfo.m_channels = (unsigned char)E_CUST_AUD_CH_CONF_2_0_1_0;
                }
                else //u1Ca = 0x2 or others
                {
                gSAPostInpStrInfo.m_channels = (unsigned char)E_CUST_AUD_CH_CONF_3_0_0_0;
                }
                break;

            case 3:
                if (u1Ca == 0x3)
                {
                    gSAPostInpStrInfo.m_channels = (unsigned char)E_CUST_AUD_CH_CONF_3_0_0_1;
                }
                else if (u1Ca == 0x5)
                {
                    gSAPostInpStrInfo.m_channels = (unsigned char)E_CUST_AUD_CH_CONF_2_0_1_1;
                }
                else if (u1Ca == 0x8)
                {
                    gSAPostInpStrInfo.m_channels = (unsigned char)E_CUST_AUD_CH_CONF_2_0_2_0;
                }
                else //u1Ca = 0x6 or others
                {
                gSAPostInpStrInfo.m_channels = (unsigned char)E_CUST_AUD_CH_CONF_3_0_1_0;
                }
                break;
            case 4:    
                if (u1Ca == 0x7)
                {
                    gSAPostInpStrInfo.m_channels = (unsigned char)E_CUST_AUD_CH_CONF_3_0_1_1;
                }
                else if (u1Ca == 0x9)
                {
                    gSAPostInpStrInfo.m_channels = (unsigned char)E_CUST_AUD_CH_CONF_2_0_2_1;
                }
                else //u1Ca = 0xA or others
                {
                gSAPostInpStrInfo.m_channels = (unsigned char)E_CUST_AUD_CH_CONF_3_0_2_0;
                }
                break;
            case 5: //u1Ca == 0xB
                gSAPostInpStrInfo.m_channels = (unsigned char)E_CUST_AUD_CH_CONF_3_0_2_1;
                break;
            default:
                gSAPostInpStrInfo.m_channels = (unsigned char)E_CUST_AUD_CH_CONF_3_0_2_1;
                break;
            }            
        }
        else if(rAudInfo.e_aud_type != AUD_TYPE_UNKNOWN)
        {
            gSAPostInpStrInfo.m_channels = (unsigned char)eChConfConv(rAudInfo.e_aud_type);
        }
        else
        {
            gSAPostInpStrInfo.m_channels = (unsigned char)eChConfConv(DSP_GetAudChlInfo(u1DecId));
        }

#ifdef CC_AUD_SAKURA_RENDER

#ifdef CC_AUD_DOLBY_SUPPORT_MS12v2
        // if Signal is AAC && Dualmono, it need to check the HeaacDualMode.
        if ((gSAPostInpStrInfo.m_channels == SAPOST_CHANNELS_DUAL_MONO) &&
                ((gSAPostInpStrInfo.m_codec == SAPOST_CODEC_MPEG2_AAC) ||
                (gSAPostInpStrInfo.m_codec == SAPOST_CODEC_MPEG4_HE_AAC)))
        {
            if(AUD_GetHeaacDualMode(u1DecId) != 2) // 0: MAIN, 1: SUB, 2: MAIN & SUB
            {
                gSAPostInpStrInfo.m_channels = SAPOST_CHANNELS_MONO;
            }
        }
#endif // CC_AUD_DOLBY_SUPPORT_MS12v2

        if(gSAPostInpStrInfo.m_codec == SAPOST_CODEC_LPCM)
        {
            gSAPostInpStrInfo.m_bitLength = 24;
        }
        else
        {
            if( rAudInfo.ui1_bit_depth != 0)
            {
                //Corrected to 8 multiples value
                if ( rAudInfo.ui1_bit_depth % 8 ){
                    gSAPostInpStrInfo.m_bitLength = rAudInfo.ui1_bit_depth + (8 - (rAudInfo.ui1_bit_depth % 8)) ;
                }
                else
                {
                    gSAPostInpStrInfo.m_bitLength = rAudInfo.ui1_bit_depth;
                }
            }
            else
            {
                gSAPostInpStrInfo.m_bitLength = 24;
            }
        }

        gSAPostInpStrInfo.m_srcEn = 0;
        //get AD info
        _vAUD_Aproc_Get (APROC_CONTROL_TYPE_AD, 0, u4AdReg, 1);
        if(u4AdReg[0] == 1){
            gSAPostInpStrInfo.m_srcEn |= (1 << SAPOST_SRC_ENABLE_ADMIX);
        }
        else{
            gSAPostInpStrInfo.m_srcEn |= (0 << SAPOST_SRC_ENABLE_ADMIX);
        }

#ifdef CC_AUD_SAKURA_RENDER
        _AUD_UpdateDspConfig(false);
#endif // CC_AUD_SAKURA_RENDER
     #ifdef CC_AUD_SAKURA_RENDER_AQ //for Sony Downmix	
        //LOG(0, "Downmix - E_CUST_AUD_SAPOST_STR_INFO -%d, %d\n", u1Option, SPK_Out_Sel);          
        Aud_Updata_DSP_Downmix(SPK_Out_Sel, gSAPostInpStrInfo.m_codec, gSAPostInpStrInfo.m_channels, gSAPostGenConfig.m_speakers, gSAPostConfig.m_soundMode, gSAPostConfig.m_surround, gSAPostConfig.m_nightMode);		
     #endif
#else // CC_AUD_SAKURA_RENDER
        vAprocDataPort_WriteByte(APROC_DATAPORT_SAPOST_STR_INFO_BASE, (UINT8 *)&gSAPostInpStrInfo, sizeof(gSAPostInpStrInfo)); 
        vAprocReg_Write (APROC_ASM_ADDR (APROC_ASM_ID_SAP_MISC_23, APROC_REG_SPOST_STR_INFO), 1); 
     #ifdef CC_AUD_SAKURA_RENDER_AQ //for Sony Downmix	
        Aud_Updata_DSP_Downmix(SPK_Out_Sel, gSAPostInpStrInfo.m_codec, gSAPostInpStrInfo.m_channels, gSAPostGenConfig.m_speakers, gSAPostConfig.m_soundMode, gSAPostConfig.m_surround, gSAPostConfig.m_nightMode);		
     #endif	   
#endif//CC_AUD_SAKURA_RENDER
        break;
    case E_CUST_AUD_SAPOST_SP_MODE:
        vAprocDataPort_WriteByte(APROC_DATAPORT_SAPOST_SP_MODE_BASE, (UINT8 *)&gSAPostSpModeInfo, sizeof(gSAPostSpModeInfo));  
#ifdef CC_AUD_SAKURA_RENDER
        vAprocReg_Write (APROC_ASM_ADDR (APROC_ASM_ID_SAP_MISC_23, APROC_REG_SPOST_SP_MODE), 1); 
#endif
        break;
    case E_CUST_AUD_SAPOST_BT_INFO:
        if (gSoundSetting.u1BtConect == E_CUST_AUD_BT_STATE_CONNECTED) {
            gSAPostBtInfo.m_connect = SAPOST_BT_CONNECT;
            gSAPostBtInfo.m_devProfile = SAPOST_BT_PROFILE_SBC;
        /* } else if (gSoundSetting.u1BtConect == E_CUST_AUD_BT_STATE_CONNECTED_HIRES) { */
        /*     gSAPostBtInfo.m_connect = SAPOST_BT_CONNECT; */
        /*     gSAPostBtInfo.m_devProfile = SAPOST_BT_PROFILE_LDAC; */
        } else {
            gSAPostBtInfo.m_connect = SAPOST_BT_DISCONNECT;
            gSAPostBtInfo.m_devProfile = SAPOST_BT_PROFILE_UNKNOWN;
        }
        vAprocDataPort_WriteByte(APROC_DATAPORT_SAPOST_BT_INFO_BASE, (UINT8 *)&gSAPostBtInfo, sizeof(gSAPostBtInfo));  
        vAprocReg_Write (APROC_ASM_ADDR (APROC_ASM_ID_SAP_MISC_23, APROC_REG_SPOST_BT_INFO), 1); 
        break;
    case E_CUST_AUD_SAPOST_AUD_ITEM_CMD:
        vAprocDataPort_Write(APROC_DATAPORT_SAPOST_AUD_ITEM_CMD_BASE, (UINT32 *)&gSAPostAudItemCmd, sizeof(gSAPostAudItemCmd)/4+1);
        vAprocReg_Write (APROC_ASM_ADDR (APROC_ASM_ID_SAP_MISC_23, APROC_REG_SPOST_AUD_ITEM_CMD), 1); 
        break;

            }        
        }   

#ifdef CC_AUD_SAKURA_RENDER 
void DRVCUST_SetSAPostStreamInfo(UINT8 u1DspId, UINT8 u1DecId)
{
    AUD_DECODER_T          arAudDecoder={0};
    AUD_DEC_INFO_T         rAudInfo={AUD_FMT_UNKNOWN,AUD_TYPE_UNKNOWN,0,0,0,AUD_DECODE_TYPE_UNKNOWN};
    AUD_FMT_T              eAudDecFormat;
    AUD_DEC_STREAM_FROM_T  rAudDecStreamFrom;
    UINT32 SPK_Out_Sel;
    UINT32 u4AdReg[2];
    UINT8 u1Ca = 0;
    
    SPK_Out_Sel= u4AprocReg_Read (APROC_ASM_ADDR(APROC_ASM_ID_SEL_0, APROC_REG_SEL_DSP_SP_IN));
    if (SPK_Out_Sel >= (UINT32)AUD_DEC_THIRD)
    {
        SPK_Out_Sel = (UINT32)AUD_DEC_MAIN; //Sometime if ASM is not set ready (e.x. just power up), set to default.
    }    
    if((u4AprocReg_Read (APROC_ASM_ADDR(APROC_ASM_ID_COMM_2, APROC_REG_AMIXER2_ADMIX_FLAG)) != 0) &&
        (SPK_Out_Sel == (UINT32)AUD_DEC_MAIN))
    {
        SPK_Out_Sel = (UINT32)AUD_DEC_AUX; //AD_TO_SRC0
    }

    AUD_DRVGetDecodeType(u1DspId, u1DecId, &rAudDecStreamFrom, &eAudDecFormat);
    AUD_GetDecoderStatus(u1DspId, u1DecId, &arAudDecoder);
	
        gSAPostInpStrInfo.m_input = (unsigned char)eInputTypeConvSAPost(arAudDecoder.eStreamFrom);                
        rAudInfo.e_dec_type=AUD_DECODE_TYPE_UNKNOWN;
        AUD_GetDtvAudInfo(u1DecId,&rAudInfo);
        if(rAudInfo.e_dec_type!=AUD_DECODE_TYPE_UNKNOWN)
        {
            gSAPostInpStrInfo.m_codec = (unsigned char)eDecTypeConvSAPost(rAudInfo.e_dec_type);      
        }
        else
        {
            gSAPostInpStrInfo.m_codec = (unsigned char)eCodecFmtConvSAPost(arAudDecoder.eDecFormat);
        }
        if(rAudInfo.ui4_sample_rate != 0)
        {
            gSAPostInpStrInfo.m_samplingRate = (unsigned char)eSampRateConvFromUINT32SAPost(rAudInfo.ui4_sample_rate);    
        }
        else
        {
            gSAPostInpStrInfo.m_samplingRate = (unsigned char)eSampRateConvSAPost(AUD_GetSampleFreq(u1DecId));    
        }
        gSAPostInpStrInfo.m_bitRateType = SAPOST_BIT_RATE_TYPE_UNKNOWN;
        if(rAudInfo.ui4_data_rate != 0)
        {
            gSAPostInpStrInfo.m_bitRate = rAudInfo.ui4_data_rate;
        }
        else
        {
            gSAPostInpStrInfo.m_bitRate = DSP_GetDataRate(u1DecId);
        }  

        if(gSAPostInpStrInfo.m_input == SAPOST_INPUT_HDMI && eAudDecFormat == AUD_FMT_PCM)
        {
            u1Ca = AUD_HDMI_Get_Aud_CA();
            switch(AUD_HDMI_Get_Aud_ChannelNum())
            {
            case 0:
                gSAPostInpStrInfo.m_channels = (unsigned char)E_CUST_AUD_CH_CONF_STEREO;
                break;
            case 1: //u1Ca == 0x0
                gSAPostInpStrInfo.m_channels = (unsigned char)E_CUST_AUD_CH_CONF_STEREO;
                break;
            case 2:
                if (u1Ca == 0x1)
                {
                    gSAPostInpStrInfo.m_channels = (unsigned char)E_CUST_AUD_CH_CONF_2_0_0_1;
                }
                else if (u1Ca == 0x4)
                {
                    gSAPostInpStrInfo.m_channels = (unsigned char)E_CUST_AUD_CH_CONF_2_0_1_0;
                }
                else //u1Ca = 0x2 or others
                {
                    gSAPostInpStrInfo.m_channels = (unsigned char)E_CUST_AUD_CH_CONF_3_0_0_0;
                }
                break;
            case 3:
                if (u1Ca == 0x3)
                {
                    gSAPostInpStrInfo.m_channels = (unsigned char)E_CUST_AUD_CH_CONF_3_0_0_1;
                }
                else if (u1Ca == 0x5)
                {
                    gSAPostInpStrInfo.m_channels = (unsigned char)E_CUST_AUD_CH_CONF_2_0_1_1;
                }
                else if (u1Ca == 0x8)
                {
                    gSAPostInpStrInfo.m_channels = (unsigned char)E_CUST_AUD_CH_CONF_2_0_2_0;
                }
                else //u1Ca = 0x6 or others
                {
                    gSAPostInpStrInfo.m_channels = (unsigned char)E_CUST_AUD_CH_CONF_3_0_1_0;
                }
                break;
            case 4:
                if (u1Ca == 0x7)
                {
                    gSAPostInpStrInfo.m_channels = (unsigned char)E_CUST_AUD_CH_CONF_3_0_1_1;
                }
                else if (u1Ca == 0x9)
                {
                    gSAPostInpStrInfo.m_channels = (unsigned char)E_CUST_AUD_CH_CONF_2_0_2_1;
                }
                else //u1Ca = 0xA or others
                {
                    gSAPostInpStrInfo.m_channels = (unsigned char)E_CUST_AUD_CH_CONF_3_0_2_0;
                }
                break;
            case 5: //u1Ca == 0xB
                gSAPostInpStrInfo.m_channels = (unsigned char)E_CUST_AUD_CH_CONF_3_0_2_1;
                break;
            default:
                gSAPostInpStrInfo.m_channels = (unsigned char)E_CUST_AUD_CH_CONF_3_0_2_1;
                break;
            }            
        }
        else if(rAudInfo.e_aud_type != AUD_TYPE_UNKNOWN)
        {
            gSAPostInpStrInfo.m_channels = (unsigned char)eChConfConv(rAudInfo.e_aud_type);
        }
        else
        {
            gSAPostInpStrInfo.m_channels = (unsigned char)eChConfConv(DSP_GetAudChlInfo(u1DecId));
        }

#ifdef CC_AUD_DOLBY_SUPPORT_MS12v2
        // if Signal is AAC && Dualmono, it need to check the HeaacDualMode.
        if ((gSAPostInpStrInfo.m_channels == SAPOST_CHANNELS_DUAL_MONO) &&
                ((gSAPostInpStrInfo.m_codec == SAPOST_CODEC_MPEG2_AAC) ||
                (gSAPostInpStrInfo.m_codec == SAPOST_CODEC_MPEG4_HE_AAC)))
        {
            if(AUD_GetHeaacDualMode(u1DecId) != 2) // 0: MAIN, 1: SUB, 2: MAIN & SUB
            {
                gSAPostInpStrInfo.m_channels = SAPOST_CHANNELS_MONO;
            }
        }
#endif // CC_AUD_DOLBY_SUPPORT_MS12v2

        if(gSAPostInpStrInfo.m_codec == SAPOST_CODEC_LPCM)
        {
            gSAPostInpStrInfo.m_bitLength = 16;
        }
        else
        {
            if( rAudInfo.ui1_bit_depth != 0)
            {
                //Corrected to 8 multiples value
                if ( rAudInfo.ui1_bit_depth % 8 ){
                    gSAPostInpStrInfo.m_bitLength = rAudInfo.ui1_bit_depth + (8 - (rAudInfo.ui1_bit_depth % 8)) ;
                }
                else
                {
                    gSAPostInpStrInfo.m_bitLength = rAudInfo.ui1_bit_depth;
                }
            }
            else
            {
                gSAPostInpStrInfo.m_bitLength = 24;
            }
        }

    gSAPostInpStrInfo.m_srcEn = 0;
    //get AD info
    _vAUD_Aproc_Get (APROC_CONTROL_TYPE_AD, 0, u4AdReg, 1);
    if(u4AdReg[0] == 1){
        gSAPostInpStrInfo.m_srcEn |= (1 << SAPOST_SRC_ENABLE_ADMIX);
    }
    else{
        gSAPostInpStrInfo.m_srcEn |= (0 << SAPOST_SRC_ENABLE_ADMIX);
    }

	return;
}
#endif //CC_AUD_SAKURA_RENDER 

//If Sony BE is muted, BE Ctrl call SetBeMuteState(TRUE)
//Else if Sony BE is unmuted, BE Ctrl call SetBeMuteState(FALSE)
void DRVCUST_SetBeMuteState(UINT8 bState)
{
    AUD_set4kBeMuteDone((BOOL)(bState));
}

//Delay value inside Sony 4K BE. The value is msec. 
extern UINT32 _gu4BeDelay;
void DRVCUST_SetBeDelay(UINT32 u4Delay)
{
    _gu4BeDelay = u4Delay;
#ifdef CC_AUD_SAKURA_RENDER
    UpdateMainDelay(TRUE, FALSE);
#endif /* CC_AUD_SAKURA_RENDER */
}

#endif //CC_MAPLE_CUST_DRV
