/*************************************************************************** * Copyright (c) 2006, Broadcom Corporation * All Rights Reserved * Confidential Property of Broadcom Corporation * * THIS SOFTWARE MAY ONLY BE USED SUBJECT TO AN EXECUTED SOFTWARE LICENSE * AGREEMENT BETWEEN THE USER AND BROADCOM. YOU HAVE NO RIGHT TO USE OR * EXPLOIT THIS MATERIAL EXCEPT SUBJECT TO THE TERMS OF SUCH AN AGREEMENT. * * $brcm_Workfile: $ * $brcm_Revision: $ * $brcm_Date: $ * * Module Description: * * PCM output * * Revision History: * * $brcm_Log: $ * * *******************************************************************************/ #include "bsettop_decode_audio.h" #include "bsettop_p_stream.h" #include "bsettop_hdmi.h" #include "bhdm.h" #include "gist.h" #ifdef BCM_DEBUG #define INIT_CHECK(a) \ { \ BDBG_MSG((#a " - Enter\n")); \ if (a != BERR_SUCCESS) \ { \ BDBG_ERR((#a " #### failed in %s:%d\n",__FUNCTION__,__LINE__)); \ goto failed; \ } \ BDBG_MSG((#a " - Exit\n")); \ } #else /* BCM_DEBUG */ #define INIT_CHECK(x) if (x != BERR_SUCCESS) goto failed #endif BDBG_MODULE(decode_audio); #define CONFIG_COMPRESS_HDMI struct baudio_decode { bool initialized; baudio_decode_config config; bool audio_decode; bool compressed_decode; int first_pts_cnt; int sample_rate_change_cnt; int tsm_failed_cnt; BXPT_RaveCx_Handle hAudioDecodeRaveCx; /* Rave context associated with the stream */ BXPT_RaveCx_Handle hAudioCompressedRaveCx; /* Rave context associated with the stream */ b_mutex_t mutex; bstream_t stream; #if (BCHP_CHIP!=7552) BRAP_AudioDescriptorFadeHandle hAdFade; BRAP_ChannelParams decodeAudioParams; BRAP_ChannelParams compressedAudioParams; BRAP_ChannelHandle hRapDecodeCh; BRAP_ChannelHandle hRapCompressedCh; #endif }; struct baudio_decode s_audio = { false, { NULL,NULL,0,0,false }, false, false, 0, 0, 0, NULL, NULL, NULL, { 0, 0, 0 }, NULL }; #if (BCHP_CHIP!=7552) extern void boutput_remove_decode_association(BRAP_ChannelHandle hRapCh); extern void boutput_add_decode_association(BRAP_ChannelHandle hRapCh); extern void boutput_add_compress_association(BRAP_ChannelHandle hRapCh); extern void boutput_remove_compress_association(BRAP_ChannelHandle hRapCh); extern void boutput_remove_decode_mai_output(void); extern void boutput_add_decode_mai_output(void); extern void boutput_add_compress_mai_output(void); extern void boutput_remove_compress_mai_output(void); extern BERR_Code boutput_set_association_vol(BRAP_OutputPort eOpType, unsigned int iLVol, unsigned int iRVol); extern BERR_Code boutput_set_association_mute(BRAP_OutputPort eOpType, bool bMute); #endif static void b_lock(baudio_decode_t codec) { bresult rc; rc = bos_acquire_mutex(&s_audio.mutex, 10 * 1000); BDBG_ASSERT(rc==b_ok); return; } static void b_unlock(baudio_decode_t codec) { bresult rc; rc = bos_release_mutex(&s_audio.mutex); BDBG_ASSERT(rc==b_ok); return; } #if (BCHP_CHIP!=7552) void baudio_decode_rate_change_cb (void *pParm1, int parm2, void *pRap_data) { baudio_decode_t audio = (baudio_decode_t)pParm1; if (audio->config.rate_change_cb) { audio->config.rate_change_cb(audio,audio->config.rate_change_data,pRap_data); } BRAP_SetPTSOffset_isr(audio->hRapDecodeCh, (int32_t)4000); audio->sample_rate_change_cnt++; } void baudio_decode_first_pts_cb (void *pParm1, int parm2, void *pRap_data) { baudio_decode_t audio = (baudio_decode_t)pParm1; BRAP_DSPCHN_PtsInfo *pPtsInfo = (BRAP_DSPCHN_PtsInfo *)pRap_data; unsigned int stc; BDBG_ASSERT(pPtsInfo); BDBG_ASSERT(audio); BDBG_ASSERT(audio->stream); BDBG_ASSERT(audio->stream->hPcrOffset); stc = BXPT_PcrOffset_GetStc_isr(audio->stream->hPcrOffset) + BXPT_PcrOffset_GetOffset_isr(audio->stream->hPcrOffset); BDBG_MSG(("baudio_decode_first_pts_cb pts = %x, stc = %x", pPtsInfo->ui32RunningPts,stc)); bstream_p_pcroffset_update(audio->stream); BRAP_SetStcValidFlag_isr(audio->hRapDecodeCh); audio->first_pts_cnt++; } void baudio_decode_tsm_failed_cb (void *pParm1, int parm2, void *pRap_data) { baudio_decode_t audio = (baudio_decode_t)pParm1; BRAP_DSPCHN_PtsInfo *pPtsInfo = (BRAP_DSPCHN_PtsInfo *)pRap_data; static BRAP_DSPCHN_TsmDebugInfo sTsmInfo; unsigned int stc; BDBG_ASSERT(pPtsInfo); BDBG_ASSERT(audio); BDBG_ASSERT(audio->stream); BDBG_ASSERT(audio->stream->hPcrOffset); stc = BXPT_PcrOffset_GetStc_isr(audio->stream->hPcrOffset) + BXPT_PcrOffset_GetOffset_isr(audio->stream->hPcrOffset); //BDBG_ERR(("baudio_decode_tsm_failed_cb pts = %x, stc = %x", pPtsInfo->ui32RunningPts,stc)); //BDBG_ERR(("baudio_decode_tsm_failed_cb delta = %d\n", stc - pPtsInfo->ui32RunningPts)); BRAP_GetTsmDebugInfo(audio->hRapDecodeCh,&sTsmInfo); BDBG_MSG(("bEnableASTMFlag = %d", sTsmInfo.bEnableASTMFlag)); BDBG_MSG(("bEnableTSMFlag = %d", sTsmInfo.bEnableTSMFlag)); BDBG_MSG(("bPlayback = %d", sTsmInfo.bPlayback)); BDBG_MSG(("bStcValidFlag = %d", sTsmInfo.bStcValidFlag)); BDBG_MSG(("i32DiscardThreshold = %d", sTsmInfo.i32DiscardThreshold)); BDBG_MSG(("i32PtsOffset = %d", sTsmInfo.i32PtsOffset)); BDBG_MSG(("i32TsmGAThreshold = %d", sTsmInfo.i32TsmGAThreshold)); BDBG_MSG(("i32TsmSLThreshold = %d", sTsmInfo.i32TsmSLThreshold)); BDBG_MSG((" ePtsType = %d", sTsmInfo.sPtsInfo.ePtsType)); BDBG_MSG((" i32Pts2StcPhase = %d", sTsmInfo.sPtsInfo.i32Pts2StcPhase)); BDBG_MSG((" i32TSMUpperThreshold = %d", sTsmInfo.sPtsInfo.i32TSMUpperThreshold)); BDBG_MSG((" ui32NumContinuousFail = %d", sTsmInfo.sPtsInfo.ui32NumContinuousFail)); BDBG_MSG((" ui32RunningPts = 0x%08x", sTsmInfo.sPtsInfo.ui32RunningPts)); bstream_p_pcroffset_update(audio->stream); BRAP_SetStcValidFlag_isr(audio->hRapDecodeCh); audio->tsm_failed_cnt++; } /* this function for watchdog recovery and be called from within Raptor's watchdogISR */ void baudio_decode_watchdog_cb(void *pParam1, int param2, void *pRap_data) { BSTD_UNUSED(pParam1); BSTD_UNUSED(param2); BSTD_UNUSED(pRap_data); BDBG_ERR(("%s: Raptor watchdog timer fired, perform recovery process", __func__)); BRAP_ProcessWatchdogInterrupt(GetRAP()); } #endif baudio_decode_t baudio_decode_open(bobject_t id) { #if (BCHP_CHIP!=7552) BAVC_CdbItbConfig cdb_itb_config; BRAP_ChannelSettings rapChSettings; #endif baudio_decode_t audio; if (s_audio.initialized) { return (baudio_decode_t)0; } /* BDBG_SetModuleLevel("rap_int", BDBG_eMsg) ; BDBG_SetModuleLevel("rap_cit", BDBG_eMsg) ; */ if (bos_create_mutex(&(s_audio.mutex)) != b_ok) { return (baudio_decode_t)0; } audio = &s_audio; #if (BCHP_CHIP!=7552) INIT_CHECK(BRAP_GetBufferConfig(GetRAP(), BRAP_BufferCfgMode_eAdvAudioMode, &cdb_itb_config)); INIT_CHECK(BXPT_Rave_AllocContext(GetRAVE(), BXPT_RaveCx_eAv, &cdb_itb_config, &(audio->hAudioDecodeRaveCx))); INIT_CHECK(BXPT_Rave_AllocContext(GetRAVE(), BXPT_RaveCx_eAv, &cdb_itb_config, &(audio->hAudioCompressedRaveCx))); INIT_CHECK(BRAP_GetDefaultChannelSettings(GetRAP(), &rapChSettings)); rapChSettings.eChType = BRAP_ChannelType_eDecode; rapChSettings.eChSubType = BRAP_ChannelSubType_eNone; rapChSettings.bEnaIndDly = true; rapChSettings.sChnRBufPool.uiMaxNumOutChPairs[0] = 3; /* Open the RAP Decode Channel */ INIT_CHECK(BRAP_OpenChannel(GetRAP(), &(audio->hRapDecodeCh), &rapChSettings)); boutput_add_decode_association(audio->hRapDecodeCh); INIT_CHECK(BRAP_InstallAppInterruptCb(audio->hRapDecodeCh,BRAP_Interrupt_eSampleRateChange,baudio_decode_rate_change_cb,audio,0)); INIT_CHECK(BRAP_InstallAppInterruptCb(audio->hRapDecodeCh,BRAP_Interrupt_eFirstPtsReady,baudio_decode_first_pts_cb,audio,0)); INIT_CHECK(BRAP_InstallAppInterruptCb(audio->hRapDecodeCh,BRAP_Interrupt_eTsmFail,baudio_decode_tsm_failed_cb,audio,0)); rapChSettings.sChnRBufPool.uiMaxNumOutChPairs[0] = 1; /* Open the RAP Decode Channel */ INIT_CHECK(BRAP_OpenChannel(GetRAP(), &(audio->hRapCompressedCh), &rapChSettings)); boutput_add_compress_association(audio->hRapCompressedCh); /* install Raptor watchdog timer */ INIT_CHECK(BRAP_InstallDeviceLevelAppInterruptCb(GetRAP(), BRAP_DeviceLevelInterrupt_eWatchdog, baudio_decode_watchdog_cb, audio, 0)); #endif s_audio.initialized = true; BKNI_Memset(&audio->config, 0, sizeof(audio->config)); /* sync the value between settop api and magnum PI */ audio->config.left_volume = audio->config.right_volume = 100; audio->config.downmix = baudio_downmix_stereo; audio->config.dolby.drc_mode = baudio_dolby_drc_mode_rf; audio->config.dolby.cut = 100; audio->config.dolby.boost = 100; audio->config.dolby.dialog_norm = true; audio->config.dolby.stereo_downmix_mode = baudio_dolby_stereo_downmix_mode_automatic; audio->config.dualmono = baudio_dualmono_stereo; return audio; failed: baudio_decode_close(audio); return (baudio_decode_t)0; } void baudio_decode_close(baudio_decode_t audio) { if (!s_audio.initialized) return; #if (BCHP_CHIP!=7552) BRAP_RemoveDeviceLevelAppInterruptCb(GetRAP(), BRAP_DeviceLevelInterrupt_eWatchdog); if (audio->hRapDecodeCh) { boutput_remove_decode_association(audio->hRapDecodeCh); BRAP_CloseChannel(audio->hRapDecodeCh); } if (audio->hRapCompressedCh) { boutput_remove_compress_association(audio->hRapCompressedCh); BRAP_CloseChannel(audio->hRapCompressedCh); } if (audio->hAudioDecodeRaveCx) { BXPT_Rave_FreeContext(audio->hAudioDecodeRaveCx); audio->hAudioDecodeRaveCx = NULL; } if (audio->hAudioCompressedRaveCx) { BXPT_Rave_FreeContext(audio->hAudioCompressedRaveCx); audio->hAudioDecodeRaveCx = NULL; } #endif if (s_audio.mutex.queue) { bos_delete_mutex(&(s_audio.mutex)); } } void baudio_decode_stop(baudio_decode_t audio) { #if (BCHP_CHIP!=7552) BERR_Code rc; BDBG_ASSERT(audio); BDBG_ASSERT(audio); b_lock(audio); if (!audio->audio_decode) { BDBG_ERR(("baudio_decode_stop - not decoding")); b_unlock(audio); return; } if (audio->compressed_decode) { rc = BXPT_Rave_DisableContext(audio->hAudioCompressedRaveCx); if (BERR_SUCCESS != rc) { BDBG_ERR(("BXPT_Rave_DisableContext failed %d (compressed)", rc)); } rc = BRAP_StopChannel(audio->hRapCompressedCh); if (BERR_SUCCESS != rc) { BDBG_ERR(("BRAP_StopChannel failed %d (compressed)", rc)); } rc = BXPT_Rave_RemovePidChannel(audio->hAudioCompressedRaveCx,B_AUDIO_PIDCH); if (BERR_SUCCESS != rc) { BDBG_ERR(("BXPT_Rave_RemovePidChannel failed %d (compressed)", rc)); } boutput_remove_compress_mai_output(); } rc = BXPT_Rave_DisableContext(audio->hAudioDecodeRaveCx); if (BERR_SUCCESS != rc) { BDBG_ERR(("BXPT_Rave_DisableContext failed %d", rc)); } rc = BRAP_StopChannel(audio->hRapDecodeCh); if (BERR_SUCCESS != rc) { BDBG_ERR(("BRAP_StopChannel failed %d", rc)); } if (audio->compressed_decode) { boutput_add_decode_mai_output(); } rc = BXPT_Rave_RemovePidChannel(audio->hAudioDecodeRaveCx,B_AUDIO_PIDCH); if (BERR_SUCCESS != rc) { BDBG_ERR(("BXPT_Rave_RemovePidChannel failed %d", rc)); } BXPT_DisablePidChannel(GetXPT(), B_AUDIO_PIDCH); BXPT_FreePidChannel(GetXPT(), B_AUDIO_PIDCH); audio->audio_decode = false; audio->compressed_decode = false; b_unlock(audio); #endif return; } static BERR_Code b_set_context(baudio_decode_t audio, BXPT_RaveCx_Handle context, bool compressed) { BERR_Code err; BXPT_Rave_AvSettings AvCtxCfg; BXPT_Rave_ContextSettings CtxConfig; BXPT_Rave_GetContextConfig(context, &CtxConfig); /* this is the default */ CtxConfig.EnablePrivateHdrItbEntry = false; CtxConfig.AudFrameInfo = 0; err = BXPT_Rave_SetContextConfig(context, &CtxConfig); if (err != BERR_SUCCESS) { BDBG_ERR(("BXPT_Rave_SetContextConfig failed %d", err)); goto failed; } BXPT_Rave_GetAvConfig(context, &AvCtxCfg); AvCtxCfg.InputFormat = BAVC_StreamType_eTsMpeg; AvCtxCfg.OutputFormat = BAVC_StreamType_eEs; BKNI_Memset(AvCtxCfg.EsRanges, 0, sizeof(AvCtxCfg.EsRanges)); /* all disabled */ #if (BCHP_CHIP!=7552) switch (audio->stream->mpeg.audio[0].format) { case BRAP_DSPCHN_AudioType_eMpeg: AvCtxCfg.ItbFormat = BAVC_ItbEsType_eMpegAudio; AvCtxCfg.StreamIdHi = 0xEF; AvCtxCfg.StreamIdLo = 0xC0; break; case BRAP_DSPCHN_AudioType_eAc3: case BRAP_DSPCHN_AudioType_eAc3Plus: AvCtxCfg.ItbFormat = BAVC_ItbEsType_eAc3Plus; /* Use AC3+ ITB type for AC3 */ AvCtxCfg.StreamIdHi = 0xEF; AvCtxCfg.StreamIdLo = 0xBD; break; default: BDBG_ERR(("Unsupported audio format.")); return BERR_TRACE(BERR_NOT_SUPPORTED); } #endif AvCtxCfg.BandHoldEn = false; AvCtxCfg.DisableContinuityCheck = false; err = BXPT_Rave_SetAvConfig(context, &AvCtxCfg); if (err != BERR_SUCCESS) { BDBG_ERR(("BXPT_Rave_SetContextConfig failed %d", err)); goto failed; } failed: return err; } bresult baudio_decode_start(baudio_decode_t audio, bdisplay_t display, bstream_t stream) { #if (BCHP_CHIP!=7552) BERR_Code err; BRAP_ChannelConfigParams chConfigParams; bool start_compressed = false; /* BDBG_SetModuleLevel("rap",BDBG_eMsg); BDBG_SetModuleLevel("rap_dec",BDBG_eMsg); BDBG_SetModuleLevel("rap_dspchn",BDBG_eMsg); BDBG_SetModuleLevel("rap_dsp",BDBG_eMsg); BDBG_SetModuleLevel("rap_hifidac",BDBG_eMsg); BDBG_SetModuleLevel("rap_fmm",BDBG_eMsg); BDBG_SetModuleLevel("rap_spdiffmm",BDBG_eMsg); BDBG_SetModuleLevel("rap_srcch",BDBG_eMsg); BDBG_SetModuleLevel("rap_mixer",BDBG_eMsg); BDBG_SetModuleLevel("BHDM",BDBG_eMsg); BDBG_SetModuleLevel("BHDM_HDCP",BDBG_eMsg); BDBG_SetModuleLevel("BHDM_EDID",BDBG_eMsg); BDBG_SetModuleLevel("BHDM_CEC",BDBG_eMsg); BDBG_SetModuleLevel("BHDM_CEC_PRIV",BDBG_eMsg); BDBG_SetModuleLevel("BHDM_DVO",BDBG_eMsg); */ BDBG_ASSERT(audio); BDBG_ASSERT(stream); b_lock(audio); if (audio->audio_decode) { BDBG_ERR(("baudio_decode_start - already decoding")); b_unlock(audio); baudio_decode_stop(audio); b_lock(audio); } audio->stream = stream; if (audio->stream->mpeg.audio[0].pid == 0) { return BERR_INVALID_PARAMETER; } err = b_set_context(audio,audio->hAudioDecodeRaveCx,false); if (BERR_SUCCESS != err) { BDBG_ERR(("b_set_context failed %d", err)); goto failed; } err = bstream_p_config_xpt_pid_ch(B_AUDIO_PIDCH, audio->stream->mpeg.audio[0].pid, audio->stream->band); if (BERR_SUCCESS != err) { BDBG_ERR(("bstream_p_config_xpt_pid_ch failed %d", err)); goto failed; } err = BXPT_Rave_AddPidChannel(audio->hAudioDecodeRaveCx, B_AUDIO_PIDCH, false); if (BERR_SUCCESS != err) { BDBG_ERR(("BXPT_Rave_AddPidChannel failed %d", err)); goto failed; } if ((audio->stream->mpeg.audio[0].format == BRAP_DSPCHN_AudioType_eAc3) || (audio->stream->mpeg.audio[0].format == BRAP_DSPCHN_AudioType_eAc3Plus)) { start_compressed = true; } err = BRAP_GetDefaultChannelParams(audio->hRapDecodeCh, &(audio->decodeAudioParams)); if (BERR_SUCCESS != err) { BDBG_ERR(("BRAP_GetDefaultChannelParams failed %d", err)); goto failed; } audio->decodeAudioParams.eAudioSource = BRAP_AudioSource_eXptInterface; audio->decodeAudioParams.eTimebase = BAVC_Timebase_e0; audio->decodeAudioParams.eInputSR = BAVC_AudioSamplingRate_e48k; audio->decodeAudioParams.bInputLfePresent = false; audio->decodeAudioParams.hAdFade = NULL; audio->decodeAudioParams.sDspChParams.eStreamType = BAVC_StreamType_eTsMpeg; audio->decodeAudioParams.sDspChParams.eType = audio->stream->mpeg.audio[0].format; audio->decodeAudioParams.sDspChParams.eDecodeMode = BRAP_DSPCHN_DecodeMode_eDecode; audio->decodeAudioParams.sDspChParams.bEnableStereoDownmixPath = false; audio->decodeAudioParams.bPlayback = false; //audio->decodeAudioParams.eInputAudMode = audio->dacDstDetails.uDstDetails.sOpDetails.eAudioMode; err = BXPT_Rave_GetContextRegisters(audio->hAudioDecodeRaveCx, &(audio->decodeAudioParams.sXptContextMap)); if (BERR_SUCCESS != err) { BDBG_ERR(("BXPT_Rave_GetContextRegisters failed %d", err)); goto failed; } BRAP_GetCurrentChannelConfig(audio->hRapDecodeCh, audio->decodeAudioParams.sDspChParams.eType, &chConfigParams); chConfigParams.eChType = BRAP_ChannelType_eDecode; chConfigParams.uChConfigParams.sDecConfigParams.eOutputMode = audio->config.mono_mix?BRAP_OutputMode_e1_0:BRAP_OutputMode_e2_0; audio->decodeAudioParams.eInputAudMode = chConfigParams.uChConfigParams.sDecConfigParams.eOutputMode; /* depends on the stream */ audio->decodeAudioParams.bInputLfePresent = chConfigParams.uChConfigParams.sDecConfigParams.bOutputLfeOn; err = BRAP_SetChannelConfig(audio->hRapDecodeCh, &chConfigParams); if (BERR_SUCCESS != err) { BDBG_ERR(("BXPT_Rave_GetContextRegisters failed %d", err)); goto failed; } err = BXPT_Rave_EnableContext( audio->hAudioDecodeRaveCx ); if (BERR_SUCCESS != err) { BDBG_ERR(("BXPT_Rave_GetContextRegisters failed %d", err)); goto failed; } #if 0 bstream_pcroffset_config_context(audio->stream); #endif bstream_p_pcroffset_pid_ch_config(audio->stream, B_AUDIO_PIDCH); err = BRAP_EnableTSM(audio->hRapDecodeCh, true); if (BERR_SUCCESS != err) { BDBG_ERR(("BXPT_Rave_GetContextRegisters failed %d", err)); goto failed; } #ifdef CONFIG_COMPRESS_HDMI if (start_compressed && audio->config.hdmi_compress) { boutput_remove_decode_mai_output(); } #endif err = BRAP_StartChannel (audio->hRapDecodeCh,&(audio->decodeAudioParams)); if (BERR_SUCCESS != err) { BDBG_ERR(("BXPT_Rave_GetContextRegisters failed %d", err)); goto failed; } err = BXPT_Rave_EnableContext( audio->hAudioDecodeRaveCx ); if (BERR_SUCCESS != err) { BDBG_ERR(("BXPT_Rave_GetContextRegisters failed %d", err)); goto failed; } #if 0 err = BRAP_SetPTSOffset(audio->hRapDecodeCh, 2000); if (BERR_SUCCESS != err) { BDBG_ERR(("BXPT_Rave_GetContextRegisters failed %d", err)); goto failed; } #endif audio->audio_decode = true; /* AC3/AC3 plug and user set the compressed output mode on HDMI */ if (start_compressed && audio->config.hdmi_compress) { #ifdef CONFIG_COMPRESS_HDMI boutput_add_compress_mai_output(); audio->compressed_decode = true; err = b_set_context(audio,audio->hAudioCompressedRaveCx,true); if (BERR_SUCCESS != err) { BDBG_ERR(("b_set_context failed %d", err)); goto failed; } err = BXPT_Rave_AddPidChannel(audio->hAudioCompressedRaveCx, B_AUDIO_PIDCH, false); if (BERR_SUCCESS != err) { BDBG_ERR(("BXPT_Rave_GetContextRegisters failed %d", err)); goto failed; } err = BRAP_GetDefaultChannelParams(audio->hRapCompressedCh, &(audio->compressedAudioParams)); audio->compressedAudioParams.eAudioSource = BRAP_AudioSource_eXptInterface; audio->compressedAudioParams.eTimebase = BAVC_Timebase_e0; audio->compressedAudioParams.eInputSR = BAVC_AudioSamplingRate_e48k; audio->compressedAudioParams.sDspChParams.eStreamType = BAVC_StreamType_eTsMpeg; audio->compressedAudioParams.sDspChParams.eType = audio->stream->mpeg.audio[0].format; audio->compressedAudioParams.sDspChParams.eDecodeMode = BRAP_DSPCHN_DecodeMode_ePassThru; audio->compressedAudioParams.bPlayback = false; //audio->compressedAudioParams.eInputAudMode = audio->dacDstDetails.uDstDetails.sOpDetails.eAudioMode; err = BXPT_Rave_GetContextRegisters(audio->hAudioCompressedRaveCx, &(audio->compressedAudioParams.sXptContextMap)); if (BERR_SUCCESS != err) { BDBG_ERR(("BXPT_Rave_GetContextRegisters failed %d", err)); goto failed; } BRAP_GetCurrentChannelConfig(audio->hRapCompressedCh, audio->compressedAudioParams.sDspChParams.eType, &chConfigParams); chConfigParams.eChType = BRAP_ChannelType_eDecode; chConfigParams.uChConfigParams.sDecConfigParams.eOutputMode = BRAP_OutputMode_e2_0; audio->decodeAudioParams.eInputAudMode = chConfigParams.uChConfigParams.sDecConfigParams.eOutputMode; /* depends on the stream */ audio->decodeAudioParams.bInputLfePresent = chConfigParams.uChConfigParams.sDecConfigParams.bOutputLfeOn; err = BRAP_SetChannelConfig(audio->hRapCompressedCh, &chConfigParams); if (BERR_SUCCESS != err) { BDBG_ERR(("BXPT_Rave_GetContextRegisters failed %d", err)); goto failed; } err = BXPT_Rave_EnableContext( audio->hAudioCompressedRaveCx ); if (BERR_SUCCESS != err) { BDBG_ERR(("BXPT_Rave_GetContextRegisters failed %d", err)); goto failed; } err = BRAP_StartChannel (audio->hRapCompressedCh,&(audio->compressedAudioParams)); if (BERR_SUCCESS != err) { BDBG_ERR(("BXPT_Rave_GetContextRegisters failed %d", err)); goto failed; } err = BRAP_EnableTSM(audio->hRapCompressedCh, false); if (BERR_SUCCESS != err) { BDBG_ERR(("BXPT_Rave_GetContextRegisters failed %d", err)); goto failed; } #endif } b_unlock(audio); return b_ok; failed: b_unlock(audio); baudio_decode_stop(audio); return err; #endif return b_ok; } void baudio_decode_get_config(baudio_decode_t audio, baudio_decode_config *config) { b_lock(audio); *config = audio->config; b_unlock(audio); } extern void boutput_set_postprocessing_volume(int volume); extern void boutput_set_postprocessing_deemphasized(bool enable); #if (BCHP_CHIP!=7552) static BERR_Code baudio_decode_p_set_dualmono(baudio_decode_t audio, baudio_dualmono dualmono) { BRAP_ChannelConfigParams chConfigParams; BERR_Code err = BERR_SUCCESS; BRAP_DSPCHN_DualMonoMode mode; BRAP_GetCurrentChannelConfig(audio->hRapDecodeCh, audio->decodeAudioParams.sDspChParams.eType, &chConfigParams); switch (dualmono) { case baudio_dualmono_left: mode = BRAP_DSPCHN_DualMonoMode_eLeftMono; break; case baudio_dualmono_right: mode = BRAP_DSPCHN_DualMonoMode_eRightMono; break; case baudio_dualmono_monomix: mode = BRAP_DSPCHN_DualMonoMode_eDualMonoMix; break; case baudio_dualmono_stereo: default: mode = BRAP_DSPCHN_DualMonoMode_eStereo; break; } if (chConfigParams.uChConfigParams.sDecConfigParams.eDualMonoMode != mode) { chConfigParams.uChConfigParams.sDecConfigParams.eDualMonoMode = mode; BDBG_WRN(("set dualmono : %d %d", chConfigParams.uChConfigParams.sDecConfigParams.eDualMonoMode, BRAP_DSPCHN_DualMonoMode_eStereo)); err = BRAP_SetChannelConfig(audio->hRapDecodeCh, &chConfigParams); if (BERR_SUCCESS != err) { BDBG_ERR(("BRAP_SetChannelConfig failed %d", __LINE__)); } } return err; } static BERR_Code baudio_decode_p_set_monomix(baudio_decode_t audio, bool bMono) { BRAP_ChannelConfigParams chConfigParams; BERR_Code err = BERR_SUCCESS; BRAP_GetCurrentChannelConfig(audio->hRapDecodeCh, audio->decodeAudioParams.sDspChParams.eType, &chConfigParams); if (bMono) { chConfigParams.uChConfigParams.sDecConfigParams.eOutputMode = BRAP_OutputMode_e1_0; } else { chConfigParams.uChConfigParams.sDecConfigParams.eOutputMode = BRAP_OutputMode_e2_0; } audio->decodeAudioParams.eInputAudMode = chConfigParams.uChConfigParams.sDecConfigParams.eOutputMode; audio->decodeAudioParams.bInputLfePresent = chConfigParams.uChConfigParams.sDecConfigParams.bOutputLfeOn; err = BRAP_SetChannelConfig(audio->hRapDecodeCh, &chConfigParams); return err; } static BERR_Code baudio_decode_p_set_dolby(baudio_decode_t audio, baudio_dolby_settings dolby, baudio_aac_downmix aac_downmix) { BRAP_ChannelConfigParams chConfigParams; BRAP_DSPCHN_Ac3ConfigParams *pAc3Config; // BRAP_DSPCHN_AacConfigParams *pAacConfig; BERR_Code err = BERR_SUCCESS; BRAP_GetCurrentChannelConfig(audio->hRapDecodeCh, audio->decodeAudioParams.sDspChParams.eType, &chConfigParams); switch (audio->decodeAudioParams.sDspChParams.eType) { case BRAP_DSPCHN_AudioType_eAc3: case BRAP_DSPCHN_AudioType_eAc3Plus: if (audio->decodeAudioParams.sDspChParams.eType == BRAP_DSPCHN_AudioType_eAc3) { pAc3Config = &chConfigParams.uChConfigParams.sDecConfigParams.uConfigParams.sAc3ConfigParams; } else { pAc3Config = &chConfigParams.uChConfigParams.sDecConfigParams.uConfigParams.sAc3PlusConfigParams; } if ( (pAc3Config->eStereoMode != dolby.stereo_downmix_mode) || (pAc3Config->eCompMode != dolby.drc_mode) || (pAc3Config->ui16DynRngScaleHi != dolby.cut) || (pAc3Config->ui16DynRngScaleLo != dolby.boost) || (pAc3Config->bStreamDialogNormEnable != dolby.dialog_norm)) { BDBG_WRN(("Dolby setting for AC3 (drc:%d, cut:%d, boost:%d, dialog:%d", dolby.drc_mode, dolby.cut, dolby.boost, dolby.dialog_norm)); pAc3Config->eStereoMode = dolby.stereo_downmix_mode; pAc3Config->eCompMode = dolby.drc_mode; pAc3Config->ui16DynRngScaleHi = dolby.cut; pAc3Config->ui16DynRngScaleLo = dolby.boost; pAc3Config->bStreamDialogNormEnable = dolby.dialog_norm; err = BRAP_SetChannelConfig(audio->hRapDecodeCh, &chConfigParams); } break; #if 0 case BRAP_DSPCHN_AudioType_eAacAdts: case BRAP_DSPCHN_AudioType_eAacLoas: pAacConfig = &chConfigParams.uChConfigParams.sDecConfigParams.uConfigParams.sAacConfigParams; if (pAacConfig->eDownmixType != aac_downmix) { BDBG_WRN(("Dolby setting for AAC(downmix: %d)", aac_downmix)); pAacConfig->eDownmixType = aac_downmix; err = BRAP_SetChannelConfig(audio->hRapDecodeCh, &chConfigParams); } break; #endif default: break; } if (BERR_SUCCESS != err) { BDBG_ERR(("BRAP_SetChannelConfig in %s failed %d", __FUNCTION__, err)); } return err; } #endif /****************************************************************************** The array to represent the value of volume in hex corresponding to the value in DB. The application inputs the volume in terms of DB and the Corresponding HEX value is mentioned here. The formula used for the same is: HEX = (2^23) * 10^(DB/20) Note: 23 is the number of bits in the volume control field. The volume can range from 0-1. 0 in hex corresponds to the 139 DB from the above Formula. If application enters more than this value, it is forced to 0. ******************************************************************************/ static const unsigned int Vol_DB[] = { 0x800000, /* volume 1.000000 <- 0.000000 db */ 0x7a3d32, /* volume 0.954993 <- -0.400000 db */ 0x74bcc5, /* volume 0.912011 <- -0.800000 db */ 0x6f7bbc, /* volume 0.870964 <- -1.200000 db */ 0x6a773c, /* volume 0.831764 <- -1.600000 db */ 0x65ac8c, /* volume 0.776247 <- -2.000000 db */ 0x5ffc88, /* volume 0.683912 <- -2.500000 db */ 0x5a9df7, /* volume 0.616595 <- -3.000000 db */ 0x558c4b, /* volume 0.543250 <- -3.500000 db */ 0x50c335, /* volume 0.478630 <- -4.000000 db */ 0x4b5f3a, /* volume 0.421697 <- -4.600000 db */ 0x46575a, /* volume 0.367282 <- -5.200000 db */ 0x41a571, /* volume 0.575440 <- -5.800000 db */ 0x3c9038, /* volume 0.530884 <- -6.500000 db */ 0x37dfc0, /* volume 0.489779 <- -7.200000 db */ 0x338c3b, /* volume 0.451856 <- -7.900000 db */ 0x2f8e77, /* volume 0.416869 <- -8.600000 db */ 0x2ae025, /* volume 0.375837 <- -9.500000 db */ 0x26a7c7, /* volume 0.338844 <- -10.400000 db */ 0x22d9bf, /* volume 0.305492 <- -11.300000 db */ 0x1f0f84, /* volume 0.272270 <- -12.300000 db */ 0x1baecb, /* volume 0.242661 <- -13.300000 db */ 0x181c57, /* volume 0.211349 <- -14.500000 db */ 0x140dee, /* volume 0.177828 <- -16.000000 db */ 0x10ae37, /* volume 0.154882 <- -17.700000 db */ 0x0d8ef6, /* volume 0.125893 <- -19.500000 db */ 0x0aa586, /* volume 0.104713 <- -21.600000 db */ 0x081385, /* volume 0.079433 <- -24.000000 db */ 0x05b7b1, /* volume 0.063096 <- -27.000000 db */ 0x039b87, /* volume 0.050119 <- -31.000000 db */ 0x01cedc, /* volume 0.035481 <- -37.000000 db */ 0x00a43a, /* volume 0.011220 <- -46.000000 db */ 0x00126d, /* volume 0.000708 <- -65.000000 db */ }; #define max_volume ((sizeof(Vol_DB)/sizeof(Vol_DB[0])) - 1) bresult baudio_decode_set_config(baudio_decode_t audio, const baudio_decode_config *config) { #if (BCHP_CHIP!=7552) BERR_Code rc; // use BTSC audio fix and our own DB based volume table. Currently HDMI and BTSC share same volume table, may need to change later unsigned int uiBtscRVolume; uiBtscRVolume = Vol_DB[max_volume - config->right_volume]; b_lock(audio); if ((audio->config.left_volume != config->left_volume) || (audio->config.right_volume != config->right_volume)) { unsigned int uiLVolume; unsigned int uiRVolume; uiLVolume = Vol_DB[max_volume - config->left_volume]; uiRVolume = Vol_DB[max_volume - config->right_volume]; #if 0 rc = BRAP_SetOutputVolume(GetRAP(),BRAP_OutputPort_eSpdif,config->left_volume,config->right_volume); if (rc != BERR_SUCCESS) { BDBG_ERR(("BRAP_SetOutputVolume SPDIF failed %d", rc)); goto failed; } rc = BRAP_SetOutputVolume(GetRAP(),BRAP_OutputPort_eDac0,config->left_volume,config->right_volume); if (rc != BERR_SUCCESS) { BDBG_ERR(("BRAP_SetOutputVolume DAC0 failed %d", rc)); goto failed; } #else boutput_set_postprocessing_volume(uiBtscRVolume); #endif BDBG_ERR(("BRAP_SetOutputVolume volume (r:%d, l:%d",config->right_volume, config->left_volume)); BDBG_ERR(("BRAP_SetOutputVolume uiRVolume %d, uiLVolume %d",uiRVolume, uiLVolume)); //rc = BRAP_SetOutputVolume(GetRAP(),BRAP_OutputPort_eMai,uiLVolume,uiRVolume); rc = boutput_set_association_vol(BRAP_OutputPort_eMai, uiLVolume, uiRVolume); if (rc != BERR_SUCCESS) { BDBG_ERR(("BRAP_SetOutputVolume Mai failed %d", rc)); goto failed; } } if (audio->config.mute != config->mute) { #if 0 rc = BRAP_SetOutputMute(GetRAP(),BRAP_OutputPort_eSpdif,config->mute); if (rc != BERR_SUCCESS) { BDBG_ERR(("BRAP_SetOutputMute SPDIF failed %d", rc)); goto failed; } rc = BRAP_SetOutputMute(GetRAP(),BRAP_OutputPort_eDac0,config->mute); if (rc != BERR_SUCCESS) { BDBG_ERR(("BRAP_SetOutputMute DAC0 failed %d", rc)); goto failed; } #else if (config->mute) { boutput_set_postprocessing_volume(0); } else { boutput_set_postprocessing_volume(uiBtscRVolume); } #endif BDBG_ERR(("BRAP_SetOutputMute mute %d", config->mute)); //rc = BRAP_SetOutputMute(GetRAP(),BRAP_OutputPort_eMai,config->mute); rc = boutput_set_association_mute(BRAP_OutputPort_eMai, config->mute); if (rc != BERR_SUCCESS) { BDBG_ERR(("BRAP_SetOutputMute Mai failed %d", rc)); goto failed; } } if (audio->config.hd_mute != config->hd_mute) { boutput_set_association_mute(BRAP_OutputPort_eMai, config->hd_mute); } if (audio->config.deemphasized != config->deemphasized) { boutput_set_postprocessing_deemphasized(config->deemphasized); } if (audio->config.mono_mix != config->mono_mix) { baudio_decode_p_set_monomix(audio, config->mono_mix); } rc = baudio_decode_p_set_dualmono(audio, config->dualmono); if (rc != BERR_SUCCESS) goto failed; /* dolby setting */ rc = baudio_decode_p_set_dolby(audio, config->dolby, config->aac_downmix); if (rc != BERR_SUCCESS) goto failed; audio->config = *config; b_unlock(audio); return b_ok; failed: b_unlock(audio); return rc; #else return b_ok; #endif } bresult baudio_decode_get_status(baudio_decode_t audio, baudio_decode_status *status) { #if (BCHP_CHIP!=7552) BRAP_DSPCHN_StreamInfo sStreamInfo; BRAP_DSPCHN_PtsInfo sPtsInfo; BXPT_Rave_BufferInfo bufferInfo; BDBG_ASSERT(audio); BDBG_ASSERT(status); BKNI_Memset(status, 0, sizeof(*status)); b_lock(audio); if (!audio->audio_decode) { b_unlock(audio); return b_ok; } BDBG_ASSERT(audio->hRapDecodeCh); BDBG_ASSERT(audio->stream); BDBG_ASSERT(audio->stream->hPcrOffset); BRAP_GetStreamInformation(audio->hRapDecodeCh,&sStreamInfo); if (BXPT_Rave_GetBufferInfo( audio->hAudioDecodeRaveCx,&bufferInfo) == BERR_SUCCESS) { status->fifo_depth = bufferInfo.CdbDepth; status->fifo_size = bufferInfo.CdbSize; } if (BRAP_GetCurrentPTS(audio->hRapDecodeCh, &sPtsInfo) == BERR_SUCCESS) { status->pts = sPtsInfo.ui32RunningPts; } status->stc = BXPT_PcrOffset_GetStc_isr(audio->stream->hPcrOffset) + BXPT_PcrOffset_GetOffset_isr(audio->stream->hPcrOffset); status->pid = audio->stream->mpeg.audio[0].pid; b_unlock(audio); #endif return b_ok; }