MHdl *PCM_Strm_Rec_Open(void(*handler)( MHdl *handle, Media_Event event ), void *param) { MHdl *hdl; pcmStrmMediaHdl *ihdl; ihdl = (pcmStrmMediaHdl*)get_ctrl_buffer( sizeof(pcmStrmMediaHdl) ); memset(ihdl, 0, sizeof(pcmStrmMediaHdl)); hdl = (MHdl *) ihdl; ihdl->pcmStrm.dedicated_mode = AM_IsSpeechOn(); mhdlInit( hdl, 0, NULL ); hdl->handler = handler; hdl->state = WAV_STATE_IDLE; ihdl->pcmStrm.isPlayback = false; hdl->Close = pcmStrmMFClose; hdl->Pause = pcmStrmMFPause; hdl->Stop = pcmStrmMFStop; hdl->Process = pcmStrmMFProcess; hdl->Record = pcmStrmMFRecord; hdl->Resume = pcmStrmMFResume; kal_trace( TRACE_FUNC, L1AUDIO_OPEN_STREAM, MEDIA_FORMAT_PCM_8K ); return hdl; }
uint32 EXT_BGSND_Start(void (*offHdr)(void), void (*DLHisr)(void), //move data from src -> ext void (*ULHisr)(void), //move data from src -> ext kal_int8 DLSNDGain, kal_int8 ULSNDGain /*, void (*EventHandler)(void)*/) { int i, j; kal_prompt_trace(MOD_L1SP, "[EXT_BGSND_Start] Enter"); ASSERT(!(NULL==DLHisr && NULL==ULHisr)); ASSERT(NULL!=offHdr); //without this, we cannot stop DSP BGSND for(i=0; i<MAX_SIZE_EXT_BGSND_SRC; i++){ kal_prompt_trace(MOD_L1SP, "[EXT_BGSND_Start] debug1 i=%d", i); if(!Ext_BGSnd.is_used[i]){ kal_prompt_trace(MOD_L1SP, "[EXT_BGSND_Start] debug2 i=%d", i); EXT_BGSND_SRC_T *pSrc = &Ext_BGSnd.src[i]; pSrc->Hdr[BGSND_DL_PROCESS] = DLHisr; pSrc->Hdr[BGSND_UL_PROCESS] = ULHisr; pSrc->offHdr = offHdr; for(j=0; j<MAX_NUM_BGSND_PROCESS; j++){//TODO temp solution pSrc->state[j] = EXT_SRC_STATE_RUN; //pSrc->fSph[j] = true; //TODO //pSrc->gain[j] = 7; //TODO // buffer reset memset(pSrc->buffer[j], 0, sizeof(kal_uint16)*EXT_BGSND_SRC_BUF_SIZE); pSrc->bufSize[j] = EXT_BGSND_SRC_BUF_SIZE; pSrc->bufRead[j] = 0; pSrc->bufWrite[j] = EXT_BGSND_BUF_PTR_DIFF; } if(AM_IsSpeechOn() || AM_IsVoIPOn()){ EXT_BGSND_ConfigMixer(i, true, DLSNDGain, BGSND_DL_PROCESS); EXT_BGSND_ConfigMixer(i, true, ULSNDGain, BGSND_UL_PROCESS); }else{ EXT_BGSND_ConfigMixer(i, false, DLSNDGain, BGSND_DL_PROCESS); EXT_BGSND_ConfigMixer(i, false, ULSNDGain, BGSND_UL_PROCESS); } Ext_BGSnd.is_used[i] = true; if( 0 == Ext_BGSnd.num_src_used++){ kal_prompt_trace(MOD_L1SP, "[EXT_BGSND_Start] selected_src_id=%d num_src_used=%d", i, Ext_BGSnd.num_src_used); // lock DSP for sherif writing. L1Audio_SetFlag( Ext_BGSnd.aud_id ); // REIMIND: Before Locking SleepMode, to access DSP sherrif tasks much time. So access DSP must be after SetFlag1 DSP_BGSND_Start(EXT_BGSND_DLHisr, EXT_BGSND_ULHisr); } kal_prompt_trace(MOD_L1SP, "[EXT_BGSND_Start] debug3 i=%d", i); break; } kal_prompt_trace(MOD_L1SP, "[EXT_BGSND_Start] debug4 i=%d", i); } kal_prompt_trace(MOD_L1SP, "[EXT_BGSND_Start] debug5 i=%d", i); ASSERT(i < MAX_SIZE_EXT_BGSND_SRC); kal_prompt_trace(MOD_L1SP, "[EXT_BGSND_Start] Leave"); return i; }
static void bgsndUpdateMixer() { if ( AM_IsSpeechOn() ) { SAL_Bgsnd_Config(bgSnd.ULGain, bgSnd.DLGain, bgSnd.fULSPH, bgSnd.fDLSPH); } else { SAL_Bgsnd_Config(bgSnd.ULGain, bgSnd.DLGain, 0, 0); } }
/** The function starts the background sound playback of the media handle. @bgSnd_hdlr: handler @ULGainLevel: uplink gain level, from 0~7 @DLGainLevel: downlink gain level, from 0~7 */ void BGSND_Start(void (*bgSnd_hisrHandler)(void), void (*bgSnd_offHandler)(void), kal_uint8 ULGainLevel , kal_uint8 DLGainLevel) { kal_trace( TRACE_FUNC, L1SND_ENTER_BGSND_START ); // clean up bgSnd.dspLastSample = 0; bgSnd.endCount = 0; // buffer reset memset(bgSndBuf, 0, sizeof(kal_uint16)*BGSND_BUF_SIZE); bgSnd.pBuf = bgSndBuf; bgSnd.bufSize = BGSND_BUF_SIZE; bgSnd.bufRead = 0; bgSnd.bufWrite = BGSND_BUF_PTR_DIFF; // clear hisr flag bgSnd.isDlHisrCome = false; bgSnd.isUlHisrCome = false; // lock DSP for sherif writing. L1Audio_SetFlag( bgSnd.aud_id ); // REIMIND: Before Locking SleepMode, to access DSP sherrif tasks much time. So access DSP must be after SetFlag1 // L1Audio_SetEventHandler(bgSnd.aud_id, BGSND_eventHandler ); bgSnd.bgSnd_hisrHandler = bgSnd_hisrHandler; #ifdef DSP_BGS_UP_DOWN_INT_SEPERATE L1Audio_HookHisrHandler(D2C_SOUND_EFFECT_INT_ID_DL, bgsndDlHisr, 0); L1Audio_HookHisrHandler(D2C_SOUND_EFFECT_INT_ID_UL, bgsndUlHisr, 0); #else L1Audio_HookHisrHandler(D2C_SOUND_EFFECT_INT_ID_DL, bgsndHisr, 0); #endif bgSnd.bgSnd_offHandler = bgSnd_offHandler; // gain setting and update if(AM_IsSpeechOn()){ BGSND_ConfigULMixer(KAL_TRUE, ULGainLevel); BGSND_ConfigDLMixer(KAL_TRUE, DLGainLevel); } else { BGSND_ConfigULMixer(KAL_FALSE, ULGainLevel); BGSND_ConfigDLMixer(KAL_FALSE, DLGainLevel); } bgsndUpdateMixer(); // Before dynamic download, all application should be off. // But background sound do not need to dynamic download, so the following is unnecessary. // KT_StopAndWait(); // turn on. bgsndOnHandler(); // L1SP_Register_BgsService(bgsndOnHandler, bgsndOffHandler); bgSnd.state = BGSND_STATE_RUN; }
static void DSP_BGSND_UpdateMixer() // private { kal_prompt_trace(MOD_L1SP, "[DSP_BGSND_UpdateMixer] Enter"); if ( AM_IsSpeechOn() || AM_IsVoIPOn()) { SAL_Bgsnd_Config(DSP_BGSnd.gain[BGSND_UL_PROCESS], DSP_BGSnd.gain[BGSND_DL_PROCESS], DSP_BGSnd.fSph[BGSND_UL_PROCESS], DSP_BGSnd.fSph[BGSND_DL_PROCESS]); } else { //When enable BT, spe_setSpeechMode() will do Speech Off and Speech On. This function may run between Off and ON, so do not use ASSERT(). //ASSERT(false); SAL_Bgsnd_Config(DSP_BGSnd.gain[BGSND_UL_PROCESS], DSP_BGSnd.gain[BGSND_DL_PROCESS], 0, 0); } kal_prompt_trace(MOD_L1SP, "[DSP_BGSND_UpdateMixer] Leave"); }
static kal_bool isNeedSphEnh(void) { if ( AM_IsSpeechOn() || Media_IsCSDMode() ) return KAL_FALSE; #if defined( __I2S_INPUT_MODE_SUPPORT__ ) if (I2S_is_I2S_open()) return KAL_FALSE; #endif return KAL_TRUE; }
static void wavRecOpenDeviceHandler( void *state ) { /*workaround for SPEECH DSP MAIN/AUX Mode Task in FCORE*/ #if !(defined(MT6573) || defined(MT6575) || defined(MT6577)) TONE_StopAndWait(); KT_StopAndWait(); #endif #ifdef BGSND_ENABLE if ((!AM_IsSpeechOn()) && (wav.sndOffHandler != NULL)) wav.sndOffHandler( wav.sndHdl ); #endif /*workaround for SPEECH DSP MAIN/AUX Mode Task in FCORE*/ if ( wav.ctrl->format == MEDIA_FORMAT_WAV_DVI_ADPCM_16K || wav.ctrl->format==MEDIA_FORMAT_PCM_16K ) AM_PCM16K_RecordOn_V2(wav.dedicated_mode, wav.ctrl->fc_aud_id); else AM_PCM8K_RecordOn_V2(wav.dedicated_mode, wav.ctrl->fc_aud_id); }
static void DSP_BGSND_Start(void (*Ext_DLHisr)(void), void (*Ext_ULHisr)(void)) { kal_prompt_trace(MOD_L1SP, "[DSP_BGSND_Start] Enter"); ASSERT(AM_IsSpeechOn() || AM_IsVoIPOn()); DSP_BGSnd.Ext_Hisr[BGSND_DL_PROCESS] = Ext_DLHisr; DSP_BGSnd.Ext_Hisr[BGSND_UL_PROCESS] = Ext_ULHisr; #ifdef DSP_BGS_UP_DOWN_INT_SEPERATE L1Audio_HookHisrHandler(D2C_SOUND_EFFECT_INT_ID_DL, DSP_BGSND_Hisr, BGSND_DL_PROCESS); L1Audio_HookHisrHandler(D2C_SOUND_EFFECT_INT_ID_UL, DSP_BGSND_Hisr, BGSND_UL_PROCESS); #else L1Audio_HookHisrHandler(D2C_SOUND_EFFECT_INT_ID_DL, DSP_BGSND_Shared_Hisr_DL_UL, 0); #endif // gain setting and update // Although these settings are allowed to modify during run time, // extended bgsnd should be fixed because the changes of volume from // each sources are calculated in MCU side. DSP_BGSND_ConfigMixer(KAL_TRUE, 7, BGSND_UL_PROCESS); DSP_BGSND_ConfigMixer(KAL_TRUE, 7, BGSND_DL_PROCESS); DSP_BGSND_UpdateMixer(); { //turn on DSP BGSND uint32 I; AM_SND_PlaybackOn(); SAL_Bgsnd_SetInit(); for( I = 0; ; I++ ) { if(SAL_Bgsnd_IsRunning()) break; ASSERT_REBOOT( I < 20 ); kal_sleep_task( 2 ); } } DSP_BGSnd.state = DSP_BGSND_STATE_RUN; kal_prompt_trace(MOD_L1SP, "[DSP_BGSND_Start] Leave"); }
/* ========================================================================= */ void SPE_CustomProcess_On(kal_uint16 sph_mode, SPE_Par_Struct *SPE_PAR, kal_uint8 *state) { #if defined( __VOICE_CHANGER_SUPPORT__ ) SPH_VOICE_CHANGER_MODE mode = 0; // Apply VCH only in speech if(!AM_IsSpeechOn()) { return; } if (!VCHIsDcmLoad) { DCM_Load(DYNAMIC_CODE_COMPRESS_VCH , 0, 0); VCHIsDcmLoad = KAL_TRUE; } kal_trace( TRACE_GROUP_AUD_SPE_CSUT, SPEECH_VCH_PROCESS, 1, VCHIsDcmLoad); #endif spe_custom = audio_alloc_mem_cacheable(sizeof(SPE_CUSTOM_STRUCT)); memset(spe_custom, 0, sizeof(SPE_CUSTOM_STRUCT)); /*Copy the actual parameters to control structure*/ spe_custom->aud_id = L1Audio_GetAudioID(); #if defined(__INTERNAL_SPE_ENGINE__) { kal_uint16 i; kal_uint32 aec_mem_size; for(i=0;i<16;i++) spe_custom->Sph_Enh_ctrl.enhance_pars[i] = SPE_PAR->mode_par[i]; for(i=0;i<12;i++) spe_custom->Sph_Enh_ctrl.enhance_pars[i+16] = SPE_PAR->common_par[i]; aec_mem_size = ENH_API_Get_Memory(&spe_custom->Sph_Enh_ctrl); if(aec_mem_size > 0) { spe_custom->working_buffer = audio_alloc_mem_cacheable( aec_mem_size * sizeof(kal_int8) ); memset(spe_custom->working_buffer, 0, aec_mem_size * sizeof(kal_int8)); ENH_API_Alloc(&spe_custom->Sph_Enh_ctrl, (kal_uint32 *)spe_custom->working_buffer); } else spe_custom->working_buffer = NULL; ENH_API_Init(&spe_custom->Sph_Enh_ctrl, SPE_PAR->out_fir, SPE_PAR->in_fir); } #elif defined( __VOICE_CHANGER_SUPPORT__ ) spe_custom->working_buffer = audio_alloc_mem_cacheable( PCM_BUFFER_LENGTH*2*sizeof(kal_uint8)); if(spe_custom->working_buffer != NULL) { memset(spe_custom->working_buffer, 0, PCM_BUFFER_LENGTH*2*sizeof(kal_uint8)); } #endif L1Audio_SetEventHandler(spe_custom->aud_id , spe_custom_task); L1Audio_SetFlag(spe_custom->aud_id); spe_custom->state = SPE_STATE_WORKING; #if defined( __VOICE_CHANGER_SUPPORT__ ) mode = L1SP_GetVoiceChangerMode(); VCHG_Open(8,mode); #endif #if 1 PCM4WAY_Start(spe_custom_hisr_hdlr, 0); #else /* under construction !*/ /* under construction !*/ /* under construction !*/ #endif }
void L1SP_D2C_LISR( uint16 itype ) { l1audio.d2c_itype = itype; l1audio.d2c_l1FN = L1I_GetTimeStamp(); L1Audio_Msg_DSP_INT( itype ); #if __DSP_WAKEUP_EVENT__ Audio_DSP_Wakeup_Eevent_clean(); #endif #if defined(MT6268) //work around in 3G, there is DP_D2C_SE_DONE int. There might be error operate especially when InterRAT HO if( itype == DP_D2C_SE_DONE && AM_IsSpeechOn() ) return; #endif #if defined(MT6236) || defined(MT6236B) || defined(MT6256_S00) || defined(MT6256_S01) || defined(MT6251) || defined(MT6253E) || defined(MT6253L)|| defined(MT6252) || defined(MT6252H) || defined(MT6255) || defined(MT6250) || defined(MT6260) if(itype == D2C_DSP_DEAD_INT_ID){ #ifndef L1D_TEST { ASSERT_DUMP_PARAM_T dump_param; dump_param.addr[0] = (kal_uint32)(DPRAM_CPU_base +0x0A0*2); dump_param.len[0] = 70*2; dump_param.addr[1] = (kal_uint32)(DPRAM2_CPU_base+0x130*2); dump_param.len[1] = 180*2; dump_param.addr[2] = 0; //End of dump param EXT_ASSERT_DUMP(0, 0x20060622, 0, 0, &dump_param); } #else { extern void L1DTest_AssertFail(void); L1DTest_AssertFail(); } #endif } #endif // #if defined(MT6236) || defined(MT6236B) || defined(MT6256) #if defined(MT6260) { bool dsp_ok = false; uint32 sph_int = 0; bool from_sph = Pseudo_SAL_DSPINT_Resolve(itype, &sph_int); if (from_sph) { { kal_int16 i; for (i = 1; i < PSEUDO_SAL_DSPINT_PRIO_MAX; i++) { if (sph_int & (1 << i)) { if (PSEUDO_SAL_DSPINT_PRIO_3G_DL == i) { // Do nothing. Don't trigger LISR here. 3G driver will trigger HISR by it's timing } else { L1Audio_TrigD2CHisr(DP_D2C_INT_MAPPING_BASIC + i); } dsp_ok |= true; } } } // After DSP send D2C and turn on bit in DP_D2C_SPEECH_UL_INT, but MCU does not receive D2C. // Handover causes VBI reset which will clean DP_D2C_SPEECH_UL_INT if (sph_int != 0) { if (!dsp_ok) { extern void L1D_WIN_DisableAllEvents(uint16 except_irq_mask); DisableIRQ(); L1D_WIN_DisableAllEvents(0); // disable all TDMA events ASSERT_REBOOT(0); } } return; } } L1Audio_TrigD2CHisr(itype); #else // chip compile option #if defined(MT6236) || defined(MT6236B) || defined(MT6256_S00) || defined(MT6256_S01) || defined(MT6251) || defined(MT6253E) || defined(MT6253L)|| defined(MT6252) || defined(MT6252H) || defined(MT6255) || defined(MT6250) if(itype == D2C_INT6_MAGIC){ bool dsp_ok = false; #else if(itype == D2C_DSP_DEAD_INT_ID){ bool dsp_ok = false; itype = *DSP_DEAD_INTERRUPT; if( itype == D2C_DSP_DEAD_INT_ID ) { extern void L1D_WIN_DisableAllEvents(uint16 except_irq_mask); DisableIRQ(); *DP_D2C_TASK1 = 0; /* freeze DSP */ L1D_WIN_DisableAllEvents( 0 ); /* disable all TDMA events */ #ifndef L1D_TEST { ASSERT_DUMP_PARAM_T dump_param; /* Write DSP debug info to exception record */ #if defined(MT6235) || defined(MT6235B) || defined(MT6268) || defined(MT6251) dump_param.addr[0] = (kal_uint32)(DPRAM_CPU_base +0x0A0*2); dump_param.len[0] = 70*2; dump_param.addr[1] = (kal_uint32)(DPRAM2_CPU_base+0x130*2); dump_param.len[1] = 180*2; dump_param.addr[2] = 0; //End of dump param #else dump_param.addr[0] = (kal_uint32)(DPRAM_CPU_base +0x130*2); dump_param.len[0] = 250*2; dump_param.addr[1] = 0; //End of dump param #endif EXT_ASSERT_DUMP(0, 0x20060622, 0, 0, &dump_param); } #else { extern void L1DTest_AssertFail(void); L1DTest_AssertFail(); } #endif//#ifndef L1D_TEST } #endif // #if defind(MT6236)|| defined(MT6256) #if defined(MT6250) itype = *DSP_DACA_UL_INT; if(itype == DP_D2C_DACA_REQ_UL){ *DSP_DACA_UL_INT = 0; L1SP_D2C_LISR(itype); dsp_ok |= true; } itype = *DSP_DACA_DL_INT; if(itype == DP_D2C_DACA_REQ_DL){ *DSP_DACA_DL_INT = 0; L1SP_D2C_LISR(itype); dsp_ok |= true; } #endif itype = *DSP_PCM_REC_INT; if( itype == D2C_UL_DL_PCM_REC_INT_ID || itype == D2C_WAV_REC_REQ_ID ) { *DSP_PCM_REC_INT = 0; L1SP_D2C_LISR(itype); dsp_ok |= true; } itype = *DSP_SOUND_EFFECT_INT; if( itype == D2C_SOUND_EFFECT_INT_ID ) { *DSP_SOUND_EFFECT_INT = 0; L1SP_D2C_LISR(itype); dsp_ok |= true; } #if defined( __BT_AUDIO_VIA_SCO__ ) && !defined(__CVSD_CODEC_SUPPORT__) itype = *DP_AUDIO_VIA_8KBT_INT; if( itype == D2C_AUDIO_VIA_8KBT_ID ) { *DP_AUDIO_VIA_8KBT_INT = 0; L1SP_D2C_LISR(itype); dsp_ok |= true; } #endif #if _SPE_FOR_TEST_SIM_ itype = *DP2_ADAPT_VOL_INT; if( itype == DP_D2C_ADAPT_VOL ) { *DP2_ADAPT_VOL_INT = 0; L1SP_D2C_LISR(itype); dsp_ok |= true; } #endif if (!dsp_ok) { extern void L1D_WIN_DisableAllEvents(uint16 except_irq_mask); DisableIRQ(); #if !defined(MT6256_S01) && !defined(MT6255) && !defined(MT6250) && !defined(MT6260) *DP_D2C_TASK1 = 0; /* freeze DSP */ #endif L1D_WIN_DisableAllEvents( 0 ); /* disable all TDMA events */ ASSERT_REBOOT(0); } return; } if( (itype == DP_D2C_SE_SD_DONE) && (!AM_IsSpeechOn()) ) // when idle 16kPCM, AMR/AWB/VM record, the driver expects the D2C_SE_DONE interrupt triggered by DSP. If System's doing SMS, howerver, DSP triggers the D2C_SE_SD_DONE to MCU. Even if in this case, because the data provided by DSP is also available, the drive just easily modifies the interrupt ID to access data provide by DSP. itype = DP_D2C_SE_DONE; { int32 I; for (I = 0; I < MAX_HISR_HANDLER; I++) { if (itype == l1audio.hisrMagicNo[I]) { l1audio.hisrMagicFlag |= (1<<I); kal_activate_hisr(l1audio.hisr); return; } } } #endif // chip compile option #if defined(MT6235) || defined(MT6235B) || defined(MT6268) || defined(MT6253) || defined(MT6236) || defined(MT6236B) || defined(MT6256_S00)|| defined(MT6256_S01) || defined(MT6251) || defined(MT6253E) || defined(MT6253L)|| defined(MT6252) || defined(MT6252H) || defined(MT6255) || defined(MT6250) || defined(MT6260) if (itype == DP_D2C_AVSYNC) { Media_A2V_LISR(); } else #endif { l1audio.media_flag = itype; kal_activate_hisr(l1audio.hisr); } } void L1Audio_HookHisrHandler( kal_uint16 magic_no, L1Audio_EventHandler handler, void *userData ) { int32 I; for( I = 0; I < MAX_HISR_HANDLER; I++ ) { if( l1audio.hisrMagicNo[I] == 0 ) { l1audio.hisrMagicNo[I] = magic_no; l1audio.hisrHandler[I] = handler; l1audio.hisrUserData[I] = userData; break; } } ASSERT_REBOOT( I != MAX_HISR_HANDLER ); }