blob: 588098e4392edcab68a7d10987fafc771fd4d5ed [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:
* ---------
* 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