blob: d310759caea2303165bf3b38a5b755832862cb45 [file] [log] [blame]
/*****************************************************************************
* Copyright Statement:
* --------------------
* This software is protected by Copyright and the information contained
* herein is confidential. The software may not be copied and the information
* contained herein may not be used or disclosed except with the written
* permission of MediaTek Inc. (C) 2005
*
* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
*
* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
*
* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
*
*****************************************************************************/
/*******************************************************************************
*
* Filename:
* ---------
* vm.c
*
* Project:
* --------
* MAUI
*
* Description:
* ------------
* VM recording/playback
*
* Author:
* -------
* -------
*
*==============================================================================
* HISTORY
* Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
*------------------------------------------------------------------------------
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
*------------------------------------------------------------------------------
* Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
*==============================================================================
*******************************************************************************/
#include "kal_public_api.h"
#include "kal_general_types.h"
#include "string.h"
#include "reg_base.h"
#include "kal_trace.h"
#include "speech_def.h"
#include "l1aud_common_def.h"
#include "l1audio.h"
#include "l1audio_trace_utmd.h"
#include "l1audio_voc_utmd.h"
#include "sp_drv.h"
#include "pcm4way.h"
#include "am.h"
#include "media.h"
#include "afe.h"
#include "l1sp_trc.h"
#include "l1audio_sph_trc.h"
#include "sal_exp.h"
#include "sal_def.h"
#include "vm.h"
#include "gmss_public.h"
/* ------------------------------------------------------------------------------ */
#define VM_4G_G_SERIAL_DEBUG
#if defined( __UMTS_RAT__ )
#define _EXTRA_LOG_FOR_BIT_TRUE_
#endif
#if defined(_EXTRA_LOG_FOR_BIT_TRUE_)
extern kal_bool g_bNeedExtraLog;
#endif
/* ------------------------------------------------------------------------------ */
#define VM_STATE_RECORD 0x1
#define VM_STATE_STOP 0x10
#define VM_STATE_RECORD_STOP 0x20 // entering vmStop
#define VM_VM_MAGIC_HEADER 0xBB88
#define VM_VM_CTRL_UL_ON 0x0001
#define VM_VM_CTRL_DL_ON 0x0001
#define VM_EPL_1STSET_RECORD_FLAG 0x0001
#define VM_EPL_2NDSET_RECORD_FLAG 0x0002
#define VM_VM_RECORD_FLAG 0x0004
#define VM_EPL_REFMIC_RECORD_FLAG 0x0008
#define VM_EPL_ECHOREF_RECORD_FLAG 0x0010
#define VM_EPL_3RDMIC_RECORD_FLAG 0x0020
#define VM_EPL_2NDECHOREF_RECORD_FLAG 0x0040
#define VM_EPL_ALL_RECORD_FLAG (VM_EPL_1STSET_RECORD_FLAG + VM_EPL_2NDSET_RECORD_FLAG + VM_EPL_REFMIC_RECORD_FLAG + VM_EPL_ECHOREF_RECORD_FLAG + VM_EPL_3RDMIC_RECORD_FLAG + VM_EPL_2NDECHOREF_RECORD_FLAG)
#define VM_EPL_BAND_UL0_SHIFT 0
#define VM_EPL_BAND_UL1_SHIFT 2
#define VM_EPL_BAND_DL0_SHIFT 4
#define VM_EPL_BAND_DL1_SHIFT 6
#define VM_EPL_BAND_UL2_SHIFT 8
#define VM_EPL_BAND_UL4_SHIFT 10
#define VM_EPL_BAND_UL3_SHIFT 12
#define VM_EPL_BAND_UL5_SHIFT 14
#define VM_VM_HEADER_SIZE 6
#define VM_VM_CONTROL_SIZE 10
#define VM_VM_MAX_HB_WORD_SIZE ((160+2)*3) // EVS_128000: 2560 bits = 160 words, UL + DL + DL2
#define VM_VM_SCH_DBGINFO_SIZE 100
#define VM_VM_ENH_DBGINFO_SIZE 160
#define VM_VM_DRV_DBGINFO_SIZE 20
#define VM_VM_SVC_DBGINFO_SIZE 20
#define VM_VM_DBGINFO_TOTAL_SIZE (VM_VM_SCH_DBGINFO_SIZE + VM_VM_ENH_DBGINFO_SIZE + VM_VM_DRV_DBGINFO_SIZE + VM_VM_SVC_DBGINFO_SIZE)
#define VM_VM_BUFFER_SIZE (VM_VM_HEADER_SIZE + VM_VM_CONTROL_SIZE + VM_VM_MAX_HB_WORD_SIZE + VM_VM_DBGINFO_TOTAL_SIZE)
#define VM_EPL_1STSET_SIZE (SAL_FB_PCM_SIZE + SAL_FB_PCM_SIZE + 2)
#define VM_EPL_2NDSET_SIZE (SAL_FB_PCM_SIZE + SAL_FB_PCM_SIZE + 2)
#define VM_EPL_REFMIC_SIZE (SAL_FB_PCM_SIZE + 2 + 2)
#define VM_EPL_ECHOREF_SIZE (SAL_FB_PCM_SIZE + 2)
#define VM_EPL_3RDMIC_SIZE (SAL_FB_PCM_SIZE + 2)
#define VM_EPL_2NDECHOREF_SIZE (SAL_FB_PCM_SIZE + 2)
#define VM_EPL_PCM_BUFFER_SIZE VM_EPL_1STSET_SIZE
#define VM_EPL_TOTAL_SIZE (VM_EPL_1STSET_SIZE + VM_EPL_2NDSET_SIZE + VM_EPL_REFMIC_SIZE + VM_EPL_ECHOREF_SIZE + VM_EPL_3RDMIC_SIZE + VM_EPL_2NDECHOREF_SIZE)
#if defined(__G_CODEC_SUPPORT__) && defined(__VOLTE_SUPPORT__)
#define G_CODEC_UL_INFO_HEADER_MAGIC_NUMBER (0x6666)
#define G_CODEC_DL_INFO_HEADER_MAGIC_NUMBER (0x6667)
//G.722 bitstream 20ms 160byte
//G.711 bitstream 10ms 80byte
//store max 4frame
#define G_CODEC_MAX_FRAME_NUMBER (4)
//stream_size+stream
#define G_CODEC_BITSTREAM_BUFFER_BYTE_SIZE (1*2+80)
//lost_info + system_time + codec + codec_parameters
#define G_CODEC_UL_INFO_BYTE_SIZE (4*2)
//lost_info + system_time + codec + codec_parameters + DL_PCM_buffer_size
#define G_CODEC_DL_INFO_BYTE_SIZE (5*2)
//header_magic_number+info_size+info_struct
#define G_CODEC_UL_INFO_TOTAL_BYTE_SIZE (2*2+G_CODEC_UL_INFO_BYTE_SIZE)
//header_magic_number+info_size+info_struct
#define G_CODEC_DL_INFO_TOTAL_BYTE_SIZE (2*2+G_CODEC_DL_INFO_BYTE_SIZE)
//total byte size
#define G_CODEC_UL_BITSTREAM_TOTAL_BYTE_SIZE ((G_CODEC_UL_INFO_TOTAL_BYTE_SIZE+G_CODEC_BITSTREAM_BUFFER_BYTE_SIZE)*G_CODEC_MAX_FRAME_NUMBER)
#define G_CODEC_DL_BITSTREAM_TOTAL_BYTE_SIZE ((G_CODEC_DL_INFO_TOTAL_BYTE_SIZE+G_CODEC_BITSTREAM_BUFFER_BYTE_SIZE)*G_CODEC_MAX_FRAME_NUMBER)
#endif //#if defined(__G_CODEC_SUPPORT__) && defined(__VOLTE_SUPPORT__)
#if defined(__G_CODEC_SUPPORT__) && defined(__VOLTE_SUPPORT__)
#define G_CODEC_MAX_HB_WORD_SIZE (((G_CODEC_UL_BITSTREAM_TOTAL_BYTE_SIZE+1)>>1) + ((G_CODEC_DL_BITSTREAM_TOTAL_BYTE_SIZE+1)>>1))
//#define VMREC_OUTPUT_BUF_SIZE (2 * (VM_VM_BUFFER_SIZE + VM_EPL_TOTAL_SIZE + G_CODEC_MAX_HB_WORD_SIZE))
#define VMREC_OUTPUT_BUF_SIZE 8000 // [REMIND] Please notify AP speech owner when vm buffer change
#else
//#define VMREC_OUTPUT_BUF_SIZE (2 * (VM_VM_BUFFER_SIZE + VM_EPL_TOTAL_SIZE))
#define VMREC_OUTPUT_BUF_SIZE 8000 // [REMIND] Please notify AP speech owner when vm buffer change
#endif
#define VM_3G_NETWORK_INFO_LEN 7
/* ------------------------------------------------------------------------------ */
static struct
{
kal_spinlockid lockId;
void (*vm_hdlr)(void); // callback function for vm logging
bool isVocOn; // only use under call AM_IsSpeechOn()
bool isVmLOn; // only use under call AM_IsSpeechOn()
bool isMosaic;
uint16 audId;
uint16 state; // record DSP runnning status (including 2 hisr)
uint16 record_info; // record flag, only use to control EPL record though it also has VM record flag
uint16 control_1;
uint16 control_2;
uint16 control_3;
uint16 control_4;
uint16 control_5;
uint16 control_6;
uint16 control_7;
uint16 control_8;
uint16 control_9;
uint16 control_10;
uint16 evs_cur_sd_mode;
uint16 sc_len;
uint16 sd_len; // sd1_len + sd2_len
uint16 vm_lost_count; // For record EPL dummy
uint16 pcm_lost_count; // For record EPL dummy
uint16 vm_counter; // For record EPL dummy
uint16 *vmBuf; // point to buffer for VM
uint16 *pcmBuf; // point to temp buffer to get EPL from DSP in N times
// related to 'vmRecOutputBuf', which is cycular buffer use to buffer formatted vm data from dsp
uint16 pOutputBufWrite;
uint16 pOutputBufRead;
uint16 outputBufSize;
} vm;
uint16 vm3GNetworkInfo[VM_3G_NETWORK_INFO_LEN];
static kal_uint16 vmBuffer[VM_VM_BUFFER_SIZE];
static kal_uint16 vmEPLPCMInputBuf[VM_EPL_PCM_BUFFER_SIZE];
static kal_uint16 vmRecOutputBuf[VMREC_OUTPUT_BUF_SIZE];
#if defined(__G_CODEC_SUPPORT__) && defined(__VOLTE_SUPPORT__)
static kal_uint32 vmGCodecULBitstreamBuf[(G_CODEC_UL_BITSTREAM_TOTAL_BYTE_SIZE + 3) / sizeof(kal_uint32)];
static kal_uint32 vmGCodecDLBitstreamBuf[(G_CODEC_DL_BITSTREAM_TOTAL_BYTE_SIZE + 3) / sizeof(kal_uint32)];
static kal_uint32 vmGCodecULBufWritePos;
static kal_uint32 vmGCodecDLBufWritePos;
static kal_uint32 vmGCodecULBufLastHeaderPos;
static kal_uint32 vmGCodecDLBufLastHeaderPos;
static kal_uint16 *p16vmGCodecULBitstreamBuf;
static kal_uint16 *p16vmGCodecDLBitstreamBuf;
#endif
/* ------------------------------------------------------------------------------ */
#if defined(__G_CODEC_SUPPORT__) && defined(__VOLTE_SUPPORT__)
void vmInitGCodecULBuf(void)
{
//memset(vmGCodecULBitstreamBuf, 0, sizeof(vmGCodecULBitstreamBuf));
p16vmGCodecULBitstreamBuf = (kal_uint16 *)vmGCodecULBitstreamBuf;
vmGCodecULBufWritePos = 0;
vmGCodecULBufLastHeaderPos = 0;
}
void vmInitGCodecDLBuf(void)
{
//memset(vmGCodecDLBitstreamBuf, 0, sizeof(vmGCodecDLBitstreamBuf));
p16vmGCodecDLBitstreamBuf = (kal_uint16 *)vmGCodecDLBitstreamBuf;
vmGCodecDLBufWritePos = 0;
vmGCodecDLBufLastHeaderPos = 0;
}
#endif //#if defined(__G_CODEC_SUPPORT__) && defined(__VOLTE_SUPPORT__)
void vmStoreGCodecULStream(vmGCodecULInfo *pstvmGCodecULInfo, kal_uint16 u16StreamSize, kal_uint8 *pu8StreamData)
{
#if defined(__G_CODEC_SUPPORT__) && defined(__VOLTE_SUPPORT__)
kal_uint32 u32TotalBufferSize = sizeof(vmGCodecULBitstreamBuf) >> 1;
//bytesize: G_CODEC_UL_INFO_TOTAL_BYTE_SIZE + stream_size + stream_data[]
//>>1 => 2byte size
kal_uint32 u32NeedSize = (G_CODEC_UL_INFO_TOTAL_BYTE_SIZE + 2 + u16StreamSize + 1) >> 1;
kal_uint32 i, j;
kal_uint16 u16tempData;
#ifdef VM_4G_G_SERIAL_DEBUG
MD_TRC_VM_GFORM_ULSTREAM_ENTER();
#endif //#ifdef VM_4G_G_SERIAL_DEBUG
// dsp status check
if (vm.state != VM_STATE_RECORD)
{
return;
}
// application status check
if ( (false == vm.isVocOn) && (false == vm.isVmLOn)) // (false == vm.isIdleVmOn) &&
{
return;
}
#ifdef VM_4G_G_SERIAL_DEBUG
MD_TRC_VM_GFORM_ULSTREAM_INFO1(u32TotalBufferSize, vmGCodecULBufWritePos, ((u16StreamSize + 1) >> 1), u16StreamSize);
#endif //#ifdef VM_4G_G_SERIAL_DEBUG
if ( (u32TotalBufferSize - vmGCodecULBufWritePos) >= u32NeedSize )
{
vmGCodecULBufLastHeaderPos = vmGCodecULBufWritePos;
p16vmGCodecULBitstreamBuf[vmGCodecULBufWritePos] = G_CODEC_UL_INFO_HEADER_MAGIC_NUMBER;
vmGCodecULBufWritePos++;
p16vmGCodecULBitstreamBuf[vmGCodecULBufWritePos] = G_CODEC_UL_INFO_BYTE_SIZE >> 1;
vmGCodecULBufWritePos++;
p16vmGCodecULBitstreamBuf[vmGCodecULBufWritePos] = pstvmGCodecULInfo->drop_info;
vmGCodecULBufWritePos++;
p16vmGCodecULBitstreamBuf[vmGCodecULBufWritePos] = (kal_uint16)(ust_get_current_time() / 1000); //ust_get_current_time(): unit is micro second (us) => ust_get_current_time()/1000: unit is ms
vmGCodecULBufWritePos++;
p16vmGCodecULBitstreamBuf[vmGCodecULBufWritePos] = pstvmGCodecULInfo->codec;
vmGCodecULBufWritePos++;
p16vmGCodecULBitstreamBuf[vmGCodecULBufWritePos] = pstvmGCodecULInfo->codec_parameters;
vmGCodecULBufWritePos++;
p16vmGCodecULBitstreamBuf[vmGCodecULBufWritePos] = u16StreamSize;
vmGCodecULBufWritePos++;
j = 0;
for (i = 0; i < (u16StreamSize >> 1); i++)
{
u16tempData = pu8StreamData[j];
j++;
u16tempData = (u16tempData << 8) | pu8StreamData[j];
j++;
p16vmGCodecULBitstreamBuf[vmGCodecULBufWritePos] = u16tempData;
vmGCodecULBufWritePos++;
}
if (u16StreamSize & 0x01)
{
u16tempData = pu8StreamData[j];
u16tempData = (u16tempData << 8) | u16tempData;
p16vmGCodecULBitstreamBuf[vmGCodecULBufWritePos] = u16tempData;
vmGCodecULBufWritePos++;
}
}
else
{
MD_TRC_VM_GFORM_ULSTREAM_INFO2(u32NeedSize, u32TotalBufferSize - vmGCodecULBufWritePos);
if (vmGCodecULBufWritePos != 0)
{
p16vmGCodecULBitstreamBuf[vmGCodecULBufLastHeaderPos + 2] += 0x0100;
}
else
{
MD_TRC_VM_GFORM_ULSTREAM_INFO3(u32NeedSize, u32TotalBufferSize);
}
}
#ifdef VM_4G_G_SERIAL_DEBUG
MD_TRC_VM_GFORM_ULSTREAM_EXIT();
#endif //#ifdef VM_4G_G_SERIAL_DEBUG
#endif //#if defined(__G_CODEC_SUPPORT__) && defined(__VOLTE_SUPPORT__)
}
void vmStoreGCodecDLStream(vmGCodecDLInfo *pstvmGCodecDLInfo, kal_uint16 u16StreamSize, kal_uint8 *pu8StreamData)
{
#if defined(__G_CODEC_SUPPORT__) && defined(__VOLTE_SUPPORT__)
kal_uint32 u32TotalBufferSize = sizeof(vmGCodecDLBitstreamBuf) >> 1;
//bytesize: G_CODEC_DL_INFO_TOTAL_BYTE_SIZE + stream_size + stream_data[]
//>>1 => 2byte size
kal_uint32 u32NeedSize = (G_CODEC_DL_INFO_TOTAL_BYTE_SIZE + 2 + u16StreamSize + 1) >> 1;
kal_uint32 i, j;
kal_uint16 u16tempData;
#ifdef VM_4G_G_SERIAL_DEBUG
MD_TRC_VM_GFORM_DLSTREAM_ENTER();
#endif //#ifdef VM_4G_G_SERIAL_DEBUG
// dsp status check
if (vm.state != VM_STATE_RECORD)
{
return;
}
// application status check
if ( (false == vm.isVocOn) && (false == vm.isVmLOn)) // (false == vm.isIdleVmOn) &&
{
return;
}
#ifdef VM_4G_G_SERIAL_DEBUG
MD_TRC_VM_GFORM_DLSTREAM_INFO1(u32TotalBufferSize, vmGCodecDLBufWritePos, ((u16StreamSize + 1) >> 1), u16StreamSize);
#endif //#ifdef VM_4G_G_SERIAL_DEBUG
if ( (u32TotalBufferSize - vmGCodecDLBufWritePos) >= u32NeedSize )
{
vmGCodecDLBufLastHeaderPos = vmGCodecDLBufWritePos;
p16vmGCodecDLBitstreamBuf[vmGCodecDLBufWritePos] = G_CODEC_DL_INFO_HEADER_MAGIC_NUMBER;
vmGCodecDLBufWritePos++;
p16vmGCodecDLBitstreamBuf[vmGCodecDLBufWritePos] = G_CODEC_DL_INFO_BYTE_SIZE >> 1;
vmGCodecDLBufWritePos++;
p16vmGCodecDLBitstreamBuf[vmGCodecDLBufWritePos] = pstvmGCodecDLInfo->drop_info;
vmGCodecDLBufWritePos++;
p16vmGCodecDLBitstreamBuf[vmGCodecDLBufWritePos] = (kal_uint16)(ust_get_current_time() / 1000); //ust_get_current_time(): unit is micro second (us) => ust_get_current_time()/1000: unit is ms
vmGCodecDLBufWritePos++;
p16vmGCodecDLBitstreamBuf[vmGCodecDLBufWritePos] = pstvmGCodecDLInfo->codec;
vmGCodecDLBufWritePos++;
p16vmGCodecDLBitstreamBuf[vmGCodecDLBufWritePos] = pstvmGCodecDLInfo->codec_parameters;
vmGCodecDLBufWritePos++;
p16vmGCodecDLBitstreamBuf[vmGCodecDLBufWritePos] = pstvmGCodecDLInfo->DL_PCM_size;
vmGCodecDLBufWritePos++;
p16vmGCodecDLBitstreamBuf[vmGCodecDLBufWritePos] = u16StreamSize;
vmGCodecDLBufWritePos++;
j = 0;
for (i = 0; i < (u16StreamSize >> 1); i++)
{
u16tempData = pu8StreamData[j];
j++;
u16tempData = (u16tempData << 8) | pu8StreamData[j];
j++;
p16vmGCodecDLBitstreamBuf[vmGCodecDLBufWritePos] = u16tempData;
vmGCodecDLBufWritePos++;
}
if (u16StreamSize & 0x01)
{
u16tempData = pu8StreamData[j];
u16tempData = (u16tempData << 8) | u16tempData;
p16vmGCodecDLBitstreamBuf[vmGCodecDLBufWritePos] = u16tempData;
vmGCodecDLBufWritePos++;
}
}
else
{
MD_TRC_VM_GFORM_DLSTREAM_INFO2(u32NeedSize, u32TotalBufferSize - vmGCodecDLBufWritePos);
if (vmGCodecDLBufWritePos != 0)
{
p16vmGCodecDLBitstreamBuf[vmGCodecDLBufLastHeaderPos + 2] += 0x0100;
}
else
{
MD_TRC_VM_GFORM_DLSTREAM_INFO3(u32NeedSize, u32TotalBufferSize);
}
}
#ifdef VM_4G_G_SERIAL_DEBUG
MD_TRC_VM_GFORM_DLSTREAM_EXIT();
#endif //#ifdef VM_4G_G_SERIAL_DEBUG
#endif //#if defined(__G_CODEC_SUPPORT__) && defined(__VOLTE_SUPPORT__)
}
void vmSet3GNetworkInfo( uint32 *l1_info, uint16 crc_result, uint16 buf_status, uint8 dl_count )
{
kal_int16 tpc_SIR_lta, dpdch_SIR_lta, TFCI_max_corr, I;
uint32 l1Info, s_value;
if ( l1_info == NULL ) {
l1Info = 0;
tpc_SIR_lta = 0;
dpdch_SIR_lta = 0;
TFCI_max_corr = 0;
s_value = 0;
} else {
l1Info = l1_info[1];
tpc_SIR_lta = l1_info[4];
dpdch_SIR_lta = l1_info[5];
TFCI_max_corr = l1_info[6];
s_value = l1_info[3];
}
I = (uint16)(l1Info & 0xFFFF);
vm3GNetworkInfo[4] = I;
I = (uint16)(l1Info >> 16);
vm3GNetworkInfo[5] = I;
vm3GNetworkInfo[3] = crc_result;
vm3GNetworkInfo[6] = (uint16)((s_value >= 32767) ? 32767 : s_value); //s_value
vm3GNetworkInfo[0] = (uint16)tpc_SIR_lta;
vm3GNetworkInfo[1] = (uint16)dpdch_SIR_lta;
vm3GNetworkInfo[2] = (uint16)TFCI_max_corr;
}
static uint16 vmEPLBandSet(uint16 u2EPLBufLen, uint16 u2EPLBufShift)
{
uint16 u2vmEPLBand = 0;
if (u2EPLBufLen == SAL_NB_PCM_SIZE)
{
u2vmEPLBand = SAL_NB;
}
else if (u2EPLBufLen == SAL_WB_PCM_SIZE)
{
u2vmEPLBand = SAL_WB;
}
else if (u2EPLBufLen == SAL_SWB_PCM_SIZE)
{
u2vmEPLBand = SAL_SWB;
}
else if (u2EPLBufLen == SAL_FB_PCM_SIZE)
{
u2vmEPLBand = SAL_FB;
}
return u2vmEPLBand << u2EPLBufShift;
}
bool VM_CodIsAMR(uint16 codec_mode)
{
if ((codec_mode <= SAL_COD_AMR475 && codec_mode >= SAL_COD_AMR122) ||
(codec_mode >= SAL_COD_AWB660 && codec_mode <= SAL_COD_AWB2385))
{
return true;
}
return false;
}
bool VM_CodIsEVS(uint16 codec_mode)
{
if ((codec_mode >= SAL_COD_EVSMIN && codec_mode <= SAL_COD_EVSMAX))
{
return true;
}
return false;
}
/* ------------------------------------------------------------------------------ */
#if defined(__G_CODEC_SUPPORT__) && defined(__VOLTE_SUPPORT__)
void vmFormatter_gseries(uint16 *vmBuf, Sal_VM_Frame *vmfrm)
{
volatile uint16 *addr;
uint16 I, sc_mode, sd_mode, sc_len, sd_len;
uint32 J;
sc_mode = SAL_COD_AMR122;
sd_mode = SAL_COD_AMR122;
sc_len = AM_GetSpeechPatternLength(sc_mode);
//ASSERT_REBOOT( sc_len > 0 );
sd_len = AM_GetSpeechPatternLength(sd_mode);
//ASSERT_REBOOT( sd_len > 0 );
//[0:0]: UL on
//[6:1]: UL mode
//[10:7]: TX type
//[11:11]: (no use) SP flag
//[13:12]: Call mode
I = 0; // Tx: NO_DATA
vm.control_1 = (I << 7) | (sc_mode << 1) | (vm.control_1 & 1);
// if Call mode = 2G, vm.control_1 = vm.control_1 | 0x0000;
if (L1SP_GetState() == L1SP_STATE_4G_SPEECH_ON)
vm.control_1 = vm.control_1 | 0x3000; // Call mode = 4G
else if (SAL_3G_Mode())
vm.control_1 = vm.control_1 | 0x1000; // Call mode = 3G
//[0:0]: DL on
//[6:1]: DL mode
//[10:7]: RX type
//[15:11]: (no use) [12:11] SID flag, [13] TAF, [14] UFI, [15] BFI
I = 0; // Rx: NO_DATA
vm.control_2 = (I << 7) | (sd_mode << 1) | (vm.control_2 & 1);
kal_prompt_trace(MOD_L1SP, "vmBuf head %x", vmBuf);
*vmBuf++ = VM_VM_MAGIC_HEADER;
J = L1SP_GetState();
I = (uint16)( ( VM_VM_DBGINFO_TOTAL_SIZE << 3 ) | J);
*vmBuf++ = I;
*vmBuf++ = VM_VM_RECORD_FLAG;
*vmBuf++ = 0; //reset EPL band
J = fma_get_glb_ts() & 0xFFFFFFFF;
#if defined(_EXTRA_LOG_FOR_BIT_TRUE_)
if ( g_bNeedExtraLog )
MD_TRC_VM_SP3G_VM_L1T(J);
#endif
I = (uint16)(J & 0xFFFF);
*vmBuf++ = I;
I = (uint16)(J >> 16);
*vmBuf++ = I;
vm.vm_counter++;
//Chip ID
vm.control_3 = VM_CHIP_ID;
//[1:0]: DL frm cnt
//[7:2]: DL2 mode
//[11:8]: DL2 RX type
//[13:12]: Codec band
//[15:14]: Expert mode (By VLP)
vm.control_4 = (vmfrm->dec_frm_num & 0x3) | ((sd_mode & 0x3F) << 2) | ((vmfrm->dec_hdr_1 & 0xE) << 8) | ((SAL_VM_Get_CodBand() & 0x3) << 12);
//[15:0]: TS control
vm.control_5 = SAL_VM_Get_TS_Info(SAL_VM_TS_INFO_CTRL);
//[7:0]: TS target scale
//[12:8]: TS max scale
vm.control_6 = (SAL_VM_Get_TS_Info(SAL_VM_TS_INFO_TARGET_SCALE) & 0xFF) | ((SAL_VM_Get_TS_Info(SAL_VM_TS_INFO_MAX_SCALE) & 0x1F) << 8);
//[10:0]: TS output size 1
vm.control_7 = SAL_VM_Get_TS_Info(SAL_VM_TS_INFO_OUTPUT_SIZE_1);
//[10:0]: TS output size 2
vm.control_8 = SAL_VM_Get_TS_Info(SAL_VM_TS_INFO_OUTPUT_SIZE_2);
// record vm control value
*vmBuf++ = vm.control_1;
*vmBuf++ = vm.control_2;
*vmBuf++ = vm.control_3;
*vmBuf++ = vm.control_4;
*vmBuf++ = vm.control_5;
*vmBuf++ = vm.control_6;
*vmBuf++ = vm.control_7;
*vmBuf++ = vm.control_8;
*vmBuf++ = vm.control_9;
*vmBuf++ = vm.control_10;
// record UL data
vm.sc_len = 0;
if ( vm.control_1 & 1 )
{
addr = vmfrm->enc_hb_addr;
for ( I = 0; I < sc_len; I++ )
{
*vmBuf++ = *addr++;
if (L1SP_GetState() == L1SP_STATE_2G_SPEECH_ON)
addr++;
}
vm.sc_len += sc_len;
}
// record DL data
vm.sd_len = 0;
if ( vm.control_2 & 1 )
{
addr = vmfrm->dec_hb_addr;
for ( I = 0; I < sd_len; I++ )
{
*vmBuf++ = *addr++;
if (L1SP_GetState() == L1SP_STATE_2G_SPEECH_ON)
addr++;
}
vm.sd_len += sd_len;
if (vmfrm->dec_frm_num == 2)
{
addr = vmfrm->dec_hb_addr_1;
for ( I = 0; I < sd_len; I++ )
{
*vmBuf++ = *addr++;
if (L1SP_GetState() == L1SP_STATE_2G_SPEECH_ON)
addr++;
}
vm.sd_len += sd_len;
}
}
kal_prompt_trace(MOD_L1SP, "Formatter_GSeries SC Len= %d, SD Len= %d, Dec_Cnt= %d", vm.sc_len, vm.sd_len, vmfrm->dec_frm_num);
// Debug info
addr = vmfrm->dbgInfo_addr;
for ( I = 0; I < VM_VM_SCH_DBGINFO_SIZE; I++ )
*vmBuf++ = *addr++;
addr = vmfrm->enh_dbgInfo_addr;
for ( I = 0; I < VM_VM_ENH_DBGINFO_SIZE; I++ )
*vmBuf++ = *addr++;
for (I = 0; I < VM_VM_DRV_DBGINFO_SIZE; I++)
{
if (I < VM_3G_NETWORK_INFO_LEN)
*vmBuf++ = vm3GNetworkInfo[I];
else
*vmBuf++ = 0;
}
addr = vmfrm->svc_dbgInfo_addr;
for ( I = 0; I < VM_VM_SVC_DBGINFO_SIZE; I++ )
*vmBuf++ = *addr++;
kal_prompt_trace(MOD_L1SP, "vmBuf tail %x", vmBuf);
}
#endif //#if defined(__G_CODEC_SUPPORT__) && defined(__VOLTE_SUPPORT__)
#if defined(__EVS_CODEC_SUPPORT__) && defined(__VOLTE_SUPPORT__)
EVS_VM_ID VM_EVS_Get_Codec_ID(SP4G_Codec EVSCod)
{
EVS_VM_ID VM_Codec_ID = 0;
switch (EVSCod)
{
case SP4G_CODEC_EVS_08K_005_9:
case SP4G_CODEC_EVS_16K_005_9:
case SP4G_CODEC_EVS_32K_005_9:
case SP4G_CODEC_EVS_48K_005_9:
VM_Codec_ID = EVS_PRI590;
break;
case SP4G_CODEC_EVS_AWB_06_60:
VM_Codec_ID = EVS_AWB660;
break;
case SP4G_CODEC_EVS_08K_007_2:
case SP4G_CODEC_EVS_16K_007_2:
case SP4G_CODEC_EVS_32K_007_2:
case SP4G_CODEC_EVS_48K_007_2:
VM_Codec_ID = EVS_PRI720;
break;
case SP4G_CODEC_EVS_08K_008_0:
case SP4G_CODEC_EVS_16K_008_0:
case SP4G_CODEC_EVS_32K_008_0:
case SP4G_CODEC_EVS_48K_008_0:
VM_Codec_ID = EVS_PRI800;
break;
case SP4G_CODEC_EVS_AWB_08_85:
VM_Codec_ID = EVS_AWB885;
break;
case SP4G_CODEC_EVS_08K_009_6:
case SP4G_CODEC_EVS_16K_009_6:
case SP4G_CODEC_EVS_32K_009_6:
case SP4G_CODEC_EVS_48K_009_6:
VM_Codec_ID = EVS_PRI960;
break;
case SP4G_CODEC_EVS_AWB_12_65:
VM_Codec_ID = EVS_AWB1265;
break;
case SP4G_CODEC_EVS_08K_013_2:
case SP4G_CODEC_EVS_16K_013_2:
case SP4G_CODEC_EVS_32K_013_2:
case SP4G_CODEC_EVS_48K_013_2:
VM_Codec_ID = EVS_PRI1320;
break;
case SP4G_CODEC_EVS_AWB_14_25:
VM_Codec_ID = EVS_AWB1425;
break;
case SP4G_CODEC_EVS_AWB_15_85:
VM_Codec_ID = EVS_AWB1585;
break;
case SP4G_CODEC_EVS_08K_016_4:
case SP4G_CODEC_EVS_16K_016_4:
case SP4G_CODEC_EVS_32K_016_4:
case SP4G_CODEC_EVS_48K_016_4:
VM_Codec_ID = EVS_PRI1640;
break;
case SP4G_CODEC_EVS_AWB_18_25:
VM_Codec_ID = EVS_AWB1825;
break;
case SP4G_CODEC_EVS_AWB_19_85:
VM_Codec_ID = EVS_AWB1985;
break;
case SP4G_CODEC_EVS_AWB_23_05:
VM_Codec_ID = EVS_AWB2305;
break;
case SP4G_CODEC_EVS_AWB_23_85:
VM_Codec_ID = EVS_AWB2385;
break;
case SP4G_CODEC_EVS_08K_024_4:
case SP4G_CODEC_EVS_16K_024_4:
case SP4G_CODEC_EVS_32K_024_4:
case SP4G_CODEC_EVS_48K_024_4:
VM_Codec_ID = EVS_PRI2440;
break;
case SP4G_CODEC_EVS_08K_032_0:
case SP4G_CODEC_EVS_16K_032_0:
case SP4G_CODEC_EVS_32K_032_0:
case SP4G_CODEC_EVS_48K_032_0:
VM_Codec_ID = EVS_PRI3200;
break;
case SP4G_CODEC_EVS_08K_048_0:
case SP4G_CODEC_EVS_16K_048_0:
case SP4G_CODEC_EVS_32K_048_0:
case SP4G_CODEC_EVS_48K_048_0:
VM_Codec_ID = EVS_PRI4800;
break;
case SP4G_CODEC_EVS_08K_064_0:
case SP4G_CODEC_EVS_16K_064_0:
case SP4G_CODEC_EVS_32K_064_0:
case SP4G_CODEC_EVS_48K_064_0:
VM_Codec_ID = EVS_PRI6400;
break;
case SP4G_CODEC_EVS_08K_096_0:
case SP4G_CODEC_EVS_16K_096_0:
case SP4G_CODEC_EVS_32K_096_0:
case SP4G_CODEC_EVS_48K_096_0:
VM_Codec_ID = EVS_PRI9600;
break;
case SP4G_CODEC_EVS_08K_128_0:
case SP4G_CODEC_EVS_16K_128_0:
case SP4G_CODEC_EVS_32K_128_0:
case SP4G_CODEC_EVS_48K_128_0:
VM_Codec_ID = EVS_PRI12800;
break;
case SP4G_CODEC_EVS_08K_002_4_SID:
case SP4G_CODEC_EVS_08K_000_0_REV:
case SP4G_CODEC_EVS_08K_000_0_LOST:
case SP4G_CODEC_EVS_08K_000_0_NODATA:
case SP4G_CODEC_EVS_16K_002_4_SID:
case SP4G_CODEC_EVS_16K_000_0_REV:
case SP4G_CODEC_EVS_16K_000_0_LOST:
case SP4G_CODEC_EVS_16K_000_0_NODATA:
case SP4G_CODEC_EVS_32K_002_4_SID:
case SP4G_CODEC_EVS_32K_000_0_REV:
case SP4G_CODEC_EVS_32K_000_0_LOST:
case SP4G_CODEC_EVS_32K_000_0_NODATA:
case SP4G_CODEC_EVS_48K_002_4_SID:
case SP4G_CODEC_EVS_48K_000_0_REV:
case SP4G_CODEC_EVS_48K_000_0_LOST:
case SP4G_CODEC_EVS_48K_000_0_NODATA:
case SP4G_CODEC_EVS_AWB_02_00_SID:
case SP4G_CODEC_EVS_AWB_00_00_REV0:
case SP4G_CODEC_EVS_AWB_00_00_REV1:
case SP4G_CODEC_EVS_AWB_00_00_REV2:
case SP4G_CODEC_EVS_AWB_00_00_REV3:
case SP4G_CODEC_EVS_AWB_00_00_LOST:
case SP4G_CODEC_EVS_AWB_00_00_NODATA:
VM_Codec_ID = EVS_SID_LOST_NODATA;
break;
default:
VM_Codec_ID = EVS_UNDEF;
break;
}
return VM_Codec_ID;
}
void vmFormatter_evs(uint16 *vmBuf, Sal_VM_Frame *vmfrm)
{
volatile uint16 *addr;
uint16 I, sc_mode, sd_mode, sc_len, sd_len;
uint32 J;
uint16 sc_mode_invalid = 0, sd_mode_invalid = 0;
sc_mode = VM_EVS_Get_Codec_ID(SAL_EVS_Get_Codec_Mode(SAL_EVS_TX_CODEC_MODE));
if (sc_mode == EVS_UNDEF)
{
sc_mode_invalid = 1;
sc_mode = EVS_PRI1640;
}
sd_mode = VM_EVS_Get_Codec_ID(SAL_EVS_Get_Codec_Mode(SAL_EVS_RX_CODEC_MODE));
if (sd_mode == EVS_SID_LOST_NODATA) // DL only, For EVS Codec ID: REV and LOST
{
if (vm.evs_cur_sd_mode == EVS_UNDEF)
sd_mode = VM_EVS_Get_Codec_ID(SAL_Get_DL_CodecMode()); //Codec mode of call open
else
sd_mode = vm.evs_cur_sd_mode;
}
if (sd_mode == EVS_UNDEF)
{
sd_mode_invalid = 1;
sd_mode = EVS_PRI1640;
}
vm.evs_cur_sd_mode = sd_mode;
sc_len = AM_GetSpeechPatternLength(sc_mode);
//ASSERT_REBOOT( sc_len > 0 );
sd_len = AM_GetSpeechPatternLength(sd_mode);
//ASSERT_REBOOT( sd_len > 0 );
//[0:0]: UL on
//[6:1]: UL mode
//[10:7]: (no use) TX type
//[11:11]: (no use) SP flag
//[13:12]: Call mode
vm.control_1 = (sc_mode << 1) | (vm.control_1 & 1);
vm.control_1 = vm.control_1 | 0x3000; // Call mode = 4G
//[0:0]: DL on
//[6:1]: DL mode
//[10:7]: (no use) RX type
//[15:11]: (no use) [12:11] SID flag, [13] TAF, [14] UFI, [15] BFI
vm.control_2 = (sd_mode << 1) | (vm.control_2 & 1);
kal_prompt_trace(MOD_L1SP, "vmBuf head %x", vmBuf);
*vmBuf++ = VM_VM_MAGIC_HEADER;
J = L1SP_GetState();
I = (uint16)( ( VM_VM_DBGINFO_TOTAL_SIZE << 3 ) | J);
*vmBuf++ = I;
*vmBuf++ = VM_VM_RECORD_FLAG;
*vmBuf++ = 0; //reset EPL band
J = fma_get_glb_ts() & 0xFFFFFFFF;
#if defined(_EXTRA_LOG_FOR_BIT_TRUE_)
if ( g_bNeedExtraLog )
MD_TRC_VM_SP3G_VM_L1T(J);
#endif
I = (uint16)(J & 0xFFFF);
*vmBuf++ = I;
I = (uint16)(J >> 16);
*vmBuf++ = I;
vm.vm_counter++;
//Chip ID
vm.control_3 = VM_CHIP_ID;
//[1:0]: DL frm cnt
//[7:2]: DL2 mode
//[11:8]: DL2 RX type
//[13:12]: Codec band
//[15:14]: Expert mode (By VLP)
vm.control_4 = (vmfrm->dec_frm_num & 0x3) | ((sd_mode & 0x3F) << 2) | ((vmfrm->dec_hdr_1 & 0xE) << 8) | ((SAL_VM_Get_CodBand() & 0x3) << 12);
//[15:0]: TS control
vm.control_5 = SAL_VM_Get_TS_Info(SAL_VM_TS_INFO_CTRL);
//[7:0]: TS target scale
//[12:8]: TS max scale
vm.control_6 = (SAL_VM_Get_TS_Info(SAL_VM_TS_INFO_TARGET_SCALE) & 0xFF) | ((SAL_VM_Get_TS_Info(SAL_VM_TS_INFO_MAX_SCALE) & 0x1F) << 8);
//[10:0]: TS output size 1
vm.control_7 = SAL_VM_Get_TS_Info(SAL_VM_TS_INFO_OUTPUT_SIZE_1);
//[10:0]: TS output size 2
vm.control_8 = SAL_VM_Get_TS_Info(SAL_VM_TS_INFO_OUTPUT_SIZE_2);
// record vm control value
*vmBuf++ = vm.control_1;
*vmBuf++ = vm.control_2;
*vmBuf++ = vm.control_3;
*vmBuf++ = vm.control_4;
*vmBuf++ = vm.control_5;
*vmBuf++ = vm.control_6;
*vmBuf++ = vm.control_7;
*vmBuf++ = vm.control_8;
*vmBuf++ = vm.control_9;
*vmBuf++ = vm.control_10;
// record UL data
vm.sc_len = 0;
if ( vm.control_1 & 1 )
{
if (sc_mode_invalid)
{
*vmBuf++ = SAL_EVS_SPEECH_GOOD_FRAME;
*vmBuf++ = 328; //EVS 16.4 HB Len
}
else
{
*vmBuf++ = SAL_EVS_Get_Enc_BFI();
*vmBuf++ = SAL_EVS_Get_Enc_HBLen();
}
addr = vmfrm->enc_hb_addr;
for ( I = 0; I < (sc_len - 2); I++ )
{
if (sc_mode_invalid)
*vmBuf++ = 0;
else
*vmBuf++ = *addr++;
}
vm.sc_len += sc_len;
}
// record DL data
vm.sd_len = 0;
if ( vm.control_2 & 1 )
{
if (sd_mode_invalid)
{
*vmBuf++ = SAL_EVS_SPEECH_GOOD_FRAME;
*vmBuf++ = 328; //EVS 16.4 HB Len
}
else
{
*vmBuf++ = SAL_EVS_Get_Dec_BFI(SAL_4G_RX_FIRST_FRM);
*vmBuf++ = SAL_EVS_Get_Dec_HBLen(SAL_4G_RX_FIRST_FRM);
}
addr = vmfrm->dec_hb_addr;
for ( I = 0; I < (sd_len - 2); I++ )
{
if (sd_mode_invalid)
*vmBuf++ = 0;
else
*vmBuf++ = *addr++;
}
vm.sd_len += sd_len;
if (vmfrm->dec_frm_num == 2)
{
if (sd_mode_invalid)
{
*vmBuf++ = SAL_EVS_SPEECH_GOOD_FRAME;
*vmBuf++ = 328; //EVS 16.4 HB Len
}
else
{
*vmBuf++ = SAL_EVS_Get_Dec_BFI(SAL_4G_RX_SECOND_FRM);
*vmBuf++ = SAL_EVS_Get_Dec_HBLen(SAL_4G_RX_SECOND_FRM);
}
addr = vmfrm->dec_hb_addr_1;
for ( I = 0; I < (sd_len - 2); I++ )
{
if (sd_mode_invalid)
*vmBuf++ = 0;
else
*vmBuf++ = *addr++;
}
vm.sd_len += sd_len;
}
}
kal_prompt_trace(MOD_L1SP, "Formatter_EVS SC Len= %d, SD Len= %d, Dec_Cnt= %d", vm.sc_len, vm.sd_len, vmfrm->dec_frm_num);
// Debug info
// SCH Dbg Info 0
addr = vmfrm->dbgInfo_addr;
*vmBuf = (*addr) & 0xEA;
*vmBuf = *vmBuf | (SAL_EVS_SPEECH_BAD_FRAME == SAL_EVS_Get_Enc_BFI()) | ((SAL_EVS_SPEECH_BAD_FRAME == SAL_EVS_Get_Dec_BFI(SAL_4G_RX_FIRST_FRM)) << 2);
vmBuf++;
// SCH Dbg Info 1
*vmBuf = (SAL_EVS_Get_PCMBW()) | ((SAL_EVS_Get_PCMBW()) << 2) | ((SAL_EVS_Get_Enc_MaxRate()) << 4);
*vmBuf = *vmBuf | ((SAL_EVS_Get_Enc_CA_Enable()) << 6) | ((SAL_EVS_Get_Enc_CA_RF_FEC_Indicator()) << 7) | ((SAL_EVS_Get_Enc_CA_RF_FEC_Offset()) << 8);
*vmBuf = *vmBuf | ((SAL_EVS_Get_Dec_CA_FrmMode(SAL_4G_RX_FIRST_FRM)) << 11) | ((SAL_EVS_Get_Dec_CA_FrmMode(SAL_4G_RX_SECOND_FRM)) << 13);
vmBuf++;
// SCH Dbg Info 2
*vmBuf++ = SAL_EVS_Get_Enc_HBLen();
// SCH Dbg Info 3
*vmBuf++ = SAL_EVS_Get_Dec_HBLen(SAL_4G_RX_FIRST_FRM);
// SCH Dbg Info 4
*vmBuf++ = SAL_EVS_Get_Dec_HBLen(SAL_4G_RX_SECOND_FRM);
// SCH Dbg Info reserved
addr = vmfrm->dbgInfo_addr + 5;
for ( I = 0; I < (VM_VM_SCH_DBGINFO_SIZE - 5); I++ )
*vmBuf++ = *addr++;
addr = vmfrm->enh_dbgInfo_addr;
for ( I = 0; I < VM_VM_ENH_DBGINFO_SIZE; I++ )
*vmBuf++ = *addr++;
for (I = 0; I < VM_VM_DRV_DBGINFO_SIZE; I++)
{
if (I < VM_3G_NETWORK_INFO_LEN)
*vmBuf++ = vm3GNetworkInfo[I];
else
*vmBuf++ = 0;
}
addr = vmfrm->svc_dbgInfo_addr;
for ( I = 0; I < VM_VM_SVC_DBGINFO_SIZE; I++ )
*vmBuf++ = *addr++;
kal_prompt_trace(MOD_L1SP, "vmBuf tail %x", vmBuf);
}
#endif
void vmFormatter_amr(uint16 *vmBuf, Sal_VM_Frame *vmfrm)
{
volatile uint16 *addr;
uint16 I, sc_mode, sd_mode, sc_len, sd_len;
uint32 J;
uint16 sc_mode_invalid = 0;
sc_mode = vmfrm->enc_mode;
sd_mode = vmfrm->dec_mode;
if ((VM_CodIsAMR(sc_mode)) == false)
{
sc_mode = sd_mode;
sc_mode_invalid = 1;
}
sc_len = AM_GetSpeechPatternLength(sc_mode);
//ASSERT_REBOOT( sc_len > 0 );
sd_len = AM_GetSpeechPatternLength(sd_mode);
//ASSERT_REBOOT( sd_len > 0 );
//[0:0]: UL on
//[6:1]: UL mode
//[10:7]: TX type
//[11:11]: (no use) SP flag
//[13:12]: Call mode
if (sc_mode_invalid)
{
I = 0; // Tx: NO_DATA
}
else
{
I = vmfrm->enc_hdr & 0x3; // Tx: bit0, bit1
}
vm.control_1 = (I << 7) | (sc_mode << 1) | (vm.control_1 & 1);
// if Call mode = 2G, vm.control_1 = vm.control_1 | 0x0000;
if (L1SP_GetState() == L1SP_STATE_4G_SPEECH_ON)
vm.control_1 = vm.control_1 | 0x3000; // Call mode = 4G
else if (SAL_3G_Mode())
vm.control_1 = vm.control_1 | 0x1000; // Call mode = 3G
//[0:0]: DL on
//[6:1]: DL mode
//[10:7]: RX type
//[15:11]: (no use) [12:11] SID flag, [13] TAF, [14] UFI, [15] BFI
I = (vmfrm->dec_hdr & 0xE) >> 1; // Rx: bit1, bit2, bit3
vm.control_2 = (I << 7) | (sd_mode << 1) | (vm.control_2 & 1);
kal_prompt_trace(MOD_L1SP, "vmBuf head %x", vmBuf);
*vmBuf++ = VM_VM_MAGIC_HEADER;
J = L1SP_GetState();
I = (uint16)( ( VM_VM_DBGINFO_TOTAL_SIZE << 3 ) | J);
*vmBuf++ = I;
*vmBuf++ = VM_VM_RECORD_FLAG;
*vmBuf++ = 0; //reset EPL band
J = fma_get_glb_ts() & 0xFFFFFFFF;
#if defined(_EXTRA_LOG_FOR_BIT_TRUE_)
if ( g_bNeedExtraLog )
MD_TRC_VM_SP3G_VM_L1T(J);
#endif
I = (uint16)(J & 0xFFFF);
*vmBuf++ = I;
I = (uint16)(J >> 16);
*vmBuf++ = I;
vm.vm_counter++;
//Chip ID
vm.control_3 = VM_CHIP_ID;
//[1:0]: DL frm cnt
//[7:2]: DL2 mode
//[11:8]: DL2 RX type
//[13:12]: Codec band
//[15:14]: Expert mode (By VLP)
vm.control_4 = (vmfrm->dec_frm_num & 0x3) | ((sd_mode & 0x3F) << 2) | ((vmfrm->dec_hdr_1 & 0xE) << 8) | ((SAL_VM_Get_CodBand() & 0x3) << 12);
//[15:0]: TS control
vm.control_5 = SAL_VM_Get_TS_Info(SAL_VM_TS_INFO_CTRL);
//[7:0]: TS target scale
//[12:8]: TS max scale
vm.control_6 = (SAL_VM_Get_TS_Info(SAL_VM_TS_INFO_TARGET_SCALE) & 0xFF) | ((SAL_VM_Get_TS_Info(SAL_VM_TS_INFO_MAX_SCALE) & 0x1F) << 8);
//[10:0]: TS output size 1
vm.control_7 = SAL_VM_Get_TS_Info(SAL_VM_TS_INFO_OUTPUT_SIZE_1);
//[10:0]: TS output size 2
vm.control_8 = SAL_VM_Get_TS_Info(SAL_VM_TS_INFO_OUTPUT_SIZE_2);
// record vm control value
*vmBuf++ = vm.control_1;
*vmBuf++ = vm.control_2;
*vmBuf++ = vm.control_3;
*vmBuf++ = vm.control_4;
*vmBuf++ = vm.control_5;
*vmBuf++ = vm.control_6;
*vmBuf++ = vm.control_7;
*vmBuf++ = vm.control_8;
*vmBuf++ = vm.control_9;
*vmBuf++ = vm.control_10;
// record UL data
vm.sc_len = 0;
if ( vm.control_1 & 1 )
{
addr = vmfrm->enc_hb_addr;
for ( I = 0; I < sc_len; I++ )
{
*vmBuf++ = *addr++;
if (L1SP_GetState() == L1SP_STATE_2G_SPEECH_ON)
addr++;
}
vm.sc_len += sc_len;
}
// record DL data
vm.sd_len = 0;
if ( vm.control_2 & 1 )
{
addr = vmfrm->dec_hb_addr;
for ( I = 0; I < sd_len; I++ )
{
*vmBuf++ = *addr++;
if (L1SP_GetState() == L1SP_STATE_2G_SPEECH_ON)
addr++;
}
vm.sd_len += sd_len;
if (vmfrm->dec_frm_num == 2)
{
addr = vmfrm->dec_hb_addr_1;
for ( I = 0; I < sd_len; I++ )
{
*vmBuf++ = *addr++;
if (L1SP_GetState() == L1SP_STATE_2G_SPEECH_ON)
addr++;
}
vm.sd_len += sd_len;
}
}
kal_prompt_trace(MOD_L1SP, "Formatter_AMR SC Len= %d, SD Len= %d, Dec_Cnt= %d", vm.sc_len, vm.sd_len, vmfrm->dec_frm_num);
// Debug info
addr = vmfrm->dbgInfo_addr;
for ( I = 0; I < VM_VM_SCH_DBGINFO_SIZE; I++ )
*vmBuf++ = *addr++;
addr = vmfrm->enh_dbgInfo_addr;
for ( I = 0; I < VM_VM_ENH_DBGINFO_SIZE; I++ )
*vmBuf++ = *addr++;
for (I = 0; I < VM_VM_DRV_DBGINFO_SIZE; I++)
{
if (I < VM_3G_NETWORK_INFO_LEN)
*vmBuf++ = vm3GNetworkInfo[I];
else
*vmBuf++ = 0;
}
addr = vmfrm->svc_dbgInfo_addr;
for ( I = 0; I < VM_VM_SVC_DBGINFO_SIZE; I++ )
*vmBuf++ = *addr++;
kal_prompt_trace(MOD_L1SP, "vmBuf tail %x", vmBuf);
}
void vmFormatter_4g(uint16 *vmBuf, Sal_VM_Frame *vmfrm)
{
#if defined(__G_CODEC_SUPPORT__) && defined(__VOLTE_SUPPORT__)
if ( SP4G_IsGCodecMode() )
{
vmFormatter_gseries(vmBuf, vmfrm);
return;
}
#endif
#if defined(__EVS_CODEC_SUPPORT__) && defined(__VOLTE_SUPPORT__)
if (VM_CodIsEVS(vmfrm->dec_mode) == true)
{
vmFormatter_evs(vmBuf, vmfrm);
return;
}
#endif
vmFormatter_amr(vmBuf, vmfrm);
}
void vmFormatter_c2k(uint16 *vmBuf, Sal_VM_Frame *vmfrm)
{
volatile uint16 *addr;
uint16 I, sc_mode, sd_mode, sc_len, sd_len;
uint32 J;
uint16 sc_mode_invalid = 0;
sc_mode = vmfrm->enc_mode;
sd_mode = vmfrm->dec_mode;
if (sc_mode != sd_mode)
{
sc_mode = sd_mode;
sc_mode_invalid = 1;
}
sc_len = AM_GetSpeechPatternLength(sc_mode);
//ASSERT_REBOOT( sc_len > 0 );
sd_len = AM_GetSpeechPatternLength(sd_mode);
//ASSERT_REBOOT( sd_len > 0 );
//[0:0]: UL on
//[6:1]: UL mode
//[10:7]: TX type
//[11:11]: (no use) SP flag
//[13:12]: Call mode
if (sc_mode_invalid)
{
I = 0; // Tx: NO_DATA
}
else
{
I = vmfrm->enc_hdr; // Tx
}
vm.control_1 = (I << 7) | (sc_mode << 1) | (vm.control_1 & 1);
vm.control_1 = vm.control_1 | 0x2000; // Call mode = C2K
//[0:0]: DL on
//[6:1]: DL mode
//[10:7]: RX type
//[15:11]: (no use) [12:11] SID flag, [13] TAF, [14] UFI, [15] BFI
I = vmfrm->dec_hdr; // Rx
vm.control_2 = (I << 7) | (sd_mode << 1) | (vm.control_2 & 1);
kal_prompt_trace(MOD_L1SP, "vmBuf head %x", vmBuf);
*vmBuf++ = VM_VM_MAGIC_HEADER;
J = L1SP_GetState();
I = (uint16)( ( VM_VM_DBGINFO_TOTAL_SIZE << 3 ) | J);
*vmBuf++ = I;
*vmBuf++ = VM_VM_RECORD_FLAG;
*vmBuf++ = 0; //reset EPL band
J = fma_get_glb_ts() & 0xFFFFFFFF;
#if defined(_EXTRA_LOG_FOR_BIT_TRUE_)
// TODO: c2k [trace]
#endif
I = (uint16)(J & 0xFFFF);
*vmBuf++ = I;
I = (uint16)(J >> 16);
*vmBuf++ = I;
vm.vm_counter++;
//Chip ID
vm.control_3 = VM_CHIP_ID;
//[1:0]: DL frm cnt
//[7:2]: DL2 mode
//[11:8]: DL2 RX type
//[13:12]: Codec band
//[15:14]: Expert mode (By VLP)
vm.control_4 = (vmfrm->dec_frm_num & 0x3) | ((sd_mode & 0x3F) << 2) | ((vmfrm->dec_hdr_1 & 0xE) << 8) | ((SAL_VM_Get_CodBand() & 0x3) << 12);
//[15:0]: TS control
vm.control_5 = SAL_VM_Get_TS_Info(SAL_VM_TS_INFO_CTRL);
//[7:0]: TS target scale
//[12:8]: TS max scale
vm.control_6 = (SAL_VM_Get_TS_Info(SAL_VM_TS_INFO_TARGET_SCALE) & 0xFF) | ((SAL_VM_Get_TS_Info(SAL_VM_TS_INFO_MAX_SCALE) & 0x1F) << 8);
//[10:0]: TS output size 1
vm.control_7 = SAL_VM_Get_TS_Info(SAL_VM_TS_INFO_OUTPUT_SIZE_1);
//[10:0]: TS output size 2
vm.control_8 = SAL_VM_Get_TS_Info(SAL_VM_TS_INFO_OUTPUT_SIZE_2);
// record vm control value
*vmBuf++ = vm.control_1;
*vmBuf++ = vm.control_2;
*vmBuf++ = vm.control_3;
*vmBuf++ = vm.control_4;
*vmBuf++ = vm.control_5;
*vmBuf++ = vm.control_6;
*vmBuf++ = vm.control_7;
*vmBuf++ = vm.control_8;
*vmBuf++ = vm.control_9;
*vmBuf++ = vm.control_10;
// record UL data
vm.sc_len = 0;
if ( vm.control_1 & 1 )
{
addr = vmfrm->enc_hb_addr;
for ( I = 0; I < sc_len; I++ )
{
*vmBuf++ = *addr++;
}
vm.sc_len += sc_len;
}
// record DL data
vm.sd_len = 0;
if ( vm.control_2 & 1 )
{
addr = vmfrm->dec_hb_addr;
for ( I = 0; I < sd_len; I++ )
{
*vmBuf++ = *addr++;
}
vm.sd_len += sd_len;
if (vmfrm->dec_frm_num == 2)
{
addr = vmfrm->dec_hb_addr_1;
for ( I = 0; I < sd_len; I++ )
{
*vmBuf++ = *addr++;
}
vm.sd_len += sd_len;
}
}
kal_prompt_trace(MOD_L1SP, "Formatter_C2K SC Len= %d, SD Len= %d, Dec_Cnt= %d", vm.sc_len, vm.sd_len, vmfrm->dec_frm_num);
// Debug info
addr = vmfrm->dbgInfo_addr;
for ( I = 0; I < VM_VM_SCH_DBGINFO_SIZE; I++ )
*vmBuf++ = *addr++;
addr = vmfrm->enh_dbgInfo_addr;
for ( I = 0; I < VM_VM_ENH_DBGINFO_SIZE; I++ )
*vmBuf++ = *addr++;
for (I = 0; I < VM_VM_DRV_DBGINFO_SIZE; I++)
{
if (I < VM_3G_NETWORK_INFO_LEN)
*vmBuf++ = vm3GNetworkInfo[I];
else
*vmBuf++ = 0;
}
addr = vmfrm->svc_dbgInfo_addr;
for ( I = 0; I < VM_VM_SVC_DBGINFO_SIZE; I++ )
*vmBuf++ = *addr++;
kal_prompt_trace(MOD_L1SP, "vmBuf tail %x", vmBuf);
}
void vmFormatter_standby(uint16 *vmBuf, Sal_VM_Frame *vmfrm)
{
volatile uint16 *addr;
uint16 I, sc_mode, sd_mode, sc_len, sd_len;
uint32 J;
uint16 sc_mode_invalid = 0;
sc_mode = vmfrm->enc_mode;
sd_mode = vmfrm->dec_mode;
if ((VM_CodIsAMR(sc_mode)) == false)
{
sc_mode = sd_mode;
sc_mode_invalid = 1;
}
sc_len = AM_GetSpeechPatternLength(sc_mode);
//ASSERT_REBOOT( sc_len > 0 );
sd_len = AM_GetSpeechPatternLength(sd_mode);
//ASSERT_REBOOT( sd_len > 0 );
//[0:0]: UL on
//[6:1]: UL mode
//[10:7]: TX type
//[11:11]: (no use) SP flag
//[13:12]: Call mode
if (sc_mode_invalid)
{
I = 0; // Tx: NO_DATA
}
else
{
I = vmfrm->enc_hdr & 0x3; // Tx: bit0, bit1
}
vm.control_1 = (I << 7) | (sc_mode << 1) | (vm.control_1 & 1);
vm.control_1 = vm.control_1 | 0x1000; // Call mode = 3G
//[0:0]: DL on
//[6:1]: DL mode
//[10:7]: RX type
//[15:11]: (no use) [12:11] SID flag, [13] TAF, [14] UFI, [15] BFI
I = (vmfrm->dec_hdr & 0xE) >> 1; // Rx: bit1, bit2, bit3
vm.control_2 = (I << 7) | (sd_mode << 1) | (vm.control_2 & 1);
kal_prompt_trace(MOD_L1SP, "vmBuf head %x", vmBuf);
*vmBuf++ = VM_VM_MAGIC_HEADER;
J = L1SP_GetState();
I = (uint16)( ( VM_VM_DBGINFO_TOTAL_SIZE << 3 ) | J);
*vmBuf++ = I;
*vmBuf++ = VM_VM_RECORD_FLAG;
*vmBuf++ = 0; //reset EPL band
J = fma_get_glb_ts() & 0xFFFFFFFF;
#if defined(_EXTRA_LOG_FOR_BIT_TRUE_)
if ( g_bNeedExtraLog )
MD_TRC_VM_SP3G_VM_L1T(J);
#endif
I = (uint16)(J & 0xFFFF);
*vmBuf++ = I;
I = (uint16)(J >> 16);
*vmBuf++ = I;
vm.vm_counter++;
//Chip ID
vm.control_3 = VM_CHIP_ID;
//[1:0]: DL frm cnt
//[7:2]: DL2 mode
//[11:8]: DL2 RX type
//[13:12]: Codec band
//[15:14]: Expert mode (By VLP)
vm.control_4 = (vmfrm->dec_frm_num & 0x3) | ((sd_mode & 0x3F) << 2) | ((vmfrm->dec_hdr_1 & 0xE) << 8) | ((SAL_VM_Get_CodBand() & 0x3) << 12);
//[15:0]: TS control
vm.control_5 = SAL_VM_Get_TS_Info(SAL_VM_TS_INFO_CTRL);
//[7:0]: TS target scale
//[12:8]: TS max scale
vm.control_6 = (SAL_VM_Get_TS_Info(SAL_VM_TS_INFO_TARGET_SCALE) & 0xFF) | ((SAL_VM_Get_TS_Info(SAL_VM_TS_INFO_MAX_SCALE) & 0x1F) << 8);
//[10:0]: TS output size 1
vm.control_7 = SAL_VM_Get_TS_Info(SAL_VM_TS_INFO_OUTPUT_SIZE_1);
//[10:0]: TS output size 2
vm.control_8 = SAL_VM_Get_TS_Info(SAL_VM_TS_INFO_OUTPUT_SIZE_2);
// record vm control value
*vmBuf++ = vm.control_1;
*vmBuf++ = vm.control_2;
*vmBuf++ = vm.control_3;
*vmBuf++ = vm.control_4;
*vmBuf++ = vm.control_5;
*vmBuf++ = vm.control_6;
*vmBuf++ = vm.control_7;
*vmBuf++ = vm.control_8;
*vmBuf++ = vm.control_9;
*vmBuf++ = vm.control_10;
// record UL data
vm.sc_len = 0;
if ( vm.control_1 & 1 )
{
addr = vmfrm->enc_hb_addr;
for ( I = 0; I < sc_len; I++ )
{
*vmBuf++ = *addr++;
}
vm.sc_len += sc_len;
}
// record DL data
vm.sd_len = 0;
if ( vm.control_2 & 1 )
{
addr = vmfrm->dec_hb_addr;
for ( I = 0; I < sd_len; I++ )
{
*vmBuf++ = *addr++;
}
vm.sd_len += sd_len;
if (vmfrm->dec_frm_num == 2)
{
addr = vmfrm->dec_hb_addr_1;
for ( I = 0; I < sd_len; I++ )
{
*vmBuf++ = *addr++;
}
vm.sd_len += sd_len;
}
}
kal_prompt_trace(MOD_L1SP, "Formatter_Standby SC Len= %d, SD Len= %d, Dec_Cnt= %d", vm.sc_len, vm.sd_len, vmfrm->dec_frm_num);
// Debug info
addr = vmfrm->dbgInfo_addr;
for ( I = 0; I < VM_VM_SCH_DBGINFO_SIZE; I++ )
*vmBuf++ = *addr++;
addr = vmfrm->enh_dbgInfo_addr;
for ( I = 0; I < VM_VM_ENH_DBGINFO_SIZE; I++ )
*vmBuf++ = *addr++;
for (I = 0; I < VM_VM_DRV_DBGINFO_SIZE; I++)
{
if (I < VM_3G_NETWORK_INFO_LEN)
*vmBuf++ = vm3GNetworkInfo[I];
else
*vmBuf++ = 0;
}
addr = vmfrm->svc_dbgInfo_addr;
for ( I = 0; I < VM_VM_SVC_DBGINFO_SIZE; I++ )
*vmBuf++ = *addr++;
kal_prompt_trace(MOD_L1SP, "vmBuf tail %x", vmBuf);
}
void vmFormatter_vm(uint16 *vmBuf, Sal_VM_Frame *vmfrm)
{
volatile uint16 *addr;
uint16 I, sc_mode, sd_mode, sc_len, sd_len;
uint32 J;
uint16 sc_mode_invalid = 0;
sc_mode = vmfrm->enc_mode;
sd_mode = vmfrm->dec_mode;
if (sc_mode != sd_mode)
{
sc_mode = sd_mode;
sc_mode_invalid = 1;
}
sc_len = AM_GetSpeechPatternLength(sc_mode);
//ASSERT_REBOOT( sc_len > 0 );
sd_len = AM_GetSpeechPatternLength(sd_mode);
//ASSERT_REBOOT( sd_len > 0 );
//[0:0]: UL on
//[6:1]: UL mode
//[10:7]: (no use) TX type
//[11:11]: SP flag
//[13:12]: Call mode
if (sc_mode_invalid)
{
I = 0; // sp_flag: Silence
}
else
{
I = (vmfrm->enc_hdr & 0x2) >> 1; // sp_flag: bit1
}
vm.control_1 = (I << 11) | (sc_mode << 1) | (vm.control_1 & 1);
// if Call mode = 2G, vm.control_1 = vm.control_1 | 0x0000;
//[0:0]: DL on
//[6:1]: DL mode
//[10:7]: (no use) RX type
//[15:11]: [12:11] SID flag, [13] TAF, [14] UFI, [15] BFI
I = (vmfrm->dec_hdr & 0x3E) >> 1; // BFI, UFI, TAF, SID
vm.control_2 = (I << 11) | (sd_mode << 1) | (vm.control_2 & 1);
kal_prompt_trace(MOD_L1SP, "vmBuf head %x", vmBuf);
*vmBuf++ = VM_VM_MAGIC_HEADER;
J = L1SP_GetState();
I = (uint16)( ( VM_VM_DBGINFO_TOTAL_SIZE << 3 ) | J);
*vmBuf++ = I;
*vmBuf++ = VM_VM_RECORD_FLAG;
*vmBuf++ = 0; //reset EPL band
J = fma_get_glb_ts() & 0xFFFFFFFF;
I = (uint16)(J & 0xFFFF);
*vmBuf++ = I;
I = (uint16)(J >> 16);
*vmBuf++ = I;
vm.vm_counter++;
//Chip ID
vm.control_3 = VM_CHIP_ID;
//[1:0]: DL frm cnt
//[7:2]: DL2 mode
//[11:8]: DL2 RX type
//[13:12]: Codec band
//[15:14]: Expert mode (By VLP)
vm.control_4 = (vmfrm->dec_frm_num & 0x3) | ((sd_mode & 0x3F) << 2) | ((vmfrm->dec_hdr_1 & 0xE) << 8) | ((SAL_VM_Get_CodBand() & 0x3) << 12);
//[15:0]: TS control
vm.control_5 = SAL_VM_Get_TS_Info(SAL_VM_TS_INFO_CTRL);
//[7:0]: TS target scale
//[12:8]: TS max scale
vm.control_6 = (SAL_VM_Get_TS_Info(SAL_VM_TS_INFO_TARGET_SCALE) & 0xFF) | ((SAL_VM_Get_TS_Info(SAL_VM_TS_INFO_MAX_SCALE) & 0x1F) << 8);
//[10:0]: TS output size 1
vm.control_7 = SAL_VM_Get_TS_Info(SAL_VM_TS_INFO_OUTPUT_SIZE_1);
//[10:0]: TS output size 2
vm.control_8 = SAL_VM_Get_TS_Info(SAL_VM_TS_INFO_OUTPUT_SIZE_2);
// record vm control value
*vmBuf++ = vm.control_1;
*vmBuf++ = vm.control_2;
*vmBuf++ = vm.control_3;
*vmBuf++ = vm.control_4;
*vmBuf++ = vm.control_5;
*vmBuf++ = vm.control_6;
*vmBuf++ = vm.control_7;
*vmBuf++ = vm.control_8;
*vmBuf++ = vm.control_9;
*vmBuf++ = vm.control_10;
// record UL data
vm.sc_len = 0;
if ( vm.control_1 & 1 )
{
addr = vmfrm->enc_hb_addr;
for ( I = 0; I < sc_len; I++ )
{
*vmBuf++ = *addr++;
if (L1SP_GetState() == L1SP_STATE_2G_SPEECH_ON)
addr++;
}
vm.sc_len += sc_len;
}
// record DL data
vm.sd_len = 0;
if ( vm.control_2 & 1 )
{
addr = vmfrm->dec_hb_addr;
for ( I = 0; I < sd_len; I++ )
{
*vmBuf++ = *addr++;
if (L1SP_GetState() == L1SP_STATE_2G_SPEECH_ON)
addr++;
}
vm.sd_len += sd_len;
if (vmfrm->dec_frm_num == 2)
{
addr = vmfrm->dec_hb_addr_1;
for ( I = 0; I < sd_len; I++ )
{
*vmBuf++ = *addr++;
if (L1SP_GetState() == L1SP_STATE_2G_SPEECH_ON)
addr++;
}
vm.sd_len += sd_len;
}
}
kal_prompt_trace(MOD_L1SP, "Formatter_VM SC Len= %d, SD Len= %d, Dec_Cnt= %d", vm.sc_len, vm.sd_len, vmfrm->dec_frm_num);
// Debug info
addr = vmfrm->dbgInfo_addr;
for ( I = 0; I < VM_VM_SCH_DBGINFO_SIZE; I++ )
*vmBuf++ = *addr++;
addr = vmfrm->enh_dbgInfo_addr;
for ( I = 0; I < VM_VM_ENH_DBGINFO_SIZE; I++ )
*vmBuf++ = *addr++;
for (I = 0; I < VM_VM_DRV_DBGINFO_SIZE; I++)
{
if (I < VM_3G_NETWORK_INFO_LEN)
*vmBuf++ = vm3GNetworkInfo[I];
else
*vmBuf++ = 0;
}
addr = vmfrm->svc_dbgInfo_addr;
for ( I = 0; I < VM_VM_SVC_DBGINFO_SIZE; I++ )
*vmBuf++ = *addr++;
kal_prompt_trace(MOD_L1SP, "vmBuf tail %x", vmBuf);
}
void vmFormatter_2g(uint16 *vmBuf, Sal_VM_Frame *vmfrm)
{
if (VM_CodIsAMR(vmfrm->dec_mode) == true)
{
vmFormatter_amr(vmBuf, vmfrm);
}
else
{
vmFormatter_vm(vmBuf, vmfrm);
}
}
/* ------------------------------------------------------------------------------ */
/**
@buf1: pointer to pcm buf1,
@len1:length of buf1, unit is word(2byte)
@buf2:pointer to pcm buf2
@len2: length of buf2. unit is word(2byte)
*/
void VmRec_GetReadBufs(kal_uint32 *add1, kal_uint16 *len1, kal_uint32 *add2, kal_uint16 *len2)
{
if (vm.pOutputBufWrite >= vm.pOutputBufRead) // write > read, 1 buf segment
{
*add1 = (kal_uint32)(&vmRecOutputBuf[vm.pOutputBufRead]);
*len1 = (vm.pOutputBufWrite - vm.pOutputBufRead);
*add2 = 0;
*len2 = 0;
}
else //write < read, 2 buf segment
{
*add1 = (kal_uint32)(&vmRecOutputBuf[vm.pOutputBufRead]);
*len1 = (vm.outputBufSize - vm.pOutputBufRead);
*add2 = (kal_uint32)(vmRecOutputBuf);
*len2 = (vm.pOutputBufWrite);
}
}
/**
@len: unit is word
*/
void VmRec_ReadDataDone(uint16 len)
{
vm.pOutputBufRead += len;
if ( vm.pOutputBufRead >= vm.outputBufSize)
vm.pOutputBufRead = vm.pOutputBufRead - vm.outputBufSize;
}
//use this function instead of Media_WriteDataDone to avoid media.waiting false usage
int32 vmRec_queryOutputBufFreeSpace(void)
{
int32 count;
count = vm.pOutputBufRead + vm.outputBufSize - vm.pOutputBufWrite - 1;
if ( count >= vm.outputBufSize )
count -= vm.outputBufSize;
return count;
}
void vmRec_getWriteBuffer(uint16 **buffer, uint32 *bufLen)
{
int32 count;
if ( vm.pOutputBufRead > vm.pOutputBufWrite )
count = vm.pOutputBufRead - vm.pOutputBufWrite - 1;
else if ( vm.pOutputBufRead == 0 )
count = vm.outputBufSize - vm.pOutputBufWrite - 1;
else
count = vm.outputBufSize - vm.pOutputBufWrite;
*buffer = &vmRecOutputBuf[vm.pOutputBufWrite];
*bufLen = (uint32)count;
}
static void vmRec_writeDataDone(uint32 len)
{
vm.pOutputBufWrite += len;
if ( vm.pOutputBufWrite >= vm.outputBufSize)
vm.pOutputBufWrite = vm.pOutputBufWrite - vm.outputBufSize;
}
static void vocWriteVocToCatcher(uint16 vmLen, uint16 *vmBuf)
{
uint32 len = vmLen * 2;
uint16 *buf = vmBuf;
while (len > 1000)
{
tst_vc_response(TVCI_VM_LOGGING, (const kal_uint8*)buf, 1000);
buf += 500;
len -= 1000;
}
tst_vc_response(TVCI_VM_LOGGING, (const kal_uint8*)buf, len);
}
static void vmRec_writeVmToOutputBuf(uint16 vmLen, uint16 *vmBuf) // a frame of VM must be written to MB
{
uint16 *toPtr;
uint32 segment, I;
vmRec_getWriteBuffer( &toPtr, &segment );
if (segment > vmLen)
segment = vmLen;
for ( I = segment ; I > 0 ; I-- ) {
*toPtr++ = *vmBuf++;
}
vmRec_writeDataDone( segment );
// second segment
vmLen -= segment; // unprocess length
if (vmLen > 0 )
{
vmRec_getWriteBuffer( &toPtr, &segment );
if (segment > vmLen)
segment = vmLen;
for ( I = segment ; I > 0 ; I-- ) {
*toPtr++ = *vmBuf++;
}
vmRec_writeDataDone( segment );
}
return;
}
static void voc4WayPcmRecord( volatile uint16* ul_addr, uint16 ul_len, volatile uint16* dl_addr, uint16 dl_len)
{
uint16 *buf;
buf = vm.pcmBuf;
// header for record 1st set of UL-DL PCM data
*buf++ = (vm.vm_lost_count << 8) + vm.pcm_lost_count;
*buf++ = vm.vm_counter ;
// make it interleave
// Uplink
EMI_ReadFromDSP((uint16*)buf, ul_addr, ul_len);
buf += ul_len;
// Downlink
EMI_ReadFromDSP((uint16*)buf, dl_addr, dl_len);
buf = vm.pcmBuf;
vocWriteVocToCatcher(ul_len + dl_len + 2, buf);
}
static void vm4WayPcmRecord(volatile uint16 *ul_addr, uint16 ul_len, volatile uint16 *dl_addr, uint16 dl_len)
{
uint32 I, tmp = 0;
uint16 *buf, *mBuf;
uint16 logsize;
logsize = ul_len + dl_len + 2;
buf = vm.pcmBuf;
// header for record 1st set of UL-DL PCM data
*buf++ = (vm.vm_lost_count << 8) + vm.pcm_lost_count;
*buf++ = vm.vm_counter ;
// Uplink
EMI_ReadFromDSP((uint16*)buf, ul_addr, ul_len);
buf += ul_len;
// Downlink
EMI_ReadFromDSP((uint16*)buf, dl_addr, dl_len);
buf = vm.pcmBuf;
vmRec_getWriteBuffer( &mBuf, &tmp );
if ( tmp > logsize )
tmp = logsize;
//for( I = tmp ; I > 0 ; I-- ) {
// *mBuf++ = *buf++;
//}
kal_mem_cpy(mBuf, buf, tmp << 1);
buf += tmp;
mBuf += tmp;
vmRec_writeDataDone(tmp);
tmp = logsize - tmp; // tmp is size did not write to Buffer
if ( (int32)tmp > 0 )
{
vmRec_getWriteBuffer( &mBuf, &I );
if (I >= tmp)
{
//for( I = tmp ; I > 0 ; I--) {
// *mBuf++ = *buf++;
//}
kal_mem_cpy(mBuf, buf, tmp << 1);
buf += tmp;
mBuf += tmp;
vmRec_writeDataDone( tmp );
}
else
{
MD_TRC_VM_REC_HISR_PCM_DATA_LOST(0);
}
}
}
static void vmRefMic_AGC_PcmRecord( bool isToVoc, volatile uint16 *addr, uint16 len )
{
uint32 I, tmp = 0;
uint16 *buf, *mBuf;
uint16 logsize;
logsize = len + 2 + 2;
buf = vm.pcmBuf;
*buf++ = (vm.vm_lost_count << 8) + vm.pcm_lost_count;
*buf++ = vm.vm_counter ;
{ //RefMic
EMI_ReadFromDSP((uint16*)buf, addr, len);
buf += len;
*buf++ = SAL_AGC_GetSWGain(0);
*buf = SAL_AGC_GetSWGain(1);
}
buf = vm.pcmBuf;
if (isToVoc)
{
vocWriteVocToCatcher(logsize, buf);
}
else // normal vm process
{
vmRec_getWriteBuffer( &mBuf, &tmp );
if ( tmp > logsize )
tmp = logsize;
kal_mem_cpy(mBuf, buf, tmp << 1);
buf += tmp;
mBuf += tmp;
vmRec_writeDataDone(tmp);
tmp = logsize - tmp;
if ( (int32)tmp > 0 )
{
vmRec_getWriteBuffer( &mBuf, &I );
if (I >= tmp)
{
kal_mem_cpy(mBuf, buf, tmp << 1);
buf += tmp;
mBuf += tmp;
vmRec_writeDataDone(tmp);
}
else
{
MD_TRC_VM_REC_HISR_PCM_DATA_LOST(0);
}
}
}
}
static void vmEchoRefPcmRecord( bool isToVoc, volatile uint16 *addr, uint16 len )
{
uint32 I, tmp = 0;
uint16 *buf, *mBuf;
uint16 logsize;
logsize = len + 2;
buf = vm.pcmBuf;
*buf++ = (vm.vm_lost_count << 8) + vm.pcm_lost_count;
*buf++ = vm.vm_counter ;
EMI_ReadFromDSP((uint16*)buf, addr, len);
buf = vm.pcmBuf;
if (isToVoc)
{
vocWriteVocToCatcher(logsize, buf);
}
else // normal vm process
{
vmRec_getWriteBuffer( &mBuf, &tmp );
if ( tmp > logsize )
tmp = logsize;
kal_mem_cpy(mBuf, buf, tmp << 1);
buf += tmp;
mBuf += tmp;
vmRec_writeDataDone(tmp);
tmp = logsize - tmp;
if ( (int32)tmp > 0 )
{
vmRec_getWriteBuffer( &mBuf, &I );
if (I >= tmp)
{
kal_mem_cpy(mBuf, buf, tmp << 1);
buf += tmp;
mBuf += tmp;
vmRec_writeDataDone(tmp);
}
else
{
MD_TRC_VM_REC_HISR_PCM_DATA_LOST(0);
}
}
}
}
/* ------------------------------------------------------------------------------ */
void vmTchPcmRecordHisr(void *param)
{
uint16 u2VM_total_size; // VM + EPL_PCM + EPL_dummy
uint16 u2VM_buffer_size; // VM
uint16 u2VM_size; // Dbg Info size + EPL PCM size
uint16 u2EPL_PCM_size = 0;
uint16 u2EPL_dummy_size = 0;
uint16 *buf;
Sal_EPL_Frame eplfrm_t;
if (KAL_SPINLOCK_NOT_AVAILABLE == kal_take_spinlock(vm.lockId, KAL_NO_WAIT))
{
MD_TRC_VM_HISR_LOCK_NOT_AVALIABLE(2);
goto leaveEplHisr;
}
// dsp status check
if ( vm.state != VM_STATE_RECORD )
{
goto leaveEplProc;
}
// application status check
if ( (false == vm.isVocOn) && (false == vm.isVmLOn))
{
goto leaveEplProc;
}
SAL_EPL_GetFrame(&eplfrm_t);
if (vm.record_info & VM_EPL_1STSET_RECORD_FLAG) {
u2EPL_PCM_size += eplfrm_t.ul_pre_len + eplfrm_t.dl_pre_len;
u2EPL_dummy_size += 2;
}
if (vm.record_info & VM_EPL_2NDSET_RECORD_FLAG) {
u2EPL_PCM_size += eplfrm_t.ul_pos_len + eplfrm_t.dl_pos_len;
u2EPL_dummy_size += 2;
}
if (vm.record_info & VM_EPL_REFMIC_RECORD_FLAG) {
u2EPL_PCM_size += eplfrm_t.ul2_pos_len;
u2EPL_dummy_size += 4;
}
if (vm.record_info & VM_EPL_ECHOREF_RECORD_FLAG) {
u2EPL_PCM_size += eplfrm_t.ul4_pos_len;
u2EPL_dummy_size += 2;
}
if (vm.record_info & VM_EPL_3RDMIC_RECORD_FLAG) {
u2EPL_PCM_size += eplfrm_t.ul3_pos_len;
u2EPL_dummy_size += 2;
}
if (vm.record_info & VM_EPL_2NDECHOREF_RECORD_FLAG) {
u2EPL_PCM_size += eplfrm_t.ul5_pos_len;
u2EPL_dummy_size += 2;
}
// handing the total size u2VM_total_size (vm + pcm buffer) in word(2byte)
buf = vm.vmBuf;
if (buf[0] == VM_VM_MAGIC_HEADER) //already buffer VM, (normal case)
{
u2VM_size = VM_VM_DBGINFO_TOTAL_SIZE + u2EPL_PCM_size;
u2VM_buffer_size = VM_VM_HEADER_SIZE + VM_VM_CONTROL_SIZE + vm.sc_len + vm.sd_len + VM_VM_DBGINFO_TOTAL_SIZE;
kal_prompt_trace(MOD_L1SP, "TchPcmRecordHisr SC Len= %d, SD Len= %d", vm.sc_len, vm.sd_len);
}
else // case when previous vmbufer is missing! Save the pcm data with empty vm
{
u2VM_size = u2EPL_PCM_size;
u2VM_buffer_size = VM_VM_HEADER_SIZE;
}
u2VM_total_size = u2VM_buffer_size + u2EPL_PCM_size + u2EPL_dummy_size;
buf[3] |= vmEPLBandSet(eplfrm_t.ul_pre_len, VM_EPL_BAND_UL0_SHIFT);
buf[3] |= vmEPLBandSet(eplfrm_t.ul_pos_len, VM_EPL_BAND_UL1_SHIFT);
buf[3] |= vmEPLBandSet(eplfrm_t.dl_pre_len, VM_EPL_BAND_DL0_SHIFT);
buf[3] |= vmEPLBandSet(eplfrm_t.dl_pos_len, VM_EPL_BAND_DL1_SHIFT);
buf[3] |= vmEPLBandSet(eplfrm_t.ul2_pos_len, VM_EPL_BAND_UL2_SHIFT);
buf[3] |= vmEPLBandSet(eplfrm_t.ul4_pos_len, VM_EPL_BAND_UL4_SHIFT);
buf[3] |= vmEPLBandSet(eplfrm_t.ul3_pos_len, VM_EPL_BAND_UL3_SHIFT);
buf[3] |= vmEPLBandSet(eplfrm_t.ul5_pos_len, VM_EPL_BAND_UL5_SHIFT);
kal_prompt_trace(MOD_L1SP, "UL_PRE %d, UL_POS %d, DL_PRE %d, DL_POS %d, UL2 %d, UL3 %d, UL4 %d, UL5 %d", eplfrm_t.ul_pre_len, eplfrm_t.ul_pos_len, eplfrm_t.dl_pre_len, eplfrm_t.dl_pos_len, eplfrm_t.ul2_pos_len, eplfrm_t.ul3_pos_len, eplfrm_t.ul4_pos_len, eplfrm_t.ul5_pos_len);
kal_prompt_trace(MOD_L1SP, "Band %x", buf[3]);
//when vm logging and VOC are both on, only send the data to vm logging to reduce log size
if (vm.isVmLOn)
{
if (vmRec_queryOutputBufFreeSpace() < u2VM_total_size)
{
// drop this log and add counter
vm.pcm_lost_count++;
MD_TRC_VM_REC_HISR_VM_DATA_LOST(vm.vm_lost_count, 1);
goto leaveEplProc;
}
else
{
uint32 timestamp;
buf[0] = VM_VM_MAGIC_HEADER;
buf[1] = (u2VM_size << 3) | (L1SP_GetState()) ;
buf[2] |= (vm.record_info & VM_EPL_ALL_RECORD_FLAG);
// buf[3] is set in previous
timestamp = fma_get_glb_ts() & 0xFFFFFFFF;
buf[4] = (uint16)(timestamp & 0xFFFF); // Lo
buf[5] = (uint16)(timestamp >> 16); // High
vmRec_writeVmToOutputBuf(u2VM_buffer_size, buf);
//pcm bufs
if (vm.record_info & VM_EPL_1STSET_RECORD_FLAG)
vm4WayPcmRecord(eplfrm_t.ul_pre_buf, eplfrm_t.ul_pre_len, eplfrm_t.dl_pre_buf, eplfrm_t.dl_pre_len);
if (vm.record_info & VM_EPL_2NDSET_RECORD_FLAG)
vm4WayPcmRecord(eplfrm_t.ul_pos_buf, eplfrm_t.ul_pos_len, eplfrm_t.dl_pos_buf, eplfrm_t.dl_pos_len);
if (vm.record_info & VM_EPL_REFMIC_RECORD_FLAG)
vmRefMic_AGC_PcmRecord(false, eplfrm_t.ul2_pos_buf, eplfrm_t.ul2_pos_len);
if (vm.record_info & VM_EPL_ECHOREF_RECORD_FLAG)
vmEchoRefPcmRecord(false, eplfrm_t.ul4_pos_buf, eplfrm_t.ul4_pos_len);
if (vm.record_info & VM_EPL_3RDMIC_RECORD_FLAG)
vmEchoRefPcmRecord(false, eplfrm_t.ul3_pos_buf, eplfrm_t.ul3_pos_len);
if (vm.record_info & VM_EPL_2NDECHOREF_RECORD_FLAG)
vmEchoRefPcmRecord(false, eplfrm_t.ul5_pos_buf, eplfrm_t.ul5_pos_len);
}
}
else // VOC
{
// fill vm buffer header
uint32 timestamp;
buf[0] = VM_VM_MAGIC_HEADER;
buf[1] = (u2VM_size << 3) | (L1SP_GetState()) ;
buf[2] |= (vm.record_info & VM_EPL_ALL_RECORD_FLAG);
// buf[3] is set in previous
timestamp = fma_get_glb_ts() & 0xFFFFFFFF;
buf[4] = (uint16)(timestamp & 0xFFFF); // Lo
buf[5] = (uint16)(timestamp >> 16); // High
vocWriteVocToCatcher(u2VM_buffer_size, buf);
if (vm.record_info & VM_EPL_1STSET_RECORD_FLAG)
voc4WayPcmRecord(eplfrm_t.ul_pre_buf, eplfrm_t.ul_pre_len, eplfrm_t.dl_pre_buf, eplfrm_t.dl_pre_len);
if (vm.record_info & VM_EPL_2NDSET_RECORD_FLAG)
voc4WayPcmRecord(eplfrm_t.ul_pos_buf, eplfrm_t.ul_pos_len, eplfrm_t.dl_pos_buf, eplfrm_t.dl_pos_len);
if (vm.record_info & VM_EPL_REFMIC_RECORD_FLAG)
vmRefMic_AGC_PcmRecord(true, eplfrm_t.ul2_pos_buf, eplfrm_t.ul2_pos_len);
if (vm.record_info & VM_EPL_ECHOREF_RECORD_FLAG)
vmEchoRefPcmRecord(true, eplfrm_t.ul4_pos_buf, eplfrm_t.ul4_pos_len);
if (vm.record_info & VM_EPL_3RDMIC_RECORD_FLAG)
vmEchoRefPcmRecord(true, eplfrm_t.ul3_pos_buf, eplfrm_t.ul3_pos_len);
if (vm.record_info & VM_EPL_2NDECHOREF_RECORD_FLAG)
vmEchoRefPcmRecord(true, eplfrm_t.ul5_pos_buf, eplfrm_t.ul5_pos_len);
}
vm.pcm_lost_count = 0;
buf[0] = 0;
buf[1] = 0;
buf[2] = 0;
buf[3] = 0;
leaveEplProc:
kal_give_spinlock(vm.lockId);
if (vm.vm_hdlr) {
vm.vm_hdlr();
}
leaveEplHisr:
return;
}
void vmTchRecordHisr(void *param)
{
uint16 u2VM_buffer_size;
uint16 *vmBuf;
uint8 sp_state = L1SP_GetState();
if (KAL_SPINLOCK_NOT_AVAILABLE == kal_take_spinlock(vm.lockId, KAL_NO_WAIT))
{
MD_TRC_VM_HISR_LOCK_NOT_AVALIABLE(1);
goto leaveHisr;
}
// check dsp status
if ( vm.state != VM_STATE_RECORD )
{
goto leaveProc;
}
// check application status
if ( (false == vm.isVocOn) && (false == vm.isVmLOn))
{
goto leaveProc;
}
// just logging
#if defined(__MA_L1__)
if (!(L1SP_GetState() == L1SP_STATE_3G_SPEECH_ON || L1SP_GetState() == L1SP_STATE_3G324M_SPEECH_ON))
{
uint8 rx_type, tx_type, BFI;
uint16 rx_debug;
rx_debug = *DSP_RX_TCH_S(0, 0);
tx_type = *DSP_RX_TCH_S(0, 0) & 0x3;
rx_type = (rx_debug >> 1) & 0x7;
BFI = (rx_debug >> 5) & 0x1; //speechBFI
if ( rx_type < 3 ) //non-amr
rx_type = 8 + (rx_type << 1) + BFI;
BFI = (rx_debug >> 8) & 0xFF; //BER
MD_TRC_L1Audio_Msg_SPEECH_FRAME( L1SP_Speech_TX_Type(tx_type), L1SP_Speech_RX_Type(rx_type), BFI);
MD_TRC_L1Audio_Msg_VM_DEBUG( DP2_3G_debug_info0, DP2_3G_debug_info1, DP2_3G_debug_info7 );
}
#endif
// process previous buffer
vmBuf = vm.vmBuf;
if (vmBuf[0] == VM_VM_MAGIC_HEADER) //already buffer VM
{
u2VM_buffer_size = VM_VM_HEADER_SIZE + VM_VM_CONTROL_SIZE + vm.sc_len + vm.sd_len + VM_VM_DBGINFO_TOTAL_SIZE;
kal_prompt_trace(MOD_L1SP, "TchRecordHisr SC Len= %d, SD Len= %d", vm.sc_len, vm.sd_len);
//when vm logging and VOC are both on, only send the data to vm logging to reduce log size
if (vm.isVmLOn)
{
if (vmRec_queryOutputBufFreeSpace() < u2VM_buffer_size)
{
// drop this log and add counter
vm.vm_lost_count++;
MD_TRC_VM_REC_HISR_VM_DATA_LOST(vm.vm_lost_count, 2);
goto leaveProc;
}
else
{
vmRec_writeVmToOutputBuf(u2VM_buffer_size, vmBuf);
}
}
else
{
vocWriteVocToCatcher(u2VM_buffer_size, vmBuf);
}
vm.vm_lost_count = 0;
vmBuf[0] = 0;
vmBuf[1] = 0;
vmBuf[2] = 0;
vmBuf[3] = 0;
}
// formatting
Sal_VM_Frame vmfrm_t;
switch (sp_state)
{
case L1SP_STATE_4G_SPEECH_ON:
SAL_VM_GetFrame3G(&vmfrm_t);
vmFormatter_4g(vmBuf, &vmfrm_t);
break;
case L1SP_STATE_3G_SPEECH_ON:
case L1SP_STATE_3G324M_SPEECH_ON:
SAL_VM_GetFrame3G(&vmfrm_t);
vmFormatter_amr(vmBuf, &vmfrm_t);
break;
case L1SP_STATE_C2K_SPEECH_ON:
SAL_VM_GetFrameC2K(&vmfrm_t);
vmFormatter_c2k(vmBuf, &vmfrm_t);
break;
default:
if (L1SP_Get_isStandByMode() || pcmEx_isRunInIdleMode())
{
SAL_VM_GetFrame3G(&vmfrm_t);
vmFormatter_standby(vmBuf, &vmfrm_t);
}
else
{
SAL_VM_GetFrame2G(&vmfrm_t);
vmFormatter_2g(vmBuf, &vmfrm_t);
}
break;
}
leaveProc:
kal_give_spinlock(vm.lockId);
if (vm.vm_hdlr)
{
vm.vm_hdlr();
}
leaveHisr:
SP_updateEmCodecEvent();
return;
}
void VM_Init(void)
{
vm.lockId = kal_create_spinlock("VM_LOCK");
}
void VMREC_ConfigEpl(void)
{
// only support phone call VM record dynamic change from AP side
if (vm.isVocOn || vm.isVmLOn)
{
kal_uint16 recordInfo = L1Audio_GetDebugInfo(VM_DEBUG_INFO);
if (ChkL1ClsFltr_L1Audio_VoC_TRACE_EPL())
{
recordInfo |= (VM_EPL_1STSET_RECORD_FLAG + VM_EPL_2NDSET_RECORD_FLAG);
recordInfo |= VM_EPL_REFMIC_RECORD_FLAG;
recordInfo |= VM_EPL_ECHOREF_RECORD_FLAG;
recordInfo |= VM_EPL_3RDMIC_RECORD_FLAG;
recordInfo |= VM_EPL_2NDECHOREF_RECORD_FLAG;
}
MD_TRC_VM_REC_DEBUG_INFO(recordInfo);
// config to open, and did not open yet
if (((recordInfo & (VM_EPL_1STSET_RECORD_FLAG + VM_EPL_2NDSET_RECORD_FLAG)) != 0)
&& ((vm.record_info & (VM_EPL_1STSET_RECORD_FLAG + VM_EPL_2NDSET_RECORD_FLAG)) == 0))
{
//EPL open
recordInfo |= VM_EPL_REFMIC_RECORD_FLAG;
recordInfo |= VM_EPL_ECHOREF_RECORD_FLAG;
recordInfo |= VM_EPL_3RDMIC_RECORD_FLAG;
recordInfo |= VM_EPL_2NDECHOREF_RECORD_FLAG;
// Initial
vm.record_info = recordInfo;
vm.vm_lost_count = 0;
vm.pcm_lost_count = 0;
vm.vm_counter = 0;
vm.pcmBuf = vmEPLPCMInputBuf;
memset(vmEPLPCMInputBuf, 0, sizeof(uint16)*VM_EPL_PCM_BUFFER_SIZE);
// Enable EPL
L1Audio_HookHisrHandler(DP_D2C_VMEPL_REC_INT, (L1Audio_EventHandler)vmTchPcmRecordHisr, 0);
AM_PCM8K_RecordOn(AM_PCM8KREC_APP_TYPE_VMEPL, 0);
}
}
}
/**
@vm_hdlr: handler
@isVoc: is call from vm over catcher.
*/
void VMREC_Start(void (*vm_hdlr)(void), bool isVoc)
{
if (AM_IsAmInSpeechState())
{
//decide the open
bool isAlreadyOn = (vm.isVocOn || vm.isVmLOn);
if (isVoc)
{
//ASSERT(!vm.isVocOn); // prevent re-entry
vm.isVocOn = true;
}
else // normal vm
{
//ASSERT(!vm.isVmLOn); // prevent re-entry
vm.isVmLOn = true;
vm.vm_hdlr = vm_hdlr;
}
#ifdef __SENSITIVE_DATA_MOSAIC__
if (dhl_mask_sensitive_trace_on())
{
vm.isMosaic = true;
return;
}
else
{
vm.isMosaic = false;
}
#endif
//already on
if (isAlreadyOn)
{
VMREC_ConfigEpl();
return;
}
else
{
// Initial
vm.audId = L1Audio_GetAudioID();
L1Audio_SetFlag(vm.audId); //Be careful.Before Locking SleepMode, to access DSP sherrif tasks much time. So access DSP must be after SetFlag
vm.state = VM_STATE_RECORD;
vm.control_1 = VM_VM_CTRL_UL_ON;
vm.control_2 = VM_VM_CTRL_DL_ON;
vm.control_3 = VM_CHIP_ID;
vm.control_4 = 0;
vm.control_5 = 0;
vm.control_6 = 0;
vm.control_7 = 0;
vm.control_8 = 0;
vm.control_9 = 0;
vm.control_10 = 0;
vm.evs_cur_sd_mode = EVS_UNDEF;
vm.sc_len = 0;
vm.sd_len = 0;
//vm buffer initital
vm.vmBuf = vmBuffer;
memset(vm.vmBuf, 0, sizeof(uint16)*VM_VM_BUFFER_SIZE);
// output buffer initial
vm.pOutputBufWrite = 0;
vm.pOutputBufRead = 0;
vm.outputBufSize = VMREC_OUTPUT_BUF_SIZE;
memset(vmRecOutputBuf, 0, sizeof(uint16)*VMREC_OUTPUT_BUF_SIZE);
VMREC_ConfigEpl();
#if defined(__G_CODEC_SUPPORT__) && defined(__VOLTE_SUPPORT__)
//G-serial codec buffer initial
{
vmInitGCodecULBuf();
vmInitGCodecDLBuf();
}
#endif
#if defined(__UMTS_RAT__)
#if defined(_EXTRA_LOG_FOR_BIT_TRUE_)
//TDD load need to reduce trace
if (SP_3G_SIM_FDD_ACTIVE == L1SP_GetSIMStatus() &&
(((int)L1Audio_GetDebugInfo(SPH_DEBUGINFO))& SPH_DEBUGINFO12_BIT1))
{
g_bNeedExtraLog = KAL_TRUE;
}
#endif
#endif
// enalbe normal VM record
L1Audio_HookHisrHandler(DP_D2C_VM_REC_INT, (L1Audio_EventHandler)vmTchRecordHisr, 0);
AM_VMRecordOn();
}
}
}
/**
@isVoc: is call from voice over cater. true is yes; false is no.
*/
void VMREC_Stop( bool isVoc)
{
// check voc & vm are both closed.
if (AM_IsAmInSpeechState())
{
if (isVoc)
{
//ASSERT(vm.isVocOn == true);
kal_take_spinlock(vm.lockId, KAL_INFINITE_WAIT);
vm.isVocOn = false;
kal_give_spinlock(vm.lockId);
if (vm.isVmLOn) //still another need vm
{
return;
}
}
else //record vm from media
{
//ASSERT(vm.isVmLOn == true);
kal_take_spinlock(vm.lockId, KAL_INFINITE_WAIT);
vm.isVmLOn = false;
vm.vm_hdlr = NULL;
kal_give_spinlock(vm.lockId);
if (vm.isVocOn) //still another need vm
{
return;
}
}
#ifdef __SENSITIVE_DATA_MOSAIC__
{
if (vm.isMosaic)
{
return;
}
}
#endif
if (VM_STATE_RECORD == vm.state)
{
kal_take_spinlock(vm.lockId, KAL_INFINITE_WAIT);
vm.state = VM_STATE_RECORD_STOP;
kal_give_spinlock(vm.lockId);
if (vm.record_info & (VM_EPL_1STSET_RECORD_FLAG + VM_EPL_2NDSET_RECORD_FLAG))
{
AM_PCM8K_RecordOff(false, AM_PCM8KREC_APP_TYPE_VMEPL);
L1Audio_UnhookHisrHandler(DP_D2C_VMEPL_REC_INT); // EPL record unhook
vm.pcmBuf = NULL;
}
AM_VMRecordOff();
L1Audio_UnhookHisrHandler(DP_D2C_VM_REC_INT); // vm record unhook
vm.vmBuf = NULL;
vm.state = VM_STATE_STOP;
vm.record_info = 0;
// output buffer clean
vm.pOutputBufWrite = 0;
vm.pOutputBufRead = 0;
vm.outputBufSize = 0;
memset(vmRecOutputBuf, 0, sizeof(uint16)*VMREC_OUTPUT_BUF_SIZE);
#if defined(__G_CODEC_SUPPORT__) && defined(__VOLTE_SUPPORT__)
//G-serial codec buffer initial
{
vmInitGCodecULBuf();
vmInitGCodecDLBuf();
}
#endif
// release sleep mode
L1Audio_ClearFlag(vm.audId);
L1Audio_FreeAudioID(vm.audId);
}
}
}