[Feature]Upload Modem source code
Change-Id: Id4294f30faced84d3e6fd6d5e61e1111bf287a37
diff --git a/mcu/driver/audio/src/v1/DTMF_drv.c b/mcu/driver/audio/src/v1/DTMF_drv.c
new file mode 100644
index 0000000..588098e
--- /dev/null
+++ b/mcu/driver/audio/src/v1/DTMF_drv.c
@@ -0,0 +1,813 @@
+/*****************************************************************************
+* 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:
+ * ---------
+ * DTMF_drv.c
+ *
+ * Project:
+ * --------
+ * MAUI
+ *
+ * Description:
+ * ------------
+ * ARM DTMF driver
+ *
+ * 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!
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *==============================================================================
+*******************************************************************************/
+
+#include "kal_public_api.h"
+#include "kal_trace.h"
+#include "l1audio.h"
+// #include "audio_def.h"
+#include "l1sp_trc.h"
+#include "am.h"
+//#include "med_utility.h"
+#include "l1audio_trace_utmd.h"
+#include "media.h"
+#include "tone_drv.h"
+
+
+
+#if defined(__MCU_DTMF_SUPPORT__) //&& !defined( MED_MODEM )
+
+//#include "pcmsink.h"
+#include "dtmf_exp.h"
+
+#define DTMF_MAX_DURATION (0xFFFFFFFF)
+//#define DTMF_DEFALUT_SAMPLE_RATE (16000)
+#define DTMF_DEFALUT_SAMPLE_RATE (32000)
+#define DTMF_BUFFERED_FRAME_NUMBER (4)
+#define DTMF_MAX_FRAME (0xFFFF)
+#define DTMF_MIN_FRAME (3) // 5 * 20 msec
+#define DTMF_FRAME_LEN (20) // 20 msec
+#define DTMF_STOP_WAIT_TICK (80)//((DTMF_FRAME_LEN*DTMF_BUFFERED_FRAME_NUMBER+2)/4)
+//#define DTMF_FLUSH_FRAME_NUMBER ((PCM_SOUND_FILLDATA_THRESHOLD/DTMF_FRAME_LEN)+1)
+//#pragma arm section code="SECONDARY_ROCODE"
+
+static kal_uint32 DTMF_FLUSH_FRAME_NUMBER = 3;
+//static kal_uint32 uDtmfMuteLength1 = 6;
+//static kal_uint32 uDtmfMuteLength2 = 0;//13;
+//static kal_uint32 uDtmfMuteLength3 = 1;
+//static kal_uint32 uDtmfMuteLength4 = 3;
+//static kal_uint32 uMuteLength = 150;//60;
+static kal_uint32 uPreSilenceLength= 3;
+kal_enhmutexid MCUTONEMUTEXID;
+kal_spinlockid MCUTONESpinLockID;
+
+static struct {
+ const L1SP_QTMF *pCurrQTMF;
+ const L1SP_Tones *pToneList;
+ void *pHandle;
+
+ kal_uint32 uRemainDuration[3];
+ kal_uint32 uTotalDuration[3];
+ kal_bool fIsQTMF[3];
+ kal_bool fIsOn[3];
+ kal_bool fEnable[3];
+
+ //buffer
+ AUD_RB_INFO RingBuffer;
+ kal_uint32 uFrameByte;
+
+ //Current Tone
+ kal_bool fNewDTMF;
+ kal_bool fClearDTMF;
+ kal_bool fIsToneListQTMF;
+ kal_bool fEnding;
+
+ kal_uint16 uAudId;
+ kal_uint16 uSampleRate;
+ kal_uint8 uCurIdx;
+
+ kal_bool fIsKeytonePlaying;
+ kal_bool fIsTonePlaying;
+ kal_uint8 uFlushSilenceCount;
+ kal_bool fForceStop;
+}DTMF_SW;
+
+
+
+
+
+
+static kal_uint32 dtmf_mcu_CheckDuration(kal_uint16 uDuration)
+{
+ if(uDuration)
+ {
+ return ((uDuration+DTMF_FRAME_LEN-1)/DTMF_FRAME_LEN);
+
+ }
+
+ return DTMF_MAX_DURATION;
+
+}
+
+static kal_bool dtmf_mcu_IsPlaying()
+{
+ if( DTMF_SW.fEnable[0] || DTMF_SW.fEnable[1] || DTMF_SW.fEnable[2] )
+ {
+ return KAL_TRUE;
+ }
+ return KAL_FALSE;
+}
+
+static void dtmf_mcu_GetKeyID(kal_uint32 uIndex, DTMF_KEY *uKey1, DTMF_KEY *uKey2 )
+{
+ ASSERT(uIndex<3);
+ if(uIndex==0)
+ {
+ *uKey1 = DTMFKEY_Ext0;
+ *uKey2 = DTMFKEY_Ext1;
+ }
+ else if(uIndex==1)
+ {
+ *uKey1 = DTMFKEY_Ext2;
+ *uKey2 = DTMFKEY_Ext3;
+ }
+ else if(uIndex==2)
+ {
+ *uKey1 = DTMFKEY_Ext4;
+ *uKey2 = DTMFKEY_Ext5;
+ }
+}
+
+static void dtmf_mcu_GetPreIndex(kal_uint32 uCurIndex, kal_uint32 *uPreIndex1, kal_uint32 *uPreIndex2 )
+{
+ ASSERT(uCurIndex<3);
+ if(uCurIndex==0)
+ {
+ *uPreIndex1 = 2;
+ *uPreIndex2 = 1;
+ }
+ else if(uCurIndex==1)
+ {
+ *uPreIndex1 = 0;
+ *uPreIndex2 = 2;
+ }
+ else
+ {
+ *uPreIndex1 = 1;
+ *uPreIndex2 = 0;
+ }
+}
+
+static void dtmf_mcu_DeActivatAllKey()
+{
+ kal_uint32 I = 0;
+ for(I=0;I<3;I++)
+ {
+ if(DTMF_SW.fEnable[I])
+ {
+ if(DTMF_SW.fIsOn[I] == KAL_FALSE)
+ {
+ DTMF_SW.fEnable[I] = KAL_FALSE;
+ }
+ DTMF_SW.uRemainDuration[I] = 1;
+ }
+ }
+}
+
+static void dtmf_mcu_ActivatNewKey()
+{
+ DTMF_KEY uKey1, uKey2;
+ kal_uint32 uPreIndex1, uPreIndex2;
+ kal_uint32 uCurrentDur;
+ DTMF_SW.uCurIdx++;
+ if(DTMF_SW.uCurIdx > 2)
+ {
+ DTMF_SW.uCurIdx = 0;
+ }
+ dtmf_mcu_GetPreIndex(DTMF_SW.uCurIdx, &uPreIndex1, &uPreIndex2);
+ dtmf_mcu_GetKeyID(DTMF_SW.uCurIdx, &uKey1, &uKey2);
+ DTMF_SetKey( DTMF_SW.pHandle, uKey1, (kal_int32)DTMF_SW.pCurrQTMF->freq1, (kal_int32)DTMF_SW.pCurrQTMF->freq2);
+ DTMF_SetKey( DTMF_SW.pHandle, uKey2, (kal_int32)DTMF_SW.pCurrQTMF->freq3, (kal_int32)DTMF_SW.pCurrQTMF->freq4);
+ uCurrentDur = dtmf_mcu_CheckDuration(DTMF_SW.pCurrQTMF->on_duration);
+ DTMF_SW.uRemainDuration[DTMF_SW.uCurIdx] = DTMF_SW.uTotalDuration[DTMF_SW.uCurIdx] = uCurrentDur;
+ DTMF_SW.fIsQTMF[DTMF_SW.uCurIdx] = DTMF_SW.fIsToneListQTMF;
+ DTMF_SW.fEnable[DTMF_SW.uCurIdx] = KAL_TRUE;
+ DTMF_SW.fIsOn[DTMF_SW.uCurIdx] = KAL_TRUE;
+ if(DTMF_SW.fEnable[uPreIndex2])
+ {
+ MD_TRC_MCU_DTMF_NEWKEY_FORCE_END_2(uPreIndex2, DTMF_SW.uRemainDuration[uPreIndex2], DTMF_SW.uTotalDuration[uPreIndex2]);
+ DTMF_SW.uRemainDuration[uPreIndex2] = 1;
+ }
+ if(DTMF_SW.fEnable[uPreIndex1])
+ {
+ MD_TRC_MCU_DTMF_NEWKEY_FORCE_END_1(uPreIndex1, DTMF_SW.uRemainDuration[uPreIndex1], DTMF_SW.uTotalDuration[uPreIndex1]);
+ if(DTMF_SW.uTotalDuration[uPreIndex1] > DTMF_MIN_FRAME)
+ {
+ kal_uint32 uPlayedDur = DTMF_SW.uTotalDuration[uPreIndex1]-DTMF_SW.uRemainDuration[uPreIndex1];
+ if(uPlayedDur >= DTMF_MIN_FRAME )
+ {
+ DTMF_SW.uRemainDuration[uPreIndex1] = 1;
+ }
+ else
+ {
+ DTMF_SW.uRemainDuration[uPreIndex1] = DTMF_MIN_FRAME - uPlayedDur;
+ }
+ }
+ if(DTMF_SW.uRemainDuration[uPreIndex1] > uCurrentDur)
+ {
+ DTMF_SW.uRemainDuration[uPreIndex1] = uCurrentDur;
+ }
+ }
+ MD_TRC_MCU_DTMF_NEWKEY(DTMF_SW.uCurIdx, uCurrentDur, DTMF_SW.fIsToneListQTMF, DTMF_SW.pCurrQTMF->freq1, DTMF_SW.pCurrQTMF->freq2, DTMF_SW.pCurrQTMF->freq3, DTMF_SW.pCurrQTMF->freq4);
+}
+
+static void dtmf_mcu_PrepareTone(kal_uint32 uIndex)
+{
+ DTMF_KEY uKey1, uKey2;
+ if(!DTMF_SW.fEnable[uIndex])
+ {
+ return;
+ }
+ dtmf_mcu_GetKeyID(uIndex, &uKey1, &uKey2);
+ if(DTMF_SW.uRemainDuration[uIndex] == DTMF_SW.uTotalDuration[uIndex])
+ {
+ if(DTMF_SW.fIsOn[uIndex] == KAL_FALSE)
+ {
+ DTMF_Tone(DTMF_SW.pHandle, uKey1, 0);
+ DTMF_Tone(DTMF_SW.pHandle, uKey2, 0);
+ }
+ else if(DTMF_SW.fIsQTMF[uIndex])
+ {
+ DTMF_Tone(DTMF_SW.pHandle, uKey1, 1);
+ DTMF_Tone(DTMF_SW.pHandle, uKey2, 1);
+ }
+ else
+ {
+ DTMF_Tone(DTMF_SW.pHandle, uKey1, 1);
+ DTMF_Tone(DTMF_SW.pHandle, uKey2, 0);
+ }
+ }
+ else if(DTMF_SW.uRemainDuration[uIndex] == 1)
+ {
+ DTMF_Tone(DTMF_SW.pHandle, uKey1, 0);
+ DTMF_Tone(DTMF_SW.pHandle, uKey2, 0);
+ }
+}
+
+static void dtmf_mcu_UpdateTone(kal_uint32 uIndex)
+{
+ DTMF_KEY uKey1, uKey2;
+ if(!DTMF_SW.fEnable[uIndex])
+ {
+ return;
+ }
+ dtmf_mcu_GetKeyID(uIndex, &uKey1, &uKey2);
+ DTMF_SW.uRemainDuration[uIndex]--;
+ if(DTMF_SW.uRemainDuration[uIndex] == 0)
+ {
+ if(DTMF_SW.uCurIdx != uIndex)
+ {
+ MD_TRC_MCU_DTMF_UPDATE_TONE_PREV_END(uIndex);
+ DTMF_SW.fEnable[uIndex] = KAL_FALSE;
+ }
+ else
+ {
+ if(DTMF_SW.fIsOn[uIndex])
+ {
+ if( DTMF_SW.pCurrQTMF->off_duration == 0 || DTMF_SW.fClearDTMF)
+ {
+ MD_TRC_MCU_DTMF_UPDATE_TONE_CURR_END(uIndex);
+ DTMF_SW.fEnable[uIndex] = KAL_FALSE;
+ }
+ else
+ {
+ MD_TRC_MCU_DTMF_UPDATE_TONE_CURR_OFF(uIndex);
+ DTMF_SW.fIsOn[uIndex] = KAL_FALSE;
+ DTMF_SW.uRemainDuration[uIndex] = DTMF_SW.uTotalDuration[uIndex] = dtmf_mcu_CheckDuration(DTMF_SW.pCurrQTMF->off_duration);
+ if(DTMF_SW.pCurrQTMF->off_duration)
+ {
+ if(DTMF_SW.fIsToneListQTMF)
+ {
+ DTMF_SW.pCurrQTMF = (L1SP_QTMF *)DTMF_SW.pToneList + DTMF_SW.pCurrQTMF->next_tone;
+ }
+ else
+ {
+ DTMF_SW.pCurrQTMF = (L1SP_QTMF *)(DTMF_SW.pToneList + DTMF_SW.pCurrQTMF->next_tone);
+ }
+ }
+ }
+ }
+ else
+ {
+ MD_TRC_MCU_DTMF_UPDATE_TONE_CURR_ON(uIndex);
+ DTMF_SetKey( DTMF_SW.pHandle, uKey1, (kal_int32)DTMF_SW.pCurrQTMF->freq1, (kal_int32)DTMF_SW.pCurrQTMF->freq2);
+ DTMF_SetKey( DTMF_SW.pHandle, uKey2, (kal_int32)DTMF_SW.pCurrQTMF->freq3, (kal_int32)DTMF_SW.pCurrQTMF->freq4);
+ DTMF_SW.uRemainDuration[DTMF_SW.uCurIdx] = DTMF_SW.uTotalDuration[DTMF_SW.uCurIdx] = dtmf_mcu_CheckDuration(DTMF_SW.pCurrQTMF->on_duration);
+ DTMF_SW.fIsOn[uIndex] = KAL_TRUE;
+ }
+ }
+ }
+ else if(DTMF_SW.uRemainDuration[uIndex] == 1 && DTMF_SW.fIsOn[uIndex])
+ { //ramp down
+ MD_TRC_MCU_DTMF_UPDATE_TONE_RAMPDOWN(uIndex);
+ DTMF_Tone(DTMF_SW.pHandle, uKey1, 0);
+ DTMF_Tone(DTMF_SW.pHandle, uKey2, 0);
+ }
+}
+
+static void dtmf_mcu_Destroy(kal_uint32 arg1, void* arg2)
+{
+
+ //kal_bool fIsAudioRunning = false;//PcmSink_IsAudioRuning() || PcmSink_IsMixerRuning();
+ MD_TRC_MCU_DTMF_DESTROY(DTMF_SW.pHandle, DTMF_SW.fNewDTMF, DTMF_SW.fEnding, DTMF_SW.fForceStop);
+ if(DTMF_SW.pHandle == NULL)
+ {
+ return;
+ }
+ if((DTMF_SW.fNewDTMF == KAL_FALSE && DTMF_SW.fEnding == KAL_TRUE) || DTMF_SW.fForceStop)
+ {
+ {
+ {
+// void AM_SWToneOff( void );
+// AM_SWToneOff();
+ }
+ }
+ kal_take_spinlock(MCUTONESpinLockID, KAL_INFINITE_WAIT);
+ DTMF_SW.pHandle = NULL;
+ DTMF_SW.RingBuffer.rb_base = NULL;
+ memset(&DTMF_SW, 0, sizeof(DTMF_SW));
+ kal_give_spinlock(MCUTONESpinLockID);
+ L1Audio_ClearFlag( DTMF_SW.uAudId);
+ L1Audio_FreeAudioID(DTMF_SW.uAudId);
+ //audio_free_mem( (void **) &DTMF_SW.RingBuffer.rb_base);//
+
+ //if(fIsAudioRunning)
+ // {
+////! PcmSink_Mute(KAL_TRUE, PCMSINK_MUTE_TONE);
+ //kal_sleep_task( AUD_1TICK(uDtmfMuteLength3) );
+ //}
+ //if(DTMF_SW.fIsKeytonePlaying)
+ //{
+////! PcmSink_StopSound(PCM_FUNC_KEYTONE);
+ //}
+ //else if(DTMF_SW.fIsTonePlaying)
+ //{
+////! PcmSink_StopSound(PCM_FUNC_TONE);
+ //}
+ //else
+ //{
+ //ASSERT(0);
+ //}
+
+ //if(fIsAudioRunning)
+ //{
+ //kal_sleep_task( AUD_1TICK(uDtmfMuteLength4) );
+ //}
+////! PcmSink_DepopUnMute( NULL );
+////! PcmSink_Mute(KAL_FALSE, PCMSINK_MUTE_TONE);
+ }
+}
+
+static kal_bool dtmf_mcu_Process_Internal()
+{
+ kal_uint32 uPreIndex1, uPreIndex2, uBufLen, uCurrentData;
+ kal_uint8 *pBuf;
+ kal_bool fIsPlaying = KAL_TRUE;
+ MD_TRC_MCU_DTMF_MCU_PROCESS_INTERNAL_ENTER();
+ kal_take_enh_mutex(MCUTONEMUTEXID);
+ if(DTMF_SW.pHandle == NULL)
+ {
+ kal_give_enh_mutex(MCUTONEMUTEXID);
+ return KAL_FALSE;
+ }
+ rbGetWriteBuffer(&DTMF_SW.RingBuffer, &pBuf, &uBufLen);
+ MD_TRC_MCU_DTMF_PROCESS_ENTRY(DTMF_SW.fNewDTMF, DTMF_SW.fClearDTMF, DTMF_SW.fEnding, uBufLen);
+ if(DTMF_SW.fClearDTMF)
+ {
+ dtmf_mcu_DeActivatAllKey();
+ if(!dtmf_mcu_IsPlaying())
+ {
+ DTMF_SW.fClearDTMF = KAL_FALSE;
+ }
+ }
+ if(uBufLen < DTMF_SW.uFrameByte || (DTMF_SW.fEnding && !DTMF_SW.fNewDTMF) )
+ {
+ kal_give_enh_mutex(MCUTONEMUTEXID);
+ return KAL_FALSE;
+ }
+ dtmf_mcu_GetPreIndex(DTMF_SW.uCurIdx, &uPreIndex1, &uPreIndex2);
+ if(DTMF_SW.fNewDTMF)
+ {
+ dtmf_mcu_ActivatNewKey(uPreIndex1, uPreIndex2);
+ DTMF_SW.fNewDTMF = KAL_FALSE;
+ }
+ else
+ { //flush data
+ fIsPlaying = dtmf_mcu_IsPlaying();
+ uCurrentData = rbGetDataCount(&DTMF_SW.RingBuffer);
+ MD_TRC_MCU_DTMF_PROCESS_STATUS(fIsPlaying, uCurrentData, DTMF_SW.uFlushSilenceCount);
+ if(!fIsPlaying && DTMF_SW.uFlushSilenceCount<DTMF_FLUSH_FRAME_NUMBER)
+ {
+ DTMF_Gen(DTMF_SW.pHandle, pBuf);
+ rbWriteDataDone(&DTMF_SW.RingBuffer, DTMF_SW.uFrameByte);
+ DTMF_SW.uFlushSilenceCount++;
+ }
+ if(!fIsPlaying && uCurrentData==0 && !DTMF_SW.fEnding)
+ {
+////! PcmSink_Mute(KAL_TRUE, PCMSINK_MUTE_TONE);
+ DTMF_SW.fEnding = KAL_TRUE;
+ L1Audio_InProcCall(dtmf_mcu_Destroy, 0, NULL);
+ kal_give_enh_mutex(MCUTONEMUTEXID);
+ return KAL_FALSE;
+ }
+ }
+ if(fIsPlaying)
+ {
+ dtmf_mcu_PrepareTone(0);
+ dtmf_mcu_PrepareTone(1);
+ dtmf_mcu_PrepareTone(2);
+ DTMF_Gen(DTMF_SW.pHandle, pBuf);
+ rbWriteDataDone(&DTMF_SW.RingBuffer, DTMF_SW.uFrameByte);
+ dtmf_mcu_UpdateTone(0);
+ dtmf_mcu_UpdateTone(1);
+ dtmf_mcu_UpdateTone(2);
+ DTMF_SW.fClearDTMF = KAL_FALSE;
+ kal_give_enh_mutex(MCUTONEMUTEXID);
+ return KAL_TRUE;
+ }
+ MD_TRC_MCU_DTMF_MCU_PROCESS_INTERNAL_LEAVE();
+ kal_give_enh_mutex(MCUTONEMUTEXID);
+ return KAL_FALSE;
+}
+
+static void dtmf_mcu_Process(void *pData)
+{
+ kal_bool fContinue;
+ do
+ {
+ fContinue = dtmf_mcu_Process_Internal();
+ }while(fContinue);
+}
+
+
+#define DTMF_MCU_BUFFER_SIZE (19000/4)
+unsigned int dtmf_mcu_buffer[DTMF_MCU_BUFFER_SIZE];
+static void dtmf_mcu_Init(kal_uint16 uSampleRate)
+{
+ kal_uint32 uIntBufSize=0, uPcmBufSize=0, uTotalBufferSize=0;
+ kal_uint8 *pAllocBuf;
+ DTMF_SR uSr=0;
+ memset(&DTMF_SW, 0, sizeof(DTMF_SW));
+ DTMF_SW.uSampleRate = uSampleRate;
+ switch (DTMF_SW.uSampleRate)
+ {
+ case 8000:
+ uSr = DTMF_8K;
+ break;
+ case 11025:
+ uSr = DTMF_11K;
+ break;
+ case 12000:
+ uSr = DTMF_12K;
+ break;
+ case 16000:
+ uSr = DTMF_16K;
+ break;
+ case 22050:
+ uSr = DTMF_22K;
+ break;
+ case 24000:
+ uSr = DTMF_24K;
+ break;
+ case 32000:
+ uSr = DTMF_32K;
+ break;
+ case 44100:
+ uSr = DTMF_44K;
+ break;
+ case 48000:
+ uSr = DTMF_48K;
+ break;
+ default:
+ ASSERT(0);
+ break;
+ }
+ DTMF_GetBufferSize(&uIntBufSize, &uPcmBufSize, uSr, DTMF_MONO);
+ uTotalBufferSize = uIntBufSize + uPcmBufSize * DTMF_BUFFERED_FRAME_NUMBER;
+ MD_TRC_MCU_DTMF_INIT(uSampleRate, uPcmBufSize, uTotalBufferSize);
+ //pAllocBuf = (kal_uint8 *)audio_alloc_mem(uTotalBufferSize);
+ //ASSERT(pAllocBuf);
+ if( (DTMF_MCU_BUFFER_SIZE<<2) < uTotalBufferSize )
+ {
+ MD_TRC_MCU_DTMF_INIT(uSampleRate, (DTMF_MCU_BUFFER_SIZE<<2), uTotalBufferSize);
+ ASSERT(0);
+ }
+ pAllocBuf = (kal_uint8 *)dtmf_mcu_buffer;
+ ASSERT(uIntBufSize);
+ ASSERT(uPcmBufSize);
+ DTMF_SW.uFrameByte = uPcmBufSize;
+ DTMF_SW.RingBuffer.rb_base = (kal_uint8*)pAllocBuf;
+ DTMF_SW.RingBuffer.rb_size = uPcmBufSize * DTMF_BUFFERED_FRAME_NUMBER;
+ DTMF_SW.RingBuffer.write = uPcmBufSize * uPreSilenceLength; //fill a silence to prevent pop up noise
+ DTMF_SW.RingBuffer.read=0;
+ pAllocBuf += uPcmBufSize * DTMF_BUFFERED_FRAME_NUMBER;
+ DTMF_SW.pHandle = DTMF_Init( (void *)pAllocBuf, DTMF_CONTINUOUS, uSr, DTMF_MONO);
+ ASSERT(DTMF_SW.pHandle);
+ DTMF_SW.uAudId = L1Audio_GetAudioID();
+ L1Audio_SetFlag( DTMF_SW.uAudId );
+ L1Audio_SetEventHandler( DTMF_SW.uAudId, dtmf_mcu_Process );
+}
+
+kal_bool DTMF_MCU_IsPlaying()
+{
+ if(DTMF_SW.pHandle)
+ {
+ return KAL_TRUE;
+ }
+ else
+ {
+ return KAL_FALSE;
+ }
+}
+
+kal_bool DTMF_MCU_IsKeytonePlaying()
+{
+ return DTMF_SW.fIsKeytonePlaying;
+}
+
+kal_bool DTMF_MCU_IsTonePlaying()
+{
+ return DTMF_SW.fIsTonePlaying;
+}
+
+void DTMF_MCU_ReadDataDone(kal_uint32 uDataWord)
+{
+ MD_TRC_MCU_DTMF_READ_DATA_DONE(uDataWord);
+ if(DTMF_SW.pHandle)
+ {
+ rbReadDataDone(&DTMF_SW.RingBuffer, uDataWord<<1);
+ }
+}
+
+void DTMF_MCU_GetReadBuffer(kal_int16 **pBuf_16b, kal_uint32 *uDataWord)
+{
+ *pBuf_16b = NULL;
+ *uDataWord = 0;
+ if(DTMF_SW.pHandle)
+ {
+ kal_uint32 uDataByte;
+ kal_uint8 *pBuf_8b;
+ rbGetReadBuffer(&DTMF_SW.RingBuffer, &pBuf_8b, &uDataByte);
+ ASSERT(!((kal_uint32)pBuf_8b & 0x1));
+ *pBuf_16b = (kal_int16*)pBuf_8b;
+ *uDataWord = uDataByte >> 1;
+ }
+ MD_TRC_MCU_DTMF_GET_REAR_BUFFER(*uDataWord);
+}
+
+kal_uint32 DTMF_MCU_GetDataCount()
+{
+ kal_uint32 uDataWord = 0;
+ if(DTMF_SW.pHandle)
+ {
+ uDataWord = (rbGetDataCount(&DTMF_SW.RingBuffer))>>1;
+ }
+ MD_TRC_MCU_DTMF_GET_DATA_COUNT(uDataWord);
+ return uDataWord;
+}
+
+void DTMF_MCU_DataRequestCallback()
+{
+ MD_TRC_MCU_DTMF_DATA_REQUEST(DTMF_SW.pHandle);
+ if(DTMF_SW.pHandle)
+ {
+ //Although dtmf_stop may cause pHandle =NULL, dtmf_mcu_internal_process check pHandle=NULL will return
+ L1Audio_SetEvent( DTMF_SW.uAudId, NULL );
+ }
+}
+
+void DTMF_MCU_StopAndWait()
+{
+ kal_int32 I=0;
+ kal_take_enh_mutex(MCUTONEMUTEXID);
+ DTMF_SW.fNewDTMF = KAL_FALSE;
+ DTMF_SW.fForceStop = KAL_FALSE;
+ if(DTMF_SW.pHandle)
+ {
+ DTMF_SW.fClearDTMF = KAL_TRUE;
+ DTMF_MCU_DataRequestCallback();
+ kal_give_enh_mutex(MCUTONEMUTEXID);
+ while(1)
+ {
+ ////! if(DTMF_SW.fEnding == KAL_TRUE || AM_IsAudioPlaybackOn() == -1 || !PcmSink_IsSoundRuning())
+ if(DTMF_SW.fEnding == KAL_TRUE)
+ {
+ DTMF_SW.fForceStop = KAL_TRUE;
+ dtmf_mcu_Destroy(0, NULL);
+ break;
+ }
+ kal_sleep_task( AUD_1TICK(1) );
+ I++;
+ ASSERT(I<DTMF_STOP_WAIT_TICK);
+ }
+ }
+ else
+ {
+ kal_give_enh_mutex(MCUTONEMUTEXID);
+ }
+
+}
+
+void DTMF_MCU_Stop(kal_bool fIsKeytone)
+{
+ MD_TRC_MCU_DTMF_STOP(DTMF_SW.pHandle);
+ if( (DTMF_SW.fIsKeytonePlaying && !fIsKeytone) || (DTMF_SW.fIsTonePlaying && fIsKeytone) )
+ {
+ return;
+ }
+ kal_take_enh_mutex(MCUTONEMUTEXID);
+ DTMF_SW.fNewDTMF = KAL_FALSE;
+ if(DTMF_SW.pHandle)
+ {
+ DTMF_SW.fClearDTMF = KAL_TRUE;
+ DTMF_MCU_DataRequestCallback();
+ }
+ kal_give_enh_mutex(MCUTONEMUTEXID);
+}
+
+
+void DTMF_MCU_lockInit()
+{
+ MCUTONEMUTEXID= kal_create_enh_mutex( "MCU_TONE_MUTEX" );
+ MCUTONESpinLockID= kal_create_spinlock( "MCU_TONE_LOCK" );
+
+}
+
+void DTMF_MCU_Play( const L1SP_Tones *pToneList, kal_bool fIsQTMF, kal_bool fIsKeytone)
+{
+ //kal_uint32 uSaveMask;
+ //kal_bool fIsAudioRunning = false;//PcmSink_IsAudioRuning() || PcmSink_IsMixerRuning();
+ MD_TRC_MCU_DTMF_PLAY(DTMF_SW.pHandle);
+ if( (DTMF_SW.fIsKeytonePlaying && !fIsKeytone) || (DTMF_SW.fIsTonePlaying && fIsKeytone) )
+ {
+ DTMF_MCU_StopAndWait();
+ }
+ kal_take_enh_mutex(MCUTONEMUTEXID);
+ if(DTMF_SW.pHandle == NULL)
+ {
+ kal_uint16 uSampleRate;
+ //kal_uint8 uChannelNumber;
+////! PcmSink_GetCurrentPcmInfo(&uSampleRate, &uChannelNumber);
+ uSampleRate = 0;
+ //uChannelNumber = 1;
+ if(uSampleRate == 0)
+ {
+ uSampleRate = DTMF_DEFALUT_SAMPLE_RATE;
+ }
+ dtmf_mcu_Init(uSampleRate);
+////! PcmSink_Mute(KAL_TRUE, PCMSINK_MUTE_TONE);
+////! if(fIsAudioRunning)
+////! {
+////! PcmSink_DepopMute(uMuteLength);
+////! if(uDtmfMuteLength1)
+////! {
+////! kal_sleep_task( AUD_1TICK(uDtmfMuteLength1) );
+////! }
+////! }
+ }
+ DTMF_SW.pToneList = pToneList;
+ DTMF_SW.pCurrQTMF = (const L1SP_QTMF *)pToneList;
+ DTMF_SW.fIsToneListQTMF = fIsQTMF;
+ DTMF_SW.fNewDTMF = KAL_TRUE;
+ DTMF_SW.fEnding = KAL_FALSE;
+ DTMF_SW.uFlushSilenceCount = 0;
+ DTMF_MCU_DataRequestCallback();
+
+ if(fIsKeytone && !DTMF_SW.fIsKeytonePlaying)
+ {
+ DTMF_SW.fIsKeytonePlaying = KAL_TRUE;
+////! PcmSink_StartSound(PCM_FUNC_KEYTONE, DTMF_SW.uSampleRate, 2);
+////! if(fIsAudioRunning && uDtmfMuteLength2)
+////! {
+////! kal_sleep_task( AUD_1TICK(uDtmfMuteLength2) );
+////! }
+ }
+ else if(!fIsKeytone && !DTMF_SW.fIsTonePlaying)
+ {
+ DTMF_SW.fIsTonePlaying = KAL_TRUE;
+////! PcmSink_StartSound(PCM_FUNC_TONE, DTMF_SW.uSampleRate, 2);
+////! if(fIsAudioRunning && uDtmfMuteLength2)
+////! {
+////! kal_sleep_task( AUD_1TICK(uDtmfMuteLength2) );
+////! }
+ }
+ kal_give_enh_mutex(MCUTONEMUTEXID);
+ {
+// void AM_SWToneOn( void );
+// AM_SWToneOn();
+ }
+////! PcmSink_Mute(KAL_FALSE, PCMSINK_MUTE_TONE);
+}
+
+//#pragma arm section
+
+#else
+
+void DTMF_MCU_Play( const L1SP_Tones *pToneList, kal_bool fIsQTMF, kal_bool fIsKeytone){}
+void DTMF_MCU_Stop(kal_bool fIsKeytone){}
+void DTMF_MCU_StopAndWait(){}
+void DTMF_MCU_DataRequestCallback(){}
+kal_uint32 DTMF_MCU_GetDataCount(){return 0;}
+void DTMF_MCU_GetReadBuffer(kal_int16 **pBuf_16b, kal_uint32 *uDataWord){}
+void DTMF_MCU_ReadDataDone(kal_uint32 uDataWord){}
+kal_bool DTMF_MCU_IsPlaying(){return KAL_FALSE;}
+kal_bool DTMF_MCU_IsKeytonePlaying(){return KAL_FALSE;}
+
+#endif
+